bootstrap: lazy load non-essential modules

It turns out that even with startup snapshots, there is a non-trivial
overhead for loading internal modules. This patch makes the loading
of the non-essential modules lazy again.

Caveat: we have to make some of the globals lazily-loaded too,
so the WPT runner is updated to test what the state of the global
scope is after the globals are accessed (and replaced with the
loaded value).

PR-URL: https://github.com/nodejs/node/pull/45659
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: Daeyeon Jeong <daeyeon.dev@gmail.com>
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
Reviewed-By: Tierney Cyren <hello@bnb.im>
This commit is contained in:
Joyee Cheung 2022-12-09 23:37:35 +01:00 committed by GitHub
parent 7d80ca3683
commit 265ea1e74e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 320 additions and 366 deletions

View File

@ -78,7 +78,8 @@ const {
isInsideNodeModules, isInsideNodeModules,
lazyDOMException, lazyDOMException,
normalizeEncoding, normalizeEncoding,
kIsEncodingSymbol kIsEncodingSymbol,
defineLazyProperties,
} = require('internal/util'); } = require('internal/util');
const { const {
isAnyArrayBuffer, isAnyArrayBuffer,
@ -121,15 +122,6 @@ const {
createUnsafeBuffer createUnsafeBuffer
} = require('internal/buffer'); } = require('internal/buffer');
const {
Blob,
resolveObjectURL,
} = require('internal/blob');
const {
File,
} = require('internal/file');
FastBuffer.prototype.constructor = Buffer; FastBuffer.prototype.constructor = Buffer;
Buffer.prototype = FastBuffer.prototype; Buffer.prototype = FastBuffer.prototype;
addBufferPrototypeMethods(Buffer.prototype); addBufferPrototypeMethods(Buffer.prototype);
@ -1323,9 +1315,6 @@ function atob(input) {
} }
module.exports = { module.exports = {
Blob,
File,
resolveObjectURL,
Buffer, Buffer,
SlowBuffer, SlowBuffer,
transcode, transcode,
@ -1352,3 +1341,14 @@ ObjectDefineProperties(module.exports, {
set(val) { INSPECT_MAX_BYTES = val; } set(val) { INSPECT_MAX_BYTES = val; }
} }
}); });
defineLazyProperties(
module.exports,
'internal/blob',
['Blob', 'resolveObjectURL']
);
defineLazyProperties(
module.exports,
'internal/file',
['File']
);

View File

