From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Samuel Attard Date: Wed, 8 Mar 2023 13:02:17 -0800 Subject: chore: expose ImportModuleDynamically and HostInitializeImportMetaObjectCallback to embedders This also subtly changes the behavior of shouldNotRegisterESMLoader to ensure that node sets up the handlers internally but simply avoids setting its own handlers on the Isolate. This is so that Electron can set it to its own blended handler between Node and Blink. Not upstreamable. diff --git a/lib/internal/modules/esm/utils.js b/lib/internal/modules/esm/utils.js index a9076a7ae941284d4585829292e2ece25c2b90e4..7335fe20f34fdd822276575686379dd954f1c8e1 100644 --- a/lib/internal/modules/esm/utils.js +++ b/lib/internal/modules/esm/utils.js @@ -34,7 +34,7 @@ const { ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING, ERR_INVALID_ARG_VALUE, } = require('internal/errors').codes; -const { getOptionValue } = require('internal/options'); +const { getOptionValue, getEmbedderOptions } = require('internal/options'); const { emitExperimentalWarning, kEmptyObject, @@ -285,12 +285,13 @@ let _shouldSpawnLoaderHookWorker = true; * should be spawned later. */ function initializeESM(shouldSpawnLoaderHookWorker = true) { + const shouldSetOnIsolate = !getEmbedderOptions().shouldNotRegisterESMLoader; _shouldSpawnLoaderHookWorker = shouldSpawnLoaderHookWorker; initializeDefaultConditions(); // Setup per-realm callbacks that locate data or callbacks that we keep // track of for different ESM modules. - setInitializeImportMetaObjectCallback(initializeImportMetaObject); - setImportModuleDynamicallyCallback(importModuleDynamicallyCallback); + setInitializeImportMetaObjectCallback(initializeImportMetaObject, shouldSetOnIsolate); + setImportModuleDynamicallyCallback(importModuleDynamicallyCallback, shouldSetOnIsolate); } /** diff --git a/src/module_wrap.cc b/src/module_wrap.cc index 26e6bcfa30be8b22b20e66ffe2f8d0b7d60fc6cc..fa2f28989be19e8ea8f53b990ae96be92ef3c3a3 100644 --- a/src/module_wrap.cc +++ b/src/module_wrap.cc @@ -1098,7 +1098,7 @@ Maybe ModuleWrap::ResolveModule( return Just(module_wrap); } -static MaybeLocal ImportModuleDynamicallyWithPhase( +MaybeLocal ImportModuleDynamicallyWithPhase( Local context, Local host_defined_options, Local resource_name, @@ -1186,14 +1186,16 @@ void ModuleWrap::SetImportModuleDynamicallyCallback( Realm* realm = Realm::GetCurrent(args); HandleScope handle_scope(isolate); - CHECK_EQ(args.Length(), 1); + CHECK_EQ(args.Length(), 2); CHECK(args[0]->IsFunction()); Local import_callback = args[0].As(); realm->set_host_import_module_dynamically_callback(import_callback); - isolate->SetHostImportModuleDynamicallyCallback(ImportModuleDynamically); - isolate->SetHostImportModuleWithPhaseDynamicallyCallback( + if (args[1]->IsBoolean() && args[1]->BooleanValue(isolate)) { + isolate->SetHostImportModuleDynamicallyCallback(ImportModuleDynamically); + isolate->SetHostImportModuleWithPhaseDynamicallyCallback( ImportModuleDynamicallyWithPhase); + } } void ModuleWrap::HostInitializeImportMetaObjectCallback( @@ -1235,13 +1237,14 @@ void ModuleWrap::SetInitializeImportMetaObjectCallback( Realm* realm = Realm::GetCurrent(args); Isolate* isolate = realm->isolate(); - CHECK_EQ(args.Length(), 1); + CHECK_EQ(args.Length(), 2); CHECK(args[0]->IsFunction()); Local import_meta_callback = args[0].As(); realm->set_host_initialize_import_meta_object_callback(import_meta_callback); - isolate->SetHostInitializeImportMetaObjectCallback( - HostInitializeImportMetaObjectCallback); + if (args[1]->IsBoolean() && args[1]->BooleanValue(isolate)) + isolate->SetHostInitializeImportMetaObjectCallback( + HostInitializeImportMetaObjectCallback); } MaybeLocal ModuleWrap::SyntheticModuleEvaluationStepsCallback( diff --git a/src/module_wrap.h b/src/module_wrap.h index 03cf8d0e91d795aad6db9b11956d296ff4999f7e..45264c2ad58e37a73fd62addac7fb671eed6d502 100644 --- a/src/module_wrap.h +++ b/src/module_wrap.h @@ -8,6 +8,7 @@ #include #include #include "base_object.h" +#include "node.h" #include "v8-script.h" namespace node { @@ -92,7 +93,15 @@ struct ModuleCacheKey : public MemoryRetainer { hash(hash) {} }; -class ModuleWrap : public BaseObject { +NODE_EXTERN v8::MaybeLocal ImportModuleDynamicallyWithPhase( + v8::Local context, + v8::Local host_defined_options, + v8::Local resource_name, + v8::Local specifier, + v8::ModuleImportPhase phase, + v8::Local import_attributes); + +class NODE_EXTERN ModuleWrap : public BaseObject { using ResolveCache = std::unordered_map; @@ -157,6 +166,8 @@ class ModuleWrap : public BaseObject { static void CreateRequiredModuleFacade( const v8::FunctionCallbackInfo& args); + static ModuleWrap* GetFromModule(node::Environment*, v8::Local); + private: ModuleWrap(Realm* realm, v8::Local object, @@ -205,7 +216,6 @@ class ModuleWrap : public BaseObject { v8::Local specifier, v8::Local import_attributes, v8::Local referrer); - static ModuleWrap* GetFromModule(node::Environment*, v8::Local); // This method may throw a JavaScript exception, so the return type is // wrapped in a Maybe.