Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 27 additions & 1 deletion src/coreclr/hosts/corerun/wasm/libCorerun.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,39 @@ function libCoreRunFactory() {
ENV["DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"] = "true";

if (ENVIRONMENT_IS_NODE) {
// V8 formats every wasm frame as "<url>:wasm-function[<index>]:<offset>".
const isWasmOnStack = () => {
const savedStackTraceLimit = Error.stackTraceLimit;
try {
Error.stackTraceLimit = Infinity;
return /wasm-function\[/.test(new Error().stack || "");
} finally {
Error.stackTraceLimit = savedStackTraceLimit;
}
};

// An exit requested from inside wasm (for example Environment.Exit) must not unwind
// the ExitStatus exception through live CLR frames, so end the process immediately.
// Otherwise let Node.js exit on its own once the event loop drains: process.exit()
// joins V8's worker threads without disposing the isolate, which can deadlock when
// a background compile job is waiting for a main thread GC (nodejs/node#64274).
const original_proc_exit = _proc_exit;
_proc_exit = (code) => {
if (!keepRuntimeAlive()) {
if (!keepRuntimeAlive() && isWasmOnStack()) {
process.exit(code);
}
return original_proc_exit(code);
};

// SystemJS_ResolveMainPromise queues an exit that can run after the runtime already
// exited, now that the process outlives that exit until the event loop drains.
const original_exit = _exit;
_exit = (status, implicit) => {
if (runtimeExited) {
throw new ExitStatus(EXITSTATUS);
}
return original_exit(status, implicit);
};
}
},
},
Expand Down
Loading