Unsurprisingly, one of WebAssembly’s primary purposes is to run on the Web, for example embedded in Web browsers (though this is not its only purpose).
This means integrating with the Web ecosystem, leveraging Web APIs, supporting the Web’s security model, preserving the Web’s portability, and designing in room for evolutionary development. Many of these goals are clearly reflected in WebAssembly’s high-level goals. In particular, WebAssembly MVP will be no looser from a security point of view than if the module was JavaScript.
More concretely, the following is a list of points of contact between WebAssembly and the rest of the Web platform that have been considered:
A JavaScript API is provided which allows JavaScript to compile WebAssembly modules, perform limited reflection on compiled modules, store and retrieve compiled modules from offline storage, instantiate compiled modules with JavaScript imports, call the exported functions of instantiated modules, alias the exported memory of instantiated modules, etc.
The Web embedding includes additional methods useful in that context. In non-web embeddings, these APIs may not be present.
In Web embeddings, the following methods are added.
Note that it is expected that compileStreaming
and instantiateStreaming
be either both present or both absent.
WebAssembly.compileStreaming
Added for milestone 2, developers must feature detect.
Promise<WebAssembly.Module> compileStreaming(source)
This function accepts a Response
object, or a
promise for one, and compiles 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 fails, the returned promise will be rejected with a WebAssembly.CompileError
.
WebAssembly.Module
constructor.Ast.module
compilation result.WebAssembly.Module
instance, with its [[Module]] set to module.WebAssembly.CompileError
containing the compilation failure information
stored in reason.WebAssembly.instantiateStreaming
Added for milestone 2, developers must feature detect.
dictionary WebAssemblyInstantiatedSource {
required WebAssembly.Module module;
required WebAssembly.Instance instance;
};
Promise<InstantiatedSource> instantiateStreaming(source [, importObject])
This function 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
WebAssembly.CompileError
, WebAssembly.LinkError
, or WebAssembly.RuntimeError
depending on the
cause of failure.
WebAssembly.Module
constructor.Ast.module
compilation result.WebAssembly.Instance
constructor.WebAssembly.Instance
constructor.WebAssembly.Instance
constructor.WebAssembly.Module
instance, with its [[Module]] set to module.module
”, moduleObject).instance
”, instanceObject).WebAssembly.CompileError
, WebAssembly.LinkError
, or
WebAssembly.RuntimeError
as appropriate for the failure information stored in reason.The above two functions both reuse much of the same infrastructure for extracting bytes from an
appropriate Response
object, differing only in
what they do with those bytes in the end. As such we define the following shared spec-level
procedure:
Process a potential WebAssembly response accepts an input argument and three sets of steps processingSteps, successSteps, and failureSteps:
Given these values, to process a potential WebAssembly response:
Response
object, reject returnValue
with a TypeError
exception and abort these substeps.`application/wasm`
, reject returnValue with a TypeError
and
abort these substeps. (NOTE: extra parameters are not allowed, including the empty
`application/wasm;`
.)TypeError
and abort these substeps.TypeError
and abort these substeps.ArrayBuffer
, and let bodyPromise be the result. (NOTE: although it is specified here that
the response is consumed entirely before processingSteps proceeds, that is purely for ease of
specification; implementations are likely to instead perform processing in a streaming
fashion. The different is unobservable, and thus the simpler model is specified.)
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 Error.stack strings does not always match, the locations are easily understandable and the same across browsers.
To achive 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 an index in the function index space.${pcOffset}
is the offset in the module binary of the first byte
of the instruction, printed in hexadecimal with lower-case digits,
with a leading 0x
prefix.Notes:
eval
; therefore if the browser has an existing
method to represent the location of the eval
call it can use a similar
one for WebAssembly.instantiate
. For example if the browser uses
foo.js line 10 > eval
or eval at bar (foo.js:10:3)
for eval
, it could
use foo.js line 10 > WebAssembly.instantiate
or
WebAssembly.instantiate at bar (foo.js:10:3)
, respectively.
Offline tools may use a filename instead.While the name
property of exported WebAssembly functions
is specified by the JS API, synthesized function names are also
displayed in other contexts like devtool callstacks and Error.stack
.
If a WebAssembly module contains a “name” section,
these names should be used to synthesize a function name as follows:
${module_name}.${function_name}
or ${function_name}
, depending
on whether the module name is present.${module_name}.wasm-function[${funcIndex}]
or
wasm-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.
WebAssembly’s modules allow for natural integration with the ES6 module system.
A WebAssembly module can have imports and exports, which are identified using
UTF-8 byte sequences. The most natural Web representation of a mapping of export
names to exports is a JS object in which each export is a property with a name
encoded in UTF-16. A WebAssembly module fails validation on the Web if it has
imports or exports whose names do not transcode cleanly to UTF-16 according to
the following conversion algorithm, assuming that the WebAssembly name is in a
Uint8Array
called array
:
function convertToJSString(array)
{
var string = "";
for (var i = 0; i < array.length; ++i)
string += String.fromCharCode(array[i]);
return decodeURIComponent(escape(string));
}
This performs the UTF8 decoding (decodeURIComponent(escape(string))
) using
a common JS idiom.
Transcoding failure is detected by decodeURIComponent
, which may throw
URIError
. If it does, the WebAssembly module will not validate. This validation
rule is only mandatory for Web embedding.
WebAssembly’s security model should depend on the same-origin policy, with cross-origin resource sharing (CORS) and subresource integrity to enable distribution through content distribution networks and to implement dynamic linking.
Once SIMD is supported WebAssembly would:
Once GC is supported, WebAssembly code would be able to reference and access JavaScript, DOM, and general WebIDL-defined objects.