-
Notifications
You must be signed in to change notification settings - Fork 503
Description
I believe the current JS-API spec underspecifies the behavior of WebAssembly.instantiate(bytes) when WebAssembly.Module has been modified to include a then method (making the module a "thenable").
Reproducer:
const bytes = new Uint8Array([0,97,115,109,1,0,0,0]); // Minimal Wasm bytes.
WebAssembly.Module.prototype.then = resolve => resolve(17);
WebAssembly.instantiate(bytes).then(v => print(`Resolved to ${v} / ${v.instance}`), e => print(`Rejected: ${e}`));
(to be run in a d8, jsc, or sm shell; on the Web replace print by console.log).
The issue:
According to the JS-API spec, instantiate(bytes) performs the following steps:
- Asynchronously compile the bytes into a WebAssembly module, let
promiseOfModulebe the result. - Instantiate that
promiseOfModule.
The second step creates a new promise which reacts to the first promise.
At the end of the first step (when compilation finishes), the internal promise is resolved with the module object. According to the ECMAScript spec for promise resolution, if the resolution value (the Module) has a then method, that method is invoked to determine the final resolution.
In the reproducer above, the user-provided then resolves the promise to 17. Consequently, the next step, instantiate-a-promise-of-a-module receives 17 instead of a WebAssembly.Module.
Currently, the spec does not define what should happen if the promise resolves to a value that is not a WebAssembly.Module.
Current Implementation Behavior:
- SpiderMonkey & JavaScriptCore: Seem to ignore the
thenproperty on the prototype, resolving with the Module object regardless. - V8: Historically ignored it. However, after refactoring
WebAssembly.instantiateto use chained promises for stricter spec compliance, we encountered this edge case. We currently reject with a TypeError, but we are unsure if this is the intended behavior.
Proposal: The spec should explicitly handle this case. I propose we add a check to instantiate that rejects the promise with a TypeError if the promiseOfModule resolves to anything that is not a WebAssembly.Module.
Alternatively, if the intention is that WebAssembly.Module instances should never be treated as thenables during this process, the spec needs to clarify how the internal promise resolution bypasses the standard then check.