mirror of
https://github.com/nodejs/node.git
synced 2025-12-28 07:50:41 +00:00
src: add initial shadow realm support
Add initial shadow realm support behind an off-by-default flag `--experimental-shadow-realm`. PR-URL: https://github.com/nodejs/node/pull/42869 Refs: https://github.com/nodejs/node/issues/42528 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Darshan Sen <raisinten@gmail.com>
This commit is contained in:
parent
3bd87e1782
commit
e86a638305
@ -337,6 +337,7 @@ module.exports = {
|
||||
TextEncoderStream: 'readable',
|
||||
TransformStream: 'readable',
|
||||
TransformStreamDefaultController: 'readable',
|
||||
ShadowRealm: 'readable',
|
||||
SubtleCrypto: 'readable',
|
||||
WritableStream: 'readable',
|
||||
WritableStreamDefaultWriter: 'readable',
|
||||
|
||||
@ -346,10 +346,18 @@ Disable experimental support for the [Fetch API][].
|
||||
|
||||
<!-- YAML
|
||||
added: v16.6.0
|
||||
-->
|
||||
-->
|
||||
|
||||
Use this flag to disable top-level await in REPL.
|
||||
|
||||
### `--experimental-shadow-realm`
|
||||
|
||||
<!-- YAML
|
||||
added: REPLACEME
|
||||
-->
|
||||
|
||||
Use this flag to enable [ShadowRealm][] support.
|
||||
|
||||
### `--experimental-specifier-resolution=mode`
|
||||
|
||||
<!-- YAML
|
||||
@ -1622,6 +1630,7 @@ Node.js options that are allowed are:
|
||||
* `--experimental-modules`
|
||||
* `--experimental-network-imports`
|
||||
* `--experimental-policy`
|
||||
* `--experimental-shadow-realm`
|
||||
* `--experimental-specifier-resolution`
|
||||
* `--experimental-top-level-await`
|
||||
* `--experimental-vm-modules`
|
||||
@ -2017,6 +2026,7 @@ $ node --max-old-space-size=1536 index.js
|
||||
[OSSL_PROVIDER-legacy]: https://www.openssl.org/docs/man3.0/man7/OSSL_PROVIDER-legacy.html
|
||||
[REPL]: repl.md
|
||||
[ScriptCoverage]: https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-ScriptCoverage
|
||||
[ShadowRealm]: https://github.com/tc39/proposal-shadowrealm
|
||||
[Source Map]: https://sourcemaps.info/spec.html
|
||||
[Subresource Integrity]: https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
|
||||
[V8 JavaScript code coverage]: https://v8project.blogspot.com/2017/12/javascript-code-coverage.html
|
||||
|
||||
@ -156,6 +156,9 @@ Enable experimental support for loading modules using `import` over `https:`.
|
||||
.It Fl -experimental-policy
|
||||
Use the specified file as a security policy.
|
||||
.
|
||||
.It Fl -experimental-shadow-realm
|
||||
Use this flag to enable ShadowRealm support.
|
||||
.
|
||||
.It Fl -no-experimental-fetch
|
||||
Disable experimental support for the Fetch API.
|
||||
.
|
||||
|
||||
@ -87,6 +87,10 @@ rules:
|
||||
message: Use `const { Request } = require('internal/deps/undici/undici');` instead of the global.
|
||||
- name: Response
|
||||
message: Use `const { Response } = require('internal/deps/undici/undici');` instead of the global.
|
||||
# ShadowRealm is not available in primordials because it can be
|
||||
# disabled with --no-harmony-shadow-realm CLI flag.
|
||||
- name: ShadowRealm
|
||||
message: Use `const { ShadowRealm } = globalThis;` instead of the global.
|
||||
# SharedArrayBuffer is not available in primordials because it can be
|
||||
# disabled with --no-harmony-sharedarraybuffer CLI flag.
|
||||
- name: SharedArrayBuffer
|
||||
|
||||
2
node.gyp
2
node.gyp
@ -531,6 +531,7 @@
|
||||
'src/node_report_module.cc',
|
||||
'src/node_report_utils.cc',
|
||||
'src/node_serdes.cc',
|
||||
'src/node_shadow_realm.cc',
|
||||
'src/node_snapshotable.cc',
|
||||
'src/node_sockaddr.cc',
|
||||
'src/node_stat_watcher.cc',
|
||||
@ -637,6 +638,7 @@
|
||||
'src/node_report.h',
|
||||
'src/node_revert.h',
|
||||
'src/node_root_certs.h',
|
||||
'src/node_shadow_realm.h',
|
||||
'src/node_snapshotable.h',
|
||||
'src/node_snapshot_builder.h',
|
||||
'src/node_sockaddr.h',
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include "node_native_module_env.h"
|
||||
#include "node_options-inl.h"
|
||||
#include "node_platform.h"
|
||||
#include "node_shadow_realm.h"
|
||||
#include "node_v8_platform-inl.h"
|
||||
#include "node_wasm_web_api.h"
|
||||
#include "uv.h"
|
||||
@ -261,6 +262,12 @@ void SetIsolateMiscHandlers(v8::Isolate* isolate, const IsolateSettings& s) {
|
||||
isolate->SetWasmStreamingCallback(wasm_web_api::StartStreamingCompilation);
|
||||
}
|
||||
|
||||
if (per_process::cli_options->get_per_isolate_options()
|
||||
->experimental_shadow_realm) {
|
||||
isolate->SetHostCreateShadowRealmContextCallback(
|
||||
shadow_realm::HostCreateShadowRealmContextCallback);
|
||||
}
|
||||
|
||||
if ((s.flags & SHOULD_NOT_SET_PROMISE_REJECTION_CALLBACK) == 0) {
|
||||
auto* promise_reject_cb = s.promise_reject_callback ?
|
||||
s.promise_reject_callback : PromiseRejectCallback;
|
||||
|
||||
@ -703,6 +703,15 @@ PerIsolateOptionsParser::PerIsolateOptionsParser(
|
||||
AddOption(
|
||||
"--experimental-top-level-await", "", NoOp{}, kAllowedInEnvironment);
|
||||
|
||||
AddOption("--experimental-shadow-realm",
|
||||
"",
|
||||
&PerIsolateOptions::experimental_shadow_realm,
|
||||
kAllowedInEnvironment);
|
||||
AddOption("--harmony-shadow-realm", "", V8Option{});
|
||||
Implies("--experimental-shadow-realm", "--harmony-shadow-realm");
|
||||
Implies("--harmony-shadow-realm", "--experimental-shadow-realm");
|
||||
ImpliesNot("--no-harmony-shadow-realm", "--experimental-shadow-realm");
|
||||
|
||||
Insert(eop, &PerIsolateOptions::get_per_env_options);
|
||||
}
|
||||
|
||||
|
||||
@ -205,6 +205,7 @@ class PerIsolateOptions : public Options {
|
||||
bool track_heap_objects = false;
|
||||
bool report_uncaught_exception = false;
|
||||
bool report_on_signal = false;
|
||||
bool experimental_shadow_realm = false;
|
||||
std::string report_signal = "SIGUSR2";
|
||||
inline EnvironmentOptions* get_per_env_options();
|
||||
void CheckOptions(std::vector<std::string>* errors) override;
|
||||
|
||||
16
src/node_shadow_realm.cc
Normal file
16
src/node_shadow_realm.cc
Normal file
@ -0,0 +1,16 @@
|
||||
#include "node_shadow_realm.h"
|
||||
|
||||
namespace node {
|
||||
namespace shadow_realm {
|
||||
using v8::Context;
|
||||
using v8::Local;
|
||||
using v8::MaybeLocal;
|
||||
|
||||
// static
|
||||
MaybeLocal<Context> HostCreateShadowRealmContextCallback(
|
||||
Local<Context> initiator_context) {
|
||||
return Context::New(initiator_context->GetIsolate());
|
||||
}
|
||||
|
||||
} // namespace shadow_realm
|
||||
} // namespace node
|
||||
19
src/node_shadow_realm.h
Normal file
19
src/node_shadow_realm.h
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef SRC_NODE_SHADOW_REALM_H_
|
||||
#define SRC_NODE_SHADOW_REALM_H_
|
||||
|
||||
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
||||
|
||||
#include "v8.h"
|
||||
|
||||
namespace node {
|
||||
namespace shadow_realm {
|
||||
|
||||
v8::MaybeLocal<v8::Context> HostCreateShadowRealmContextCallback(
|
||||
v8::Local<v8::Context> initiator_context);
|
||||
|
||||
} // namespace shadow_realm
|
||||
} // namespace node
|
||||
|
||||
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
||||
|
||||
#endif // SRC_NODE_SHADOW_REALM_H_
|
||||
12
test/parallel/test-shadow-realm.js
Normal file
12
test/parallel/test-shadow-realm.js
Normal file
@ -0,0 +1,12 @@
|
||||
// Flags: --experimental-shadow-realm
|
||||
'use strict';
|
||||
|
||||
require('../common');
|
||||
const assert = require('assert');
|
||||
|
||||
// Validates we can construct ShadowRealm successfully.
|
||||
const shadowRealm = new ShadowRealm();
|
||||
|
||||
const getter = shadowRealm.evaluate('globalThis.realmValue = "inner"; () => globalThis.realmValue;');
|
||||
assert.strictEqual(getter(), 'inner');
|
||||
assert.strictEqual('realmValue' in globalThis, false);
|
||||
Loading…
Reference in New Issue
Block a user