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. Non-web embeddings are not required to support these additional methods.
🌀 Added for milestone 2, developers must feature detect.
In Web embeddings, the following overloads are added (in addition to the core JS API method of the same name).
Promise<WebAssembly.Module> compile(Response source)
Promise<WebAssembly.Module> compile(Promise<Response> source)
Developers can set the argument source with either a promise that resolves
with a
Response
object or a
Response
object (which is automatically cast to a
promise).
If when unwrapped that Promise is not a Response object, then the returned Promise is
rejected
with a TypeError.
Renderer-side
security checks about tainting for cross-origin content are tied to the types
of filtered responses defined in
Fetch.
This function starts an asynchronous task to compile a WebAssembly.Module
as described in the WebAssembly.Module constructor.
On success, the Promise is fulfilled
with the resulting WebAssembly.Module object. On failure, the Promise is
rejected with a
WebAssembly.CompileError.
The Promise<Response> is used as the source of the bytes to compile.
MIME type information is
extracted
from the Response, WebAssembly source data must have a MIME type of application/wasm,
extra parameters are not allowed (including empty application/wasm;).
MIME type mismatch or opaque response types
reject the Promise with a
WebAssembly.CompileError.
🌀 Added for milestone 2, developers must feature detect.
In Web embeddings, the following overloads are added (in addition to the core JS API method of the same name).
Promise<{module:WebAssembly.Module, instance:WebAssembly.Instance}>
instantiate(Response source [, importObject])
Promise<{module:WebAssembly.Module, instance:WebAssembly.Instance}>
instantiate(Promise<Response> source [, importObject])
Developers can set the argument source with either a promise that resolves
with a
Response
object or a
Response
object (which is automatically cast to a
promise).
If when unwrapped that Promise is not a Response object, then the returned Promise is
rejected
with a TypeError.
Renderer-side
security checks about tainting for cross-origin content are tied to the types
of filtered responses defined in
Fetch.
This function starts an asynchronous task that first compiles a WebAssembly.Module
based on bytes from source as described in
the WebAssembly.Module constructor
and then instantiate the resulting Module with importObject as described in the
WebAssembly.Instance constructor.
On success, the Promise is fulfilled
with a plain JavaScript object pair {module, instance} containing the resulting
WebAssembly.Module and WebAssembly.Instance. The 2 properties module and instance of the returned pair are configurable, enumerable and writable.
On failure, the Promise is
rejected with a
WebAssembly.CompileError, WebAssembly.LinkError, or WebAssembly.RuntimeError, depending on the cause of failure.
The Promise<Response> is used as the source of the bytes to compile.
MIME type information is
extracted
from the Response, WebAssembly source data must have a MIME type of application/wasm,
extra parameters are not allowed (including empty application/wasm;).
MIME type mismatch or opaque response types
reject the Promise with a
WebAssembly.CompileError.
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.
Source maps are a debug-information format used on the web, generated by toolchains that target JavaScript, either from other languages (e.g. TypeScript, Emscripten) or from JavaScript itself (e.g. Closure, minifiers). A browser that supports source maps can display the original source in its developer tools instead of the compiled JavaScript that the VM actually executes. It can support setting breakpoints specified as source lines, single-stepping through source lines, and showing source lines in stack traces; however it cannot support getting or setting variables from the original source code because the format is not "full" debug info: it only maps locations from the compiled code back to locations in the source files (where a generated-code location consists of a line and column number, and a source location consists of file, line, and column). Generated files use a specially-formatted comment to specify a URL for a source map that describes the file.
Source maps can be made to serve the same purpose for WebAssembly binary files, allowing parity with asm.js. By re-using an existing standard, browsers can take advantage of their existing source map support without having to make significant changes to their developer tools.
An alternative method is to specify location mapping information in some way other than source maps. For example, it could be encoded directly into the wasm binary the way function and local names are written in the "name" section. This is more convenient if the VM itself uses the information (for example to generate a stack trace). However existing developer tools implementations are designed around the source map model of passing a URL from the VM to the dev tools code, which fetches and interprets the information. Therefore it is expected that it will be much simpler to use "real" source maps than to design another format.
Source maps also have known limitations (e.g. source variables cannot be described). A complete debug info format will eventually be needed; however the intention of this specification is to allow for easy integration with existing developer tools implementations in browsers.
With few exceptions, most aspects of the source map spec may be applied directly to wasm. Because wasm is a binary format (and thus does not have lines and columns, or comments per se), some simple reinterpretation of concepts is needed.
Source maps specify how to map a (zero-based) line and column position in generated code to a file, line, and column location in the source. For wasm binary locations, the line number is always 0, and the column number is interpreted as a byte offset into the wasm binary content (this results in a more efficient encoding than using the line number instead). Source locations are interpreted as in the source map spec.
When the generated code is JavaScript, it includes a specially-formatted line
at the end, which is the URL of the associated source map. For wasm, a custom
section named "sourceMappingURL" contains the URL.
The URL is defined as in the the WHATWG
URL spec, and is
resolved according to the source map spec,
For wasm modules with an associated HTTP response (e.g. those using
the response-based compile or instantiation
APIs) the URL may also be specified
using the SourceMap: HTTP header as with JavaScript source maps.
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:
- Be statically typed analogous to SIMD.js-in-asm.js;
- Reuse specification of operation semantics (with TC39);
- Reuse backend implementation (same IR nodes).
Once GC is supported, WebAssembly code would be able to reference and access JavaScript, DOM, and general WebIDL-defined objects.