I want to instantiate a WebAssembly module using the WebAssembly.Memory object created by a previous Module instance (all this using emscripten's glue code), is that feasible?
It's a bit easier to create a memory object yourself and then inject it during instantiation of one or more WASM modules. I managed to do this with Emscripten by overriding instantiateWasm.
Start by creating a memory that will be shared by the WASM instances:
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;
Then implement a custom instantiator that injects this memory into the import object:
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 {};
};
};
Now you can instantiate the two modules using the same memory. Here I recommend to use Modularize
(see documentation and settings.js, which means adding -s Modularize=1 -s EXPORT_NAME='MY_MODULE_NAME_1'
to emcc
command-line. Emscripten will create a function called MY_MODULE_NAME_1
that accepts a Module
object where you can override certain elements such as the instantiator and the memory.
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 } );
With these promise-like WASM instances, you can now interact with the two modules:
createInstance1.then( (instance1) => {
createInstance2.then( (instance2) => {
useWasm(instance1, instance2);
});
});
But - there is a serious caveat here: if both modules try to allocate dynamic memory in the same memory, they override each-other's allocated buffers! So far I haven't found how to resolve this issue :-(.
See working example in This repo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With