Skip to content

Commit bce827e

Browse files
joyeecheungRafaelGSS
authored andcommittedSep 5, 2022
vm: make ContextifyContext template context-independent
Instead of creating an object template for every ContextifyContext, we now create one object template that can be reused by all contexts. The native pointer can be obtained through an embdder pointer field in the creation context of the receiver in the interceptors, because the interceptors are only meant to be invoked on the global object of the contextified contexts. This makes the ContextifyContext template context-independent and therefore snapshotable. PR-URL: #44252 Refs: #44014 Refs: #37476 Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
1 parent 65c1f40 commit bce827e

File tree

6 files changed

+162
-113
lines changed

6 files changed

+162
-113
lines changed
 

‎src/env.cc

+10-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "memory_tracker-inl.h"
77
#include "node_buffer.h"
88
#include "node_context_data.h"
9+
#include "node_contextify.h"
910
#include "node_errors.h"
1011
#include "node_internals.h"
1112
#include "node_options-inl.h"
@@ -429,6 +430,8 @@ void IsolateData::CreateProperties() {
429430
#undef V
430431

431432
// TODO(legendecas): eagerly create per isolate templates.
433+
set_contextify_global_template(
434+
contextify::ContextifyContext::CreateGlobalTemplate(isolate_));
432435
}
433436

