Поделиться WebAssembly.Memory между экземплярами модуля - PullRequest
0 голосов
/ 30 апреля 2019

Я хочу создать экземпляр модуля WebAssembly, используя объект WebAssembly.Memory, созданный предыдущим экземпляром модуля (все это с помощью связующего кода emscripten), это возможно?

1 Ответ

0 голосов
/ 09 мая 2019

Немного проще создать объект памяти самостоятельно, а затем внедрить его при создании одного или нескольких модулей 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 (см. документацию и settings.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);
   });
});

Но - здесь есть серьезное предостережение: если оба модуля пытаются выделить динамическую память в одной и той же памяти, они переопределяют друг друга распределенные буферы! Пока я не нашел, как решить эту проблему: - (.

См. Рабочий пример в Это репо .

...