Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ccc76bb

Browse filesBrowse files
joyeecheungmarco-ippolito
authored andcommitted
src: simplify embedder entry point execution
Previously we wrapped the embedder entry point callback into a binding and then invoke the binding from JS land which was a bit convoluted. Now we just call it directly from C++. The main scripts that needed to tail call the embedder callback now return the arguments in an array so that the C++ land can extract the arguments and pass them to the callback. We also set `PauseOnNextJavascriptStatement()` for --inspect-brk and mark the bootstrap complete milestone directly in C++ for these execution modes. PR-URL: #51557 Reviewed-By: Daniel Lemire <daniel@lemire.me> Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
1 parent 275cea0 commit ccc76bb
Copy full SHA for ccc76bb

File tree

Expand file treeCollapse file tree

6 files changed

+54
-60
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

6 files changed

+54
-60
lines changed
Open diff view settings
Collapse file

‎lib/internal/main/embedding.js‎

Copy file name to clipboard
+1-4Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
'use strict';
22
const {
33
prepareMainThreadExecution,
4-
markBootstrapComplete,
54
} = require('internal/process/pre_execution');
65
const { isExperimentalSeaWarningNeeded } = internalBinding('sea');
76
const { emitExperimentalWarning } = require('internal/util');
87
const { embedderRequire, embedderRunCjs } = require('internal/util/embedding');
9-
const { runEmbedderEntryPoint } = internalBinding('mksnapshot');
108

119
prepareMainThreadExecution(false, true);
12-
markBootstrapComplete();
1310

1411
if (isExperimentalSeaWarningNeeded()) {
1512
emitExperimentalWarning('Single executable application');
1613
}
1714

18-
return runEmbedderEntryPoint(process, embedderRequire, embedderRunCjs);
15+
return [process, embedderRequire, embedderRunCjs];
Collapse file

‎lib/internal/main/mksnapshot.js‎

