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