mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
vm: include vm context in the embedded snapshot
Include a minimally initialized contextify context in the embedded snapshot. This paves the way for user-land vm context snapshots. PR-URL: https://github.com/nodejs/node/pull/44252 Refs: https://github.com/nodejs/node/issues/44014 Refs: https://github.com/nodejs/node/issues/37476 Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
This commit is contained in:
@@ -1002,7 +1002,8 @@ struct SnapshotData {
|
||||
enum class DataOwnership { kOwned, kNotOwned };
|
||||
|
||||
static const uint32_t kMagic = 0x143da19;
|
||||
static const SnapshotIndex kNodeBaseContextIndex = 0;
|
||||
static const SnapshotIndex kNodeVMContextIndex = 0;
|
||||
static const SnapshotIndex kNodeBaseContextIndex = kNodeVMContextIndex + 1;
|
||||
static const SnapshotIndex kNodeMainContextIndex = kNodeBaseContextIndex + 1;
|
||||
|
||||
DataOwnership data_ownership = DataOwnership::kOwned;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "node_errors.h"
|
||||
#include "node_external_reference.h"
|
||||
#include "node_internals.h"
|
||||
#include "node_snapshot_builder.h"
|
||||
#include "node_watchdog.h"
|
||||
#include "util-inl.h"
|
||||
|
||||
@@ -118,6 +119,9 @@ ContextifyContext::ContextifyContext(
|
||||
object_template = CreateGlobalTemplate(env->isolate());
|
||||
env->set_contextify_global_template(object_template);
|
||||
}
|
||||
bool use_node_snapshot = per_process::cli_options->node_snapshot;
|
||||
const SnapshotData* snapshot_data =
|
||||
use_node_snapshot ? SnapshotBuilder::GetEmbeddedSnapshotData() : nullptr;
|
||||
|
||||
MicrotaskQueue* queue =
|
||||
microtask_queue()
|
||||
@@ -125,7 +129,7 @@ ContextifyContext::ContextifyContext(
|
||||
: env->isolate()->GetCurrentContext()->GetMicrotaskQueue();
|
||||
|
||||
Local<Context> v8_context;
|
||||
if (!(CreateV8Context(env->isolate(), object_template, queue)
|
||||
if (!(CreateV8Context(env->isolate(), object_template, snapshot_data, queue)
|
||||
.ToLocal(&v8_context)) ||
|
||||
!InitializeContext(v8_context, env, sandbox_obj, options)) {
|
||||
// Allocation failure, maximum call stack size reached, termination, etc.
|
||||
@@ -190,17 +194,28 @@ Local<ObjectTemplate> ContextifyContext::CreateGlobalTemplate(
|
||||
MaybeLocal<Context> ContextifyContext::CreateV8Context(
|
||||
Isolate* isolate,
|
||||
Local<ObjectTemplate> object_template,
|
||||
const SnapshotData* snapshot_data,
|
||||
MicrotaskQueue* queue) {
|
||||
EscapableHandleScope scope(isolate);
|
||||
|
||||
Local<Context> ctx = Context::New(isolate,
|
||||
nullptr, // extensions
|
||||
object_template,
|
||||
{}, // global object
|
||||
{}, // deserialization callback
|
||||
queue);
|
||||
if (ctx.IsEmpty()) return MaybeLocal<Context>();
|
||||
|
||||
Local<Context> ctx;
|
||||
if (snapshot_data == nullptr) {
|
||||
ctx = Context::New(isolate,
|
||||
nullptr, // extensions
|
||||
object_template,
|
||||
{}, // global object
|
||||
{}, // deserialization callback
|
||||
queue);
|
||||
if (ctx.IsEmpty()) return MaybeLocal<Context>();
|
||||
} else if (!Context::FromSnapshot(isolate,
|
||||
SnapshotData::kNodeVMContextIndex,
|
||||
{}, // deserialization callback
|
||||
nullptr, // extensions
|
||||
{}, // global object
|
||||
queue)
|
||||
.ToLocal(&ctx)) {
|
||||
return MaybeLocal<Context>();
|
||||
}
|
||||
return scope.Escape(ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,7 @@ class ContextifyContext {
|
||||
static v8::MaybeLocal<v8::Context> CreateV8Context(
|
||||
v8::Isolate* isolate,
|
||||
v8::Local<v8::ObjectTemplate> object_template,
|
||||
const SnapshotData* snapshot_data,
|
||||
v8::MicrotaskQueue* queue);
|
||||
bool InitializeContext(v8::Local<v8::Context> ctx,
|
||||
Environment* env,
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "env-inl.h"
|
||||
#include "node_blob.h"
|
||||
#include "node_builtins.h"
|
||||
#include "node_contextify.h"
|
||||
#include "node_errors.h"
|
||||
#include "node_external_reference.h"
|
||||
#include "node_file.h"
|
||||
@@ -32,6 +33,7 @@ using v8::HandleScope;
|
||||
using v8::Isolate;
|
||||
using v8::Local;
|
||||
using v8::Object;
|
||||
using v8::ObjectTemplate;
|
||||
using v8::ScriptCompiler;
|
||||
using v8::ScriptOrigin;
|
||||
using v8::SnapshotCreator;
|
||||
@@ -1031,6 +1033,19 @@ int SnapshotBuilder::Generate(SnapshotData* out,
|
||||
// The default context with only things created by V8.
|
||||
Local<Context> default_context = Context::New(isolate);
|
||||
|
||||
// The context used by the vm module.
|
||||
Local<Context> vm_context;
|
||||
{
|
||||
Local<ObjectTemplate> global_template =
|
||||
main_instance->isolate_data()->contextify_global_template();
|
||||
CHECK(!global_template.IsEmpty());
|
||||
if (!contextify::ContextifyContext::CreateV8Context(
|
||||
isolate, global_template, nullptr, nullptr)
|
||||
.ToLocal(&vm_context)) {
|
||||
return SNAPSHOT_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// The Node.js-specific context with primodials, can be used by workers
|
||||
// TODO(joyeecheung): investigate if this can be used by vm contexts
|
||||
// without breaking compatibility.
|
||||
@@ -1112,7 +1127,9 @@ int SnapshotBuilder::Generate(SnapshotData* out,
|
||||
// blob is created. So initialize all the contexts before adding them.
|
||||
// TODO(joyeecheung): figure out how to remove this restriction.
|
||||
creator.SetDefaultContext(default_context);
|
||||
size_t index = creator.AddContext(base_context);
|
||||
size_t index = creator.AddContext(vm_context);
|
||||
CHECK_EQ(index, SnapshotData::kNodeVMContextIndex);
|
||||
index = creator.AddContext(base_context);
|
||||
CHECK_EQ(index, SnapshotData::kNodeBaseContextIndex);
|
||||
index = creator.AddContext(main_context,
|
||||
{SerializeNodeContextInternalFields, env});
|
||||
|
||||
Reference in New Issue
Block a user