Copy file name to clipboardExpand all lines: lib/internal/main/mksnapshot.js
+2-13Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ const {
1111

1212
const { BuiltinModule: { normalizeRequirableId } } = require('internal/bootstrap/realm');
1313
const {
14-
runEmbedderEntryPoint,
1514
compileSerializeMain,
1615
anonymousMainPath,
1716
} = internalBinding('mksnapshot');
@@ -20,9 +19,6 @@ const { isExperimentalSeaWarningNeeded } = internalBinding('sea');
2019

2120
const { emitExperimentalWarning } = require('internal/util');
2221
const { emitWarningSync } = require('internal/process/warning');
23-
const {
24-
getOptionValue,
25-
} = require('internal/options');
2622

2723
const {
2824
initializeCallbacks,
@@ -179,18 +175,11 @@ function main() {
179175
return fn(requireForUserSnapshot, filename, dirname);
180176
}
181177

182-
const serializeMainArgs = [process, requireForUserSnapshot, minimalRunCjs];
183-
184178
if (isExperimentalSeaWarningNeeded()) {
185179
emitExperimentalWarning('Single executable application');
186180
}
187181

188-
if (getOptionValue('--inspect-brk')) {
189-
internalBinding('inspector').callAndPauseOnStart(
190-
runEmbedderEntryPoint, undefined, ...serializeMainArgs);
191-
} else {
192-
runEmbedderEntryPoint(...serializeMainArgs);
193-
}
182+
return [process, requireForUserSnapshot, minimalRunCjs];
194183
}
195184

196-
main();
185+
return main();
Collapse file

‎src/env-inl.h‎

Copy file name to clipboardExpand all lines: src/env-inl.h
-8Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -430,14 +430,6 @@ inline builtins::BuiltinLoader* Environment::builtin_loader() {
430430
return &builtin_loader_;
431431
}
432432

433-
inline const StartExecutionCallback& Environment::embedder_entry_point() const {
434-
return embedder_entry_point_;
435-
}
436-
437-
inline void Environment::set_embedder_entry_point(StartExecutionCallback&& fn) {
438-
embedder_entry_point_ = std::move(fn);
439-
}
440-
441433
inline double Environment::new_async_id() {
442434
async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
443435
return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
Collapse file

‎src/env.h‎

Copy file name to clipboardExpand all lines: src/env.h
-4Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -999,9 +999,6 @@ class Environment : public MemoryRetainer {
999999

10001000
#endif // HAVE_INSPECTOR
10011001

1002-
inline const StartExecutionCallback& embedder_entry_point() const;
1003-
inline void set_embedder_entry_point(StartExecutionCallback&& fn);
1004-
10051002
inline void set_process_exit_handler(
10061003
std::function<void(Environment*, ExitCode)>&& handler);
10071004

@@ -1212,7 +1209,6 @@ class Environment : public MemoryRetainer {
12121209
std::unique_ptr<PrincipalRealm> principal_realm_ = nullptr;
12131210

12141211
builtins::BuiltinLoader builtin_loader_;
1215-
StartExecutionCallback embedder_entry_point_;
12161212

12171213
// Used by allocate_managed_buffer() and release_managed_buffer() to keep
12181214
// track of the BackingStore for a given pointer.
Collapse file

‎src/node.cc‎

Copy file name to clipboardExpand all lines: src/node.cc
+51-9Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,10 @@
131131

132132
namespace node {
133133

134+
using v8::Array;
135+
using v8::Context;
134136
using v8::EscapableHandleScope;
137+
using v8::Function;
135138
using v8::Isolate;
136139
using v8::Local;
137140
using v8::MaybeLocal;
@@ -278,26 +281,65 @@ MaybeLocal<Value> StartExecution(Environment* env, const char* main_script_id) {
278281
return scope.EscapeMaybe(realm->ExecuteBootstrapper(main_script_id));
279282
}
280283

284+
// Convert the result returned by an intermediate main script into
285+
// StartExecutionCallbackInfo. Currently the result is an array containing
286+
// [process, requireFunction, cjsRunner]
287+
std::optional<StartExecutionCallbackInfo> CallbackInfoFromArray(
288+
Local<Context> context, Local<Value> result) {
289+
CHECK(result->IsArray());
290+
Local<Array> args = result.As<Array>();
291+
CHECK_EQ(args->Length(), 3);
292+
Local<Value> process_obj, require_fn, runcjs_fn;
293+
if (!args->Get(context, 0).ToLocal(&process_obj) ||
294+
!args->Get(context, 1).ToLocal(&require_fn) ||
295+
!args->Get(context, 2).ToLocal(&runcjs_fn)) {
296+
return std::nullopt;
297+
}
298+
CHECK(process_obj->IsObject());
299+
CHECK(require_fn->IsFunction());
300+
CHECK(runcjs_fn->IsFunction());
301+
node::StartExecutionCallbackInfo info{process_obj.As<Object>(),
302+
require_fn.As<Function>(),
303+
runcjs_fn.As<Function>()};
304+
return info;
305+
}
306+
281307
MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {
282308
InternalCallbackScope callback_scope(
283309
env,
284310
Object::New(env->isolate()),
285311
{ 1, 0 },
286312
InternalCallbackScope::kSkipAsyncHooks);
287313

314+
// Only snapshot builder or embedder applications set the
315+
// callback.
288316
if (cb != nullptr) {
289317
EscapableHandleScope scope(env->isolate());
290-
// TODO(addaleax): pass the callback to the main script more directly,
291-
// e.g. by making StartExecution(env, builtin) parametrizable
292-
env->set_embedder_entry_point(std::move(cb));
293-
auto reset_entry_point =
294-
OnScopeLeave([&]() { env->set_embedder_entry_point({}); });
295318

296-
const char* entry = env->isolate_data()->is_building_snapshot()
297-
? "internal/main/mksnapshot"
298-
: "internal/main/embedding";
319+
Local<Value> result;
320+
if (env->isolate_data()->is_building_snapshot()) {
321+
if (!StartExecution(env, "internal/main/mksnapshot").ToLocal(&result)) {
322+
return MaybeLocal<Value>();
323+
}
324+
} else {
325+
if (!StartExecution(env, "internal/main/embedding").ToLocal(&result)) {
326+
return MaybeLocal<Value>();
327+
}
328+
}
329+
330+
auto info = CallbackInfoFromArray(env->context(), result);
331+
if (!info.has_value()) {
332+
MaybeLocal<Value>();
333+
}
334+
#if HAVE_INSPECTOR
335+
if (env->options()->debug_options().break_first_line) {
336+
env->inspector_agent()->PauseOnNextJavascriptStatement("Break on start");
337+
}
338+
#endif
299339

300-
return scope.EscapeMaybe(StartExecution(env, entry));
340+
env->performance_state()->Mark(
341+
performance::NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE);
342+
return scope.EscapeMaybe(cb(info.value()));
301343
}
302344

303345
CHECK(!env->isolate_data()->is_building_snapshot());
Collapse file

‎src/node_snapshotable.cc‎

Copy file name to clipboardExpand all lines: src/node_snapshotable.cc
-22Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ using v8::FunctionCallbackInfo;
4141
using v8::HandleScope;
4242
using v8::Isolate;
4343
using v8::Local;
44-
using v8::MaybeLocal;
4544
using v8::Object;
4645
using v8::ObjectTemplate;
4746
using v8::ScriptCompiler;
@@ -1411,25 +1410,6 @@ void SerializeSnapshotableObjects(Realm* realm,
14111410
});
14121411
}
14131412

1414-
static void RunEmbedderEntryPoint(const FunctionCallbackInfo<Value>& args) {
1415-
Environment* env = Environment::GetCurrent(args);
1416-
Local<Value> process_obj = args[0];
1417-
Local<Value> require_fn = args[1];
1418-
Local<Value> runcjs_fn = args[2];
1419-
CHECK(process_obj->IsObject());
1420-
CHECK(require_fn->IsFunction());
1421-
CHECK(runcjs_fn->IsFunction());
1422-
1423-
const node::StartExecutionCallback& callback = env->embedder_entry_point();
1424-
node::StartExecutionCallbackInfo info{process_obj.As<Object>(),
1425-
require_fn.As<Function>(),
1426-
runcjs_fn.As<Function>()};
1427-
MaybeLocal<Value> retval = callback(info);
1428-
if (!retval.IsEmpty()) {
1429-
args.GetReturnValue().Set(retval.ToLocalChecked());
1430-
}
1431-
}
1432-
14331413
void CompileSerializeMain(const FunctionCallbackInfo<Value>& args) {
14341414
CHECK(args[0]->IsString());
14351415
Local<String> filename = args[0].As<String>();
@@ -1553,7 +1533,6 @@ void CreatePerContextProperties(Local<Object> target,
15531533
void CreatePerIsolateProperties(IsolateData* isolate_data,
15541534
Local<ObjectTemplate> target) {
15551535
Isolate* isolate = isolate_data->isolate();
1556-
SetMethod(isolate, target, "runEmbedderEntryPoint", RunEmbedderEntryPoint);
15571536
SetMethod(isolate, target, "compileSerializeMain", CompileSerializeMain);
15581537
SetMethod(isolate, target, "setSerializeCallback", SetSerializeCallback);
15591538
SetMethod(isolate, target, "setDeserializeCallback", SetDeserializeCallback);
@@ -1566,7 +1545,6 @@ void CreatePerIsolateProperties(IsolateData* isolate_data,
15661545
}
15671546

15681547
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
1569-
registry->Register(RunEmbedderEntryPoint);
15701548
registry->Register(CompileSerializeMain);
15711549
registry->Register(SetSerializeCallback);
15721550
registry->Register(SetDeserializeCallback);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.