javascript - 获取 WebAssembly 导出函数的地址?

标签 javascript c clang webassembly

假设有这个 C 代码,

int add(int a, int b) { return a + b; }
int mul(int a, int b) { return a * b; }
void *add_ptr() { return add; }
void *mul_ptr() { return mul; }
int op(int a, int b, int (*op) (int a, int b)) { return op(a, b); }
void *op_ptr() { return op; }

并使用常规的 clang 8/9 编译它以构建一个 wasm 文件,
clang --target=wasm32 a.c -nostdlib -Wl,--no-entry -Wl,--export=add -Wl,--export=mul -Wl,--export=mul_ptr -Wl,--export=add_ptr -Wl,--export=op -Wl,--export=op_ptr -o a.wasm
并使用 html 页面运行它,例如,

<script>
WebAssembly.instantiateStreaming(fetch('a.wasm')).then(result => alert(`
add: ${result.instance.exports.add(2, 3)}
mul: ${result.instance.exports.mul(2, 3)}

op_add: ${result.instance.exports.op(2, 3, result.instance.exports.add_ptr())}
op_mul: ${result.instance.exports.op(2, 3, result.instance.exports.mul_ptr())}

add_ptr: ${result.instance.exports.add_ptr()}
mul_ptr: ${result.instance.exports.mul_ptr()}
op_ptr: ${result.instance.exports.op_ptr()}

add.name: ${result.instance.exports.add.name}
mul.name: ${result.instance.exports.mul.name}
add_ptr.name: ${result.instance.exports.add_ptr.name}
mul_ptr.name: ${result.instance.exports.mul_ptr.name}
op.name: ${result.instance.exports.op.name}
`));
</script>

这使,
add: 5
mul: 6

op_add: 5
op_mul: 6

add_ptr: 1
mul_ptr: 2
op_ptr: 3

add.name: 0
mul.name: 1
add_ptr.name: 2
mul_ptr.name: 3
op.name: 4

获取add的指针地址的可靠方法是什么?/mul在没有 {add|mul}_ptr 的 WebAssembly 实例中喜欢功能?不能是.nameop.name不同于 op_ptr结果。

这里的最终目的(我已将我的用例简化为这个片段)是拥有 addmul地址并将其传递给 op像获取函数指针的函数。

最佳答案

对于 WebAssembly 函数以及它们包含的可执行代码,它们位于与数据不同的命名空间中。因此,您无法获得指向函数的地址/指针并将其用作调用它的间接机制。

我认为您在代码中看到的是 WebAssembly 模块的 function section 中的函数索引。 .

add_ptr: 1
mul_ptr: 2
op_ptr: 3

可以通过底层 call_indirect 执行动态函数调用WebAssembly 操作。这允许您调用存储在 table section 中的函数。 .

但是,我不确定 clang 编译器是否支持利用此功能的方式来支持您正在寻找的行为。

关于javascript - 获取 WebAssembly 导出函数的地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59282861/

相关文章:

javascript - 尝试使用 VBA 在 web 浏览器控件上执行 javascript 命令

c - Contiki OS中是否有适合Atmega128平台的双线接口(interface)/I2C读写库?

javascript - NodeJs 中的级联 require,要求一个文件需要另一个文件 NodeJs

c - 如何在 c 中构建查询字符串?

c - a>b>c 当每个都有数值时进行评估

compilation - 使用 Clang 编译 RISC-V

objective-c - 这个: _Pragma ("clang assume_nonnull begin")是什么意思

clang - LLVM 和 Clang 安装 : apt-get vs. 手动安装

javascript - 获取方法的实例所有者

javascript - 对数组中的值进行采样,性能良好