From f3ebba329fea4a7d926b82eab63501e4c2871dc7 Mon Sep 17 00:00:00 2001 From: Heejin Ahn Date: Thu, 23 May 2024 17:06:30 -0700 Subject: [PATCH] Revive legacy JS API and restructure legacy spec directory (#303) This adds `core` and `js-api` directory in `document/legacy/exceptions`, moves all core spec files into `core/`, and restores the deleted legacy JS API files in `js-api/`. The core legacy spec only contains the EH instructions, which is easier to view, but it is hard to precisely carve out the modified part from the JS API file, so this adds the whole file for the legacy spec. --- .github/workflows/ci-spec.yml | 70 +- document/Makefile | 2 +- document/legacy/exceptions/{ => core}/LICENSE | 0 .../legacy/exceptions/{ => core}/Makefile | 0 .../legacy/exceptions/{ => core}/README.md | 0 .../{ => core}/appendix/index-instructions.py | 0 .../legacy/exceptions/{ => core}/binary.rst | 0 document/legacy/exceptions/{ => core}/conf.py | 0 .../legacy/exceptions/{ => core}/exec.rst | 0 .../legacy/exceptions/{ => core}/index.rst | 0 .../legacy/exceptions/{ => core}/intro.rst | 0 .../exceptions/{ => core}/static/custom.css | 0 .../{ => core}/static/webassembly.png | Bin .../legacy/exceptions/{ => core}/syntax.rst | 0 .../legacy/exceptions/{ => core}/text.rst | 0 .../exceptions/{ => core}/util/macros.def | 0 .../exceptions/{ => core}/util/mathdef.py | 0 .../{ => core}/util/pseudo-lexer.py | 0 .../legacy/exceptions/{ => core}/valid.rst | 0 document/legacy/exceptions/js-api/Makefile | 44 + document/legacy/exceptions/js-api/index.bs | 1450 +++++++++++++++++ 21 files changed, 1540 insertions(+), 26 deletions(-) rename document/legacy/exceptions/{ => core}/LICENSE (100%) rename document/legacy/exceptions/{ => core}/Makefile (100%) rename document/legacy/exceptions/{ => core}/README.md (100%) rename document/legacy/exceptions/{ => core}/appendix/index-instructions.py (100%) rename document/legacy/exceptions/{ => core}/binary.rst (100%) rename document/legacy/exceptions/{ => core}/conf.py (100%) rename document/legacy/exceptions/{ => core}/exec.rst (100%) rename document/legacy/exceptions/{ => core}/index.rst (100%) rename document/legacy/exceptions/{ => core}/intro.rst (100%) rename document/legacy/exceptions/{ => core}/static/custom.css (100%) rename document/legacy/exceptions/{ => core}/static/webassembly.png (100%) rename document/legacy/exceptions/{ => core}/syntax.rst (100%) rename document/legacy/exceptions/{ => core}/text.rst (100%) rename document/legacy/exceptions/{ => core}/util/macros.def (100%) rename document/legacy/exceptions/{ => core}/util/mathdef.py (100%) rename document/legacy/exceptions/{ => core}/util/pseudo-lexer.py (100%) rename document/legacy/exceptions/{ => core}/valid.rst (100%) create mode 100644 document/legacy/exceptions/js-api/Makefile create mode 100644 document/legacy/exceptions/js-api/index.bs diff --git a/.github/workflows/ci-spec.yml b/.github/workflows/ci-spec.yml index 08b093cc5..fecb93657 100644 --- a/.github/workflows/ci-spec.yml +++ b/.github/workflows/ci-spec.yml @@ -41,25 +41,6 @@ jobs: name: core-rendered path: document/core/_build/html - build-legacy-exceptions-spec: - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v2 - with: - submodules: "recursive" - - name: Setup TexLive - run: sudo apt-get update -y && sudo apt-get install -y latexmk texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended - - name: Setup Sphinx - run: pip install six && pip install sphinx==5.1.0 - - name: Build main spec - run: cd document/legacy/exceptions && make main - - name: Upload artifact - uses: actions/upload-artifact@v2 - with: - name: legacy-exceptions-rendered - path: document/legacy/exceptions/_build/html - build-js-api-spec: runs-on: ubuntu-latest steps: @@ -90,9 +71,43 @@ jobs: name: web-api-rendered path: document/web-api/index.html + build-legacy-exceptions-core-spec: + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v2 + with: + submodules: "recursive" + - name: Setup TexLive + run: sudo apt-get update -y && sudo apt-get install -y latexmk texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended + - name: Setup Sphinx + run: pip install six && pip install sphinx==5.1.0 + - name: Build main spec + run: cd document/legacy/exceptions/core && make main + - name: Upload artifact + uses: actions/upload-artifact@v2 + with: + name: legacy-exceptions-core-rendered + path: document/legacy/exceptions/core/_build/html + + build-legacy-exceptions-js-api-spec: + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v2 + - name: Setup Bikeshed + run: pip install bikeshed && bikeshed update + - name: Run Bikeshed + run: bikeshed spec "document/legacy/exceptions/js-api/index.bs" "document/legacy/exceptions/js-api/index.html" + - name: Upload artifact + uses: actions/upload-artifact@v2 + with: + name: legacy-exceptions-js-api-rendered + path: document/legacy/exceptions/js-api/index.html + publish-spec: runs-on: ubuntu-latest - needs: [build-core-spec, build-legacy-exceptions-spec, build-js-api-spec, build-web-api-spec] + needs: [build-core-spec, build-js-api-spec, build-web-api-spec, build-legacy-exceptions-core-spec, build-legacy-exceptions-js-api-spec] steps: - name: Checkout repo uses: actions/checkout@v2 @@ -103,11 +118,6 @@ jobs: with: name: core-rendered path: _output/core - - name: Download legacy exceptions spec artifact - uses: actions/download-artifact@v2 - with: - name: legacy-exceptions-rendered - path: _output/legacy/exceptions - name: Download JS API spec artifact uses: actions/download-artifact@v2 with: @@ -118,6 +128,16 @@ jobs: with: name: web-api-rendered path: _output/web-api + - name: Download legacy exceptions core spec artifact + uses: actions/download-artifact@v2 + with: + name: legacy-exceptions-core-rendered + path: _output/legacy/exceptions/core + - name: Download legacy exceptions JS API spec artifact + uses: actions/download-artifact@v2 + with: + name: legacy-exceptions-js-api-rendered + path: _output/legacy/exceptions/js-api - name: Publish to GitHub Pages if: github.ref == 'refs/heads/main' uses: peaceiris/actions-gh-pages@v3 diff --git a/document/Makefile b/document/Makefile index 629d5f512..1a9625c14 100644 --- a/document/Makefile +++ b/document/Makefile @@ -1,4 +1,4 @@ -DIRS = core js-api web-api legacy/exceptions +DIRS = core js-api web-api legacy/exception-handling FILES = index.html BUILDDIR = _build diff --git a/document/legacy/exceptions/LICENSE b/document/legacy/exceptions/core/LICENSE similarity index 100% rename from document/legacy/exceptions/LICENSE rename to document/legacy/exceptions/core/LICENSE diff --git a/document/legacy/exceptions/Makefile b/document/legacy/exceptions/core/Makefile similarity index 100% rename from document/legacy/exceptions/Makefile rename to document/legacy/exceptions/core/Makefile diff --git a/document/legacy/exceptions/README.md b/document/legacy/exceptions/core/README.md similarity index 100% rename from document/legacy/exceptions/README.md rename to document/legacy/exceptions/core/README.md diff --git a/document/legacy/exceptions/appendix/index-instructions.py b/document/legacy/exceptions/core/appendix/index-instructions.py similarity index 100% rename from document/legacy/exceptions/appendix/index-instructions.py rename to document/legacy/exceptions/core/appendix/index-instructions.py diff --git a/document/legacy/exceptions/binary.rst b/document/legacy/exceptions/core/binary.rst similarity index 100% rename from document/legacy/exceptions/binary.rst rename to document/legacy/exceptions/core/binary.rst diff --git a/document/legacy/exceptions/conf.py b/document/legacy/exceptions/core/conf.py similarity index 100% rename from document/legacy/exceptions/conf.py rename to document/legacy/exceptions/core/conf.py diff --git a/document/legacy/exceptions/exec.rst b/document/legacy/exceptions/core/exec.rst similarity index 100% rename from document/legacy/exceptions/exec.rst rename to document/legacy/exceptions/core/exec.rst diff --git a/document/legacy/exceptions/index.rst b/document/legacy/exceptions/core/index.rst similarity index 100% rename from document/legacy/exceptions/index.rst rename to document/legacy/exceptions/core/index.rst diff --git a/document/legacy/exceptions/intro.rst b/document/legacy/exceptions/core/intro.rst similarity index 100% rename from document/legacy/exceptions/intro.rst rename to document/legacy/exceptions/core/intro.rst diff --git a/document/legacy/exceptions/static/custom.css b/document/legacy/exceptions/core/static/custom.css similarity index 100% rename from document/legacy/exceptions/static/custom.css rename to document/legacy/exceptions/core/static/custom.css diff --git a/document/legacy/exceptions/static/webassembly.png b/document/legacy/exceptions/core/static/webassembly.png similarity index 100% rename from document/legacy/exceptions/static/webassembly.png rename to document/legacy/exceptions/core/static/webassembly.png diff --git a/document/legacy/exceptions/syntax.rst b/document/legacy/exceptions/core/syntax.rst similarity index 100% rename from document/legacy/exceptions/syntax.rst rename to document/legacy/exceptions/core/syntax.rst diff --git a/document/legacy/exceptions/text.rst b/document/legacy/exceptions/core/text.rst similarity index 100% rename from document/legacy/exceptions/text.rst rename to document/legacy/exceptions/core/text.rst diff --git a/document/legacy/exceptions/util/macros.def b/document/legacy/exceptions/core/util/macros.def similarity index 100% rename from document/legacy/exceptions/util/macros.def rename to document/legacy/exceptions/core/util/macros.def diff --git a/document/legacy/exceptions/util/mathdef.py b/document/legacy/exceptions/core/util/mathdef.py similarity index 100% rename from document/legacy/exceptions/util/mathdef.py rename to document/legacy/exceptions/core/util/mathdef.py diff --git a/document/legacy/exceptions/util/pseudo-lexer.py b/document/legacy/exceptions/core/util/pseudo-lexer.py similarity index 100% rename from document/legacy/exceptions/util/pseudo-lexer.py rename to document/legacy/exceptions/core/util/pseudo-lexer.py diff --git a/document/legacy/exceptions/valid.rst b/document/legacy/exceptions/core/valid.rst similarity index 100% rename from document/legacy/exceptions/valid.rst rename to document/legacy/exceptions/core/valid.rst diff --git a/document/legacy/exceptions/js-api/Makefile b/document/legacy/exceptions/js-api/Makefile new file mode 100644 index 000000000..84ba5d3ab --- /dev/null +++ b/document/legacy/exceptions/js-api/Makefile @@ -0,0 +1,44 @@ +BUILDDIR = _build +STATICDIR = _static +DOWNLOADDIR = _download +NAME = WebAssembly + +.PHONY: all +all: + mkdir -p $(BUILDDIR)/html + bikeshed spec index.bs $(BUILDDIR)/html/index.html + @echo "Build finished. The HTML pages are in `pwd`/$(BUILDDIR)/html." + +.PHONY: publish +publish: + (cd ..; make publish-js-api) + +.PHONY: clean +clean: + rm -rf $(BUILDDIR) + rm -rf $(STATICDIR) + +.PHONY: diff +diff: all + @echo "Downloading the old single-file html spec..." + curl `grep "^TR" index.bs | cut -d' ' -f2` -o $(BUILDDIR)/html/old.html + @echo "Done." + @echo "Diffing new against old..." + perl ../util/htmldiff.pl $(BUILDDIR)/html/old.html $(BUILDDIR)/html/index.html $(BUILDDIR)/html/diff.html + @echo "Done. The diff is at $(BUILDDIR)/html/diff.html" + +.PHONY: WD-tar +WD-tar: + bikeshed echidna --just-tar index.bs $(BUILDDIR)/html/index.html + mv test.tar $(BUILDDIR)/WD.tar + @echo "Built $(BUILDDIR)/WD.tar." + +.PHONY: WD-echidna +WD-echidna: + @if [ -z $(W3C_USERNAME) ] || \ + [ -z $(W3C_PASSWORD) ] || \ + [ -z $(DECISION_URL) ] ; then \ + echo "Must provide W3C_USERNAME, W3C_PASSWORD, and DECISION_URL environment variables"; \ + exit 1; \ + fi + bikeshed echidna index.bs --u $(W3C_USERNAME) --p $(W3C_PASSWORD) --d $(DECISION_URL) diff --git a/document/legacy/exceptions/js-api/index.bs b/document/legacy/exceptions/js-api/index.bs new file mode 100644 index 000000000..e7db14074 --- /dev/null +++ b/document/legacy/exceptions/js-api/index.bs @@ -0,0 +1,1450 @@ +
+Title: WebAssembly JavaScript Interface: Exception Handling
+Shortname: wasm-js-api
+Group: wasm
+Status: ED
+Level: 2
+TR: https://www.w3.org/TR/wasm-js-api-2/
+ED: https://webassembly.github.io/exception-handling/js-api/
+Editor: Ms2ger, Igalia
+Repository: WebAssembly/spec
+Markup Shorthands: css no, markdown yes
+Abstract: This document provides an explicit JavaScript API for interacting with WebAssembly.
+Prepare For TR: true
+
+ +
+{
+  "WEBASSEMBLY": {
+    "href": "https://webassembly.github.io/spec/core/",
+    "title": "WebAssembly Core Specification",
+    "publisher": "W3C WebAssembly Community Group",
+    "status": "Draft"
+  }
+}
+
+ +
+urlPrefix: https://tc39.github.io/ecma262/; spec: ECMASCRIPT
+    type: interface; for: ECMAScript
+        text: ArrayBuffer; url: sec-arraybuffer-objects
+    type: exception; for: ECMAScript
+        text: Error; url: sec-error-objects
+        text: NativeError; url: sec-nativeerror-constructors
+        text: TypeError; url: sec-native-error-types-used-in-this-standard-typeerror
+        text: RangeError; url: sec-native-error-types-used-in-this-standard-rangeerror
+    type: dfn
+        url: sec-returnifabrupt-shorthands
+            text: !
+            text: ?
+        text: Type; url: sec-ecmascript-data-types-and-values
+        text: current Realm; url: current-realm
+        text: Built-in Function Objects; url: sec-built-in-function-objects
+        text: NativeError Object Structure; url: sec-nativeerror-object-structure
+        text: 𝔽; url: #𝔽
+        text: ℤ; url: #ℤ
+urlPrefix: https://webassembly.github.io/exception-handling/core/; spec: WebAssembly; type: dfn
+    url: valid/modules.html#valid-module
+        text: valid
+        text: WebAssembly module validation
+    text: module grammar; url: binary/modules.html#binary-module
+    text: custom section; url: binary/modules.html#custom-section
+    text: customsec; url: binary/modules.html#binary-customsec
+    text: memory instance; url: exec/runtime.html#memory-instances
+    text: table instance; url: exec/runtime.html#table-instances
+    text: global instance; url: exec/runtime.html#global-instances
+    text: trap; url: exec/runtime.html#syntax-trap
+    url: exec/runtime.html#values
+        text: WebAssembly value
+        text: i64.const
+        text: i32.const
+        text: f32.const
+        text: f64.const
+        text: v128.const
+        text: ref.null
+        text: ref.func
+        text: ref.extern
+    text: function index; url: syntax/modules.html#syntax-funcidx
+    text: function instance; url: exec/runtime.html#function-instances
+    text: store_init; url: appendix/embedding.html#embed-store-init
+    text: module_decode; url: appendix/embedding.html#embed-module-decode
+    text: module_validate; url: appendix/embedding.html#embed-module-validate
+    text: module_instantiate; url: appendix/embedding.html#embed-module-instantiate
+    text: module_imports; url: appendix/embedding.html#embed-module-imports
+    text: module_exports; url: appendix/embedding.html#embed-module-exports
+    text: instance_export; url: appendix/embedding.html#embed-instance-export
+    text: func_alloc; url: appendix/embedding.html#embed-func-alloc
+    text: func_type; url: appendix/embedding.html#embed-func-type
+    text: func_invoke; url: appendix/embedding.html#embed-func-invoke
+    text: table_alloc; url: appendix/embedding.html#embed-table-alloc
+    text: table_type; url: appendix/embedding.html#embed-table-type
+    text: table_read; url: appendix/embedding.html#embed-table-read
+    text: table_write; url: appendix/embedding.html#embed-table-write
+    text: table_size; url: appendix/embedding.html#embed-table-size
+    text: table_grow; url: appendix/embedding.html#embed-table-grow
+    text: mem_alloc; url: appendix/embedding.html#embed-mem-alloc
+    text: mem_type; url: appendix/embedding.html#embed-mem-type
+    text: mem_read; url: appendix/embedding.html#embed-mem-read
+    text: mem_write; url: appendix/embedding.html#embed-mem-write
+    text: mem_size; url: appendix/embedding.html#embed-mem-size
+    text: mem_grow; url: appendix/embedding.html#embed-mem-grow
+    text: global_alloc; url: appendix/embedding.html#embed-global-alloc
+    text: global_type; url: appendix/embedding.html#embed-global-type
+    text: global_read; url: appendix/embedding.html#embed-global-read
+    text: global_write; url: appendix/embedding.html#embed-global-write
+    text: error; url: appendix/embedding.html#embed-error
+    text: store; url: exec/runtime.html#syntax-store
+    text: table type; url: syntax/types.html#syntax-tabletype
+    text: table address; url: exec/runtime.html#syntax-tableaddr
+    text: function address; url: exec/runtime.html#syntax-funcaddr
+    text: memory address; url: exec/runtime.html#syntax-memaddr
+    text: global address; url: exec/runtime.html#syntax-globaladdr
+    text: extern address; url: exec/runtime.html#syntax-externaddr
+    text: tag address; url: exec/runtime.html#syntax-tagaddr
+    url: syntax/types.html#syntax-numtype
+        text: i32
+        text: i64
+        text: f32
+        text: f64
+    url: syntax/types.html#vector-types
+        text: v128
+    url: syntax/types.html#syntax-reftype
+        text: reftype
+        text: funcref
+        text: externref
+    url: syntax/values.html#syntax-float
+        text: +∞
+        text: −∞
+        text: nan
+        text: canon
+        text: signif
+    text: function element; url: exec/runtime.html#syntax-funcelem
+    text: import component; url: syntax/modules.html#imports
+    url: exec/runtime.html#syntax-externval
+        text: external value
+        for: external value
+            text: tag
+    text: host function; url: exec/runtime.html#syntax-hostfunc
+    text: the instantiation algorithm; url: exec/modules.html#instantiation
+    text: module; url: syntax/modules.html#syntax-module
+    text: imports; url: syntax/modules.html#syntax-module
+    text: import; url: syntax/modules.html#syntax-import
+    url: syntax/types.html#external-types
+        text: external type
+        text: func
+        text: table
+        text: mem
+        text: global
+        for: externtype
+            text: tag
+    text: global type; url: syntax/types.html#syntax-globaltype
+    url: syntax/types.html#syntax-mut
+        text: var
+        text: const
+    text: address; url: exec/runtime.html#addresses
+    text: signed_32; url: exec/numerics.html#aux-signed
+    text: memory.grow; url: exec/instructions.html#exec-memory-grow
+    text: current frame; url: exec/conventions.html#exec-notation-textual
+    text: module; for: frame; url: exec/runtime.html#syntax-frame
+    text: memaddrs; for: moduleinst; url: exec/runtime.html#syntax-moduleinst
+    text: signed_64; url: exec/numerics.html#aux-signed
+    text: sequence; url: syntax/conventions.html#grammar-notation
+    text: exception; for: tagtype/attribute; url: syntax/types.html#syntax-tagtype
+urlPrefix: https://heycam.github.io/webidl/; spec: WebIDL
+    type: dfn
+        text: create a namespace object; url: create-a-namespace-object
+urlPrefix: https://webassembly.github.io/js-types/js-api/; spec: WebAssembly JS API (JS Type Reflection)
+    type: abstract-op; text: FromValueType; url: abstract-opdef-fromvaluetype
+
+ + + + + +This API provides a way to access WebAssembly [[WEBASSEMBLY]] through a bridge to explicitly construct modules from JavaScript [[ECMASCRIPT]]. + +

Sample API Usage

+ +

This section is non-normative.

+ +Given `demo.wat` (encoded to `demo.wasm`): + +```lisp +(module + (import "js" "import1" (func $i1)) + (import "js" "import2" (func $i2)) + (func $main (call $i1)) + (start $main) + (func (export "f") (call $i2)) +) +``` + +and the following JavaScript, run in a browser: + +```javascript +var importObj = {js: { + import1: () => console.log("hello,"), + import2: () => console.log("world!") +}}; +fetch('demo.wasm').then(response => + response.arrayBuffer() +).then(buffer => + WebAssembly.instantiate(buffer, importObj) +).then(({module, instance}) => + instance.exports.f() +); +``` + +

Notation

+ +This specification depends on the Infra Standard. [[INFRA]] + +The WebAssembly [=sequence=] type is equivalent to the [=list=] type defined there; values of one +are treated as values of the other transparently. + +

Internal storage

+ +

Interaction of the WebAssembly Store with JavaScript

+ +Note: WebAssembly semantics are defined in terms of an abstract [=store=], representing the state of the WebAssembly abstract machine. WebAssembly operations take a store and return an updated store. + +Each [=agent=] has an associated store. When a new agent is created, its associated store is set to the result of [=store_init=](). + +Note: In this specification, no WebAssembly-related objects, memory or addresses can be shared among agents in an [=agent cluster=]. In a future version of WebAssembly, this may change. + +Elements of the WebAssembly store may be identified with JavaScript values. In particular, each WebAssembly [=memory instance=] with a corresponding {{Memory}} object is identified with a JavaScript [=Data Block=]; modifications to this Data Block are identified to updating the agent's store to a store which reflects those changes, and vice versa. + +

WebAssembly JS Object Caches

+ +Note: There are several WebAssembly objects that may have a corresponding JavaScript object. The correspondence is stored in a per-agent mapping from WebAssembly [=address=]es to JavaScript objects. +This mapping is used to ensure that, for a given [=agent=], there exists at most one JavaScript object for a particular WebAssembly address. However, this property does not hold for shared objects. + +Each [=agent=] is associated with the following [=ordered map=]s: + * The Memory object cache, mapping [=memory address=]es to {{Memory}} objects. + * The Table object cache, mapping [=table address=]es to {{Table}} objects. + * The Exported Function cache, mapping [=function address=]es to [=Exported Function=] objects. + * The Global object cache, mapping [=global address=]es to {{Global}} objects. + * The Extern value cache, mapping [=extern address=]es to values. + * The Tag object cache, mapping [=tag addresses=] to {{Tag}} objects. + +

The WebAssembly Namespace

+ +
+dictionary WebAssemblyInstantiatedSource {
+    required Module module;
+    required Instance instance;
+};
+
+[Exposed=*]
+namespace WebAssembly {
+    boolean validate(BufferSource bytes);
+    Promise<Module> compile(BufferSource bytes);
+
+    Promise<WebAssemblyInstantiatedSource> instantiate(
+        BufferSource bytes, optional object importObject);
+
+    Promise<Instance> instantiate(
+        Module moduleObject, optional object importObject);
+};
+
+ + + +
+ To compile a WebAssembly module from source bytes |bytes|, perform the following steps: + 1. Let |module| be [=module_decode=](|bytes|). If |module| is [=error=], return [=error=]. + 1. If [=module_validate=](|module|) is [=error=], return [=error=]. + 1. Return |module|. +
+ +
+ The validate(|bytes|) method, when invoked, performs the following steps: + 1. Let |stableBytes| be a [=get a copy of the buffer source|copy of the bytes held by the buffer=] |bytes|. + 1. [=Compile a WebAssembly module|Compile=] |stableBytes| as a WebAssembly module and store the results as |module|. + 1. If |module| is [=error=], return false. + 1. Return true. +
+ +A {{Module}} object represents a single WebAssembly module. Each {{Module}} object has the following internal slots: + + * \[[Module]] : a WebAssembly [=/module=] + * \[[Bytes]] : the source bytes of \[[Module]]. + +
+ To construct a WebAssembly module object from a module |module| and source bytes |bytes|, perform the following steps: + + 1. Let |moduleObject| be a new {{Module}} object. + 1. Set |moduleObject|.\[[Module]] to |module|. + 1. Set |moduleObject|.\[[Bytes]] to |bytes|. + 1. Return |moduleObject|. +
+ +
+ To asynchronously compile a WebAssembly module from source bytes |bytes|, using optional [=task source=] |taskSource|, perform the following steps: + + 1. Let |promise| be [=a new promise=]. + 1. Run the following steps [=in parallel=]: + 1. [=compile a WebAssembly module|Compile the WebAssembly module=] |bytes| and store the result as |module|. + 1. [=Queue a task=] to perform the following steps. If |taskSource| was provided, queue the task on that task source. + 1. If |module| is [=error=], reject |promise| with a {{CompileError}} exception. + 1. Otherwise, + 1. [=Construct a WebAssembly module object=] from |module| and |bytes|, and let |moduleObject| be the result. + 1. [=Resolve=] |promise| with |moduleObject|. + 1. Return |promise|. +
+ +
+ The compile(|bytes|) method, when invoked, performs the following steps: + 1. Let |stableBytes| be a [=get a copy of the buffer source|copy of the bytes held by the buffer=] |bytes|. + 1. [=Asynchronously compile a WebAssembly module=] from |stableBytes| and return the result. +
+ +
+ To read the imports from a WebAssembly module |module| from imports object |importObject|, perform the following steps: + 1. If |module|.[=imports=] [=list/is empty|is not empty=], and |importObject| is undefined, throw a {{TypeError}} exception. + 1. Let |imports| be « ». + 1. [=list/iterate|For each=] (|moduleName|, |componentName|, |externtype|) of [=module_imports=](|module|), + 1. Let |o| be [=?=] [$Get$](|importObject|, |moduleName|). + 1. If [=Type=](|o|) is not Object, throw a {{TypeError}} exception. + 1. Let |v| be [=?=] [$Get$](|o|, |componentName|). + 1. If |externtype| is of the form [=func=] |functype|, + 1. If [$IsCallable$](|v|) is false, throw a {{LinkError}} exception. + 1. If |v| has a \[[FunctionAddress]] internal slot, and therefore is an [=Exported Function=], + 1. Let |funcaddr| be the value of |v|'s \[[FunctionAddress]] internal slot. + 1. Otherwise, + 1. [=Create a host function=] from |v| and |functype|, and let |funcaddr| be the result. + 1. Let |index| be the number of external functions in |imports|. This value |index| is known as the index of the host function |funcaddr|. + 1. Let |externfunc| be the [=external value=] [=external value|func=] |funcaddr|. + 1. [=list/Append=] |externfunc| to |imports|. + 1. If |externtype| is of the form [=global=] mut |valtype|, + 1. If [=Type=](|v|) is Number or BigInt, + 1. If |valtype| is [=i64=] and [=Type=](|v|) is Number, + 1. Throw a {{LinkError}} exception. + 1. If |valtype| is not [=i64=] and [=Type=](|v|) is BigInt, + 1. Throw a {{LinkError}} exception. + 1. If |valtype| is [=v128=], + 1. Throw a {{LinkError}} exception. + 1. Let |value| be [=ToWebAssemblyValue=](|v|, |valtype|). + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Let (|store|, |globaladdr|) be [=global_alloc=](|store|, [=const=] |valtype|, |value|). + 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. + 1. Otherwise, if |v| [=implements=] {{Global}}, + 1. Let |globaladdr| be |v|.\[[Global]]. + 1. Otherwise, + 1. Throw a {{LinkError}} exception. + 1. Let |externglobal| be [=external value|global=] |globaladdr|. + 1. [=list/Append=] |externglobal| to |imports|. + 1. If |externtype| is of the form [=mem=] memtype, + 1. If |v| does not [=implement=] {{Memory}}, throw a {{LinkError}} exception. + 1. Let |externmem| be the [=external value=] [=external value|mem=] |v|.\[[Memory]]. + 1. [=list/Append=] |externmem| to |imports|. + 1. If |externtype| is of the form [=table=] tabletype, + 1. If |v| does not [=implement=] {{Table}}, throw a {{LinkError}} exception. + 1. Let |tableaddr| be |v|.\[[Table]]. + 1. Let |externtable| be the [=external value=] [=external value|table=] |tableaddr|. + 1. [=list/Append=] |externtable| to |imports|. + 1. If |externtype| is of the form [=externtype/tag=] |attribute| functype, + 1. Assert: |attribute| is [=tagtype/attribute/exception=]. + 1. If |v| does not [=implement=] {{Tag}}, throw a {{LinkError}} exception. + 1. Let |tagaddr| be |v|.\[[Address]]. + 1. Let |externtag| be the [=external value=] [=external value/tag=] |tagaddr|. + 1. [=list/Append=] |externtag| to |imports|. + 1. Return |imports|. + +Note: This algorithm only verifies the right kind of JavaScript values are passed. +The verification of WebAssembly type requirements is deferred to the +"[=instantiate the core of a WebAssembly module=]" algorithm. +
+ +
+ To create an exports object from a WebAssembly module |module| and instance |instance|, perform the following steps: + 1. Let |exportsObject| be [=!=] [$OrdinaryObjectCreate$](null). + 1. [=list/iterate|For each=] (|name|, |externtype|) of [=module_exports=](|module|), + 1. Let |externval| be [=instance_export=](|instance|, |name|). + 1. Assert: |externval| is not [=error=]. + 1. If |externtype| is of the form [=func=] functype, + 1. Assert: |externval| is of the form [=external value|func=] |funcaddr|. + 1. Let [=external value|func=] |funcaddr| be |externval|. + 1. Let |func| be the result of creating [=a new Exported Function=] from |funcaddr|. + 1. Let |value| be |func|. + 1. If |externtype| is of the form [=global=] mut globaltype, + 1. Assert: |externval| is of the form [=external value|global=] |globaladdr|. + 1. Let [=external value|global=] |globaladdr| be |externval|. + 1. Let |global| be [=create a global object|a new Global object=] created from |globaladdr|. + 1. Let |value| be |global|. + 1. If |externtype| is of the form [=mem=] memtype, + 1. Assert: |externval| is of the form [=external value|mem=] |memaddr|. + 1. Let [=external value|mem=] |memaddr| be |externval|. + 1. Let |memory| be [=create a memory object|a new Memory object=] created from |memaddr|. + 1. Let |value| be |memory|. + 1. If |externtype| is of the form [=table=] tabletype, + 1. Assert: |externval| is of the form [=external value|table=] |tableaddr|. + 1. Let [=external value|table=] |tableaddr| be |externval|. + 1. Let |table| be [=create a Table object|a new Table object=] created from |tableaddr|. + 1. Let |value| be |table|. + 1. If |externtype| is of the form [=externtype/tag=] |attribute| functype, + 1. Assert: |attribute| is [=tagtype/attribute/exception=]. + 1. Assert: |externval| is of the form [=external value/tag=] |tagaddr|. + 1. Let [=external value/tag=] |tagaddr| be |externval|. + 1. Let |tag| be [=create a Tag object|a new Tag object=] created from |tagaddr|. + 1. Let |value| be |tag|. + 1. Let |status| be [=!=] [$CreateDataProperty$](|exportsObject|, |name|, |value|). + 1. Assert: |status| is true. + + Note: the validity and uniqueness checks performed during [=WebAssembly module validation=] ensure that each property name is valid and no properties are defined twice. + 1. Perform [=!=] [$SetIntegrityLevel$](|exportsObject|, `"frozen"`). + 1. Return |exportsObject|. +
+ +
+ To initialize an instance object |instanceObject| from a WebAssembly module |module| and instance |instance|, perform the following steps: + + 1. [=Create an exports object=] from |module| and |instance| and let |exportsObject| be the result. + 1. Set |instanceObject|.\[[Instance]] to |instance|. + 1. Set |instanceObject|.\[[Exports]] to |exportsObject|. +
+ +
+ To instantiate the core of a WebAssembly module from a module |module| and imports |imports|, perform the following steps: + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Let |result| be [=module_instantiate=](|store|, |module|, |imports|). + 1. If |result| is [=error=], throw an appropriate exception type: + * A {{LinkError}} exception for most cases which occur during linking. + * If the error came when running the start function, throw a {{RuntimeError}} for most errors which occur from WebAssembly, or the error object propagated from inner ECMAScript code. + * Another error type if appropriate, for example an out-of-memory exception, as documented in the WebAssembly error mapping. + 1. Let (|store|, |instance|) be |result|. + 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. + 1. Return |instance|. +
+ +
+ To asynchronously instantiate a WebAssembly module from a {{Module}} |moduleObject| and imports |importObject|, perform the following steps: + 1. Let |promise| be [=a new promise=]. + 1. Let |module| be |moduleObject|.\[[Module]]. + 1. [=Read the imports=] of |module| with imports |importObject|, and let |imports| be the result. + If this operation throws an exception, catch it, [=reject=] |promise| with the exception, and return |promise|. + 1. Run the following steps [=in parallel=]: + 1. [=Queue a task=] to perform the following steps: + Note: Implementation-specific work may be performed here. + 1. [=Instantiate the core of a WebAssembly module=] |module| with |imports|, and let |instance| be the result. + If this throws an exception, catch it, [=reject=] |promise| with the exception, and terminate these substeps. + 1. Let |instanceObject| be a [=/new=] {{Instance}}. + 1. [=initialize an instance object|Initialize=] |instanceObject| from |module| and |instance|. + If this throws an exception, catch it, [=reject=] |promise| with the exception, and terminate these substeps. + 1. [=Resolve=] |promise| with |instanceObject|. + 1. Return |promise|. +
+ +
+ To synchronously instantiate a WebAssembly module from a {{Module}} |moduleObject| and imports |importObject|, perform the following steps: + 1. Let |module| be |moduleObject|.\[[Module]]. + 1. [=Read the imports=] of |module| with imports |importObject|, and let |imports| be the result. + 1. [=Instantiate the core of a WebAssembly module=] |module| with |imports|, and let |instance| be the result. + 1. Let |instanceObject| be a [=/new=] {{Instance}}. + 1. [=initialize an instance object|Initialize=] |instanceObject| from |module| and |instance|. + 1. Return |instanceObject|. +
+ +
+ To instantiate a promise of a module |promiseOfModule| with imports |importObject|, perform the following steps: + + 1. Let |promise| be [=a new promise=]. + 1. [=Upon fulfillment=] of |promiseOfModule| with value |module|: + 1. [=asynchronously instantiate a WebAssembly module|Instantiate the WebAssembly module=] |module| importing |importObject|, and let |innerPromise| be the result. + 1. [=Upon fulfillment=] of |innerPromise| with value |instance|. + 1. Let |result| be the {{WebAssemblyInstantiatedSource}} value «[ "{{WebAssemblyInstantiatedSource/module}}" → |module|, "{{WebAssemblyInstantiatedSource/instance}}" → |instance| ]». + 1. [=Resolve=] |promise| with |result|. + 1. [=Upon rejection=] of |innerPromise| with reason |reason|: + 1. [=Reject=] |promise| with |reason|. + 1. [=Upon rejection=] of |promiseOfModule| with reason |reason|: + 1. [=Reject=] |promise| with |reason|. + 1. Return |promise|. +
+ +
+ The instantiate(|bytes|, |importObject|) method, when invoked, performs the following steps: + 1. Let |stableBytes| be a [=get a copy of the buffer source|copy of the bytes held by the buffer=] |bytes|. + 1. [=Asynchronously compile a WebAssembly module=] from |stableBytes| and let |promiseOfModule| be the result. + 1. [=Instantiate a promise of a module|Instantiate=] |promiseOfModule| with imports |importObject| and return the result. +
+ +
+ The instantiate(|moduleObject|, |importObject|) method, when invoked, performs the following steps: + 1. [=asynchronously instantiate a WebAssembly module|Asynchronously instantiate the WebAssembly module=] |moduleObject| importing |importObject|, and return the result. +
+ +Note: A follow-on streaming API is documented in the WebAssembly Web API. + +

Modules

+ +
+enum ImportExportKind {
+  "function",
+  "table",
+  "memory",
+  "global",
+  "tag"
+};
+
+dictionary ModuleExportDescriptor {
+  required USVString name;
+  required ImportExportKind kind;
+  // Note: Other fields such as signature may be added in the future.
+};
+
+dictionary ModuleImportDescriptor {
+  required USVString module;
+  required USVString name;
+  required ImportExportKind kind;
+};
+
+[LegacyNamespace=WebAssembly, Exposed=*]
+interface Module {
+  constructor(BufferSource bytes);
+  static sequence<ModuleExportDescriptor> exports(Module moduleObject);
+  static sequence<ModuleImportDescriptor> imports(Module moduleObject);
+  static sequence<ArrayBuffer> customSections(Module moduleObject, DOMString sectionName);
+};
+
+ +
+ The string value of the extern type |type| is + * "function" if |type| is of the form [=func=] functype + * "table" if |type| is of the form [=table=] tabletype + * "memory" if |type| is of the form [=mem=] memtype + * "global" if |type| is of the form [=global=] globaltype + * "tag" if |type| is of the form [=externtype/tag=] tag +
+ +
+ The exports(|moduleObject|) method, when invoked, performs the following steps: + 1. Let |module| be |moduleObject|.\[[Module]]. + 1. Let |exports| be « ». + 1. [=list/iterate|For each=] (|name|, |type|) of [=module_exports=](|module|), + 1. Let |kind| be the [=string value of the extern type=] |type|. + 1. Let |obj| be «[ "{{ModuleExportDescriptor/name}}" → |name|, "{{ModuleExportDescriptor/kind}}" → |kind| ]». + 1. [=list/Append=] |obj| to |exports|. + 1. Return |exports|. +
+ +
+ The imports(|moduleObject|) method, when invoked, performs the following steps: + 1. Let |module| be |moduleObject|.\[[Module]]. + 1. Let |imports| be « ». + 1. [=list/iterate|For each=] (|moduleName|, |name|, |type|) of [=module_imports=](|module|), + 1. Let |kind| be the [=string value of the extern type=] |type|. + 1. Let |obj| be «[ "{{ModuleImportDescriptor/module}}" → |moduleName|, "{{ModuleImportDescriptor/name}}" → |name|, "{{ModuleImportDescriptor/kind}}" → |kind| ]». + 1. [=list/Append=] |obj| to |imports|. + 1. Return |imports|. +
+ +
+ The customSections(|moduleObject|, |sectionName|) method, when invoked, performs the following steps: + 1. Let |bytes| be |moduleObject|.\[[Bytes]]. + 1. Let |customSections| be « ». + 1. [=list/iterate|For each=] [=custom section=] |customSection| of |bytes|, interpreted according to the [=module grammar=], + 1. Let |name| be the name of |customSection|, [=UTF-8 decode without BOM or fail|decoded as UTF-8=]. + 1. Assert: |name| is not failure (|moduleObject|.\[[Module]] is [=valid=]). + 1. If |name| equals |sectionName| as string values, + 1. [=list/Append=] a new {{ArrayBuffer}} containing a copy of the bytes in |bytes| for the range matched by this [=customsec=] production to |customSections|. + 1. Return |customSections|. +
+ +
+ The Module(|bytes|) constructor, when invoked, performs the following steps: + + 1. Let |stableBytes| be a [=get a copy of the buffer source|copy of the bytes held by the buffer=] |bytes|. + 1. [=Compile a WebAssembly module|Compile the WebAssembly module=] |stableBytes| and store the result as |module|. + 1. If |module| is [=error=], throw a {{CompileError}} exception. + 1. Set **this**.\[[Module]] to |module|. + 1. Set **this**.\[[Bytes]] to |stableBytes|. + +Note: Some implementations enforce a size limitation on |bytes|. Use of this API is discouraged, in favor of asynchronous APIs. +
+ +

Instances

+ +
+[LegacyNamespace=WebAssembly, Exposed=*]
+interface Instance {
+  constructor(Module module, optional object importObject);
+  readonly attribute object exports;
+};
+
+ +
+ The Instance(|module|, |importObject|) constructor, when invoked, runs the following steps: + 1. Let |module| be |module|.\[[Module]]. + 1. [=Read the imports=] of |module| with imports |importObject|, and let |imports| be the result. + 1. [=Instantiate the core of a WebAssembly module=] |module| with |imports|, and let |instance| be the result. + 1. [=initialize an instance object|Initialize=] **this** from |module| and |instance|. + +Note: The use of this synchronous API is discouraged, as some implementations sometimes do long-running compilation work when instantiating. +
+ +
+ The getter of the exports attribute of {{Instance}} returns **this**.\[[Exports]]. +
+ +

Memories

+ +
+dictionary MemoryDescriptor {
+  required [EnforceRange] unsigned long initial;
+  [EnforceRange] unsigned long maximum;
+};
+
+[LegacyNamespace=WebAssembly, Exposed=*]
+interface Memory {
+  constructor(MemoryDescriptor descriptor);
+  unsigned long grow([EnforceRange] unsigned long delta);
+  readonly attribute ArrayBuffer buffer;
+};
+
+ +A {{Memory}} object represents a single [=memory instance=] +which can be simultaneously referenced by multiple {{Instance}} objects. Each +{{Memory}} object has the following internal slots: + + * \[[Memory]] : a [=memory address=] + * \[[BufferObject]] : an {{ArrayBuffer}} whose [=Data Block=] is [=identified with=] the above memory address + +
+ To create a memory buffer from a [=memory address=] |memaddr|, perform the following steps: + + 1. Let |block| be a [=Data Block=] which is [=identified with=] the underlying memory of |memaddr|. + 1. Let |buffer| be a new {{ArrayBuffer}} whose \[[ArrayBufferData]] is |block| and \[[ArrayBufferByteLength]] is set to the length of |block|. + 1. Set |buffer|.\[[ArrayBufferDetachKey]] to "WebAssembly.Memory". + 1. Return |buffer|. +
+ +
+ To initialize a memory object |memory| from a [=memory address=] |memaddr|, perform the following steps: + 1. Let |map| be the [=surrounding agent=]'s associated [=Memory object cache=]. + 1. Assert: |map|[|memaddr|] doesn't [=map/exist=]. + 1. Let |buffer| be the result of [=create a memory buffer|creating a memory buffer=] from |memaddr|. + 1. Set |memory|.\[[Memory]] to |memaddr|. + 1. Set |memory|.\[[BufferObject]] to |buffer|. + 1. [=map/Set=] |map|[|memaddr|] to |memory|. +
+ +
+ To create a memory object from a [=memory address=] |memaddr|, perform the following steps: + + 1. Let |map| be the [=surrounding agent=]'s associated [=Memory object cache=]. + 1. If |map|[|memaddr|] [=map/exists=], + 1. Return |map|[|memaddr|]. + 1. Let |memory| be a [=/new=] {{Memory}}. + 1. [=initialize a memory object|Initialize=] |memory| from |memaddr|. + 1. Return |memory|. +
+ +
+ The Memory(|descriptor|) constructor, when invoked, performs the following steps: + 1. Let |initial| be |descriptor|["initial"]. + 1. If |descriptor|["maximum"] [=map/exists=], let |maximum| be |descriptor|["maximum"]; otherwise, let |maximum| be empty. + 1. If |maximum| is not empty and |maximum| < |initial|, throw a {{RangeError}} exception. + 1. Let |memtype| be { min |initial|, max |maximum| }. + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Let (|store|, |memaddr|) be [=mem_alloc=](|store|, |memtype|). If allocation fails, throw a {{RangeError}} exception. + 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. + 1. [=initialize a memory object|Initialize=] **this** from |memaddr|. +
+ +
+ To reset the Memory buffer of |memaddr|, perform the following steps: + + 1. Let |map| be the [=surrounding agent=]'s associated [=Memory object cache=]. + 1. Assert: |map|[|memaddr|] [=map/exists=]. + 1. Let |memory| be |map|[|memaddr|]. + 1. Perform [=!=] [$DetachArrayBuffer$](|memory|.\[[BufferObject]], "WebAssembly.Memory"). + 1. Let |buffer| be the result of [=create a memory buffer|creating a memory buffer=] from |memaddr|. + 1. Set |memory|.\[[BufferObject]] to |buffer|. +
+ +
+ The grow(|delta|) method, when invoked, performs the following steps: + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Let |memaddr| be **this**.\[[Memory]]. + 1. Let |ret| be the [=mem_size=](|store|, |memaddr|). + 1. Let |store| be [=mem_grow=](|store|, |memaddr|, |delta|). + 1. If |store| is [=error=], throw a {{RangeError}} exception. + 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. + 1. [=Reset the memory buffer=] of |memaddr|. + 1. Return |ret|. +
+ +Immediately after a WebAssembly [=memory.grow=] instruction executes, perform the following steps: + +
+ 1. If the top of the stack is not [=i32.const=] (−1), + 1. Let |frame| be the [=current frame=]. + 1. Assert: due to validation, |frame|.[=frame/module=].[=moduleinst/memaddrs=][0] exists. + 1. Let |memaddr| be the memory address |frame|.[=frame/module=].[=moduleinst/memaddrs=][0]. + 1. [=Reset the memory buffer=] of |memaddr|. +
+ +
+ The getter of the buffer attribute of {{Memory}} returns **this**.\[[BufferObject]]. +
+ +

Tables

+ +
+enum TableKind {
+  "externref",
+  "anyfunc",
+  // Note: More values may be added in future iterations,
+  // e.g., typed function references, typed GC references
+};
+
+dictionary TableDescriptor {
+  required TableKind element;
+  required [EnforceRange] unsigned long initial;
+  [EnforceRange] unsigned long maximum;
+};
+
+[LegacyNamespace=WebAssembly, Exposed=*]
+interface Table {
+  constructor(TableDescriptor descriptor, optional any value);
+  unsigned long grow([EnforceRange] unsigned long delta, optional any value);
+  any get([EnforceRange] unsigned long index);
+  undefined set([EnforceRange] unsigned long index, optional any value);
+  readonly attribute unsigned long length;
+};
+
+ +A {{Table}} object represents a single [=table instance=] which can be simultaneously referenced by +multiple {{Instance}} objects. +Each {{Table}} object has a \[[Table]] internal slot, which is a [=table address=]. + +
+ To initialize a table object |table| from a [=table address=] |tableaddr|, perform the following steps: + 1. Let |map| be the [=surrounding agent=]'s associated [=Table object cache=]. + 1. Assert: |map|[|tableaddr|] doesn't [=map/exist=]. + 1. Set |table|.\[[Table]] to |tableaddr|. + 1. [=map/Set=] |map|[|tableaddr|] to |table|. +
+ +
+ To create a table object from a [=table address=] |tableaddr|, perform the following steps: + 1. Let |map| be the [=surrounding agent=]'s associated [=Table object cache=]. + 1. If |map|[|tableaddr|] [=map/exists=], + 1. Return |map|[|tableaddr|]. + 1. Let |table| be a [=/new=] {{Table}}. + 1. [=initialize a table object|Initialize=] |table| from |tableaddr|. + 1. Return |table|. +
+ +
+ The Table(|descriptor|, |value|) constructor, when invoked, performs the following steps: + 1. Let |elementType| be [=ToValueType=](|descriptor|["element"]). + 1. If |elementType| is not a [=reftype=], + 1. [=Throw=] a {{TypeError}} exception. + 1. Let |initial| be |descriptor|["initial"]. + 1. If |descriptor|["maximum"] [=map/exists=], let |maximum| be |descriptor|["maximum"]; otherwise, let |maximum| be empty. + 1. If |maximum| is not empty and |maximum| < |initial|, throw a {{RangeError}} exception. + 1. If |value| is missing, + 1. Let |ref| be [=DefaultValue=](|elementType|). + 1. Otherwise, + 1. Let |ref| be [=?=] [=ToWebAssemblyValue=](|value|, |elementType|). + 1. Let |type| be the [=table type=] {[=table type|min=] |initial|, [=table type|max=] |maximum|} |elementType|. + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Let (|store|, |tableaddr|) be [=table_alloc=](|store|, |type|, |ref|). + 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. + 1. [=initialize a table object|Initialize=] **this** from |tableaddr|. +
+ +
+ The grow(|delta|, |value|) method, when invoked, performs the following steps: + 1. Let |tableaddr| be **this**.\[[Table]]. + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Let |initialSize| be [=table_size=](|store|, |tableaddr|). + 1. Let (limits, |elementType|) be [=table_type=](|tableaddr|). + 1. If |value| is missing, + 1. Let |ref| be [=DefaultValue=](|elementType|). + 1. Otherwise, + 1. Let |ref| be [=?=] [=ToWebAssemblyValue=](|value|, |elementType|). + 1. Let |result| be [=table_grow=](|store|, |tableaddr|, |delta|, |ref|). + 1. If |result| is [=error=], throw a {{RangeError}} exception. + + Note: The above exception can happen due to either insufficient memory or an invalid size parameter. + + 1. Set the [=surrounding agent=]'s [=associated store=] to |result|. + 1. Return |initialSize|. +
+ +
+ The getter of the length attribute of {{Table}}, when invoked, performs the following steps: + 1. Let |tableaddr| be **this**.\[[Table]]. + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Return [=table_size=](|store|, |tableaddr|). +
+ +
+ The get(|index|) method, when invoked, performs the following steps: + 1. Let |tableaddr| be **this**.\[[Table]]. + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Let |result| be [=table_read=](|store|, |tableaddr|, |index|). + 1. If |result| is [=error=], throw a {{RangeError}} exception. + 1. Return [=ToJSValue=](|result|). +
+ +
+ The set(|index|, |value|) method, when invoked, performs the following steps: + 1. Let |tableaddr| be **this**.\[[Table]]. + 1. Let (limits, |elementType|) be [=table_type=](|tableaddr|). + 1. If |value| is missing, + 1. Let |ref| be [=DefaultValue=](|elementType|). + 1. Otherwise, + 1. Let |ref| be [=?=] [=ToWebAssemblyValue=](|value|, |elementType|). + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Let |store| be [=table_write=](|store|, |tableaddr|, |index|, |ref|). + 1. If |store| is [=error=], throw a {{RangeError}} exception. + 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. +
+ +

Globals

+ +
+enum ValueType {
+  "i32",
+  "i64",
+  "f32",
+  "f64",
+  "v128",
+  "externref",
+  "anyfunc",
+};
+
+ +Note: this type may be extended with additional cases in future versions of WebAssembly. + +
+dictionary GlobalDescriptor {
+  required ValueType value;
+  boolean mutable = false;
+};
+
+[LegacyNamespace=WebAssembly, Exposed=*]
+interface Global {
+  constructor(GlobalDescriptor descriptor, optional any v);
+  any valueOf();
+  attribute any value;
+};
+
+ +A {{Global}} object represents a single [=global instance=] +which can be simultaneously referenced by multiple {{Instance}} objects. Each +{{Global}} object has one internal slot: + + * \[[Global]] : a [=global address=] + +
+ To initialize a global object |global| from a [=global address=] |globaladdr|, perform the following steps: + 1. Let |map| be the [=surrounding agent=]'s associated [=Global object cache=]. + 1. Assert: |map|[|globaladdr|] doesn't [=map/exist=]. + 1. Set |global|.\[[Global]] to |globaladdr|. + 1. [=map/Set=] |map|[|globaladdr|] to |global|. +
+ +
+ To create a global object from a [=global address=] |globaladdr|, perform the following steps: + 1. Let |map| be the current [=agent=]'s associated [=Global object cache=]. + 1. If |map|[|globaladdr|] [=map/exists=], + 1. Return |map|[|globaladdr|]. + 1. Let |global| be a [=/new=] {{Global}}. + 1. [=initialize a global object|Initialize=] |global| from |globaladdr|. + 1. Return |global|. +
+ +
+ The algorithm ToValueType(|s|) performs the following steps: + 1. If |s| equals "i32", return [=i32=]. + 1. If |s| equals "i64", return [=i64=]. + 1. If |s| equals "f32", return [=f32=]. + 1. If |s| equals "f64", return [=f64=]. + 1. If |s| equals "v128", return [=v128=]. + 1. If |s| equals "anyfunc", return [=funcref=]. + 1. If |s| equals "externref", return [=externref=]. + 1. Assert: This step is not reached. +
+ +
+ The algorithm DefaultValue(|valuetype|) performs the following steps: + 1. If |valuetype| equals [=i32=], return [=i32.const=] 0. + 1. If |valuetype| equals [=i64=], return [=i64.const=] 0. + 1. If |valuetype| equals [=f32=], return [=f32.const=] 0. + 1. If |valuetype| equals [=f64=], return [=f64.const=] 0. + 1. If |valuetype| equals [=funcref=], return [=ref.null=] [=funcref=]. + 1. If |valuetype| equals [=externref=], return [=ToWebAssemblyValue=](undefined, |valuetype|). + 1. Assert: This step is not reached. +
+ +
+ The Global(|descriptor|, |v|) constructor, when invoked, performs the following steps: + 1. Let |mutable| be |descriptor|["mutable"]. + 1. Let |valuetype| be [=ToValueType=](|descriptor|["value"]). + 1. If |valuetype| is [=v128=], + 1. Throw a {{TypeError}} exception. + 1. If |v| is missing, + 1. Let |value| be [=DefaultValue=](|valuetype|). + 1. Otherwise, + 1. Let |value| be [=ToWebAssemblyValue=](|v|, |valuetype|). + 1. If |mutable| is true, let |globaltype| be [=var=] |valuetype|; otherwise, let |globaltype| be [=const=] |valuetype|. + 1. Let |store| be the current agent's [=associated store=]. + 1. Let (|store|, |globaladdr|) be [=global_alloc=](|store|, |globaltype|, |value|). + 1. Set the current agent's [=associated store=] to |store|. + 1. [=initialize a global object|Initialize=] **this** from |globaladdr|. +
+ +
+ The algorithm GetGlobalValue({{Global}} |global|) performs the following steps: + 1. Let |store| be the current agent's [=associated store=]. + 1. Let |globaladdr| be |global|.\[[Global]]. + 1. Let |globaltype| be [=global_type=](|store|, |globaladdr|). + 1. If |globaltype| is of the form mut [=v128=], throw a {{TypeError}}. + 1. Let |value| be [=global_read=](|store|, |globaladdr|). + 1. Return [=ToJSValue=](|value|). +
+ +
+ The getter of the value attribute of {{Global}}, when invoked, performs the following steps: + 1. Return [=GetGlobalValue=](**this**). + + The setter of the value attribute of {{Global}}, when invoked, performs the following steps: + 1. Let |store| be the current agent's [=associated store=]. + 1. Let |globaladdr| be **this**.\[[Global]]. + 1. Let |mut| |valuetype| be [=global_type=](|store|, |globaladdr|). + 1. If |valuetype| is [=v128=], throw a {{TypeError}}. + 1. If |mut| is [=const=], throw a {{TypeError}}. + 1. Let |value| be [=ToWebAssemblyValue=](**the given value**, |valuetype|). + 1. Let |store| be [=global_write=](|store|, |globaladdr|, |value|). + 1. If |store| is [=error=], throw a {{RangeError}} exception. + 1. Set the current agent's [=associated store=] to |store|. +
+ +
+ The valueOf() method, when invoked, performs the following steps: + 1. Return [=GetGlobalValue=](**this**). +
+ +

Exported Functions

+ +A WebAssembly function is made available in JavaScript as an Exported Function. +Exported Functions are [=Built-in Function Objects=] which are not constructors, and which have a \[[FunctionAddress]] internal slot. +This slot holds a [=function address=] relative to the [=surrounding agent=]'s [=associated store=]. + +
+ The name of the WebAssembly function |funcaddr| is found by performing the following steps: + + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Let |funcinst| be |store|.funcs[|funcaddr|]. + 1. If |funcinst| is of the form {type functype, hostcode |hostfunc|}, + 1. Assert: |hostfunc| is a JavaScript object and [$IsCallable$](|hostfunc|) is true. + 1. Let |index| be the [=index of the host function=] |funcaddr|. + 1. Otherwise, + 1. Let |moduleinst| be |funcinst|.module. + 1. Assert: |funcaddr| is contained in |moduleinst|.funcaddrs. + 1. Let |index| be the index of |moduleinst|.funcaddrs where |funcaddr| is found. + 1. Return [=!=] [$ToString$](|index|). +
+ +
+ To create a new Exported Function from a WebAssembly [=function address=] |funcaddr|, perform the following steps: + + 1. Let |map| be the [=surrounding agent=]'s associated [=Exported Function cache=]. + 1. If |map|[|funcaddr|] [=map/exists=], + 1. Return |map|[|funcaddr|]. + 1. Let |steps| be "[=call an Exported Function|call the Exported Function=] |funcaddr| with arguments." + 1. Let |realm| be the [=current Realm=]. + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Let |functype| be [=func_type=](|store|, |funcaddr|). + 1. Let [|paramTypes|] → [resultTypes] be |functype|. + 1. Let |arity| be |paramTypes|'s [=list/size=]. + 1. Let |name| be the [=name of the WebAssembly function=] |funcaddr|. + 1. Let |function| be [=!=] [$CreateBuiltinFunction$](|steps|, |arity|, |name|, « \[[FunctionAddress]] », |realm|). + 1. Set |function|.\[[FunctionAddress]] to |funcaddr|. + 1. [=map/Set=] |map|[|funcaddr|] to |function|. + 1. Return |function|. +
+ +
+ To call an Exported Function with [=function address=] |funcaddr| and a [=list=] of JavaScript arguments |argValues|, perform the following steps: + + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Let |functype| be [=func_type=](|store|, |funcaddr|). + 1. Let [|parameters|] → [|results|] be |functype|. + 1. If |parameters| or |results| contain [=v128=], throw a {{TypeError}}. + + Note: the above error is thrown each time the \[[Call]] method is invoked. + 1. Let |args| be « ». + 1. Let |i| be 0. + 1. [=list/iterate|For each=] |t| of |parameters|, + 1. If |argValues|'s [=list/size=] > |i|, let |arg| be |argValues|[|i|]. + 1. Otherwise, let |arg| be undefined. + 1. [=list/Append=] [=ToWebAssemblyValue=](|arg|, |t|) to |args|. + 1. Set |i| to |i| + 1. + 1. Let (|store|, |ret|) be the result of [=func_invoke=](|store|, |funcaddr|, |args|). + 1. Note: The expectation is that [=func_invoke=] will be updated to return (|store|, val* | [=error=] | (exception |exntag| |payload| |opaqueData|)). + 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. + 1. If |ret| is [=error=], throw an exception. This exception should be a WebAssembly {{RuntimeError}} exception, unless otherwise indicated by the WebAssembly error mapping. + 1. If |ret| is exception |exntag| |payload| |opaqueData|, then + 1. If |opaqueData| is not [=ref.null=] [=externref=], + 1. Let « [=ref.extern=] |externaddr| » be |opaqueData|. + 1. Throw the result of [=retrieving an extern value=] from |externaddr|. + 1. Let |exception| be [=create an Exception object|a new Exception=] for |exntag| and |payload|. + 1. Throw |exception|. + 1. Let |outArity| be the [=list/size=] of |ret|. + 1. If |outArity| is 0, return undefined. + 1. Otherwise, if |outArity| is 1, return [=ToJSValue=](|ret|[0]). + 1. Otherwise, + 1. Let |values| be « ». + 1. [=list/iterate|For each=] |r| of |ret|, + 1. [=list/Append=] [=ToJSValue=](|r|) to |values|. + 1. Return [$CreateArrayFromList$](|values|). +
+ +Note: [=call an Exported Function|Calling an Exported Function=] executes in the \[[Realm]] of the callee Exported Function, as per the definition of [=built-in function objects=]. + +Note: Exported Functions do not have a \[[Construct]] method and thus it is not possible to call one with the `new` operator. + +
+ To run a host function from the JavaScript object |func|, type |functype|, and [=list=] of [=WebAssembly values=] |arguments|, perform the following steps: + + 1. Let [|parameters|] → [|results|] be |functype|. + 1. If |parameters| or |results| contain [=v128=], throw a {{TypeError}}. + 1. Let |jsArguments| be « ». + 1. [=list/iterate|For each=] |arg| of |arguments|, + 1. [=list/Append=] [=!=] [=ToJSValue=](|arg|) to |jsArguments|. + 1. Let |ret| be [=?=] [$Call$](|func|, undefined, |jsArguments|). + 1. Let |resultsSize| be |results|'s [=list/size=]. + 1. If |resultsSize| is 0, return « ». + 1. Otherwise, if |resultsSize| is 1, return « [=?=] [=ToWebAssemblyValue=](|ret|, |results|[0]) ». + 1. Otherwise, + 1. Let |method| be [=?=] [$GetMethod$](|ret|, {{@@iterator}}). + 1. If |method| is undefined, [=throw=] a {{TypeError}}. + 1. Let |values| be [=?=] [$IterableToList$](|ret|, |method|). + 1. Let |wasmValues| be a new, empty [=list=]. + 1. If |values|'s [=list/size=] is not |resultsSize|, throw a {{TypeError}} exception. + 1. For each |value| and |resultType| in |values| and |results|, paired linearly, + 1. [=list/Append=] [=ToWebAssemblyValue=](|value|, |resultType|) to |wasmValues|. + 1. Return |wasmValues|. +
+ +
+ To create a host function from the JavaScript object |func| and type |functype|, perform the following steps: + + 1. Assert: [$IsCallable$](|func|). + 1. Let |stored settings| be the incumbent settings object. + 1. Let |hostfunc| be a [=host function=] which performs the following steps when called with arguments |arguments|: + 1. Let |realm| be |func|'s [=associated Realm=]. + 1. Let |relevant settings| be |realm|'s [=realm/settings object=]. + 1. [=Prepare to run script=] with |relevant settings|. + 1. [=Prepare to run a callback=] with |stored settings|. + 1. Let |result| be the result of [=run a host function|running a host function=] from |func|, |functype|, and |arguments|. + 1. [=Clean up after running a callback=] with |stored settings|. + 1. [=Clean up after running script=] with |relevant settings|. + 1. Assert: |result|.\[[Type]] is throw or normal. + 1. If |result|.\[[Type]] is throw, then: + 1. Let |v| be |result|.\[[Value]]. + 1. If |v| [=implements=] {{Exception}}, + 1. Let |type| be |v|.\[[Type]]. + 1. Let |payload| be |v|.\[[Payload]]. + 1. Otherwise, + 1. Let |type| be the [=JavaScript exception tag=]. + 1. Let |payload| be « ». + 1. Let |opaqueData| be [=ToWebAssemblyValue=](|v|, [=externref=]) + 1. [=WebAssembly/Throw=] with |type|, |payload| and |opaqueData|. + 1. Otherwise, return |result|.\[[Value]]. + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Let (|store|, |funcaddr|) be [=func_alloc=](|store|, |functype|, |hostfunc|). + 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. + 1. Return |funcaddr|. +
+ +
+The algorithm ToJSValue(|w|) coerces a [=WebAssembly value=] to a JavaScript value by performing the following steps: + +1. Assert: |w| is not of the form [=v128.const=] v128. +1. If |w| is of the form [=i64.const=] |i64|, + 1. Let |v| be [=signed_64=](|i64|). + 1. Return [=ℤ=](|v| interpreted as a mathematical value). +1. If |w| is of the form [=i32.const=] |i32|, return [=𝔽=]([=signed_32=](|i32| interpreted as a mathematical value)). +1. If |w| is of the form [=f32.const=] |f32|, + 1. If |f32| is [=+∞=] or [=−∞=], return **+∞**𝔽 or **-∞**𝔽, respectively. + 1. If |f32| is [=nan=], return **NaN**. + 1. Return [=𝔽=](|f32| interpreted as a mathematical value). +1. If |w| is of the form [=f64.const=] |f64|, + 1. If |f64| is [=+∞=] or [=−∞=], return **+∞**𝔽 or **-∞**𝔽, respectively. + 1. If |f64| is [=nan=], return **NaN**. + 1. Return [=𝔽=](|f64| interpreted as a mathematical value). +1. If |w| is of the form [=ref.null=] t, return null. +1. If |w| is of the form [=ref.func=] |funcaddr|, return the result of creating [=a new Exported Function=] from |funcaddr|. +1. If |w| is of the form [=ref.extern=] |externaddr|, return the result of [=retrieving an extern value=] from |externaddr|. + +Note: Number values which are equal to NaN may have various observable NaN payloads; see [$NumericToRawBytes$] for details. +
+ +
+ +For retrieving an extern value from an [=extern address=] |externaddr|, perform the following steps: + +1. Let |map| be the [=surrounding agent=]'s associated [=extern value cache=]. +1. Assert: |map|[|externaddr|] [=map/exists=]. +1. Return |map|[|externaddr|]. + +
+ +
+The algorithm ToWebAssemblyValue(|v|, |type|) coerces a JavaScript value to a [=WebAssembly value=] by performing the following steps: + +1. Assert: |type| is not [=v128=]. +1. If |type| is [=i64=], + 1. Let |i64| be [=?=] [$ToBigInt64$](|v|). + 1. Return [=i64.const=] |i64|. +1. If |type| is [=i32=], + 1. Let |i32| be [=?=] [$ToInt32$](|v|). + 1. Return [=i32.const=] |i32|. +1. If |type| is [=f32=], + 1. Let |number| be [=?=] [$ToNumber$](|v|). + 1. If |number| is **NaN**, + 1. Let |n| be an implementation-defined integer such that [=canon=]32 ≤ |n| < 2[=signif=](32). + 1. Let |f32| be [=nan=](n). + 1. Otherwise, + 1. Let |f32| be |number| rounded to the nearest representable value using IEEE 754-2008 round to nearest, ties to even mode. [[IEEE-754]] + 1. Return [=f32.const=] |f32|. +1. If |type| is [=f64=], + 1. Let |number| be [=?=] [$ToNumber$](|v|). + 1. If |number| is **NaN**, + 1. Let |n| be an implementation-defined integer such that [=canon=]64 ≤ |n| < 2[=signif=](64). + 1. Let |f64| be [=nan=](n). + 1. Otherwise, + 1. Let |f64| be |number|. + 1. Return [=f64.const=] |f64|. +1. If |type| is [=funcref=], + 1. If |v| is null, + 1. Return [=ref.null=] [=funcref=]. + 1. If |v| is an [=Exported Function=], + 1. Let |funcaddr| be the value of |v|'s \[[FunctionAddress]] internal slot. + 1. Return [=ref.func=] |funcaddr|. + 1. Throw a {{TypeError}}. +1. If |type| is [=externref=], + 1. If |v| is null, + 1. Return [=ref.null=] [=externref=]. + 1. Let |map| be the [=surrounding agent=]'s associated [=extern value cache=]. + 1. If a [=extern address=] |externaddr| exists such that |map|[|externaddr|] is the same as |v|, + 1. Return [=ref.extern=] |externaddr|. + 1. Let [=extern address=] |externaddr| be the smallest address such that |map|[|externaddr|] [=map/exists=] is false. + 1. [=map/Set=] |map|[|externaddr|] to |v|. + 1. Return [=ref.extern=] |externaddr|. +1. Assert: This step is not reached. + +
+ +

Tags

+ +The tag_alloc(|store|, |parameters|) algorithm creates a new [=tag address=] for |parameters| in |store| and returns the updated store and the [=tag address=]. + +The tag_parameters(|store|, |tagAddress|) algorithm returns the [=list=] of types for |tagAddress| in |store|. + +

Exception types

+ +
+dictionary TagType {
+  required sequence<ValueType> parameters;
+};
+
+[LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)]
+interface Tag {
+  constructor(TagType type);
+  TagType type();
+};
+
+ +A {{Tag}} value represents a type of exception. + +
+ +To initialize a Tag object |tag| from a [=tag address=] |tagAddress|, perform the following steps: + +1. Let |map| be the [=surrounding agent=]'s associated [=Tag object cache=]. +1. Assert: |map|[|tagAddress|] doesn't [=map/exist=]. +1. Set |tag|.\[[Address]] to |tagAddress|. +1. [=map/Set=] |map|[|tagAddress|] to |tag|. + +
+ +
+ +To create a Tag object from a [=tag address=] |tagAddress|, perform the following steps: + +1. Let |map| be the [=surrounding agent=]'s associated [=Tag object cache=]. +1. If |map|[|tagAddress|] [=map/exists=], + 1. Return |map|[|tagAddress|]. +1. Let |tag| be a [=new=] {{Tag}}. +1. [=initialize a Tag object|Initialize=] |tag| from |tagAddress|. +1. Return |tag|. + +
+ +
+ +The new Tag(|type|) constructor steps are: + +1. Let |parameters| be |type|["parameters"]. +1. Let |wasmParameters| be «». +1. [=list/iterate|For each=] |type| of |parameters|, + 1. [=list/Append=] [=ToValueType=](|type|) to |wasmParameters|. +1. Let |store| be the current agent's [=associated store=]. +1. Let (|store|, |tagAddress|) be [=tag_alloc=](|store|, |wasmParameters|). +1. Set the current agent's [=associated store=] to |store|. +1. [=initialize a Tag object|Initialize=] **this** from |tagAddress|. + +
+ +
+ +The type() method steps are: + +1. Let |store| be the [=surrounding agent=]'s [=associated store=]. +1. Let |parameters| be [=tag_parameters=](|store|, **this**.\[[Address]]). +1. Let |idlParameters| be «». +1. [=list/iterate|For each=] |type| of |parameters|, + 1. [=list/Append=] [$FromValueType$](|type|) to |idlParameters|. +1. Return «[ "{{TagType/parameters}}" → |idlParameters| ]». + +Advisement: This method is only expected to be implemented or shipped when both this proposal and the Type Reflection proposal are implemented or shipped (respectively). + +
+ +

