WebAssembly Web API: Exception Handling

Editor’s Draft,

More details about this document
This version:
https://webassembly.github.io/spec/web-api/
Latest published version:
https://www.w3.org/TR/wasm-web-api-2/
Implementation Report:
https://webassembly.org/features/
Feedback:
GitHub
Editor:
Ms2ger (Igalia)
Issue Tracking:
GitHub Issues

Abstract

This document describes the integration of WebAssembly with the broader web platform.

This is part of a collection of related documents: the Core WebAssembly Specification, the WebAssembly JS Interface, and the WebAssembly Web API.

Status of this document

This is a public copy of the editors’ draft. It is provided for discussion only and may change at any moment. Its publication here does not imply endorsement of its contents by W3C. Don’t cite this document other than as work in progress.

GitHub Issues are preferred for discussion of this specification. All issues and comments are archived.

This document was produced by the WebAssembly Working Group.

This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 03 November 2023 W3C Process Document.

1. Introduction

This document builds off of the WebAssembly specification [WEBASSEMBLY] and the WebAssembly JavaScript embedding [WASMJS]. It describes the integration of WebAssembly into the broader Web platform, for example with additional APIs that are implemented by Web user agents but are outside the scope of JavaScript [ECMASCRIPT] itself.

2. Streaming Module Compilation and Instantiation

[Exposed=(Window,Worker)]
partial namespace WebAssembly {
  Promise<Module> compileStreaming(Promise<Response> source);
  Promise<WebAssemblyInstantiatedSource> instantiateStreaming(
      Promise<Response> source, optional object importObject);
};
The compileStreaming(source) method, when invoked, returns the result of compiling a potential WebAssembly response with source.
The instantiateStreaming(source, importObject) method, when invoked, performs the following steps:
  1. Let promiseOfModule be the result of compiling a potential WebAssembly response with source.

  2. Return the result of instantiating the promise of a module promiseOfModule with imports importObject.

To compile a potential WebAssembly response with a promise of a 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.

  1. Let returnValue be a new promise

  2. Upon fulfillment of source with value unwrappedSource:

    1. Let response be unwrappedSource’s response.

    2. Let mimeType be the result of getting `Content-Type` from response’s header list.

    3. If mimeType is null, reject returnValue with a TypeError and abort these substeps.

    4. Remove all HTTP tab or space byte from the start and end of mimeType.

    5. If mimeType is not a byte-case-insensitive match for `application/wasm`, reject returnValue with a TypeError and abort these substeps.

      Note: extra parameters are not allowed, including the empty `application/wasm;`.

    6. If response is not CORS-same-origin, reject returnValue with a TypeError and abort these substeps.

    7. If response’s status is not an ok status, reject returnValue with a TypeError and abort these substeps.

    8. 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.

    9. Upon fulfillment of bodyPromise with value bodyArrayBuffer:

      1. Let stableBytes be a copy of the bytes held by the buffer bodyArrayBuffer.

      2. Asynchronously compile the WebAssembly module stableBytes using the networking task source and resolve returnValue with the result.

    10. Upon rejection of bodyPromise with reason reason:

      1. Reject returnValue with reason.

  3. Upon rejection of source with reason reason:

    1. Reject returnValue with reason.

  4. Return returnValue.

3. Serialization

Web user agents must augment the Module interface with the [Serializable] extended attribute.

The serialization steps, given value, serialized, and forStorage, are:

  1. If forStorage is true, throw a "DataCloneError" DOMException.

  2. Set serialized.[[Bytes]] to the sub-serialization of value.[[Bytes]].

  3. Set serialized.[[AgentCluster]] to the current Realm's corresponding agent cluster.

The deserialization steps, given serialized, value, and targetRealm are:

  1. Let bytes be the sub-deserialization of serialized.[[Bytes]].

  2. Set value.[[Bytes]] to bytes.

  3. If targetRealm’s corresponding agent cluster is not serialized.[[AgentCluster]], then throw a "DataCloneError" DOMException.

  4. 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.

