diff --git a/src/parseTools.js b/src/parseTools.js index 7630913696db8..8b1e44f8be5a6 100644 --- a/src/parseTools.js +++ b/src/parseTools.js @@ -1320,11 +1320,13 @@ function makeStructuralReturn(values, inAsm) { } function makeThrow(what) { - if (ASSERTIONS) { - return 'throw ' + what + (DISABLE_EXCEPTION_CATCHING == 1 ? ' + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch."' : '') + ';'; - } else { - return 'throw ' + what + ';'; + if (ASSERTIONS && DISABLE_EXCEPTION_CATCHING == 1) { + what += ' + " - Exception catching is disabled, this exception cannot be caught. Compile with -s DISABLE_EXCEPTION_CATCHING=0 or DISABLE_EXCEPTION_CATCHING=2 to catch."'; + if (MAIN_MODULE) { + what += ' + " (note: in dynamic linking, if a side module wants exceptions, the main module must be built with that support)"'; + } } + return 'throw ' + what + ';'; } function makeSignOp(value, type, op, force, ignore) { diff --git a/tests/test_other.py b/tests/test_other.py index 363c4b07e44d4..6add3400960ca 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -6497,11 +6497,11 @@ def test_ld_library_path(self): self.assertContained('Ok', out) def test_dlopen_rtld_global(self): - # TODO: wasm support. this test checks RTLD_GLOBAL where a module is loaded - # before the module providing a global it needs is. in asm.js we use JS - # to create a redirection function. In wasm we just have wasm, so we - # need to introspect the wasm module. Browsers may add that eventually, - # or we could ship a little library that does it. + # This test checks RTLD_GLOBAL where a module is loaded + # before the module providing a global it needs is. in asm.js we use JS + # to create a redirection function. In wasm we just have wasm, so we + # need to introspect the wasm module. Browsers may add that eventually, + # or we could ship a little library that does it. create_test_file('hello1.c', r''' #include @@ -6565,6 +6565,59 @@ def test_dlopen_rtld_global(self): self.assertContained('hello1_val by hello1:3', out) self.assertContained('hello1_val by hello2:3', out) + @no_fastcomp() + def test_main_module_without_exceptions_message(self): + # A side module that needs exceptions needs a main module with that + # support enabled; show a clear message in that case. + create_test_file('side.cpp', r''' + #include + #include + + extern "C" void test_throw() { + try { + throw 42; + } catch(int x) { + printf("catch %d.\n", x); + return; + } + puts("bad location"); + } + ''') + create_test_file('main.cpp', r''' + #include + #include + #include + #include + #include + + typedef void (*voidf)(); + + int main() { + void* h = dlopen ("libside.wasm", RTLD_NOW|RTLD_GLOBAL); + assert(h); + voidf f = (voidf)dlsym(h, "test_throw"); + assert(f); + f(); + return 0; + } + ''') + run_process([PYTHON, EMCC, '-o', 'libside.wasm', 'side.cpp', '-s', 'SIDE_MODULE=1', '-fexceptions']) + + def build_main(args): + print(args) + with env_modify({'EMCC_FORCE_STDLIBS': 'libc++abi'}): + run_process([PYTHON, EMCC, 'main.cpp', '-s', 'MAIN_MODULE=1', '-s', 'EXPORT_ALL', + '--embed-file', 'libside.wasm'] + args) + + build_main([]) + out = run_js('a.out.js', assert_returncode=None, stderr=STDOUT) + self.assertContained('Exception catching is disabled, this exception cannot be caught.', out) + self.assertContained('note: in dynamic linking, if a side module wants exceptions, the main module must be built with that support', out) + + build_main(['-fexceptions']) + out = run_js('a.out.js') + self.assertContained('catch 42', out) + def test_debug_asmLastOpts(self): create_test_file('src.c', r''' #include