11cb0ef41Sopenharmony_ci'use strict'; 21cb0ef41Sopenharmony_ci 31cb0ef41Sopenharmony_ciconst { 41cb0ef41Sopenharmony_ci Symbol, 51cb0ef41Sopenharmony_ci RegExpPrototypeExec, 61cb0ef41Sopenharmony_ci globalThis, 71cb0ef41Sopenharmony_ci} = primordials; 81cb0ef41Sopenharmony_ci 91cb0ef41Sopenharmony_ciconst path = require('path'); 101cb0ef41Sopenharmony_ci 111cb0ef41Sopenharmony_ciconst { 121cb0ef41Sopenharmony_ci codes: { 131cb0ef41Sopenharmony_ci ERR_INVALID_ARG_TYPE, 141cb0ef41Sopenharmony_ci ERR_UNCAUGHT_EXCEPTION_CAPTURE_ALREADY_SET, 151cb0ef41Sopenharmony_ci ERR_EVAL_ESM_CANNOT_PRINT, 161cb0ef41Sopenharmony_ci }, 171cb0ef41Sopenharmony_ci} = require('internal/errors'); 181cb0ef41Sopenharmony_ci 191cb0ef41Sopenharmony_ciconst { 201cb0ef41Sopenharmony_ci executionAsyncId, 211cb0ef41Sopenharmony_ci clearDefaultTriggerAsyncId, 221cb0ef41Sopenharmony_ci clearAsyncIdStack, 231cb0ef41Sopenharmony_ci hasAsyncIdStack, 241cb0ef41Sopenharmony_ci afterHooksExist, 251cb0ef41Sopenharmony_ci emitAfter, 261cb0ef41Sopenharmony_ci popAsyncContext, 271cb0ef41Sopenharmony_ci} = require('internal/async_hooks'); 281cb0ef41Sopenharmony_ciconst { 291cb0ef41Sopenharmony_ci makeContextifyScript, runScriptInThisContext, 301cb0ef41Sopenharmony_ci} = require('internal/vm'); 311cb0ef41Sopenharmony_ci// shouldAbortOnUncaughtToggle is a typed array for faster 321cb0ef41Sopenharmony_ci// communication with JS. 331cb0ef41Sopenharmony_ciconst { shouldAbortOnUncaughtToggle } = internalBinding('util'); 341cb0ef41Sopenharmony_ci 351cb0ef41Sopenharmony_cifunction tryGetCwd() { 361cb0ef41Sopenharmony_ci try { 371cb0ef41Sopenharmony_ci return process.cwd(); 381cb0ef41Sopenharmony_ci } catch { 391cb0ef41Sopenharmony_ci // getcwd(3) can fail if the current working directory has been deleted. 401cb0ef41Sopenharmony_ci // Fall back to the directory name of the (absolute) executable path. 411cb0ef41Sopenharmony_ci // It's not really correct but what are the alternatives? 421cb0ef41Sopenharmony_ci return path.dirname(process.execPath); 431cb0ef41Sopenharmony_ci } 441cb0ef41Sopenharmony_ci} 451cb0ef41Sopenharmony_ci 461cb0ef41Sopenharmony_cifunction evalModule(source, print) { 471cb0ef41Sopenharmony_ci if (print) { 481cb0ef41Sopenharmony_ci throw new ERR_EVAL_ESM_CANNOT_PRINT(); 491cb0ef41Sopenharmony_ci } 501cb0ef41Sopenharmony_ci const { loadESM } = require('internal/process/esm_loader'); 511cb0ef41Sopenharmony_ci const { handleMainPromise } = require('internal/modules/run_main'); 521cb0ef41Sopenharmony_ci RegExpPrototypeExec(/^/, ''); // Necessary to reset RegExp statics before user code runs. 531cb0ef41Sopenharmony_ci return handleMainPromise(loadESM((loader) => loader.eval(source))); 541cb0ef41Sopenharmony_ci} 551cb0ef41Sopenharmony_ci 561cb0ef41Sopenharmony_cifunction evalScript(name, body, breakFirstLine, print, shouldLoadESM = false) { 571cb0ef41Sopenharmony_ci const CJSModule = require('internal/modules/cjs/loader').Module; 581cb0ef41Sopenharmony_ci const { pathToFileURL } = require('internal/url'); 591cb0ef41Sopenharmony_ci 601cb0ef41Sopenharmony_ci const cwd = tryGetCwd(); 611cb0ef41Sopenharmony_ci const origModule = globalThis.module; // Set e.g. when called from the REPL. 621cb0ef41Sopenharmony_ci 631cb0ef41Sopenharmony_ci const module = new CJSModule(name); 641cb0ef41Sopenharmony_ci module.filename = path.join(cwd, name); 651cb0ef41Sopenharmony_ci module.paths = CJSModule._nodeModulePaths(cwd); 661cb0ef41Sopenharmony_ci 671cb0ef41Sopenharmony_ci const { handleMainPromise } = require('internal/modules/run_main'); 681cb0ef41Sopenharmony_ci const asyncESM = require('internal/process/esm_loader'); 691cb0ef41Sopenharmony_ci const baseUrl = pathToFileURL(module.filename).href; 701cb0ef41Sopenharmony_ci const { loadESM } = asyncESM; 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_ci const runScript = () => { 731cb0ef41Sopenharmony_ci // Create wrapper for cache entry 741cb0ef41Sopenharmony_ci const script = ` 751cb0ef41Sopenharmony_ci globalThis.module = module; 761cb0ef41Sopenharmony_ci globalThis.exports = exports; 771cb0ef41Sopenharmony_ci globalThis.__dirname = __dirname; 781cb0ef41Sopenharmony_ci globalThis.require = require; 791cb0ef41Sopenharmony_ci return (main) => main(); 801cb0ef41Sopenharmony_ci `; 811cb0ef41Sopenharmony_ci globalThis.__filename = name; 821cb0ef41Sopenharmony_ci RegExpPrototypeExec(/^/, ''); // Necessary to reset RegExp statics before user code runs. 831cb0ef41Sopenharmony_ci const result = module._compile(script, `${name}-wrapper`)(() => { 841cb0ef41Sopenharmony_ci const hostDefinedOptionId = Symbol(name); 851cb0ef41Sopenharmony_ci async function importModuleDynamically(specifier, _, importAttributes) { 861cb0ef41Sopenharmony_ci const loader = asyncESM.esmLoader; 871cb0ef41Sopenharmony_ci return loader.import(specifier, baseUrl, importAttributes); 881cb0ef41Sopenharmony_ci } 891cb0ef41Sopenharmony_ci const script = makeContextifyScript( 901cb0ef41Sopenharmony_ci body, // code 911cb0ef41Sopenharmony_ci name, // filename, 921cb0ef41Sopenharmony_ci 0, // lineOffset 931cb0ef41Sopenharmony_ci 0, // columnOffset, 941cb0ef41Sopenharmony_ci undefined, // cachedData 951cb0ef41Sopenharmony_ci false, // produceCachedData 961cb0ef41Sopenharmony_ci undefined, // parsingContext 971cb0ef41Sopenharmony_ci hostDefinedOptionId, // hostDefinedOptionId 981cb0ef41Sopenharmony_ci importModuleDynamically, // importModuleDynamically 991cb0ef41Sopenharmony_ci ); 1001cb0ef41Sopenharmony_ci return runScriptInThisContext(script, true, !!breakFirstLine); 1011cb0ef41Sopenharmony_ci }); 1021cb0ef41Sopenharmony_ci if (print) { 1031cb0ef41Sopenharmony_ci const { log } = require('internal/console/global'); 1041cb0ef41Sopenharmony_ci log(result); 1051cb0ef41Sopenharmony_ci } 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ci if (origModule !== undefined) 1081cb0ef41Sopenharmony_ci globalThis.module = origModule; 1091cb0ef41Sopenharmony_ci }; 1101cb0ef41Sopenharmony_ci 1111cb0ef41Sopenharmony_ci if (shouldLoadESM) { 1121cb0ef41Sopenharmony_ci return handleMainPromise(loadESM(runScript)); 1131cb0ef41Sopenharmony_ci } 1141cb0ef41Sopenharmony_ci return runScript(); 1151cb0ef41Sopenharmony_ci} 1161cb0ef41Sopenharmony_ci 1171cb0ef41Sopenharmony_ciconst exceptionHandlerState = { 1181cb0ef41Sopenharmony_ci captureFn: null, 1191cb0ef41Sopenharmony_ci reportFlag: false, 1201cb0ef41Sopenharmony_ci}; 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_cifunction setUncaughtExceptionCaptureCallback(fn) { 1231cb0ef41Sopenharmony_ci if (fn === null) { 1241cb0ef41Sopenharmony_ci exceptionHandlerState.captureFn = fn; 1251cb0ef41Sopenharmony_ci shouldAbortOnUncaughtToggle[0] = 1; 1261cb0ef41Sopenharmony_ci process.report.reportOnUncaughtException = exceptionHandlerState.reportFlag; 1271cb0ef41Sopenharmony_ci return; 1281cb0ef41Sopenharmony_ci } 1291cb0ef41Sopenharmony_ci if (typeof fn !== 'function') { 1301cb0ef41Sopenharmony_ci throw new ERR_INVALID_ARG_TYPE('fn', ['Function', 'null'], fn); 1311cb0ef41Sopenharmony_ci } 1321cb0ef41Sopenharmony_ci if (exceptionHandlerState.captureFn !== null) { 1331cb0ef41Sopenharmony_ci throw new ERR_UNCAUGHT_EXCEPTION_CAPTURE_ALREADY_SET(); 1341cb0ef41Sopenharmony_ci } 1351cb0ef41Sopenharmony_ci exceptionHandlerState.captureFn = fn; 1361cb0ef41Sopenharmony_ci shouldAbortOnUncaughtToggle[0] = 0; 1371cb0ef41Sopenharmony_ci exceptionHandlerState.reportFlag = 1381cb0ef41Sopenharmony_ci process.report.reportOnUncaughtException === true; 1391cb0ef41Sopenharmony_ci process.report.reportOnUncaughtException = false; 1401cb0ef41Sopenharmony_ci} 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_cifunction hasUncaughtExceptionCaptureCallback() { 1431cb0ef41Sopenharmony_ci return exceptionHandlerState.captureFn !== null; 1441cb0ef41Sopenharmony_ci} 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_cifunction noop() {} 1471cb0ef41Sopenharmony_ci 1481cb0ef41Sopenharmony_ci// XXX(joyeecheung): for some reason this cannot be defined at the top-level 1491cb0ef41Sopenharmony_ci// and exported to be written to process._fatalException, it has to be 1501cb0ef41Sopenharmony_ci// returned as an *anonymous function* wrapped inside a factory function, 1511cb0ef41Sopenharmony_ci// otherwise it breaks the test-timers.setInterval async hooks test - 1521cb0ef41Sopenharmony_ci// this may indicate that node::errors::TriggerUncaughtException() should 1531cb0ef41Sopenharmony_ci// fix up the callback scope before calling into process._fatalException, 1541cb0ef41Sopenharmony_ci// or this function should take extra care of the async hooks before it 1551cb0ef41Sopenharmony_ci// schedules a setImmediate. 1561cb0ef41Sopenharmony_cifunction createOnGlobalUncaughtException() { 1571cb0ef41Sopenharmony_ci // The C++ land node::errors::TriggerUncaughtException() will 1581cb0ef41Sopenharmony_ci // exit the process if it returns false, and continue execution if it 1591cb0ef41Sopenharmony_ci // returns true (which indicates that the exception is handled by the user). 1601cb0ef41Sopenharmony_ci return (er, fromPromise) => { 1611cb0ef41Sopenharmony_ci // It's possible that defaultTriggerAsyncId was set for a constructor 1621cb0ef41Sopenharmony_ci // call that threw and was never cleared. So clear it now. 1631cb0ef41Sopenharmony_ci clearDefaultTriggerAsyncId(); 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ci const type = fromPromise ? 'unhandledRejection' : 'uncaughtException'; 1661cb0ef41Sopenharmony_ci process.emit('uncaughtExceptionMonitor', er, type); 1671cb0ef41Sopenharmony_ci if (exceptionHandlerState.captureFn !== null) { 1681cb0ef41Sopenharmony_ci exceptionHandlerState.captureFn(er); 1691cb0ef41Sopenharmony_ci } else if (!process.emit('uncaughtException', er, type)) { 1701cb0ef41Sopenharmony_ci // If someone handled it, then great. Otherwise, die in C++ land 1711cb0ef41Sopenharmony_ci // since that means that we'll exit the process, emit the 'exit' event. 1721cb0ef41Sopenharmony_ci try { 1731cb0ef41Sopenharmony_ci if (!process._exiting) { 1741cb0ef41Sopenharmony_ci process._exiting = true; 1751cb0ef41Sopenharmony_ci process.exitCode = 1; 1761cb0ef41Sopenharmony_ci process.emit('exit', 1); 1771cb0ef41Sopenharmony_ci } 1781cb0ef41Sopenharmony_ci } catch { 1791cb0ef41Sopenharmony_ci // Nothing to be done about it at this point. 1801cb0ef41Sopenharmony_ci } 1811cb0ef41Sopenharmony_ci return false; 1821cb0ef41Sopenharmony_ci } 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_ci // If we handled an error, then make sure any ticks get processed 1851cb0ef41Sopenharmony_ci // by ensuring that the next Immediate cycle isn't empty. 1861cb0ef41Sopenharmony_ci require('timers').setImmediate(noop); 1871cb0ef41Sopenharmony_ci 1881cb0ef41Sopenharmony_ci // Emit the after() hooks now that the exception has been handled. 1891cb0ef41Sopenharmony_ci if (afterHooksExist()) { 1901cb0ef41Sopenharmony_ci do { 1911cb0ef41Sopenharmony_ci const asyncId = executionAsyncId(); 1921cb0ef41Sopenharmony_ci if (asyncId === 0) 1931cb0ef41Sopenharmony_ci popAsyncContext(0); 1941cb0ef41Sopenharmony_ci else 1951cb0ef41Sopenharmony_ci emitAfter(asyncId); 1961cb0ef41Sopenharmony_ci } while (hasAsyncIdStack()); 1971cb0ef41Sopenharmony_ci } 1981cb0ef41Sopenharmony_ci // And completely empty the id stack, including anything that may be 1991cb0ef41Sopenharmony_ci // cached on the native side. 2001cb0ef41Sopenharmony_ci clearAsyncIdStack(); 2011cb0ef41Sopenharmony_ci 2021cb0ef41Sopenharmony_ci return true; 2031cb0ef41Sopenharmony_ci }; 2041cb0ef41Sopenharmony_ci} 2051cb0ef41Sopenharmony_ci 2061cb0ef41Sopenharmony_cifunction readStdin(callback) { 2071cb0ef41Sopenharmony_ci process.stdin.setEncoding('utf8'); 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_ci let code = ''; 2101cb0ef41Sopenharmony_ci process.stdin.on('data', (d) => { 2111cb0ef41Sopenharmony_ci code += d; 2121cb0ef41Sopenharmony_ci }); 2131cb0ef41Sopenharmony_ci 2141cb0ef41Sopenharmony_ci process.stdin.on('end', () => { 2151cb0ef41Sopenharmony_ci callback(code); 2161cb0ef41Sopenharmony_ci }); 2171cb0ef41Sopenharmony_ci} 2181cb0ef41Sopenharmony_ci 2191cb0ef41Sopenharmony_cimodule.exports = { 2201cb0ef41Sopenharmony_ci readStdin, 2211cb0ef41Sopenharmony_ci tryGetCwd, 2221cb0ef41Sopenharmony_ci evalModule, 2231cb0ef41Sopenharmony_ci evalScript, 2241cb0ef41Sopenharmony_ci onGlobalUncaughtException: createOnGlobalUncaughtException(), 2251cb0ef41Sopenharmony_ci setUncaughtExceptionCaptureCallback, 2261cb0ef41Sopenharmony_ci hasUncaughtExceptionCaptureCallback, 2271cb0ef41Sopenharmony_ci}; 228