Skip to content

Commit e83051c

Browse files
joyeecheungpanva
authored andcommitted
modules: move callbacks and conditions into modules/esm/utils.js
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#45849 Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
1 parent 722b958 commit e83051c

11 files changed

Lines changed: 130 additions & 91 deletions

File tree

lib/internal/modules/esm/create_dynamic_module.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ ${ArrayPrototypeJoin(ArrayPrototypeMap(imports, createImport), '\n')}
3535
${ArrayPrototypeJoin(ArrayPrototypeMap(exports, createExport), '\n')}
3636
import.meta.done();
3737
`;
38-
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
38+
const { ModuleWrap } = internalBinding('module_wrap');
3939
const m = new ModuleWrap(`${url}`, undefined, source, 0, 0);
4040

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

4747
if (imports.length)
4848
reflect.imports = ObjectCreate(null);
49-
50-
callbackMap.set(m, {
49+
const { setCallbackForWrap } = require('internal/modules/esm/utils');
50+
setCallbackForWrap(m, {
5151
initializeImportMeta: (meta, wrap) => {
5252
meta.exports = reflect.exports;
5353
if (reflect.imports)

lib/internal/modules/esm/loader.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,12 @@ function newModuleMap() {
4747

4848
const {
4949
defaultResolve,
50-
DEFAULT_CONDITIONS,
5150
} = require('internal/modules/esm/resolve');
5251

52+
const {
53+
getDefaultConditions,
54+
} = require('internal/modules/esm/utils');
55+
5356
function getTranslators() {
5457
const { translators } = require('internal/modules/esm/translators');
5558
return translators;
@@ -375,9 +378,10 @@ class ESMLoader {
375378
url = pathToFileURL(`${process.cwd()}/[eval${++this.evalIndex}]`).href
376379
) {
377380
const evalInstance = (url) => {
378-
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
381+
const { ModuleWrap } = internalBinding('module_wrap');
382+
const { setCallbackForWrap } = require('internal/modules/esm/utils');
379383
const module = new ModuleWrap(url, undefined, source, 0, 0);
380-
callbackMap.set(module, {
384+
setCallbackForWrap(module, {
381385
importModuleDynamically: (specifier, { url }, importAssertions) => {
382386
return this.import(specifier, url, importAssertions);
383387
}
@@ -805,7 +809,7 @@ class ESMLoader {
805809
}
806810
const chain = this.#hooks.resolve;
807811
const context = {
808-
conditions: DEFAULT_CONDITIONS,
812+
conditions: getDefaultConditions(),
809813
importAssertions,
810814
parentURL,
811815
};

lib/internal/modules/esm/resolve.js

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const {
77
ArrayPrototypeShift,
88
JSONParse,
99
JSONStringify,
10-
ObjectFreeze,
1110
ObjectGetOwnPropertyNames,
1211
ObjectPrototypeHasOwnProperty,
1312
RegExp,
@@ -47,7 +46,6 @@ const typeFlag = getOptionValue('--input-type');
4746
const { URL, pathToFileURL, fileURLToPath } = require('internal/url');
4847
const {
4948
ERR_INPUT_TYPE_NOT_ALLOWED,
50-
ERR_INVALID_ARG_VALUE,
5149
ERR_INVALID_MODULE_SPECIFIER,
5250
ERR_INVALID_PACKAGE_CONFIG,
5351
ERR_INVALID_PACKAGE_TARGET,
@@ -63,25 +61,13 @@ const {
6361
const { Module: CJSModule } = require('internal/modules/cjs/loader');
6462
const packageJsonReader = require('internal/modules/package_json_reader');
6563
const { getPackageConfig, getPackageScopeConfig } = require('internal/modules/esm/package_config');
64+
const { getConditionsSet } = require('internal/modules/esm/utils');
6665

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

7170

72-
const userConditions = getOptionValue('--conditions');
73-
const noAddons = getOptionValue('--no-addons');
74-
const addonConditions = noAddons ? [] : ['node-addons'];
75-
76-
const DEFAULT_CONDITIONS = ObjectFreeze([
77-
'node',
78-
'import',
79-
...addonConditions,
80-
...userConditions,
81-
]);
82-
83-
const DEFAULT_CONDITIONS_SET = new SafeSet(DEFAULT_CONDITIONS);
84-
8571
const emittedPackageWarnings = new SafeSet();
8672

8773
function emitTrailingSlashPatternDeprecation(match, pjsonUrl, base) {
@@ -151,21 +137,6 @@ function emitLegacyIndexDeprecation(url, packageJSONUrl, base, main) {
151137
);
152138
}
153139

154-
/**
155-
* @param {string[]} [conditions]
156-
* @returns {Set<string>}
157-
*/
158-
function getConditionsSet(conditions) {
159-
if (conditions !== undefined && conditions !== DEFAULT_CONDITIONS) {
160-
if (!ArrayIsArray(conditions)) {
161-
throw new ERR_INVALID_ARG_VALUE('conditions', conditions,
162-
'expected an array');
163-
}
164-
return new SafeSet(conditions);
165-
}
166-
return DEFAULT_CONDITIONS_SET;
167-
}
168-
169140
const realpathCache = new SafeMap();
170141

171142
/**
@@ -1190,7 +1161,6 @@ async function defaultResolve(specifier, context = {}) {
11901161
}
11911162

11921163
module.exports = {
1193-
DEFAULT_CONDITIONS,
11941164
defaultResolve,
11951165
encodedSepRegEx,
11961166
getPackageScopeConfig,

lib/internal/modules/esm/translators.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,8 @@ translators.set('module', async function moduleStrategy(url, source, isMain) {
115115
maybeCacheSourceMap(url, source);
116116
debug(`Translating StandardModule ${url}`);
117117
const module = new ModuleWrap(url, undefined, source, 0, 0);
118-
moduleWrap.callbackMap.set(module, {
118+
const { setCallbackForWrap } = require('internal/modules/esm/utils');
119+
setCallbackForWrap(module, {
119120
initializeImportMeta: (meta, wrap) => this.importMetaInitialize(meta, { url }),
120121
importModuleDynamically,
121122
});

lib/internal/modules/esm/utils.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
'use strict';
2+
const {
3+
ArrayIsArray,
4+
SafeSet,
5+
SafeWeakMap,
6+
ObjectFreeze,
7+
} = primordials;
8+
9+
const {
10+
ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING,
11+
ERR_INVALID_ARG_VALUE,
12+
} = require('internal/errors').codes;
13+
14+
const { getOptionValue } = require('internal/options');
15+
16+
const {
17+
setImportModuleDynamicallyCallback,
18+
setInitializeImportMetaObjectCallback
19+
} = internalBinding('module_wrap');
20+
const {
21+
getModuleFromWrap,
22+
} = require('internal/vm/module');
23+
const assert = require('internal/assert');
24+
25+
const callbackMap = new SafeWeakMap();
26+
function setCallbackForWrap(wrap, data) {
27+
callbackMap.set(wrap, data);
28+
}
29+
30+
let defaultConditions;
31+
function getDefaultConditions() {
32+
assert(defaultConditions !== undefined);
33+
return defaultConditions;
34+
}
35+
36+
let defaultConditionsSet;
37+
function getDefaultConditionsSet() {
38+
assert(defaultConditionsSet !== undefined);
39+
return defaultConditionsSet;
40+
}
41+
42+
// This function is called during pre-execution, before any user code is run.
43+
function initializeDefaultConditions() {
44+
const userConditions = getOptionValue('--conditions');
45+
const noAddons = getOptionValue('--no-addons');
46+
const addonConditions = noAddons ? [] : ['node-addons'];
47+
48+
defaultConditions = ObjectFreeze([
49+
'node',
50+
'import',
51+
...addonConditions,
52+
...userConditions,
53+
]);
54+
defaultConditionsSet = new SafeSet(defaultConditions);
55+
}
56+
57+
/**
58+
* @param {string[]} [conditions]
59+
* @returns {Set<string>}
60+
*/
61+
function getConditionsSet(conditions) {
62+
if (conditions !== undefined && conditions !== getDefaultConditions()) {
63+
if (!ArrayIsArray(conditions)) {
64+
throw new ERR_INVALID_ARG_VALUE('conditions', conditions,
65+
'expected an array');
66+
}
67+
return new SafeSet(conditions);
68+
}
69+
return getDefaultConditionsSet();
70+
}
71+
72+
function initializeImportMetaObject(wrap, meta) {
73+
if (callbackMap.has(wrap)) {
74+
const { initializeImportMeta } = callbackMap.get(wrap);
75+
if (initializeImportMeta !== undefined) {
76+
initializeImportMeta(meta, getModuleFromWrap(wrap) || wrap);
77+
}
78+
}
79+
}
80+
81+
async function importModuleDynamicallyCallback(wrap, specifier, assertions) {
82+
if (callbackMap.has(wrap)) {
83+
const { importModuleDynamically } = callbackMap.get(wrap);
84+
if (importModuleDynamically !== undefined) {
85+
return importModuleDynamically(
86+
specifier, getModuleFromWrap(wrap) || wrap, assertions);
87+
}
88+
}
89+
throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING();
90+
}
91+
92+
function initializeESM() {
93+
initializeDefaultConditions();
94+
// Setup per-isolate callbacks that locate data or callbacks that we keep
95+
// track of for different ESM modules.
96+
setInitializeImportMetaObjectCallback(initializeImportMetaObject);
97+
setImportModuleDynamicallyCallback(importModuleDynamicallyCallback);
98+
}
99+
100+
module.exports = {
101+
setCallbackForWrap,
102+
initializeESM,
103+
getDefaultConditions,
104+
getConditionsSet,
105+
};

lib/internal/process/esm_loader.js

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,11 @@ const {
44
ObjectCreate,
55
} = primordials;
66

7-
const {
8-
ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING,
9-
} = require('internal/errors').codes;
107
const { ESMLoader } = require('internal/modules/esm/loader');
118
const {
129
hasUncaughtExceptionCaptureCallback,
1310
} = require('internal/process/execution');
1411
const { pathToFileURL } = require('internal/url');
15-
const {
16-
getModuleFromWrap,
17-
} = require('internal/vm/module');
18-
19-
exports.initializeImportMetaObject = function(wrap, meta) {
20-
const { callbackMap } = internalBinding('module_wrap');
21-
if (callbackMap.has(wrap)) {
22-
const { initializeImportMeta } = callbackMap.get(wrap);
23-
if (initializeImportMeta !== undefined) {
24-
initializeImportMeta(meta, getModuleFromWrap(wrap) || wrap);
25-
}
26-
}
27-
};
28-
29-
exports.importModuleDynamicallyCallback =
30-
async function importModuleDynamicallyCallback(wrap, specifier, assertions) {
31-
const { callbackMap } = internalBinding('module_wrap');
32-
if (callbackMap.has(wrap)) {
33-
const { importModuleDynamically } = callbackMap.get(wrap);
34-
if (importModuleDynamically !== undefined) {
35-
return importModuleDynamically(
36-
specifier, getModuleFromWrap(wrap) || wrap, assertions);
37-
}
38-
}
39-
throw new ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING();
40-
};
4112

4213
const esmLoader = new ESMLoader();
4314
exports.esmLoader = esmLoader;

lib/internal/process/pre_execution.js

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const {
55
ObjectDefineProperties,
66
ObjectDefineProperty,
77
SafeMap,
8-
SafeWeakMap,
98
StringPrototypeStartsWith,
109
globalThis,
1110
} = primordials;
@@ -561,20 +560,10 @@ function initializeCJSLoader() {
561560
}
562561

563562
function initializeESMLoader() {
564-
// Create this WeakMap in js-land because V8 has no C++ API for WeakMap.
565-
internalBinding('module_wrap').callbackMap = new SafeWeakMap();
566-
567563
if (getEmbedderOptions().shouldNotRegisterESMLoader) return;
568564

569-
const {
570-
setImportModuleDynamicallyCallback,
571-
setInitializeImportMetaObjectCallback
572-
} = internalBinding('module_wrap');
573-
const esm = require('internal/process/esm_loader');
574-
// Setup per-isolate callbacks that locate data or callbacks that we keep
575-
// track of for different ESM modules.
576-
setInitializeImportMetaObjectCallback(esm.initializeImportMetaObject);
577-
setImportModuleDynamicallyCallback(esm.importModuleDynamicallyCallback);
565+
const { initializeESM } = require('internal/modules/esm/utils');
566+
initializeESM();
578567

579568
// Patch the vm module when --experimental-vm-modules is on.
580569
// Please update the comments in vm.js when this block changes.

lib/internal/vm.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,11 @@ function internalCompileFunction(code, params, options) {
9393
if (importModuleDynamically !== undefined) {
9494
validateFunction(importModuleDynamically,
9595
'options.importModuleDynamically');
96-
const { importModuleDynamicallyWrap } =
97-
require('internal/vm/module');
98-
const { callbackMap } = internalBinding('module_wrap');
96+
const { importModuleDynamicallyWrap } = require('internal/vm/module');
9997
const wrapped = importModuleDynamicallyWrap(importModuleDynamically);
10098
const func = result.function;
101-
callbackMap.set(result.cacheKey, {
99+
const { setCallbackForWrap } = require('internal/modules/esm/utils');
100+
setCallbackForWrap(result.cacheKey, {
102101
importModuleDynamically: (s, _k, i) => wrapped(s, func, i),
103102
});
104103
}

lib/internal/vm/module.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ class Module {
125125
this[kWrap] = new ModuleWrap(identifier, context, sourceText,
126126
options.lineOffset, options.columnOffset,
127127
options.cachedData);
128-
129-
binding.callbackMap.set(this[kWrap], {
128+
const { setCallbackForWrap } = require('internal/modules/esm/utils');
129+
setCallbackForWrap(this[kWrap], {
130130
initializeImportMeta: options.initializeImportMeta,
131131
importModuleDynamically: options.importModuleDynamically ?
132132
importModuleDynamicallyWrap(options.importModuleDynamically) :

lib/vm.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,9 @@ class Script extends ContextifyScript {
111111
if (importModuleDynamically !== undefined) {
112112
validateFunction(importModuleDynamically,
113113
'options.importModuleDynamically');
114-
const { importModuleDynamicallyWrap } =
115-
require('internal/vm/module');
116-
const { callbackMap } = internalBinding('module_wrap');
117-
callbackMap.set(this, {
114+
const { importModuleDynamicallyWrap } = require('internal/vm/module');
115+
const { setCallbackForWrap } = require('internal/modules/esm/utils');
116+
setCallbackForWrap(this, {
118117
importModuleDynamically:
119118
importModuleDynamicallyWrap(importModuleDynamically),
120119
});

0 commit comments

Comments
 (0)