From 2c7f4f474bfbb19b7ae6597112cca41141bf71a4 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Sun, 13 Jan 2019 23:44:09 +0800 Subject: process: allow StartExecution() to take a main script ID The idea is to allow the C++ layer to run arbitrary scripts as the main script. This paves the way for - cctest of the execution of Node.js instances - Earlier handling of per-process CLI options that affect execution modes (those usually do not make sense for the embedders). - Targets like mkcodecache or mksnapshot. Also moves the handling of `_third_party_main.js` into C++. PR-URL: https://github.com/nodejs/node/pull/25474 Reviewed-By: Anna Henningsen Reviewed-By: Minwoo Jung --- src/node.cc | 38 +++++++++++++++++++++++++++++++++++--- src/node_internals.h | 2 +- src/node_native_module.cc | 4 ++++ src/node_native_module.h | 2 ++ src/node_worker.cc | 6 ++++-- 5 files changed, 46 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/node.cc b/src/node.cc index 7a585646f6..0f66847244 100644 --- a/src/node.cc +++ b/src/node.cc @@ -647,7 +647,28 @@ static MaybeLocal ExecuteBootstrapper( void LoadEnvironment(Environment* env) { RunBootstrapping(env); - StartExecution(env); + + // To allow people to extend Node in different ways, this hook allows + // one to drop a file lib/_third_party_main.js into the build + // directory which will be executed instead of Node's normal loading. + if (per_process::native_module_loader.Exists("_third_party_main")) { + StartExecution(env, "_third_party_main"); + } else { + // TODO(joyeecheung): create different scripts for different + // execution modes: + // - `main_thread_main.js` when env->is_main_thread() + // - `worker_thread_main.js` when !env->is_main_thread() + // - `run_third_party_main.js` for `_third_party_main` + // - `inspect_main.js` for `node inspect` + // - `mkcodecache_main.js` for the code cache generator + // - `print_help_main.js` for --help + // - `bash_completion_main.js` for --completion-bash + // - `internal/v8_prof_processor` for --prof-process + // And leave bootstrap/node.js dedicated to the setup of the environment. + // We may want to move this switch out of LoadEnvironment, especially for + // the per-process options. + StartExecution(env, nullptr); + } } void RunBootstrapping(Environment* env) { @@ -724,7 +745,7 @@ void RunBootstrapping(Environment* env) { env->set_start_execution_function(start_execution.As()); } -void StartExecution(Environment* env) { +void StartExecution(Environment* env, const char* main_script_id) { HandleScope handle_scope(env->isolate()); // We have to use Local<>::New because of the optimized way in which we access // the object in the env->...() getters, which does not play well with @@ -734,8 +755,19 @@ void StartExecution(Environment* env) { env->set_start_execution_function(Local()); if (start_execution.IsEmpty()) return; + + Local main_script_v; + if (main_script_id == nullptr) { + // TODO(joyeecheung): make this mandatory - we may also create an overload + // for main_script that is a Local. + main_script_v = Undefined(env->isolate()); + } else { + main_script_v = OneByteString(env->isolate(), main_script_id); + } + + Local argv[] = {main_script_v}; USE(start_execution->Call( - env->context(), Undefined(env->isolate()), 0, nullptr)); + env->context(), Undefined(env->isolate()), arraysize(argv), argv)); } static void StartInspector(Environment* env, const char* path) { diff --git a/src/node_internals.h b/src/node_internals.h index 5dd0593f41..70c82dd2fc 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -369,7 +369,7 @@ bool SafeGetenv(const char* key, std::string* text); void DefineZlibConstants(v8::Local target); void RunBootstrapping(Environment* env); -void StartExecution(Environment* env); +void StartExecution(Environment* env, const char* main_script_id); } // namespace node diff --git a/src/node_native_module.cc b/src/node_native_module.cc index 1b1a5e8ec1..00775885d6 100644 --- a/src/node_native_module.cc +++ b/src/node_native_module.cc @@ -61,6 +61,10 @@ Local ToJsSet(Local context, return out; } +bool NativeModuleLoader::Exists(const char* id) { + return source_.find(id) != source_.end(); +} + void NativeModuleLoader::GetCacheUsage( const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); diff --git a/src/node_native_module.h b/src/node_native_module.h index 9a0afcc0b9..62c417a0b6 100644 --- a/src/node_native_module.h +++ b/src/node_native_module.h @@ -54,6 +54,8 @@ class NativeModuleLoader { std::vector>* arguments, Environment* optional_env); + bool Exists(const char* id); + private: static void GetCacheUsage(const v8::FunctionCallbackInfo& args); // Passing ids of builtin module source code into JS land as diff --git a/src/node_worker.cc b/src/node_worker.cc index 65d3b7297c..dab7945aae 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -185,8 +185,10 @@ void Worker::Run() { HandleScope handle_scope(isolate_); Environment::AsyncCallbackScope callback_scope(env_.get()); env_->async_hooks()->push_async_ids(1, 0); - // This loads the Node bootstrapping code. - LoadEnvironment(env_.get()); + RunBootstrapping(env_.get()); + // TODO(joyeecheung): create a main script for worker threads + // that starts listening on the message port. + StartExecution(env_.get(), nullptr); env_->async_hooks()->pop_async_id(1); Debug(this, "Loaded environment for worker %llu", thread_id_); -- cgit v1.2.3