Skip to content

Commit 38aa7cc

Browse files
committed
src: get embedder options on-demand
Only query embedder options when they are needed so that the bootstrap remains as stateless as possible so that the bootstrap snapshot is controlled solely by configure options, and subsequent runtime changes should be done in pre-execution. PR-URL: #40357 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Shelley Vohr <shelley.vohr@gmail.com>
1 parent 6baea14 commit 38aa7cc

4 files changed

Lines changed: 48 additions & 30 deletions

File tree

‎lib/internal/bootstrap/pre_execution.js‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ const {
1111

1212
const{
1313
getOptionValue,
14-
noGlobalSearchPaths,
15-
shouldNotRegisterESMLoader,
14+
getEmbedderOptions,
1615
}=require('internal/options');
1716
const{ reconnectZeroFillToggle }=require('internal/buffer');
1817

@@ -421,7 +420,7 @@ function initializeWASI() {
421420

422421
functioninitializeCJSLoader(){
423422
constCJSLoader=require('internal/modules/cjs/loader');
424-
if(!noGlobalSearchPaths){
423+
if(!getEmbedderOptions().noGlobalSearchPaths){
425424
CJSLoader.Module._initPaths();
426425
}
427426
// TODO(joyeecheung): deprecate this in favor of a proper hook?
@@ -433,7 +432,7 @@ function initializeESMLoader() {
433432
// Create this WeakMap in js-land because V8 has no C++ API for WeakMap.
434433
internalBinding('module_wrap').callbackMap=newSafeWeakMap();
435434

436-
if(shouldNotRegisterESMLoader)return;
435+
if(getEmbedderOptions().shouldNotRegisterESMLoader)return;
437436

438437
const{
439438
setImportModuleDynamicallyCallback,

‎lib/internal/options.js‎

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,43 @@
11
'use strict';
22

33
const{
4-
getOptions,
5-
noGlobalSearchPaths,
6-
shouldNotRegisterESMLoader,
4+
getCLIOptions,
5+
getEmbedderOptions: getEmbedderOptionsFromBinding,
76
}=internalBinding('options');
87

98
letwarnOnAllowUnauthorized=true;
109

1110
letoptionsMap;
1211
letaliasesMap;
12+
letembedderOptions;
1313

14-
// getOptions() would serialize the option values from C++ land.
14+
// getCLIOptions() would serialize the option values from C++ land.
1515
// It would error if the values are queried before bootstrap is
1616
// complete so that we don't accidentally include runtime-dependent
1717
// states into a runtime-independent snapshot.
18-
functiongetOptionsFromBinding(){
18+
functiongetCLIOptionsFromBinding(){
1919
if(!optionsMap){
20-
({options: optionsMap}=getOptions());
20+
({options: optionsMap}=getCLIOptions());
2121
}
2222
returnoptionsMap;
2323
}
2424

2525
functiongetAliasesFromBinding(){
2626
if(!aliasesMap){
27-
({aliases: aliasesMap}=getOptions());
27+
({aliases: aliasesMap}=getCLIOptions());
2828
}
2929
returnaliasesMap;
3030
}
3131

32+
functiongetEmbedderOptions(){
33+
if(!embedderOptions){
34+
embedderOptions=getEmbedderOptionsFromBinding();
35+
}
36+
returnembedderOptions;
37+
}
38+
3239
functiongetOptionValue(optionName){
33-
constoptions=getOptionsFromBinding();
40+
constoptions=getCLIOptionsFromBinding();
3441
if(optionName.startsWith('--no-')){
3542
constoption=options.get('--'+optionName.slice(5));
3643
returnoption&&!option.value;
@@ -54,13 +61,12 @@ function getAllowUnauthorized() {
5461

5562
module.exports={
5663
getoptions(){
57-
returngetOptionsFromBinding();
64+
returngetCLIOptionsFromBinding();
5865
},
5966
getaliases(){
6067
returngetAliasesFromBinding();
6168
},
6269
getOptionValue,
6370
getAllowUnauthorized,
64-
noGlobalSearchPaths,
65-
shouldNotRegisterESMLoader,
71+
getEmbedderOptions
6672
};

‎src/node_options.cc‎

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -920,7 +920,7 @@ std::string GetBashCompletion() {
920920

921921
// Return a map containing all the options and their metadata as well
922922
// as the aliases
923-
voidGetOptions(const FunctionCallbackInfo<Value>& args) {
923+
voidGetCLIOptions(const FunctionCallbackInfo<Value>& args) {
924924
Mutex::ScopedLock lock(per_process::cli_options_mutex);
925925
Environment* env = Environment::GetCurrent(args);
926926
if (!env->has_run_bootstrapping_code()) {
@@ -1061,13 +1061,38 @@ void GetOptions(const FunctionCallbackInfo<Value>& args) {
10611061
args.GetReturnValue().Set(ret);
10621062
}
10631063

1064+
voidGetEmbedderOptions(const FunctionCallbackInfo<Value>& args) {
1065+
Environment* env = Environment::GetCurrent(args);
1066+
if (!env->has_run_bootstrapping_code()) {
1067+
// No code because this is an assertion.
1068+
return env->ThrowError(
1069+
"Should not query options before bootstrapping is done");
1070+
}
1071+
Isolate* isolate = args.GetIsolate();
1072+
Local<Context> context = env->context();
1073+
Local<Object> ret = Object::New(isolate);
1074+
1075+
if (ret->Set(context,
1076+
FIXED_ONE_BYTE_STRING(env->isolate(), "shouldNotRegisterESMLoader"),
1077+
Boolean::New(isolate, env->should_not_register_esm_loader()))
1078+
.IsNothing()) return;
1079+
1080+
if (ret->Set(context,
1081+
FIXED_ONE_BYTE_STRING(env->isolate(), "noGlobalSearchPaths"),
1082+
Boolean::New(isolate, env->no_global_search_paths()))
1083+
.IsNothing()) return;
1084+
1085+
args.GetReturnValue().Set(ret);
1086+
}
1087+
10641088
voidInitialize(Local<Object> target,
10651089
Local<Value> unused,
10661090
Local<Context> context,
10671091
void* priv) {
10681092
Environment* env = Environment::GetCurrent(context);
10691093
Isolate* isolate = env->isolate();
1070-
env->SetMethodNoSideEffect(target, "getOptions", GetOptions);
1094+
env->SetMethodNoSideEffect(target, "getCLIOptions", GetCLIOptions);
1095+
env->SetMethodNoSideEffect(target, "getEmbedderOptions", GetEmbedderOptions);
10711096

10721097
Local<Object> env_settings = Object::New(isolate);
10731098
NODE_DEFINE_CONSTANT(env_settings, kAllowedInEnvironment);
@@ -1077,18 +1102,6 @@ void Initialize(Local<Object> target,
10771102
context, FIXED_ONE_BYTE_STRING(isolate, "envSettings"), env_settings)
10781103
.Check();
10791104

1080-
target
1081-
->Set(context,
1082-
FIXED_ONE_BYTE_STRING(env->isolate(), "shouldNotRegisterESMLoader"),
1083-
Boolean::New(isolate, env->should_not_register_esm_loader()))
1084-
.Check();
1085-
1086-
target
1087-
->Set(context,
1088-
FIXED_ONE_BYTE_STRING(env->isolate(), "noGlobalSearchPaths"),
1089-
Boolean::New(isolate, env->no_global_search_paths()))
1090-
.Check();
1091-
10921105
Local<Object> types = Object::New(isolate);
10931106
NODE_DEFINE_CONSTANT(types, kNoOp);
10941107
NODE_DEFINE_CONSTANT(types, kV8Option);

‎src/node_options.h‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ class OptionsParser {
462462
template <typename OtherOptions>
463463
friendclassOptionsParser;
464464

465-
friendvoidGetOptions(const v8::FunctionCallbackInfo<v8::Value>& args);
465+
friendvoidGetCLIOptions(const v8::FunctionCallbackInfo<v8::Value>& args);
466466
friend std::string GetBashCompletion();
467467
};
468468

0 commit comments

Comments
 (0)