Skip to content

postMessage, WebAssembly.Memory, and undetachable ArrayBuffers #4601

Closed
@ajklein

Description

@ajklein

There's a difference in behavior between Firefox and Chrome for the following code:

postMessage('foo', '*', [new WebAssembly.Memory({initial: 4}).buffer]);

Firefox throws a TypeError, while Chrome happily "transfers" the buffer. Except it doesn't transfer, but rather is silently copied. This is because the ArrayBuffer objects returned from the buffer getter are not allowed to be detached, except when the WebAssembly.Memory is grown (there are more details here, of course, but I don't think they're relevant to HTML).

It seems that neither of these behaviors is specified, e.g., there's no check about "non-detachability" or "wasm memory association" in the postMessage transfer algorithm.

The infrastructure for handling it is already available: when WebAssembly [creates a WebAssembly.Memory](https://webassembly.github.io/spec/js-api/index.html#create-a-memory-buffer] object, it sets [[ArrayBufferDetachKey]] to "WebAssembly.Memory". And ECMAScript allows passing a key to DetachArrayBuffer.

So, having looked at all that, I think this may be a trivial fix: since HTML does not pass a key argument to DetachArrayBuffer, it defaults to undefined. And therefore step 4 of DetachArrayBuffer will throw a TypeError, since SameValue("WebAssembly.Memory", undefined) is false.

Therefore, I think the fix is to replace ! with ? preceding the call to DetachArrayBuffer in step 5.4.4 of the transfer algorithm (2.8.7), and DetachArrayBuffer itself will do the right thing.

All of this is assuming the Firefox behavior is what we want, of course.

@Ms2ger @littledan @domenic @dtig @binji

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions