在模块实例之间共享WebAssembly.Memory

luc4s

我想使用由以前的Module实例创建的WebAssembly.Memory对象实例化WebAssembly模块(所有这些都使用emscripten的粘合代码),是否可行?

阿迪·莱文

自己创建一个内存对象,然后在实例化一个或多个WASM模块期间将其注入会容易一些。我设法通过覆盖与Emscripten做到这一点instantiateWasm

首先创建一个将由WASM实例共享的内存:

var TOTAL_MEMORY = 16777216;
var WASM_PAGE_SIZE = 65536;
var wasmMemory = new WebAssembly.Memory({ 'initial': TOTAL_MEMORY / WASM_PAGE_SIZE, 'maximum': TOTAL_MEMORY / WASM_PAGE_SIZE });
var buffer = wasmMemory.buffer;

然后实现一个自定义实例化器,将该实例注入到导入对象中:

function wasmInstantiator(wasmBinary) {
  return (info, receiveInstance) => {
    var importObject = Object.assign({}, info);
    importObject['env']['memory'] = wasmMemory;
    WebAssembly.instantiateStreaming(fetch(wasmBinary, { credentials: 'same-origin' }), importObject)
    .then((output) => { receiveInstance(output['instance']); },
          (err) => { console.error('wasm streaming compile failed: ' + err);});
     return {};
  };
};

现在,您可以使用相同的内存实例化这两个模块。我建议在这里使用Modularize(请参阅documentationsettings.js,这意味着添加-s Modularize=1 -s EXPORT_NAME='MY_MODULE_NAME_1'emcc命令行。Emscripten将创建一个名为的函数MY_MODULE_NAME_1该函数接受一个Module对象,您可以在其中重写某些元素,例如实例化器和内存。

var createInstance1 = MY_MODULE_NAME_1( { instantiateWasm: wasmInstantiator('module1.wasm') , TOTAL_MEMORY, buffer } );
var createInstance2 = MY_MODULE_NAME_2( { instantiateWasm: wasmInstantiator('module2.wasm') , TOTAL_MEMORY, buffer } );

有了这些类似诺言的WASM实例,您现在可以与两个模块进行交互:

createInstance1.then( (instance1) => {
   createInstance2.then( (instance2) => {
       useWasm(instance1, instance2);
   });
});

但是-这里有一个严重的警告:如果两个模块都试图在同一内存中分配动态内存,则它们会覆盖彼此分配的缓冲区!到目前为止,我还没有找到如何解决这个问题的方法:-(。

请参阅此仓库中的工作示例

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章