diff --git a/src/api/environment.cc b/src/api/environment.cc index 5c3756c75dd9f5..8c1f5aaff2a5e4 100644 --- a/src/api/environment.cc +++ b/src/api/environment.cc @@ -287,7 +287,7 @@ Environment* CreateEnvironment(IsolateData* isolate_data, Environment::kOwnsProcessState | Environment::kOwnsInspector)); env->InitializeLibuv(per_process::v8_is_profiling); - if (RunBootstrapping(env).IsEmpty()) { + if (env->RunBootstrapping().IsEmpty()) { return nullptr; } diff --git a/src/env.h b/src/env.h index f3d6ec4d474805..54442738bf8a19 100644 --- a/src/env.h +++ b/src/env.h @@ -809,6 +809,10 @@ class Environment : public MemoryRetainer { int InitializeInspector(inspector::ParentInspectorHandle* parent_handle); #endif + v8::MaybeLocal BootstrapInternalLoaders(); + v8::MaybeLocal BootstrapNode(); + v8::MaybeLocal RunBootstrapping(); + inline size_t async_callback_scope_depth() const; inline void PushAsyncCallbackScope(); inline void PopAsyncCallbackScope(); diff --git a/src/node.cc b/src/node.cc index 095ee53693dbbc..b3212a17fc3d7a 100644 --- a/src/node.cc +++ b/src/node.cc @@ -119,7 +119,6 @@ using options_parser::kAllowedInEnvironment; using options_parser::kDisallowedInEnvironment; using v8::Boolean; -using v8::Context; using v8::EscapableHandleScope; using v8::Exception; using v8::Function; @@ -271,99 +270,111 @@ void Environment::InitializeDiagnostics() { #endif } -MaybeLocal RunBootstrapping(Environment* env) { - CHECK(!env->has_run_bootstrapping_code()); - - EscapableHandleScope scope(env->isolate()); - Isolate* isolate = env->isolate(); - Local context = env->context(); - - - // Add a reference to the global object - Local global = context->Global(); - Local process = env->process_object(); - - // Setting global properties for the bootstrappers to use: - // - global - // Expose the global object as a property on itself - // (Allows you to set stuff on `global` from anywhere in JavaScript.) - global->Set(context, FIXED_ONE_BYTE_STRING(env->isolate(), "global"), global) - .Check(); - +MaybeLocal Environment::BootstrapInternalLoaders() { + EscapableHandleScope scope(isolate_); // Create binding loaders std::vector> loaders_params = { - env->process_string(), - FIXED_ONE_BYTE_STRING(isolate, "getLinkedBinding"), - FIXED_ONE_BYTE_STRING(isolate, "getInternalBinding"), - env->primordials_string()}; + process_string(), + FIXED_ONE_BYTE_STRING(isolate_, "getLinkedBinding"), + FIXED_ONE_BYTE_STRING(isolate_, "getInternalBinding"), + primordials_string()}; std::vector> loaders_args = { - process, - env->NewFunctionTemplate(binding::GetLinkedBinding) - ->GetFunction(context) + process_object(), + NewFunctionTemplate(binding::GetLinkedBinding) + ->GetFunction(context()) .ToLocalChecked(), - env->NewFunctionTemplate(binding::GetInternalBinding) - ->GetFunction(context) + NewFunctionTemplate(binding::GetInternalBinding) + ->GetFunction(context()) .ToLocalChecked(), - env->primordials()}; + primordials()}; // Bootstrap internal loaders - MaybeLocal loader_exports = ExecuteBootstrapper( - env, "internal/bootstrap/loaders", &loaders_params, &loaders_args); - if (loader_exports.IsEmpty()) { + Local loader_exports; + if (!ExecuteBootstrapper( + this, "internal/bootstrap/loaders", &loaders_params, &loaders_args) + .ToLocal(&loader_exports)) { return MaybeLocal(); } - - Local loader_exports_obj = - loader_exports.ToLocalChecked().As(); + CHECK(loader_exports->IsObject()); + Local loader_exports_obj = loader_exports.As(); Local internal_binding_loader = - loader_exports_obj->Get(context, env->internal_binding_string()) + loader_exports_obj->Get(context(), internal_binding_string()) .ToLocalChecked(); - env->set_internal_binding_loader(internal_binding_loader.As()); - + CHECK(internal_binding_loader->IsFunction()); + set_internal_binding_loader(internal_binding_loader.As()); Local require = - loader_exports_obj->Get(context, env->require_string()).ToLocalChecked(); - env->set_native_module_require(require.As()); + loader_exports_obj->Get(context(), require_string()).ToLocalChecked(); + CHECK(require->IsFunction()); + set_native_module_require(require.As()); + + return scope.Escape(loader_exports); +} + +MaybeLocal Environment::BootstrapNode() { + EscapableHandleScope scope(isolate_); + + Local global = context()->Global(); + // TODO(joyeecheung): this can be done in JS land now. + global->Set(context(), FIXED_ONE_BYTE_STRING(isolate_, "global"), global) + .Check(); // process, require, internalBinding, isMainThread, // ownsProcessState, primordials std::vector> node_params = { - env->process_string(), - env->require_string(), - env->internal_binding_string(), - FIXED_ONE_BYTE_STRING(isolate, "isMainThread"), - FIXED_ONE_BYTE_STRING(isolate, "ownsProcessState"), - env->primordials_string()}; + process_string(), + require_string(), + internal_binding_string(), + FIXED_ONE_BYTE_STRING(isolate_, "isMainThread"), + FIXED_ONE_BYTE_STRING(isolate_, "ownsProcessState"), + primordials_string()}; std::vector> node_args = { - process, - require, - internal_binding_loader, - Boolean::New(isolate, env->is_main_thread()), - Boolean::New(isolate, env->owns_process_state()), - env->primordials()}; + process_object(), + native_module_require(), + internal_binding_loader(), + Boolean::New(isolate_, is_main_thread()), + Boolean::New(isolate_, owns_process_state()), + primordials()}; MaybeLocal result = ExecuteBootstrapper( - env, "internal/bootstrap/node", &node_params, &node_args); + this, "internal/bootstrap/node", &node_params, &node_args); Local env_var_proxy; - if (!CreateEnvVarProxy(context, isolate, env->as_callback_data()) + if (!CreateEnvVarProxy(context(), isolate_, as_callback_data()) .ToLocal(&env_var_proxy) || - process - ->Set(env->context(), - FIXED_ONE_BYTE_STRING(env->isolate(), "env"), - env_var_proxy) - .IsNothing()) + process_object() + ->Set( + context(), FIXED_ONE_BYTE_STRING(isolate_, "env"), env_var_proxy) + .IsNothing()) { + return MaybeLocal(); + } + + return scope.EscapeMaybe(result); +} + +MaybeLocal Environment::RunBootstrapping() { + EscapableHandleScope scope(isolate_); + + CHECK(!has_run_bootstrapping_code()); + + if (BootstrapInternalLoaders().IsEmpty()) { + return MaybeLocal(); + } + + Local result; + if (!BootstrapNode().ToLocal(&result)) { return MaybeLocal(); + } // Make sure that no request or handle is created during bootstrap - // if necessary those should be done in pre-execution. // TODO(joyeecheung): print handles/requests before aborting - CHECK(env->req_wrap_queue()->IsEmpty()); - CHECK(env->handle_wrap_queue()->IsEmpty()); + CHECK(req_wrap_queue()->IsEmpty()); + CHECK(handle_wrap_queue()->IsEmpty()); - env->set_has_run_bootstrapping_code(true); + set_has_run_bootstrapping_code(true); - return scope.EscapeMaybe(result); + return scope.Escape(result); } void MarkBootstrapComplete(const FunctionCallbackInfo& args) { diff --git a/src/node_internals.h b/src/node_internals.h index 21625e60232bbe..d40375ee72602f 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -278,7 +278,6 @@ void DefineZlibConstants(v8::Local target); v8::Isolate* NewIsolate(v8::Isolate::CreateParams* params, uv_loop_t* event_loop, MultiIsolatePlatform* platform); -v8::MaybeLocal RunBootstrapping(Environment* env); v8::MaybeLocal StartExecution(Environment* env, const char* main_script_id); v8::MaybeLocal GetPerContextExports(v8::Local context); diff --git a/src/node_main_instance.cc b/src/node_main_instance.cc index d724f392cda64c..5c84dd64e6fa64 100644 --- a/src/node_main_instance.cc +++ b/src/node_main_instance.cc @@ -205,7 +205,7 @@ std::unique_ptr NodeMainInstance::CreateMainEnvironment( return env; } - if (RunBootstrapping(env.get()).IsEmpty()) { + if (env->RunBootstrapping().IsEmpty()) { *exit_code = 1; } diff --git a/src/node_worker.cc b/src/node_worker.cc index 239e71c56f7967..a98b81065932df 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -271,7 +271,7 @@ void Worker::Run() { HandleScope handle_scope(isolate_); AsyncCallbackScope callback_scope(env_.get()); env_->async_hooks()->push_async_ids(1, 0); - if (!RunBootstrapping(env_.get()).IsEmpty()) { + if (!env_->RunBootstrapping().IsEmpty()) { CreateEnvMessagePort(env_.get()); if (is_stopped()) return; Debug(this, "Created message port for worker %llu", thread_id_);