Skip to content

Commit

Permalink
module: move callbacks and conditions into
Browse files Browse the repository at this point in the history
This moves the following utils into modules/esm/utils.js:

- Code related to default conditions
- The callbackMap (which is now created in the module instead of
  hanging off the module_wrap binding, since the C++ land
  does not need it).
- Per-isolate module callbacks

These are self-contained code that can be included into the
built-in snapshot.

PR-URL: nodejs/node#45849
Backport-PR-URL: nodejs/node#46425
Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
  • Loading branch information
sercher committed Apr 25, 2024
1 parent 558499b commit 584c382
Show file tree
Hide file tree
Showing 10 changed files with 25 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ ${ArrayPrototypeJoin(ArrayPrototypeMap(imports, createImport), '\n')}
${ArrayPrototypeJoin(ArrayPrototypeMap(exports, createExport), '\n')}
import.meta.done();
`;
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
const { ModuleWrap } = internalBinding('module_wrap');
const m = new ModuleWrap(`${url}`, undefined, source, 0, 0);

const readyfns = new SafeSet();
Expand All @@ -46,8 +46,8 @@ import.meta.done();

if (imports.length)
reflect.imports = ObjectCreate(null);

callbackMap.set(m, {
const { setCallbackForWrap } = require('internal/modules/esm/utils');
setCallbackForWrap(m, {
initializeImportMeta: (meta, wrap) => {
meta.exports = reflect.exports;
if (reflect.imports)
Expand Down
12 changes: 8 additions & 4 deletions graal-nodejs/lib/internal/modules/esm/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,12 @@ function newModuleMap() {

const {
defaultResolve,
DEFAULT_CONDITIONS,
} = require('internal/modules/esm/resolve');

const {
getDefaultConditions,
} = require('internal/modules/esm/utils');

function getTranslators() {
const { translators } = require('internal/modules/esm/translators');
return translators;
Expand Down Expand Up @@ -375,9 +378,10 @@ class ESMLoader {
url = pathToFileURL(`${process.cwd()}/[eval${++this.evalIndex}]`).href,
) {
const evalInstance = (url) => {
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
const { ModuleWrap } = internalBinding('module_wrap');
const { setCallbackForWrap } = require('internal/modules/esm/utils');
const module = new ModuleWrap(url, undefined, source, 0, 0);
callbackMap.set(module, {
setCallbackForWrap(module, {
importModuleDynamically: (specifier, { url }, importAssertions) => {
return this.import(specifier, url, importAssertions);
},
Expand Down Expand Up @@ -802,7 +806,7 @@ class ESMLoader {
}
const chain = this.#hooks.resolve;
const context = {
conditions: DEFAULT_CONDITIONS,
conditions: getDefaultConditions(),
importAssertions,
parentURL,
};
Expand Down
32 changes: 1 addition & 31 deletions graal-nodejs/lib/internal/modules/esm/resolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ const {
ArrayPrototypeShift,
JSONParse,
JSONStringify,
ObjectFreeze,
ObjectGetOwnPropertyNames,
ObjectPrototypeHasOwnProperty,
RegExp,
Expand Down Expand Up @@ -46,7 +45,6 @@ const typeFlag = getOptionValue('--input-type');
const { URL, pathToFileURL, fileURLToPath } = require('internal/url');
const {
ERR_INPUT_TYPE_NOT_ALLOWED,
ERR_INVALID_ARG_VALUE,
ERR_INVALID_MODULE_SPECIFIER,
ERR_INVALID_PACKAGE_CONFIG,
ERR_INVALID_PACKAGE_TARGET,
Expand All @@ -61,25 +59,13 @@ const {
const { Module: CJSModule } = require('internal/modules/cjs/loader');
const packageJsonReader = require('internal/modules/package_json_reader');
const { getPackageConfig, getPackageScopeConfig } = require('internal/modules/esm/package_config');
const { getConditionsSet } = require('internal/modules/esm/utils');

/**
* @typedef {import('internal/modules/esm/package_config.js').PackageConfig} PackageConfig
*/


const userConditions = getOptionValue('--conditions');
const noAddons = getOptionValue('--no-addons');
const addonConditions = noAddons ? [] : ['node-addons'];

const DEFAULT_CONDITIONS = ObjectFreeze([
'node',
'import',
...addonConditions,
...userConditions,
]);

const DEFAULT_CONDITIONS_SET = new SafeSet(DEFAULT_CONDITIONS);

const emittedPackageWarnings = new SafeSet();

function emitTrailingSlashPatternDeprecation(match, pjsonUrl, base) {
Expand Down Expand Up @@ -150,21 +136,6 @@ function emitLegacyIndexDeprecation(url, packageJSONUrl, base, main) {
}
}

/**
* @param {string[]} [conditions]
* @returns {Set<string>}
*/
function getConditionsSet(conditions) {
if (conditions !== undefined && conditions !== DEFAULT_CONDITIONS) {
if (!ArrayIsArray(conditions)) {
throw new ERR_INVALID_ARG_VALUE('conditions', conditions,
'expected an array');
}
return new SafeSet(conditions);
}
return DEFAULT_CONDITIONS_SET;
}

const realpathCache = new SafeMap();

/**
Expand Down Expand Up @@ -1167,7 +1138,6 @@ async function defaultResolve(specifier, context = {}) {
}

module.exports = {
DEFAULT_CONDITIONS,
defaultResolve,
encodedSepRegEx,
getPackageScopeConfig,
Expand Down
3 changes: 2 additions & 1 deletion graal-nodejs/lib/internal/modules/esm/translators.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ translators.set('module', async function moduleStrategy(url, source, isMain) {
maybeCacheSourceMap(url, source);
debug(`Translating StandardModule ${url}`);
const module = new ModuleWrap(url, undefined, source, 0, 0);
moduleWrap.callbackMap.set(module, {
const { setCallbackForWrap } = require('internal/modules/esm/utils');
setCallbackForWrap(module, {
initializeImportMeta: (meta, wrap) => this.importMetaInitialize(meta, { url }),
importModuleDynamically,
});
Expand Down
29 changes: 0 additions & 29 deletions graal-nodejs/lib/internal/process/esm_loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,11 @@ const {
ObjectCreate,
} = primordials;

const {
ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING,
} = require('internal/errors').codes;
const { ESMLoader } = require('internal/modules/esm/loader');
const {
hasUncaughtExceptionCaptureCallback,
} = require('internal/process/execution');
const { pathToFileURL } = require('internal/url');
const {
getModuleFromWrap,
} = require('internal/vm/module');

exports.initializeImportMetaObject = function(wrap, meta) {
const { callbackMap } = internalBinding('module_wrap');
if (callbackMap.has(wrap)) {
const { initializeImportMeta } = callbackMap.get(wrap);
if (initializeImportMeta !== undefined) {
initializeImportMeta(meta, getModuleFromWrap(wrap) || wrap);
}
}
};

exports.importModuleDynamicallyCallback =
async function importModuleDynamicallyCallback(wrap, specifier, assertions) {
const { callbackMap } = internalBinding('module_wrap');
if (callbackMap.has(wrap)) {
const { importModuleDynamically } = callbackMap.get(wrap);
if (importModuleDynamically !== undefined) {
return importModuleDynamically(
specifier, getModuleFromWrap(wrap) || wrap, assertions);
}
}
throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING();
};

const esmLoader = new ESMLoader();
exports.esmLoader = esmLoader;
Expand Down
15 changes: 2 additions & 13 deletions graal-nodejs/lib/internal/process/pre_execution.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ const {
ObjectDefineProperties,
ObjectDefineProperty,
SafeMap,
SafeWeakMap,
StringPrototypeStartsWith,
Symbol,
SymbolDispose,
Expand Down Expand Up @@ -561,20 +560,10 @@ function initializeCJSLoader() {
}

function initializeESMLoader() {
// Create this WeakMap in js-land because V8 has no C++ API for WeakMap.
internalBinding('module_wrap').callbackMap = new SafeWeakMap();

if (getEmbedderOptions().shouldNotRegisterESMLoader) return;

const {
setImportModuleDynamicallyCallback,
setInitializeImportMetaObjectCallback,
} = internalBinding('module_wrap');
const esm = require('internal/process/esm_loader');
// Setup per-isolate callbacks that locate data or callbacks that we keep
// track of for different ESM modules.
setInitializeImportMetaObjectCallback(esm.initializeImportMetaObject);
setImportModuleDynamicallyCallback(esm.importModuleDynamicallyCallback);
const { initializeESM } = require('internal/modules/esm/utils');
initializeESM();

// Patch the vm module when --experimental-vm-modules is on.
// Please update the comments in vm.js when this block changes.
Expand Down
7 changes: 3 additions & 4 deletions graal-nodejs/lib/internal/vm.js
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,11 @@ function internalCompileFunction(code, params, options) {
if (importModuleDynamically !== undefined) {
validateFunction(importModuleDynamically,
'options.importModuleDynamically');
const { importModuleDynamicallyWrap } =
require('internal/vm/module');
const { callbackMap } = internalBinding('module_wrap');
const { importModuleDynamicallyWrap } = require('internal/vm/module');
const wrapped = importModuleDynamicallyWrap(importModuleDynamically);
const func = result.function;
callbackMap.set(result.cacheKey, {
const { setCallbackForWrap } = require('internal/modules/esm/utils');
setCallbackForWrap(result.cacheKey, {
importModuleDynamically: (s, _k, i) => wrapped(s, func, i),
});
}
Expand Down
4 changes: 2 additions & 2 deletions graal-nodejs/lib/internal/vm/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ class Module {
this[kWrap] = new ModuleWrap(identifier, context, sourceText,
options.lineOffset, options.columnOffset,
options.cachedData);

binding.callbackMap.set(this[kWrap], {
const { setCallbackForWrap } = require('internal/modules/esm/utils');
setCallbackForWrap(this[kWrap], {
initializeImportMeta: options.initializeImportMeta,
importModuleDynamically: options.importModuleDynamically ?
importModuleDynamicallyWrap(options.importModuleDynamically) :
Expand Down
7 changes: 3 additions & 4 deletions graal-nodejs/lib/vm.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,9 @@ class Script extends ContextifyScript {
if (importModuleDynamically !== undefined) {
validateFunction(importModuleDynamically,
'options.importModuleDynamically');
const { importModuleDynamicallyWrap } =
require('internal/vm/module');
const { callbackMap } = internalBinding('module_wrap');
callbackMap.set(this, {
const { importModuleDynamicallyWrap } = require('internal/vm/module');
const { setCallbackForWrap } = require('internal/modules/esm/utils');
setCallbackForWrap(this, {
importModuleDynamically:
importModuleDynamicallyWrap(importModuleDynamically),
});
Expand Down
1 change: 1 addition & 0 deletions graal-nodejs/test/parallel/test-bootstrap-modules.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const expectedModules = new Set([
'NativeModule internal/modules/esm/package_config',
'NativeModule internal/modules/esm/resolve',
'NativeModule internal/modules/esm/translators',
'NativeModule internal/modules/esm/utils',
'NativeModule internal/modules/package_json_reader',
'NativeModule internal/modules/run_main',
'NativeModule internal/net',
Expand Down

0 comments on commit 584c382

Please sign in to comment.