mirror of
https://github.com/zebrajr/node.git
synced 2026-01-15 12:15:26 +00:00
bootstrap: generate bootstrapper arguments in BuiltinLoader
PR-URL: https://github.com/nodejs/node/pull/44488 Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
This commit is contained in:
@@ -456,11 +456,7 @@ MaybeLocal<Value> LoadEnvironment(
|
||||
env->set_main_utf16(std::move(main_utf16));
|
||||
Realm* realm = env->principal_realm();
|
||||
|
||||
// Arguments must match the parameters specified in
|
||||
// BuiltinLoader::LookupAndCompile().
|
||||
std::vector<Local<Value>> args = {realm->process_object(),
|
||||
realm->builtin_module_require()};
|
||||
return realm->ExecuteBootstrapper(name.c_str(), &args);
|
||||
return realm->ExecuteBootstrapper(name.c_str());
|
||||
});
|
||||
}
|
||||
|
||||
@@ -699,19 +695,11 @@ Maybe<bool> InitializePrimordials(Local<Context> context) {
|
||||
nullptr};
|
||||
|
||||
for (const char** module = context_files; *module != nullptr; module++) {
|
||||
// Arguments must match the parameters specified in
|
||||
// BuiltinLoader::LookupAndCompile().
|
||||
Local<Value> arguments[] = {exports, primordials};
|
||||
MaybeLocal<Function> maybe_fn =
|
||||
builtins::BuiltinLoader::LookupAndCompile(context, *module, nullptr);
|
||||
Local<Function> fn;
|
||||
if (!maybe_fn.ToLocal(&fn)) {
|
||||
return Nothing<bool>();
|
||||
}
|
||||
MaybeLocal<Value> result =
|
||||
fn->Call(context, Undefined(isolate), arraysize(arguments), arguments);
|
||||
// Execution failed during context creation.
|
||||
if (result.IsEmpty()) {
|
||||
if (builtins::BuiltinLoader::CompileAndCall(
|
||||
context, *module, arraysize(arguments), arguments, nullptr)
|
||||
.IsEmpty()) {
|
||||
// Execution failed during context creation.
|
||||
return Nothing<bool>();
|
||||
}
|
||||
}
|
||||
|
||||
10
src/node.cc
10
src/node.cc
@@ -261,15 +261,7 @@ MaybeLocal<Value> StartExecution(Environment* env, const char* main_script_id) {
|
||||
CHECK_NOT_NULL(main_script_id);
|
||||
Realm* realm = env->principal_realm();
|
||||
|
||||
// Arguments must match the parameters specified in
|
||||
// BuiltinLoader::LookupAndCompile().
|
||||
std::vector<Local<Value>> arguments = {env->process_object(),
|
||||
env->builtin_module_require(),
|
||||
env->internal_binding_loader(),
|
||||
env->primordials()};
|
||||
|
||||
return scope.EscapeMaybe(
|
||||
realm->ExecuteBootstrapper(main_script_id, &arguments));
|
||||
return scope.EscapeMaybe(realm->ExecuteBootstrapper(main_script_id));
|
||||
}
|
||||
|
||||
MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {
|
||||
|
||||
@@ -26,6 +26,7 @@ using v8::ScriptOrigin;
|
||||
using v8::Set;
|
||||
using v8::SideEffectType;
|
||||
using v8::String;
|
||||
using v8::Undefined;
|
||||
using v8::Value;
|
||||
|
||||
BuiltinLoader BuiltinLoader::instance_;
|
||||
@@ -352,8 +353,12 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompile(
|
||||
FIXED_ONE_BYTE_STRING(isolate, "exports"),
|
||||
FIXED_ONE_BYTE_STRING(isolate, "primordials"),
|
||||
};
|
||||
} else if (strncmp(id, "internal/main/", strlen("internal/main/")) == 0) {
|
||||
// internal/main/*: process, require, internalBinding, primordials
|
||||
} else if (strncmp(id, "internal/main/", strlen("internal/main/")) == 0 ||
|
||||
strncmp(id,
|
||||
"internal/bootstrap/",
|
||||
strlen("internal/bootstrap/")) == 0) {
|
||||
// internal/main/*, internal/bootstrap/*: process, require,
|
||||
// internalBinding, primordials
|
||||
parameters = {
|
||||
FIXED_ONE_BYTE_STRING(isolate, "process"),
|
||||
FIXED_ONE_BYTE_STRING(isolate, "require"),
|
||||
@@ -366,16 +371,6 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompile(
|
||||
FIXED_ONE_BYTE_STRING(isolate, "process"),
|
||||
FIXED_ONE_BYTE_STRING(isolate, "require"),
|
||||
};
|
||||
} else if (strncmp(id,
|
||||
"internal/bootstrap/",
|
||||
strlen("internal/bootstrap/")) == 0) {
|
||||
// internal/bootstrap/*: process, require, internalBinding, primordials
|
||||
parameters = {
|
||||
FIXED_ONE_BYTE_STRING(isolate, "process"),
|
||||
FIXED_ONE_BYTE_STRING(isolate, "require"),
|
||||
FIXED_ONE_BYTE_STRING(isolate, "internalBinding"),
|
||||
FIXED_ONE_BYTE_STRING(isolate, "primordials"),
|
||||
};
|
||||
} else {
|
||||
// others: exports, require, module, process, internalBinding, primordials
|
||||
parameters = {
|
||||
@@ -396,6 +391,76 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompile(
|
||||
return maybe;
|
||||
}
|
||||
|
||||
MaybeLocal<Value> BuiltinLoader::CompileAndCall(Local<Context> context,
|
||||
const char* id,
|
||||
Realm* realm) {
|
||||
Isolate* isolate = context->GetIsolate();
|
||||
// Arguments must match the parameters specified in
|
||||
// BuiltinLoader::LookupAndCompile().
|
||||
std::vector<Local<Value>> arguments;
|
||||
// Detects parameters of the scripts based on module ids.
|
||||
// internal/bootstrap/loaders: process, getLinkedBinding,
|
||||
// getInternalBinding, primordials
|
||||
if (strcmp(id, "internal/bootstrap/loaders") == 0) {
|
||||
Local<Value> get_linked_binding;
|
||||
Local<Value> get_internal_binding;
|
||||
if (!NewFunctionTemplate(isolate, binding::GetLinkedBinding)
|
||||
->GetFunction(context)
|
||||
.ToLocal(&get_linked_binding) ||
|
||||
!NewFunctionTemplate(isolate, binding::GetInternalBinding)
|
||||
->GetFunction(context)
|
||||
.ToLocal(&get_internal_binding)) {
|
||||
return MaybeLocal<Value>();
|
||||
}
|
||||
arguments = {realm->process_object(),
|
||||
get_linked_binding,
|
||||
get_internal_binding,
|
||||
realm->primordials()};
|
||||
} else if (strncmp(id, "internal/main/", strlen("internal/main/")) == 0 ||
|
||||
strncmp(id,
|
||||
"internal/bootstrap/",
|
||||
strlen("internal/bootstrap/")) == 0) {
|
||||
// internal/main/*, internal/bootstrap/*: process, require,
|
||||
// internalBinding, primordials
|
||||
arguments = {realm->process_object(),
|
||||
realm->builtin_module_require(),
|
||||
realm->internal_binding_loader(),
|
||||
realm->primordials()};
|
||||
} else if (strncmp(id, "embedder_main_", strlen("embedder_main_")) == 0) {
|
||||
// Synthetic embedder main scripts from LoadEnvironment(): process, require
|
||||
arguments = {
|
||||
realm->process_object(),
|
||||
realm->builtin_module_require(),
|
||||
};
|
||||
} else {
|
||||
// This should be invoked with the other CompileAndCall() methods, as
|
||||
// we are unable to generate the arguments.
|
||||
// Currently there are two cases:
|
||||
// internal/per_context/*: the arguments are generated in
|
||||
// InitializePrimordials()
|
||||
// all the other cases: the arguments are generated in the JS-land loader.
|
||||
UNREACHABLE();
|
||||
}
|
||||
return CompileAndCall(
|
||||
context, id, arguments.size(), arguments.data(), realm->env());
|
||||
}
|
||||
|
||||
MaybeLocal<Value> BuiltinLoader::CompileAndCall(Local<Context> context,
|
||||
const char* id,
|
||||
int argc,
|
||||
Local<Value> argv[],
|
||||
Environment* optional_env) {
|
||||
// Arguments must match the parameters specified in
|
||||
// BuiltinLoader::LookupAndCompile().
|
||||
MaybeLocal<Function> maybe_fn = LookupAndCompile(context, id, optional_env);
|
||||
Local<Function> fn;
|
||||
if (!maybe_fn.ToLocal(&fn)) {
|
||||
return MaybeLocal<Value>();
|
||||
}
|
||||
Local<Value> undefined = Undefined(context->GetIsolate());
|
||||
return fn->Call(context, undefined, argc, argv);
|
||||
}
|
||||
|
||||
bool BuiltinLoader::CompileAllBuiltins(Local<Context> context) {
|
||||
BuiltinLoader* loader = GetInstance();
|
||||
std::vector<std::string> ids = loader->GetBuiltinIds();
|
||||
|
||||
@@ -18,6 +18,8 @@ class PerProcessTest;
|
||||
namespace node {
|
||||
class SnapshotBuilder;
|
||||
class ExternalReferenceRegistry;
|
||||
class Realm;
|
||||
|
||||
namespace builtins {
|
||||
|
||||
using BuiltinSourceMap = std::map<std::string, UnionBytes>;
|
||||
@@ -50,6 +52,16 @@ class NODE_EXTERN_PRIVATE BuiltinLoader {
|
||||
const char* id,
|
||||
Environment* optional_env);
|
||||
|
||||
static v8::MaybeLocal<v8::Value> CompileAndCall(
|
||||
v8::Local<v8::Context> context,
|
||||
const char* id,
|
||||
int argc,
|
||||
v8::Local<v8::Value> argv[],
|
||||
Environment* optional_env);
|
||||
|
||||
static v8::MaybeLocal<v8::Value> CompileAndCall(
|
||||
v8::Local<v8::Context> context, const char* id, Realm* realm);
|
||||
|
||||
static v8::Local<v8::Object> GetSourceObject(v8::Local<v8::Context> context);
|
||||
// Returns config.gypi as a JSON string
|
||||
static v8::Local<v8::String> GetConfigString(v8::Isolate* isolate);
|
||||
|
||||
@@ -18,7 +18,6 @@ using v8::MaybeLocal;
|
||||
using v8::Object;
|
||||
using v8::SnapshotCreator;
|
||||
using v8::String;
|
||||
using v8::Undefined;
|
||||
using v8::Value;
|
||||
|
||||
Realm::Realm(Environment* env,
|
||||
@@ -148,20 +147,10 @@ void Realm::DeserializeProperties(const RealmSerializeInfo* info) {
|
||||
DoneBootstrapping();
|
||||
}
|
||||
|
||||
MaybeLocal<Value> Realm::ExecuteBootstrapper(
|
||||
const char* id, std::vector<Local<Value>>* arguments) {
|
||||
MaybeLocal<Value> Realm::ExecuteBootstrapper(const char* id) {
|
||||
EscapableHandleScope scope(isolate());
|
||||
Local<Context> ctx = context();
|
||||
MaybeLocal<Function> maybe_fn =
|
||||
BuiltinLoader::LookupAndCompile(ctx, id, env());
|
||||
|
||||
Local<Function> fn;
|
||||
if (!maybe_fn.ToLocal(&fn)) {
|
||||
return MaybeLocal<Value>();
|
||||
}
|
||||
|
||||
MaybeLocal<Value> result =
|
||||
fn->Call(ctx, Undefined(isolate()), arguments->size(), arguments->data());
|
||||
MaybeLocal<Value> result = BuiltinLoader::CompileAndCall(ctx, id, this);
|
||||
|
||||
// If there was an error during bootstrap, it must be unrecoverable
|
||||
// (e.g. max call stack exceeded). Clear the stack so that the
|
||||
@@ -179,21 +168,9 @@ MaybeLocal<Value> Realm::ExecuteBootstrapper(
|
||||
MaybeLocal<Value> Realm::BootstrapInternalLoaders() {
|
||||
EscapableHandleScope scope(isolate_);
|
||||
|
||||
// Arguments must match the parameters specified in
|
||||
// BuiltinLoader::LookupAndCompile().
|
||||
std::vector<Local<Value>> loaders_args = {
|
||||
process_object(),
|
||||
NewFunctionTemplate(isolate_, binding::GetLinkedBinding)
|
||||
->GetFunction(context())
|
||||
.ToLocalChecked(),
|
||||
NewFunctionTemplate(isolate_, binding::GetInternalBinding)
|
||||
->GetFunction(context())
|
||||
.ToLocalChecked(),
|
||||
primordials()};
|
||||
|
||||
// Bootstrap internal loaders
|
||||
Local<Value> loader_exports;
|
||||
if (!ExecuteBootstrapper("internal/bootstrap/loaders", &loaders_args)
|
||||
if (!ExecuteBootstrapper("internal/bootstrap/loaders")
|
||||
.ToLocal(&loader_exports)) {
|
||||
return MaybeLocal<Value>();
|
||||
}
|
||||
@@ -216,23 +193,14 @@ MaybeLocal<Value> Realm::BootstrapInternalLoaders() {
|
||||
MaybeLocal<Value> Realm::BootstrapNode() {
|
||||
EscapableHandleScope scope(isolate_);
|
||||
|
||||
// Arguments must match the parameters specified in
|
||||
// BuiltinLoader::LookupAndCompile().
|
||||
// process, require, internalBinding, primordials
|
||||
std::vector<Local<Value>> node_args = {process_object(),
|
||||
builtin_module_require(),
|
||||
internal_binding_loader(),
|
||||
primordials()};
|
||||
|
||||
MaybeLocal<Value> result =
|
||||
ExecuteBootstrapper("internal/bootstrap/node", &node_args);
|
||||
MaybeLocal<Value> result = ExecuteBootstrapper("internal/bootstrap/node");
|
||||
|
||||
if (result.IsEmpty()) {
|
||||
return MaybeLocal<Value>();
|
||||
}
|
||||
|
||||
if (!env_->no_browser_globals()) {
|
||||
result = ExecuteBootstrapper("internal/bootstrap/browser", &node_args);
|
||||
result = ExecuteBootstrapper("internal/bootstrap/browser");
|
||||
|
||||
if (result.IsEmpty()) {
|
||||
return MaybeLocal<Value>();
|
||||
@@ -243,7 +211,7 @@ MaybeLocal<Value> Realm::BootstrapNode() {
|
||||
auto thread_switch_id =
|
||||
env_->is_main_thread() ? "internal/bootstrap/switches/is_main_thread"
|
||||
: "internal/bootstrap/switches/is_not_main_thread";
|
||||
result = ExecuteBootstrapper(thread_switch_id, &node_args);
|
||||
result = ExecuteBootstrapper(thread_switch_id);
|
||||
|
||||
if (result.IsEmpty()) {
|
||||
return MaybeLocal<Value>();
|
||||
@@ -253,7 +221,7 @@ MaybeLocal<Value> Realm::BootstrapNode() {
|
||||
env_->owns_process_state()
|
||||
? "internal/bootstrap/switches/does_own_process_state"
|
||||
: "internal/bootstrap/switches/does_not_own_process_state";
|
||||
result = ExecuteBootstrapper(process_state_switch_id, &node_args);
|
||||
result = ExecuteBootstrapper(process_state_switch_id);
|
||||
|
||||
if (result.IsEmpty()) {
|
||||
return MaybeLocal<Value>();
|
||||
|
||||
@@ -60,8 +60,7 @@ class Realm : public MemoryRetainer {
|
||||
RealmSerializeInfo Serialize(v8::SnapshotCreator* creator);
|
||||
void DeserializeProperties(const RealmSerializeInfo* info);
|
||||
|
||||
v8::MaybeLocal<v8::Value> ExecuteBootstrapper(
|
||||
const char* id, std::vector<v8::Local<v8::Value>>* arguments);
|
||||
v8::MaybeLocal<v8::Value> ExecuteBootstrapper(const char* id);
|
||||
v8::MaybeLocal<v8::Value> BootstrapInternalLoaders();
|
||||
v8::MaybeLocal<v8::Value> BootstrapNode();
|
||||
v8::MaybeLocal<v8::Value> RunBootstrapping();
|
||||
|
||||
Reference in New Issue
Block a user