instantiate_wasm is a function that instantiates a TB's Wasm binary, importing the functions as specified by its arguments. Following the header definition in wasm32/tcg-target.c.inc, QEMU's memory is imported into the module as "env.buffer", and helper functions are imported as "helper.<id>". The instantiated Wasm module is imported to QEMU using Emscripten's "addFunction" feature[1] which returns a function pointer. This allows QEMU to call this module directly from C code via that pointer.
Note Since FireFox 138, WebAssembly.Module no longer accepts a SharedArrayBuffer as input [2] as reported by Nicolas Vandeginste in my downstream fork[3]. This commit ensures that WebAssembly.Module() is passed a Uint8Array created from the binary data on a SharedArrayBuffer. [1] https://emscripten.org/docs/porting/connecting_cpp_and_javascript/Interacting-with-code.html#calling-javascript-functions-as-function-pointers-from-c [2] https://bugzilla.mozilla.org/show_bug.cgi?id=1965217 [3] https://github.com/ktock/qemu-wasm/pull/25 Signed-off-by: Kohei Tokunaga <ktokunaga.m...@gmail.com> --- tcg/wasm32.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tcg/wasm32.c b/tcg/wasm32.c index b238ccf6d6..f2269c0a22 100644 --- a/tcg/wasm32.c +++ b/tcg/wasm32.c @@ -25,6 +25,7 @@ #include "disas/dis-asm.h" #include "tcg-has.h" #include <ffi.h> +#include <emscripten.h> #define ctpop_tr glue(ctpop, TCG_TARGET_REG_BITS) @@ -44,6 +45,29 @@ __thread uintptr_t tci_tb_ptr; +EM_JS(int, instantiate_wasm, (int wasm_begin, + int wasm_size, + int import_vec_begin, + int import_vec_size), +{ + const memory_v = new DataView(HEAP8.buffer); + const wasm = HEAP8.subarray(wasm_begin, wasm_begin + wasm_size); + var helper = {}; + for (var i = 0; i < import_vec_size / 4; i++) { + helper[i] = wasmTable.get( + memory_v.getInt32(import_vec_begin + i * 4, true)); + } + const mod = new WebAssembly.Module(new Uint8Array(wasm)); + const inst = new WebAssembly.Instance(mod, { + "env" : { + "buffer" : wasmMemory, + }, + "helper" : helper, + }); + + return addFunction(inst.exports.start, 'ii'); +}); + static void tci_write_reg64(tcg_target_ulong *regs, uint32_t high_index, uint32_t low_index, uint64_t value) { -- 2.43.0