From 6a6daf50087cd33339985164e4100baf85249b20 Mon Sep 17 00:00:00 2001 From: Zoltan Varga Date: Mon, 19 Nov 2018 01:24:22 -0500 Subject: [PATCH] Implement ftCall_ functions with non-legal signatures in emulated function pointer mode correctly by calling the ftCall_helper_ functions exported by the wasm mode. Part of the fix for: https://github.com/kripken/emscripten/issues/7399 --- emscripten.py | 18 ++++++++++++++++-- tests/test_core.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 2 deletions(-) diff --git a/emscripten.py b/emscripten.py index 9a71c63ec3318..20b50c8836674 100644 --- a/emscripten.py +++ b/emscripten.py @@ -345,6 +345,7 @@ def define_asmjs_import_names(imports): function_tables_impls = make_function_tables_impls(function_table_data) final_function_tables = '\n'.join(function_tables_impls) + '\n' + function_tables_defs + if shared.Settings.EMULATED_FUNCTION_POINTERS: final_function_tables = ( final_function_tables @@ -1332,8 +1333,21 @@ def setup_function_pointers(function_table_sigs): else: # otherwise, wasm emulated function pointers *without* emulated casts can just all # into the table - table_access = "Module['wasmTable']" - table_read = table_access + '.get(x)' + if not shared.Settings.WASM_BACKEND and 'j' in sig: + legal_sig = shared.JS.legalize_sig(sig) + args = ['a%d' % i for i in range(len(legal_sig) - 1)] + full_args = ['x'] + args + call = "Module['asm']['ftCall_helper_%s'](%s)" % (sig, ', '.join (full_args)); + asm_setup += ''' +function ftCall_%s(%s) { + return %s; +} +''' % (sig, ', '.join(full_args), call); + # and we are done with this signature, continue + continue + else: + table_access = "Module['wasmTable']" + table_read = table_access + '.get(x)' else: table_access = 'FUNCTION_TABLE_' + sig if shared.Settings.SIDE_MODULE: diff --git a/tests/test_core.py b/tests/test_core.py index cf65220957d2b..5d8772b76e2e9 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1209,6 +1209,35 @@ def test_exceptions_uncaught_2(self): ''' self.do_run(src, 'OK\n') + def test_exceptions_i64_emulated_function_pointers(self): + self.set_setting('EMULATED_FUNCTION_POINTERS', 1) + self.set_setting('DISABLE_EXCEPTION_CATCHING', 0) + # needs to flush stdio streams + self.set_setting('EXIT_RUNTIME', 1) + src = r''' + #include + #include + + int64_t long_func(int64_t l) { + return l + 1; + } + + int main() { + int64_t res; + + try { + res = long_func(0x121212123434); + if (res == 0x121212123435) + std::cout << "OK"; + } catch(std::exception) { + try { + throw; + } catch(std::exception) {} + } + } + ''' + self.do_run(src, 'OK\n') + def test_exceptions_typed(self): self.set_setting('DISABLE_EXCEPTION_CATCHING', 0) # needs to flush stdio streams