From b5790b7b12bfd4ea82f2f810bc1fb2c9b5d823f7 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Wed, 28 Sep 2022 19:53:42 +0800 Subject: [PATCH] fixup! vm: make ContextifyContext a BaseObject This reverts commit b9042c87b60184a37d9c8674ec8c8b29b2a8ab5e. --- src/node_contextify.cc | 165 +++++++++++++++++++++-------------------- src/node_contextify.h | 9 ++- 2 files changed, 89 insertions(+), 85 deletions(-) diff --git a/src/node_contextify.cc b/src/node_contextify.cc index 25ea299d140e3c..04393e182ffba0 100644 --- a/src/node_contextify.cc +++ b/src/node_contextify.cc @@ -131,81 +131,7 @@ BaseObjectPtr ContextifyContext::New( // Allocation failure, maximum call stack size reached, termination, etc. return BaseObjectPtr(); } - - // This only initializes part of the context. The primordials are - // only initilaized when needed because even deserializing them slows - // things down significantly and they are only needed in rare occasions - // in the vm contexts. - if (InitializeContextRuntime(v8_context).IsNothing()) { - return BaseObjectPtr(); - } - - Local main_context = env->context(); - Local new_context_global = v8_context->Global(); - v8_context->SetSecurityToken(main_context->GetSecurityToken()); - - // We need to tie the lifetime of the sandbox object with the lifetime of - // newly created context. We do this by making them hold references to each - // other. The context can directly hold a reference to the sandbox as an - // embedder data field. The sandbox uses a private symbol to hold a reference - // to the ContextifyContext wrapper which in turn internally references - // the context from its constructor. - v8_context->SetEmbedderData(ContextEmbedderIndex::kSandboxObject, - sandbox_obj); - - // Delegate the code generation validation to - // node::ModifyCodeGenerationFromStrings. - v8_context->AllowCodeGenerationFromStrings(false); - v8_context->SetEmbedderData( - ContextEmbedderIndex::kAllowCodeGenerationFromStrings, - options.allow_code_gen_strings); - v8_context->SetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration, - options.allow_code_gen_wasm); - - Utf8Value name_val(env->isolate(), options.name); - ContextInfo info(*name_val); - if (!options.origin.IsEmpty()) { - Utf8Value origin_val(env->isolate(), options.origin); - info.origin = *origin_val; - } - - BaseObjectPtr result; - Local wrapper; - { - Context::Scope context_scope(v8_context); - Local ctor_name = sandbox_obj->GetConstructorName(); - if (!ctor_name->Equals(v8_context, env->object_string()).FromMaybe(false) && - new_context_global - ->DefineOwnProperty( - v8_context, - v8::Symbol::GetToStringTag(env->isolate()), - ctor_name, - static_cast(v8::DontEnum)) - .IsNothing()) { - return BaseObjectPtr(); - } - env->AssignToContext(v8_context, nullptr, info); - - if (!env->contextify_wrapper_template() - ->NewInstance(v8_context) - .ToLocal(&wrapper)) { - return BaseObjectPtr(); - } - - result = - MakeBaseObject(env, wrapper, v8_context, options); - // The only strong reference to the wrapper will come from the sandbox. - result->MakeWeak(); - } - - if (sandbox_obj - ->SetPrivate( - v8_context, env->contextify_context_private_symbol(), wrapper) - .IsNothing()) { - return BaseObjectPtr(); - } - - return result; + return New(v8_context, env, sandbox_obj, options); } void ContextifyContext::MemoryInfo(MemoryTracker* tracker) const { @@ -316,6 +242,89 @@ MaybeLocal ContextifyContext::CreateV8Context( return scope.Escape(ctx); } + +BaseObjectPtr ContextifyContext::New( + Local v8_context, + Environment* env, + Local sandbox_obj, + const ContextOptions& options) { + HandleScope scope(env->isolate()); + // This only initializes part of the context. The primordials are + // only initilaized when needed because even deserializing them slows + // things down significantly and they are only needed in rare occasions + // in the vm contexts. + if (InitializeContextRuntime(v8_context).IsNothing()) { + return BaseObjectPtr(); + } + + Local main_context = env->context(); + Local new_context_global = v8_context->Global(); + v8_context->SetSecurityToken(main_context->GetSecurityToken()); + + // We need to tie the lifetime of the sandbox object with the lifetime of + // newly created context. We do this by making them hold references to each + // other. The context can directly hold a reference to the sandbox as an + // embedder data field. The sandbox uses a private symbol to hold a reference + // to the ContextifyContext wrapper which in turn internally references + // the context from its constructor. + v8_context->SetEmbedderData(ContextEmbedderIndex::kSandboxObject, + sandbox_obj); + + // Delegate the code generation validation to + // node::ModifyCodeGenerationFromStrings. + v8_context->AllowCodeGenerationFromStrings(false); + v8_context->SetEmbedderData( + ContextEmbedderIndex::kAllowCodeGenerationFromStrings, + options.allow_code_gen_strings); + v8_context->SetEmbedderData(ContextEmbedderIndex::kAllowWasmCodeGeneration, + options.allow_code_gen_wasm); + + Utf8Value name_val(env->isolate(), options.name); + ContextInfo info(*name_val); + if (!options.origin.IsEmpty()) { + Utf8Value origin_val(env->isolate(), options.origin); + info.origin = *origin_val; + } + + BaseObjectPtr result; + Local wrapper; + { + Context::Scope context_scope(v8_context); + Local ctor_name = sandbox_obj->GetConstructorName(); + if (!ctor_name->Equals(v8_context, env->object_string()).FromMaybe(false) && + new_context_global + ->DefineOwnProperty( + v8_context, + v8::Symbol::GetToStringTag(env->isolate()), + ctor_name, + static_cast(v8::DontEnum)) + .IsNothing()) { + return BaseObjectPtr(); + } + env->AssignToContext(v8_context, nullptr, info); + + if (!env->contextify_wrapper_template() + ->NewInstance(v8_context) + .ToLocal(&wrapper)) { + return BaseObjectPtr(); + } + + result = + MakeBaseObject(env, wrapper, v8_context, options); + // The only strong reference to the wrapper will come from the sandbox. + result->MakeWeak(); + } + + if (sandbox_obj + ->SetPrivate( + v8_context, env->contextify_context_private_symbol(), wrapper) + .IsNothing()) { + return BaseObjectPtr(); + } + + return result; +} + void ContextifyContext::Init(Environment* env, Local target) { Local context = env->context(); SetMethod(context, target, "makeContext", MakeContext); @@ -387,12 +396,6 @@ void ContextifyContext::MakeContext(const FunctionCallbackInfo& args) { try_catch.ReThrow(); return; } - - if (context_ptr.get() == nullptr) { - return; - } - Local new_context = context_ptr->context(); - if (new_context.IsEmpty()) return; } diff --git a/src/node_contextify.h b/src/node_contextify.h index 9564b31a0123fa..208f759811aff9 100644 --- a/src/node_contextify.h +++ b/src/node_contextify.h @@ -56,15 +56,16 @@ class ContextifyContext : public BaseObject { static BaseObjectPtr New(Environment* env, v8::Local sandbox_obj, const ContextOptions& options); + // Initialize a context created from CreateV8Context() + static BaseObjectPtr New(v8::Local ctx, + Environment* env, + v8::Local sandbox_obj, + const ContextOptions& options); static v8::MaybeLocal CreateV8Context( v8::Isolate* isolate, v8::Local object_template, const SnapshotData* snapshot_data, v8::MicrotaskQueue* queue); - static bool InitializeContext(v8::Local ctx, - Environment* env, - v8::Local sandbox_obj, - const ContextOptions& options); static void Init(Environment* env, v8::Local target); static void RegisterExternalReferences(ExternalReferenceRegistry* registry);