434437
IsolateData::IsolateData(Isolate* isolate,
@@ -497,13 +500,19 @@ void TrackingTraceStateObserver::UpdateTraceCategoryState() {
497500

498501
void Environment::AssignToContext(Local<v8::Context> context,
499502
const ContextInfo& info) {
500-
ContextEmbedderTag::TagNodeContext(context);
501503
context->SetAlignedPointerInEmbedderData(ContextEmbedderIndex::kEnvironment,
502504
this);
503505
// Used to retrieve bindings
504506
context->SetAlignedPointerInEmbedderData(
505507
ContextEmbedderIndex::kBindingListIndex, &(this->bindings_));
506508

509+
// ContextifyContexts will update this to a pointer to the native object.
510+
context->SetAlignedPointerInEmbedderData(
511+
ContextEmbedderIndex::kContextifyContext, nullptr);
512+
513+
// This must not be done before other context fields are initialized.
514+
ContextEmbedderTag::TagNodeContext(context);
515+
507516
#if HAVE_INSPECTOR
508517
inspector_agent()->ContextCreated(context, info);
509518
#endif // HAVE_INSPECTOR

‎src/env.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,7 @@ class NoArrayBufferZeroFillScope {
349349
V(nistcurve_string, "nistCurve") \
350350
V(node_string, "node") \
351351
V(nsname_string, "nsname") \
352+
V(object_string, "Object") \
352353
V(ocsp_request_string, "OCSPRequest") \
353354
V(oncertcb_string, "oncertcb") \
354355
V(onchange_string, "onchange") \
@@ -477,6 +478,7 @@ class NoArrayBufferZeroFillScope {
477478
V(binding_data_ctor_template, v8::FunctionTemplate) \
478479
V(blob_constructor_template, v8::FunctionTemplate) \
479480
V(blocklist_constructor_template, v8::FunctionTemplate) \
481+
V(contextify_global_template, v8::ObjectTemplate) \
480482
V(compiled_fn_entry_template, v8::ObjectTemplate) \
481483
V(dir_instance_template, v8::ObjectTemplate) \
482484
V(fd_constructor_template, v8::ObjectTemplate) \
@@ -560,7 +562,6 @@ class NoArrayBufferZeroFillScope {
560562
V(primordials_safe_weak_set_prototype_object, v8::Object) \
561563
V(promise_hook_handler, v8::Function) \
562564
V(promise_reject_callback, v8::Function) \
563-
V(script_data_constructor_function, v8::Function) \
564565
V(snapshot_serialize_callback, v8::Function) \
565566
V(snapshot_deserialize_callback, v8::Function) \
566567
V(snapshot_deserialize_main, v8::Function) \

‎src/node_context_data.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,15 @@ namespace node {
3232
#define NODE_CONTEXT_ALLOW_CODE_GENERATION_FROM_STRINGS_INDEX 36
3333
#endif
3434

35+
#ifndef NODE_CONTEXT_CONTEXTIFY_CONTEXT_INDEX
36+
#define NODE_CONTEXT_CONTEXTIFY_CONTEXT_INDEX 37
37+
#endif
38+
3539
// NODE_CONTEXT_TAG must be greater than any embedder indexes so that a single
3640
// check on the number of embedder data fields can assure the presence of all
3741
// embedder indexes.
3842
#ifndef NODE_CONTEXT_TAG
39-
#define NODE_CONTEXT_TAG 37
43+
#define NODE_CONTEXT_TAG 38
4044
#endif
4145

4246
enum ContextEmbedderIndex {
@@ -46,6 +50,7 @@ enum ContextEmbedderIndex {
4650
kBindingListIndex = NODE_BINDING_LIST_INDEX,
4751
kAllowCodeGenerationFromStrings =
4852
NODE_CONTEXT_ALLOW_CODE_GENERATION_FROM_STRINGS_INDEX,
53+
kContextifyContext = NODE_CONTEXT_CONTEXTIFY_CONTEXT_INDEX,
4954
kContextTag = NODE_CONTEXT_TAG,
5055
};
5156

‎src/node_contextify.cc

+124-102
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,26 @@ ContextifyContext::ContextifyContext(
113113
const ContextOptions& options)
114114
: env_(env),
115115
microtask_queue_wrap_(options.microtask_queue_wrap) {
116-
MaybeLocal<Context> v8_context = CreateV8Context(env, sandbox_obj, options);
116+
Local<ObjectTemplate> object_template = env->contextify_global_template();
117+
if (object_template.IsEmpty()) {
118+
object_template = CreateGlobalTemplate(env->isolate());
119+
env->set_contextify_global_template(object_template);
120+
}
121+
122+
MicrotaskQueue* queue =
123+
microtask_queue()
124+
? microtask_queue().get()
125+
: env->isolate()->GetCurrentContext()->GetMicrotaskQueue();
117126

118-
// Allocation failure, maximum call stack size reached, termination, etc.
119-
if (v8_context.IsEmpty()) return;
127+
Local<Context> v8_context;
128+
if (!(CreateV8Context(env->isolate(), object_template, queue)
129+
.ToLocal(&v8_context)) ||
130+
!InitializeContext(v8_context, env, sandbox_obj, options)) {
131+
// Allocation failure, maximum call stack size reached, termination, etc.
132+
return;
133+
}
120134

121-
context_.Reset(env->isolate(), v8_context.ToLocalChecked());
135+
context_.Reset(env->isolate(), v8_context);
122136
context_.SetWeak(this, WeakCallback, WeakCallbackType::kParameter);
123137
env->AddCleanupHook(CleanupHook, this);
124138
}
@@ -140,49 +154,21 @@ void ContextifyContext::CleanupHook(void* arg) {
140154
delete self;
141155
}
142156

143-
144-
// This is an object that just keeps an internal pointer to this
145-
// ContextifyContext. It's passed to the NamedPropertyHandler. If we
146-
// pass the main JavaScript context object we're embedded in, then the
147-
// NamedPropertyHandler will store a reference to it forever and keep it
148-
// from getting gc'd.
149-
MaybeLocal<Object> ContextifyContext::CreateDataWrapper(Environment* env) {
150-
Local<Object> wrapper;
151-
if (!env->script_data_constructor_function()
152-
->NewInstance(env->context())
153-
.ToLocal(&wrapper)) {
154-
return MaybeLocal<Object>();
155-
}
156-
157-
wrapper->SetAlignedPointerInInternalField(ContextifyContext::kSlot, this);
158-
return wrapper;
159-
}
160-
161-
MaybeLocal<Context> ContextifyContext::CreateV8Context(
162-
Environment* env,
163-
Local<Object> sandbox_obj,
164-
const ContextOptions& options) {
165-
EscapableHandleScope scope(env->isolate());
166-
Local<FunctionTemplate> function_template =
167-
FunctionTemplate::New(env->isolate());
168-
169-
function_template->SetClassName(sandbox_obj->GetConstructorName());
157+
Local<ObjectTemplate> ContextifyContext::CreateGlobalTemplate(
158+
Isolate* isolate) {
159+
Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate);
170160

171161
Local<ObjectTemplate> object_template =
172162
function_template->InstanceTemplate();
173163

174-
Local<Object> data_wrapper;
175-
if (!CreateDataWrapper(env).ToLocal(&data_wrapper))
176-
return MaybeLocal<Context>();
177-
178164
NamedPropertyHandlerConfiguration config(
179165
PropertyGetterCallback,
180166
PropertySetterCallback,
181167
PropertyDescriptorCallback,
182168
PropertyDeleterCallback,
183169
PropertyEnumeratorCallback,
184170
PropertyDefinerCallback,
185-
data_wrapper,
171+
{},
186172
PropertyHandlerFlags::kHasNoSideEffect);
187173

188174
IndexedPropertyHandlerConfiguration indexed_config(
@@ -192,33 +178,48 @@ MaybeLocal<Context> ContextifyContext::CreateV8Context(
192178
IndexedPropertyDeleterCallback,
193179
PropertyEnumeratorCallback,
194180
IndexedPropertyDefinerCallback,
195-
data_wrapper,
181+
{},
196182
PropertyHandlerFlags::kHasNoSideEffect);
197183

198184
object_template->SetHandler(config);
199185
object_template->SetHandler(indexed_config);
200-
Local<Context> ctx = Context::New(
201-
env->isolate(),
202-
nullptr, // extensions
203-
object_template,
204-
{}, // global object
205-
{}, // deserialization callback
206-
microtask_queue() ?
207-
microtask_queue().get() :
208-
env->isolate()->GetCurrentContext()->GetMicrotaskQueue());
186+
187+
return object_template;
188+
}
189+
190+
MaybeLocal<Context> ContextifyContext::CreateV8Context(
191+
Isolate* isolate,
192+
Local<ObjectTemplate> object_template,
193+
MicrotaskQueue* queue) {
194+
EscapableHandleScope scope(isolate);
195+
196+
Local<Context> ctx = Context::New(isolate,
197+
nullptr, // extensions
198+
object_template,
199+
{}, // global object
200+
{}, // deserialization callback
201+
queue);
209202
if (ctx.IsEmpty()) return MaybeLocal<Context>();
210-
// Only partially initialize the context - the primordials are left out
211-
// and only initialized when necessary.
212-
if (InitializeContextRuntime(ctx).IsNothing()) {
213-
return MaybeLocal<Context>();
214-
}
215203

216-
if (ctx.IsEmpty()) {
217-
return MaybeLocal<Context>();
204+
return scope.Escape(ctx);
205+
}
206+
207+
bool ContextifyContext::InitializeContext(Local<Context> ctx,
208+
Environment* env,
209+
Local<Object> sandbox_obj,
210+
const ContextOptions& options) {
211+
HandleScope scope(env->isolate());
212+
213+
// This only initializes part of the context. The primordials are
214+
// only initilaized when needed because even deserializing them slows
215+
// things down significantly and they are only needed in rare occasions
216+
// in the vm contexts.
217+
if (InitializeContextRuntime(ctx).IsNothing()) {
218+
return false;
218219
}
219220

220-
Local<Context> context = env->context();
221-
ctx->SetSecurityToken(context->GetSecurityToken());
221+
Local<Context> main_context = env->context();
222+
ctx->SetSecurityToken(main_context->GetSecurityToken());
222223

223224
// We need to tie the lifetime of the sandbox object with the lifetime of
224225
// newly created context. We do this by making them hold references to each
@@ -227,11 +228,9 @@ MaybeLocal<Context> ContextifyContext::CreateV8Context(
227228
// directly in an Object, we instead hold onto the new context's global
228229
// object instead (which then has a reference to the context).
229230
ctx->SetEmbedderData(ContextEmbedderIndex::kSandboxObject, sandbox_obj);
230-
sandbox_obj->SetPrivate(context,
231-
env->contextify_global_private_symbol(),
232-
ctx->Global());
231+
sandbox_obj->SetPrivate(
232+
main_context, env->contextify_global_private_symbol(), ctx->Global());
233233

234-
Utf8Value name_val(env->isolate(), options.name);
235234
// Delegate the code generation validation to
236235
// node::ModifyCodeGenerationFromStrings.
237236
ctx->AllowCodeGenerationFromStrings(false);
@@ -240,30 +239,39 @@ MaybeLocal<Context> ContextifyContext::CreateV8Context(
240239
ctx->SetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration,
241240
options.allow_code_gen_wasm);
242241

242+
Utf8Value name_val(env->isolate(), options.name);
243243
ContextInfo info(*name_val);
244-
245244
if (!options.origin.IsEmpty()) {
246245
Utf8Value origin_val(env->isolate(), options.origin);
247246
info.origin = *origin_val;
248247
}
249248

249+
{
250+
Context::Scope context_scope(ctx);
251+
Local<String> ctor_name = sandbox_obj->GetConstructorName();
252+
if (!ctor_name->Equals(ctx, env->object_string()).FromMaybe(false) &&
253+
ctx->Global()
254+
->DefineOwnProperty(
255+
ctx,
256+
v8::Symbol::GetToStringTag(env->isolate()),
257+
ctor_name,
258+
static_cast<v8::PropertyAttribute>(v8::DontEnum))
259+
.IsNothing()) {
260+
return false;
261+
}
262+
}
263+
250264
env->AssignToContext(ctx, info);
251265

252-
return scope.Escape(ctx);
266+
// This should only be done after the initial initializations of the context
267+
// global object is finished.
268+
ctx->SetAlignedPointerInEmbedderData(ContextEmbedderIndex::kContextifyContext,
269+
this);
270+
return true;
253271
}
254272

255-
256273
void ContextifyContext::Init(Environment* env, Local<Object> target) {
257-
Isolate* isolate = env->isolate();
258274
Local<Context> context = env->context();
259-
260-
Local<FunctionTemplate> function_template =
261-
NewFunctionTemplate(isolate, nullptr);
262-
function_template->InstanceTemplate()->SetInternalFieldCount(
263-
ContextifyContext::kInternalFieldCount);
264-
env->set_script_data_constructor_function(
265-
function_template->GetFunction(env->context()).ToLocalChecked());
266-
267275
SetMethod(context, target, "makeContext", MakeContext);
268276
SetMethod(context, target, "isContext", IsContext);
269277
SetMethod(context, target, "compileFunction", CompileFunction);
@@ -274,6 +282,17 @@ void ContextifyContext::RegisterExternalReferences(
274282
registry->Register(MakeContext);
275283
registry->Register(IsContext);
276284
registry->Register(CompileFunction);
285+
registry->Register(PropertyGetterCallback);
286+
registry->Register(PropertySetterCallback);
287+
registry->Register(PropertyDescriptorCallback);
288+
registry->Register(PropertyDeleterCallback);
289+
registry->Register(PropertyEnumeratorCallback);
290+
registry->Register(PropertyDefinerCallback);
291+
registry->Register(IndexedPropertyGetterCallback);
292+
registry->Register(IndexedPropertySetterCallback);
293+
registry->Register(IndexedPropertyDescriptorCallback);
294+
registry->Register(IndexedPropertyDeleterCallback);
295+
registry->Register(IndexedPropertyDefinerCallback);
277296
}
278297

279298
// makeContext(sandbox, name, origin, strings, wasm);
@@ -323,8 +342,8 @@ void ContextifyContext::MakeContext(const FunctionCallbackInfo<Value>& args) {
323342
return;
324343
}
325344

326-
if (context_ptr->context().IsEmpty())
327-
return;
345+
Local<Context> new_context = context_ptr->context();
346+
if (new_context.IsEmpty()) return;
328347

329348
sandbox->SetPrivate(
330349
env->context(),
@@ -371,10 +390,20 @@ ContextifyContext* ContextifyContext::ContextFromContextifiedSandbox(
371390
// static
372391
template <typename T>
373392
ContextifyContext* ContextifyContext::Get(const PropertyCallbackInfo<T>& args) {
374-
Local<Value> data = args.Data();
393+
Local<Context> context;
394+
if (!args.This()->GetCreationContext().ToLocal(&context)) {
395+
return nullptr;
396+
}
397+
if (!ContextEmbedderTag::IsNodeContext(context)) {
398+
return nullptr;
399+
}
375400
return static_cast<ContextifyContext*>(
376-
data.As<Object>()->GetAlignedPointerFromInternalField(
377-
ContextifyContext::kSlot));
401+
context->GetAlignedPointerFromEmbedderData(
402+
ContextEmbedderIndex::kContextifyContext));
403+
}
404+
405+
bool ContextifyContext::IsStillInitializing(const ContextifyContext* ctx) {
406+
return ctx == nullptr || ctx->context_.IsEmpty();
378407
}
379408

380409
// static
@@ -384,8 +413,7 @@ void ContextifyContext::PropertyGetterCallback(
384413
ContextifyContext* ctx = ContextifyContext::Get(args);
385414

386415
// Still initializing
387-
if (ctx->context_.IsEmpty())
388-
return;
416+
if (IsStillInitializing(ctx)) return;
389417

390418
Local<Context> context = ctx->context();
391419
Local<Object> sandbox = ctx->sandbox();
@@ -413,8 +441,7 @@ void ContextifyContext::PropertySetterCallback(
413441
ContextifyContext* ctx = ContextifyContext::Get(args);
414442

415443
// Still initializing
416-
if (ctx->context_.IsEmpty())
417-
return;
444+
if (IsStillInitializing(ctx)) return;
418445

419446
Local<Context> context = ctx->context();
420447
PropertyAttribute attributes = PropertyAttribute::None;
@@ -466,8 +493,7 @@ void ContextifyContext::PropertyDescriptorCallback(
466493
ContextifyContext* ctx = ContextifyContext::Get(args);
467494

468495
// Still initializing
469-
if (ctx->context_.IsEmpty())
470-
return;
496+
if (IsStillInitializing(ctx)) return;
471497

472498
Local<Context> context = ctx->context();
473499

@@ -489,8 +515,7 @@ void ContextifyContext::PropertyDefinerCallback(
489515
ContextifyContext* ctx = ContextifyContext::Get(args);
490516

491517
// Still initializing
492-
if (ctx->context_.IsEmpty())
493-
return;
518+
if (IsStillInitializing(ctx)) return;
494519

495520
Local<Context> context = ctx->context();
496521
Isolate* isolate = context->GetIsolate();
@@ -550,8 +575,7 @@ void ContextifyContext::PropertyDeleterCallback(
550575
ContextifyContext* ctx = ContextifyContext::Get(args);
551576

552577
// Still initializing
553-
if (ctx->context_.IsEmpty())
554-
return;
578+
if (IsStillInitializing(ctx)) return;
555579

556580
Maybe<bool> success = ctx->sandbox()->Delete(ctx->context(), property);
557581

@@ -569,8 +593,7 @@ void ContextifyContext::PropertyEnumeratorCallback(
569593
ContextifyContext* ctx = ContextifyContext::Get(args);
570594

571595
// Still initializing
572-
if (ctx->context_.IsEmpty())
573-
return;
596+
if (IsStillInitializing(ctx)) return;
574597

575598
Local<Array> properties;
576599

@@ -587,8 +610,7 @@ void ContextifyContext::IndexedPropertyGetterCallback(
587610
ContextifyContext* ctx = ContextifyContext::Get(args);
588611

589612
// Still initializing
590-
if (ctx->context_.IsEmpty())
591-
return;
613+
if (IsStillInitializing(ctx)) return;
592614

593615
ContextifyContext::PropertyGetterCallback(
594616
Uint32ToName(ctx->context(), index), args);
@@ -602,8 +624,7 @@ void ContextifyContext::IndexedPropertySetterCallback(
602624
ContextifyContext* ctx = ContextifyContext::Get(args);
603625

604626
// Still initializing
605-
if (ctx->context_.IsEmpty())
606-
return;
627+
if (IsStillInitializing(ctx)) return;
607628

608629
ContextifyContext::PropertySetterCallback(
609630
Uint32ToName(ctx->context(), index), value, args);
@@ -616,8 +637,7 @@ void ContextifyContext::IndexedPropertyDescriptorCallback(
616637
ContextifyContext* ctx = ContextifyContext::Get(args);
617638

618639
// Still initializing
619-
if (ctx->context_.IsEmpty())
620-
return;
640+
if (IsStillInitializing(ctx)) return;
621641

622642
ContextifyContext::PropertyDescriptorCallback(
623643
Uint32ToName(ctx->context(), index), args);
@@ -631,8 +651,7 @@ void ContextifyContext::IndexedPropertyDefinerCallback(
631651
ContextifyContext* ctx = ContextifyContext::Get(args);
632652

633653
// Still initializing
634-
if (ctx->context_.IsEmpty())
635-
return;
654+
if (IsStillInitializing(ctx)) return;
636655

637656
ContextifyContext::PropertyDefinerCallback(
638657
Uint32ToName(ctx->context(), index), desc, args);
@@ -645,8 +664,7 @@ void ContextifyContext::IndexedPropertyDeleterCallback(
645664
ContextifyContext* ctx = ContextifyContext::Get(args);
646665

647666
// Still initializing
648-
if (ctx->context_.IsEmpty())
649-
return;
667+
if (IsStillInitializing(ctx)) return;
650668

651669
Maybe<bool> success = ctx->sandbox()->Delete(ctx->context(), index);
652670

@@ -891,8 +909,8 @@ void ContextifyScript::RunInContext(const FunctionCallbackInfo<Value>& args) {
891909
bool break_on_first_line = args[4]->IsTrue();
892910

893911
// Do the eval within the context
894-
Context::Scope context_scope(context);
895-
EvalMachine(env,
912+
EvalMachine(context,
913+
env,
896914
timeout,
897915
display_errors,
898916
break_on_sigint,
@@ -901,13 +919,16 @@ void ContextifyScript::RunInContext(const FunctionCallbackInfo<Value>& args) {
901919
args);
902920
}
903921

904-
bool ContextifyScript::EvalMachine(Environment* env,
922+
bool ContextifyScript::EvalMachine(Local<Context> context,
923+
Environment* env,
905924
const int64_t timeout,
906925
const bool display_errors,
907926
const bool break_on_sigint,
908927
const bool break_on_first_line,
909928
std::shared_ptr<MicrotaskQueue> mtask_queue,
910929
const FunctionCallbackInfo<Value>& args) {
930+
Context::Scope context_scope(context);
931+
911932
if (!env->can_call_into_js())
912933
return false;
913934
if (!ContextifyScript::InstanceOf(env, args.Holder())) {
@@ -916,6 +937,7 @@ bool ContextifyScript::EvalMachine(Environment* env,
916937
"Script methods can only be called on script instances.");
917938
return false;
918939
}
940+
919941
TryCatchScope try_catch(env);
920942
Isolate::SafeForTerminationScope safe_for_termination(env->isolate());
921943
ContextifyScript* wrapped_script;
@@ -934,7 +956,7 @@ bool ContextifyScript::EvalMachine(Environment* env,
934956
bool timed_out = false;
935957
bool received_signal = false;
936958
auto run = [&]() {
937-
MaybeLocal<Value> result = script->Run(env->context());
959+
MaybeLocal<Value> result = script->Run(context);
938960
if (!result.IsEmpty() && mtask_queue)
939961
mtask_queue->PerformCheckpoint(env->isolate());
940962
return result;

‎src/node_contextify.h

+14-7
Original file line numberDiff line numberDiff line change
@@ -43,17 +43,20 @@ struct ContextOptions {
4343

4444
class ContextifyContext {
4545
public:
46-
enum InternalFields { kSlot, kInternalFieldCount };
4746
ContextifyContext(Environment* env,
4847
v8::Local<v8::Object> sandbox_obj,
4948
const ContextOptions& options);
5049
~ContextifyContext();
5150
static void CleanupHook(void* arg);
5251

53-
v8::MaybeLocal<v8::Object> CreateDataWrapper(Environment* env);
54-
v8::MaybeLocal<v8::Context> CreateV8Context(Environment* env,
55-
v8::Local<v8::Object> sandbox_obj,
56-
const ContextOptions& options);
52+
static v8::MaybeLocal<v8::Context> CreateV8Context(
53+
v8::Isolate* isolate,
54+
v8::Local<v8::ObjectTemplate> object_template,
55+
v8::MicrotaskQueue* queue);
56+
bool InitializeContext(v8::Local<v8::Context> ctx,
57+
Environment* env,
58+
v8::Local<v8::Object> sandbox_obj,
59+
const ContextOptions& options);
5760
static void Init(Environment* env, v8::Local<v8::Object> target);
5861
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
5962

@@ -83,11 +86,14 @@ class ContextifyContext {
8386
return microtask_queue_wrap_->microtask_queue();
8487
}
8588

86-
8789
template <typename T>
8890
static ContextifyContext* Get(const v8::PropertyCallbackInfo<T>& args);
8991

92+
static v8::Local<v8::ObjectTemplate> CreateGlobalTemplate(
93+
v8::Isolate* isolate);
94+
9095
private:
96+
static bool IsStillInitializing(const ContextifyContext* ctx);
9197
static void MakeContext(const v8::FunctionCallbackInfo<v8::Value>& args);
9298
static void IsContext(const v8::FunctionCallbackInfo<v8::Value>& args);
9399
static void CompileFunction(
@@ -150,7 +156,8 @@ class ContextifyScript : public BaseObject {
150156
static bool InstanceOf(Environment* env, const v8::Local<v8::Value>& args);
151157
static void CreateCachedData(const v8::FunctionCallbackInfo<v8::Value>& args);
152158
static void RunInContext(const v8::FunctionCallbackInfo<v8::Value>& args);
153-
static bool EvalMachine(Environment* env,
159+
static bool EvalMachine(v8::Local<v8::Context> context,
160+
Environment* env,
154161
const int64_t timeout,
155162
const bool display_errors,
156163
const bool break_on_sigint,

‎src/node_external_reference.h

+6-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,12 @@ class ExternalReferenceRegistry {
3030
V(v8::GenericNamedPropertyDeleterCallback) \
3131
V(v8::GenericNamedPropertyEnumeratorCallback) \
3232
V(v8::GenericNamedPropertyQueryCallback) \
33-
V(v8::GenericNamedPropertySetterCallback)
33+
V(v8::GenericNamedPropertySetterCallback) \
34+
V(v8::IndexedPropertySetterCallback) \
35+
V(v8::IndexedPropertyDefinerCallback) \
36+
V(v8::IndexedPropertyDeleterCallback) \
37+
V(v8::IndexedPropertyQueryCallback) \
38+
V(v8::IndexedPropertyDescriptorCallback)
3439

3540
#define V(ExternalReferenceType) \
3641
void Register(ExternalReferenceType addr) { RegisterT(addr); }

0 commit comments

Comments
 (0)
Please sign in to comment.