entCounter; cachedCwd = originalCwd(); return cachedCwd; }; workerIo.sharedCwdCounter = cwdCounter; } if (manifestSrc) { require('internal/process/policy').setup(manifestSrc, manifestURL); } const isLoaderWorker = doEval === 'internal' && filename === require('internal/modules/esm/utils').loaderWorkerId; setupUserModules(isLoaderWorker); if (!hasStdin) process.stdin.push(null); debug(`[${threadId}] starts worker script ${filename} ` + `(eval = ${doEval}) at cwd = ${process.cwd()}`); port.postMessage({ type: UP_AND_RUNNING }); switch (doEval) { case 'internal': { // Create this WeakMap in js-land because V8 has no C++ API for WeakMap. internalBinding('module_wrap').callbackMap = new SafeWeakMap(); require(filename)(workerData, publicPort); break; } case 'classic': { const { evalScript } = require('internal/process/execution'); const name = '[worker eval]'; // This is necessary for CJS module compilation. // TODO: pass this with something really internal. ObjectDefineProperty(process, '_eval', { __proto__: null, configurable: true, enumerable: true, value: filename, }); ArrayPrototypeSplice(process.argv, 1, 0, name); evalScript(name, filename); break; } case 'module': { const { evalModule } = require('internal/process/execution'); PromisePrototypeThen(evalModule(filename), undefined, (e) => { workerOnGlobalUncaughtException(e, true); }); break; } default: { // script filename // runMain here might be monkey-patched by users in --require. // XXX: the monkey-patchability here should probably be deprecated. ArrayPrototypeSplice(process.argv, 1, 0, filename); const CJSLoader = require('internal/modules/cjs/loader'); CJSLoader.Module.runMain(filename); break; } } } else if (message.type === STDIO_PAYLOAD) { const { stream, chunks } = message; ArrayPrototypeForEach(chunks, ({ chunk, encoding }) => { process[stream].push(chunk, encoding); }); } else { assert( message.type === STDIO_WANTS_MORE_DATA, `Unknown worker message type ${message.type}`, ); const { stream } = message; process[stream][kStdioWantsMoreDataCallback](); } }); function workerOnGlobalUncaughtException(error, fromPromise) { debug(`[${threadId}] gets uncaught exception`); let handled = false; let handlerThrew = false; try { handled = onGlobalUncaughtException(error, fromPromise); } catch (e) { error = e; handlerThrew = true; } debug(`[${threadId}] uncaught exception handled = ${handled}`); if (handled) { return true; } if (!process._exiting) { try { process._exiting = true; process.exitCode = 1; if (!handlerThrew) { process.emit('exit', process.exitCode); } } catch { // Continue regardless of error. } } let serialized; try { const { serializeError } = require('internal/error_serdes'); serialized = serializeError(error); } catch { // Continue regardless of error. } debug(`[${threadId}] uncaught exception serialized = ${!!serialized}`); if (serialized) port.postMessage({ type: ERROR_MESSAGE, error: serialized, }); else port.postMessage({ type: COULD_NOT_SERIALIZE_ERROR }); const { clearAsyncIdStack } = require('internal/async_hooks'); clearAsyncIdStack(); process.exit(); } // Patch the global uncaught exception handler so it gets picked up by // node::errors::TriggerUncaughtException(). process._fatalException = workerOnGlobalUncaughtException; markBootstrapComplete(); // Necessary to reset RegExp statics before user code runs. RegExpPrototypeExec(/^/, ''); port.start();