src: provide a variant of LoadEnvironment taking a callback · nodejs/node@c5aa3f4 · GitHub
Skip to content

Commit c5aa3f4

Browse files
committed
src: provide a variant of LoadEnvironment taking a callback
This allows embedders to flexibly control how they start JS code rather than using `third_party_main`. Backport-PR-URL: #35241 PR-URL: #30467 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
1 parent 808dedc commit c5aa3f4

6 files changed

Lines changed: 99 additions & 16 deletions

File tree

src/api/environment.cc

Lines changed: 3 additions & 4 deletions

src/node.cc

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ void MarkBootstrapComplete(const FunctionCallbackInfo<Value>& args) {
364364
performance::NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE);
365365
}
366366

367+
static
367368
MaybeLocal<Value> StartExecution(Environment* env, const char* main_script_id) {
368369
EscapableHandleScope scope(env->isolate());
369370
CHECK_NOT_NULL(main_script_id);
@@ -384,17 +385,31 @@ MaybeLocal<Value> StartExecution(Environment* env, const char* main_script_id) {
384385
->GetFunction(env->context())
385386
.ToLocalChecked()};
386387

387-
InternalCallbackScope callback_scope(
388-
env,
389-
Object::New(env->isolate()),
390-
{ 1, 0 },
391-
InternalCallbackScope::kSkipAsyncHooks);
392-
393388
return scope.EscapeMaybe(
394389
ExecuteBootstrapper(env, main_script_id, &parameters, &arguments));
395390
}
396391

397-
MaybeLocal<Value> StartExecution(Environment* env) {
392+
MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {
393+
InternalCallbackScope callback_scope(
394+
env,
395+
Object::New(env->isolate()),
396+
{ 1, 0 },
397+
InternalCallbackScope::kSkipAsyncHooks);
398+
399+
if (cb != nullptr) {
400+
EscapableHandleScope scope(env->isolate());
401+
402+
if (StartExecution(env, "internal/bootstrap/environment").IsEmpty())
403+
return {};
404+
405+
StartExecutionCallbackInfo info = {
406+
env->process_object(),
407+
env->native_module_require(),
408+
};
409+
410+
return scope.EscapeMaybe(cb(info));
411+
}
412+
398413
// To allow people to extend Node in different ways, this hook allows
399414
// one to drop a file lib/_third_party_main.js into the build
400415
// directory which will be executed instead of Node's normal loading.

src/node.h

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
#include "node_version.h" // NODE_MODULE_VERSION
7474

7575
#include <memory>
76+
#include <functional>
7677

7778
#define NODE_MAKE_VERSION(major, minor, patch) \
7879
((major) * 0x1000 + (minor) * 0x100 + (patch))
@@ -417,12 +418,20 @@ NODE_EXTERN std::unique_ptr<InspectorParentHandle> GetInspectorParentHandle(
417418
ThreadId child_thread_id,
418419
const char* child_url);
419420

420-
// TODO(addaleax): Deprecate this in favour of the MaybeLocal<> overload
421-
// and provide a more flexible approach than third_party_main.
421+
struct StartExecutionCallbackInfo {
422+
v8::Local<v8::Object> process_object;
423+
v8::Local<v8::Function> native_require;
424+
};
425+
426+
using StartExecutionCallback =
427+
std::function<v8::MaybeLocal<v8::Value>(const StartExecutionCallbackInfo&)>;
428+
429+
// TODO(addaleax): Deprecate this in favour of the MaybeLocal<> overload.
422430
NODE_EXTERN void LoadEnvironment(Environment* env);
423431
NODE_EXTERN v8::MaybeLocal<v8::Value> LoadEnvironment(
424432
Environment* env,
425-
std::unique_ptr<InspectorParentHandle> inspector_parent_handle);
433+
StartExecutionCallback cb,
434+
std::unique_ptr<InspectorParentHandle> inspector_parent_handle = {});
426435
NODE_EXTERN void FreeEnvironment(Environment* env);
427436

428437
// This may return nullptr if context is not associated with a Node instance.

src/node_internals.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,9 +301,10 @@ void DefineZlibConstants(v8::Local<v8::Object> target);
301301
v8::Isolate* NewIsolate(v8::Isolate::CreateParams* params,
302302
uv_loop_t* event_loop,
303303
MultiIsolatePlatform* platform);
304-
v8::MaybeLocal<v8::Value> StartExecution(Environment* env);
304+
// This overload automatically picks the right 'main_script_id' if no callback
305+
// was provided by the embedder.
305306
v8::MaybeLocal<v8::Value> StartExecution(Environment* env,
306-
const char* main_script_id);
307+
StartExecutionCallback cb = nullptr);
307308
v8::MaybeLocal<v8::Object> GetPerContextExports(v8::Local<v8::Context> context);
308309
v8::MaybeLocal<v8::Value> ExecuteBootstrapper(
309310
Environment* env,

src/node_worker.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ void Worker::Run() {
333333
CreateEnvMessagePort(env_.get());
334334
Debug(this, "Created message port for worker %llu", thread_id_.id);
335335
if (LoadEnvironment(env_.get(),
336+
nullptr,
336337
std::move(inspector_parent_handle_))
337338
.IsEmpty()) {
338339
return;

test/cctest/test_environment.cc

Lines changed: 58 additions & 0 deletions

0 commit comments

Comments
 (0)