From 6ec5cffef2f4b61ff7d8aac068fa8d17cd889aa3 Mon Sep 17 00:00:00 2001 From: Sam Clegg Date: Mon, 20 May 2024 11:45:24 -0700 Subject: [PATCH] [wasm64] Enable table64 lowering This change prepares for the LLVM change which actually enables the use of table64 in the output: https://github.com/llvm/llvm-project/pull/92042 --- tools/emscripten.py | 24 ++++++++++++++++++------ tools/link.py | 9 ++++++++- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/tools/emscripten.py b/tools/emscripten.py index b4f0a1b5a3887..696da9b7297a1 100644 --- a/tools/emscripten.py +++ b/tools/emscripten.py @@ -662,18 +662,18 @@ def create_tsd(metadata, embind_tsd): out += create_tsd_exported_runtime_methods(metadata) # Manually generate defintions for any Wasm function exports. out += 'interface WasmModule {\n' - for name, types in metadata.function_exports.items(): + for name, functype in metadata.function_exports.items(): mangled = asmjs_mangle(name) should_export = settings.EXPORT_KEEPALIVE and mangled in settings.EXPORTED_FUNCTIONS if not should_export: continue arguments = [] - for index, type in enumerate(types.params): + for index, type in enumerate(functype.params): arguments.append(f"_{index}: {type_to_ts_type(type)}") out += f' {mangled}({", ".join(arguments)}): ' - assert len(types.returns) <= 1, 'One return type only supported' - if types.returns: - out += f'{type_to_ts_type(types.returns[0])}' + assert len(functype.returns) <= 1, 'One return type only supported' + if functype.returns: + out += f'{type_to_ts_type(functype.returns[0])}' else: out += 'void' out += ';\n' @@ -791,6 +791,8 @@ def add_standard_wasm_imports(send_items_map): if settings.RELOCATABLE: send_items_map['__indirect_function_table'] = 'wasmTable' + if settings.MEMORY64: + send_items_map['__table_base32'] = '___table_base32' if settings.AUTODEBUG: extra_sent_items += [ @@ -1100,7 +1102,17 @@ def create_pointer_conversion_wrappers(metadata): sigs_seen = set() wrap_functions = [] - for symbol in metadata.function_exports: + for symbol, functype in metadata.function_exports.items(): + # dynCall_ functions are generated by binaryen. They all take a + # function pointer as their first argument. + # The second part of this check can be removed once the table64 + # llvm changs lands. + if symbol.startswith('dynCall_') and functype.params[0] == webassembly.Type.I64: + sig = symbol.split('_')[-1] + sig = ['p' if t == 'p' else '_' for t in sig] + sig.insert(1, 'p') + sig = ''.join(sig) + mapping[symbol] = sig sig = mapping.get(symbol) if sig: if settings.MEMORY64: diff --git a/tools/link.py b/tools/link.py index 7727e0acc68ad..09d1496910585 100644 --- a/tools/link.py +++ b/tools/link.py @@ -1336,6 +1336,9 @@ def phase_linker_setup(options, state, newargs): # Any "pointers" passed to JS will now be i64's, in both modes. settings.WASM_BIGINT = 1 + if settings.MEMORY64 and settings.RELOCATABLE: + settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE.append('__table_base32') + if settings.WASM_WORKERS: settings.DEFAULT_LIBRARY_FUNCS_TO_INCLUDE += ['$_wasmWorkerInitializeRuntime'] # set location of Wasm Worker bootstrap JS file @@ -1957,11 +1960,15 @@ def run_embind_gen(wasm_target, js_syms, extra_settings): outfile_js = in_temp('tsgen_a.out.js') # The Wasm outfile may be modified by emscripten.emscript, so use a temporary file. outfile_wasm = in_temp('tsgen_a.out.wasm') - emscripten.emscript(wasm_target, outfile_wasm, outfile_js, js_syms, False) + emscripten.emscript(wasm_target, outfile_wasm, outfile_js, js_syms, finalize=False) # Build the flags needed by Node.js to properly run the output file. node_args = [] if settings.MEMORY64: node_args += shared.node_memory64_flags() + # Currently we don't have any engines that support table64 so we need + # to lower it in order to run the output. + # In the normal flow this happens later in `phase_binaryen` + building.run_wasm_opt(outfile_wasm, outfile_wasm, ['--table64-lowering']) if settings.WASM_EXCEPTIONS: node_args += shared.node_exception_flags(config.NODE_JS) # Run the generated JS file with the proper flags to generate the TypeScript bindings.