diff options
author | Joyee Cheung <joyeec9h3@gmail.com> | 2022-03-24 16:37:08 +0300 |
---|---|---|
committer | Joyee Cheung <joyeec9h3@gmail.com> | 2022-03-31 14:29:12 +0300 |
commit | 37aee80643822c8c9ff35c906d034ecc8fc448d5 (patch) | |
tree | 65a9107f2ed3b7e4cdaf38936a1df65ccd25a587 /src/node_snapshotable.cc | |
parent | 8a297ba3a0aa39afb7c84fceee4accff609b7cfe (diff) |
build: add --node-snapshot-main configure option
This adds a --build-snapshot runtime option which is currently only
supported by the node_mksnapshot binary, and a --node-snapshot-main
configure option that makes use it to run a custom script when
building the embedded snapshot. The idea is to have this experimental
feature in core as a configure-time feature for now, and investigate
the renaming V8 bugs before we make it available to more users via
making it a runtime option.
PR-URL: https://github.com/nodejs/node/pull/42466
Reviewed-By: Darshan Sen <raisinten@gmail.com>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Khaidi Chu <i@2333.moe>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Diffstat (limited to 'src/node_snapshotable.cc')
-rw-r--r-- | src/node_snapshotable.cc | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc index 71b025df81e..327246743bb 100644 --- a/src/node_snapshotable.cc +++ b/src/node_snapshotable.cc @@ -18,12 +18,18 @@ namespace node { using v8::Context; +using v8::Function; +using v8::FunctionCallbackInfo; using v8::HandleScope; using v8::Isolate; using v8::Local; +using v8::MaybeLocal; using v8::Object; +using v8::ScriptCompiler; +using v8::ScriptOrigin; using v8::SnapshotCreator; using v8::StartupData; +using v8::String; using v8::TryCatch; using v8::Value; @@ -130,16 +136,36 @@ void SnapshotBuilder::Generate(SnapshotData* out, nullptr, node::EnvironmentFlags::kDefaultFlags, {}); + // TODO(joyeecheung): run env->InitializeInspector({}) here. // Run scripts in lib/internal/bootstrap/ { TryCatch bootstrapCatch(isolate); - v8::MaybeLocal<Value> result = env->RunBootstrapping(); + MaybeLocal<Value> result = env->RunBootstrapping(); if (bootstrapCatch.HasCaught()) { PrintCaughtException(isolate, context, bootstrapCatch); } result.ToLocalChecked(); } + // If --build-snapshot is true, lib/internal/main/mksnapshot.js would be + // loaded via LoadEnvironment() to execute process.argv[1] as the entry + // point (we currently only support this kind of entry point, but we + // could also explore snapshotting other kinds of execution modes + // in the future). + if (per_process::cli_options->build_snapshot) { + TryCatch bootstrapCatch(isolate); + // TODO(joyeecheung): we could use the result for something special, + // like setting up initializers that should be invoked at snapshot + // dehydration. + MaybeLocal<Value> result = + LoadEnvironment(env, StartExecutionCallback{}); + if (bootstrapCatch.HasCaught()) { + PrintCaughtException(isolate, context, bootstrapCatch); + } + result.ToLocalChecked(); + // TODO(joyeecheung): run SpinEventLoop here. + } + if (per_process::enabled_debug_list.enabled(DebugCategory::MKSNAPSHOT)) { env->PrintAllBaseObjects(); printf("Environment = %p\n", env); @@ -309,4 +335,57 @@ void SerializeBindingData(Environment* env, }); } +namespace mksnapshot { + +static void CompileSnapshotMain(const FunctionCallbackInfo<Value>& args) { + CHECK(args[0]->IsString()); + Local<String> filename = args[0].As<String>(); + Local<String> source = args[1].As<String>(); + Isolate* isolate = args.GetIsolate(); + Local<Context> context = isolate->GetCurrentContext(); + ScriptOrigin origin(isolate, filename, 0, 0, true); + // TODO(joyeecheung): do we need all of these? Maybe we would want a less + // internal version of them. + std::vector<Local<String>> parameters = { + FIXED_ONE_BYTE_STRING(isolate, "require"), + FIXED_ONE_BYTE_STRING(isolate, "__filename"), + FIXED_ONE_BYTE_STRING(isolate, "__dirname"), + }; + ScriptCompiler::Source script_source(source, origin); + Local<Function> fn; + if (ScriptCompiler::CompileFunctionInContext(context, + &script_source, + parameters.size(), + parameters.data(), + 0, + nullptr, + ScriptCompiler::kEagerCompile) + .ToLocal(&fn)) { + args.GetReturnValue().Set(fn); + } +} + +static void Initialize(Local<Object> target, + Local<Value> unused, + Local<Context> context, + void* priv) { + Environment* env = Environment::GetCurrent(context); + Isolate* isolate = context->GetIsolate(); + env->SetMethod(target, "compileSnapshotMain", CompileSnapshotMain); + target + ->Set(context, + FIXED_ONE_BYTE_STRING(isolate, "cleanups"), + v8::Array::New(isolate)) + .Check(); +} + +static void RegisterExternalReferences(ExternalReferenceRegistry* registry) { + registry->Register(CompileSnapshotMain); + registry->Register(MarkBootstrapComplete); +} +} // namespace mksnapshot } // namespace node + +NODE_MODULE_CONTEXT_AWARE_INTERNAL(mksnapshot, node::mksnapshot::Initialize) +NODE_MODULE_EXTERNAL_REFERENCE(mksnapshot, + node::mksnapshot::RegisterExternalReferences) |