|
18 | 18 |
|
19 | 19 | const { internalBinding, NativeModule } = loaderExports; |
20 | 20 |
|
21 | | -const exceptionHandlerState = { captureFn: null }; |
22 | 21 | let getOptionValue; |
23 | 22 |
|
24 | 23 | function startup() { |
25 | 24 | setupTraceCategoryState(); |
26 | 25 |
|
27 | 26 | setupProcessObject(); |
28 | 27 |
|
29 | | - // Do this good and early, since it handles errors. |
30 | | - setupProcessFatal(); |
| 28 | + // TODO(joyeecheung): this does not have to done so early, any fatal errors |
| 29 | + // thrown before user code execution should simply crash the process |
| 30 | + // and we do not care about any clean up at that point. We don't care |
| 31 | + // about emitting any events if the process crash upon bootstrap either. |
| 32 | + { |
| 33 | + const { |
| 34 | + fatalException, |
| 35 | + setUncaughtExceptionCaptureCallback, |
| 36 | + hasUncaughtExceptionCaptureCallback |
| 37 | + } = NativeModule.require('internal/process/execution'); |
| 38 | + |
| 39 | + process._fatalException = fatalException; |
| 40 | + process.setUncaughtExceptionCaptureCallback = |
| 41 | + setUncaughtExceptionCaptureCallback; |
| 42 | + process.hasUncaughtExceptionCaptureCallback = |
| 43 | + hasUncaughtExceptionCaptureCallback; |
| 44 | + } |
31 | 45 |
|
32 | 46 | setupGlobalVariables(); |
33 | 47 |
|
@@ -83,20 +97,14 @@ function startup() { |
83 | 97 | process.reallyExit = rawMethods.reallyExit; |
84 | 98 | process._kill = rawMethods._kill; |
85 | 99 |
|
86 | | - const wrapped = perThreadSetup.wrapProcessMethods( |
87 | | - rawMethods, exceptionHandlerState |
88 | | - ); |
| 100 | + const wrapped = perThreadSetup.wrapProcessMethods(rawMethods); |
89 | 101 | process._rawDebug = wrapped._rawDebug; |
90 | 102 | process.hrtime = wrapped.hrtime; |
91 | 103 | process.hrtime.bigint = wrapped.hrtimeBigInt; |
92 | 104 | process.cpuUsage = wrapped.cpuUsage; |
93 | 105 | process.memoryUsage = wrapped.memoryUsage; |
94 | 106 | process.kill = wrapped.kill; |
95 | 107 | process.exit = wrapped.exit; |
96 | | - process.setUncaughtExceptionCaptureCallback = |
97 | | - wrapped.setUncaughtExceptionCaptureCallback; |
98 | | - process.hasUncaughtExceptionCaptureCallback = |
99 | | - wrapped.hasUncaughtExceptionCaptureCallback; |
100 | 108 | } |
101 | 109 |
|
102 | 110 | NativeModule.require('internal/process/warning').setup(); |
@@ -311,7 +319,7 @@ function startExecution() { |
311 | 319 | // This means we are in a Worker context, and any script execution |
312 | 320 | // will be directed by the worker module. |
313 | 321 | if (internalBinding('worker').getEnvMessagePort() !== undefined) { |
314 | | - NativeModule.require('internal/worker').setupChild(evalScript); |
| 322 | + NativeModule.require('internal/worker').setupChild(); |
315 | 323 | return; |
316 | 324 | } |
317 | 325 |
|
@@ -382,7 +390,9 @@ function executeUserCode() { |
382 | 390 | addBuiltinLibsToObject |
383 | 391 | } = NativeModule.require('internal/modules/cjs/helpers'); |
384 | 392 | addBuiltinLibsToObject(global); |
385 | | - evalScript('[eval]', wrapForBreakOnFirstLine(getOptionValue('--eval'))); |
| 393 | + const source = getOptionValue('--eval'); |
| 394 | + const { evalScript } = NativeModule.require('internal/process/execution'); |
| 395 | + evalScript('[eval]', source, process._breakFirstLine); |
386 | 396 | return; |
387 | 397 | } |
388 | 398 |
|
@@ -436,7 +446,8 @@ function executeUserCode() { |
436 | 446 |
|
437 | 447 | // User passed '-e' or '--eval' along with `-i` or `--interactive` |
438 | 448 | if (process._eval != null) { |
439 | | - evalScript('[eval]', wrapForBreakOnFirstLine(process._eval)); |
| 449 | + const { evalScript } = NativeModule.require('internal/process/execution'); |
| 450 | + evalScript('[eval]', process._eval, process._breakFirstLine); |
440 | 451 | } |
441 | 452 | return; |
442 | 453 | } |
@@ -458,7 +469,8 @@ function readAndExecuteStdin() { |
458 | 469 | checkScriptSyntax(code, '[stdin]'); |
459 | 470 | } else { |
460 | 471 | process._eval = code; |
461 | | - evalScript('[stdin]', wrapForBreakOnFirstLine(process._eval)); |
| 472 | + const { evalScript } = NativeModule.require('internal/process/execution'); |
| 473 | + evalScript('[stdin]', process._eval, process._breakFirstLine); |
462 | 474 | } |
463 | 475 | }); |
464 | 476 | } |
@@ -654,93 +666,6 @@ function setupDOMException() { |
654 | 666 |
|
655 | 667 | function noop() {} |
656 | 668 |
|
657 | | -function setupProcessFatal() { |
658 | | - const { |
659 | | - executionAsyncId, |
660 | | - clearDefaultTriggerAsyncId, |
661 | | - clearAsyncIdStack, |
662 | | - hasAsyncIdStack, |
663 | | - afterHooksExist, |
664 | | - emitAfter |
665 | | - } = NativeModule.require('internal/async_hooks'); |
666 | | - |
667 | | - process._fatalException = (er) => { |
668 | | - // It's possible that defaultTriggerAsyncId was set for a constructor |
669 | | - // call that threw and was never cleared. So clear it now. |
670 | | - clearDefaultTriggerAsyncId(); |
671 | | - |
672 | | - if (exceptionHandlerState.captureFn !== null) { |
673 | | - exceptionHandlerState.captureFn(er); |
674 | | - } else if (!process.emit('uncaughtException', er)) { |
675 | | - // If someone handled it, then great. otherwise, die in C++ land |
676 | | - // since that means that we'll exit the process, emit the 'exit' event. |
677 | | - try { |
678 | | - if (!process._exiting) { |
679 | | - process._exiting = true; |
680 | | - process.exitCode = 1; |
681 | | - process.emit('exit', 1); |
682 | | - } |
683 | | - } catch { |
684 | | - // Nothing to be done about it at this point. |
685 | | - } |
686 | | - try { |
687 | | - const { kExpandStackSymbol } = NativeModule.require('internal/util'); |
688 | | - if (typeof er[kExpandStackSymbol] === 'function') |
689 | | - er[kExpandStackSymbol](); |
690 | | - } catch { |
691 | | - // Nothing to be done about it at this point. |
692 | | - } |
693 | | - return false; |
694 | | - } |
695 | | - |
696 | | - // If we handled an error, then make sure any ticks get processed |
697 | | - // by ensuring that the next Immediate cycle isn't empty. |
698 | | - NativeModule.require('timers').setImmediate(noop); |
699 | | - |
700 | | - // Emit the after() hooks now that the exception has been handled. |
701 | | - if (afterHooksExist()) { |
702 | | - do { |
703 | | - emitAfter(executionAsyncId()); |
704 | | - } while (hasAsyncIdStack()); |
705 | | - // Or completely empty the id stack. |
706 | | - } else { |
707 | | - clearAsyncIdStack(); |
708 | | - } |
709 | | - |
710 | | - return true; |
711 | | - }; |
712 | | -} |
713 | | - |
714 | | -function wrapForBreakOnFirstLine(source) { |
715 | | - if (!process._breakFirstLine) |
716 | | - return source; |
717 | | - const fn = `function() {\n\n${source};\n\n}`; |
718 | | - return `process.binding('inspector').callAndPauseOnStart(${fn}, {})`; |
719 | | -} |
720 | | - |
721 | | -function evalScript(name, body) { |
722 | | - const CJSModule = NativeModule.require('internal/modules/cjs/loader'); |
723 | | - const path = NativeModule.require('path'); |
724 | | - const { tryGetCwd } = NativeModule.require('internal/util'); |
725 | | - const cwd = tryGetCwd(path); |
726 | | - |
727 | | - const module = new CJSModule(name); |
728 | | - module.filename = path.join(cwd, name); |
729 | | - module.paths = CJSModule._nodeModulePaths(cwd); |
730 | | - const script = `global.__filename = ${JSON.stringify(name)};\n` + |
731 | | - 'global.exports = exports;\n' + |
732 | | - 'global.module = module;\n' + |
733 | | - 'global.__dirname = __dirname;\n' + |
734 | | - 'global.require = require;\n' + |
735 | | - 'return require("vm").runInThisContext(' + |
736 | | - `${JSON.stringify(body)}, { filename: ` + |
737 | | - `${JSON.stringify(name)}, displayErrors: true });\n`; |
738 | | - const result = module._compile(script, `${name}-wrapper`); |
739 | | - if (getOptionValue('--print')) console.log(result); |
740 | | - // Handle any nextTicks added in the first tick of the program. |
741 | | - process._tickCallback(); |
742 | | -} |
743 | | - |
744 | 669 | function checkScriptSyntax(source, filename) { |
745 | 670 | const CJSModule = NativeModule.require('internal/modules/cjs/loader'); |
746 | 671 | const vm = NativeModule.require('vm'); |
|