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.mail@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