@ -57,7 +57,6 @@ const {
const pathModule = require('path'); const pathModule = require('path');
const { isArrayBufferView } = require('internal/util/types'); const { isArrayBufferView } = require('internal/util/types');
const nonNativeWatcher = require('internal/fs/recursive_watch');
// We need to get the statValues from the binding at the callsite since // We need to get the statValues from the binding at the callsite since
// it's re-initialized after deserialization. // it's re-initialized after deserialization.
@ -84,6 +83,7 @@ const {
custom: kCustomPromisifiedSymbol, custom: kCustomPromisifiedSymbol,
}, },
SideEffectFreeRegExpPrototypeExec, SideEffectFreeRegExpPrototypeExec,
defineLazyProperties,
} = require('internal/util'); } = require('internal/util');
const { const {
constants: { constants: {
@ -119,11 +119,6 @@ const {
validateStringAfterArrayBufferView, validateStringAfterArrayBufferView,
warnOnNonPortableTemplate warnOnNonPortableTemplate
} = require('internal/fs/utils'); } = require('internal/fs/utils');
const {
Dir,
opendir,
opendirSync
} = require('internal/fs/dir');
const { const {
CHAR_FORWARD_SLASH, CHAR_FORWARD_SLASH,
CHAR_BACKWARD_SLASH, CHAR_BACKWARD_SLASH,
@ -140,9 +135,6 @@ const {
validateString, validateString,
} = require('internal/validators'); } = require('internal/validators');
const watchers = require('internal/fs/watchers');
const ReadFileContext = require('internal/fs/read_file_context');
let truncateWarn = true; let truncateWarn = true;
let fs; let fs;
@ -379,6 +371,7 @@ function checkAborted(signal, callback) {
function readFile(path, options, callback) { function readFile(path, options, callback) {
callback = maybeCallback(callback || options); callback = maybeCallback(callback || options);
options = getOptions(options, { flag: 'r' }); options = getOptions(options, { flag: 'r' });
const ReadFileContext = require('internal/fs/read_file_context');
const context = new ReadFileContext(callback, options.encoding); const context = new ReadFileContext(callback, options.encoding);
context.isUserFd = isFd(path); // File descriptor ownership context.isUserFd = isFd(path); // File descriptor ownership
@ -2298,11 +2291,12 @@ function watch(filename, options, listener) {
if (options.recursive === undefined) options.recursive = false; if (options.recursive === undefined) options.recursive = false;
let watcher; let watcher;
const watchers = require('internal/fs/watchers');
// TODO(anonrig): Remove non-native watcher when/if libuv supports recursive. // TODO(anonrig): Remove non-native watcher when/if libuv supports recursive.
// As of November 2022, libuv does not support recursive file watch on all platforms, // As of November 2022, libuv does not support recursive file watch on all platforms,
// e.g. Linux due to the limitations of inotify. // e.g. Linux due to the limitations of inotify.
if (options.recursive && !isOSX && !isWindows) { if (options.recursive && !isOSX && !isWindows) {
const nonNativeWatcher = require('internal/fs/recursive_watch');
watcher = new nonNativeWatcher.FSWatcher(options); watcher = new nonNativeWatcher.FSWatcher(options);
watcher[watchers.kFSWatchStart](filename); watcher[watchers.kFSWatchStart](filename);
} else { } else {
@ -2370,7 +2364,7 @@ function watchFile(filename, options, listener) {
validateFunction(listener, 'listener'); validateFunction(listener, 'listener');
stat = statWatchers.get(filename); stat = statWatchers.get(filename);
const watchers = require('internal/fs/watchers');
if (stat === undefined) { if (stat === undefined) {
stat = new watchers.StatWatcher(options.bigint); stat = new watchers.StatWatcher(options.bigint);
stat[watchers.kFSStatWatcherStart](filename, stat[watchers.kFSStatWatcherStart](filename,
@ -2396,7 +2390,7 @@ function unwatchFile(filename, listener) {
const stat = statWatchers.get(filename); const stat = statWatchers.get(filename);
if (stat === undefined) return; if (stat === undefined) return;
const watchers = require('internal/fs/watchers');
if (typeof listener === 'function') { if (typeof listener === 'function') {
const beforeListenerCount = stat.listenerCount('change'); const beforeListenerCount = stat.listenerCount('change');
stat.removeListener('change', listener); stat.removeListener('change', listener);
@ -3000,8 +2994,6 @@ module.exports = fs = {
mkdtempSync, mkdtempSync,
open, open,
openSync, openSync,
opendir,
opendirSync,
readdir, readdir,
readdirSync, readdirSync,
read, read,
@ -3039,7 +3031,6 @@ module.exports = fs = {
writeSync, writeSync,
writev, writev,
writevSync, writevSync,
Dir,
Dirent, Dirent,
Stats, Stats,
@ -3085,6 +3076,12 @@ module.exports = fs = {
_toUnixTimestamp: toUnixTimestamp _toUnixTimestamp: toUnixTimestamp
}; };
defineLazyProperties(
fs,
'internal/fs/dir',
['Dir', 'opendir', 'opendirSync']
);
ObjectDefineProperties(fs, { ObjectDefineProperties(fs, {
F_OK: { __proto__: null, enumerable: true, value: F_OK || 0 }, F_OK: { __proto__: null, enumerable: true, value: F_OK || 0 },
R_OK: { __proto__: null, enumerable: true, value: R_OK || 0 }, R_OK: { __proto__: null, enumerable: true, value: R_OK || 0 },

View File

@ -10,8 +10,6 @@ const {
const { exitCodes: { kGenericUserError } } = internalBinding('errors'); const { exitCodes: { kGenericUserError } } = internalBinding('errors');
const promiseHooks = require('internal/promise_hooks');
const async_wrap = internalBinding('async_wrap'); const async_wrap = internalBinding('async_wrap');
const { setCallbackTrampoline } = async_wrap; const { setCallbackTrampoline } = async_wrap;
/* async_hook_fields is a Uint32Array wrapping the uint32_t array of /* async_hook_fields is a Uint32Array wrapping the uint32_t array of
@ -384,6 +382,7 @@ function updatePromiseHookMode() {
initHook = destroyTracking; initHook = destroyTracking;
} }
if (stopPromiseHook) stopPromiseHook(); if (stopPromiseHook) stopPromiseHook();
const promiseHooks = require('internal/promise_hooks');
stopPromiseHook = promiseHooks.createHook({ stopPromiseHook = promiseHooks.createHook({
init: initHook, init: initHook,
before: promiseBeforeHook, before: promiseBeforeHook,

View File

@ -9,6 +9,9 @@ const {
defineOperation, defineOperation,
exposeInterface, exposeInterface,
lazyDOMExceptionClass, lazyDOMExceptionClass,
defineLazyProperties,
defineReplaceableLazyAttribute,
exposeLazyInterfaces,
} = require('internal/util'); } = require('internal/util');
const config = internalBinding('config'); const config = internalBinding('config');
@ -28,36 +31,6 @@ exposeGetterAndSetter(globalThis,
exposeInterface(globalThis, 'DOMException', value); exposeInterface(globalThis, 'DOMException', value);
}); });
const {
TextEncoder, TextDecoder
} = require('internal/encoding');
// https://encoding.spec.whatwg.org/#textencoder
exposeInterface(globalThis, 'TextEncoder', TextEncoder);
// https://encoding.spec.whatwg.org/#textdecoder
exposeInterface(globalThis, 'TextDecoder', TextDecoder);
const {
AbortController,
AbortSignal,
} = require('internal/abort_controller');
exposeInterface(globalThis, 'AbortController', AbortController);
exposeInterface(globalThis, 'AbortSignal', AbortSignal);
const {
EventTarget,
Event,
} = require('internal/event_target');
exposeInterface(globalThis, 'EventTarget', EventTarget);
exposeInterface(globalThis, 'Event', Event);
const {
MessageChannel,
MessagePort,
MessageEvent,
} = require('internal/worker/io');
exposeInterface(globalThis, 'MessageChannel', MessageChannel);
exposeInterface(globalThis, 'MessagePort', MessagePort);
exposeInterface(globalThis, 'MessageEvent', MessageEvent);
// https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope // https://html.spec.whatwg.org/multipage/webappapis.html#windoworworkerglobalscope
const timers = require('timers'); const timers = require('timers');
defineOperation(globalThis, 'clearInterval', timers.clearInterval); defineOperation(globalThis, 'clearInterval', timers.clearInterval);
@ -65,24 +38,32 @@ defineOperation(globalThis, 'clearTimeout', timers.clearTimeout);
defineOperation(globalThis, 'setInterval', timers.setInterval); defineOperation(globalThis, 'setInterval', timers.setInterval);
defineOperation(globalThis, 'setTimeout', timers.setTimeout); defineOperation(globalThis, 'setTimeout', timers.setTimeout);
const buffer = require('buffer'); // Lazy ones.
defineOperation(globalThis, 'atob', buffer.atob); exposeLazyInterfaces(globalThis, 'internal/abort_controller', [
defineOperation(globalThis, 'btoa', buffer.btoa); 'AbortController', 'AbortSignal',
]);
exposeLazyInterfaces(globalThis, 'internal/event_target', [
'EventTarget', 'Event',
]);
exposeLazyInterfaces(globalThis, 'internal/worker/io', [
'MessageChannel', 'MessagePort', 'MessageEvent',
]);
defineLazyProperties(globalThis, 'buffer', ['atob', 'btoa']);
// https://www.w3.org/TR/FileAPI/#dfn-Blob // https://www.w3.org/TR/FileAPI/#dfn-Blob
exposeInterface(globalThis, 'Blob', buffer.Blob); exposeLazyInterfaces(globalThis, 'internal/blob', ['Blob']);
// https://www.w3.org/TR/hr-time-2/#the-performance-attribute // https://www.w3.org/TR/hr-time-2/#the-performance-attribute
const perf_hooks = require('perf_hooks'); exposeLazyInterfaces(globalThis, 'perf_hooks', [
exposeInterface(globalThis, 'Performance', perf_hooks.Performance); 'Performance', 'PerformanceEntry', 'PerformanceMark', 'PerformanceMeasure',
exposeInterface(globalThis, 'PerformanceEntry', perf_hooks.PerformanceEntry); 'PerformanceObserver', 'PerformanceObserverEntryList', 'PerformanceResourceTiming',
exposeInterface(globalThis, 'PerformanceMark', perf_hooks.PerformanceMark); ]);
exposeInterface(globalThis, 'PerformanceMeasure', perf_hooks.PerformanceMeasure);
exposeInterface(globalThis, 'PerformanceObserver', perf_hooks.PerformanceObserver); defineReplaceableLazyAttribute(globalThis, 'perf_hooks', ['performance']);
exposeInterface(globalThis, 'PerformanceObserverEntryList', perf_hooks.PerformanceObserverEntryList);
exposeInterface(globalThis, 'PerformanceResourceTiming', perf_hooks.PerformanceResourceTiming); // https://encoding.spec.whatwg.org/#textencoder
defineReplaceableAttribute(globalThis, 'performance', // https://encoding.spec.whatwg.org/#textdecoder
perf_hooks.performance); exposeLazyInterfaces(globalThis,
'internal/encoding',
['TextEncoder', 'TextDecoder']);
function createGlobalConsole() { function createGlobalConsole() {
const consoleFromNode = const consoleFromNode =
@ -120,86 +101,43 @@ function exposeGetterAndSetter(target, name, getter, setter = undefined) {
}); });
} }
// https://webidl.spec.whatwg.org/#Replaceable
function defineReplaceableAttribute(target, name, value) {
let slot = value;
// https://webidl.spec.whatwg.org/#dfn-attribute-getter
function get() {
return slot;
}
ObjectDefineProperty(get, 'name', {
__proto__: null,
value: `get ${name}`,
});
function set(value) {
slot = value;
}
ObjectDefineProperty(set, 'name', {
__proto__: null,
value: `set ${name}`,
});
ObjectDefineProperty(target, name, {
__proto__: null,
enumerable: true,
configurable: true,
get,
set,
});
}
// Web Streams API // Web Streams API
const { exposeLazyInterfaces(
TransformStream, globalThis,
TransformStreamDefaultController, 'internal/webstreams/transformstream',
} = require('internal/webstreams/transformstream'); ['TransformStream', 'TransformStreamDefaultController']);
const { exposeLazyInterfaces(
WritableStream, globalThis,
WritableStreamDefaultController, 'internal/webstreams/writablestream',
WritableStreamDefaultWriter, ['WritableStream', 'WritableStreamDefaultController', 'WritableStreamDefaultWriter']);
} = require('internal/webstreams/writablestream');
const { exposeLazyInterfaces(
ReadableStream, globalThis,
ReadableStreamDefaultReader, 'internal/webstreams/readablestream',
ReadableStreamBYOBReader, [
ReadableStreamBYOBRequest, 'ReadableStream', 'ReadableStreamDefaultReader',
ReadableByteStreamController, 'ReadableStreamBYOBReader', 'ReadableStreamBYOBRequest',
ReadableStreamDefaultController, 'ReadableByteStreamController', 'ReadableStreamDefaultController',
} = require('internal/webstreams/readablestream'); ]);
const { exposeLazyInterfaces(
ByteLengthQueuingStrategy, globalThis,
CountQueuingStrategy, 'internal/webstreams/queuingstrategies',
} = require('internal/webstreams/queuingstrategies'); [
'ByteLengthQueuingStrategy', 'CountQueuingStrategy',
]);
const { exposeLazyInterfaces(
TextEncoderStream, globalThis,
TextDecoderStream, 'internal/webstreams/encoding',
} = require('internal/webstreams/encoding'); [
'TextEncoderStream', 'TextDecoderStream',
]);
const { exposeLazyInterfaces(
CompressionStream, globalThis,
DecompressionStream, 'internal/webstreams/compression',
} = require('internal/webstreams/compression'); [
'CompressionStream', 'DecompressionStream',
exposeInterface(globalThis, 'ReadableStream', ReadableStream); ]);
exposeInterface(globalThis, 'ReadableStreamDefaultReader', ReadableStreamDefaultReader);
exposeInterface(globalThis, 'ReadableStreamBYOBReader', ReadableStreamBYOBReader);
exposeInterface(globalThis, 'ReadableStreamBYOBRequest', ReadableStreamBYOBRequest);
exposeInterface(globalThis, 'ReadableByteStreamController', ReadableByteStreamController);
exposeInterface(globalThis, 'ReadableStreamDefaultController', ReadableStreamDefaultController);
exposeInterface(globalThis, 'TransformStream', TransformStream);
exposeInterface(globalThis, 'TransformStreamDefaultController', TransformStreamDefaultController);
exposeInterface(globalThis, 'WritableStream', WritableStream);
exposeInterface(globalThis, 'WritableStreamDefaultWriter', WritableStreamDefaultWriter);
exposeInterface(globalThis, 'WritableStreamDefaultController', WritableStreamDefaultController);
exposeInterface(globalThis, 'ByteLengthQueuingStrategy', ByteLengthQueuingStrategy);
exposeInterface(globalThis, 'CountQueuingStrategy', CountQueuingStrategy);
exposeInterface(globalThis, 'TextEncoderStream', TextEncoderStream);
exposeInterface(globalThis, 'TextDecoderStream', TextDecoderStream);
exposeInterface(globalThis, 'CompressionStream', CompressionStream);
exposeInterface(globalThis, 'DecompressionStream', DecompressionStream);

View File

@ -74,7 +74,8 @@ const internalTimers = require('internal/timers');
const { const {
defineOperation, defineOperation,
deprecate, deprecate,
exposeInterface, defineLazyProperties,
exposeLazyInterfaces,
} = require('internal/util'); } = require('internal/util');
const { const {
validateInteger, validateInteger,
@ -223,20 +224,23 @@ const {
} = require('internal/process/task_queues'); } = require('internal/process/task_queues');
// Non-standard extensions: // Non-standard extensions:
const { BroadcastChannel } = require('internal/worker/io');
exposeInterface(globalThis, 'BroadcastChannel', BroadcastChannel);
defineOperation(globalThis, 'queueMicrotask', queueMicrotask); defineOperation(globalThis, 'queueMicrotask', queueMicrotask);
const timers = require('timers'); const timers = require('timers');
defineOperation(globalThis, 'clearImmediate', timers.clearImmediate); defineOperation(globalThis, 'clearImmediate', timers.clearImmediate);
defineOperation(globalThis, 'setImmediate', timers.setImmediate); defineOperation(globalThis, 'setImmediate', timers.setImmediate);
const { defineLazyProperties(
structuredClone, globalThis,
} = require('internal/structured_clone'); 'internal/structured_clone',
defineOperation(globalThis, 'structuredClone', structuredClone); ['structuredClone']
);
exposeLazyInterfaces(
globalThis,
'internal/worker/io',
['BroadcastChannel']
);
// Set the per-Environment callback that will be called // Set the per-Environment callback that will be called
// when the TrackingTraceStateObserver updates trace state. // when the TrackingTraceStateObserver updates trace state.
// Note that when NODE_USE_V8_PLATFORM is true, the observer is // Note that when NODE_USE_V8_PLATFORM is true, the observer is
@ -348,16 +352,6 @@ process.emitWarning = emitWarning;
// Note: only after this point are the timers effective // Note: only after this point are the timers effective
} }
// Preload modules so that they are included in the builtin snapshot.
require('fs');
require('v8');
require('vm');
require('url');
require('internal/options');
if (config.hasOpenSSL) {
require('crypto');
}
function setupPrepareStackTrace() { function setupPrepareStackTrace() {
const { const {
setEnhanceStackForFatalException, setEnhanceStackForFatalException,

View File

@ -3,9 +3,11 @@
const { ObjectDefineProperty } = primordials; const { ObjectDefineProperty } = primordials;
const rawMethods = internalBinding('process_methods'); const rawMethods = internalBinding('process_methods');
const { const {
addSerializeCallback, namespace: {
isBuildingSnapshot addSerializeCallback,
} = require('v8').startupSnapshot; isBuildingSnapshot
},
} = require('internal/v8/startup_snapshot');
// TODO(joyeecheung): deprecate and remove these underscore methods // TODO(joyeecheung): deprecate and remove these underscore methods
process._debugProcess = rawMethods._debugProcess; process._debugProcess = rawMethods._debugProcess;
process._debugEnd = rawMethods._debugEnd; process._debugEnd = rawMethods._debugEnd;

View File

@ -690,9 +690,11 @@ function initializeGlobalConsole(globalConsole) {
globalConsole[kBindProperties](true, 'auto'); globalConsole[kBindProperties](true, 'auto');
const { const {
addSerializeCallback, namespace: {
isBuildingSnapshot, addSerializeCallback,
} = require('v8').startupSnapshot; isBuildingSnapshot,
}
} = require('internal/v8/startup_snapshot');
if (!internalBinding('config').hasInspector || !isBuildingSnapshot()) { if (!internalBinding('config').hasInspector || !isBuildingSnapshot()) {
return; return;

View File

@ -37,10 +37,12 @@ const {
} = errors.codes; } = errors.codes;
const { const {
addSerializeCallback, namespace: {
addDeserializeCallback, addSerializeCallback,
isBuildingSnapshot, addDeserializeCallback,
} = require('v8').startupSnapshot; isBuildingSnapshot,
},
} = require('internal/v8/startup_snapshot');
function validateTimeout(options) { function validateTimeout(options) {
const { timeout = -1 } = { ...options }; const { timeout = -1 } = { ...options };

View File

@ -200,7 +200,7 @@ function lazyBuffer() {
function isErrorStackTraceLimitWritable() { function isErrorStackTraceLimitWritable() {
// Do no touch Error.stackTraceLimit as V8 would attempt to install // Do no touch Error.stackTraceLimit as V8 would attempt to install
// it again during deserialization. // it again during deserialization.
if (require('v8').startupSnapshot.isBuildingSnapshot()) { if (require('internal/v8/startup_snapshot').namespace.isBuildingSnapshot()) {
return false; return false;
} }

View File

@ -109,14 +109,6 @@ const {
JSTransferable, kDeserialize, kTransfer, kTransferList JSTransferable, kDeserialize, kTransfer, kTransferList
} = require('internal/worker/js_transferable'); } = require('internal/worker/js_transferable');
const {
newReadableStreamFromStreamBase,
} = require('internal/webstreams/adapters');
const {
readableStreamCancel,
} = require('internal/webstreams/readablestream');
const getDirectoryEntriesPromise = promisify(getDirents); const getDirectoryEntriesPromise = promisify(getDirents);
const validateRmOptionsPromise = promisify(validateRmOptions); const validateRmOptionsPromise = promisify(validateRmOptions);
@ -264,12 +256,17 @@ class FileHandle extends EventEmitterMixin(JSTransferable) {
if (this[kLocked]) if (this[kLocked])
throw new ERR_INVALID_STATE('The FileHandle is locked'); throw new ERR_INVALID_STATE('The FileHandle is locked');
this[kLocked] = true; this[kLocked] = true;
const {
newReadableStreamFromStreamBase,
} = require('internal/webstreams/adapters');
const readable = newReadableStreamFromStreamBase( const readable = newReadableStreamFromStreamBase(
this[kHandle], this[kHandle],
undefined, undefined,
{ ondone: () => this[kUnref]() }); { ondone: () => this[kUnref]() });
const {
readableStreamCancel,
} = require('internal/webstreams/readablestream');
this[kRef](); this[kRef]();
this.once('close', () => { this.once('close', () => {
readableStreamCancel(readable); readableStreamCancel(readable);

View File

@ -95,7 +95,6 @@ const internalFS = require('internal/fs/utils');
const path = require('path'); const path = require('path');
const { sep } = path; const { sep } = path;
const { internalModuleStat } = internalBinding('fs'); const { internalModuleStat } = internalBinding('fs');
const packageJsonReader = require('internal/modules/package_json_reader');
const { safeGetenv } = internalBinding('credentials'); const { safeGetenv } = internalBinding('credentials');
const { const {
cjsConditions, cjsConditions,
@ -338,6 +337,7 @@ function readPackage(requestPath) {
const existing = packageJsonCache.get(jsonPath); const existing = packageJsonCache.get(jsonPath);
if (existing !== undefined) return existing; if (existing !== undefined) return existing;
const packageJsonReader = require('internal/modules/package_json_reader');
const result = packageJsonReader.read(jsonPath); const result = packageJsonReader.read(jsonPath);
const json = result.containsKeys === false ? '{}' : result.string; const json = result.containsKeys === false ? '{}' : result.string;
if (json === undefined) { if (json === undefined) {

View File

@ -8,7 +8,6 @@ const {
} = primordials; } = primordials;
const { basename, extname, relative } = require('path'); const { basename, extname, relative } = require('path');
const { getOptionValue } = require('internal/options'); const { getOptionValue } = require('internal/options');
const { fetchModule } = require('internal/modules/esm/fetch_module');
const { const {
extensionFormatMap, extensionFormatMap,
mimeToFormat, mimeToFormat,
@ -82,6 +81,7 @@ function getFileProtocolModuleFormat(url, context, ignoreErrors) {
*/ */
function getHttpProtocolModuleFormat(url, context) { function getHttpProtocolModuleFormat(url, context) {
if (experimentalNetworkImports) { if (experimentalNetworkImports) {
const { fetchModule } = require('internal/modules/esm/fetch_module');
return PromisePrototypeThen( return PromisePrototypeThen(
PromiseResolve(fetchModule(url, context)), PromiseResolve(fetchModule(url, context)),
(entry) => { (entry) => {

View File

@ -9,7 +9,6 @@ const {
const { defaultGetFormat } = require('internal/modules/esm/get_format'); const { defaultGetFormat } = require('internal/modules/esm/get_format');
const { validateAssertions } = require('internal/modules/esm/assert'); const { validateAssertions } = require('internal/modules/esm/assert');
const { getOptionValue } = require('internal/options'); const { getOptionValue } = require('internal/options');
const { fetchModule } = require('internal/modules/esm/fetch_module');
// Do not eagerly grab .manifest, it may be in TDZ // Do not eagerly grab .manifest, it may be in TDZ
const policy = getOptionValue('--experimental-policy') ? const policy = getOptionValue('--experimental-policy') ?
@ -20,7 +19,6 @@ const experimentalNetworkImports =
const { Buffer: { from: BufferFrom } } = require('buffer'); const { Buffer: { from: BufferFrom } } = require('buffer');
const { readFile: readFileAsync } = require('internal/fs/promises').exports;
const { URL } = require('internal/url'); const { URL } = require('internal/url');
const { const {
ERR_INVALID_URL, ERR_INVALID_URL,
@ -34,6 +32,7 @@ async function getSource(url, context) {
let responseURL = url; let responseURL = url;
let source; let source;
if (parsed.protocol === 'file:') { if (parsed.protocol === 'file:') {
const { readFile: readFileAsync } = require('internal/fs/promises').exports;
source = await readFileAsync(parsed); source = await readFileAsync(parsed);
} else if (parsed.protocol === 'data:') { } else if (parsed.protocol === 'data:') {
const match = RegExpPrototypeExec(DATA_URL_PATTERN, parsed.pathname); const match = RegExpPrototypeExec(DATA_URL_PATTERN, parsed.pathname);
@ -46,6 +45,7 @@ async function getSource(url, context) {
parsed.protocol === 'https:' || parsed.protocol === 'https:' ||
parsed.protocol === 'http:' parsed.protocol === 'http:'
)) { )) {
const { fetchModule } = require('internal/modules/esm/fetch_module');
const res = await fetchModule(parsed, context); const res = await fetchModule(parsed, context);
source = await res.body; source = await res.body;
responseURL = res.resolvedHREF; responseURL = res.resolvedHREF;

View File

@ -20,7 +20,6 @@ const {
StringPrototypeToUpperCase, StringPrototypeToUpperCase,
globalThis, globalThis,
} = primordials; } = primordials;
const { MessageChannel } = require('internal/worker/io');
const { const {
ERR_LOADER_CHAIN_INCOMPLETE, ERR_LOADER_CHAIN_INCOMPLETE,
@ -41,19 +40,20 @@ const {
validateObject, validateObject,
validateString, validateString,
} = require('internal/validators'); } = require('internal/validators');
const ModuleMap = require('internal/modules/esm/module_map'); function newModuleMap() {
const ModuleJob = require('internal/modules/esm/module_job'); const ModuleMap = require('internal/modules/esm/module_map');
return new ModuleMap();
}
const { const {
defaultResolve, defaultResolve,
DEFAULT_CONDITIONS, DEFAULT_CONDITIONS,
} = require('internal/modules/esm/resolve'); } = require('internal/modules/esm/resolve');
const {
initializeImportMeta function getTranslators() {
} = require('internal/modules/esm/initialize_import_meta'); const { translators } = require('internal/modules/esm/translators');
const { defaultLoad } = require('internal/modules/esm/load'); return translators;
const { translators } = require( }
'internal/modules/esm/translators');
const { getOptionValue } = require('internal/options'); const { getOptionValue } = require('internal/options');
/** /**
@ -176,6 +176,7 @@ function nextHookFactory(chain, meta, { validateArgs, validateOutput }) {
* Currently, this is a singleton -- there is only one used for loading * Currently, this is a singleton -- there is only one used for loading
* the main module and everything in its dependency graph. * the main module and everything in its dependency graph.
*/ */
class ESMLoader { class ESMLoader {
#hooks = { #hooks = {
/** /**
@ -192,7 +193,7 @@ class ESMLoader {
*/ */
load: [ load: [
{ {
fn: defaultLoad, fn: require('internal/modules/esm/load').defaultLoad,
url: 'node:internal/modules/esm/load', url: 'node:internal/modules/esm/load',
}, },
], ],
@ -210,7 +211,7 @@ class ESMLoader {
], ],
}; };
#importMetaInitializer = initializeImportMeta; #importMetaInitializer = require('internal/modules/esm/initialize_import_meta').initializeImportMeta;
/** /**
* Map of already-loaded CJS modules to use * Map of already-loaded CJS modules to use
@ -225,12 +226,12 @@ class ESMLoader {
/** /**
* Registry of loaded modules, akin to `require.cache` * Registry of loaded modules, akin to `require.cache`
*/ */
moduleMap = new ModuleMap(); moduleMap = newModuleMap();
/** /**
* Methods which translate input code or other information into ES modules * Methods which translate input code or other information into ES modules
*/ */
translators = translators; translators = getTranslators();
constructor() { constructor() {
if (getOptionValue('--experimental-loader').length > 0) { if (getOptionValue('--experimental-loader').length > 0) {
@ -372,6 +373,7 @@ class ESMLoader {
return module; return module;
}; };
const ModuleJob = require('internal/modules/esm/module_job');
const job = new ModuleJob( const job = new ModuleJob(
this, url, undefined, evalInstance, false, false); this, url, undefined, evalInstance, false, false);
this.moduleMap.set(url, undefined, job); this.moduleMap.set(url, undefined, job);
@ -448,7 +450,7 @@ class ESMLoader {
importAssertions, importAssertions,
}); });
const translator = translators.get(finalFormat); const translator = getTranslators().get(finalFormat);
if (!translator) { if (!translator) {
throw new ERR_UNKNOWN_MODULE_FORMAT(finalFormat, responseURL); throw new ERR_UNKNOWN_MODULE_FORMAT(finalFormat, responseURL);
@ -465,7 +467,7 @@ class ESMLoader {
if (process.env.WATCH_REPORT_DEPENDENCIES && process.send) { if (process.env.WATCH_REPORT_DEPENDENCIES && process.send) {
process.send({ 'watch:import': [url] }); process.send({ 'watch:import': [url] });
} }
const ModuleJob = require('internal/modules/esm/module_job');
const job = new ModuleJob( const job = new ModuleJob(
this, this,
url, url,
@ -674,6 +676,7 @@ class ESMLoader {
preload() { preload() {
for (let i = this.#hooks.globalPreload.length - 1; i >= 0; i--) { for (let i = this.#hooks.globalPreload.length - 1; i >= 0; i--) {
const { MessageChannel } = require('internal/worker/io');
const channel = new MessageChannel(); const channel = new MessageChannel();
const { const {
port1: insidePreload, port1: insidePreload,

View File

@ -1,6 +1,5 @@
'use strict'; 'use strict';
const ModuleJob = require('internal/modules/esm/module_job');
const { kImplicitAssertType } = require('internal/modules/esm/assert'); const { kImplicitAssertType } = require('internal/modules/esm/assert');
const { const {
ObjectCreate, ObjectCreate,
@ -23,6 +22,8 @@ class ModuleMap extends SafeMap {
set(url, type = kImplicitAssertType, job) { set(url, type = kImplicitAssertType, job) {
validateString(url, 'url'); validateString(url, 'url');
validateString(type, 'type'); validateString(type, 'type');
const ModuleJob = require('internal/modules/esm/module_job');
if (job instanceof ModuleJob !== true && if (job instanceof ModuleJob !== true &&
typeof job !== 'function') { typeof job !== 'function') {
throw new ERR_INVALID_ARG_TYPE('job', 'ModuleJob', job); throw new ERR_INVALID_ARG_TYPE('job', 'ModuleJob', job);

View File

@ -11,7 +11,6 @@ const {
ERR_INVALID_PACKAGE_CONFIG, ERR_INVALID_PACKAGE_CONFIG,
} = require('internal/errors').codes; } = require('internal/errors').codes;
const packageJsonReader = require('internal/modules/package_json_reader');
const { filterOwnProperties } = require('internal/util'); const { filterOwnProperties } = require('internal/util');
@ -42,6 +41,7 @@ function getPackageConfig(path, specifier, base) {
if (existing !== undefined) { if (existing !== undefined) {
return existing; return existing;
} }
const packageJsonReader = require('internal/modules/package_json_reader');
const source = packageJsonReader.read(path).string; const source = packageJsonReader.read(path).string;
if (source === undefined) { if (source === undefined) {
const packageConfig = { const packageConfig = {

View File

@ -36,8 +36,6 @@ const {
cjsParseCache cjsParseCache
} = require('internal/modules/cjs/loader'); } = require('internal/modules/cjs/loader');
const internalURLModule = require('internal/url'); const internalURLModule = require('internal/url');
const createDynamicModule = require(
'internal/modules/esm/create_dynamic_module');
const { fileURLToPath, URL } = require('url'); const { fileURLToPath, URL } = require('url');
let debug = require('internal/util/debuglog').debuglog('esm', (fn) => { let debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
debug = fn; debug = fn;
@ -52,7 +50,6 @@ const moduleWrap = internalBinding('module_wrap');
const { ModuleWrap } = moduleWrap; const { ModuleWrap } = moduleWrap;
const asyncESM = require('internal/process/esm_loader'); const asyncESM = require('internal/process/esm_loader');
const { emitWarningSync } = require('internal/process/warning'); const { emitWarningSync } = require('internal/process/warning');
const { TextDecoder } = require('internal/encoding');
let cjsParse; let cjsParse;
async function initCJSParse() { async function initCJSParse() {
@ -94,6 +91,7 @@ function assertBufferSource(body, allowString, hookName) {
function stringify(body) { function stringify(body) {
if (typeof body === 'string') return body; if (typeof body === 'string') return body;
assertBufferSource(body, false, 'transformSource'); assertBufferSource(body, false, 'transformSource');
const { TextDecoder } = require('internal/encoding');
DECODER = DECODER === null ? new TextDecoder() : DECODER; DECODER = DECODER === null ? new TextDecoder() : DECODER;
return DECODER.decode(body); return DECODER.decode(body);
} }
@ -341,6 +339,8 @@ translators.set('wasm', async function(url, source) {
ArrayPrototypeMap(WebAssembly.Module.exports(compiled), ArrayPrototypeMap(WebAssembly.Module.exports(compiled),
({ name }) => name); ({ name }) => name);
const createDynamicModule = require(
'internal/modules/esm/create_dynamic_module');
return createDynamicModule(imports, exports, url, (reflect) => { return createDynamicModule(imports, exports, url, (reflect) => {
const { exports } = new WebAssembly.Instance(compiled, reflect.imports); const { exports } = new WebAssembly.Instance(compiled, reflect.imports);
for (const expt of ObjectKeys(exports)) for (const expt of ObjectKeys(exports))

View File

@ -8,9 +8,6 @@ const CJSLoader = require('internal/modules/cjs/loader');
const { Module, toRealPath, readPackageScope } = CJSLoader; const { Module, toRealPath, readPackageScope } = CJSLoader;
const { getOptionValue } = require('internal/options'); const { getOptionValue } = require('internal/options');
const path = require('path'); const path = require('path');
const {
handleProcessExit,
} = require('internal/modules/esm/handle_process_exit');
function resolveMainPath(main) { function resolveMainPath(main) {
// Note extension resolution for the main entry point can be deprecated in a // Note extension resolution for the main entry point can be deprecated in a
@ -61,6 +58,9 @@ function runMainESM(mainPath) {
} }
async function handleMainPromise(promise) { async function handleMainPromise(promise) {
const {
handleProcessExit,
} = require('internal/modules/esm/handle_process_exit');
process.on('exit', handleProcessExit); process.on('exit', handleProcessExit);
try { try {
return await promise; return await promise;

View File

@ -49,10 +49,6 @@ const {
} = require('internal/validators'); } = require('internal/validators');
const constants = internalBinding('constants').os.signals; const constants = internalBinding('constants').os.signals;
const {
handleProcessExit,
} = require('internal/modules/esm/handle_process_exit');
const kInternal = Symbol('internal properties'); const kInternal = Symbol('internal properties');
function assert(x, msg) { function assert(x, msg) {
@ -181,6 +177,9 @@ function wrapProcessMethods(binding) {
memoryUsage.rss = rss; memoryUsage.rss = rss;
function exit(code) { function exit(code) {
const {
handleProcessExit,
} = require('internal/modules/esm/handle_process_exit');
process.off('exit', handleProcessExit); process.off('exit', handleProcessExit);
if (arguments.length !== 0) { if (arguments.length !== 0) {

View File

@ -20,6 +20,8 @@ const { reconnectZeroFillToggle } = require('internal/buffer');
const { const {
defineOperation, defineOperation,
exposeInterface, exposeInterface,
exposeLazyInterfaces,
defineReplaceableLazyAttribute,
} = require('internal/util'); } = require('internal/util');
const { const {
@ -27,11 +29,12 @@ const {
ERR_NO_CRYPTO, ERR_NO_CRYPTO,
} = require('internal/errors').codes; } = require('internal/errors').codes;
const assert = require('internal/assert'); const assert = require('internal/assert');
const { const {
addSerializeCallback, namespace: {
isBuildingSnapshot, addSerializeCallback,
} = require('v8').startupSnapshot; isBuildingSnapshot,
},
} = require('internal/v8/startup_snapshot');
function prepareMainThreadExecution(expandArgv1 = false, initializeModules = true) { function prepareMainThreadExecution(expandArgv1 = false, initializeModules = true) {
prepareExecution({ prepareExecution({
@ -274,16 +277,13 @@ function setupWebCrypto() {
} }
if (internalBinding('config').hasOpenSSL) { if (internalBinding('config').hasOpenSSL) {
const webcrypto = require('internal/crypto/webcrypto'); defineReplaceableLazyAttribute(
ObjectDefineProperty(globalThis, 'crypto', globalThis, 'internal/crypto/webcrypto', ['crypto'], false
{ __proto__: null, ...ObjectGetOwnPropertyDescriptor({ );
get crypto() { exposeLazyInterfaces(
return webcrypto.crypto; globalThis, 'internal/crypto/webcrypto',
} ['Crypto', 'CryptoKey', 'SubtleCrypto']
}, 'crypto') }); );
exposeInterface(globalThis, 'Crypto', webcrypto.Crypto);
exposeInterface(globalThis, 'CryptoKey', webcrypto.CryptoKey);
exposeInterface(globalThis, 'SubtleCrypto', webcrypto.SubtleCrypto);
} else { } else {
ObjectDefineProperty(globalThis, 'crypto', ObjectDefineProperty(globalThis, 'crypto',
{ __proto__: null, ...ObjectGetOwnPropertyDescriptor({ { __proto__: null, ...ObjectGetOwnPropertyDescriptor({

View File

@ -23,7 +23,6 @@ const { Buffer } = require('buffer');
let debug = require('internal/util/debuglog').debuglog('source_map', (fn) => { let debug = require('internal/util/debuglog').debuglog('source_map', (fn) => {
debug = fn; debug = fn;
}); });
const fs = require('fs');
const { getOptionValue } = require('internal/options'); const { getOptionValue } = require('internal/options');
const { IterableWeakMap } = require('internal/util/iterable_weak_map'); const { IterableWeakMap } = require('internal/util/iterable_weak_map');
const { const {
@ -222,6 +221,7 @@ function lineLengths(content) {
function sourceMapFromFile(mapURL) { function sourceMapFromFile(mapURL) {
try { try {
const fs = require('fs');
const content = fs.readFileSync(fileURLToPath(mapURL), 'utf8'); const content = fs.readFileSync(fileURLToPath(mapURL), 'utf8');
const data = JSONParse(content); const data = JSONParse(content);
return sourcesToAbsolute(mapURL, data); return sourcesToAbsolute(mapURL, data);

View File

@ -501,6 +501,90 @@ function exposeInterface(target, name, interfaceObject) {
}); });
} }
function defineLazyProperties(target, id, keys, enumerable = true) {
const descriptors = { __proto__: null };
let mod;
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
let lazyLoadedValue;
function set(value) {
ObjectDefineProperty(target, key, {
__proto__: null,
writable: true,
value,
});
}
ObjectDefineProperty(set, 'name', {
__proto__: null,
value: `set ${key}`,
});
function get() {
mod ??= require(id);
if (lazyLoadedValue === undefined) {
lazyLoadedValue = mod[key];
set(lazyLoadedValue);
}
return lazyLoadedValue;
}
ObjectDefineProperty(get, 'name', {
__proto__: null,
value: `get ${key}`,
});
descriptors[key] = {
__proto__: null,
configurable: true,
enumerable,
get,
set,
};
}
ObjectDefineProperties(target, descriptors);
}
function defineReplaceableLazyAttribute(target, id, keys, writable = true) {
let mod;
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
let value;
let setterCalled = false;
function get() {
if (setterCalled) {
return value;
}
mod ??= require(id);
value ??= mod[key];
return value;
}
ObjectDefineProperty(get, 'name', {
__proto__: null,
value: `get ${key}`,
});
function set(val) {
setterCalled = true;
value = val;
}
ObjectDefineProperty(set, 'name', {
__proto__: null,
value: `set ${key}`,
});
ObjectDefineProperty(target, key, {
__proto__: null,
enumerable: true,
configurable: true,
get,
set: writable ? set : undefined,
});
}
}
function exposeLazyInterfaces(target, id, keys) {
defineLazyProperties(target, id, keys, false);
}
let _DOMException; let _DOMException;
const lazyDOMExceptionClass = () => { const lazyDOMExceptionClass = () => {
_DOMException ??= internalBinding('messaging').DOMException; _DOMException ??= internalBinding('messaging').DOMException;
@ -578,9 +662,12 @@ module.exports = {
createDeferredPromise, createDeferredPromise,
decorateErrorStack, decorateErrorStack,
defineOperation, defineOperation,
defineLazyProperties,
defineReplaceableLazyAttribute,
deprecate, deprecate,
emitExperimentalWarning, emitExperimentalWarning,
exposeInterface, exposeInterface,
exposeLazyInterfaces,
filterDuplicateStrings, filterDuplicateStrings,
filterOwnProperties, filterOwnProperties,
getConstructorOf, getConstructorOf,

View File

@ -62,13 +62,10 @@ const {
stripVTControlCharacters, stripVTControlCharacters,
} = require('internal/util/inspect'); } = require('internal/util/inspect');
const { debuglog } = require('internal/util/debuglog'); const { debuglog } = require('internal/util/debuglog');
const { parseArgs } = require('internal/util/parse_args/parse_args');
const { const {
validateFunction, validateFunction,
validateNumber, validateNumber,
} = require('internal/validators'); } = require('internal/validators');
const { TextDecoder, TextEncoder } = require('internal/encoding');
const { MIMEType, MIMEParams } = require('internal/mime');
const { isBuffer } = require('buffer').Buffer; const { isBuffer } = require('buffer').Buffer;
const types = require('internal/util/types'); const types = require('internal/util/types');
@ -78,6 +75,7 @@ const {
getSystemErrorName: internalErrorName, getSystemErrorName: internalErrorName,
promisify, promisify,
toUSVString, toUSVString,
defineLazyProperties,
} = require('internal/util'); } = require('internal/util');
let abortController; let abortController;
@ -386,14 +384,9 @@ module.exports = {
isFunction, isFunction,
isPrimitive, isPrimitive,
log, log,
MIMEType,
MIMEParams,
parseArgs,
promisify, promisify,
stripVTControlCharacters, stripVTControlCharacters,
toUSVString, toUSVString,
TextDecoder,
TextEncoder,
get transferableAbortSignal() { get transferableAbortSignal() {
return lazyAbortController().transferableAbortSignal; return lazyAbortController().transferableAbortSignal;
}, },
@ -402,3 +395,21 @@ module.exports = {
}, },
types types
}; };
defineLazyProperties(
module.exports,
'internal/util/parse_args/parse_args',
['parseArgs']
);
defineLazyProperties(
module.exports,
'internal/encoding',
['TextDecoder', 'TextEncoder']
);
defineLazyProperties(
module.exports,
'internal/mime',
['MIMEType', 'MIMEParams']
);

View File

@ -364,6 +364,7 @@ class WPTRunner {
this.globalThisInitScripts.push( this.globalThisInitScripts.push(
`global.Window = Object.getPrototypeOf(globalThis).constructor; `global.Window = Object.getPrototypeOf(globalThis).constructor;
self.GLOBAL.isWorker = () => false;`); self.GLOBAL.isWorker = () => false;`);
this.loadLazyGlobals();
break; break;
} }
@ -377,6 +378,31 @@ class WPTRunner {
} }
} }
loadLazyGlobals() {
const lazyProperties = [
'Performance', 'PerformanceEntry', 'PerformanceMark', 'PerformanceMeasure',
'PerformanceObserver', 'PerformanceObserverEntryList', 'PerformanceResourceTiming',
'Blob', 'atob', 'btoa',
'MessageChannel', 'MessagePort', 'MessageEvent',
'EventTarget', 'Event',
'AbortController', 'AbortSignal',
'performance',
'TransformStream', 'TransformStreamDefaultController',
'WritableStream', 'WritableStreamDefaultController', 'WritableStreamDefaultWriter',
'ReadableStream', 'ReadableStreamDefaultReader',
'ReadableStreamBYOBReader', 'ReadableStreamBYOBRequest',
'ReadableByteStreamController', 'ReadableStreamDefaultController',
'ByteLengthQueuingStrategy', 'CountQueuingStrategy',
'TextEncoderStream', 'TextDecoderStream',
'CompressionStream', 'DecompressionStream',
];
if (Boolean(process.versions.openssl) && !process.env.NODE_SKIP_CRYPTO) {
lazyProperties.push('crypto');
}
const script = lazyProperties.map((name) => `globalThis.${name};`).join('\n');
this.globalThisInitScripts.push(script);
}
brandCheckGlobalScopeAttribute(name) { brandCheckGlobalScopeAttribute(name) {
// TODO(legendecas): idlharness GlobalScope attribute receiver validation. // TODO(legendecas): idlharness GlobalScope attribute receiver validation.
const script = ` const script = `

View File

@ -10,7 +10,6 @@ const assert = require('assert');
const expectedModules = new Set([ const expectedModules = new Set([
'Internal Binding async_wrap', 'Internal Binding async_wrap',
'Internal Binding block_list',
'Internal Binding buffer', 'Internal Binding buffer',
'Internal Binding builtins', 'Internal Binding builtins',
'Internal Binding config', 'Internal Binding config',
@ -18,74 +17,48 @@ const expectedModules = new Set([
'Internal Binding contextify', 'Internal Binding contextify',
'Internal Binding credentials', 'Internal Binding credentials',
'Internal Binding errors', 'Internal Binding errors',
'Internal Binding fs_dir',
'Internal Binding fs_event_wrap',
'Internal Binding fs', 'Internal Binding fs',
'Internal Binding heap_utils',
'Internal Binding mksnapshot', 'Internal Binding mksnapshot',
'Internal Binding messaging', 'Internal Binding messaging',
'Internal Binding module_wrap', 'Internal Binding module_wrap',
'Internal Binding options', 'Internal Binding options',
'Internal Binding performance', 'Internal Binding performance',
'Internal Binding pipe_wrap',
'Internal Binding process_methods', 'Internal Binding process_methods',
'Internal Binding report', 'Internal Binding report',
'Internal Binding serdes',
'Internal Binding stream_wrap',
'Internal Binding string_decoder', 'Internal Binding string_decoder',
'Internal Binding symbols', 'Internal Binding symbols',
'Internal Binding task_queue', 'Internal Binding task_queue',
'Internal Binding tcp_wrap',
'Internal Binding timers', 'Internal Binding timers',
'Internal Binding trace_events', 'Internal Binding trace_events',
'Internal Binding types', 'Internal Binding types',
'Internal Binding url', 'Internal Binding url',
'Internal Binding util', 'Internal Binding util',
'Internal Binding uv',
'Internal Binding v8',
'Internal Binding wasm_web_api', 'Internal Binding wasm_web_api',
'Internal Binding worker', 'Internal Binding worker',
'NativeModule buffer', 'NativeModule buffer',
'NativeModule diagnostics_channel',
'NativeModule events', 'NativeModule events',
'NativeModule fs', 'NativeModule fs',
'NativeModule internal/abort_controller',
'NativeModule internal/assert', 'NativeModule internal/assert',
'NativeModule internal/async_hooks', 'NativeModule internal/async_hooks',
'NativeModule internal/blocklist',
'NativeModule internal/buffer', 'NativeModule internal/buffer',
'NativeModule internal/console/constructor', 'NativeModule internal/console/constructor',
'NativeModule internal/console/global', 'NativeModule internal/console/global',
'NativeModule internal/constants', 'NativeModule internal/constants',
'NativeModule internal/dns/utils', 'NativeModule internal/dns/utils',
'NativeModule internal/encoding',
'NativeModule internal/errors', 'NativeModule internal/errors',
'NativeModule internal/event_target', 'NativeModule internal/event_target',
'NativeModule internal/fixed_queue', 'NativeModule internal/fixed_queue',
'NativeModule internal/fs/dir',
'NativeModule internal/fs/promises',
'NativeModule internal/fs/read_file_context',
'NativeModule internal/fs/recursive_watch',
'NativeModule internal/fs/rimraf',
'NativeModule internal/fs/utils', 'NativeModule internal/fs/utils',
'NativeModule internal/fs/watchers',
'NativeModule internal/heap_utils',
'NativeModule internal/histogram',
'NativeModule internal/idna', 'NativeModule internal/idna',
'NativeModule internal/linkedlist', 'NativeModule internal/linkedlist',
'NativeModule internal/mime',
'NativeModule internal/modules/cjs/helpers', 'NativeModule internal/modules/cjs/helpers',
'NativeModule internal/modules/cjs/loader', 'NativeModule internal/modules/cjs/loader',
'NativeModule internal/modules/esm/assert', 'NativeModule internal/modules/esm/assert',
'NativeModule internal/modules/esm/create_dynamic_module',
'NativeModule internal/modules/esm/fetch_module',
'NativeModule internal/modules/esm/formats', 'NativeModule internal/modules/esm/formats',
'NativeModule internal/modules/esm/get_format', 'NativeModule internal/modules/esm/get_format',
'NativeModule internal/modules/esm/handle_process_exit',
'NativeModule internal/modules/esm/initialize_import_meta', 'NativeModule internal/modules/esm/initialize_import_meta',
'NativeModule internal/modules/esm/load', 'NativeModule internal/modules/esm/load',
'NativeModule internal/modules/esm/loader', 'NativeModule internal/modules/esm/loader',
'NativeModule internal/modules/esm/module_job',
'NativeModule internal/modules/esm/module_map', 'NativeModule internal/modules/esm/module_map',
'NativeModule internal/modules/esm/package_config', 'NativeModule internal/modules/esm/package_config',
'NativeModule internal/modules/esm/resolve', 'NativeModule internal/modules/esm/resolve',
@ -94,15 +67,6 @@ const expectedModules = new Set([
'NativeModule internal/modules/run_main', 'NativeModule internal/modules/run_main',
'NativeModule internal/net', 'NativeModule internal/net',
'NativeModule internal/options', 'NativeModule internal/options',
'NativeModule internal/perf/event_loop_delay',
'NativeModule internal/perf/event_loop_utilization',
'NativeModule internal/perf/nodetiming',
'NativeModule internal/perf/observe',
'NativeModule internal/perf/performance_entry',
'NativeModule internal/perf/performance',
'NativeModule internal/perf/timerify',
'NativeModule internal/perf/usertiming',
'NativeModule internal/perf/resource_timing',
'NativeModule internal/perf/utils', 'NativeModule internal/perf/utils',
'NativeModule internal/priority_queue', 'NativeModule internal/priority_queue',
'NativeModule internal/process/esm_loader', 'NativeModule internal/process/esm_loader',
@ -114,70 +78,27 @@ const expectedModules = new Set([
'NativeModule internal/process/signal', 'NativeModule internal/process/signal',
'NativeModule internal/process/task_queues', 'NativeModule internal/process/task_queues',
'NativeModule internal/process/warning', 'NativeModule internal/process/warning',
'NativeModule internal/promise_hooks',
'NativeModule internal/querystring', 'NativeModule internal/querystring',
'NativeModule internal/readline/callbacks',
'NativeModule internal/readline/interface',
'NativeModule internal/readline/utils',
'NativeModule internal/socketaddress',
'NativeModule internal/source_map/source_map_cache', 'NativeModule internal/source_map/source_map_cache',
'NativeModule internal/stream_base_commons',
'NativeModule internal/streams/add-abort-signal',
'NativeModule internal/streams/buffer_list',
'NativeModule internal/streams/compose',
'NativeModule internal/streams/destroy',
'NativeModule internal/streams/duplex',
'NativeModule internal/streams/end-of-stream',
'NativeModule internal/streams/from',
'NativeModule internal/streams/legacy',
'NativeModule internal/streams/operators',
'NativeModule internal/streams/passthrough',
'NativeModule internal/streams/pipeline',
'NativeModule internal/streams/readable',
'NativeModule internal/streams/state',
'NativeModule internal/streams/transform',
'NativeModule internal/streams/utils',
'NativeModule internal/streams/writable',
'NativeModule internal/structured_clone',
'NativeModule internal/timers', 'NativeModule internal/timers',
'NativeModule internal/url', 'NativeModule internal/url',
'NativeModule internal/util', 'NativeModule internal/util',
'NativeModule internal/util/debuglog', 'NativeModule internal/util/debuglog',
'NativeModule internal/util/inspect', 'NativeModule internal/util/inspect',
'NativeModule internal/util/iterable_weak_map', 'NativeModule internal/util/iterable_weak_map',
'NativeModule internal/util/parse_args/utils',
'NativeModule internal/util/parse_args/parse_args',
'NativeModule internal/util/types', 'NativeModule internal/util/types',
'NativeModule internal/validators', 'NativeModule internal/validators',
'NativeModule internal/vm', 'NativeModule internal/vm',
'NativeModule internal/vm/module', 'NativeModule internal/vm/module',
'NativeModule internal/wasm_web_api', 'NativeModule internal/wasm_web_api',
'NativeModule internal/webidl',
'NativeModule internal/webstreams/adapters',
'NativeModule internal/webstreams/compression',
'NativeModule internal/webstreams/encoding',
'NativeModule internal/webstreams/queuingstrategies',
'NativeModule internal/webstreams/readablestream',
'NativeModule internal/webstreams/transformstream',
'NativeModule internal/webstreams/util',
'NativeModule internal/webstreams/writablestream',
'NativeModule internal/worker/io',
'NativeModule internal/worker/js_transferable', 'NativeModule internal/worker/js_transferable',
'Internal Binding blob', 'Internal Binding blob',
'NativeModule internal/blob',
'NativeModule internal/file',
'NativeModule async_hooks', 'NativeModule async_hooks',
'NativeModule net',
'NativeModule path', 'NativeModule path',
'NativeModule perf_hooks',
'NativeModule querystring', 'NativeModule querystring',
'NativeModule stream',
'NativeModule stream/promises',
'NativeModule string_decoder',
'NativeModule timers', 'NativeModule timers',
'NativeModule url', 'NativeModule url',
'NativeModule util', 'NativeModule util',
'NativeModule v8',
'NativeModule internal/v8/startup_snapshot', 'NativeModule internal/v8/startup_snapshot',
'NativeModule vm', 'NativeModule vm',
]); ]);
@ -188,23 +109,33 @@ if (!common.isMainThread) {
'Internal Binding performance', 'Internal Binding performance',
'Internal Binding symbols', 'Internal Binding symbols',
'Internal Binding worker', 'Internal Binding worker',
'NativeModule internal/streams/duplex', 'NativeModule diagnostics_channel',
'NativeModule internal/streams/passthrough', 'NativeModule internal/abort_controller',
'NativeModule internal/streams/readable',
'NativeModule internal/streams/transform',
'NativeModule internal/streams/writable',
'NativeModule internal/error_serdes', 'NativeModule internal/error_serdes',
'NativeModule internal/perf/event_loop_utilization',
'NativeModule internal/process/worker_thread_only', 'NativeModule internal/process/worker_thread_only',
'NativeModule internal/streams/add-abort-signal',
'NativeModule internal/streams/buffer_list', 'NativeModule internal/streams/buffer_list',
'NativeModule internal/streams/compose',
'NativeModule internal/streams/destroy', 'NativeModule internal/streams/destroy',
'NativeModule internal/streams/duplex',
'NativeModule internal/streams/end-of-stream', 'NativeModule internal/streams/end-of-stream',
'NativeModule internal/streams/from',
'NativeModule internal/streams/legacy', 'NativeModule internal/streams/legacy',
'NativeModule internal/streams/operators',
'NativeModule internal/streams/passthrough',
'NativeModule internal/streams/pipeline', 'NativeModule internal/streams/pipeline',
'NativeModule internal/streams/readable',
'NativeModule internal/streams/state', 'NativeModule internal/streams/state',
'NativeModule internal/streams/transform',
'NativeModule internal/streams/utils',
'NativeModule internal/streams/writable',
'NativeModule internal/worker', 'NativeModule internal/worker',
'NativeModule internal/worker/io', 'NativeModule internal/worker/io',
'NativeModule stream',
'NativeModule worker_threads', 'NativeModule worker_threads',
'NativeModule stream',
'NativeModule stream/promises',
'NativeModule string_decoder',
].forEach(expectedModules.add.bind(expectedModules)); ].forEach(expectedModules.add.bind(expectedModules));
} }
@ -214,46 +145,10 @@ if (common.hasIntl) {
expectedModules.add('NativeModule url'); expectedModules.add('NativeModule url');
} }
if (common.hasCrypto) {
expectedModules.add('Internal Binding crypto')
.add('NativeModule internal/crypto/hash')
.add('NativeModule internal/crypto/hashnames')
.add('NativeModule internal/crypto/keys')
.add('NativeModule internal/crypto/random')
.add('NativeModule internal/crypto/util')
.add('NativeModule internal/crypto/webcrypto')
.add('NativeModule internal/streams/lazy_transform');
}
if (process.features.inspector) { if (process.features.inspector) {
expectedModules.add('Internal Binding inspector'); expectedModules.add('Internal Binding inspector');
expectedModules.add('NativeModule internal/inspector_async_hook'); expectedModules.add('NativeModule internal/inspector_async_hook');
expectedModules.add('NativeModule internal/util/inspector'); expectedModules.add('NativeModule internal/util/inspector');
expectedModules.add('Internal Binding profiler');
}
if (process.env.NODE_V8_COVERAGE) {
expectedModules.add('Internal Binding profiler');
}
if (common.hasCrypto) {
expectedModules.add('Internal Binding crypto');
expectedModules.add('NativeModule crypto');
expectedModules.add('NativeModule internal/crypto/certificate');
expectedModules.add('NativeModule internal/crypto/cipher');
expectedModules.add('NativeModule internal/crypto/diffiehellman');
expectedModules.add('NativeModule internal/crypto/hash');
expectedModules.add('NativeModule internal/crypto/hashnames');
expectedModules.add('NativeModule internal/crypto/hkdf');
expectedModules.add('NativeModule internal/crypto/keygen');
expectedModules.add('NativeModule internal/crypto/keys');
expectedModules.add('NativeModule internal/crypto/pbkdf2');
expectedModules.add('NativeModule internal/crypto/random');
expectedModules.add('NativeModule internal/crypto/scrypt');
expectedModules.add('NativeModule internal/crypto/sig');
expectedModules.add('NativeModule internal/crypto/util');
expectedModules.add('NativeModule internal/crypto/x509');
expectedModules.add('NativeModule internal/streams/lazy_transform');
} }
const difference = (setA, setB) => { const difference = (setA, setB) => {

View File

@ -6,6 +6,7 @@ const { WPTRunner } = require('../common/wpt');
const runner = new WPTRunner('streams'); const runner = new WPTRunner('streams');
// Set a script that will be executed in the worker before running the tests. // Set a script that will be executed in the worker before running the tests.
runner.pretendGlobalThisAs('Window');
runner.setInitScript(` runner.setInitScript(`
// Simulate global postMessage for enqueue-with-detached-buffer.window.js // Simulate global postMessage for enqueue-with-detached-buffer.window.js
function postMessage(value, origin, transferList) { function postMessage(value, origin, transferList) {