Runtime exceptions

+ +
+dictionary ExceptionOptions {
+  boolean traceStack = false;
+};
+
+[LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)]
+interface Exception {
+  constructor(Tag exceptionTag, sequence<any> payload, optional ExceptionOptions options = {});
+  any getArg(Tag exceptionTag, [EnforceRange] unsigned long index);
+  boolean is(Tag exceptionTag);
+  readonly attribute (DOMString or undefined) stack;
+};
+
+ +An {{Exception}} value represents an exception. + +
+ +To create an Exception object from a [=tag address=] |tagAddress| and a [=list=] of +WebAssembly values |payload|, perform the following steps: + +1. Let |store| be the [=surrounding agent=]'s [=associated store=]. +1. Let |types| be [=tag_parameters=](|store|, |tagAddress|). +1. Assert: |types|'s [=list/size=] is |payload|'s [=list/size=]. +1. [=list/iterate|For each=] |value| and |resultType| of |payload| and |types|, paired linearly, + 1. Assert: |value|'s type matches |resultType|. +1. Let |exception| be a [=new=] {{Exception}}. +1. Set |exception|.\[[Type]] to |tagAddress|. +1. Set |exception|.\[[Payload]] to |payload|. +1. Set |exception|.\[[Stack]] to undefined. +1. Return |exception|. + +
+ +
+ +The new Exception(|exceptionTag|, |payload|, |options|) +constructor steps are: + +1. Let |store| be the [=surrounding agent=]'s [=associated store=]. +1. Let |types| be [=tag_parameters=](|store|, |exceptionTag|.\[[Address]]). +1. If |types|'s [=list/size=] is not |payload|'s [=list/size=], + 1. Throw a {{TypeError}}. +1. Let |wasmPayload| be « ». +1. [=list/iterate|For each=] |value| and |resultType| of |payload| and |types|, paired linearly, + 1. [=list/Append=] ? [=ToWebAssemblyValue=](|value|, |resultType|) to |wasmPayload|. +1. Set **this**.\[[Type]] to |exceptionTag|.\[[Address]]. +1. Set **this**.\[[Payload]] to |wasmPayload|. +1. If |options|["traceStack"] is true, + 1. Set **this**.\[[Stack]] to either a {{DOMString}} representation of the current call stack or undefined. +1. Otherwise, + 1. Set **this**.\[[Stack]] to undefined. + +
+ +
+ +The getArg(|exceptionTag|, |index|) method steps are: + +1. If **this**.\[[Type]] is not equal to |exceptionTag|.\[[Address]], + 1. Throw a {{TypeError}}. +1. Let |payload| be **this**.\[[Payload]]. +1. If |index| ≥ |payload|'s [=list/size=], + 1. Throw a {{RangeError}}. +1. Return [=ToJSValue=](|payload|[|index|]). + +
+ +
+ +The is(|exceptionTag|) method steps are: + +1. If **this**.\[[Type]] is not equal to |exceptionTag|.\[[Address]], + 1. Return false. +1. Return true. + +
+ +
+ +The stack getter steps are: + +1. Return **this**.\[[Stack]]. + +
+ +

