有没有办法访问WebAssembly模块中的函数指针?
例如,假定以下“模块”编译为WebAssembly:
extern void set_callback(void (*callback)(void *arg), void *arg);
static void callback(void *arg)
{
/* ... */
}
int main() {
set_callback(&callback, 0);
return 0;
}
JavaScript中do_callback
的实现是否可以调用回调,而不必依赖中间的C函数导出来执行实际的函数调用?
var instance = new WebAssembly.Instance(module, {
memory: /* ... */
env: {
set_callback: function set_callback(callbackptr, argptr) {
// We only got the pointer, is there any
},
},
});
通过中间函数导出,我的意思是我可以添加一个具有公共可见性的内部函数。
do_callback(void (*callback)(void *arg), void *arg)
{
callback();
}
然后JavaScript set_callback
函数可以通过委托do_callback
函数调用函数指针。
function set_callback(callbackptr, argptr) {
instance.exports.do_callback(callbackptr, argptr);
}
但是,最好不要通过显式的间接方式来完成,有可能吗,也许用函数表?
3条答案
按热度按时间g6ll5ycj1#
您可以从Javascript调用函数指针。
函数指针存储在表中。当函数指针传递到Javascript时,您将接收到该函数指针在表中的整数索引。将该索引传递到
Table.prototype.get()
,您就可以调用该函数。您可以在MDN页面的表格部分阅读更多信息:https://developer.mozilla.org/en-US/docs/WebAssembly/Using_the_JavaScript_API#Tables
**编辑:**下面是我用来测试这一点的最小示例。
第一个文件是使用
emcc fptr.c -Os -s WASM=1 -s SIDE_MODULE=1 -o fptr.wasm
编译的fptr.c
这里是
fptr.html
ha5z0ras2#
出于某种原因,表格方法对我不起作用,所以我反其道而行之:我用源语言(D)实现了一个函数表。
这样,我可以通过传递句柄到javascript来使它工作:
这里我没有直接调用_getFuncAddress,因为还有另一种方法可以发送我为D编写的函数,用于参数计数和类型检查。
这样,我就可以调用任何函数,只要有多少参数,而不依赖于wasm的实现。
6ie5vjzr3#
当时的问题是,Clang基本上没有实现call_indirect,并且在代码生成期间实际上没有用任何东西填充函数表。
已在LLVM的当前版本中得到解决。