Skip to content

Commit b8290ff

Browse files
legendecasjuanarbol
authored andcommittedNov 4, 2022
src: add initial shadow realm support
Add initial shadow realm support behind an off-by-default flag `--experimental-shadow-realm`. PR-URL: #42869 Refs: #42528 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Darshan Sen <raisinten@gmail.com>
1 parent 8cae0a1 commit b8290ff

11 files changed

+85
-1
lines changed
 

‎.eslintrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ module.exports = {
338338
TextEncoderStream: 'readable',
339339
TransformStream: 'readable',
340340
TransformStreamDefaultController: 'readable',
341+
ShadowRealm: 'readable',
341342
SubtleCrypto: 'readable',
342343
WritableStream: 'readable',
343344
WritableStreamDefaultWriter: 'readable',

‎doc/api/cli.md

+11-1
Original file line numberDiff line numberDiff line change
@@ -411,10 +411,18 @@ Disable experimental support for the [Fetch API][].
411411

412412
<!-- YAML
413413
added: v16.6.0
414-
-->
414+
-->
415415

416416
Use this flag to disable top-level await in REPL.
417417

418+
### `--experimental-shadow-realm`
419+
420+
<!-- YAML
421+
added: REPLACEME
422+
-->
423+
424+
Use this flag to enable [ShadowRealm][] support.
425+
418426
### `--experimental-specifier-resolution=mode`
419427

420428
<!-- YAML
@@ -1807,6 +1815,7 @@ Node.js options that are allowed are:
18071815
* `--experimental-modules`
18081816
* `--experimental-network-imports`
18091817
* `--experimental-policy`
1818+
* `--experimental-shadow-realm`
18101819
* `--experimental-specifier-resolution`
18111820
* `--experimental-top-level-await`
18121821
* `--experimental-vm-modules`
@@ -2236,6 +2245,7 @@ done
22362245
[OSSL_PROVIDER-legacy]: https://www.openssl.org/docs/man3.0/man7/OSSL_PROVIDER-legacy.html
22372246
[REPL]: repl.md
22382247
[ScriptCoverage]: https://chromedevtools.github.io/devtools-protocol/tot/Profiler#type-ScriptCoverage
2248+
[ShadowRealm]: https://github.com/tc39/proposal-shadowrealm
22392249
[Source Map]: https://sourcemaps.info/spec.html
22402250
[Subresource Integrity]: https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity
22412251
[V8 JavaScript code coverage]: https://v8project.blogspot.com/2017/12/javascript-code-coverage.html

‎doc/node.1

+3
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ Enable experimental support for loading modules using `import` over `https:`.
159159
.It Fl -experimental-policy
160160
Use the specified file as a security policy.
161161
.
162+
.It Fl -experimental-shadow-realm
163+
Use this flag to enable ShadowRealm support.
164+
.
162165
.It Fl -no-experimental-fetch
163166
Disable experimental support for the Fetch API.
164167
.

‎lib/.eslintrc.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ rules:
8989
message: Use `const { Request } = require('internal/deps/undici/undici');` instead of the global.
9090
- name: Response
9191
message: Use `const { Response } = require('internal/deps/undici/undici');` instead of the global.
92+
# ShadowRealm is not available in primordials because it can be
93+
# disabled with --no-harmony-shadow-realm CLI flag.
94+
- name: ShadowRealm
95+
message: Use `const { ShadowRealm } = globalThis;` instead of the global.
9296
# SharedArrayBuffer is not available in primordials because it can be
9397
# disabled with --no-harmony-sharedarraybuffer CLI flag.
9498
- name: SharedArrayBuffer

‎node.gyp

+2
Original file line numberDiff line numberDiff line change
@@ -529,6 +529,7 @@
529529
'src/node_report_module.cc',
530530
'src/node_report_utils.cc',
531531
'src/node_serdes.cc',
532+
'src/node_shadow_realm.cc',
532533
'src/node_snapshotable.cc',
533534
'src/node_sockaddr.cc',
534535
'src/node_stat_watcher.cc',
@@ -634,6 +635,7 @@
634635
'src/node_report.h',
635636
'src/node_revert.h',
636637
'src/node_root_certs.h',
638+
'src/node_shadow_realm.h',
637639
'src/node_snapshotable.h',
638640
'src/node_snapshot_builder.h',
639641
'src/node_sockaddr.h',

‎src/api/environment.cc

+7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "node_internals.h"
66
#include "node_options-inl.h"
77
#include "node_platform.h"
8+
#include "node_shadow_realm.h"
89
#include "node_v8_platform-inl.h"
910
#include "node_wasm_web_api.h"
1011
#include "uv.h"
@@ -264,6 +265,12 @@ void SetIsolateMiscHandlers(v8::Isolate* isolate, const IsolateSettings& s) {
264265
isolate->SetWasmStreamingCallback(wasm_web_api::StartStreamingCompilation);
265266
}
266267

268+
if (per_process::cli_options->get_per_isolate_options()
269+
->experimental_shadow_realm) {
270+
isolate->SetHostCreateShadowRealmContextCallback(
271+
shadow_realm::HostCreateShadowRealmContextCallback);
272+
}
273+
267274
if ((s.flags & SHOULD_NOT_SET_PROMISE_REJECTION_CALLBACK) == 0) {
268275
auto* promise_reject_cb = s.promise_reject_callback ?
269276
s.promise_reject_callback : PromiseRejectCallback;

‎src/node_options.cc

+9
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,15 @@ PerIsolateOptionsParser::PerIsolateOptionsParser(
753753
AddOption(
754754
"--experimental-top-level-await", "", NoOp{}, kAllowedInEnvironment);
755755

756+
AddOption("--experimental-shadow-realm",
757+
"",
758+
&PerIsolateOptions::experimental_shadow_realm,
759+
kAllowedInEnvironment);
760+
AddOption("--harmony-shadow-realm", "", V8Option{});
761+
Implies("--experimental-shadow-realm", "--harmony-shadow-realm");
762+
Implies("--harmony-shadow-realm", "--experimental-shadow-realm");
763+
ImpliesNot("--no-harmony-shadow-realm", "--experimental-shadow-realm");
764+
756765
Insert(eop, &PerIsolateOptions::get_per_env_options);
757766
}
758767

‎src/node_options.h

+1
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ class PerIsolateOptions : public Options {
214214
bool track_heap_objects = false;
215215
bool report_uncaught_exception = false;
216216
bool report_on_signal = false;
217+
bool experimental_shadow_realm = false;
217218
std::string report_signal = "SIGUSR2";
218219
inline EnvironmentOptions* get_per_env_options();
219220
void CheckOptions(std::vector<std::string>* errors) override;

‎src/node_shadow_realm.cc

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "node_shadow_realm.h"
2+
3+
namespace node {
4+
namespace shadow_realm {
5+
using v8::Context;
6+
using v8::Local;
7+
using v8::MaybeLocal;
8+
9+
// static
10+
MaybeLocal<Context> HostCreateShadowRealmContextCallback(
11+
Local<Context> initiator_context) {
12+
return Context::New(initiator_context->GetIsolate());
13+
}
14+
15+
} // namespace shadow_realm
16+
} // namespace node

‎src/node_shadow_realm.h

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef SRC_NODE_SHADOW_REALM_H_
2+
#define SRC_NODE_SHADOW_REALM_H_
3+
4+
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
5+
6+
#include "v8.h"
7+
8+
namespace node {
9+
namespace shadow_realm {
10+
11+
v8::MaybeLocal<v8::Context> HostCreateShadowRealmContextCallback(
12+
v8::Local<v8::Context> initiator_context);
13+
14+
} // namespace shadow_realm
15+
} // namespace node
16+
17+
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
18+
19+
#endif // SRC_NODE_SHADOW_REALM_H_

‎test/parallel/test-shadow-realm.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Flags: --experimental-shadow-realm
2+
'use strict';
3+
4+
require('../common');
5+
const assert = require('assert');
6+
7+
// Validates we can construct ShadowRealm successfully.
8+
const shadowRealm = new ShadowRealm();
9+
10+
const getter = shadowRealm.evaluate('globalThis.realmValue = "inner"; () => globalThis.realmValue;');
11+
assert.strictEqual(getter(), 'inner');
12+
assert.strictEqual('realmValue' in globalThis, false);

0 commit comments

Comments
 (0)