Skip to content

Commit 7850802

Browse files
authored
bootstrap: generate bootstrapper arguments in BuiltinLoader
PR-URL: #44488 Reviewed-By: Chengzhong Wu <[email protected]>
1 parent 5c546e1 commit 7850802

6 files changed

+103
-79
lines changed

src/api/environment.cc

+5-17
Original file line numberDiff line numberDiff line change
@@ -456,11 +456,7 @@ MaybeLocal<Value> LoadEnvironment(
456456
env->set_main_utf16(std::move(main_utf16));
457457
Realm* realm = env->principal_realm();
458458

459-
// Arguments must match the parameters specified in
460-
// BuiltinLoader::LookupAndCompile().
461-
std::vector<Local<Value>> args = {realm->process_object(),
462-
realm->builtin_module_require()};
463-
return realm->ExecuteBootstrapper(name.c_str(), &args);
459+
return realm->ExecuteBootstrapper(name.c_str());
464460
});
465461
}
466462

@@ -699,19 +695,11 @@ Maybe<bool> InitializePrimordials(Local<Context> context) {
699695
nullptr};
700696

701697
for (const char** module = context_files; *module != nullptr; module++) {
702-
// Arguments must match the parameters specified in
703-
// BuiltinLoader::LookupAndCompile().
704698
Local<Value> arguments[] = {exports, primordials};
705-
MaybeLocal<Function> maybe_fn =
706-
builtins::BuiltinLoader::LookupAndCompile(context, *module, nullptr);
707-
Local<Function> fn;
708-
if (!maybe_fn.ToLocal(&fn)) {
709-
return Nothing<bool>();
710-
}
711-
MaybeLocal<Value> result =
712-
fn->Call(context, Undefined(isolate), arraysize(arguments), arguments);
713-
// Execution failed during context creation.
714-
if (result.IsEmpty()) {
699+
if (builtins::BuiltinLoader::CompileAndCall(
700+
context, *module, arraysize(arguments), arguments, nullptr)
701+
.IsEmpty()) {
702+
// Execution failed during context creation.
715703
return Nothing<bool>();
716704
}
717705
}

src/node.cc

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

264-
// Arguments must match the parameters specified in
265-
// BuiltinLoader::LookupAndCompile().
266-
std::vector<Local<Value>> arguments = {env->process_object(),
267-
env->builtin_module_require(),
268-
env->internal_binding_loader(),
269-
env->primordials()};
270-
271-
return scope.EscapeMaybe(
272-
realm->ExecuteBootstrapper(main_script_id, &arguments));
264+
return scope.EscapeMaybe(realm->ExecuteBootstrapper(main_script_id));
273265
}
274266

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

src/node_builtins.cc

+77-12
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ using v8::ScriptOrigin;
2626
using v8::Set;
2727
using v8::SideEffectType;
2828
using v8::String;
29+
using v8::Undefined;
2930
using v8::Value;
3031