JavaScript exceptions

+ +The JavaScript exception tag is a [=tag address=] reserved by this +specification to distinguish exceptions originating from JavaScript. + +For any [=associated store=] |store|, the result of +[=tag_parameters=](|store|, [=JavaScript exception tag=]) must be « ». + +
+ +To throw with a [=tag address=] |type|, a matching [=list=] of WebAssembly values |payload|, and an [=externref=] |opaqueData|, perform the following steps: + +1. Unwind the stack until reaching the *catching try block* given |type|. +1. Invoke the catch block with |payload| and |opaqueData|. + +Note: This algorithm is expected to be moved into the core specification. + +
+ +

Error Objects

+ +WebAssembly defines the following Error classes: CompileError, LinkError, and RuntimeError. + +
+When the [=namespace object=] for the {{WebAssembly}} namespace is [=create a namespace object|created=], the following steps must be run: + +1. Let |namespaceObject| be the [=namespace object=]. +1. [=list/iterate|For each=] |error| of « "CompileError", "LinkError", "RuntimeError" », + 1. Let |constructor| be a new object, implementing the [=NativeError Object Structure=], with NativeError set to |error|. + 1. [=!=] [$CreateMethodProperty$](|namespaceObject|, |error|, |constructor|). + +
+ +Note: This defines {{CompileError}}, {{LinkError}}, and {{RuntimeError}} classes on the {{WebAssembly}} namespace, which are produced by the APIs defined in this specification. +They expose the same interface as native JavaScript errors like {{TypeError}} and {{RangeError}}. + +Note: It is not currently possible to define this behavior using Web IDL. + + +

