emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.91k stars 3.32k forks source link

Provide `readyPromiseReject` to `instantiateWasm` #23038

Open FelixNumworks opened 4 days ago

FelixNumworks commented 4 days ago

When providing an instantiateWasm method to the Module, only a successCallback is passed to the method (see docs here)

The problem is that no failureCallback is provided. In the case of a sync instantiation of the WASM, I can return false if the instantiation fails. But in the case of an async instantiation, if the instantiation fails, the error isn't properly handled and the page freezes.

I'd like instantiateWasm to take 3 args instead of 2: imports, successCallback and failureCallback.

This means changing this line:

https://github.com/emscripten-core/emscripten/blob/06cebfca51f908d3bc6897113330e45a77010db2/src/preamble.js#L1067

to

return Module['instantiateWasm'](info, receiveInstance, readyPromiseReject);

Current workaround

For others having the same problem, I'm currently using a dirty hack through pre-js.js by doing:

// pre-js.js

if (Module['readyPromiseRejectWrapper']) {
  Module['readyPromiseRejectWrapper']['value'] = readyPromiseReject;
}

And when I instantiate my module:

const readyPromiseRejectWrapper = { value: (e) => {} };
// Pass the wrapper to Module
const module = Module(
  readyPromiseRejectWrapper,
  // You can use the wrapper in 'instantiateWasm' when instantiation fails
  instantiateWasm: (imports, successCallback) => {
    (async () => {
      try {
        // instantiate the wasm
        successCallback(instance, module);
      } catch (e) {
        readyPromiseRejectWrapper.value(e);
      }
    })();
    return {};
  }
);

Version of emscripten/emsdk: emcc 3.1.61