mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
src: add Realm document in the src README.md
PR-URL: https://github.com/nodejs/node/pull/47932 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
This commit is contained in:
@@ -96,6 +96,7 @@ Typical ways of accessing the current `Isolate` in the Node.js code are:
|
||||
using `args.GetIsolate()`.
|
||||
* Given a [`Context`][], using `context->GetIsolate()`.
|
||||
* Given a [`Environment`][], using `env->isolate()`.
|
||||
* Given a [`Realm`][], using `realm->isolate()`.
|
||||
|
||||
### V8 JavaScript values
|
||||
|
||||
@@ -264,19 +265,25 @@ heap. Node.js exposes this ability through the [`vm` module][].
|
||||
V8 refers to each of these global objects and their associated builtins as a
|
||||
`Context`.
|
||||
|
||||
Currently, in Node.js there is one main `Context` associated with an
|
||||
[`Environment`][] instance, and most Node.js features will only work inside
|
||||
that context. (The only exception at the time of writing are
|
||||
[`MessagePort`][] objects.) This restriction is not inherent to the design of
|
||||
Node.js, and a sufficiently committed person could restructure Node.js to
|
||||
provide built-in modules inside of `vm.Context`s.
|
||||
Currently, in Node.js there is one main `Context` associated with the
|
||||
principal [`Realm`][] of an [`Environment`][] instance, and a number of
|
||||
subsidiary `Context`s that are created with `vm.Context` or associated with
|
||||
[`ShadowRealm`][].
|
||||
|
||||
Most Node.js features will only work inside a context associated with a
|
||||
`Realm`. The only exception at the time of writing are [`MessagePort`][]
|
||||
objects. This restriction is not inherent to the design of Node.js, and a
|
||||
sufficiently committed person could restructure Node.js to provide built-in
|
||||
modules inside of `vm.Context`s.
|
||||
|
||||
Often, the `Context` is passed around for [exception handling][].
|
||||
Typical ways of accessing the current `Context` in the Node.js code are:
|
||||
|
||||
* Given an [`Isolate`][], using `isolate->GetCurrentContext()`.
|
||||
* Given an [`Environment`][], using `env->context()` to get the `Environment`'s
|
||||
main context.
|
||||
principal [`Realm`][]'s context.
|
||||
* Given a [`Realm`][], using `realm->context()` to get the `Realm`'s
|
||||
context.
|
||||
|
||||
<a id="event-loop"></a>
|
||||
|
||||
@@ -303,15 +310,11 @@ Currently, every `Environment` class is associated with:
|
||||
|
||||
* One [event loop][]
|
||||
* One [`Isolate`][]
|
||||
* One main [`Context`][]
|
||||
* One principal [`Realm`][]
|
||||
|
||||
The `Environment` class contains a large number of different fields for
|
||||
different Node.js modules, for example a libuv timer for `setTimeout()` or
|
||||
the memory for a `Float64Array` that the `fs` module uses for storing data
|
||||
returned from a `fs.stat()` call.
|
||||
|
||||
It also provides [cleanup hooks][] and maintains a list of [`BaseObject`][]
|
||||
instances.
|
||||
different built-in modules that can be shared across different `Realm`
|
||||
instances, for example, the inspector agent, async hooks info.
|
||||
|
||||
Typical ways of accessing the current `Environment` in the Node.js code are:
|
||||
|
||||
@@ -325,6 +328,45 @@ Typical ways of accessing the current `Environment` in the Node.js code are:
|
||||
* Given an [`Isolate`][], using `Environment::GetCurrent(isolate)`. This looks
|
||||
up the current [`Context`][] and then uses that.
|
||||
|
||||
<a id="realm"></a>
|
||||
|
||||
### `Realm`
|
||||
|
||||
The `Realm` class is a container for a set of JavaScript objects and functions
|
||||
that are associated with a particular [ECMAScript realm][].
|
||||
|
||||
Each ECMAScript realm comes with a global object and a set of intrinsic
|
||||
objects. An ECMAScript realm has a `[[HostDefined]]` field, which represents
|
||||
the Node.js [`Realm`][] object.
|
||||
|
||||
Every `Realm` instance is created for a particular [`Context`][]. A `Realm`
|
||||
can be a principal realm or a synthetic realm. A principal realm is created
|
||||
for each `Environment`'s main [`Context`][]. A synthetic realm is created
|
||||
for the [`Context`][] of each [`ShadowRealm`][] constructed from the JS API. No
|
||||
`Realm` is created for the [`Context`][] of a `vm.Context`.
|
||||
|
||||
Native bindings and built-in modules can be evaluated in either a principal
|
||||
realm or a synthetic realm.
|
||||
|
||||
The `Realm` class contains a large number of different fields for
|
||||
different built-in modules, for example the memory for a `Uint32Array` that
|
||||
the `url` module uses for storing data returned from a
|
||||
`urlBinding.update()` call.
|
||||
|
||||
It also provides [cleanup hooks][] and maintains a list of [`BaseObject`][]
|
||||
instances.
|
||||
|
||||
Typical ways of accessing the current `Realm` in the Node.js code are:
|
||||
|
||||
* Given a `FunctionCallbackInfo` for a [binding function][],
|
||||
using `Realm::GetCurrent(args)`.
|
||||
* Given a [`BaseObject`][], using `realm()` or `self->realm()`.
|
||||
* Given a [`Context`][], using `Realm::GetCurrent(context)`.
|
||||
This requires that `context` has been associated with the `Realm`
|
||||
instance, e.g. is the principal `Realm` for the `Environment`.
|
||||
* Given an [`Isolate`][], using `Realm::GetCurrent(isolate)`. This looks
|
||||
up the current [`Context`][] and then uses its `Realm`.
|
||||
|
||||
<a id="isolate-data"></a>
|
||||
|
||||
### `IsolateData`
|
||||
@@ -509,7 +551,7 @@ implement them. Otherwise, add the id and the class name to the
|
||||
// In the HTTP parser source code file:
|
||||
class BindingData : public BaseObject {
|
||||
public:
|
||||
BindingData(Environment* env, Local<Object> obj) : BaseObject(env, obj) {}
|
||||
BindingData(Realm* realm, Local<Object> obj) : BaseObject(realm, obj) {}
|
||||
|
||||
SET_BINDING_ID(http_parser_binding_data)
|
||||
|
||||
@@ -525,7 +567,7 @@ static void New(const FunctionCallbackInfo<Value>& args) {
|
||||
new Parser(binding_data, args.This());
|
||||
}
|
||||
|
||||
// ... because the initialization function told the Environment to store the
|
||||
// ... because the initialization function told the Realm to store the
|
||||
// BindingData object:
|
||||
void InitializeHttpParser(Local<Object> target,
|
||||
Local<Value> unused,
|
||||
@@ -710,11 +752,13 @@ any resources owned by it, e.g. memory or libuv requests/handles.
|
||||
|
||||
#### Cleanup hooks
|
||||
|
||||
Cleanup hooks are provided that run before the [`Environment`][]
|
||||
is destroyed. They can be added and removed through by using
|
||||
Cleanup hooks are provided that run before the [`Environment`][] or the
|
||||
[`Realm`][] is destroyed. They can be added and removed by using
|
||||
`env->AddCleanupHook(callback, hint);` and
|
||||
`env->RemoveCleanupHook(callback, hint);`, where callback takes a `void* hint`
|
||||
argument.
|
||||
`env->RemoveCleanupHook(callback, hint);`, or
|
||||
`realm->AddCleanupHook(callback, hint);` and
|
||||
`realm->RemoveCleanupHook(callback, hint);` respectively, where callback takes
|
||||
a `void* hint` argument.
|
||||
|
||||
Inside these cleanup hooks, new asynchronous operations _may_ be started on the
|
||||
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
|
||||
Node.js, and most classes that are associated with JavaScript objects are
|
||||
subclasses of it. It is defined in [`base_object.h`][].
|
||||
|
||||
Every `BaseObject` is associated with one [`Environment`][] and one
|
||||
Every `BaseObject` is associated with one [`Realm`][] and one
|
||||
`v8::Object`. The `v8::Object` needs to have at least one [internal field][]
|
||||
that is used for storing the pointer to the C++ object. In order to ensure this,
|
||||
the V8 `SetInternalFieldCount()` function is usually used when setting up the
|
||||
@@ -1038,6 +1082,7 @@ static void GetUserInfo(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
[C++ coding style]: ../doc/contributing/cpp-style-guide.md
|
||||
[Callback scopes]: #callback-scopes
|
||||
[ECMAScript realm]: https://tc39.es/ecma262/#sec-code-realms
|
||||
[JavaScript value handles]: #js-handles
|
||||
[N-API]: https://nodejs.org/api/n-api.html
|
||||
[`BaseObject`]: #baseobject
|
||||
@@ -1050,7 +1095,9 @@ static void GetUserInfo(const FunctionCallbackInfo<Value>& args) {
|
||||
[`Local`]: #local-handles
|
||||
[`MakeCallback()`]: #makecallback
|
||||
[`MessagePort`]: https://nodejs.org/api/worker_threads.html#worker_threads_class_messageport
|
||||
[`Realm`]: #realm
|
||||
[`ReqWrap`]: #reqwrap
|
||||
[`ShadowRealm`]: https://github.com/tc39/proposal-shadowrealm
|
||||
[`async_hooks` module]: https://nodejs.org/api/async_hooks.html
|
||||
[`async_wrap.h`]: async_wrap.h
|
||||
[`base_object.h`]: base_object.h
|
||||
|
||||
Reference in New Issue
Block a user