Error Condition Mappings to JavaScript

+ +Running WebAssembly programs encounter certain events which halt execution of the WebAssembly code. +WebAssembly code (currently) +has no way to catch these conditions and thus an exception will necessarily +propagate to the enclosing non-WebAssembly caller (whether it is a browser, +JavaScript or another runtime system) where it is handled like a normal JavaScript exception. + +If WebAssembly calls JavaScript via import and the JavaScript throws an +exception, the exception is propagated through the WebAssembly activation to the +enclosing caller. + +Because JavaScript exceptions can be handled, and JavaScript can continue to +call WebAssembly exports after a trap has been handled, traps do not, in +general, prevent future execution. + +

Stack Overflow

+ +Whenever a stack overflow occurs in +WebAssembly code, the same class of exception is thrown as for a stack overflow in +JavaScript. The particular exception here is implementation-defined in both cases. + +Note: ECMAScript doesn't specify any sort of behavior on stack overflow; implementations have been observed to throw {{RangeError}}, InternalError or Error. Any is valid here. + +

Out of Memory

+ +Whenever validation, compilation or instantiation run out of memory, the +same class of exception is thrown as for out of memory conditions in JavaScript. +The particular exception here is implementation-defined in both cases. + +Note: ECMAScript doesn't specify any sort of behavior on out-of-memory conditions; implementations have been observed to throw OOMError and to crash. Either is valid here. + +
+ A failed allocation of a large table or memory may either result in + - a {{RangeError}}, as specified in the {{Memory}} {{Memory/grow()}} and {{Table}} {{Table/grow()}} operations + - returning -1 as the [=memory.grow=] instruction + - UA-specific OOM behavior as described in this section. + In a future revision, we may reconsider more reliable and recoverable errors for allocations of large amounts of memory. + + See [Issue 879](https://github.com/WebAssembly/spec/issues/879) for further discussion. +
+ +

Implementation-defined Limits

+ +The WebAssembly core specification allows an implementation to define limits on the syntactic structure of the module. +While each embedding of WebAssembly may choose to define its own limits, for predictability the standard WebAssembly JavaScript Interface described in this document defines the following exact limits. +An implementation must reject a module that exceeds one of the following limits with a {{CompileError}}: +In practice, an implementation may run out of resources for valid modules below these limits. + + + +An implementation must throw a {{RuntimeError}} if one of the following limits is exceeded during runtime: +In practice, an implementation may run out of resources for valid modules below these limits. + + + +

Security and Privacy Considerations

+ +

This section is non-normative.

+ +This document defines a host environment for WebAssembly. It enables a WebAssembly instance to [=import=] JavaScript objects and functions from an [=read the imports|import object=], but otherwise provides no access to the embedding environment. Thus a WebAssembly instance is bound to the same constraints as JavaScript.