summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoyee Cheung <joyeec9h3@gmail.com>2019-01-15 23:12:21 +0800
committerJoyee Cheung <joyeec9h3@gmail.com>2019-01-30 21:03:17 +0800
commit6967f91368cbb9cad3877ee59874cc83ccef4653 (patch)
tree2a7bae3359725c21df01aa31f266d6c79a2b7d35 /src
parentfeebdc5bc5a44779069a2269f4d3f15d4e36a277 (diff)
downloadandroid-node-v8-6967f91368cbb9cad3877ee59874cc83ccef4653.tar.gz
android-node-v8-6967f91368cbb9cad3877ee59874cc83ccef4653.tar.bz2
android-node-v8-6967f91368cbb9cad3877ee59874cc83ccef4653.zip
process: split execution into main scripts
This patch splits the execution mode selection from the environment setup in `lib/internal/bootstrap/node.js`, and split the entry point of different execution mode into main scripts under `lib/internal/main`: - `check_syntax.js`: used when `-c`/`--check` which only checks the syntax of the input instead of executing it. - `eval_stdin.js`: used when `-e` is passed without value and stdin is not a TTY (e.g. something is piped). - `eval_string`: used when `-e` is passed along with a string argument - `inspect.js`: for `node inspect`/`node debug` - `print_bash_completion.js`: for `--completion-bash` - `print_help.js`: for `--help` - `prof_process.js`: for `--prof-process` - `repl.js`: for the REPL - `run_main_module.js`: used when a main module is passed - `run_third_party_main.js`: for the legacy `_third_party_main.js` support - `worker_thread.js`: for workers This makes the entry points easier to navigate and paves the way for customized v8 snapshots (that do not need to deserialize execution mode setup) and better embedder APIs. As an example, after this patch, for the most common case where Node.js executes a user module as an entry point, it essentially goes through: - `lib/internal/per_context.js` to setup the v8 Context (which is also run when setting up contexts for the `vm` module) - `lib/internal/bootstrap/loaders.js` to set up internal binding and builtin module loaders (that are separate from the loaders accessible in the user land). - `lib/internal/bootstrap/node.js`: to set up the rest of the environment, including various globals and the process object - `lib/internal/main/run_main_module.js`: which is selected from C++ to prepare execution of the user module. This patch also removes `NativeModuleLoader::CompileAndCall` and exposes `NativeModuleLoader::LookupAndCompile` directly so that we can handle syntax errors and runtime errors of bootstrap scripts differently. PR-URL: https://github.com/nodejs/node/pull/25667 Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'src')
-rw-r--r--src/env.cc13
-rw-r--r--src/env.h26
-rw-r--r--src/node.cc216
-rw-r--r--src/node_internals.h5
-rw-r--r--src/node_native_module.cc20
-rw-r--r--src/node_native_module.h24
-rw-r--r--src/node_worker.cc12
7 files changed, 192 insertions, 124 deletions
diff --git a/src/env.cc b/src/env.cc
index 78ed42f89a..8ecab92df7 100644
--- a/src/env.cc
+++ b/src/env.cc
@@ -332,9 +332,20 @@ void Environment::Start(bool start_profiler_idle_notifier) {
uv_key_set(&thread_local_env, this);
}
-MaybeLocal<Object> Environment::CreateProcessObject(
+MaybeLocal<Object> Environment::ProcessCliArgs(
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args) {
+ if (args.size() > 1) {
+ std::string first_arg = args[1];
+ if (first_arg == "inspect") {
+ execution_mode_ = ExecutionMode::kInspect;
+ } else if (first_arg == "debug") {
+ execution_mode_ = ExecutionMode::kDebug;
+ } else if (first_arg != "-") {
+ execution_mode_ = ExecutionMode::kRunMainModule;
+ }
+ }
+
if (*TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(
TRACING_CATEGORY_NODE1(environment)) != 0) {
auto traced_value = tracing::TracedValue::Create();
diff --git a/src/env.h b/src/env.h
index 2fab688fc8..139694104e 100644
--- a/src/env.h
+++ b/src/env.h
@@ -315,7 +315,7 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
V(write_host_object_string, "_writeHostObject") \
V(write_queue_size_string, "writeQueueSize") \
V(x_forwarded_string, "x-forwarded-for") \
- V(zero_return_string, "ZERO_RETURN") \
+ V(zero_return_string, "ZERO_RETURN")
#define ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V) \
V(as_external, v8::External) \
@@ -355,11 +355,13 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
V(http2session_on_stream_trailers_function, v8::Function) \
V(http2settings_constructor_template, v8::ObjectTemplate) \
V(http2stream_constructor_template, v8::ObjectTemplate) \
+ V(internal_binding_loader, v8::Function) \
V(immediate_callback_function, v8::Function) \
V(inspector_console_extension_installer, v8::Function) \
V(libuv_stream_wrap_ctor_template, v8::FunctionTemplate) \
V(message_port, v8::Object) \
V(message_port_constructor_template, v8::FunctionTemplate) \
+ V(native_module_require, v8::Function) \
V(performance_entry_callback, v8::Function) \
V(performance_entry_template, v8::Function) \
V(pipe_constructor_template, v8::FunctionTemplate) \
@@ -371,7 +373,6 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2;
V(script_data_constructor_function, v8::Function) \
V(secure_context_constructor_template, v8::FunctionTemplate) \
V(shutdown_wrap_template, v8::ObjectTemplate) \
- V(start_execution_function, v8::Function) \
V(tcp_constructor_template, v8::FunctionTemplate) \
V(tick_callback_function, v8::Function) \
V(timers_callback_function, v8::Function) \
@@ -611,7 +612,7 @@ class Environment {
~Environment();
void Start(bool start_profiler_idle_notifier);
- v8::MaybeLocal<v8::Object> CreateProcessObject(
+ v8::MaybeLocal<v8::Object> ProcessCliArgs(
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args);
@@ -928,6 +929,24 @@ class Environment {
inline std::shared_ptr<EnvironmentOptions> options();
inline std::shared_ptr<HostPort> inspector_host_port();
+ enum class ExecutionMode {
+ kDefault,
+ kInspect, // node inspect
+ kDebug, // node debug
+ kPrintHelp, // node --help
+ kPrintBashCompletion, // node --completion-bash
+ kProfProcess, // node --prof-process
+ kEvalString, // node --eval without --interactive
+ kCheckSyntax, // node --check (incompatible with --eval)
+ kRepl,
+ kEvalStdin,
+ kRunMainModule
+ };
+
+ inline ExecutionMode execution_mode() { return execution_mode_; }
+
+ inline void set_execution_mode(ExecutionMode mode) { execution_mode_ = mode; }
+
private:
inline void CreateImmediate(native_immediate_callback cb,
void* data,
@@ -937,6 +956,7 @@ class Environment {
inline void ThrowError(v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
const char* errmsg);
+ ExecutionMode execution_mode_ = ExecutionMode::kDefault;
std::list<binding::DLib> loaded_addons_;
v8::Isolate* const isolate_;
IsolateData* const isolate_data_;
diff --git a/src/node.cc b/src/node.cc
index 881ace6e42..e67b16af83 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -100,6 +100,7 @@
#if defined(_MSC_VER)
#include <direct.h>
#include <io.h>
+#define STDIN_FILENO 0
#else
#include <pthread.h>
#include <sys/resource.h> // getrlimit, setrlimit
@@ -114,6 +115,7 @@ using v8::Array;
using v8::Boolean;
using v8::Context;
using v8::DEFAULT;
+using v8::EscapableHandleScope;
using v8::Exception;
using v8::Function;
using v8::FunctionCallbackInfo;
@@ -605,8 +607,20 @@ static MaybeLocal<Value> ExecuteBootstrapper(
const char* id,
std::vector<Local<String>>* parameters,
std::vector<Local<Value>>* arguments) {
- MaybeLocal<Value> ret = per_process::native_module_loader.CompileAndCall(
- env->context(), id, parameters, arguments, env);
+ EscapableHandleScope scope(env->isolate());
+ MaybeLocal<Function> maybe_fn =
+ per_process::native_module_loader.LookupAndCompile(
+ env->context(), id, parameters, env);
+
+ if (maybe_fn.IsEmpty()) {
+ return MaybeLocal<Value>();
+ }
+
+ Local<Function> fn = maybe_fn.ToLocalChecked();
+ MaybeLocal<Value> result = fn->Call(env->context(),
+ Undefined(env->isolate()),
+ arguments->size(),
+ arguments->data());
// If there was an error during bootstrap then it was either handled by the
// FatalException handler or it's unrecoverable (e.g. max call stack
@@ -615,44 +629,17 @@ static MaybeLocal<Value> ExecuteBootstrapper(
// There are only two ways to have a stack size > 1: 1) the user manually
// called MakeCallback or 2) user awaited during bootstrap, which triggered
// _tickCallback().
- if (ret.IsEmpty()) {
+ if (result.IsEmpty()) {
env->async_hooks()->clear_async_id_stack();
}
- return ret;
-}
-
-void LoadEnvironment(Environment* env) {
- RunBootstrapping(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);
- }
+ return scope.EscapeMaybe(result);
}
-void RunBootstrapping(Environment* env) {
+MaybeLocal<Value> RunBootstrapping(Environment* env) {
CHECK(!env->has_run_bootstrapping_code());
- env->set_has_run_bootstrapping_code(true);
- HandleScope handle_scope(env->isolate());
+ EscapableHandleScope scope(env->isolate());
Isolate* isolate = env->isolate();
Local<Context> context = env->context();
@@ -702,14 +689,24 @@ void RunBootstrapping(Environment* env) {
Boolean::New(isolate,
env->options()->expose_internals)};
- MaybeLocal<Value> loader_exports;
// Bootstrap internal loaders
- loader_exports = ExecuteBootstrapper(
+ MaybeLocal<Value> loader_exports = ExecuteBootstrapper(
env, "internal/bootstrap/loaders", &loaders_params, &loaders_args);
if (loader_exports.IsEmpty()) {
- return;
+ return MaybeLocal<Value>();
}
+ Local<Object> loader_exports_obj =
+ loader_exports.ToLocalChecked().As<Object>();
+ Local<Value> internal_binding_loader =
+ loader_exports_obj->Get(context, env->internal_binding_string())
+ .ToLocalChecked();
+ env->set_internal_binding_loader(internal_binding_loader.As<Function>());
+
+ Local<Value> require =
+ loader_exports_obj->Get(context, env->require_string()).ToLocalChecked();
+ env->set_native_module_require(require.As<Function>());
+
// process, loaderExports, isMainThread
std::vector<Local<String>> node_params = {
env->process_string(),
@@ -717,43 +714,107 @@ void RunBootstrapping(Environment* env) {
FIXED_ONE_BYTE_STRING(isolate, "isMainThread")};
std::vector<Local<Value>> node_args = {
process,
- loader_exports.ToLocalChecked(),
+ loader_exports_obj,
Boolean::New(isolate, env->is_main_thread())};
- Local<Value> start_execution;
- if (!ExecuteBootstrapper(
- env, "internal/bootstrap/node", &node_params, &node_args)
- .ToLocal(&start_execution)) {
- return;
- }
+ MaybeLocal<Value> result = ExecuteBootstrapper(
+ env, "internal/bootstrap/node", &node_params, &node_args);
- if (start_execution->IsFunction())
- env->set_start_execution_function(start_execution.As<Function>());
+ env->set_has_run_bootstrapping_code(true);
+
+ return scope.EscapeMaybe(result);
}
-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
- // resetting the handle while we're accessing the object through the Local<>.
- Local<Function> start_execution =
- Local<Function>::New(env->isolate(), env->start_execution_function());
- env->set_start_execution_function(Local<Function>());
-
- if (start_execution.IsEmpty()) return;
-
- Local<Value> 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<Function>.
- main_script_v = Undefined(env->isolate());
- } else {
- main_script_v = OneByteString(env->isolate(), main_script_id);
+void MarkBootstrapComplete(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ env->performance_state()->Mark(
+ performance::NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE);
+}
+
+MaybeLocal<Value> StartExecution(Environment* env, const char* main_script_id) {
+ EscapableHandleScope scope(env->isolate());
+ CHECK_NE(main_script_id, nullptr);
+
+ std::vector<Local<String>> parameters = {
+ env->process_string(),
+ env->require_string(),
+ env->internal_binding_string(),
+ FIXED_ONE_BYTE_STRING(env->isolate(), "markBootstrapComplete")};
+
+ std::vector<Local<Value>> arguments = {
+ env->process_object(),
+ env->native_module_require(),
+ env->internal_binding_loader(),
+ env->NewFunctionTemplate(MarkBootstrapComplete)
+ ->GetFunction(env->context())
+ .ToLocalChecked()};
+
+ MaybeLocal<Value> result =
+ ExecuteBootstrapper(env, main_script_id, &parameters, &arguments);
+ return scope.EscapeMaybe(result);
+}
+
+MaybeLocal<Value> StartMainThreadExecution(Environment* 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")) {
+ return StartExecution(env, "internal/main/run_third_party_main");
+ }
+
+ if (env->execution_mode() == Environment::ExecutionMode::kInspect ||
+ env->execution_mode() == Environment::ExecutionMode::kDebug) {
+ return StartExecution(env, "internal/main/inspect");
+ }
+
+ if (per_process::cli_options->print_help) {
+ env->set_execution_mode(Environment::ExecutionMode::kPrintHelp);
+ return StartExecution(env, "internal/main/print_help");
+ }
+
+ if (per_process::cli_options->print_bash_completion) {
+ env->set_execution_mode(Environment::ExecutionMode::kPrintBashCompletion);
+ return StartExecution(env, "internal/main/print_bash_completion");
+ }
+
+ if (env->options()->prof_process) {
+ env->set_execution_mode(Environment::ExecutionMode::kPrintBashCompletion);
+ return StartExecution(env, "internal/main/prof_process");
+ }
+
+ // -e/--eval without -i/--interactive
+ if (env->options()->has_eval_string && !env->options()->force_repl) {
+ env->set_execution_mode(Environment::ExecutionMode::kEvalString);
+ return StartExecution(env, "internal/main/eval_string");
+ }
+
+ if (env->options()->syntax_check_only) {
+ env->set_execution_mode(Environment::ExecutionMode::kCheckSyntax);
+ return StartExecution(env, "internal/main/check_syntax");
+ }
+
+ if (env->execution_mode() == Environment::ExecutionMode::kRunMainModule) {
+ return StartExecution(env, "internal/main/run_main_module");
+ }
+
+ if (env->options()->force_repl || uv_guess_handle(STDIN_FILENO) == UV_TTY) {
+ env->set_execution_mode(Environment::ExecutionMode::kRepl);
+ return StartExecution(env, "internal/main/repl");
}
- Local<Value> argv[] = {main_script_v};
- USE(start_execution->Call(
- env->context(), Undefined(env->isolate()), arraysize(argv), argv));
+ env->set_execution_mode(Environment::ExecutionMode::kEvalStdin);
+ return StartExecution(env, "internal/main/eval_stdin");
+}
+
+void LoadEnvironment(Environment* env) {
+ CHECK(env->is_main_thread());
+ // TODO(joyeecheung): Not all of the execution modes in
+ // StartMainThreadExecution() make sense for embedders. Pick the
+ // useful ones out, and allow embedders to customize the entry
+ // point more directly without using _third_party_main.js
+ if (!RunBootstrapping(env).IsEmpty()) {
+ USE(StartMainThreadExecution(env));
+ }
}
@@ -1180,7 +1241,7 @@ Environment* CreateEnvironment(IsolateData* isolate_data,
std::vector<std::string> exec_args(exec_argv, exec_argv + exec_argc);
Environment* env = new Environment(isolate_data, context);
env->Start(per_process::v8_is_profiling);
- env->CreateProcessObject(args, exec_args);
+ env->ProcessCliArgs(args, exec_args);
return env;
}
@@ -1220,7 +1281,7 @@ void FreePlatform(MultiIsolatePlatform* platform) {
Local<Context> NewContext(Isolate* isolate,
Local<ObjectTemplate> object_template) {
- auto context = Context::New(isolate, nullptr, object_template);
+ Local<Context> context = Context::New(isolate, nullptr, object_template);
if (context.IsEmpty()) return context;
HandleScope handle_scope(isolate);
@@ -1233,12 +1294,19 @@ Local<Context> NewContext(Isolate* isolate,
std::vector<Local<String>> parameters = {
FIXED_ONE_BYTE_STRING(isolate, "global")};
- std::vector<Local<Value>> arguments = {context->Global()};
- MaybeLocal<Value> result = per_process::native_module_loader.CompileAndCall(
- context, "internal/per_context", &parameters, &arguments, nullptr);
+ Local<Value> arguments[] = {context->Global()};
+ MaybeLocal<Function> maybe_fn =
+ per_process::native_module_loader.LookupAndCompile(
+ context, "internal/per_context", &parameters, nullptr);
+ if (maybe_fn.IsEmpty()) {
+ return Local<Context>();
+ }
+ Local<Function> fn = maybe_fn.ToLocalChecked();
+ MaybeLocal<Value> result =
+ fn->Call(context, Undefined(isolate), arraysize(arguments), arguments);
+ // Execution failed during context creation.
+ // TODO(joyeecheung): deprecate this signature and return a MaybeLocal.
if (result.IsEmpty()) {
- // Execution failed during context creation.
- // TODO(joyeecheung): deprecate this signature and return a MaybeLocal.
return Local<Context>();
}
}
@@ -1255,7 +1323,7 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data,
Context::Scope context_scope(context);
Environment env(isolate_data, context);
env.Start(per_process::v8_is_profiling);
- env.CreateProcessObject(args, exec_args);
+ env.ProcessCliArgs(args, exec_args);
#if HAVE_INSPECTOR && NODE_USE_V8_PLATFORM
CHECK(!env.inspector_agent()->IsListening());
diff --git a/src/node_internals.h b/src/node_internals.h
index 0d4fe74ebf..bf66c77e6f 100644
--- a/src/node_internals.h
+++ b/src/node_internals.h
@@ -268,8 +268,9 @@ bool SafeGetenv(const char* key, std::string* text);
void DefineZlibConstants(v8::Local<v8::Object> target);
-void RunBootstrapping(Environment* env);
-void StartExecution(Environment* env, const char* main_script_id);
+v8::MaybeLocal<v8::Value> RunBootstrapping(Environment* env);
+v8::MaybeLocal<v8::Value> 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 27456dd546..675495e34b 100644
--- a/src/node_native_module.cc
+++ b/src/node_native_module.cc
@@ -175,26 +175,6 @@ void NativeModuleLoader::CompileFunction(
}
}
-// TODO(joyeecheung): it should be possible to generate the argument names
-// from some special comments for the bootstrapper case.
-MaybeLocal<Value> NativeModuleLoader::CompileAndCall(
- Local<Context> context,
- const char* id,
- std::vector<Local<String>>* parameters,
- std::vector<Local<Value>>* arguments,
- Environment* optional_env) {
- Isolate* isolate = context->GetIsolate();
- MaybeLocal<Function> compiled =
- per_process::native_module_loader.LookupAndCompile(
- context, id, parameters, nullptr);
- if (compiled.IsEmpty()) {
- return MaybeLocal<Value>();
- }
- Local<Function> fn = compiled.ToLocalChecked().As<Function>();
- return fn->Call(
- context, v8::Null(isolate), arguments->size(), arguments->data());
-}
-
MaybeLocal<Function> NativeModuleLoader::CompileAsModule(Environment* env,
const char* id) {
std::vector<Local<String>> parameters = {env->exports_string(),
diff --git a/src/node_native_module.h b/src/node_native_module.h
index 62c417a0b6..be1fc92a76 100644
--- a/src/node_native_module.h
+++ b/src/node_native_module.h
@@ -42,20 +42,17 @@ class NativeModuleLoader {
// Returns config.gypi as a JSON string
v8::Local<v8::String> GetConfigString(v8::Isolate* isolate) const;
- // Run a script with JS source bundled inside the binary as if it's wrapped
- // in a function called with a null receiver and arguments specified in C++.
- // The returned value is empty if an exception is encountered.
- // JS code run with this method can assume that their top-level
- // declarations won't affect the global scope.
- v8::MaybeLocal<v8::Value> CompileAndCall(
+ bool Exists(const char* id);
+
+ // For bootstrappers optional_env may be a nullptr.
+ // If an exception is encountered (e.g. source code contains
+ // syntax error), the returned value is empty.
+ v8::MaybeLocal<v8::Function> LookupAndCompile(
v8::Local<v8::Context> context,
const char* id,
std::vector<v8::Local<v8::String>>* parameters,
- std::vector<v8::Local<v8::Value>>* arguments,
Environment* optional_env);
- bool Exists(const char* id);
-
private:
static void GetCacheUsage(const v8::FunctionCallbackInfo<v8::Value>& args);
// Passing ids of builtin module source code into JS land as
@@ -87,15 +84,6 @@ class NativeModuleLoader {
static v8::MaybeLocal<v8::Function> CompileAsModule(Environment* env,
const char* id);
- // For bootstrappers optional_env may be a nullptr.
- // If an exception is encountered (e.g. source code contains
- // syntax error), the returned value is empty.
- v8::MaybeLocal<v8::Function> LookupAndCompile(
- v8::Local<v8::Context> context,
- const char* id,
- std::vector<v8::Local<v8::String>>* parameters,
- Environment* optional_env);
-
NativeModuleRecordMap source_;
NativeModuleCacheMap code_cache_;
UnionBytes config_;
diff --git a/src/node_worker.cc b/src/node_worker.cc
index e5ba438bc1..4b78d65392 100644
--- a/src/node_worker.cc
+++ b/src/node_worker.cc
@@ -133,8 +133,8 @@ Worker::Worker(Environment* env,
env_->set_thread_id(thread_id_);
env_->Start(env->profiler_idle_notifier_started());
- env_->CreateProcessObject(std::vector<std::string>{},
- std::vector<std::string>{});
+ env_->ProcessCliArgs(std::vector<std::string>{},
+ std::vector<std::string>{});
// Done while on the parent thread
AddWorkerInspector(env, env_.get(), thread_id_, url_);
}
@@ -192,10 +192,10 @@ void Worker::Run() {
HandleScope handle_scope(isolate_);
Environment::AsyncCallbackScope callback_scope(env_.get());
env_->async_hooks()->push_async_ids(1, 0);
- RunBootstrapping(env_.get());
- // TODO(joyeecheung): create a main script for worker threads
- // that starts listening on the message port.
- StartExecution(env_.get(), nullptr);
+ if (!RunBootstrapping(env_.get()).IsEmpty()) {
+ USE(StartExecution(env_.get(), "internal/main/worker_thread"));
+ }
+
env_->async_hooks()->pop_async_id(1);
Debug(this, "Loaded environment for worker %llu", thread_id_);