3132
BuiltinLoader BuiltinLoader::instance_;
@@ -352,8 +353,12 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompile(
352353
FIXED_ONE_BYTE_STRING(isolate, "exports"),
353354
FIXED_ONE_BYTE_STRING(isolate, "primordials"),
354355
};
355-
} else if (strncmp(id, "internal/main/", strlen("internal/main/")) == 0) {
356-
// internal/main/*: process, require, internalBinding, primordials
356+
} else if (strncmp(id, "internal/main/", strlen("internal/main/")) == 0 ||
357+
strncmp(id,
358+
"internal/bootstrap/",
359+
strlen("internal/bootstrap/")) == 0) {
360+
// internal/main/*, internal/bootstrap/*: process, require,
361+
// internalBinding, primordials
357362
parameters = {
358363
FIXED_ONE_BYTE_STRING(isolate, "process"),
359364
FIXED_ONE_BYTE_STRING(isolate, "require"),
@@ -366,16 +371,6 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompile(
366371
FIXED_ONE_BYTE_STRING(isolate, "process"),
367372
FIXED_ONE_BYTE_STRING(isolate, "require"),
368373
};
369-
} else if (strncmp(id,
370-
"internal/bootstrap/",
371-
strlen("internal/bootstrap/")) == 0) {
372-
// internal/bootstrap/*: process, require, internalBinding, primordials
373-
parameters = {
374-
FIXED_ONE_BYTE_STRING(isolate, "process"),
375-
FIXED_ONE_BYTE_STRING(isolate, "require"),
376-
FIXED_ONE_BYTE_STRING(isolate, "internalBinding"),
377-
FIXED_ONE_BYTE_STRING(isolate, "primordials"),
378-
};
379374
} else {
380375
// others: exports, require, module, process, internalBinding, primordials
381376
parameters = {
@@ -396,6 +391,76 @@ MaybeLocal<Function> BuiltinLoader::LookupAndCompile(
396391
return maybe;
397392
}
398393

394+
MaybeLocal<Value> BuiltinLoader::CompileAndCall(Local<Context> context,
395+
const char* id,
396+
Realm* realm) {
397+
Isolate* isolate = context->GetIsolate();
398+
// Arguments must match the parameters specified in
399+
// BuiltinLoader::LookupAndCompile().
400+
std::vector<Local<Value>> arguments;
401+
// Detects parameters of the scripts based on module ids.
402+
// internal/bootstrap/loaders: process, getLinkedBinding,
403+
// getInternalBinding, primordials
404+
if (strcmp(id, "internal/bootstrap/loaders") == 0) {
405+
Local<Value> get_linked_binding;
406+
Local<Value> get_internal_binding;
407+
if (!NewFunctionTemplate(isolate, binding::GetLinkedBinding)
408+
->GetFunction(context)
409+
.ToLocal(&get_linked_binding) ||
410+
!NewFunctionTemplate(isolate, binding::GetInternalBinding)
411+
->GetFunction(context)
412+
.ToLocal(&get_internal_binding)) {
413+
return MaybeLocal<Value>();
414+
}
415+
arguments = {realm->process_object(),
416+
get_linked_binding,
417+
get_internal_binding,
418+
realm->primordials()};
419+
} else if (strncmp(id, "internal/main/", strlen("internal/main/")) == 0 ||
420+
strncmp(id,
421+
"internal/bootstrap/",
422+
strlen("internal/bootstrap/")) == 0) {
423+
// internal/main/*, internal/bootstrap/*: process, require,
424+
// internalBinding, primordials
425+
arguments = {realm->process_object(),
426+
realm->builtin_module_require(),
427+
realm->internal_binding_loader(),
428+
realm->primordials()};
429+
} else if (strncmp(id, "embedder_main_", strlen("embedder_main_")) == 0) {
430+
// Synthetic embedder main scripts from LoadEnvironment(): process, require
431+
arguments = {
432+
realm->process_object(),
433+
realm->builtin_module_require(),
434+
};
435+
} else {
436+
// This should be invoked with the other CompileAndCall() methods, as
437+
// we are unable to generate the arguments.
438+
// Currently there are two cases:
439+
// internal/per_context/*: the arguments are generated in
440+
// InitializePrimordials()
441+
// all the other cases: the arguments are generated in the JS-land loader.
442+
UNREACHABLE();
443+
}
444+
return CompileAndCall(
445+
context, id, arguments.size(), arguments.data(), realm->env());
446+
}
447+
448+
MaybeLocal<Value> BuiltinLoader::CompileAndCall(Local<Context> context,
449+
const char* id,
450+
int argc,
451+
Local<Value> argv[],
452+
Environment* optional_env) {
453+
// Arguments must match the parameters specified in
454+
// BuiltinLoader::LookupAndCompile().
455+
MaybeLocal<Function> maybe_fn = LookupAndCompile(context, id, optional_env);
456+
Local<Function> fn;
457+
if (!maybe_fn.ToLocal(&fn)) {
458+
return MaybeLocal<Value>();
459+
}
460+
Local<Value> undefined = Undefined(context->GetIsolate());
461+
return fn->Call(context, undefined, argc, argv);
462+
}
463+
399464
bool BuiltinLoader::CompileAllBuiltins(Local<Context> context) {
400465
BuiltinLoader* loader = GetInstance();
401466
std::vector<std::string> ids = loader->GetBuiltinIds();

src/node_builtins.h

+12
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ class PerProcessTest;
1818
namespace node {
1919
class SnapshotBuilder;
2020
class ExternalReferenceRegistry;
21+
class Realm;
22+
2123
namespace builtins {
2224

2325
using BuiltinSourceMap = std::map<std::string, UnionBytes>;
@@ -50,6 +52,16 @@ class NODE_EXTERN_PRIVATE BuiltinLoader {
5052
const char* id,
5153
Environment* optional_env);
5254

55+
static v8::MaybeLocal<v8::Value> CompileAndCall(
56+
v8::Local<v8::Context> context,
57+
const char* id,
58+
int argc,
59+
v8::Local<v8::Value> argv[],
60+
Environment* optional_env);
61+
62+
static v8::MaybeLocal<v8::Value> CompileAndCall(
63+
v8::Local<v8::Context> context, const char* id, Realm* realm);
64+
5365
static v8::Local<v8::Object> GetSourceObject(v8::Local<v8::Context> context);
5466
// Returns config.gypi as a JSON string
5567
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,
@@ -148,20 +147,10 @@ void Realm::DeserializeProperties(const RealmSerializeInfo* info) {
148147
DoneBootstrapping();
149148
}
150149

151-
MaybeLocal<Value> Realm::ExecuteBootstrapper(
152-
const char* id, std::vector<Local<Value>>* arguments) {
150+
MaybeLocal<Value> Realm::ExecuteBootstrapper(const char* id) {
153151
EscapableHandleScope scope(isolate());
154152
Local<Context> ctx = context();
155-
MaybeLocal<Function> maybe_fn =
156-
BuiltinLoader::LookupAndCompile(ctx, id, env());
157-
158-
Local<Function> fn;
159-
if (!maybe_fn.ToLocal(&fn)) {
160-
return MaybeLocal<Value>();
161-
}
162-
163-
MaybeLocal<Value> result =
164-
fn->Call(ctx, Undefined(isolate()), arguments->size(), arguments->data());
153+
MaybeLocal<Value> result = BuiltinLoader::CompileAndCall(ctx, id, this);
165154

166155
// If there was an error during bootstrap, it must be unrecoverable
167156
// (e.g. max call stack exceeded). Clear the stack so that the
@@ -179,21 +168,9 @@ MaybeLocal<Value> Realm::ExecuteBootstrapper(
179168
MaybeLocal<Value> Realm::BootstrapInternalLoaders() {
180169
EscapableHandleScope scope(isolate_);
181170

182-
// Arguments must match the parameters specified in
183-
// BuiltinLoader::LookupAndCompile().
184-
std::vector<Local<Value>> loaders_args = {
185-
process_object(),
186-
NewFunctionTemplate(isolate_, binding::GetLinkedBinding)
187-
->GetFunction(context())
188-
.ToLocalChecked(),
189-
NewFunctionTemplate(isolate_, binding::GetInternalBinding)
190-
->GetFunction(context())
191-
.ToLocalChecked(),
192-
primordials()};
193-
194171
// Bootstrap internal loaders
195172
Local<Value> loader_exports;
196-
if (!ExecuteBootstrapper("internal/bootstrap/loaders", &loaders_args)
173+
if (!ExecuteBootstrapper("internal/bootstrap/loaders")
197174
.ToLocal(&loader_exports)) {
198175
return MaybeLocal<Value>();
199176
}
@@ -216,23 +193,14 @@ MaybeLocal<Value> Realm::BootstrapInternalLoaders() {
216193
MaybeLocal<Value> Realm::BootstrapNode() {
217194
EscapableHandleScope scope(isolate_);
218195

219-
// Arguments must match the parameters specified in
220-
// BuiltinLoader::LookupAndCompile().
221-
// process, require, internalBinding, primordials
222-
std::vector<Local<Value>> node_args = {process_object(),
223-
builtin_module_require(),
224-
internal_binding_loader(),
225-
primordials()};
226-
227-
MaybeLocal<Value> result =
228-
ExecuteBootstrapper("internal/bootstrap/node", &node_args);
196+
MaybeLocal<Value> result = ExecuteBootstrapper("internal/bootstrap/node");
229197

230198
if (result.IsEmpty()) {
231199
return MaybeLocal<Value>();
232200
}
233201

234202
if (!env_->no_browser_globals()) {
235-
result = ExecuteBootstrapper("internal/bootstrap/browser", &node_args);
203+
result = ExecuteBootstrapper("internal/bootstrap/browser");
236204

237205
if (result.IsEmpty()) {
238206
return MaybeLocal<Value>();
@@ -243,7 +211,7 @@ MaybeLocal<Value> Realm::BootstrapNode() {
243211
auto thread_switch_id =
244212
env_->is_main_thread() ? "internal/bootstrap/switches/is_main_thread"
245213
: "internal/bootstrap/switches/is_not_main_thread";
246-
result = ExecuteBootstrapper(thread_switch_id, &node_args);
214+
result = ExecuteBootstrapper(thread_switch_id);
247215

248216
if (result.IsEmpty()) {
249217
return MaybeLocal<Value>();
@@ -253,7 +221,7 @@ MaybeLocal<Value> Realm::BootstrapNode() {
253221
env_->owns_process_state()
254222
? "internal/bootstrap/switches/does_own_process_state"
255223
: "internal/bootstrap/switches/does_not_own_process_state";
256-
result = ExecuteBootstrapper(process_state_switch_id, &node_args);
224+
result = ExecuteBootstrapper(process_state_switch_id);
257225

258226
if (result.IsEmpty()) {
259227
return MaybeLocal<Value>();

src/node_realm.h

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

63-
v8::MaybeLocal<v8::Value> ExecuteBootstrapper(
64-
const char* id, std::vector<v8::Local<v8::Value>>* arguments);
63+
v8::MaybeLocal<v8::Value> ExecuteBootstrapper(const char* id);
6564
v8::MaybeLocal<v8::Value> BootstrapInternalLoaders();
6665
v8::MaybeLocal<v8::Value> BootstrapNode();
6766
v8::MaybeLocal<v8::Value> RunBootstrapping();

0 commit comments

Comments
 (0)