4. 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 representation 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

Notes:

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:

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.

5. Media-type Registration

The media type application/wasm has been registered with the IANA media type database [IANA-MEDIA-TYPES], with the following registration template:

application/wasm

Type Name:
application
Subtype Name:
wasm
Required Parameters:
None
Optional Parameters:
None
Encoding Considerations:
binary
Security Considerations:

WebAssembly is a standard, a safe, portable, low-level code format. The security considerations associated with executing WebAssembly code are described in https://www.w3.org/TR/wasm-core/#security-considerations.

The WebAssembly format includes no integrity or privacy protection. If such protection is needed it must be provided externally, e.g., through the use of HTTPS.

Interoperability Considerations:
See WebAssembly Core Conformance
https://www.w3.org/TR/wasm-core/#conformance
Published specification:
https://www.w3.org/TR/wasm-core-1/ https://www.w3.org/TR/wasm-js-api-1/ https://www.w3.org/TR/wasm-web-api-1/
Application Usage:
The application/wasm media type is intended for use as the type used to describe WebAssembly files when sent over HTTP to be executed by browsers, which is a common scenario. Additionally, the type is used by several WebAssembly runtimes that take advantage of the safety and portability while targeting efficient execution and compact representation.
Fragment Identifier Considerations:
None
Restrictions on usage:
None
Provisional Registrations:
N/A
Additional information:
Deprecated alias names for this type:
None
Magic number(s):
0x00 0x61 0x73 0x6D
File extension(s):
.wasm
Macintosh file type code(s):
None
Object Identifier(s) or OID(s):
None
Intended usage:
Common
Other Information & Comments:
Common
Contact Person:
Contact Name:
Eric Prud’hommeaux
Contact Email Address:
eric@w3.org
Author/Change Controller:
W3C

6. Security and Privacy Considerations

This section is non-normative.

WebAssembly provides no access to the surrounding environment other than via the JavaScript API described in the JS API specification. Therefore, WebAssembly cannot collect or expose any information (personal, sensitive or otherwise) to Web sites or other parties beyond what can be collected, exposed or processed with JavaScript. WebAssembly memory has the same lifetime as the objects in the surrounding JavaScript environment and is not persisted or serialized (other than by copying it out to JavaScript and using existing serialization APIs). No access is provided to the underlying platform or hardware, or to other devices, or to the user agent’s native UI.

WebAssembly is an additional program execution mechanism, and can be executed wherever JavaScript can be executed. Therefore the threat model is essentially the same as for JavaScript code, and has similar considerations for delivery (e.g. WebAssembly code should be protected in transit from active and passive network attackers) and policy (e.g. some loading mechanisms or execution are restricted via mechanisms such as the same-origin policy or Content Security Policy).

7. Change History

This section is non-normative.

Since the original release 1.0 of the WebAssembly specification, a number of proposals for extensions have been integrated. The following sections provide an overview of what has changed.

7.1. Release 2.0

Media-type Registraton Completed

The registration for the application/wasm media type has been successfully completed.

Conformance

Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Conformant Algorithms

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.

Conformance requirements phrased as algorithms or specific steps can be implemented in any manner, so long as the end result is equivalent. In particular, the algorithms defined in this specification are intended to be easy to understand and are not intended to be performant. Implementers are encouraged to optimize.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[WASMJS]
WebAssembly JS Integration Specification. Draft. URL: https://webassembly.github.io/spec/js-api/
[WEBASSEMBLY]
WebAssembly Core Specification. Draft. URL: https://webassembly.github.io/spec/core/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

Informative References

[IANA-MEDIA-TYPES]
Media Types. URL: https://www.iana.org/assignments/media-types/

IDL Index

[Exposed=(Window,Worker)]
partial namespace WebAssembly {
  Promise<Module> compileStreaming(Promise<Response> source);
  Promise<WebAssemblyInstantiatedSource> instantiateStreaming(
      Promise<Response> source, optional object importObject);
};