module: initialize module_wrap.callbackMap during pre-execution

Since the bootstrap does not actually use ESM at all, there
is no need to create this map so early. This patch moves
the initialization of the map to pre-execution,
so that the only binding loaded in loaders is native_module.
In addition, switch to SafeWeakMap.

PR-URL: https://github.com/nodejs/node/pull/27323
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
This commit is contained in:
Joyee Cheung 2019-04-20 21:45:18 +08:00
parent b9f1e57201
commit 80c0b89bbb
No known key found for this signature in database
GPG Key ID: 92B78A53C8303B8D
7 changed files with 12 additions and 14 deletions

View File

@ -135,9 +135,6 @@ let internalBinding;
}; };
} }
// Create this WeakMap in js-land because V8 has no C++ API for WeakMap.
internalBinding('module_wrap').callbackMap = new WeakMap();
// Think of this as module.exports in this file even though it is not // Think of this as module.exports in this file even though it is not
// written in CommonJS style. // written in CommonJS style.
const loaderExports = { const loaderExports = {

View File

@ -1,6 +1,6 @@
'use strict'; 'use strict';
const { Object } = primordials; const { Object, SafeWeakMap } = primordials;
const { getOptionValue } = require('internal/options'); const { getOptionValue } = require('internal/options');
const { Buffer } = require('buffer'); const { Buffer } = require('buffer');
@ -342,6 +342,9 @@ function initializeCJSLoader() {
} }
function initializeESMLoader() { function initializeESMLoader() {
// Create this WeakMap in js-land because V8 has no C++ API for WeakMap.
internalBinding('module_wrap').callbackMap = new SafeWeakMap();
const experimentalModules = getOptionValue('--experimental-modules'); const experimentalModules = getOptionValue('--experimental-modules');
const experimentalVMModules = getOptionValue('--experimental-vm-modules'); const experimentalVMModules = getOptionValue('--experimental-vm-modules');
if (experimentalModules || experimentalVMModules) { if (experimentalModules || experimentalVMModules) {

View File

@ -2,7 +2,6 @@
const { ArrayPrototype } = primordials; const { ArrayPrototype } = primordials;
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
const debug = require('internal/util/debuglog').debuglog('esm'); const debug = require('internal/util/debuglog').debuglog('esm');
const createDynamicModule = (exports, url = '', evaluate) => { const createDynamicModule = (exports, url = '', evaluate) => {
@ -21,7 +20,7 @@ import.meta.exports.${name} = {
import.meta.done(); import.meta.done();
`; `;
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
const m = new ModuleWrap(source, `${url}`); const m = new ModuleWrap(source, `${url}`);
m.link(() => 0); m.link(() => 0);
m.instantiate(); m.instantiate();

View File

@ -7,7 +7,6 @@ const {
} = primordials; } = primordials;
const { NativeModule } = require('internal/bootstrap/loaders'); const { NativeModule } = require('internal/bootstrap/loaders');
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
const { const {
stripShebang, stripShebang,
stripBOM stripBOM
@ -45,6 +44,7 @@ async function importModuleDynamically(specifier, { url }) {
translators.set('module', async function moduleStrategy(url) { translators.set('module', async function moduleStrategy(url) {
const source = `${await readFileAsync(new URL(url))}`; const source = `${await readFileAsync(new URL(url))}`;
debug(`Translating StandardModule ${url}`); debug(`Translating StandardModule ${url}`);
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
const module = new ModuleWrap(stripShebang(source), url); const module = new ModuleWrap(stripShebang(source), url);
callbackMap.set(module, { callbackMap.set(module, {
initializeImportMeta, initializeImportMeta,

View File

@ -1,8 +1,5 @@
'use strict'; 'use strict';
const {
callbackMap,
} = internalBinding('module_wrap');
const { const {
ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING, ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING,
} = require('internal/errors').codes; } = require('internal/errors').codes;
@ -14,6 +11,7 @@ const {
} = require('internal/vm/source_text_module'); } = require('internal/vm/source_text_module');
exports.initializeImportMetaObject = function(wrap, meta) { exports.initializeImportMetaObject = function(wrap, meta) {
const { callbackMap } = internalBinding('module_wrap');
if (callbackMap.has(wrap)) { if (callbackMap.has(wrap)) {
const { initializeImportMeta } = callbackMap.get(wrap); const { initializeImportMeta } = callbackMap.get(wrap);
if (initializeImportMeta !== undefined) { if (initializeImportMeta !== undefined) {
@ -23,6 +21,7 @@ exports.initializeImportMetaObject = function(wrap, meta) {
}; };
exports.importModuleDynamicallyCallback = async function(wrap, specifier) { exports.importModuleDynamicallyCallback = async function(wrap, specifier) {
const { callbackMap } = internalBinding('module_wrap');
if (callbackMap.has(wrap)) { if (callbackMap.has(wrap)) {
const { importModuleDynamically } = callbackMap.get(wrap); const { importModuleDynamically } = callbackMap.get(wrap);
if (importModuleDynamically !== undefined) { if (importModuleDynamically !== undefined) {

View File

@ -25,16 +25,16 @@ const {
validateString validateString
} = require('internal/validators'); } = require('internal/validators');
const binding = internalBinding('module_wrap');
const { const {
ModuleWrap, ModuleWrap,
callbackMap,
kUninstantiated, kUninstantiated,
kInstantiating, kInstantiating,
kInstantiated, kInstantiated,
kEvaluating, kEvaluating,
kEvaluated, kEvaluated,
kErrored, kErrored,
} = internalBinding('module_wrap'); } = binding;
const STATUS_MAP = { const STATUS_MAP = {
[kUninstantiated]: 'uninstantiated', [kUninstantiated]: 'uninstantiated',
@ -116,7 +116,7 @@ class SourceTextModule {
linkingStatusMap.set(this, 'unlinked'); linkingStatusMap.set(this, 'unlinked');
wrapToModuleMap.set(wrap, this); wrapToModuleMap.set(wrap, this);
callbackMap.set(wrap, { binding.callbackMap.set(wrap, {
initializeImportMeta, initializeImportMeta,
importModuleDynamically: importModuleDynamically ? async (...args) => { importModuleDynamically: importModuleDynamically ? async (...args) => {
const m = await importModuleDynamically(...args); const m = await importModuleDynamically(...args);

View File

@ -29,7 +29,6 @@ const {
isContext: _isContext, isContext: _isContext,
compileFunction: _compileFunction compileFunction: _compileFunction
} = internalBinding('contextify'); } = internalBinding('contextify');
const { callbackMap } = internalBinding('module_wrap');
const { const {
ERR_INVALID_ARG_TYPE, ERR_INVALID_ARG_TYPE,
ERR_VM_MODULE_NOT_MODULE, ERR_VM_MODULE_NOT_MODULE,
@ -100,6 +99,7 @@ class Script extends ContextifyScript {
} }
const { wrapMap, linkingStatusMap } = const { wrapMap, linkingStatusMap } =
require('internal/vm/source_text_module'); require('internal/vm/source_text_module');
const { callbackMap } = internalBinding('module_wrap');
callbackMap.set(this, { importModuleDynamically: async (...args) => { callbackMap.set(this, { importModuleDynamically: async (...args) => {
const m = await importModuleDynamically(...args); const m = await importModuleDynamically(...args);
if (isModuleNamespaceObject(m)) { if (isModuleNamespaceObject(m)) {