diff --git a/lib/internal/bootstrap/cache.js b/lib/internal/bootstrap/cache.js index e706ccb20dc813..bed20106060193 100644 --- a/lib/internal/bootstrap/cache.js +++ b/lib/internal/bootstrap/cache.js @@ -13,7 +13,7 @@ const { hasTracing, hasInspector } = process.binding('config'); // Modules with source code compiled in js2c that // cannot be compiled with the code cache. -const cannotUseCache = [ +const cannotBeRequired = [ 'sys', // Deprecated. 'internal/v8_prof_polyfill', 'internal/v8_prof_processor', @@ -21,8 +21,7 @@ const cannotUseCache = [ 'internal/per_context', 'internal/test/binding', - // TODO(joyeecheung): update the C++ side so that - // the code cache is also used when compiling these two files. + 'internal/bootstrap/loaders', 'internal/bootstrap/node' ]; @@ -30,16 +29,16 @@ const cannotUseCache = [ // Skip modules that cannot be required when they are not // built into the binary. if (!hasInspector) { - cannotUseCache.push( + cannotBeRequired.push( 'inspector', 'internal/util/inspector', ); } if (!hasTracing) { - cannotUseCache.push('trace_events'); + cannotBeRequired.push('trace_events'); } if (!process.versions.openssl) { - cannotUseCache.push( + cannotBeRequired.push( 'crypto', 'https', 'http2', @@ -67,11 +66,11 @@ if (!process.versions.openssl) { const cachableBuiltins = []; for (const id of NativeModule.map.keys()) { - if (id.startsWith('internal/deps') || + if (id.startsWith('internal/deps') || id.startsWith('internal/main') || id.startsWith('v8/') || id.startsWith('node-inspect/')) { - cannotUseCache.push(id); + cannotBeRequired.push(id); } - if (!cannotUseCache.includes(id)) { + if (!cannotBeRequired.includes(id)) { cachableBuiltins.push(id); } } @@ -80,5 +79,5 @@ module.exports = { cachableBuiltins, getCodeCache, compileFunction, - cannotUseCache + cannotBeRequired }; diff --git a/lib/internal/bootstrap/loaders.js b/lib/internal/bootstrap/loaders.js index 6eed9eab267fa4..7078707b83adb1 100644 --- a/lib/internal/bootstrap/loaders.js +++ b/lib/internal/bootstrap/loaders.js @@ -160,7 +160,12 @@ internalBinding('module_wrap').callbackMap = new WeakMap(); // Think of this as module.exports in this file even though it is not // written in CommonJS style. -const loaderExports = { internalBinding, NativeModule }; +const loaderExports = { + internalBinding, + NativeModule, + require: nativeModuleRequire +}; + const loaderId = 'internal/bootstrap/loaders'; // Set up NativeModule. @@ -194,7 +199,7 @@ for (var i = 0; i < moduleIds.length; ++i) { NativeModule.map.set(id, mod); } -NativeModule.require = function(id) { +function nativeModuleRequire(id) { if (id === loaderId) { return loaderExports; } @@ -218,8 +223,9 @@ NativeModule.require = function(id) { moduleLoadList.push(`NativeModule ${id}`); mod.compile(); return mod.exports; -}; +} +NativeModule.require = nativeModuleRequire; NativeModule.exists = function(id) { return NativeModule.map.has(id); }; diff --git a/lib/internal/bootstrap/node.js b/lib/internal/bootstrap/node.js index 27eb50f8d60ebf..24f7033f714845 100644 --- a/lib/internal/bootstrap/node.js +++ b/lib/internal/bootstrap/node.js @@ -21,570 +21,318 @@ const { internalBinding, NativeModule } = loaderExports; const { getOptionValue } = NativeModule.require('internal/options'); const config = internalBinding('config'); -function startup() { - setupTraceCategoryState(); - - setupProcessObject(); - - // TODO(joyeecheung): this does not have to done so early, any fatal errors - // thrown before user code execution should simply crash the process - // and we do not care about any clean up at that point. We don't care - // about emitting any events if the process crash upon bootstrap either. - { - const { - fatalException, - setUncaughtExceptionCaptureCallback, - hasUncaughtExceptionCaptureCallback - } = NativeModule.require('internal/process/execution'); - - process._fatalException = fatalException; - process.setUncaughtExceptionCaptureCallback = +setupTraceCategoryState(); + +setupProcessObject(); + +// TODO(joyeecheung): this does not have to done so early, any fatal errors +// thrown before user code execution should simply crash the process +// and we do not care about any clean up at that point. We don't care +// about emitting any events if the process crash upon bootstrap either. +{ + const { + fatalException, + setUncaughtExceptionCaptureCallback, + hasUncaughtExceptionCaptureCallback + } = NativeModule.require('internal/process/execution'); + + process._fatalException = fatalException; + process.setUncaughtExceptionCaptureCallback = setUncaughtExceptionCaptureCallback; - process.hasUncaughtExceptionCaptureCallback = + process.hasUncaughtExceptionCaptureCallback = hasUncaughtExceptionCaptureCallback; - } +} - setupGlobalVariables(); +setupGlobalVariables(); + +// Bootstrappers for all threads, including worker threads and main thread +const perThreadSetup = NativeModule.require('internal/process/per_thread'); +// Bootstrappers for the main thread only +let mainThreadSetup; +// Bootstrappers for the worker threads only +let workerThreadSetup; +if (isMainThread) { + mainThreadSetup = NativeModule.require( + 'internal/process/main_thread_only' + ); +} else { + workerThreadSetup = NativeModule.require( + 'internal/process/worker_thread_only' + ); +} - // Bootstrappers for all threads, including worker threads and main thread - const perThreadSetup = NativeModule.require('internal/process/per_thread'); - // Bootstrappers for the main thread only - let mainThreadSetup; - // Bootstrappers for the worker threads only - let workerThreadSetup; - if (isMainThread) { - mainThreadSetup = NativeModule.require( - 'internal/process/main_thread_only' - ); - } else { - workerThreadSetup = NativeModule.require( - 'internal/process/worker_thread_only' - ); - } +// process.config is serialized config.gypi +process.config = JSON.parse(internalBinding('native_module').config); - // process.config is serialized config.gypi - process.config = JSON.parse(internalBinding('native_module').config); +const rawMethods = internalBinding('process_methods'); +// Set up methods and events on the process object for the main thread +if (isMainThread) { + // This depends on process being an event emitter + mainThreadSetup.setupSignalHandlers(internalBinding); - const rawMethods = internalBinding('process_methods'); - // Set up methods and events on the process object for the main thread - if (isMainThread) { - // This depends on process being an event emitter - mainThreadSetup.setupSignalHandlers(internalBinding); - - process.abort = rawMethods.abort; - const wrapped = mainThreadSetup.wrapProcessMethods(rawMethods); - process.umask = wrapped.umask; - process.chdir = wrapped.chdir; - - // TODO(joyeecheung): deprecate and remove these underscore methods - process._debugProcess = rawMethods._debugProcess; - process._debugEnd = rawMethods._debugEnd; - process._startProfilerIdleNotifier = + process.abort = rawMethods.abort; + const wrapped = mainThreadSetup.wrapProcessMethods(rawMethods); + process.umask = wrapped.umask; + process.chdir = wrapped.chdir; + + // TODO(joyeecheung): deprecate and remove these underscore methods + process._debugProcess = rawMethods._debugProcess; + process._debugEnd = rawMethods._debugEnd; + process._startProfilerIdleNotifier = rawMethods._startProfilerIdleNotifier; - process._stopProfilerIdleNotifier = rawMethods._stopProfilerIdleNotifier; - } else { - const wrapped = workerThreadSetup.wrapProcessMethods(rawMethods); + process._stopProfilerIdleNotifier = rawMethods._stopProfilerIdleNotifier; +} else { + const wrapped = workerThreadSetup.wrapProcessMethods(rawMethods); - process.umask = wrapped.umask; - } + process.umask = wrapped.umask; +} - // Set up methods on the process object for all threads - { - process.cwd = rawMethods.cwd; - process.dlopen = rawMethods.dlopen; - process.uptime = rawMethods.uptime; - - // TODO(joyeecheung): either remove them or make them public - process._getActiveRequests = rawMethods._getActiveRequests; - process._getActiveHandles = rawMethods._getActiveHandles; - - // TODO(joyeecheung): remove these - process.reallyExit = rawMethods.reallyExit; - process._kill = rawMethods._kill; - - const wrapped = perThreadSetup.wrapProcessMethods(rawMethods); - process._rawDebug = wrapped._rawDebug; - process.hrtime = wrapped.hrtime; - process.hrtime.bigint = wrapped.hrtimeBigInt; - process.cpuUsage = wrapped.cpuUsage; - process.memoryUsage = wrapped.memoryUsage; - process.kill = wrapped.kill; - process.exit = wrapped.exit; - } +// Set up methods on the process object for all threads +{ + process.cwd = rawMethods.cwd; + process.dlopen = rawMethods.dlopen; + process.uptime = rawMethods.uptime; + + // TODO(joyeecheung): either remove them or make them public + process._getActiveRequests = rawMethods._getActiveRequests; + process._getActiveHandles = rawMethods._getActiveHandles; + + // TODO(joyeecheung): remove these + process.reallyExit = rawMethods.reallyExit; + process._kill = rawMethods._kill; + + const wrapped = perThreadSetup.wrapProcessMethods(rawMethods); + process._rawDebug = wrapped._rawDebug; + process.hrtime = wrapped.hrtime; + process.hrtime.bigint = wrapped.hrtimeBigInt; + process.cpuUsage = wrapped.cpuUsage; + process.memoryUsage = wrapped.memoryUsage; + process.kill = wrapped.kill; + process.exit = wrapped.exit; +} - const { - onWarning, - emitWarning - } = NativeModule.require('internal/process/warning'); - if (!process.noProcessWarnings && process.env.NODE_NO_WARNINGS !== '1') { - process.on('warning', onWarning); - } - process.emitWarning = emitWarning; +const { + onWarning, + emitWarning +} = NativeModule.require('internal/process/warning'); +if (!process.noProcessWarnings && process.env.NODE_NO_WARNINGS !== '1') { + process.on('warning', onWarning); +} +process.emitWarning = emitWarning; + +const { + nextTick, + runNextTicks +} = NativeModule.require('internal/process/next_tick').setup(); + +process.nextTick = nextTick; +// Used to emulate a tick manually in the JS land. +// A better name for this function would be `runNextTicks` but +// it has been exposed to the process object so we keep this legacy name +// TODO(joyeecheung): either remove it or make it public +process._tickCallback = runNextTicks; + +const credentials = internalBinding('credentials'); +if (credentials.implementsPosixCredentials) { + process.getuid = credentials.getuid; + process.geteuid = credentials.geteuid; + process.getgid = credentials.getgid; + process.getegid = credentials.getegid; + process.getgroups = credentials.getgroups; - const { - nextTick, - runNextTicks - } = NativeModule.require('internal/process/next_tick').setup(); - - process.nextTick = nextTick; - // Used to emulate a tick manually in the JS land. - // A better name for this function would be `runNextTicks` but - // it has been exposed to the process object so we keep this legacy name - // TODO(joyeecheung): either remove it or make it public - process._tickCallback = runNextTicks; - - const credentials = internalBinding('credentials'); - if (credentials.implementsPosixCredentials) { - process.getuid = credentials.getuid; - process.geteuid = credentials.geteuid; - process.getgid = credentials.getgid; - process.getegid = credentials.getegid; - process.getgroups = credentials.getgroups; - - if (isMainThread) { - const wrapped = mainThreadSetup.wrapPosixCredentialSetters(credentials); - process.initgroups = wrapped.initgroups; - process.setgroups = wrapped.setgroups; - process.setegid = wrapped.setegid; - process.seteuid = wrapped.seteuid; - process.setgid = wrapped.setgid; - process.setuid = wrapped.setuid; - } + if (isMainThread) { + const wrapped = mainThreadSetup.wrapPosixCredentialSetters(credentials); + process.initgroups = wrapped.initgroups; + process.setgroups = wrapped.setgroups; + process.setegid = wrapped.setegid; + process.seteuid = wrapped.seteuid; + process.setgid = wrapped.setgid; + process.setuid = wrapped.setuid; } +} - if (isMainThread) { - const { getStdout, getStdin, getStderr } = +if (isMainThread) { + const { getStdout, getStdin, getStderr } = NativeModule.require('internal/process/stdio').getMainThreadStdio(); - setupProcessStdio(getStdout, getStdin, getStderr); - } else { - const { getStdout, getStdin, getStderr } = + setupProcessStdio(getStdout, getStdin, getStderr); +} else { + const { getStdout, getStdin, getStderr } = workerThreadSetup.initializeWorkerStdio(); - setupProcessStdio(getStdout, getStdin, getStderr); - } - - if (config.hasInspector) { - const { - enable, - disable - } = NativeModule.require('internal/inspector_async_hook'); - internalBinding('inspector').registerAsyncHook(enable, disable); - } - - // If the process is spawned with env NODE_CHANNEL_FD, it's probably - // spawned by our child_process module, then initialize IPC. - // This attaches some internal event listeners and creates: - // process.send(), process.channel, process.connected, - // process.disconnect() - if (isMainThread && process.env.NODE_CHANNEL_FD) { - mainThreadSetup.setupChildProcessIpcChannel(); - } + setupProcessStdio(getStdout, getStdin, getStderr); +} - // TODO(joyeecheung): move this down further to get better snapshotting - const experimentalPolicy = getOptionValue('--experimental-policy'); - if (isMainThread && experimentalPolicy) { - process.emitWarning('Policies are experimental.', - 'ExperimentalWarning'); - const { pathToFileURL, URL } = NativeModule.require('url'); - // URL here as it is slightly different parsing - // no bare specifiers for now - let manifestURL; - if (NativeModule.require('path').isAbsolute(experimentalPolicy)) { - manifestURL = new URL(`file:///${experimentalPolicy}`); - } else { - const cwdURL = pathToFileURL(process.cwd()); - cwdURL.pathname += '/'; - manifestURL = new URL(experimentalPolicy, cwdURL); - } - const fs = NativeModule.require('fs'); - const src = fs.readFileSync(manifestURL, 'utf8'); - NativeModule.require('internal/process/policy') - .setup(src, manifestURL.href); - } +if (config.hasInspector) { + const { + enable, + disable + } = NativeModule.require('internal/inspector_async_hook'); + internalBinding('inspector').registerAsyncHook(enable, disable); +} - const browserGlobals = !process._noBrowserGlobals; - if (browserGlobals) { - setupGlobalTimeouts(); - setupGlobalConsole(); - setupGlobalURL(); - setupGlobalEncoding(); - setupQueueMicrotask(); - } +// If the process is spawned with env NODE_CHANNEL_FD, it's probably +// spawned by our child_process module, then initialize IPC. +// This attaches some internal event listeners and creates: +// process.send(), process.channel, process.connected, +// process.disconnect() +if (isMainThread && process.env.NODE_CHANNEL_FD) { + mainThreadSetup.setupChildProcessIpcChannel(); +} - setupDOMException(); +const browserGlobals = !process._noBrowserGlobals; +if (browserGlobals) { + setupGlobalTimeouts(); + setupGlobalConsole(); + setupGlobalURL(); + setupGlobalEncoding(); + setupQueueMicrotask(); +} - // On OpenBSD process.execPath will be relative unless we - // get the full path before process.execPath is used. - if (process.platform === 'openbsd') { - const { realpathSync } = NativeModule.require('fs'); - process.execPath = realpathSync.native(process.execPath); - } +setupDOMException(); - Object.defineProperty(process, 'argv0', { - enumerable: true, - configurable: false, - value: process.argv[0] - }); - process.argv[0] = process.execPath; +// On OpenBSD process.execPath will be relative unless we +// get the full path before process.execPath is used. +if (process.platform === 'openbsd') { + const { realpathSync } = NativeModule.require('fs'); + process.execPath = realpathSync.native(process.execPath); +} - // Handle `--debug*` deprecation and invalidation. - if (process._invalidDebug) { - process.emitWarning( - '`node --debug` and `node --debug-brk` are invalid. ' + +Object.defineProperty(process, 'argv0', { + enumerable: true, + configurable: false, + value: process.argv[0] +}); +process.argv[0] = process.execPath; + +// Handle `--debug*` deprecation and invalidation. +if (process._invalidDebug) { + process.emitWarning( + '`node --debug` and `node --debug-brk` are invalid. ' + 'Please use `node --inspect` or `node --inspect-brk` instead.', - 'DeprecationWarning', 'DEP0062', startup, true); - process.exit(9); - } else if (process._deprecatedDebugBrk) { - process.emitWarning( - '`node --inspect --debug-brk` is deprecated. ' + + 'DeprecationWarning', 'DEP0062', undefined, true); + process.exit(9); +} else if (process._deprecatedDebugBrk) { + process.emitWarning( + '`node --inspect --debug-brk` is deprecated. ' + 'Please use `node --inspect-brk` instead.', - 'DeprecationWarning', 'DEP0062', startup, true); - } + 'DeprecationWarning', 'DEP0062', undefined, true); +} - const { deprecate } = NativeModule.require('internal/util'); - { - // Install legacy getters on the `util` binding for typechecking. - // TODO(addaleax): Turn into a full runtime deprecation. - const pendingDeprecation = getOptionValue('--pending-deprecation'); - const utilBinding = internalBinding('util'); - const types = NativeModule.require('internal/util/types'); - for (const name of [ - 'isArrayBuffer', 'isArrayBufferView', 'isAsyncFunction', - 'isDataView', 'isDate', 'isExternal', 'isMap', 'isMapIterator', - 'isNativeError', 'isPromise', 'isRegExp', 'isSet', 'isSetIterator', - 'isTypedArray', 'isUint8Array', 'isAnyArrayBuffer' - ]) { - utilBinding[name] = pendingDeprecation ? - deprecate(types[name], - 'Accessing native typechecking bindings of Node ' + +const { deprecate } = NativeModule.require('internal/util'); +{ + // Install legacy getters on the `util` binding for typechecking. + // TODO(addaleax): Turn into a full runtime deprecation. + const pendingDeprecation = getOptionValue('--pending-deprecation'); + const utilBinding = internalBinding('util'); + const types = NativeModule.require('internal/util/types'); + for (const name of [ + 'isArrayBuffer', 'isArrayBufferView', 'isAsyncFunction', + 'isDataView', 'isDate', 'isExternal', 'isMap', 'isMapIterator', + 'isNativeError', 'isPromise', 'isRegExp', 'isSet', 'isSetIterator', + 'isTypedArray', 'isUint8Array', 'isAnyArrayBuffer' + ]) { + utilBinding[name] = pendingDeprecation ? + deprecate(types[name], + 'Accessing native typechecking bindings of Node ' + 'directly is deprecated. ' + `Please use \`util.types.${name}\` instead.`, - 'DEP0103') : - types[name]; - } + 'DEP0103') : + types[name]; } - - // TODO(jasnell): The following have been globals since around 2012. - // That's just silly. The underlying perfctr support has been removed - // so these are now deprecated non-ops that can be removed after one - // major release cycle. - if (process.platform === 'win32') { - const names = [ - 'NET_SERVER_CONNECTION', - 'NET_SERVER_CONNECTION_CLOSE', - 'HTTP_SERVER_REQUEST', - 'HTTP_SERVER_RESPONSE', - 'HTTP_CLIENT_REQUEST', - 'HTTP_CLIENT_RESPONSE' - ]; - for (var n = 0; n < names.length; n++) { - Object.defineProperty(global, `COUNTER_${names[n]}`, { - configurable: true, - enumerable: false, - value: deprecate(noop, - `COUNTER_${names[n]}() is deprecated.`, - 'DEP0120') - }); - } - } - - // process.allowedNodeEnvironmentFlags - Object.defineProperty(process, 'allowedNodeEnvironmentFlags', { - get() { - const flags = perThreadSetup.buildAllowedFlags(); - process.allowedNodeEnvironmentFlags = flags; - return process.allowedNodeEnvironmentFlags; - }, - // If the user tries to set this to another value, override - // this completely to that value. - set(value) { - Object.defineProperty(this, 'allowedNodeEnvironmentFlags', { - value, - configurable: true, - enumerable: true, - writable: true - }); - }, - enumerable: true, - configurable: true - }); - // process.assert - process.assert = deprecate( - perThreadSetup.assert, - 'process.assert() is deprecated. Please use the `assert` module instead.', - 'DEP0100'); - - // TODO(joyeecheung): this property has not been well-maintained, should we - // deprecate it in favor of a better API? - const { isDebugBuild, hasOpenSSL } = config; - Object.defineProperty(process, 'features', { - enumerable: true, - writable: false, - configurable: false, - value: { - debug: isDebugBuild, - uv: true, - ipv6: true, // TODO(bnoordhuis) ping libuv - tls_alpn: hasOpenSSL, - tls_sni: hasOpenSSL, - tls_ocsp: hasOpenSSL, - tls: hasOpenSSL - } - }); - - // User-facing NODE_V8_COVERAGE environment variable that writes - // ScriptCoverage to a specified file. - if (process.env.NODE_V8_COVERAGE) { - const originalReallyExit = process.reallyExit; - const cwd = NativeModule.require('internal/process/execution').tryGetCwd(); - const { resolve } = NativeModule.require('path'); - // Resolve the coverage directory to an absolute path, and - // overwrite process.env so that the original path gets passed - // to child processes even when they switch cwd. - const coverageDirectory = resolve(cwd, process.env.NODE_V8_COVERAGE); - process.env.NODE_V8_COVERAGE = coverageDirectory; - const { - writeCoverage, - setCoverageDirectory - } = NativeModule.require('internal/coverage-gen/with_profiler'); - setCoverageDirectory(coverageDirectory); - process.on('exit', writeCoverage); - process.reallyExit = (code) => { - writeCoverage(); - originalReallyExit(code); - }; - } - - const perf = internalBinding('performance'); - const { - NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE, - } = perf.constants; - perf.markMilestone(NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE); - - if (getOptionValue('--experimental-report')) { - NativeModule.require('internal/process/report').setup(); - } - - if (isMainThread) { - return startMainThreadExecution; - } else { - return startWorkerThreadExecution; - } -} - -function startWorkerThreadExecution() { - // If we are in a worker thread, execute the script sent through the - // message port. - const { - getEnvMessagePort, - threadId - } = internalBinding('worker'); - const { - createMessageHandler, - createWorkerFatalExeception - } = NativeModule.require('internal/process/worker_thread_only'); - - // Set up the message port and start listening - const debug = NativeModule.require('util').debuglog('worker'); - debug(`[${threadId}] is setting up worker child environment`); - - const port = getEnvMessagePort(); - port.on('message', createMessageHandler( - port, - prepareUserCodeExecution)); - port.start(); - - // Overwrite fatalException - process._fatalException = createWorkerFatalExeception(port); } -// There are various modes that Node can run in. The most common two -// are running from a script and running the REPL - but there are a few -// others like the debugger or running --eval arguments. Here we decide -// which mode we run in. -function startMainThreadExecution(mainScript) { - if (mainScript) { - process.nextTick(() => { - NativeModule.require(mainScript); - }); - return; - } - - // `node inspect ...` or `node debug ...` - if (process.argv[1] === 'inspect' || process.argv[1] === 'debug') { - if (process.argv[1] === 'debug') { - process.emitWarning( - '`node debug` is deprecated. Please use `node inspect` instead.', - 'DeprecationWarning', 'DEP0068'); - } - - // Start the debugger agent. - process.nextTick(() => { - NativeModule.require('internal/deps/node-inspect/lib/_inspect').start(); +// TODO(jasnell): The following have been globals since around 2012. +// That's just silly. The underlying perfctr support has been removed +// so these are now deprecated non-ops that can be removed after one +// major release cycle. +if (process.platform === 'win32') { + const names = [ + 'NET_SERVER_CONNECTION', + 'NET_SERVER_CONNECTION_CLOSE', + 'HTTP_SERVER_REQUEST', + 'HTTP_SERVER_RESPONSE', + 'HTTP_CLIENT_REQUEST', + 'HTTP_CLIENT_RESPONSE' + ]; + for (var n = 0; n < names.length; n++) { + Object.defineProperty(global, `COUNTER_${names[n]}`, { + configurable: true, + enumerable: false, + value: deprecate(noop, + `COUNTER_${names[n]}() is deprecated.`, + 'DEP0120') }); - return; - } - - // node --help - if (getOptionValue('--help')) { - NativeModule.require('internal/print_help').print(process.stdout); - return; } - - // e.g. node --completion-bash >> ~/.bashrc - if (getOptionValue('--completion-bash')) { - NativeModule.require('internal/bash_completion').print(process.stdout); - return; - } - - // `node --prof-process` - if (getOptionValue('--prof-process')) { - NativeModule.require('internal/v8_prof_processor'); - return; - } - - // There is user code to be run. - prepareUserCodeExecution(); - executeUserCode(); } -function prepareUserCodeExecution() { - // If this is a worker in cluster mode, start up the communication - // channel. This needs to be done before any user code gets executed - // (including preload modules). - if (process.argv[1] && process.env.NODE_UNIQUE_ID) { - const cluster = NativeModule.require('cluster'); - cluster._setupWorker(); - // Make sure it's not accidentally inherited by child processes. - delete process.env.NODE_UNIQUE_ID; - } - - const experimentalModules = getOptionValue('--experimental-modules'); - const experimentalVMModules = getOptionValue('--experimental-vm-modules'); - if (experimentalModules || experimentalVMModules) { - if (experimentalModules) { - process.emitWarning( - 'The ESM module loader is experimental.', - 'ExperimentalWarning', undefined); - } - - const { - setImportModuleDynamicallyCallback, - setInitializeImportMetaObjectCallback - } = internalBinding('module_wrap'); - const esm = NativeModule.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 userLoader = getOptionValue('--loader'); - // If --loader is specified, create a loader with user hooks. Otherwise - // create the default loader. - esm.initializeLoader(process.cwd(), userLoader); - } - - // For user code, we preload modules if `-r` is passed - const preloadModules = getOptionValue('--require'); - if (preloadModules.length) { - const { - _preloadModules - } = NativeModule.require('internal/modules/cjs/loader'); - _preloadModules(preloadModules); - } -} - -function executeUserCode() { - // User passed `-e` or `--eval` arguments to Node without `-i` or - // `--interactive`. - // Note that the name `forceRepl` is merely an alias of `interactive` - // in code. - if (getOptionValue('[has_eval_string]') && !getOptionValue('--interactive')) { - const { - addBuiltinLibsToObject - } = NativeModule.require('internal/modules/cjs/helpers'); - addBuiltinLibsToObject(global); - const source = getOptionValue('--eval'); - const { evalScript } = NativeModule.require('internal/process/execution'); - evalScript('[eval]', source, process._breakFirstLine); - return; - } - - // If the first argument is a file name, run it as a main script - if (process.argv[1] && process.argv[1] !== '-') { - // Expand process.argv[1] into a full path. - const path = NativeModule.require('path'); - process.argv[1] = path.resolve(process.argv[1]); - - const CJSModule = NativeModule.require('internal/modules/cjs/loader'); - - // If user passed `-c` or `--check` arguments to Node, check its syntax - // instead of actually running the file. - if (getOptionValue('--check')) { - const fs = NativeModule.require('fs'); - // Read the source. - const filename = CJSModule._resolveFilename(process.argv[1]); - const source = fs.readFileSync(filename, 'utf-8'); - checkScriptSyntax(source, filename); - process.exit(0); - } - - // Note: this actually tries to run the module as a ESM first if - // --experimental-modules is on. - // TODO(joyeecheung): can we move that logic to here? Note that this - // is an undocumented method available via `require('module').runMain` - CJSModule.runMain(); - return; - } - - // Create the REPL if `-i` or `--interactive` is passed, or if - // stdin is a TTY. - // Note that the name `forceRepl` is merely an alias of `interactive` - // in code. - if (process._forceRepl || NativeModule.require('tty').isatty(0)) { - const cliRepl = NativeModule.require('internal/repl'); - cliRepl.createInternalRepl(process.env, (err, repl) => { - if (err) { - throw err; - } - repl.on('exit', () => { - if (repl._flushing) { - repl.pause(); - return repl.once('flushHistory', () => { - process.exit(); - }); - } - process.exit(); - }); +// process.allowedNodeEnvironmentFlags +Object.defineProperty(process, 'allowedNodeEnvironmentFlags', { + get() { + const flags = perThreadSetup.buildAllowedFlags(); + process.allowedNodeEnvironmentFlags = flags; + return process.allowedNodeEnvironmentFlags; + }, + // If the user tries to set this to another value, override + // this completely to that value. + set(value) { + Object.defineProperty(this, 'allowedNodeEnvironmentFlags', { + value, + configurable: true, + enumerable: true, + writable: true }); - - // User passed '-e' or '--eval' along with `-i` or `--interactive` - if (process._eval != null) { - const { evalScript } = NativeModule.require('internal/process/execution'); - evalScript('[eval]', process._eval, process._breakFirstLine); - } - return; - } - - // Stdin is not a TTY, we will read it and execute it. - readAndExecuteStdin(); + }, + enumerable: true, + configurable: true +}); +// process.assert +process.assert = deprecate( + perThreadSetup.assert, + 'process.assert() is deprecated. Please use the `assert` module instead.', + 'DEP0100'); + +// TODO(joyeecheung): this property has not been well-maintained, should we +// deprecate it in favor of a better API? +const { isDebugBuild, hasOpenSSL } = config; +Object.defineProperty(process, 'features', { + enumerable: true, + writable: false, + configurable: false, + value: { + debug: isDebugBuild, + uv: true, + ipv6: true, // TODO(bnoordhuis) ping libuv + tls_alpn: hasOpenSSL, + tls_sni: hasOpenSSL, + tls_ocsp: hasOpenSSL, + tls: hasOpenSSL + } +}); + +// User-facing NODE_V8_COVERAGE environment variable that writes +// ScriptCoverage to a specified file. +if (process.env.NODE_V8_COVERAGE) { + const originalReallyExit = process.reallyExit; + const cwd = NativeModule.require('internal/process/execution').tryGetCwd(); + const { resolve } = NativeModule.require('path'); + // Resolve the coverage directory to an absolute path, and + // overwrite process.env so that the original path gets passed + // to child processes even when they switch cwd. + const coverageDirectory = resolve(cwd, process.env.NODE_V8_COVERAGE); + process.env.NODE_V8_COVERAGE = coverageDirectory; + const { + writeCoverage, + setCoverageDirectory + } = NativeModule.require('internal/coverage-gen/with_profiler'); + setCoverageDirectory(coverageDirectory); + process.on('exit', writeCoverage); + process.reallyExit = (code) => { + writeCoverage(); + originalReallyExit(code); + }; } -function readAndExecuteStdin() { - process.stdin.setEncoding('utf8'); - - let code = ''; - process.stdin.on('data', (d) => { - code += d; - }); - - process.stdin.on('end', () => { - if (process._syntax_check_only != null) { - checkScriptSyntax(code, '[stdin]'); - } else { - process._eval = code; - const { evalScript } = NativeModule.require('internal/process/execution'); - evalScript('[stdin]', process._eval, process._breakFirstLine); - } - }); +if (getOptionValue('--experimental-report')) { + NativeModule.require('internal/process/report').setup(); } function setupTraceCategoryState() { @@ -810,22 +558,3 @@ function setupDOMException() { } function noop() {} - -function checkScriptSyntax(source, filename) { - const CJSModule = NativeModule.require('internal/modules/cjs/loader'); - const vm = NativeModule.require('vm'); - const { - stripShebang, stripBOM - } = NativeModule.require('internal/modules/cjs/helpers'); - - // Remove Shebang. - source = stripShebang(source); - // Remove BOM. - source = stripBOM(source); - // Wrap it. - source = CJSModule.wrap(source); - // Compile the script, this will throw if it fails. - new vm.Script(source, { displayErrors: true, filename }); -} - -return startup(); diff --git a/lib/internal/bootstrap/pre_execution.js b/lib/internal/bootstrap/pre_execution.js new file mode 100644 index 00000000000000..798c581a721735 --- /dev/null +++ b/lib/internal/bootstrap/pre_execution.js @@ -0,0 +1,82 @@ +'use strict'; + +const { getOptionValue } = require('internal/options'); + +function initializeClusterIPC() { + // If this is a worker in cluster mode, start up the communication + // channel. This needs to be done before any user code gets executed + // (including preload modules). + if (process.argv[1] && process.env.NODE_UNIQUE_ID) { + const cluster = require('cluster'); + cluster._setupWorker(); + // Make sure it's not accidentally inherited by child processes. + delete process.env.NODE_UNIQUE_ID; + } +} + +function initializePolicy() { + const experimentalPolicy = getOptionValue('--experimental-policy'); + if (experimentalPolicy) { + process.emitWarning('Policies are experimental.', + 'ExperimentalWarning'); + const { pathToFileURL, URL } = require('url'); + // URL here as it is slightly different parsing + // no bare specifiers for now + let manifestURL; + if (require('path').isAbsolute(experimentalPolicy)) { + manifestURL = new URL(`file:///${experimentalPolicy}`); + } else { + const cwdURL = pathToFileURL(process.cwd()); + cwdURL.pathname += '/'; + manifestURL = new URL(experimentalPolicy, cwdURL); + } + const fs = require('fs'); + const src = fs.readFileSync(manifestURL, 'utf8'); + require('internal/process/policy') + .setup(src, manifestURL.href); + } +} + +function initializeESMLoader() { + const experimentalModules = getOptionValue('--experimental-modules'); + const experimentalVMModules = getOptionValue('--experimental-vm-modules'); + if (experimentalModules || experimentalVMModules) { + if (experimentalModules) { + process.emitWarning( + 'The ESM module loader is experimental.', + 'ExperimentalWarning', undefined); + } + + 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 userLoader = getOptionValue('--loader'); + // If --loader is specified, create a loader with user hooks. Otherwise + // create the default loader. + esm.initializeLoader(process.cwd(), userLoader); + } +} + +function loadPreloadModules() { + // For user code, we preload modules if `-r` is passed + const preloadModules = getOptionValue('--require'); + if (preloadModules) { + const { + _preloadModules + } = require('internal/modules/cjs/loader'); + _preloadModules(preloadModules); + } +} + +module.exports = { + initializeClusterIPC, + initializePolicy, + initializeESMLoader, + loadPreloadModules +}; diff --git a/lib/internal/main/.eslintrc.yaml b/lib/internal/main/.eslintrc.yaml new file mode 100644 index 00000000000000..dfb75077782301 --- /dev/null +++ b/lib/internal/main/.eslintrc.yaml @@ -0,0 +1,2 @@ +globals: + markBootstrapComplete: true diff --git a/lib/internal/main/check_syntax.js b/lib/internal/main/check_syntax.js new file mode 100644 index 00000000000000..5d4d7a04ebd0eb --- /dev/null +++ b/lib/internal/main/check_syntax.js @@ -0,0 +1,56 @@ +'use strict'; + +// If user passed `-c` or `--check` arguments to Node, check its syntax +// instead of actually running the file. + +const { + initializeClusterIPC, + initializePolicy, + initializeESMLoader, + loadPreloadModules +} = require('internal/bootstrap/pre_execution'); + +const { + readStdin +} = require('internal/process/execution'); + +const CJSModule = require('internal/modules/cjs/loader'); +const vm = require('vm'); +const { + stripShebang, stripBOM +} = require('internal/modules/cjs/helpers'); + +// TODO(joyeecheung): not every one of these are necessary +initializeClusterIPC(); +initializePolicy(); +initializeESMLoader(); +loadPreloadModules(); +markBootstrapComplete(); + +if (process.argv[1] && process.argv[1] !== '-') { + // Expand process.argv[1] into a full path. + const path = require('path'); + process.argv[1] = path.resolve(process.argv[1]); + // Read the source. + const filename = CJSModule._resolveFilename(process.argv[1]); + + const fs = require('fs'); + const source = fs.readFileSync(filename, 'utf-8'); + + checkScriptSyntax(source, filename); +} else { + readStdin((code) => { + checkScriptSyntax(code, '[stdin]'); + }); +} + +function checkScriptSyntax(source, filename) { + // Remove Shebang. + source = stripShebang(source); + // Remove BOM. + source = stripBOM(source); + // Wrap it. + source = CJSModule.wrap(source); + // Compile the script, this will throw if it fails. + new vm.Script(source, { displayErrors: true, filename }); +} diff --git a/lib/internal/main/eval_stdin.js b/lib/internal/main/eval_stdin.js new file mode 100644 index 00000000000000..ad15fdb93cd49d --- /dev/null +++ b/lib/internal/main/eval_stdin.js @@ -0,0 +1,26 @@ +'use strict'; + +// Stdin is not a TTY, we will read it and execute it. + +const { + initializeClusterIPC, + initializePolicy, + initializeESMLoader, + loadPreloadModules +} = require('internal/bootstrap/pre_execution'); + +const { + evalScript, + readStdin +} = require('internal/process/execution'); + +initializeClusterIPC(); +initializePolicy(); +initializeESMLoader(); +loadPreloadModules(); +markBootstrapComplete(); + +readStdin((code) => { + process._eval = code; + evalScript('[stdin]', process._eval, process._breakFirstLine); +}); diff --git a/lib/internal/main/eval_string.js b/lib/internal/main/eval_string.js new file mode 100644 index 00000000000000..cd382b48e76663 --- /dev/null +++ b/lib/internal/main/eval_string.js @@ -0,0 +1,22 @@ +'use strict'; + +// User passed `-e` or `--eval` arguments to Node without `-i` or +// `--interactive`. + +const { + initializeClusterIPC, + initializePolicy, + initializeESMLoader, + loadPreloadModules +} = require('internal/bootstrap/pre_execution'); +const { evalScript } = require('internal/process/execution'); +const { addBuiltinLibsToObject } = require('internal/modules/cjs/helpers'); + +const source = require('internal/options').getOptionValue('--eval'); +initializeClusterIPC(); +initializePolicy(); +initializeESMLoader(); +loadPreloadModules(); +addBuiltinLibsToObject(global); +markBootstrapComplete(); +evalScript('[eval]', source, process._breakFirstLine); diff --git a/lib/internal/main/inspect.js b/lib/internal/main/inspect.js new file mode 100644 index 00000000000000..7376f8984b13e1 --- /dev/null +++ b/lib/internal/main/inspect.js @@ -0,0 +1,16 @@ +'use strict'; + +// `node inspect ...` or `node debug ...` + +if (process.argv[1] === 'debug') { + process.emitWarning( + '`node debug` is deprecated. Please use `node inspect` instead.', + 'DeprecationWarning', 'DEP0068'); +} + +markBootstrapComplete(); + +// Start the debugger agent. +process.nextTick(() => { + require('internal/deps/node-inspect/lib/_inspect').start(); +}); diff --git a/lib/internal/bash_completion.js b/lib/internal/main/print_bash_completion.js similarity index 91% rename from lib/internal/bash_completion.js rename to lib/internal/main/print_bash_completion.js index 13363e8c4b8c32..225ed3d2221c00 100644 --- a/lib/internal/bash_completion.js +++ b/lib/internal/main/print_bash_completion.js @@ -18,6 +18,6 @@ function print(stream) { complete -F _node_complete node node_g`); } -module.exports = { - print -}; +markBootstrapComplete(); + +print(process.stdout); diff --git a/lib/internal/print_help.js b/lib/internal/main/print_help.js similarity index 99% rename from lib/internal/print_help.js rename to lib/internal/main/print_help.js index fdec7bd09bd87e..ca60994d942c6c 100644 --- a/lib/internal/print_help.js +++ b/lib/internal/main/print_help.js @@ -172,6 +172,6 @@ function print(stream) { stream.write('\nDocumentation can be found at https://nodejs.org/\n'); } -module.exports = { - print -}; +markBootstrapComplete(); + +print(process.stdout); diff --git a/lib/internal/main/prof_process.js b/lib/internal/main/prof_process.js new file mode 100644 index 00000000000000..a1143cb201e79c --- /dev/null +++ b/lib/internal/main/prof_process.js @@ -0,0 +1,4 @@ +'use strict'; + +markBootstrapComplete(); +require('internal/v8_prof_processor'); diff --git a/lib/internal/main/repl.js b/lib/internal/main/repl.js new file mode 100644 index 00000000000000..4ca328421bcb9a --- /dev/null +++ b/lib/internal/main/repl.js @@ -0,0 +1,44 @@ +'use strict'; + +// Create the REPL if `-i` or `--interactive` is passed, or if +// the main module is not specified and stdin is a TTY. + +const { + initializeClusterIPC, + initializePolicy, + initializeESMLoader, + loadPreloadModules +} = require('internal/bootstrap/pre_execution'); + +const { + evalScript +} = require('internal/process/execution'); + +initializeClusterIPC(); +initializePolicy(); +initializeESMLoader(); +loadPreloadModules(); + +const cliRepl = require('internal/repl'); +cliRepl.createInternalRepl(process.env, (err, repl) => { + if (err) { + throw err; + } + repl.on('exit', () => { + if (repl._flushing) { + repl.pause(); + return repl.once('flushHistory', () => { + process.exit(); + }); + } + process.exit(); + }); +}); + +// If user passed '-e' or '--eval' along with `-i` or `--interactive`, +// evaluate the code in the current context. +if (process._eval != null) { + evalScript('[eval]', process._eval, process._breakFirstLine); +} + +markBootstrapComplete(); diff --git a/lib/internal/main/run_main_module.js b/lib/internal/main/run_main_module.js new file mode 100644 index 00000000000000..b5049cffc5250c --- /dev/null +++ b/lib/internal/main/run_main_module.js @@ -0,0 +1,27 @@ +'use strict'; + +const { + initializeClusterIPC, + initializePolicy, + initializeESMLoader, + loadPreloadModules +} = require('internal/bootstrap/pre_execution'); + +initializeClusterIPC(); +initializePolicy(); +initializeESMLoader(); +loadPreloadModules(); + +// Expand process.argv[1] into a full path. +const path = require('path'); +process.argv[1] = path.resolve(process.argv[1]); + +const CJSModule = require('internal/modules/cjs/loader'); + +markBootstrapComplete(); + +// Note: this actually tries to run the module as a ESM first if +// --experimental-modules is on. +// TODO(joyeecheung): can we move that logic to here? Note that this +// is an undocumented method available via `require('module').runMain` +CJSModule.runMain(); diff --git a/lib/internal/main/run_third_party_main.js b/lib/internal/main/run_third_party_main.js new file mode 100644 index 00000000000000..c26c1f25f380c8 --- /dev/null +++ b/lib/internal/main/run_third_party_main.js @@ -0,0 +1,9 @@ +'use strict'; + +// Legacy _third_party_main.js support + +markBootstrapComplete(); + +process.nextTick(() => { + require('_third_party_main'); +}); diff --git a/lib/internal/main/worker_thread.js b/lib/internal/main/worker_thread.js new file mode 100644 index 00000000000000..62a4bb1b7dd77e --- /dev/null +++ b/lib/internal/main/worker_thread.js @@ -0,0 +1,39 @@ +'use strict'; + +// In worker threads, execute the script sent through the +// message port. + +const { + initializeClusterIPC, + initializeESMLoader, + loadPreloadModules +} = require('internal/bootstrap/pre_execution'); + +const { + getEnvMessagePort, + threadId +} = internalBinding('worker'); + +const { + createMessageHandler, + createWorkerFatalExeception +} = require('internal/process/worker_thread_only'); + +const debug = require('util').debuglog('worker'); +debug(`[${threadId}] is setting up worker child environment`); + +function prepareUserCodeExecution() { + initializeClusterIPC(); + initializeESMLoader(); + loadPreloadModules(); +} + +// Set up the message port and start listening +const port = getEnvMessagePort(); +port.on('message', createMessageHandler(port, prepareUserCodeExecution)); +port.start(); + +// Overwrite fatalException +process._fatalException = createWorkerFatalExeception(port); + +markBootstrapComplete(); diff --git a/lib/internal/process/execution.js b/lib/internal/process/execution.js index 7aac90d79d7248..a35feaacce28ff 100644 --- a/lib/internal/process/execution.js +++ b/lib/internal/process/execution.js @@ -164,7 +164,21 @@ function createFatalException() { }; } +function readStdin(callback) { + process.stdin.setEncoding('utf8'); + + let code = ''; + process.stdin.on('data', (d) => { + code += d; + }); + + process.stdin.on('end', () => { + callback(code); + }); +} + module.exports = { + readStdin, tryGetCwd, evalScript, fatalException: createFatalException(), diff --git a/node.gyp b/node.gyp index 8f974b020b8e75..56b7548349f1dc 100644 --- a/node.gyp +++ b/node.gyp @@ -30,6 +30,7 @@ 'lib/internal/bootstrap/cache.js', 'lib/internal/bootstrap/loaders.js', 'lib/internal/bootstrap/node.js', + 'lib/internal/bootstrap/pre_execution.js', 'lib/async_hooks.js', 'lib/assert.js', 'lib/buffer.js', @@ -87,7 +88,6 @@ 'lib/internal/assert.js', 'lib/internal/assert/assertion_error.js', 'lib/internal/async_hooks.js', - 'lib/internal/bash_completion.js', 'lib/internal/buffer.js', 'lib/internal/cli_table.js', 'lib/internal/child_process.js', @@ -132,6 +132,17 @@ 'lib/internal/inspector_async_hook.js', 'lib/internal/js_stream_socket.js', 'lib/internal/linkedlist.js', + 'lib/internal/main/check_syntax.js', + 'lib/internal/main/eval_string.js', + 'lib/internal/main/eval_stdin.js', + 'lib/internal/main/inspect.js', + 'lib/internal/main/print_bash_completion.js', + 'lib/internal/main/print_help.js', + 'lib/internal/main/prof_process.js', + 'lib/internal/main/repl.js', + 'lib/internal/main/run_main_module.js', + 'lib/internal/main/run_third_party_main.js', + 'lib/internal/main/worker_thread.js', 'lib/internal/modules/cjs/helpers.js', 'lib/internal/modules/cjs/loader.js', 'lib/internal/modules/esm/loader.js', @@ -143,9 +154,8 @@ 'lib/internal/safe_globals.js', 'lib/internal/net.js', 'lib/internal/options.js', - 'lib/internal/policy/sri.js', 'lib/internal/policy/manifest.js', - 'lib/internal/print_help.js', + 'lib/internal/policy/sri.js', 'lib/internal/priority_queue.js', 'lib/internal/process/esm_loader.js', 'lib/internal/process/execution.js', diff --git a/src/env.cc b/src/env.cc index bdec7129e0bca6..269da1a49f1ee6 100644 --- a/src/env.cc +++ b/src/env.cc @@ -330,9 +330,20 @@ void Environment::Start(bool start_profiler_idle_notifier) { uv_key_set(&thread_local_env, this); } -MaybeLocal Environment::CreateProcessObject( +MaybeLocal Environment::ProcessCliArgs( const std::vector& args, const std::vector& exec_args) { + if (args.size() > 1) { + std::string first_arg = args[1]; + if (first_arg == "inspect") { + execution_mode_ = ExecutionMode::kInspect; + } else if (first_arg == "debug") { + execution_mode_ = ExecutionMode::kDebug; + } else if (first_arg != "-") { + execution_mode_ = ExecutionMode::kRunMainModule; + } + } + if (*TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED( TRACING_CATEGORY_NODE1(environment)) != 0) { auto traced_value = tracing::TracedValue::Create(); diff --git a/src/env.h b/src/env.h index 009d00f6378c70..8a6b2d0e479997 100644 --- a/src/env.h +++ b/src/env.h @@ -353,11 +353,13 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2; V(http2session_on_stream_trailers_function, v8::Function) \ V(http2settings_constructor_template, v8::ObjectTemplate) \ V(http2stream_constructor_template, v8::ObjectTemplate) \ + V(internal_binding_loader, v8::Function) \ V(immediate_callback_function, v8::Function) \ V(inspector_console_extension_installer, v8::Function) \ V(libuv_stream_wrap_ctor_template, v8::FunctionTemplate) \ V(message_port, v8::Object) \ V(message_port_constructor_template, v8::FunctionTemplate) \ + V(native_module_require, v8::Function) \ V(performance_entry_callback, v8::Function) \ V(performance_entry_template, v8::Function) \ V(pipe_constructor_template, v8::FunctionTemplate) \ @@ -369,7 +371,6 @@ constexpr size_t kFsStatsBufferLength = kFsStatsFieldsNumber * 2; V(script_data_constructor_function, v8::Function) \ V(secure_context_constructor_template, v8::FunctionTemplate) \ V(shutdown_wrap_template, v8::ObjectTemplate) \ - V(start_execution_function, v8::Function) \ V(tcp_constructor_template, v8::FunctionTemplate) \ V(tick_callback_function, v8::Function) \ V(timers_callback_function, v8::Function) \ @@ -609,7 +610,7 @@ class Environment { ~Environment(); void Start(bool start_profiler_idle_notifier); - v8::MaybeLocal CreateProcessObject( + v8::MaybeLocal ProcessCliArgs( const std::vector& args, const std::vector& exec_args); @@ -926,6 +927,24 @@ class Environment { inline std::shared_ptr options(); inline std::shared_ptr inspector_host_port(); + enum class ExecutionMode { + kDefault, + kInspect, // node inspect + kDebug, // node debug + kPrintHelp, // node --help + kPrintBashCompletion, // node --completion-bash + kProfProcess, // node --prof-process + kEvalString, // node --eval without --interactive + kCheckSyntax, // node --check (incompatible with --eval) + kRepl, + kEvalStdin, + kRunMainModule + }; + + inline ExecutionMode execution_mode() { return execution_mode_; } + + inline void set_execution_mode(ExecutionMode mode) { execution_mode_ = mode; } + private: inline void CreateImmediate(native_immediate_callback cb, void* data, @@ -935,6 +954,7 @@ class Environment { inline void ThrowError(v8::Local (*fun)(v8::Local), const char* errmsg); + ExecutionMode execution_mode_ = ExecutionMode::kDefault; std::list loaded_addons_; v8::Isolate* const isolate_; IsolateData* const isolate_data_; diff --git a/src/node.cc b/src/node.cc index 881ace6e425a77..e67b16af83f0df 100644 --- a/src/node.cc +++ b/src/node.cc @@ -100,6 +100,7 @@ #if defined(_MSC_VER) #include #include +#define STDIN_FILENO 0 #else #include #include // getrlimit, setrlimit @@ -114,6 +115,7 @@ using v8::Array; using v8::Boolean; using v8::Context; using v8::DEFAULT; +using v8::EscapableHandleScope; using v8::Exception; using v8::Function; using v8::FunctionCallbackInfo; @@ -605,8 +607,20 @@ static MaybeLocal ExecuteBootstrapper( const char* id, std::vector>* parameters, std::vector>* arguments) { - MaybeLocal ret = per_process::native_module_loader.CompileAndCall( - env->context(), id, parameters, arguments, env); + EscapableHandleScope scope(env->isolate()); + MaybeLocal maybe_fn = + per_process::native_module_loader.LookupAndCompile( + env->context(), id, parameters, env); + + if (maybe_fn.IsEmpty()) { + return MaybeLocal(); + } + + Local fn = maybe_fn.ToLocalChecked(); + MaybeLocal result = fn->Call(env->context(), + Undefined(env->isolate()), + arguments->size(), + arguments->data()); // If there was an error during bootstrap then it was either handled by the // FatalException handler or it's unrecoverable (e.g. max call stack @@ -615,44 +629,17 @@ static MaybeLocal ExecuteBootstrapper( // There are only two ways to have a stack size > 1: 1) the user manually // called MakeCallback or 2) user awaited during bootstrap, which triggered // _tickCallback(). - if (ret.IsEmpty()) { + if (result.IsEmpty()) { env->async_hooks()->clear_async_id_stack(); } - return ret; -} - -void LoadEnvironment(Environment* env) { - RunBootstrapping(env); - - // To allow people to extend Node in different ways, this hook allows - // one to drop a file lib/_third_party_main.js into the build - // directory which will be executed instead of Node's normal loading. - if (per_process::native_module_loader.Exists("_third_party_main")) { - StartExecution(env, "_third_party_main"); - } else { - // TODO(joyeecheung): create different scripts for different - // execution modes: - // - `main_thread_main.js` when env->is_main_thread() - // - `worker_thread_main.js` when !env->is_main_thread() - // - `run_third_party_main.js` for `_third_party_main` - // - `inspect_main.js` for `node inspect` - // - `mkcodecache_main.js` for the code cache generator - // - `print_help_main.js` for --help - // - `bash_completion_main.js` for --completion-bash - // - `internal/v8_prof_processor` for --prof-process - // And leave bootstrap/node.js dedicated to the setup of the environment. - // We may want to move this switch out of LoadEnvironment, especially for - // the per-process options. - StartExecution(env, nullptr); - } + return scope.EscapeMaybe(result); } -void RunBootstrapping(Environment* env) { +MaybeLocal RunBootstrapping(Environment* env) { CHECK(!env->has_run_bootstrapping_code()); - env->set_has_run_bootstrapping_code(true); - HandleScope handle_scope(env->isolate()); + EscapableHandleScope scope(env->isolate()); Isolate* isolate = env->isolate(); Local context = env->context(); @@ -702,14 +689,24 @@ void RunBootstrapping(Environment* env) { Boolean::New(isolate, env->options()->expose_internals)}; - MaybeLocal loader_exports; // Bootstrap internal loaders - loader_exports = ExecuteBootstrapper( + MaybeLocal loader_exports = ExecuteBootstrapper( env, "internal/bootstrap/loaders", &loaders_params, &loaders_args); if (loader_exports.IsEmpty()) { - return; + return MaybeLocal(); } + Local loader_exports_obj = + loader_exports.ToLocalChecked().As(); + Local internal_binding_loader = + loader_exports_obj->Get(context, env->internal_binding_string()) + .ToLocalChecked(); + env->set_internal_binding_loader(internal_binding_loader.As()); + + Local require = + loader_exports_obj->Get(context, env->require_string()).ToLocalChecked(); + env->set_native_module_require(require.As()); + // process, loaderExports, isMainThread std::vector> node_params = { env->process_string(), @@ -717,43 +714,107 @@ void RunBootstrapping(Environment* env) { FIXED_ONE_BYTE_STRING(isolate, "isMainThread")}; std::vector> node_args = { process, - loader_exports.ToLocalChecked(), + loader_exports_obj, Boolean::New(isolate, env->is_main_thread())}; - Local start_execution; - if (!ExecuteBootstrapper( - env, "internal/bootstrap/node", &node_params, &node_args) - .ToLocal(&start_execution)) { - return; - } + MaybeLocal result = ExecuteBootstrapper( + env, "internal/bootstrap/node", &node_params, &node_args); - if (start_execution->IsFunction()) - env->set_start_execution_function(start_execution.As()); + env->set_has_run_bootstrapping_code(true); + + return scope.EscapeMaybe(result); } -void StartExecution(Environment* env, const char* main_script_id) { - HandleScope handle_scope(env->isolate()); - // We have to use Local<>::New because of the optimized way in which we access - // the object in the env->...() getters, which does not play well with - // resetting the handle while we're accessing the object through the Local<>. - Local start_execution = - Local::New(env->isolate(), env->start_execution_function()); - env->set_start_execution_function(Local()); - - if (start_execution.IsEmpty()) return; - - Local main_script_v; - if (main_script_id == nullptr) { - // TODO(joyeecheung): make this mandatory - we may also create an overload - // for main_script that is a Local. - main_script_v = Undefined(env->isolate()); - } else { - main_script_v = OneByteString(env->isolate(), main_script_id); +void MarkBootstrapComplete(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); + env->performance_state()->Mark( + performance::NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE); +} + +MaybeLocal StartExecution(Environment* env, const char* main_script_id) { + EscapableHandleScope scope(env->isolate()); + CHECK_NE(main_script_id, nullptr); + + std::vector> parameters = { + env->process_string(), + env->require_string(), + env->internal_binding_string(), + FIXED_ONE_BYTE_STRING(env->isolate(), "markBootstrapComplete")}; + + std::vector> arguments = { + env->process_object(), + env->native_module_require(), + env->internal_binding_loader(), + env->NewFunctionTemplate(MarkBootstrapComplete) + ->GetFunction(env->context()) + .ToLocalChecked()}; + + MaybeLocal result = + ExecuteBootstrapper(env, main_script_id, ¶meters, &arguments); + return scope.EscapeMaybe(result); +} + +MaybeLocal StartMainThreadExecution(Environment* env) { + // To allow people to extend Node in different ways, this hook allows + // one to drop a file lib/_third_party_main.js into the build + // directory which will be executed instead of Node's normal loading. + if (per_process::native_module_loader.Exists("_third_party_main")) { + return StartExecution(env, "internal/main/run_third_party_main"); + } + + if (env->execution_mode() == Environment::ExecutionMode::kInspect || + env->execution_mode() == Environment::ExecutionMode::kDebug) { + return StartExecution(env, "internal/main/inspect"); + } + + if (per_process::cli_options->print_help) { + env->set_execution_mode(Environment::ExecutionMode::kPrintHelp); + return StartExecution(env, "internal/main/print_help"); + } + + if (per_process::cli_options->print_bash_completion) { + env->set_execution_mode(Environment::ExecutionMode::kPrintBashCompletion); + return StartExecution(env, "internal/main/print_bash_completion"); + } + + if (env->options()->prof_process) { + env->set_execution_mode(Environment::ExecutionMode::kPrintBashCompletion); + return StartExecution(env, "internal/main/prof_process"); + } + + // -e/--eval without -i/--interactive + if (env->options()->has_eval_string && !env->options()->force_repl) { + env->set_execution_mode(Environment::ExecutionMode::kEvalString); + return StartExecution(env, "internal/main/eval_string"); + } + + if (env->options()->syntax_check_only) { + env->set_execution_mode(Environment::ExecutionMode::kCheckSyntax); + return StartExecution(env, "internal/main/check_syntax"); + } + + if (env->execution_mode() == Environment::ExecutionMode::kRunMainModule) { + return StartExecution(env, "internal/main/run_main_module"); + } + + if (env->options()->force_repl || uv_guess_handle(STDIN_FILENO) == UV_TTY) { + env->set_execution_mode(Environment::ExecutionMode::kRepl); + return StartExecution(env, "internal/main/repl"); } - Local argv[] = {main_script_v}; - USE(start_execution->Call( - env->context(), Undefined(env->isolate()), arraysize(argv), argv)); + env->set_execution_mode(Environment::ExecutionMode::kEvalStdin); + return StartExecution(env, "internal/main/eval_stdin"); +} + +void LoadEnvironment(Environment* env) { + CHECK(env->is_main_thread()); + // TODO(joyeecheung): Not all of the execution modes in + // StartMainThreadExecution() make sense for embedders. Pick the + // useful ones out, and allow embedders to customize the entry + // point more directly without using _third_party_main.js + if (!RunBootstrapping(env).IsEmpty()) { + USE(StartMainThreadExecution(env)); + } } @@ -1180,7 +1241,7 @@ Environment* CreateEnvironment(IsolateData* isolate_data, std::vector exec_args(exec_argv, exec_argv + exec_argc); Environment* env = new Environment(isolate_data, context); env->Start(per_process::v8_is_profiling); - env->CreateProcessObject(args, exec_args); + env->ProcessCliArgs(args, exec_args); return env; } @@ -1220,7 +1281,7 @@ void FreePlatform(MultiIsolatePlatform* platform) { Local NewContext(Isolate* isolate, Local object_template) { - auto context = Context::New(isolate, nullptr, object_template); + Local context = Context::New(isolate, nullptr, object_template); if (context.IsEmpty()) return context; HandleScope handle_scope(isolate); @@ -1233,12 +1294,19 @@ Local NewContext(Isolate* isolate, std::vector> parameters = { FIXED_ONE_BYTE_STRING(isolate, "global")}; - std::vector> arguments = {context->Global()}; - MaybeLocal result = per_process::native_module_loader.CompileAndCall( - context, "internal/per_context", ¶meters, &arguments, nullptr); + Local arguments[] = {context->Global()}; + MaybeLocal maybe_fn = + per_process::native_module_loader.LookupAndCompile( + context, "internal/per_context", ¶meters, nullptr); + if (maybe_fn.IsEmpty()) { + return Local(); + } + Local fn = maybe_fn.ToLocalChecked(); + MaybeLocal result = + fn->Call(context, Undefined(isolate), arraysize(arguments), arguments); + // Execution failed during context creation. + // TODO(joyeecheung): deprecate this signature and return a MaybeLocal. if (result.IsEmpty()) { - // Execution failed during context creation. - // TODO(joyeecheung): deprecate this signature and return a MaybeLocal. return Local(); } } @@ -1255,7 +1323,7 @@ inline int Start(Isolate* isolate, IsolateData* isolate_data, Context::Scope context_scope(context); Environment env(isolate_data, context); env.Start(per_process::v8_is_profiling); - env.CreateProcessObject(args, exec_args); + env.ProcessCliArgs(args, exec_args); #if HAVE_INSPECTOR && NODE_USE_V8_PLATFORM CHECK(!env.inspector_agent()->IsListening()); diff --git a/src/node_internals.h b/src/node_internals.h index 0d4fe74ebf3d02..bf66c77e6f043c 100644 --- a/src/node_internals.h +++ b/src/node_internals.h @@ -268,8 +268,9 @@ bool SafeGetenv(const char* key, std::string* text); void DefineZlibConstants(v8::Local target); -void RunBootstrapping(Environment* env); -void StartExecution(Environment* env, const char* main_script_id); +v8::MaybeLocal RunBootstrapping(Environment* env); +v8::MaybeLocal StartExecution(Environment* env, + const char* main_script_id); } // namespace node diff --git a/src/node_native_module.cc b/src/node_native_module.cc index 27456dd54606e4..675495e34bff5a 100644 --- a/src/node_native_module.cc +++ b/src/node_native_module.cc @@ -175,26 +175,6 @@ void NativeModuleLoader::CompileFunction( } } -// TODO(joyeecheung): it should be possible to generate the argument names -// from some special comments for the bootstrapper case. -MaybeLocal NativeModuleLoader::CompileAndCall( - Local context, - const char* id, - std::vector>* parameters, - std::vector>* arguments, - Environment* optional_env) { - Isolate* isolate = context->GetIsolate(); - MaybeLocal compiled = - per_process::native_module_loader.LookupAndCompile( - context, id, parameters, nullptr); - if (compiled.IsEmpty()) { - return MaybeLocal(); - } - Local fn = compiled.ToLocalChecked().As(); - return fn->Call( - context, v8::Null(isolate), arguments->size(), arguments->data()); -} - MaybeLocal NativeModuleLoader::CompileAsModule(Environment* env, const char* id) { std::vector> parameters = {env->exports_string(), diff --git a/src/node_native_module.h b/src/node_native_module.h index 62c417a0b61474..be1fc92a7672f3 100644 --- a/src/node_native_module.h +++ b/src/node_native_module.h @@ -42,20 +42,17 @@ class NativeModuleLoader { // Returns config.gypi as a JSON string v8::Local GetConfigString(v8::Isolate* isolate) const; - // Run a script with JS source bundled inside the binary as if it's wrapped - // in a function called with a null receiver and arguments specified in C++. - // The returned value is empty if an exception is encountered. - // JS code run with this method can assume that their top-level - // declarations won't affect the global scope. - v8::MaybeLocal CompileAndCall( + bool Exists(const char* id); + + // For bootstrappers optional_env may be a nullptr. + // If an exception is encountered (e.g. source code contains + // syntax error), the returned value is empty. + v8::MaybeLocal LookupAndCompile( v8::Local context, const char* id, std::vector>* parameters, - std::vector>* arguments, Environment* optional_env); - bool Exists(const char* id); - private: static void GetCacheUsage(const v8::FunctionCallbackInfo& args); // Passing ids of builtin module source code into JS land as @@ -87,15 +84,6 @@ class NativeModuleLoader { static v8::MaybeLocal CompileAsModule(Environment* env, const char* id); - // For bootstrappers optional_env may be a nullptr. - // If an exception is encountered (e.g. source code contains - // syntax error), the returned value is empty. - v8::MaybeLocal LookupAndCompile( - v8::Local context, - const char* id, - std::vector>* parameters, - Environment* optional_env); - NativeModuleRecordMap source_; NativeModuleCacheMap code_cache_; UnionBytes config_; diff --git a/src/node_worker.cc b/src/node_worker.cc index e5ba438bc1501c..4b78d653929d4b 100644 --- a/src/node_worker.cc +++ b/src/node_worker.cc @@ -133,8 +133,8 @@ Worker::Worker(Environment* env, env_->set_thread_id(thread_id_); env_->Start(env->profiler_idle_notifier_started()); - env_->CreateProcessObject(std::vector{}, - std::vector{}); + env_->ProcessCliArgs(std::vector{}, + std::vector{}); // Done while on the parent thread AddWorkerInspector(env, env_.get(), thread_id_, url_); } @@ -192,10 +192,10 @@ void Worker::Run() { HandleScope handle_scope(isolate_); Environment::AsyncCallbackScope callback_scope(env_.get()); env_->async_hooks()->push_async_ids(1, 0); - RunBootstrapping(env_.get()); - // TODO(joyeecheung): create a main script for worker threads - // that starts listening on the message port. - StartExecution(env_.get(), nullptr); + if (!RunBootstrapping(env_.get()).IsEmpty()) { + USE(StartExecution(env_.get(), "internal/main/worker_thread")); + } + env_->async_hooks()->pop_async_id(1); Debug(this, "Loaded environment for worker %llu", thread_id_); diff --git a/test/code-cache/test-code-cache.js b/test/code-cache/test-code-cache.js index 54bd0b0e2a66be..6232f1ae61b324 100644 --- a/test/code-cache/test-code-cache.js +++ b/test/code-cache/test-code-cache.js @@ -9,7 +9,7 @@ const { isMainThread } = require('../common'); const assert = require('assert'); const { cachableBuiltins, - cannotUseCache + cannotBeRequired } = require('internal/bootstrap/cache'); const { @@ -60,7 +60,7 @@ if (process.config.variables.node_code_cache_path === undefined) { ); for (const key of loadedModules) { - if (cannotUseCache.includes(key)) { + if (cannotBeRequired.includes(key)) { assert(compiledWithoutCache.has(key), `"${key}" should've been compiled without code cache`); } else { diff --git a/test/message/assert_throws_stack.out b/test/message/assert_throws_stack.out index cf96ee42c98cb7..0457670d6a317c 100644 --- a/test/message/assert_throws_stack.out +++ b/test/message/assert_throws_stack.out @@ -17,4 +17,3 @@ AssertionError [ERR_ASSERTION]: Expected values to be strictly deep-equal: at * at * at * - at * diff --git a/test/message/core_line_numbers.out b/test/message/core_line_numbers.out index 59953132fa0542..0336e5b451651e 100644 --- a/test/message/core_line_numbers.out +++ b/test/message/core_line_numbers.out @@ -12,4 +12,4 @@ RangeError: Invalid input at tryModuleLoad (internal/modules/cjs/loader.js:*:*) at Function.Module._load (internal/modules/cjs/loader.js:*:*) at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) - at executeUserCode (internal/bootstrap/node.js:*:*) + at internal/main/run_main_module.js:*:* diff --git a/test/message/error_exit.out b/test/message/error_exit.out index 7e0112d586cecb..3364210099ca75 100644 --- a/test/message/error_exit.out +++ b/test/message/error_exit.out @@ -14,5 +14,4 @@ AssertionError [ERR_ASSERTION]: Expected values to be strictly equal: at tryModuleLoad (internal/modules/cjs/loader.js:*:*) at Function.Module._load (internal/modules/cjs/loader.js:*:*) at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) - at executeUserCode (internal/bootstrap/node.js:*:*) - at startMainThreadExecution (internal/bootstrap/node.js:*:*) + at internal/main/run_main_module.js:*:* diff --git a/test/message/eval_messages.out b/test/message/eval_messages.out index 3af7c9792121b9..0d2e68f3d79b04 100644 --- a/test/message/eval_messages.out +++ b/test/message/eval_messages.out @@ -9,8 +9,7 @@ SyntaxError: Strict mode code may not include a with statement at Object. ([eval]-wrapper:*:*) at Module._compile (internal/modules/cjs/loader.js:*:*) at evalScript (internal/process/execution.js:*:*) - at executeUserCode (internal/bootstrap/node.js:*:*) - at startMainThreadExecution (internal/bootstrap/node.js:*:*) + at internal/main/eval_string.js:*:* 42 42 [eval]:1 @@ -24,8 +23,7 @@ Error: hello at Object. ([eval]-wrapper:*:*) at Module._compile (internal/modules/cjs/loader.js:*:*) at evalScript (internal/process/execution.js:*:*) - at executeUserCode (internal/bootstrap/node.js:*:*) - at startMainThreadExecution (internal/bootstrap/node.js:*:*) + at internal/main/eval_string.js:*:* [eval]:1 throw new Error("hello") @@ -38,8 +36,7 @@ Error: hello at Object. ([eval]-wrapper:*:*) at Module._compile (internal/modules/cjs/loader.js:*:*) at evalScript (internal/process/execution.js:*:*) - at executeUserCode (internal/bootstrap/node.js:*:*) - at startMainThreadExecution (internal/bootstrap/node.js:*:*) + at internal/main/eval_string.js:*:* 100 [eval]:1 var x = 100; y = x; @@ -52,8 +49,7 @@ ReferenceError: y is not defined at Object. ([eval]-wrapper:*:*) at Module._compile (internal/modules/cjs/loader.js:*:*) at evalScript (internal/process/execution.js:*:*) - at executeUserCode (internal/bootstrap/node.js:*:*) - at startMainThreadExecution (internal/bootstrap/node.js:*:*) + at internal/main/eval_string.js:*:* [eval]:1 var ______________________________________________; throw 10 diff --git a/test/message/events_unhandled_error_common_trace.out b/test/message/events_unhandled_error_common_trace.out index 331d669272320c..0d64143c67f865 100644 --- a/test/message/events_unhandled_error_common_trace.out +++ b/test/message/events_unhandled_error_common_trace.out @@ -12,11 +12,10 @@ Error: foo:bar at tryModuleLoad (internal/modules/cjs/loader.js:*:*) at Function.Module._load (internal/modules/cjs/loader.js:*:*) at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) - at executeUserCode (internal/bootstrap/node.js:*:*) + at internal/main/run_main_module.js:*:* Emitted 'error' event at: at quux (*events_unhandled_error_common_trace.js:*:*) at Object. (*events_unhandled_error_common_trace.js:*:*) at Module._compile (internal/modules/cjs/loader.js:*:*) [... lines matching original stack trace ...] - at executeUserCode (internal/bootstrap/node.js:*:*) - at startMainThreadExecution (internal/bootstrap/node.js:*:*) + at internal/main/run_main_module.js:*:* diff --git a/test/message/events_unhandled_error_nexttick.out b/test/message/events_unhandled_error_nexttick.out index 8875eda532882f..4132ae9f3bc1be 100644 --- a/test/message/events_unhandled_error_nexttick.out +++ b/test/message/events_unhandled_error_nexttick.out @@ -10,12 +10,10 @@ Error at tryModuleLoad (internal/modules/cjs/loader.js:*:*) at Function.Module._load (internal/modules/cjs/loader.js:*:*) at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) - at executeUserCode (internal/bootstrap/node.js:*:*) - at startMainThreadExecution (internal/bootstrap/node.js:*:*) + at internal/main/run_main_module.js:*:* Emitted 'error' event at: at process.nextTick (*events_unhandled_error_nexttick.js:*:*) at processTicksAndRejections (internal/process/next_tick.js:*:*) at process.runNextTicks [as _tickCallback] (internal/process/next_tick.js:*:*) at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) - at executeUserCode (internal/bootstrap/node.js:*:*) - at startMainThreadExecution (internal/bootstrap/node.js:*:*) + at internal/main/run_main_module.js:*:* diff --git a/test/message/events_unhandled_error_sameline.out b/test/message/events_unhandled_error_sameline.out index ff024c826eb5da..f877b254aafe97 100644 --- a/test/message/events_unhandled_error_sameline.out +++ b/test/message/events_unhandled_error_sameline.out @@ -10,10 +10,9 @@ Error at tryModuleLoad (internal/modules/cjs/loader.js:*:*) at Function.Module._load (internal/modules/cjs/loader.js:*:*) at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) - at executeUserCode (internal/bootstrap/node.js:*:*) - at startMainThreadExecution (internal/bootstrap/node.js:*:*) + at internal/main/run_main_module.js:*:* Emitted 'error' event at: at Object. (*events_unhandled_error_sameline.js:*:*) at Module._compile (internal/modules/cjs/loader.js:*:*) [... lines matching original stack trace ...] - at startMainThreadExecution (internal/bootstrap/node.js:*:*) + at internal/main/run_main_module.js:*:* diff --git a/test/message/nexttick_throw.out b/test/message/nexttick_throw.out index 4bcdcaa62c8bc5..7aa38a0424bd99 100644 --- a/test/message/nexttick_throw.out +++ b/test/message/nexttick_throw.out @@ -7,5 +7,4 @@ ReferenceError: undefined_reference_error_maker is not defined at processTicksAndRejections (internal/process/next_tick.js:*:*) at process.runNextTicks [as _tickCallback] (internal/process/next_tick.js:*:*) at Function.Module.runMain (internal/modules/cjs/loader.js:*:*) - at executeUserCode (internal/bootstrap/node.js:*:*) - at startMainThreadExecution (internal/bootstrap/node.js:*:*) + at internal/main/run_main_module.js:*:* diff --git a/test/message/stdin_messages.out b/test/message/stdin_messages.out index 2bf935d7cbd16f..837e9017d7f947 100644 --- a/test/message/stdin_messages.out +++ b/test/message/stdin_messages.out @@ -2,6 +2,7 @@ [stdin]:1 with(this){__filename} ^^^^ + SyntaxError: Strict mode code may not include a with statement at new Script (vm.js:*) at createScript (vm.js:*) @@ -9,10 +10,10 @@ SyntaxError: Strict mode code may not include a with statement at Object. ([stdin]-wrapper:*:*) at Module._compile (internal/modules/cjs/loader.js:*:*) at evalScript (internal/process/execution.js:*:*) - at Socket.process.stdin.on (internal/bootstrap/node.js:*:*) + at readStdin (internal/main/eval_stdin.js:*:*) + at Socket.process.stdin.on (internal/process/execution.js:*:*) at Socket.emit (events.js:*:*) at endReadableNT (_stream_readable.js:*:*) - at processTicksAndRejections (internal/process/next_tick.js:*:*) 42 42 [stdin]:1 @@ -26,10 +27,10 @@ Error: hello at Object. ([stdin]-wrapper:*:*) at Module._compile (internal/modules/cjs/loader.js:*:*) at evalScript (internal/process/execution.js:*:*) - at Socket.process.stdin.on (internal/bootstrap/node.js:*:*) + at readStdin (internal/main/eval_stdin.js:*:*) + at Socket.process.stdin.on (internal/process/execution.js:*:*) at Socket.emit (events.js:*:*) at endReadableNT (_stream_readable.js:*:*) - at processTicksAndRejections (internal/process/next_tick.js:*:*) [stdin]:1 throw new Error("hello") ^ @@ -41,10 +42,10 @@ Error: hello at Object. ([stdin]-wrapper:*:*) at Module._compile (internal/modules/cjs/loader.js:*:*) at evalScript (internal/process/execution.js:*:*) - at Socket.process.stdin.on (internal/bootstrap/node.js:*:*) + at readStdin (internal/main/eval_stdin.js:*:*) + at Socket.process.stdin.on (internal/process/execution.js:*:*) at Socket.emit (events.js:*:*) at endReadableNT (_stream_readable.js:*:*) - at processTicksAndRejections (internal/process/next_tick.js:*:*) 100 [stdin]:1 var x = 100; y = x; @@ -57,10 +58,10 @@ ReferenceError: y is not defined at Object. ([stdin]-wrapper:*:*) at Module._compile (internal/modules/cjs/loader.js:*:*) at evalScript (internal/process/execution.js:*:*) - at Socket.process.stdin.on (internal/bootstrap/node.js:*:*) + at readStdin (internal/main/eval_stdin.js:*:*) + at Socket.process.stdin.on (internal/process/execution.js:*:*) at Socket.emit (events.js:*:*) at endReadableNT (_stream_readable.js:*:*) - at processTicksAndRejections (internal/process/next_tick.js:*:*) [stdin]:1 var ______________________________________________; throw 10 diff --git a/test/message/unhandled_promise_trace_warnings.out b/test/message/unhandled_promise_trace_warnings.out index 1f88a136a9aa13..60c08805f5cd54 100644 --- a/test/message/unhandled_promise_trace_warnings.out +++ b/test/message/unhandled_promise_trace_warnings.out @@ -13,8 +13,6 @@ at * at * at * - at * - at * (node:*) Error: This was rejected at * (*test*message*unhandled_promise_trace_warnings.js:*) at * @@ -24,7 +22,6 @@ at * at * at * - at * (node:*) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code. at * at * @@ -33,7 +30,6 @@ at * at * at * - at * (node:*) PromiseRejectionHandledWarning: Promise rejection was handled asynchronously (rejection id: 1) at handledRejection (internal/process/promises.js:*) at promiseRejectHandler (internal/process/promises.js:*) diff --git a/test/message/util_inspect_error.out b/test/message/util_inspect_error.out index 406d8112ce2599..31b65eb2e2bf3c 100644 --- a/test/message/util_inspect_error.out +++ b/test/message/util_inspect_error.out @@ -9,7 +9,6 @@ at * at * at * - at * nested: { err: Error: foo @@ -22,7 +21,6 @@ at * at * at * - at * } } { err: Error: foo bar @@ -34,7 +32,6 @@ at * at * at * - at *, nested: { err: Error: foo bar @@ -46,7 +43,6 @@ at * at * at * - at * } } { Error: foo @@ -59,5 +55,4 @@ bar at * at * at * - at * foo: 'bar' }