Skip to content

Commit 5f73782

Browse files
authored
Use RuntimeError in abort() before module instantiation (#18664)
We decided use a trap for `abort` function in case of Wasm EH in order to prevent infinite-looping (#16910). https://github.com/emscripten-core/emscripten/blob/44b2c2a1ecad39c534e14179acb49419dfee528b/src/preamble.js#L472-L474 The short reason is, in Wasm EH `RuntimeError` is treated as a foreign exception and caught by `catch_all`, so you try to abort the program and throw a `RuntimeError`, but it is caught by some `catch_all` used in the cleanup (=destructors, etc) code, causing the program to continue to run. `__trap` is defined in compiler-rt and exported when Wasm EH is enabled. This has worked so far, but in case we fail to instantiate a Wasm module and call `abort` because of it, we don't have access to the imported `Module['asm']['__trap']`, because `Module['asm']` has not been set: https://github.com/emscripten-core/emscripten/blob/44b2c2a1ecad39c534e14179acb49419dfee528b/src/preamble.js#L848 So the `abort` call will end like this: ```console TypeError: Cannot read properties of undefined (reading '__trap') at ___trap (/usr/local/google/home/aheejin/test/gl84/exported_api.js:5152:34) at abort (/usr/local/google/home/aheejin/test/gl84/exported_api.js:892:5) at /usr/local/google/home/aheejin/test/gl84/exported_api.js:1172:5 ``` which may not be the worst thing in the world given that we are crashing anyway, but not the situation we intended. This PR lets us throw `RuntimeError` in case we don't have the wasm module instantiated and have access to `Module['asm']['__trap']`. This is OK even with Wasm EH because we haven't been running the module, there's no risk of infinite-looping we tried to prevent in #16910.
1 parent 87083ed commit 5f73782

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

src/preamble.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -471,8 +471,19 @@ function abort(what) {
471471
// TODO(https://github.com/google/closure-compiler/pull/3913): Remove if/when upstream closure gets fixed.
472472
#if WASM_EXCEPTIONS == 1
473473
// See above, in the meantime, we resort to wasm code for trapping.
474-
___trap();
475-
#else
474+
//
475+
// In case abort() is called before the module is initialized, Module['asm']
476+
// and its exported '__trap' function is not available, in which case we throw
477+
// a RuntimeError.
478+
//
479+
// We trap instead of throwing RuntimeError to prevent infinite-looping in
480+
// Wasm EH code (because RuntimeError is considered as a foreign exception and
481+
// caught by 'catch_all'), but in case throwing RuntimeError is fine because
482+
// the module has not even been instantiated, even less running.
483+
if (runtimeInitialized) {
484+
___trap();
485+
}
486+
#endif
476487
/** @suppress {checkTypes} */
477488
var e = new WebAssembly.RuntimeError(what);
478489

@@ -483,7 +494,6 @@ function abort(what) {
483494
// in code paths apart from instantiation where an exception is expected
484495
// to be thrown when abort is called.
485496
throw e;
486-
#endif
487497
}
488498

489499
#include "memoryprofiler.js"

0 commit comments

Comments
 (0)