Skip to content

[js-api] Ambiguity in WebAssembly.instantiate(bytes) if WebAssembly.Module is a thenable #2034

@backes

Description

@backes

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:

  1. Asynchronously compile the bytes into a WebAssembly module, let promiseOfModule be the result.
  2. 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:

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions