Skip to content

Commit c1bc811

Browse files
joyeecheungtargos
authored andcommittedOct 28, 2023
bootstrap: generate bootstrapper arguments in BuiltinLoader
PR-URL: #44488 Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
1 parent b55eb2a commit c1bc811

File tree

6 files changed

+103
-79
lines changed

6 files changed

+103
-79
lines changed
 

‎src/api/environment.cc

+5-17
Original file line numberDiff line numberDiff line change
@@ -492,11 +492,7 @@ MaybeLocal<Value> LoadEnvironment(
492492
builtins::BuiltinLoader::Add(name.c_str(), main_script_source_utf8);
493493
Realm* realm = env->principal_realm();
494494

495-
// Arguments must match the parameters specified in
496-
// BuiltinLoader::LookupAndCompile().
497-
std::vector<Local<Value>> args = {realm->process_object(),
498-
realm->builtin_module_require()};
499-
return realm->ExecuteBootstrapper(name.c_str(), &args);
495+
return realm->ExecuteBootstrapper(name.c_str());
500496
});
501497
}
502498

@@ -734,19 +730,11 @@ Maybe<bool> InitializePrimordials(Local<Context> context) {
734730
nullptr};
735731

736732
for (const char** module = context_files; *module != nullptr; module++) {
737-
// Arguments must match the parameters specified in
738-
// BuiltinLoader::LookupAndCompile().
739733
Local<Value> arguments[] = {exports, primordials};
740-
MaybeLocal<Function> maybe_fn =
741-
builtins::BuiltinLoader::LookupAndCompile(context, *module, nullptr);
742-
Local<Function> fn;
743-
if (!maybe_fn.ToLocal(&fn)) {
744-
return Nothing<bool>();
745-
}
746-
MaybeLocal<Value> result =
747-
fn->Call(context, Undefined(isolate), arraysize(arguments), arguments);
748-
// Execution failed during context creation.
749-
if (result.IsEmpty()) {
734+
if (builtins::BuiltinLoader::CompileAndCall(
735+
context, *module, arraysize(arguments), arguments, nullptr)
736+
.IsEmpty()) {
737+
// Execution failed during context creation.
750738
return Nothing<bool>();
751739
}
752740
}

‎src/node.cc

+1-9
Original file line numberDiff line numberDiff line change
@@ -275,15 +275,7 @@ MaybeLocal<Value> StartExecution(Environment* env, const char* main_script_id) {
275275
CHECK_NOT_NULL(main_script_id);
276276
Realm* realm = env->principal_realm();
277277

278-
// Arguments must match the parameters specified in
279-
// BuiltinLoader::LookupAndCompile().
280-
std::vector<Local<Value>> arguments = {env->process_object(),
281-
env->builtin_module_require(),
282-
env->internal_binding_loader(),
283-
env->primordials()};
284-
285-
return scope.EscapeMaybe(
286-
realm->ExecuteBootstrapper(main_script_id, &arguments));
278+
return scope.EscapeMaybe(realm->ExecuteBootstrapper(main_script_id));
287279
}
288280

289281
MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {

‎src/node_builtins.cc

+77-12
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ using v8::ScriptOrigin;
2727
using v8::Set;
2828
using v8::SideEffectType;
2929
using v8::String;
30+
using v8::Undefined;
3031
using v8::Value;
3132

3233
BuiltinLoader BuiltinLoader::instance_;
@@ -390,8 +391,12 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompile(
390391
FIXED_ONE_BYTE_STRING(isolate, "exports"),
391392
FIXED_ONE_BYTE_STRING(isolate, "primordials"),
392393
};
393-
} else if (strncmp(id, "internal/main/", strlen("internal/main/")) == 0) {
394-
// internal/main/*: process, require, internalBinding, primordials
394+
} else if (strncmp(id, "internal/main/", strlen("internal/main/")) == 0 ||
395+
strncmp(id,
396+
"internal/bootstrap/",
397+
strlen("internal/bootstrap/")) == 0) {
398+
// internal/main/*, internal/bootstrap/*: process, require,
399+
// internalBinding, primordials
395400
parameters = {
396401
FIXED_ONE_BYTE_STRING(isolate, "process"),
397402
FIXED_ONE_BYTE_STRING(isolate, "require"),
@@ -404,16 +409,6 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompile(
404409
FIXED_ONE_BYTE_STRING(isolate, "process"),
405410
FIXED_ONE_BYTE_STRING(isolate, "require"),
406411
};
407-
} else if (strncmp(id,
408-
"internal/bootstrap/",
409-
strlen("internal/bootstrap/")) == 0) {
410-
// internal/bootstrap/*: process, require, internalBinding, primordials
411-
parameters = {
412-
FIXED_ONE_BYTE_STRING(isolate, "process"),
413-
FIXED_ONE_BYTE_STRING(isolate, "require"),
414-
FIXED_ONE_BYTE_STRING(isolate, "internalBinding"),
415-
FIXED_ONE_BYTE_STRING(isolate, "primordials"),
416-
};
417412
} else {
418413
// others: exports, require, module, process, internalBinding, primordials
419414
parameters = {
@@ -434,6 +429,76 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompile(
434429
return maybe;
435430
}
436431

432+
MaybeLocal<Value> BuiltinLoader::CompileAndCall(Local<Context> context,
433+
const char* id,
434+
Realm* realm) {
435+
Isolate* isolate = context->GetIsolate();
436+
// Arguments must match the parameters specified in
437+
// BuiltinLoader::LookupAndCompile().
438+
std::vector<Local<Value>> arguments;
439+
// Detects parameters of the scripts based on module ids.
440+
// internal/bootstrap/loaders: process, getLinkedBinding,
441+
// getInternalBinding, primordials
442+
if (strcmp(id, "internal/bootstrap/loaders") == 0) {
443+
Local<Value> get_linked_binding;
444+
Local<Value> get_internal_binding;
445+
if (!NewFunctionTemplate(isolate, binding::GetLinkedBinding)
446+
->GetFunction(context)
447+
.ToLocal(&get_linked_binding) ||
448+
!NewFunctionTemplate(isolate, binding::GetInternalBinding)
449+
->GetFunction(context)
450+
.ToLocal(&get_internal_binding)) {
451+
return MaybeLocal<Value>();
452+
}
453+
arguments = {realm->process_object(),
454+
get_linked_binding,
455+
get_internal_binding,
456+
realm->primordials()};
457+
} else if (strncmp(id, "internal/main/", strlen("internal/main/")) == 0 ||
458+
strncmp(id,
459+
"internal/bootstrap/",
460+
strlen("internal/bootstrap/")) == 0) {
461+
// internal/main/*, internal/bootstrap/*: process, require,
462+
// internalBinding, primordials
463+
arguments = {realm->process_object(),
464+
realm->builtin_module_require(),
465+
realm->internal_binding_loader(),
466+
realm->primordials()};
467+
} else if (strncmp(id, "embedder_main_", strlen("embedder_main_")) == 0) {
468+
// Synthetic embedder main scripts from LoadEnvironment(): process, require
469+
arguments = {
470+
realm->process_object(),
471+
realm->builtin_module_require(),
472+
};
473+
} else {
474+
// This should be invoked with the other CompileAndCall() methods, as
475+
// we are unable to generate the arguments.
476+
// Currently there are two cases:
477+
// internal/per_context/*: the arguments are generated in
478+
// InitializePrimordials()
479+
// all the other cases: the arguments are generated in the JS-land loader.
480+
UNREACHABLE();
481+
}
482+
return CompileAndCall(
483+
context, id, arguments.size(), arguments.data(), realm->env());
484+
}
485+
486+
MaybeLocal<Value> BuiltinLoader::CompileAndCall(Local<Context> context,
487+
const char* id,
488+
int argc,
489+
Local<Value> argv[],
490+
Environment* optional_env) {
491+
// Arguments must match the parameters specified in
492+
// BuiltinLoader::LookupAndCompile().
493+
MaybeLocal<Function> maybe_fn = LookupAndCompile(context, id, optional_env);
494+
Local<Function> fn;
495+
if (!maybe_fn.ToLocal(&fn)) {
496+
return MaybeLocal<Value>();
497+
}
498+
Local<Value> undefined = Undefined(context->GetIsolate());
499+
return fn->Call(context, undefined, argc, argv);
500+
}
501+
437502
bool BuiltinLoader::CompileAllBuiltins(Local<Context> context) {
438503
BuiltinLoader* loader = GetInstance();
439504
std::vector<std::string> ids = loader->GetBuiltinIds();

‎src/node_builtins.h

+12
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ class PerProcessTest;
1919
namespace node {
2020
class SnapshotBuilder;
2121
class ExternalReferenceRegistry;
22+
class Realm;
23+
2224
namespace builtins {
2325

2426
using BuiltinSourceMap = std::map<std::string, UnionBytes>;
@@ -51,6 +53,16 @@ class NODE_EXTERN_PRIVATE BuiltinLoader {
5153
const char* id,
5254
Environment* optional_env);
5355

56+
static v8::MaybeLocal<v8::Value> CompileAndCall(
57+
v8::Local<v8::Context> context,
58+
const char* id,
59+
int argc,
60+
v8::Local<v8::Value> argv[],
61+
Environment* optional_env);
62+
63+
static v8::MaybeLocal<v8::Value> CompileAndCall(
64+
v8::Local<v8::Context> context, const char* id, Realm* realm);
65+
5466
static v8::Local<v8::Object> GetSourceObject(v8::Local<v8::Context> context);
5567
// Returns config.gypi as a JSON string
5668
static v8::Local<v8::String> GetConfigString(v8::Isolate* isolate);

‎src/node_realm.cc

+7-39
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ using v8::MaybeLocal;
1818
using v8::Object;
1919
using v8::SnapshotCreator;
2020
using v8::String;
21-
using v8::Undefined;
2221
using v8::Value;
2322

2423
Realm::Realm(Environment* env,
@@ -157,20 +156,10 @@ void Realm::DeserializeProperties(const RealmSerializeInfo* info) {
157156
DoneBootstrapping();
158157
}
159158

160-
MaybeLocal<Value> Realm::ExecuteBootstrapper(
161-
const char* id, std::vector<Local<Value>>* arguments) {
159+
MaybeLocal<Value> Realm::ExecuteBootstrapper(const char* id) {
162160
EscapableHandleScope scope(isolate());
163161
Local<Context> ctx = context();
164-
MaybeLocal<Function> maybe_fn =
165-
BuiltinLoader::LookupAndCompile(ctx, id, env());
166-
167-
Local<Function> fn;
168-
if (!maybe_fn.ToLocal(&fn)) {
169-
return MaybeLocal<Value>();
170-
}
171-
172-
MaybeLocal<Value> result =
173-
fn->Call(ctx, Undefined(isolate()), arguments->size(), arguments->data());
162+
MaybeLocal<Value> result = BuiltinLoader::CompileAndCall(ctx, id, this);
174163

175164
// If there was an error during bootstrap, it must be unrecoverable
176165
// (e.g. max call stack exceeded). Clear the stack so that the
@@ -188,21 +177,9 @@ MaybeLocal<Value> Realm::ExecuteBootstrapper(
188177
MaybeLocal<Value> Realm::BootstrapInternalLoaders() {
189178
EscapableHandleScope scope(isolate_);
190179

191-
// Arguments must match the parameters specified in
192-
// BuiltinLoader::LookupAndCompile().
193-
std::vector<Local<Value>> loaders_args = {
194-
process_object(),
195-
NewFunctionTemplate(isolate_, binding::GetLinkedBinding)
196-
->GetFunction(context())
197-
.ToLocalChecked(),
198-
NewFunctionTemplate(isolate_, binding::GetInternalBinding)
199-
->GetFunction(context())
200-
.ToLocalChecked(),
201-
primordials()};
202-
203180
// Bootstrap internal loaders
204181
Local<Value> loader_exports;
205-
if (!ExecuteBootstrapper("internal/bootstrap/loaders", &loaders_args)
182+
if (!ExecuteBootstrapper("internal/bootstrap/loaders")
206183
.ToLocal(&loader_exports)) {
207184
return MaybeLocal<Value>();
208185
}
@@ -225,23 +202,14 @@ MaybeLocal<Value> Realm::BootstrapInternalLoaders() {
225202
MaybeLocal<Value> Realm::BootstrapNode() {
226203
EscapableHandleScope scope(isolate_);
227204

228-
// Arguments must match the parameters specified in
229-
// BuiltinLoader::LookupAndCompile().
230-
// process, require, internalBinding, primordials
231-
std::vector<Local<Value>> node_args = {process_object(),
232-
builtin_module_require(),
233-
internal_binding_loader(),
234-
primordials()};
235-
236-
MaybeLocal<Value> result =
237-
ExecuteBootstrapper("internal/bootstrap/node", &node_args);
205+
MaybeLocal<Value> result = ExecuteBootstrapper("internal/bootstrap/node");
238206

239207
if (result.IsEmpty()) {
240208
return MaybeLocal<Value>();
241209
}
242210

243211
if (!env_->no_browser_globals()) {
244-
result = ExecuteBootstrapper("internal/bootstrap/browser", &node_args);
212+
result = ExecuteBootstrapper("internal/bootstrap/browser");
245213

246214
if (result.IsEmpty()) {
247215
return MaybeLocal<Value>();
@@ -252,7 +220,7 @@ MaybeLocal<Value> Realm::BootstrapNode() {
252220
auto thread_switch_id =
253221
env_->is_main_thread() ? "internal/bootstrap/switches/is_main_thread"
254222
: "internal/bootstrap/switches/is_not_main_thread";
255-
result = ExecuteBootstrapper(thread_switch_id, &node_args);
223+
result = ExecuteBootstrapper(thread_switch_id);
256224

257225
if (result.IsEmpty()) {
258226
return MaybeLocal<Value>();
@@ -262,7 +230,7 @@ MaybeLocal<Value> Realm::BootstrapNode() {
262230
env_->owns_process_state()
263231
? "internal/bootstrap/switches/does_own_process_state"
264232
: "internal/bootstrap/switches/does_not_own_process_state";
265-
result = ExecuteBootstrapper(process_state_switch_id, &node_args);
233+
result = ExecuteBootstrapper(process_state_switch_id);
266234

267235
if (result.IsEmpty()) {
268236
return MaybeLocal<Value>();

‎src/node_realm.h

+1-2
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,7 @@ class Realm : public MemoryRetainer {
6767
RealmSerializeInfo Serialize(v8::SnapshotCreator* creator);
6868
void DeserializeProperties(const RealmSerializeInfo* info);
6969

70-
v8::MaybeLocal<v8::Value> ExecuteBootstrapper(
71-
const char* id, std::vector<v8::Local<v8::Value>>* arguments);
70+
v8::MaybeLocal<v8::Value> ExecuteBootstrapper(const char* id);
7271
v8::MaybeLocal<v8::Value> BootstrapInternalLoaders();
7372
v8::MaybeLocal<v8::Value> BootstrapNode();
7473
v8::MaybeLocal<v8::Value> RunBootstrapping();

0 commit comments

Comments
 (0)
Please sign in to comment.