Skip to content

Commit dc4d654

Browse files
authored
[Wasm64] Enable emescipten exceptions and SjLj (#19262)
Whatever was preventing this from working previously must have been fixed by all the work we have done in the mean time on wasm64 support more generally.
1 parent b1fbec1 commit dc4d654

File tree

4 files changed

+15
-23
lines changed

4 files changed

+15
-23
lines changed

emcc.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2424,8 +2424,6 @@ def phase_linker_setup(options, state, newargs):
24242424
if settings.MEMORY64:
24252425
if settings.ASYNCIFY and settings.MEMORY64 == 1:
24262426
exit_with_error('MEMORY64=1 is not compatible with ASYNCIFY')
2427-
if not settings.DISABLE_EXCEPTION_CATCHING:
2428-
exit_with_error('MEMORY64 is not compatible with DISABLE_EXCEPTION_CATCHING=0')
24292427
# Any "pointers" passed to JS will now be i64's, in both modes.
24302428
settings.WASM_BIGINT = 1
24312429

emscripten.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,8 @@ def create_wasm64_wrappers(metadata):
886886
'emscripten_stack_set_limits': '_pp',
887887
'__set_stack_limits': '_pp',
888888
'__cxa_can_catch': '_ppp',
889+
'__cxa_increment_exception_refcount': '_p',
890+
'__cxa_decrement_exception_refcount': '_p',
889891
'_wasmfs_write_file': '_ppp',
890892
'__dl_seterr': '_pp',
891893
'_emscripten_run_in_main_runtime_thread_js': '___p_',

src/library_exceptions.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ var LibraryExceptions = {
213213
},
214214

215215
__cxa_current_primary_exception__deps: ['$exceptionCaught', '__cxa_increment_exception_refcount'],
216+
__cxa_current_primary_exception__sig: 'p',
216217
__cxa_current_primary_exception: function() {
217218
if (!exceptionCaught.length) {
218219
return 0;
@@ -223,6 +224,7 @@ var LibraryExceptions = {
223224
},
224225

225226
__cxa_rethrow_primary_exception__deps: ['$ExceptionInfo', '$exceptionCaught', '__cxa_rethrow'],
227+
__cxa_rethrow_primary_exception__sig: 'vp',
226228
__cxa_rethrow_primary_exception: function(ptr) {
227229
if (!ptr) return;
228230
var info = new ExceptionInfo(ptr);
@@ -242,7 +244,11 @@ var LibraryExceptions = {
242244
// We'll do that here, instead, to keep things simpler.
243245
__cxa_find_matching_catch__deps: ['$exceptionLast', '$ExceptionInfo', '__resumeException', '__cxa_can_catch', 'setTempRet0'],
244246
__cxa_find_matching_catch: function() {
245-
var thrown =
247+
// Here we use explicit calls to `from64`/`to64` rather then using the
248+
// `__sig` attribute to perform these automatically. This is because the
249+
// `__sig` wrapper uses arrow function notation, which is not compatible
250+
// with the use of `arguments` in this function.
251+
var thrown =
246252
#if EXCEPTION_STACK_TRACES
247253
exceptionLast && exceptionLast.excPtr;
248254
#else
@@ -251,15 +257,15 @@ var LibraryExceptions = {
251257
if (!thrown) {
252258
// just pass through the null ptr
253259
setTempRet0(0);
254-
return 0;
260+
return {{{ to64(0) }}};
255261
}
256262
var info = new ExceptionInfo(thrown);
257263
info.set_adjusted_ptr(thrown);
258264
var thrownType = info.get_type();
259265
if (!thrownType) {
260266
// just pass through the thrown ptr
261267
setTempRet0(0);
262-
return thrown;
268+
return {{{ to64('thrown') }}};
263269
}
264270

265271
// can_catch receives a **, add indirection
@@ -272,6 +278,8 @@ var LibraryExceptions = {
272278
// return the type of the catch block which should be called.
273279
for (var i = 0; i < arguments.length; i++) {
274280
var caughtType = arguments[i];
281+
{{{ from64('caughtType') }}};
282+
275283
if (caughtType === 0 || caughtType === thrownType) {
276284
// Catch all clause matched or exactly the same type is caught
277285
break;
@@ -282,11 +290,11 @@ var LibraryExceptions = {
282290
dbg(" __cxa_find_matching_catch found " + [ptrToString(info.get_adjusted_ptr()), caughtType]);
283291
#endif
284292
setTempRet0(caughtType);
285-
return thrown;
293+
return {{{ to64('thrown') }}};
286294
}
287295
}
288296
setTempRet0(thrownType);
289-
return thrown;
297+
return {{{ to64('thrown') }}};
290298
},
291299

292300
__resumeException__deps: ['$exceptionLast'],

test/test_core.py

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,6 @@ def metafunc(self, is_native):
109109
self.set_setting('SUPPORT_LONGJMP', 'wasm')
110110
f(self)
111111
else:
112-
if self.get_setting('MEMORY64'):
113-
self.skipTest('MEMORY64 does not yet support emscripten EH/SjLj')
114112
self.set_setting('DISABLE_EXCEPTION_CATCHING', 0)
115113
self.set_setting('SUPPORT_LONGJMP', 'emscripten')
116114
# DISABLE_EXCEPTION_CATCHING=0 exports __cxa_can_catch and
@@ -549,7 +547,6 @@ def test_i64_varargs(self):
549547
self.do_core_test('test_i64_varargs.c', args='waka fleefl asdfasdfasdfasdf'.split())
550548

551549
@no_wasm2js('wasm_bigint')
552-
@no_wasm64('MEMORY64 does not yet support exceptions')
553550
@requires_node
554551
def test_i64_invoke_bigint(self):
555552
self.set_setting('WASM_BIGINT')
@@ -1100,7 +1097,6 @@ def test_longjmp_standalone(self):
11001097
def test_longjmp(self):
11011098
self.do_core_test('test_longjmp.c')
11021099

1103-
@no_wasm64('MEMORY64 does not yet support SJLJ')
11041100
def test_longjmp_with_and_without_exceptions(self):
11051101
# Emscripten SjLj with and without Emscripten EH support
11061102
self.set_setting('SUPPORT_LONGJMP', 'emscripten')
@@ -1157,7 +1153,6 @@ def test_longjmp_stacked(self):
11571153
def test_longjmp_exc(self):
11581154
self.do_core_test('test_longjmp_exc.c', assert_returncode=NON_ZERO)
11591155

1160-
@no_wasm64('MEMORY64 does not yet support exception handling')
11611156
def test_longjmp_throw(self):
11621157
for disable_throw in [0, 1]:
11631158
print(disable_throw)
@@ -1237,7 +1232,6 @@ def test_exceptions(self):
12371232
self.maybe_closure()
12381233
self.do_run_from_file(test_file('core/test_exceptions.cpp'), test_file('core/test_exceptions_caught.out'))
12391234

1240-
@no_wasm64('MEMORY64 does not yet support exceptions')
12411235
def test_exceptions_with_and_without_longjmp(self):
12421236
self.set_setting('EXCEPTION_DEBUG')
12431237
self.maybe_closure()
@@ -1267,7 +1261,6 @@ def test_exceptions_off(self):
12671261

12681262
@no_wasmfs('https://github.com/emscripten-core/emscripten/issues/16816')
12691263
@no_asan('TODO: ASan support in minimal runtime')
1270-
@no_wasm64('MEMORY64 does not yet support exceptions')
12711264
def test_exceptions_minimal_runtime(self):
12721265
self.set_setting('EXIT_RUNTIME')
12731266
self.maybe_closure()
@@ -1373,7 +1366,6 @@ def test_exceptions_3(self):
13731366
print('2')
13741367
self.do_run('src.js', 'Caught exception: Hello\nDone.', args=['2'], no_build=True)
13751368

1376-
@no_wasm64('MEMORY64 does not yet support exceptions')
13771369
def test_exceptions_allowed(self):
13781370
self.set_setting('EXCEPTION_CATCHING_ALLOWED', ["_Z12somefunctionv"])
13791371
# otherwise it is inlined and not identified
@@ -1425,7 +1417,6 @@ def test_exceptions_allowed(self):
14251417
if not any(o in self.emcc_args for o in ('-O3', '-Oz', '-Os')):
14261418
self.assertLess(disabled_size, fake_size)
14271419

1428-
@no_wasm64('MEMORY64 does not yet support exceptions')
14291420
def test_exceptions_allowed_2(self):
14301421
self.set_setting('EXCEPTION_CATCHING_ALLOWED', ["main"])
14311422
# otherwise it is inlined and not identified
@@ -1437,7 +1428,6 @@ def test_exceptions_allowed_2(self):
14371428
self.emcc_args += ['-DMAIN_NO_SIGNATURE']
14381429
self.do_core_test('test_exceptions_allowed_2.cpp')
14391430

1440-
@no_wasm64('MEMORY64 does not yet support exceptions')
14411431
def test_exceptions_allowed_uncaught(self):
14421432
self.emcc_args += ['-std=c++11']
14431433
self.set_setting('EXCEPTION_CATCHING_ALLOWED', ["_Z4testv"])
@@ -1446,7 +1436,6 @@ def test_exceptions_allowed_uncaught(self):
14461436

14471437
self.do_core_test('test_exceptions_allowed_uncaught.cpp')
14481438

1449-
@no_wasm64('MEMORY64 does not yet support exceptions')
14501439
def test_exceptions_allowed_misuse(self):
14511440
self.set_setting('EXCEPTION_CATCHING_ALLOWED', ['foo'])
14521441

@@ -1608,7 +1597,6 @@ def test_exceptions_rethrow_missing(self):
16081597
create_file('main.cpp', 'int main() { throw; }')
16091598
self.do_runf('main.cpp', None, assert_returncode=NON_ZERO)
16101599

1611-
@no_wasm64('MEMORY64 does not yet support exceptions')
16121600
@with_both_eh_sjlj
16131601
def test_EXPORT_EXCEPTION_HANDLING_HELPERS(self):
16141602
self.set_setting('ASSERTIONS', 0)
@@ -2471,7 +2459,6 @@ def test_memorygrowth_3_force_fail_reallocBuffer(self):
24712459
})
24722460
@no_asan('requires more memory when growing')
24732461
@no_lsan('requires more memory when growing')
2474-
@no_wasm64('does not fail under wasm64')
24752462
def test_aborting_new(self, args):
24762463
# test that C++ new properly errors if we fail to malloc when growth is
24772464
# enabled, with or without growth
@@ -4636,7 +4623,6 @@ def test_dylink_i64_c(self):
46364623

46374624
@needs_dylink
46384625
@also_with_wasm_bigint
4639-
@no_wasm64('MEMORY64 does not yet support exceptions')
46404626
def test_dylink_i64_invoke(self):
46414627
self.set_setting('DISABLE_EXCEPTION_CATCHING', 0)
46424628
self.dylink_test(r'''\
@@ -9350,7 +9336,6 @@ def test_pthread_create_embind_stack_check(self):
93509336
self.do_run_in_out_file_test('core/pthread/create.cpp')
93519337

93529338
@node_pthreads
9353-
@no_wasm64('MEMORY64 does not yet support exceptions')
93549339
def test_pthread_exceptions(self):
93559340
self.set_setting('PTHREAD_POOL_SIZE', 2)
93569341
self.set_setting('EXIT_RUNTIME')
@@ -9469,7 +9454,6 @@ def test_pthread_dylink_entry_point(self, args):
94699454

94709455
@needs_dylink
94719456
@node_pthreads
9472-
@no_wasm64('MEMORY64 does not yet support exceptions')
94739457
def test_pthread_dylink_exceptions(self):
94749458
self.emcc_args += ['-Wno-experimental', '-pthread']
94759459
self.emcc_args.append('-fexceptions')

0 commit comments

Comments
 (0)