embedding: allow creating context within inspectable node::Environment
Checklist
-
make -j4 test
(UNIX), orvcbuild test
(Windows) passes -
tests and/or benchmarks are included -
documentation is changed or added -
commit message follows commit guidelines
NodeJS allow native addons that can access V8 environment through V8 api or through node
namespace. Currently there are two options to create v8::Context
: v8::Context::New
and node::NewContext
. Once created the embedder can create JavaScript code using v8::ScriptCompiler
. Unfortunately, this JS code cannot be inspected by node --inspect
option. The reason is that the internal handle of the v8::Context
does not have associated debug_context_id
and the inspector frontend is not notified for the creation of the new context. For example functions created in the new context through v8::ScriptCompiler::CompileFunctionInContext
would not have a location and their source would not be visible in the inspector. This might be the module's intended behavior.
However, C++ addons that compile JavaScript code operating in different context within the same isolate, might want to allow users to debug their code. This could only happen when a node::Environment
exists with an existing inspector agent client. Embedders can still write their own inspector agents in case of different types of embedding, but C++ addons should rely on the existing client provided by the --inspect
option.
This is a proposal for a solution to this problem. A C++ addon could create thin v8::Context
(similar to v8::Context::New
) using polymorphic variant of node::NewContext
or alternatively it can specify parameter to create full node::NewContext
(with initialization). In both cases, since an environment is provided, it can be assigned to new context which will allow:
- preview of any compiled code within that context in the inspector (the new context is reported to the inspector with
ContextCreated
notification); -
v8::PrepareStackTraceCallback
does not modify stack traces for contexts that are not assigned to annode::Environment
; Embedder could potentially fix this by assign new callback, but the callback is assigned to an isolate and the current isolate might (and almost always will be) the node's isolate, thus rendering large part of the node's internal unusable (i.e. it is bad solution); With the new feature the embedder does not need to do that. -
node_contextify
is the way to create new context within nodejs's JavaScript environment. However, it is difficult (not impossible though) for C++ addon torequire('vm')
and the newly created context will have global based on some innerv8::FunctionTemplate
. C++ addons and other embedders might need to be able to createv8::Context
with an existingv8::ObjectTemplate
and still compile inspectable code.
A more elaborate feature could be later implemented to handle situations where more than one node::Environment
with an inspector agent exists for the same isolate, or to handle debugging code within a node::MultiIsolatePlatform
, etc. However, currently for C++ addons, this solution is better, because they will operate within only one node::Environment
, and the solution does not require any changes to an existing functions, or any additional memory.