Skip to content

Commit a6a0939

Browse files
committed
[EmscriptenEH] Always use custom JS class for C/C++ exceptions
This has a slight codesize cost but it means we no longer have to worry about the ambiguity in when we catch a Number.
1 parent de5d6f0 commit a6a0939

19 files changed

Lines changed: 77 additions & 102 deletions

src/lib/libcore.js

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -484,11 +484,7 @@ addToLibrary({
484484
// a proxy and declare the dependency here.
485485
_emscripten_throw_longjmp__deps: ['setThrew'],
486486
_emscripten_throw_longjmp: () => {
487-
#if EXCEPTION_STACK_TRACES
488487
throw new EmscriptenSjLj;
489-
#else
490-
throw Infinity;
491-
#endif
492488
},
493489
#elif !SUPPORT_LONGJMP
494490
#if !INCLUDE_FULL_LIBRARY

src/lib/libdylink.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,16 +93,9 @@ var LibraryDylink = {
9393
} catch(e) {
9494
stackRestore(sp);
9595
// Create a try-catch guard that rethrows the Emscripten EH exception.
96-
#if EXCEPTION_STACK_TRACES
9796
// Exceptions thrown from C++ and longjmps will be an instance of
9897
// EmscriptenEH.
9998
if (!(e instanceof EmscriptenEH)) throw e;
100-
#else
101-
// Exceptions thrown from C++ will be a pointer (number) and longjmp
102-
// will throw the number Infinity. Use the compact and fast "e !== e+0"
103-
// test to check if e was not a Number.
104-
if (e !== e+0) throw e;
105-
#endif
10699
_setThrew(1, 0);
107100
#if WASM_BIGINT
108101
// In theory this if statement could be done on

src/lib/libemval.js

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -401,27 +401,10 @@ ${functionBody}
401401
object = Emval.toValue(object);
402402
#if !WASM_EXCEPTIONS
403403
// If we are throwing Emcripten C++ exception, set exceptionLast, as we do
404-
// in __cxa_throw. When EXCEPTION_STACK_TRACES is set, a C++ exception will
405-
// be an instance of EmscriptenEH, and when EXCEPTION_STACK_TRACES is not
406-
// set, it will be a pointer (number).
407-
//
408-
// This is different from __cxa_throw() in libexception.js because
409-
// __cxa_throw() is called from the user C++ code when the 'throw' keyword
410-
// is used, and the value thrown is a C++ pointer. When
411-
// EXCEPTION_STACK_TRACES is true, we wrap it with CppException. But this
412-
// _emval_throw is called when we throw whatever is contained in 'object',
413-
// which can be anything including a CppException object, or a number, or
414-
// other JS object. So we don't use storeException() wrapper here and we
415-
// throw it as is.
416-
#if EXCEPTION_STACK_TRACES
404+
// in __cxa_throw. C++ exception will be an instance of CppEmscripten.
417405
if (object instanceof CppException) {
418406
exceptionLast = object;
419407
}
420-
#else
421-
if (object === object+0) { // Check if it is a number
422-
exceptionLast = object;
423-
}
424-
#endif
425408
#endif
426409
throw object;
427410
},

src/lib/libexceptions.js

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ var LibraryExceptions = {
8787
'__cxa_increment_exception_refcount',
8888
#endif
8989
#if EXCEPTION_STACK_TRACES
90-
// When EXCEPTION_STACK_TRACES is enabled, storeException contains a call to
91-
// 'new CppException', whose constructor calls getExceptionMessage. We can't
92-
// track the dependency there, so we track it here.
90+
// When EXCEPTION_STACK_TRACES is enabled the 'new CppException' constructor
91+
// calls getExceptionMessage. We can't track the dependency there, so we
92+
// track it here.
9393
'$getExceptionMessage',
9494
// These functions can be necessary to prevent memory leaks from the JS
9595
// side. Even though they are not used it here directly, we export them when
@@ -106,8 +106,8 @@ var LibraryExceptions = {
106106
info.init(type, destructor);
107107
#if !DISABLE_EXCEPTION_CATCHING
108108
___cxa_increment_exception_refcount(ptr);
109+
exceptionLast = new CppException(ptr);
109110
#endif
110-
{{{ storeException('exceptionLast', 'ptr') }}}
111111
uncaughtExceptionCount++;
112112
{{{ makeThrow('exceptionLast') }}}
113113
},
@@ -140,7 +140,9 @@ var LibraryExceptions = {
140140
dbg('__cxa_rethrow, popped ' +
141141
[ptrToString(ptr), exceptionLast, 'stack', exceptionCaught]);
142142
#endif
143-
{{{ storeException('exceptionLast', 'ptr') }}}
143+
#if !DISABLE_EXCEPTION_CATCHING
144+
exceptionLast = new CppException(ptr);
145+
#endif
144146
{{{ makeThrow('exceptionLast') }}}
145147
},
146148

@@ -226,12 +228,7 @@ var LibraryExceptions = {
226228
// We'll do that here, instead, to keep things simpler.
227229
$findMatchingCatch__deps: ['$exceptionLast', '$ExceptionInfo', '__cxa_can_catch', '$setTempRet0'],
228230
$findMatchingCatch: (args) => {
229-
var thrown =
230-
#if EXCEPTION_STACK_TRACES
231-
exceptionLast?.excPtr;
232-
#else
233-
exceptionLast;
234-
#endif
231+
var thrown = exceptionLast?.excPtr;
235232
if (!thrown) {
236233
// just pass through the null ptr
237234
setTempRet0(0);
@@ -277,9 +274,11 @@ var LibraryExceptions = {
277274
#if EXCEPTION_DEBUG
278275
dbg("__resumeException " + [ptrToString(ptr), exceptionLast]);
279276
#endif
277+
#if !DISABLE_EXCEPTION_CATCHING
280278
if (!exceptionLast) {
281-
{{{ storeException('exceptionLast', 'ptr') }}}
279+
exceptionLast = new CppException(ptr);
282280
}
281+
#endif
283282
{{{ makeThrow('exceptionLast') }}}
284283
},
285284

src/parseTools.mjs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -661,11 +661,6 @@ function makeThrow(excPtr) {
661661
return `throw ${excPtr};`;
662662
}
663663

664-
function storeException(varName, excPtr) {
665-
var exceptionToStore = EXCEPTION_STACK_TRACES ? `new CppException(${excPtr})` : `${excPtr}`;
666-
return `${varName} = ${exceptionToStore};`;
667-
}
668-
669664
function charCode(char) {
670665
return char.charCodeAt(0);
671666
}
@@ -1255,7 +1250,6 @@ addToCompileTimeContext({
12551250
runtimeKeepalivePop,
12561251
runtimeKeepalivePush,
12571252
splitI64,
1258-
storeException,
12591253
to64,
12601254
toIndexType,
12611255
nodePthreadDetection,

src/preamble.js

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -360,11 +360,7 @@ function makeAbortWrapper(original) {
360360
ABORT // rethrow exception if abort() was called in the original function call above
361361
|| abortWrapperDepth > 1 // rethrow exceptions not caught at the top level if exception catching is enabled; rethrow from exceptions from within callMain
362362
#if SUPPORT_LONGJMP == 'emscripten' // Rethrow longjmp if enabled
363-
#if EXCEPTION_STACK_TRACES
364-
|| e instanceof EmscriptenSjLj // EXCEPTION_STACK_TRACES=1 will throw an instance of EmscriptenSjLj
365-
#else
366-
|| e === Infinity // EXCEPTION_STACK_TRACES=0 will throw Infinity
367-
#endif // EXCEPTION_STACK_TRACES
363+
|| e instanceof EmscriptenSjLj
368364
#endif
369365
|| e === 'unwind'
370366
) {

src/runtime_exceptions.js

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,35 @@
44
* SPDX-License-Identifier: MIT
55
*/
66

7-
#if EXCEPTION_STACK_TRACES && !WASM_EXCEPTIONS
7+
#if !WASM_EXCEPTIONS
8+
89
// Base Emscripten EH error class
10+
#if EXCEPTION_STACK_TRACES
911
class EmscriptenEH extends Error {}
12+
#else
13+
class EmscriptenEH {}
14+
#endif
1015

1116
#if SUPPORT_LONGJMP == 'emscripten'
1217
class EmscriptenSjLj extends EmscriptenEH {}
1318
#endif
1419

20+
#if !DISABLE_EXCEPTION_CATCHING
1521
class CppException extends EmscriptenEH {
1622
constructor(excPtr) {
23+
#if EXCEPTION_STACK_TRACES
1724
super(excPtr);
25+
#else
26+
super();
27+
#endif
1828
this.excPtr = excPtr;
19-
#if !DISABLE_EXCEPTION_CATCHING
29+
#if !DISABLE_EXCEPTION_CATCHING && EXCEPTION_STACK_TRACES
2030
const excInfo = getExceptionMessage(excPtr);
2131
this.name = excInfo[0];
2232
this.message = excInfo[1];
2333
#endif
2434
}
2535
}
26-
#endif // EXCEPTION_STACK_TRACES && !WASM_EXCEPTIONS
36+
#endif
37+
38+
#endif // !WASM_EXCEPTIONS

test/codesize/test_codesize_cxx_ctors1.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
2-
"a.out.js": 19214,
3-
"a.out.js.gz": 7981,
2+
"a.out.js": 19199,
3+
"a.out.js.gz": 7975,
44
"a.out.nodebug.wasm": 132638,
55
"a.out.nodebug.wasm.gz": 49927,
6-
"total": 151852,
7-
"total_gz": 57908,
6+
"total": 151837,
7+
"total_gz": 57902,
88
"sent": [
99
"__cxa_throw",
1010
"_abort_js",

test/codesize/test_codesize_cxx_ctors2.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
2-
"a.out.js": 19191,
3-
"a.out.js.gz": 7966,
2+
"a.out.js": 19176,
3+
"a.out.js.gz": 7961,
44
"a.out.nodebug.wasm": 132064,
55
"a.out.nodebug.wasm.gz": 49586,
6-
"total": 151255,
7-
"total_gz": 57552,
6+
"total": 151240,
7+
"total_gz": 57547,
88
"sent": [
99
"__cxa_throw",
1010
"_abort_js",

test/codesize/test_codesize_cxx_except.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
{
2-
"a.out.js": 22875,
3-
"a.out.js.gz": 8956,
2+
"a.out.js": 23189,
3+
"a.out.js.gz": 8965,
44
"a.out.nodebug.wasm": 172516,
55
"a.out.nodebug.wasm.gz": 57438,
6-
"total": 195391,
7-
"total_gz": 66394,
6+
"total": 195705,
7+
"total_gz": 66403,
88
"sent": [
99
"__cxa_begin_catch",
1010
"__cxa_end_catch",

0 commit comments

Comments
 (0)