Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nodejs/node.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlegendecas <legendecas@gmail.com>2022-05-02 19:46:31 +0300
committerGitHub <noreply@github.com>2022-05-02 19:46:31 +0300
commite86a6383054623e5168384a83d8cd6ebfe1fb584 (patch)
tree1953d373d3f24e9b5c6f2e84217328ff213289b6
parent3bd87e1782b45fec6df7809823fdf16ec07bc4a7 (diff)
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>
-rw-r--r--.eslintrc.js1
-rw-r--r--doc/api/cli.md12
-rw-r--r--doc/node.13
-rw-r--r--lib/.eslintrc.yaml4
-rw-r--r--node.gyp2
-rw-r--r--src/api/environment.cc7
-rw-r--r--src/node_options.cc9
-rw-r--r--src/node_options.h1
-rw-r--r--src/node_shadow_realm.cc16
-rw-r--r--src/node_shadow_realm.h19
-rw-r--r--test/parallel/test-shadow-realm.js12
11 files changed, 85 insertions, 1 deletions
diff --git a/.eslintrc.js b/.eslintrc.js
index ea69a2893ff..167107a0018 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -337,6 +337,7 @@ module.exports = {
TextEncoderStream: 'readable',
TransformStream: 'readable',
TransformStreamDefaultController: 'readable',
+ ShadowRealm: 'readable',
SubtleCrypto: 'readable',
WritableStream: 'readable',
WritableStreamDefaultWriter: 'readable',
diff --git a/doc/api/cli.md b/doc/api/cli.md
index 44ba09624b0..5bb0c3cf33d 100644
--- a/doc/api/cli.md
+++ b/doc/api/cli.md
@@ -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
diff --git a/doc/node.1 b/doc/node.1
index 2003bc8ca79..6ac0d675834 100644
--- a/doc/node.1
+++ b/doc/node.1
@@ -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.
.
diff --git a/lib/.eslintrc.yaml b/lib/.eslintrc.yaml
index c1635e4cf08..6bfc102b817 100644
--- a/lib/.eslintrc.yaml
+++ b/lib/.eslintrc.yaml
@@ -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
diff --git a/node.gyp b/node.gyp
index 4e06d00c823..512e341b5b7 100644
--- a/node.gyp
+++ b/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',
diff --git a/src/api/environment.cc b/src/api/environment.cc
index f3a8f49812d..ccdcdefb20f 100644
--- a/src/api/environment.cc
+++ b/src/api/environment.cc
@@ -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;
diff --git a/src/node_options.cc b/src/node_options.cc
index 8341724089a..f7551248f7d 100644
--- a/src/node_options.cc
+++ b/src/node_options.cc
@@ -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);
}
diff --git a/src/node_options.h b/src/node_options.h
index a3937900b41..a5af1684d38 100644
--- a/src/node_options.h
+++ b/src/node_options.h
@@ -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;
diff --git a/src/node_shadow_realm.cc b/src/node_shadow_realm.cc
new file mode 100644
index 00000000000..2ccd62edc31
--- /dev/null
+++ b/src/node_shadow_realm.cc
@@ -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
diff --git a/src/node_shadow_realm.h b/src/node_shadow_realm.h
new file mode 100644
index 00000000000..a10fc425661
--- /dev/null
+++ b/src/node_shadow_realm.h
@@ -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_
diff --git a/test/parallel/test-shadow-realm.js b/test/parallel/test-shadow-realm.js
new file mode 100644
index 00000000000..0b20265537f
--- /dev/null
+++ b/test/parallel/test-shadow-realm.js
@@ -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);