This document builds off of the WebAssembly specification [WEBASSEMBLY] and the WebAssembly JavaScript embedding [WASMJS].
1. Streaming Module Compilation and Instantiation
partial namespace WebAssembly {Promise <Module >compileStreaming (Promise <Response >);
source Promise <WebAssemblyInstantiatedSource >instantiateStreaming (Promise <Response >,
source optional object ); };
importObject
compileStreaming(source)
method, when invoked, returns the result of compiling a potential WebAssembly response with source. instantiateStreaming(source, importObject)
method, when invoked, performs the following steps:
-
Let promiseOfModule be the result of compiling a potential WebAssembly response with source.
-
Return the result of instantiating the promise of a module promiseOfModule with imports importObject.
Response
source, perform the following steps:
Note: This algorithm accepts a Response
object, or a
promise for one, and compiles and instantiates the resulting bytes of the response. This compilation
can be performed in the background and in a streaming manner. If the Response
is not CORS-same-origin, does not represent an ok status, or does not match the `application/wasm`
MIME type, the returned promise will be rejected with a TypeError
; if
compilation or instantiation fails, the returned promise will be rejected with a CompileError
or other relevant error type, depending on the cause of failure.
-
Let returnValue be a new promise
-
Upon fulfillment of source with value unwrappedSource:
-
Let response be unwrappedSource’s response.
-
Let mimeType be the result of extracting a MIME type from response’s header list.
-
If mimeType is not
`application/wasm`
, reject returnValue with aTypeError
and abort these substeps.Note: extra parameters are not allowed, including the empty
`application/wasm;`
. -
If response is not CORS-same-origin, reject returnValue with a
TypeError
and abort these substeps. -
If response’s status is not an ok status, reject returnValue with a
TypeError
and abort these substeps. -
consume response’s body as an
ArrayBuffer
, and let bodyPromise be the result.Note: Although it is specified here that the response is consumed entirely before compilation proceeds, that is purely for ease of specification; implementations are likely to instead perform processing in a streaming fashion. The difference is unobservable, and thus the simpler model is specified.
-
Upon fulfillment of bodyPromise with value bodyArrayBuffer:
-
Let stableBytes be a copy of the bytes held by the buffer bodyArrayBuffer.
-
Asynchronously compile the WebAssembly module stableBytes using the networking task source and resolve returnValue with the result.
-
-
Upon rejection of bodyPromise with reason reason:
-
Reject returnValue with reason.
-
-
-
Upon rejection of source with reason reason:
-
Reject returnValue with reason.
-
-
Return returnValue.
2. Serialization
Web user agents must augment the Module
interface with the [Serializable]
extended attribute.
The serialization steps, given value, serialized, and forStorage, are:
-
If forStorage is true, throw a "DataCloneError"
DOMException
-
Set serialized.[[Bytes]] to the sub-serialization of value.[[Bytes]].
-
Set serialized.[[AgentCluster]] to the current Realm's corresponding agent cluster.
The deserialization steps, given serialized and value, are:
-
Let bytes be the sub-deserialization of serialized.[[Bytes]].
-
Set value.[[Bytes]] to bytes.
-
If targetRealm’s corresponding agent cluster is not serialized.[[AgentCluster]], then throw a "DataCloneError"
DOMException
. -
Compile a WebAssembly module from bytes and set value.[[Module]] to the result.
Engines should attempt to share/reuse internal compiled code when performing a structured serialization, although in corner cases like CPU upgrade or browser update, this might not be possible and full recompilation may be necessary.
Note: The semantics of a structured serialization is as-if the binary source, from which the Module
was compiled, is serialized, then deserialized, and recompiled into the target realm.
Given the above engine optimizations, structured serialization provides developers
explicit control over both compiled-code caching and cross-window/worker code
sharing.
3. Developer-Facing Display Conventions
This section is non-normative.
Browsers, JavaScript engines, and offline tools have common ways of referring to JavaScript artifacts and language constructs. For example, locations in JavaScript source code are printed in stack traces or error messages, and are represented naturally as decimal-format lines and columns in text files. Names of functions and variables are taken directly from the sources. Therefore (for example) even though the exact format of implementation-dependent stack trace strings does not always match, the locations are easily understandable and the same across browsers.
To achieve the same goal of a common representations for WebAssembly constructs, the following conventions are adopted.
A WebAssembly location is a reference to a particular instruction in the binary, and may be displayed by a browser or engine in similar contexts as JavaScript source locations. It has the following format:
${url}:wasm-function[${funcIndex}]:${pcOffset}
Where
-
${url}
is the URL associated with the module, if applicable (see notes). -
${funcIndex}
is the function index relative to the module. -
${pcOffset}
is the offset in the module binary of the first byte of the instruction, printed in hexadecimal with lower-case digits, with a leading0x
prefix.
Notes:
-
The URL field may be interpreted differently depending on the context. When the response-based instantiation API is used in a browser, the associated URL should be used; or when the
ArrayBuffer
-based instantiation API is used, the browser should represent the location of the API call. This kind of instantiation is analogous to executing JavaScript usingeval
; therefore if the browser has an existing method to represent the location of theeval
call it can use a similar one forWebAssembly.instantiate
. For example if the browser usesfoo.js line 10 > eval
oreval at bar (foo.js:10:3)
foreval
, it could usefoo.js line 10 > WebAssembly.instantiate
orWebAssembly.instantiate at bar (foo.js:10:3)
, respectively. Offline tools may use a filename instead. -
Using hexadecimal for module offsets matches common conventions in native tools such as
objdump
(where addresses are printed in hex) and makes them visually distinct from JavaScript line numbers. Other numbers are represented in decimal.
While the "name" property of an Exported Function instance is specified by the JS API, synthesized function names are also displayed in other contexts like call stacks in debuggers and string representations of stack traces. If a WebAssembly module contains a name section, these names should be used to synthesize a function name as follows:
-
If a function name subsection is present, the displayed name should be
${module_name}.${function_name}
or${function_name}
, depending on whether the module name is present. -
Otherwise, the output can be context-dependent:
-
If the function name is shown alongside its location in a stack trace, then just the module name (if present) or an empty string can be used (because the function index is already in the location).
-
Otherwise,
${module_name}.wasm-function[${funcIndex}]
orwasm-function[${funcIndex}]
should be used to convey the function index.
-
Note that this document does not specify the full format of strings such as stack frame representations; this allows engines to continue using their existing formats for JavaScript (which existing code may already be depending on) while still printing WebAssembly frames in a format consistent with JavaScript.