From d1196dda31e21cc06e4b8f3c1d4d38db310e610f Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Sun, 22 Mar 2026 02:44:07 +0000 Subject: [PATCH 1/8] Remove dep between __cxa_rethrow_primary_exception and __cxa_rethrow Currently `__cxa_rethrow_primary_exception` calls `__cxa_rethrow`, and `__cxa_rethrow` is unnecessarily complicated to split logic when it is called from `__cxa_rethrow_primary_exception` and when it is not. This just decouples the two and duplicates the necessary logic in `__cxa_rethrow_primary_exception`. This makes `__cxa_rethrow` simple and easy to follow. --- src/lib/libexceptions.js | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/src/lib/libexceptions.js b/src/lib/libexceptions.js index fd84b2e8114b6..c7ddf4d5a9c7a 100644 --- a/src/lib/libexceptions.js +++ b/src/lib/libexceptions.js @@ -121,23 +121,19 @@ var LibraryExceptions = { #endif ], __cxa_rethrow: () => { - var info = exceptionCaught.pop(); - if (!info) { + if (exceptionCaught.length == 0) { abort('no exception to throw'); } + var info = exceptionCaught.at(-1); var ptr = info.excPtr; - if (!info.get_rethrown()) { - // Only pop if the corresponding push was through rethrow_primary_exception - exceptionCaught.push(info); - info.set_rethrown(true); - info.set_caught(false); - uncaughtExceptionCount++; - } + info.set_rethrown(true); + info.set_caught(false); + uncaughtExceptionCount++; #if !DISABLE_EXCEPTION_CATCHING ___cxa_increment_exception_refcount(ptr); #endif #if EXCEPTION_DEBUG - dbg('__cxa_rethrow, popped ' + + dbg('__cxa_rethrow: ' + [ptrToString(ptr), exceptionLast, 'stack', exceptionCaught]); #endif {{{ storeException('exceptionLast', 'ptr') }}} @@ -206,13 +202,24 @@ var LibraryExceptions = { return info.get_type(); }, - __cxa_rethrow_primary_exception__deps: ['$ExceptionInfo', '$exceptionCaught', '__cxa_rethrow'], + __cxa_rethrow_primary_exception__deps: ['$ExceptionInfo', '$uncaughtExceptionCount', '$exceptionLast', +#if !DISABLE_EXCEPTION_CATCHING + '__cxa_increment_exception_refcount', +#endif + ], __cxa_rethrow_primary_exception: (ptr) => { if (!ptr) return; var info = new ExceptionInfo(ptr); - exceptionCaught.push(info); info.set_rethrown(true); - ___cxa_rethrow(); + info.set_caught(false); +#if !DISABLE_EXCEPTION_CATCHING + ___cxa_increment_exception_refcount(ptr); +#endif +#if EXCEPTION_DEBUG + dbg('__cxa_rethrow_primary_exception: ' + ptrToString(ptr)); +#endif + {{{ storeException('exceptionLast', 'ptr') }}} + {{{ makeThrow('exceptionLast') }}} }, // Finds a suitable catch clause for when an exception is thrown. From 5c75daf95bb79e7ffe7e35c98397f49af7d9b4e2 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Sun, 22 Mar 2026 05:32:31 +0000 Subject: [PATCH 2/8] Automatic rebaseline of codesize expectations. NFC This is an automatic change generated by tools/maint/rebaseline_tests.py. The following (8) test expectation files were updated by running the tests with `--rebaseline`: ``` codesize/test_codesize_cxx_except.json: 195391 => 195372 [-19 bytes / -0.01%] codesize/test_codesize_cxx_mangle.json: 261882 => 261863 [-19 bytes / -0.01%] codesize/test_codesize_hello_dylink_all.json: 821851 => 821662 [-189 bytes / -0.02%] codesize/test_codesize_minimal_pthreads.json: 26629 => 26630 [+1 bytes / +0.00%] codesize/test_codesize_minimal_pthreads_memgrowth.json: 27032 => 27033 [+1 bytes / +0.00%] codesize/test_minimal_runtime_code_size_hello_embind.json: 14909 => 14908 [-1 bytes / -0.01%] codesize/test_minimal_runtime_code_size_hello_embind_val.json: 11642 => 11641 [-1 bytes / -0.01%] codesize/test_minimal_runtime_code_size_hello_wasm_worker.json: 4055 => 4060 [+5 bytes / +0.12%] Average change: +0.01% (-0.02% - +0.12%) ``` --- test/codesize/test_codesize_cxx_except.json | 8 ++++---- test/codesize/test_codesize_cxx_mangle.json | 8 ++++---- test/codesize/test_codesize_hello_dylink_all.json | 4 ++-- test/codesize/test_codesize_minimal_pthreads.json | 8 ++++---- .../test_codesize_minimal_pthreads_memgrowth.json | 8 ++++---- .../test_minimal_runtime_code_size_hello_embind.json | 8 ++++---- .../test_minimal_runtime_code_size_hello_embind_val.json | 8 ++++---- .../test_minimal_runtime_code_size_hello_wasm_worker.json | 8 ++++---- 8 files changed, 30 insertions(+), 30 deletions(-) diff --git a/test/codesize/test_codesize_cxx_except.json b/test/codesize/test_codesize_cxx_except.json index 0ef6129a7520a..c9c5300be621c 100644 --- a/test/codesize/test_codesize_cxx_except.json +++ b/test/codesize/test_codesize_cxx_except.json @@ -1,10 +1,10 @@ { - "a.out.js": 22875, - "a.out.js.gz": 8956, + "a.out.js": 22856, + "a.out.js.gz": 8947, "a.out.nodebug.wasm": 172516, "a.out.nodebug.wasm.gz": 57438, - "total": 195391, - "total_gz": 66394, + "total": 195372, + "total_gz": 66385, "sent": [ "__cxa_begin_catch", "__cxa_end_catch", diff --git a/test/codesize/test_codesize_cxx_mangle.json b/test/codesize/test_codesize_cxx_mangle.json index 469c39c54514f..0593274c78ffa 100644 --- a/test/codesize/test_codesize_cxx_mangle.json +++ b/test/codesize/test_codesize_cxx_mangle.json @@ -1,10 +1,10 @@ { - "a.out.js": 22925, - "a.out.js.gz": 8978, + "a.out.js": 22906, + "a.out.js.gz": 8969, "a.out.nodebug.wasm": 238957, "a.out.nodebug.wasm.gz": 79847, - "total": 261882, - "total_gz": 88825, + "total": 261863, + "total_gz": 88816, "sent": [ "__cxa_begin_catch", "__cxa_end_catch", diff --git a/test/codesize/test_codesize_hello_dylink_all.json b/test/codesize/test_codesize_hello_dylink_all.json index ec660a1c0d877..92d21277de468 100644 --- a/test/codesize/test_codesize_hello_dylink_all.json +++ b/test/codesize/test_codesize_hello_dylink_all.json @@ -1,7 +1,7 @@ { "a.out.js": 244367, - "a.out.nodebug.wasm": 577484, - "total": 821851, + "a.out.nodebug.wasm": 577295, + "total": 821662, "sent": [ "IMG_Init", "IMG_Load", diff --git a/test/codesize/test_codesize_minimal_pthreads.json b/test/codesize/test_codesize_minimal_pthreads.json index da85c8790e0ef..dbd6785088354 100644 --- a/test/codesize/test_codesize_minimal_pthreads.json +++ b/test/codesize/test_codesize_minimal_pthreads.json @@ -1,10 +1,10 @@ { "a.out.js": 7364, "a.out.js.gz": 3607, - "a.out.nodebug.wasm": 19265, - "a.out.nodebug.wasm.gz": 8934, - "total": 26629, - "total_gz": 12541, + "a.out.nodebug.wasm": 19266, + "a.out.nodebug.wasm.gz": 8933, + "total": 26630, + "total_gz": 12540, "sent": [ "a (memory)", "b (emscripten_get_now)", diff --git a/test/codesize/test_codesize_minimal_pthreads_memgrowth.json b/test/codesize/test_codesize_minimal_pthreads_memgrowth.json index a96e1eea00ba9..2b501541d9134 100644 --- a/test/codesize/test_codesize_minimal_pthreads_memgrowth.json +++ b/test/codesize/test_codesize_minimal_pthreads_memgrowth.json @@ -1,10 +1,10 @@ { "a.out.js": 7766, "a.out.js.gz": 3812, - "a.out.nodebug.wasm": 19266, - "a.out.nodebug.wasm.gz": 8935, - "total": 27032, - "total_gz": 12747, + "a.out.nodebug.wasm": 19267, + "a.out.nodebug.wasm.gz": 8934, + "total": 27033, + "total_gz": 12746, "sent": [ "a (memory)", "b (emscripten_get_now)", diff --git a/test/codesize/test_minimal_runtime_code_size_hello_embind.json b/test/codesize/test_minimal_runtime_code_size_hello_embind.json index 6f8026cfbadb0..f6f0dc1feea65 100644 --- a/test/codesize/test_minimal_runtime_code_size_hello_embind.json +++ b/test/codesize/test_minimal_runtime_code_size_hello_embind.json @@ -3,8 +3,8 @@ "a.html.gz": 371, "a.js": 7262, "a.js.gz": 3324, - "a.wasm": 7099, - "a.wasm.gz": 3257, - "total": 14909, - "total_gz": 6952 + "a.wasm": 7098, + "a.wasm.gz": 3255, + "total": 14908, + "total_gz": 6950 } diff --git a/test/codesize/test_minimal_runtime_code_size_hello_embind_val.json b/test/codesize/test_minimal_runtime_code_size_hello_embind_val.json index 1140b98f22baa..6be1ede872705 100644 --- a/test/codesize/test_minimal_runtime_code_size_hello_embind_val.json +++ b/test/codesize/test_minimal_runtime_code_size_hello_embind_val.json @@ -3,8 +3,8 @@ "a.html.gz": 371, "a.js": 5353, "a.js.gz": 2524, - "a.wasm": 5741, - "a.wasm.gz": 2690, - "total": 11642, - "total_gz": 5585 + "a.wasm": 5740, + "a.wasm.gz": 2692, + "total": 11641, + "total_gz": 5587 } diff --git a/test/codesize/test_minimal_runtime_code_size_hello_wasm_worker.json b/test/codesize/test_minimal_runtime_code_size_hello_wasm_worker.json index 678af8ef670c3..c757c1c02aa01 100644 --- a/test/codesize/test_minimal_runtime_code_size_hello_wasm_worker.json +++ b/test/codesize/test_minimal_runtime_code_size_hello_wasm_worker.json @@ -3,8 +3,8 @@ "a.html.gz": 355, "a.js": 956, "a.js.gz": 605, - "a.wasm": 2584, - "a.wasm.gz": 1438, - "total": 4055, - "total_gz": 2398 + "a.wasm": 2589, + "a.wasm.gz": 1440, + "total": 4060, + "total_gz": 2400 } From 2456de7cdcaf9b0a90d87e912b03728165950ed1 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Sun, 22 Mar 2026 06:15:05 +0000 Subject: [PATCH 3/8] Automatic rebaseline of codesize expectations. NFC This is an automatic change generated by tools/maint/rebaseline_tests.py. The following (6) test expectation files were updated by running the tests with `--rebaseline`: ``` codesize/test_codesize_hello_dylink_all.json: 821662 => 821851 [+189 bytes / +0.02%] codesize/test_codesize_minimal_pthreads.json: 26630 => 26629 [-1 bytes / -0.00%] codesize/test_codesize_minimal_pthreads_memgrowth.json: 27033 => 27032 [-1 bytes / -0.00%] codesize/test_minimal_runtime_code_size_hello_embind.json: 14908 => 14909 [+1 bytes / +0.01%] codesize/test_minimal_runtime_code_size_hello_embind_val.json: 11641 => 11642 [+1 bytes / +0.01%] codesize/test_minimal_runtime_code_size_hello_wasm_worker.json: 4060 => 4055 [-5 bytes / -0.12%] Average change: -0.02% (-0.12% - +0.02%) ``` --- test/codesize/test_codesize_hello_dylink_all.json | 4 ++-- test/codesize/test_codesize_minimal_pthreads.json | 8 ++++---- .../test_codesize_minimal_pthreads_memgrowth.json | 8 ++++---- .../test_minimal_runtime_code_size_hello_embind.json | 8 ++++---- .../test_minimal_runtime_code_size_hello_embind_val.json | 8 ++++---- .../test_minimal_runtime_code_size_hello_wasm_worker.json | 8 ++++---- 6 files changed, 22 insertions(+), 22 deletions(-) diff --git a/test/codesize/test_codesize_hello_dylink_all.json b/test/codesize/test_codesize_hello_dylink_all.json index 92d21277de468..ec660a1c0d877 100644 --- a/test/codesize/test_codesize_hello_dylink_all.json +++ b/test/codesize/test_codesize_hello_dylink_all.json @@ -1,7 +1,7 @@ { "a.out.js": 244367, - "a.out.nodebug.wasm": 577295, - "total": 821662, + "a.out.nodebug.wasm": 577484, + "total": 821851, "sent": [ "IMG_Init", "IMG_Load", diff --git a/test/codesize/test_codesize_minimal_pthreads.json b/test/codesize/test_codesize_minimal_pthreads.json index dbd6785088354..da85c8790e0ef 100644 --- a/test/codesize/test_codesize_minimal_pthreads.json +++ b/test/codesize/test_codesize_minimal_pthreads.json @@ -1,10 +1,10 @@ { "a.out.js": 7364, "a.out.js.gz": 3607, - "a.out.nodebug.wasm": 19266, - "a.out.nodebug.wasm.gz": 8933, - "total": 26630, - "total_gz": 12540, + "a.out.nodebug.wasm": 19265, + "a.out.nodebug.wasm.gz": 8934, + "total": 26629, + "total_gz": 12541, "sent": [ "a (memory)", "b (emscripten_get_now)", diff --git a/test/codesize/test_codesize_minimal_pthreads_memgrowth.json b/test/codesize/test_codesize_minimal_pthreads_memgrowth.json index 2b501541d9134..a96e1eea00ba9 100644 --- a/test/codesize/test_codesize_minimal_pthreads_memgrowth.json +++ b/test/codesize/test_codesize_minimal_pthreads_memgrowth.json @@ -1,10 +1,10 @@ { "a.out.js": 7766, "a.out.js.gz": 3812, - "a.out.nodebug.wasm": 19267, - "a.out.nodebug.wasm.gz": 8934, - "total": 27033, - "total_gz": 12746, + "a.out.nodebug.wasm": 19266, + "a.out.nodebug.wasm.gz": 8935, + "total": 27032, + "total_gz": 12747, "sent": [ "a (memory)", "b (emscripten_get_now)", diff --git a/test/codesize/test_minimal_runtime_code_size_hello_embind.json b/test/codesize/test_minimal_runtime_code_size_hello_embind.json index f6f0dc1feea65..6f8026cfbadb0 100644 --- a/test/codesize/test_minimal_runtime_code_size_hello_embind.json +++ b/test/codesize/test_minimal_runtime_code_size_hello_embind.json @@ -3,8 +3,8 @@ "a.html.gz": 371, "a.js": 7262, "a.js.gz": 3324, - "a.wasm": 7098, - "a.wasm.gz": 3255, - "total": 14908, - "total_gz": 6950 + "a.wasm": 7099, + "a.wasm.gz": 3257, + "total": 14909, + "total_gz": 6952 } diff --git a/test/codesize/test_minimal_runtime_code_size_hello_embind_val.json b/test/codesize/test_minimal_runtime_code_size_hello_embind_val.json index 6be1ede872705..1140b98f22baa 100644 --- a/test/codesize/test_minimal_runtime_code_size_hello_embind_val.json +++ b/test/codesize/test_minimal_runtime_code_size_hello_embind_val.json @@ -3,8 +3,8 @@ "a.html.gz": 371, "a.js": 5353, "a.js.gz": 2524, - "a.wasm": 5740, - "a.wasm.gz": 2692, - "total": 11641, - "total_gz": 5587 + "a.wasm": 5741, + "a.wasm.gz": 2690, + "total": 11642, + "total_gz": 5585 } diff --git a/test/codesize/test_minimal_runtime_code_size_hello_wasm_worker.json b/test/codesize/test_minimal_runtime_code_size_hello_wasm_worker.json index c757c1c02aa01..678af8ef670c3 100644 --- a/test/codesize/test_minimal_runtime_code_size_hello_wasm_worker.json +++ b/test/codesize/test_minimal_runtime_code_size_hello_wasm_worker.json @@ -3,8 +3,8 @@ "a.html.gz": 355, "a.js": 956, "a.js.gz": 605, - "a.wasm": 2589, - "a.wasm.gz": 1440, - "total": 4060, - "total_gz": 2400 + "a.wasm": 2584, + "a.wasm.gz": 1438, + "total": 4055, + "total_gz": 2398 } From d8852eb95f5218ceecdbae7eda7d401a080516e4 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Mon, 23 Mar 2026 20:58:55 +0000 Subject: [PATCH 4/8] Move debugging up to the beginning of the function --- src/lib/libexceptions.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/libexceptions.js b/src/lib/libexceptions.js index c7ddf4d5a9c7a..061e8e2d7d27b 100644 --- a/src/lib/libexceptions.js +++ b/src/lib/libexceptions.js @@ -209,14 +209,14 @@ var LibraryExceptions = { ], __cxa_rethrow_primary_exception: (ptr) => { if (!ptr) return; +#if EXCEPTION_DEBUG + dbg('__cxa_rethrow_primary_exception: ' + ptrToString(ptr)); +#endif var info = new ExceptionInfo(ptr); info.set_rethrown(true); info.set_caught(false); #if !DISABLE_EXCEPTION_CATCHING ___cxa_increment_exception_refcount(ptr); -#endif -#if EXCEPTION_DEBUG - dbg('__cxa_rethrow_primary_exception: ' + ptrToString(ptr)); #endif {{{ storeException('exceptionLast', 'ptr') }}} {{{ makeThrow('exceptionLast') }}} From 511fe8d7a2b2bcebd98b0c0cf4dc1ae762360af4 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Tue, 24 Mar 2026 00:02:52 +0000 Subject: [PATCH 5/8] !exceptionCaught.length --- src/lib/libexceptions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/libexceptions.js b/src/lib/libexceptions.js index 061e8e2d7d27b..eb47b54fcbe4a 100644 --- a/src/lib/libexceptions.js +++ b/src/lib/libexceptions.js @@ -121,7 +121,7 @@ var LibraryExceptions = { #endif ], __cxa_rethrow: () => { - if (exceptionCaught.length == 0) { + if (!exceptionCaught.length) { abort('no exception to throw'); } var info = exceptionCaught.at(-1); From d3a8cb90a41afeb924c6e47fdcfbc7c985a387b2 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Tue, 24 Mar 2026 01:41:18 +0000 Subject: [PATCH 6/8] Remove use of storeException --- src/lib/libexceptions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/libexceptions.js b/src/lib/libexceptions.js index 7f717a60bb02c..e2753df497d8a 100644 --- a/src/lib/libexceptions.js +++ b/src/lib/libexceptions.js @@ -227,8 +227,8 @@ var LibraryExceptions = { info.set_caught(false); #if !DISABLE_EXCEPTION_CATCHING ___cxa_increment_exception_refcount(ptr); + exceptionLast = new CppException(ptr); #endif - {{{ storeException('exceptionLast', 'ptr') }}} {{{ makeThrow('exceptionLast') }}} }, From bd31cfd207cfc0e39fbb8b70cf7ffde5632836a4 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Tue, 24 Mar 2026 01:43:44 +0000 Subject: [PATCH 7/8] Automatic rebaseline of codesize expectations. NFC This is an automatic change generated by tools/maint/rebaseline_tests.py. The following (2) test expectation files were updated by running the tests with `--rebaseline`: ``` codesize/test_codesize_cxx_except.json: 195711 => 195689 [-22 bytes / -0.01%] codesize/test_codesize_cxx_mangle.json: 262202 => 262180 [-22 bytes / -0.01%] Average change: -0.01% (-0.01% - -0.01%) ``` --- test/codesize/test_codesize_cxx_except.json | 8 ++++---- test/codesize/test_codesize_cxx_mangle.json | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/test/codesize/test_codesize_cxx_except.json b/test/codesize/test_codesize_cxx_except.json index f5beaf9c15fb0..65d5840622ee1 100644 --- a/test/codesize/test_codesize_cxx_except.json +++ b/test/codesize/test_codesize_cxx_except.json @@ -1,10 +1,10 @@ { - "a.out.js": 23195, - "a.out.js.gz": 8968, + "a.out.js": 23173, + "a.out.js.gz": 8962, "a.out.nodebug.wasm": 172516, "a.out.nodebug.wasm.gz": 57438, - "total": 195711, - "total_gz": 66406, + "total": 195689, + "total_gz": 66400, "sent": [ "__cxa_begin_catch", "__cxa_end_catch", diff --git a/test/codesize/test_codesize_cxx_mangle.json b/test/codesize/test_codesize_cxx_mangle.json index 626d3a0d494a4..fa71038445551 100644 --- a/test/codesize/test_codesize_cxx_mangle.json +++ b/test/codesize/test_codesize_cxx_mangle.json @@ -1,10 +1,10 @@ { - "a.out.js": 23245, - "a.out.js.gz": 8990, + "a.out.js": 23223, + "a.out.js.gz": 8984, "a.out.nodebug.wasm": 238957, "a.out.nodebug.wasm.gz": 79847, - "total": 262202, - "total_gz": 88837, + "total": 262180, + "total_gz": 88831, "sent": [ "__cxa_begin_catch", "__cxa_end_catch", From c332b363edb6a06f1baad62aa6ab26d796044de7 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Tue, 24 Mar 2026 01:59:42 +0000 Subject: [PATCH 8/8] Fix exceptionLast dep --- src/lib/libexceptions.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lib/libexceptions.js b/src/lib/libexceptions.js index e2753df497d8a..c3a05a763e819 100644 --- a/src/lib/libexceptions.js +++ b/src/lib/libexceptions.js @@ -212,8 +212,9 @@ var LibraryExceptions = { return info.get_type(); }, - __cxa_rethrow_primary_exception__deps: ['$ExceptionInfo', '$uncaughtExceptionCount', '$exceptionLast', + __cxa_rethrow_primary_exception__deps: ['$ExceptionInfo', '$uncaughtExceptionCount', #if !DISABLE_EXCEPTION_CATCHING + '$exceptionLast', '__cxa_increment_exception_refcount', #endif ],