@@ -96,6 +96,7 @@ Typical ways of accessing the current `Isolate` in the Node.js code are:
96
96
using ` args.GetIsolate() ` .
97
97
* Given a [ ` Context ` ] [ ] , using ` context->GetIsolate() ` .
98
98
* Given a [ ` Environment ` ] [ ] , using ` env->isolate() ` .
99
+ * Given a [ ` Realm ` ] [ ] , using ` realm->isolate() ` .
99
100
100
101
### V8 JavaScript values
101
102
@@ -264,19 +265,25 @@ heap. Node.js exposes this ability through the [`vm` module][].
264
265
V8 refers to each of these global objects and their associated builtins as a
265
266
`Context`.
266
267
267
- Currently, in Node.js there is one main `Context` associated with an
268
- [`Environment`][] instance, and most Node.js features will only work inside
269
- that context. (The only exception at the time of writing are
270
- [`MessagePort`][] objects.) This restriction is not inherent to the design of
271
- Node.js, and a sufficiently committed person could restructure Node.js to
272
- provide built-in modules inside of `vm.Context`s.
268
+ Currently, in Node.js there is one main `Context` associated with the
269
+ principal [`Realm`][] of an [`Environment`][] instance, and a number of
270
+ subsidiary `Context`s that are created with `vm.Context` or associated with
271
+ [`ShadowRealm`][].
272
+
273
+ Most Node.js features will only work inside a context associated with a
274
+ `Realm`. The only exception at the time of writing are [`MessagePort`][]
275
+ objects. This restriction is not inherent to the design of Node.js, and a
276
+ sufficiently committed person could restructure Node.js to provide built-in
277
+ modules inside of `vm.Context`s.
273
278
274
279
Often, the `Context` is passed around for [exception handling][].
275
280
Typical ways of accessing the current `Context` in the Node.js code are:
276
281
277
282
* Given an [`Isolate`][], using `isolate->GetCurrentContext()`.
278
283
* Given an [`Environment`][], using `env->context()` to get the `Environment`'s
279
- main context.
284
+ principal [`Realm`][]'s context.
285
+ * Given a [`Realm`][], using `realm->context()` to get the `Realm`'s
286
+ context.
280
287
281
288
<a id="event-loop"></a>
282
289
@@ -303,15 +310,11 @@ Currently, every `Environment` class is associated with:
303
310
304
311
* One [event loop][]
305
312
* One [`Isolate`][]
306
- * One main [`Context `][]
313
+ * One principal [`Realm `][]
307
314
308
315
The `Environment` class contains a large number of different fields for
309
- different Node.js modules, for example a libuv timer for `setTimeout()` or
310
- the memory for a `Float64Array` that the `fs` module uses for storing data
311
- returned from a `fs.stat()` call.
312
-
313
- It also provides [cleanup hooks][] and maintains a list of [`BaseObject`][]
314
- instances.
316
+ different built-in modules that can be shared across different `Realm`
317
+ instances, for example, the inspector agent, async hooks info.
315
318
316
319
Typical ways of accessing the current `Environment` in the Node.js code are:
317
320
@@ -325,6 +328,45 @@ Typical ways of accessing the current `Environment` in the Node.js code are:
325
328
* Given an [`Isolate`][], using `Environment::GetCurrent(isolate)`. This looks
326
329
up the current [`Context`][] and then uses that.
327
330
331
+ <a id="realm"></a>
332
+
333
+ ### `Realm`
334
+
335
+ The `Realm` class is a container for a set of JavaScript objects and functions
336
+ that are associated with a particular [ECMAScript realm][].
337
+
338
+ Each ECMAScript realm comes with a global object and a set of intrinsic
339
+ objects. An ECMAScript realm has a `[[HostDefined]]` field, which represents
340
+ the Node.js [`Realm`][] object.
341
+
342
+ Every `Realm` instance is created for a particular [`Context`][]. A `Realm`
343
+ can be a principal realm or a synthetic realm. A principal realm is created
344
+ for each `Environment`'s main [`Context`][]. A synthetic realm is created
345
+ for the [`Context`][] of each [`ShadowRealm`][] constructed from the JS API. No
346
+ `Realm` is created for the [`Context`][] of a `vm.Context`.
347
+
348
+ Native bindings and built-in modules can be evaluated in either a principal
349
+ realm or a synthetic realm.
350
+
351
+ The `Realm` class contains a large number of different fields for
352
+ different built-in modules, for example the memory for a `Uint32Array` that
353
+ the `url` module uses for storing data returned from a
354
+ `urlBinding.update()` call.
355
+
356
+ It also provides [cleanup hooks][] and maintains a list of [`BaseObject`][]
357
+ instances.
358
+
359
+ Typical ways of accessing the current `Realm` in the Node.js code are:
360
+
361
+ * Given a `FunctionCallbackInfo` for a [binding function][],
362
+ using `Realm::GetCurrent(args)`.
363
+ * Given a [`BaseObject`][], using `realm()` or `self->realm()`.
364
+ * Given a [`Context`][], using `Realm::GetCurrent(context)`.
365
+ This requires that `context` has been associated with the `Realm`
366
+ instance, e.g. is the principal `Realm` for the `Environment`.
367
+ * Given an [`Isolate`][], using `Realm::GetCurrent(isolate)`. This looks
368
+ up the current [`Context`][] and then uses its `Realm`.
369
+
328
370
<a id="isolate-data"></a>
329
371
330
372
### `IsolateData`
@@ -509,7 +551,7 @@ implement them. Otherwise, add the id and the class name to the
509
551
// In the HTTP parser source code file:
510
552
class BindingData : public BaseObject {
511
553
public:
512
- BindingData(Environment * env , Local<Object > obj) : BaseObject(env , obj) {}
554
+ BindingData(Realm * realm , Local<Object > obj) : BaseObject(realm , obj) {}
513
555
514
556
SET_BINDING_ID(http_parser_binding_data)
515
557
@@ -525,7 +567,7 @@ static void New(const FunctionCallbackInfo<Value>& args) {
525
567
new Parser(binding_data, args.This());
526
568
}
527
569
528
- // ... because the initialization function told the Environment to store the
570
+ // ... because the initialization function told the Realm to store the
529
571
// BindingData object:
530
572
void InitializeHttpParser(Local<Object > target,
531
573
Local<Value > unused,
@@ -710,11 +752,13 @@ any resources owned by it, e.g. memory or libuv requests/handles.
710
752
711
753
#### Cleanup hooks
712
754
713
- Cleanup hooks are provided that run before the [ ` Environment ` ] [ ]
714
- is destroyed. They can be added and removed through by using
755
+ Cleanup hooks are provided that run before the [ ` Environment ` ] [ ] or the
756
+ [ ` Realm ` ] [ ] is destroyed. They can be added and removed by using
715
757
` env->AddCleanupHook(callback, hint); ` and
716
- ` env->RemoveCleanupHook(callback, hint); ` , where callback takes a ` void* hint `
717
- argument.
758
+ ` env->RemoveCleanupHook(callback, hint); ` , or
759
+ ` realm->AddCleanupHook(callback, hint); ` and
760
+ ` realm->RemoveCleanupHook(callback, hint); ` respectively, where callback takes
761
+ a ` void* hint ` argument.
718
762
719
763
Inside these cleanup hooks, new asynchronous operations _ may_ be started on the
720
764
event loop, although ideally that is avoided as much as possible.
@@ -776,7 +820,7 @@ need to be tied together. `BaseObject` is the main abstraction for that in
776
820
Node.js, and most classes that are associated with JavaScript objects are
777
821
subclasses of it. It is defined in [ ` base_object.h ` ] [ ] .
778
822
779
- Every ` BaseObject ` is associated with one [ ` Environment ` ] [ ] and one
823
+ Every ` BaseObject ` is associated with one [ ` Realm ` ] [ ] and one
780
824
` v8::Object ` . The ` v8::Object ` needs to have at least one [ internal field] [ ]
781
825
that is used for storing the pointer to the C++ object. In order to ensure this,
782
826
the V8 ` SetInternalFieldCount() ` function is usually used when setting up the
@@ -1038,6 +1082,7 @@ static void GetUserInfo(const FunctionCallbackInfo<Value>& args) {
1038
1082
1039
1083
[ C++ coding style ] : ../doc/contributing/cpp-style-guide.md
1040
1084
[ Callback scopes ] : #callback-scopes
1085
+ [ ECMAScript realm ] : https://tc39.es/ecma262/#sec-code-realms
1041
1086
[ JavaScript value handles ] : #js-handles
1042
1087
[ N-API ] : https://nodejs.org/api/n-api.html
1043
1088
[ `BaseObject` ] : #baseobject
@@ -1050,7 +1095,9 @@ static void GetUserInfo(const FunctionCallbackInfo<Value>& args) {
1050
1095
[ `Local` ] : #local-handles
1051
1096
[ `MakeCallback()` ] : #makecallback
1052
1097
[ `MessagePort` ] : https://nodejs.org/api/worker_threads.html#worker_threads_class_messageport
1098
+ [ `Realm` ] : #realm
1053
1099
[ `ReqWrap` ] : #reqwrap
1100
+ [ `ShadowRealm` ] : https://github.com/tc39/proposal-shadowrealm
1054
1101
[ `async_hooks` module ] : https://nodejs.org/api/async_hooks.html
1055
1102
[ `async_wrap.h` ] : async_wrap.h
1056
1103
[ `base_object.h` ] : base_object.h
0 commit comments