blob: a9dc728d4b42530064a430d166225ec13b58bb51 [file] [log] [blame] [edit]
<pre class='metadata'>
Title: WebAssembly JavaScript Interface
Shortname: wasm-js-api
Group: wasm
Status: ED
Issue Tracking: GitHub https://github.com/WebAssembly/spec/issues
Level: 2
TR: https://www.w3.org/TR/wasm-js-api-2/
ED: https://webassembly.github.io/spec/js-api/
Implementation Report: https://webassembly.org/features/
Editor: Ms2ger, w3cid 46309, 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
Date: now
</pre>
<pre class='biblio'>
{
"WEBASSEMBLY": {
"href": "https://webassembly.github.io/spec/core/",
"title": "WebAssembly Core Specification",
"publisher": "W3C WebAssembly Community Group",
"status": "Draft"
},
"WASMWEB": {
"href": "https://webassembly.github.io/spec/web-api/",
"title": "WebAssembly Web API Specification",
"publisher": "W3C WebAssembly Community Group",
"status": "Draft"
}
}
</pre>
<pre class="anchors">
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-string-object
text: String
url: sec-returnifabrupt-shorthands
text: !
text: ?
url: sec-ecmascript-language-types-bigint-type
text: is a BigInt
text: is not a BigInt
url: sec-ecmascript-language-types-boolean-type
text: is a Boolean
text: is not a Boolean
url: sec-ecmascript-language-types-number-type
text: is a Number
text: is not a Number
url: sec-ecmascript-language-types-string-type
text: is a String
text: is not a String
url: sec-ecmascript-language-types-symbol-type
text: is a Symbol
text: is not a Symbol
url: sec-object-type
text: is an Object
text: is not an Object
text: current Realm; url: current-realm
text: ObjectCreate; url: sec-objectcreate
text: CreateBuiltinFunction; url: sec-createbuiltinfunction
text: SetFunctionName; url: sec-setfunctionname
text: SetFunctionLength; url: sec-setfunctionlength
text: the Number value; url: sec-ecmascript-language-types-number-type
text: is a Number; url: sec-ecmascript-language-types-number-type
text: is a BigInt; url: sec-ecmascript-language-types-bigint-type
text: NumberToRawBytes; url: sec-numbertorawbytes
text: Built-in Function Objects; url: sec-built-in-function-objects
text: NativeError Object Structure; url: sec-nativeerror-object-structure
text: CreateArrayFromList; url: sec-createarrayfromlist
text: GetMethod; url: sec-getmethod
text: IterableToList; url: sec-iterabletolist
text: ToBigInt64; url: #sec-tobigint64
text: BigInt; url: #sec-ecmascript-language-types-bigint-type
text: MakeBasicObject; url: #sec-makebasicobject
text: ℝ; url: #ℝ
text: Built-in Function Objects; url: sec-built-in-function-objects
text: NativeError Object Structure; url: sec-nativeerror-object-structure
text: 𝔽; url: #𝔽
text: ℤ; url: #ℤ
text: mathematical value; url: #mathematical-value
text: SameValue; url: sec-samevalue
text: IsStrictlyEqual; url: sec-isstrictlyequal
text: IsLessThan; url: sec-islessthan
text: String.fromCharCode; url: sec-string.fromcharcode
text: String.fromCodePoint; url: sec-string.fromcodepoint
text: String.prototype.charCodeAt; url: sec-string.prototype.charcodeat
text: String.prototype.codePointAt; url: sec-string.prototype.codepointat
text: String.prototype.concat; url: sec-string.prototype.concat
text: String.prototype.substring; url: sec-string.prototype.substring
text: Array; url: sec-array-exotic-objects
text: BigInt; url: sec-ecmascript-language-types-bigint-type
urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: dfn
text: embedding interface; url: appending/embedding.html
text: scope; url: intro/introduction.html#scope
url: valid/modules.html#valid-module
text: valid
text: WebAssembly module validation
text: valid limits; url: valid/types.html#valid-limits
text: valid memtype; url: valid/types.html#valid-memtype
text: valid tabletype; url: valid/types.html#valid-tabletype
urlPrefix: valid/matching.html; for: matches
text: valtype; url: #match-valtype
text: reftype; url: #match-reftype
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.i31
text: ref.array
text: ref.struct
text: ref.func
text: ref.host
text: ref.extern
text: ref.exn
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: ref_type; url: appendix/embedding.html#embed-ref-type
text: val_default; url: appendix/embedding.html#embed-val-default
text: match_valtype; url: appendix/embedding.html#embed-match-valtype
text: match_externtype; url: appendix/embedding.html#embed-match-externtype
text: error; url: appendix/embedding.html#embed-error
text: store; url: exec/runtime.html#syntax-store
text: address type; url: syntax/types.html#syntax-addrtype
text: limits; url: syntax/types.html#syntax-limits
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 type; url: syntax/types.html#syntax-memtype
text: memory address; url: exec/runtime.html#syntax-memaddr
text: global address; url: exec/runtime.html#syntax-globaladdr
text: tag address; url: exec/runtime.html#syntax-tagaddr
text: tag type; url: syntax/types.html#syntax-tagtype
text: struct address; url: exec/runtime.html#syntax-structaddr
text: array address; url: exec/runtime.html#syntax-arrayaddr
text: exception address; url: exec/runtime.html#syntax-exnaddr
text: host address; url: exec/runtime.html#syntax-hostaddr
text: extern address; url: exec/runtime.html#syntax-externaddr
text: page size; url: exec/runtime.html#page-size
text: tag_alloc; url: appendix/embedding.html#embed-tag-alloc
text: tag_type; url: appendix/embedding.html#embed-tag-type
text: exn_alloc; url: appendix/embedding.html#embed-exn-alloc
text: exn_tag; url: appendix/embedding.html#embed-exn-tag
text: exn_read; url: appendix/embedding.html#embed-exn-read
url: syntax/values.html#syntax-int
text: u32
text: u64
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: exnref
text: externref
text: ref
url: syntax/types.html#heap-types; for: heap-type
text: extern
text: func
text: i31
text: any
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; for: external-type
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_31; url: exec/numerics.html#aux-signed
text: signed_32; url: exec/numerics.html#aux-signed
text: memory.grow; url: exec/instructions.html#exec-memory-grow
text: throw_ref; url: exec/instructions.html#exec-throw-ref
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
text: [EnforceRange]; url: #EnforceRange
text: unsigned long; url: #idl-unsigned-long
text: js-unsigned-long; url: #js-unsigned-long
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
urlPrefix: https://tc39.es/proposal-resizablearraybuffer/; spec: ResizableArrayBuffer proposal
type: dfn
text: handled; url: sec-hostresizearraybuffer
text: IsFixedLengthArrayBuffer; url: sec-isfixedarraybuffer
text: HostResizeArrayBuffer; url: sec-hostresizearraybuffer
</pre>
<pre class='link-defaults'>
spec:infra; type:dfn; text:list
spec:ecma-262; type:exception; for:ECMAScript; text:Error
spec:ecmascript; type:exception; for:ECMAScript; text:TypeError
spec:ecmascript; type:exception; for:ECMAScript; text:RangeError
spec:ecmascript; type:interface; for:ECMAScript; text:ArrayBuffer
spec:ecmascript; type:dfn; text:agent
spec:webidl; type:dfn; text:resolve
</pre>
<style>
emu-const {
font-family: serif;
}
</style>
<h2 id="intro">Introduction</h2>
By design, the [=scope=] of the WebAssembly core specification [[WEBASSEMBLY]] does not include a description of how WebAssembly programs interact with their surrounding execution environment.
Instead it defines an abstract [=embedding interface=] between WebAssembly and its environment, (called the *embedder*).
It is only through this interface that an embedder interacts with the semantics of WebAssembly, and the embedder implements the connection between its host environment and the embedding API.
This document describes the embedding of WebAssembly into JavaScript [[ECMASCRIPT]] environments, including how WebAssembly modules can be constructed and instantiated, how imported and exported functions are called, how data is exchanged, and how errors are handled.
When the JavaScript environment is itself embedded in a Web browser, the Web API spec [[WASMWEB]] describes additional behavior relevant to the Web environment.
<h2 id="sample">Sample API Usage</h2>
<p><em>This section is non-normative.</em></p>
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()
);
```
<h2 id="notation">Notation</h2>
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.
<h2 id="webassembly-storage">Internal storage</h2>
<h3 id="store">Interaction of the WebAssembly Store with JavaScript</h3>
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 <dfn>associated store</dfn>. 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 <dfn>identified with</dfn> 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.
<h3 id="object-caches">WebAssembly JS Object Caches</h3>
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 <dfn>Memory object cache</dfn>, mapping [=memory address=]es to {{Memory}} objects.
* The <dfn>Table object cache</dfn>, mapping [=table address=]es to {{Table}} objects.
* The <dfn>Exported Function cache</dfn>, mapping [=function address=]es to [=Exported Function=] objects.
* The <dfn>Exported GC Object cache</dfn>, mapping [=struct address=]es and [=array address=]es to [=Exported GC Object=] objects.
* The <dfn>Global object cache</dfn>, mapping [=global address=]es to {{Global}} objects.
* The <dfn>Tag object cache</dfn>, mapping [=tag addresses=] to {{Tag}} objects.
* The <dfn>Exception object cache</dfn>, mapping [=exception address=]es to {{Exception}} objects.
* The <dfn>Host value cache</dfn>, mapping [=host address=]es to values.
<h2 id="webassembly-namespace">The WebAssembly Namespace</h2>
<pre class="idl">
dictionary WebAssemblyInstantiatedSource {
required Module module;
required Instance instance;
};
dictionary WebAssemblyCompileOptions {
USVString? importedStringConstants;
sequence&lt;USVString> builtins;
};
[Exposed=*]
namespace WebAssembly {
boolean validate(BufferSource bytes, optional WebAssemblyCompileOptions options = {});
Promise&lt;Module> compile(BufferSource bytes, optional WebAssemblyCompileOptions options = {});
Promise&lt;WebAssemblyInstantiatedSource> instantiate(
BufferSource bytes, optional object importObject, optional WebAssemblyCompileOptions options = {});
Promise&lt;Instance> instantiate(
Module moduleObject, optional object importObject);
readonly attribute Tag JSTag;
};
</pre>
<!--
Should we include notes describing what the functions do, as the HTML spec does? It could look like this:
Note:
WebAssembly.validate(|bytes|) synchronously validates bytes of WebAssembly, returning true if the validation was successful.
WebAssembly.compile(|bytes|) asynchronously validates and complies bytes of WebAssembly into a Module.
WebAssembly.instantiate(|bytes|, |importObject|) asynchronously compiles and instantiates a WebAssembly module from bytes of source.
The WebAssembly.instantiate(|moduleObject|, |importObject|) asynchronously instantiates a compiled module.
-->
<div algorithm>
To <dfn>compile a WebAssembly module</dfn> 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|.
</div>
<div algorithm>
To <dfn>validate builtins and imported string for a WebAssembly module</dfn> from module |module|, enabled builtins |builtinSetNames|, and |importedStringModule|, perform the following steps:
1. If [=validate builtin set names|validating builtin set names=] for |builtinSetNames| is false, return false.
1. [=list/iterate|For each=] |import| of [=module_imports=](|module|),
1. If |importedStringModule| is not null and |import|[0] equals |importedStringModule|,
1. Let |importExternType| be |import|[2].
1. Let |stringExternType| be `global const (ref extern)`.
1. If [=match_externtype=](|stringExternType|, |importExternType|) is false, return false
1. Else,
1. If [=validate an import for builtins|validating a import for builtin=] with |import| and |builtinSetNames| is false, return false.
1. Return true.
</div>
<div algorithm>
The <dfn method for="WebAssembly">validate(|bytes|, |options|)</dfn> 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. Let |builtinSetNames| be |options|["builtins"].
1. Let |importedStringModule| be |options|["importedStringConstants"].
1. If [=validate builtins and imported string for a WebAssembly module|validating builtins and imported strings=] for |module| with |builtinSetNames| and |importedStringModule| returns false, return false.
1. Return true.
</div>
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]].
* \[[BuiltinSets]] : an ordered set of names of <a href="#builtins">builtin sets</a>
* \[[ImportedStringModule]] : an optional module specifier string where any string constant can be imported from.
<div algorithm>
To <dfn>construct a WebAssembly module object</dfn> from a module |module|, source bytes |bytes|, enabled builtins |builtinSetNames|, and |importedStringModule|, 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. Set |moduleObject|.\[[BuiltinSets]] to |builtinSetNames|.
1. Set |moduleObject|.\[[ImportedStringModule]] to |importedStringModule|.
1. Return |moduleObject|.
</div>
<div algorithm>
To <dfn>asynchronously compile a WebAssembly module</dfn> from source bytes |bytes| and {{WebAssemblyCompileOptions}} |options| 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. Let |builtinSetNames| be |options|["builtins"].
1. Let |importedStringModule| be |options|["importedStringConstants"].
1. If [=validate builtins and imported string for a WebAssembly module|validating builtins and imported strings=] for |module| with |builtinSetNames| and |importedStringModule| is false, reject |promise| with a {{CompileError}} exception.
1. Otherwise,
1. [=Construct a WebAssembly module object=] from |module|, |bytes|, |builtinSetNames|, |importedStringModule|, and let |moduleObject| be the result.
1. [=Resolve=] |promise| with |moduleObject|.
1. Return |promise|.
</div>
<div algorithm>
The <dfn method for="WebAssembly">compile(|bytes|, |options|)</dfn> 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| using |options| and return the result.
</div>
<div algorithm>
To <dfn>instantiate imported strings</dfn> with module |module| and |importedStringModule|, perform the following steps:
1. Assert: |importedStringModule| is not null.
1. Let |exportsObject| be [=!=] [$OrdinaryObjectCreate$](null).
1. [=list/iterate|For each=] (|moduleName|, |componentName|, |externtype|) of [=module_imports=](|module|),
1. If |moduleName| does not equal |importedStringModule|, then [=iteration/continue=].
1. Let |stringConstant| be |componentName|.
1. Let |status| be [=!=] [$CreateDataProperty$](|exportsObject|, |stringConstant|, |stringConstant|).
1. Assert: |status| is true.
1. Return |exportsObject|.
</div>
<div algorithm="read-the-imports">
To <dfn>read the imports</dfn> from a WebAssembly module |module| from imports object |importObject|, enabled builtins |builtinSetNames|, and |importedStringModule|, perform the following steps:
1. If |module|.[=imports=] [=list/is empty|is not empty=], and |importObject| is undefined, throw a {{TypeError}} exception.
1. Let |builtinOrStringImports| be the ordered map « ».
1. [=list/iterate|For each=] |builtinSetName| of |builtinSetNames|,
1. Assert: |builtinOrStringImports| does not contain |builtinSetName|
1. If |builtinSetName| does not refer to a builtin set, then [=iteration/continue=].
1. Let |exportsObject| be the result of [=instantiate a builtin set=] with |builtinSetName|
1. Let |builtinSetQualifiedName| be |builtinSetName| prefixed with "wasm:"
1. [=map/set|Set=] |builtinOrStringImports|[|builtinSetQualifiedName|] to |exportsObject|
1. If |importedStringModule| is not null,
1. Let |exportsObject| be the result of [=instantiate imported strings=] with |module| and |importedStringModule|
1. [=map/set|Set=] |builtinOrStringImports|[|importedStringModule|] to |exportsObject|
1. Let |imports| be « ».
1. [=list/iterate|For each=] (|moduleName|, |componentName|, |externtype|) of [=module_imports=](|module|),
1. If |builtinOrStringImports| [=map/exist|contains=] |moduleName|,
1. Let |o| be |builtinOrStringImports|[|moduleName|].
1. If |o| [=is not an Object=] or if |o| [=map/exist|does not contain=] |componentName|,
1. Set |o| to [=?=] [$Get$](|importObject|, |moduleName|).
1. Else,
1. Let |o| be [=?=] [$Get$](|importObject|, |moduleName|).
1. If |o| [=is not an Object=], throw a {{TypeError}} exception.
1. Let |v| be [=?=] [$Get$](|o|, |componentName|).
1. If |externtype| is of the form [=external-type/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 <dfn>index of the host function</dfn> |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 [=external-type/global=] <var ignore>mut</var> |valtype|,
1. If |v| [=implements=] {{Global}},
1. Let |globaladdr| be |v|.\[[Global]].
1. Otherwise,
1. If |valtype| is [=i64=] and |v| [=is not a BigInt=],
1. Throw a {{LinkError}} exception.
1. If |valtype| is one of [=i32=], [=f32=] or [=f64=] and |v| [=is not a Number=],
1. Throw a {{LinkError}} exception.
1. If |valtype| is [=v128=],
1. Throw a {{LinkError}} exception.
1. Let |value| be [=ToWebAssemblyValue=](|v|, |valtype|). If this operation throws a {{TypeError}}, catch it, and throw a {{LinkError}} exception.
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. Let |externglobal| be [=external value|global=] |globaladdr|.
1. [=list/Append=] |externglobal| to |imports|.
1. If |externtype| is of the form [=external-type/mem=] <var ignore>memtype</var>,
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 [=external-type/table=] <var ignore>tabletype</var>,
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 [=external-type/tag=] |attribute| <var ignore>functype</var>,
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.
</div>
<div algorithm>
To <dfn>create an exports object</dfn> 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 [=external-type/func=] <var ignore>functype</var>,
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 [=external-type/global=] <var ignore>mut</var> <var ignore>globaltype</var>,
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 [=external-type/mem=] <var ignore>memtype</var>,
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 [=external-type/table=] <var ignore>tabletype</var>,
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 [=external-type/tag=] |attribute| <var ignore>functype</var>,
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|.
</div>
<div algorithm>
To <dfn>initialize an instance object</dfn> |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|.
</div>
<div algorithm>
To <dfn>instantiate the core of a WebAssembly module</dfn> 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 <a href="#errors">the WebAssembly error mapping</a>.
1. Let (|store|, |instance|) be |result|.
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
1. Return |instance|.
</div>
<div algorithm>
To <dfn>asynchronously instantiate a WebAssembly module</dfn> 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. Let |builtinSetNames| be |moduleObject|.\[[BuiltinSets]].
1. Let |importedStringModule| be |moduleObject|.\[[ImportedStringModule]].
1. [=Read the imports=] of |module| with imports |importObject|, |builtinSetNames| and |importedStringModule|, 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|.
</div>
<div algorithm>
To <dfn>instantiate a promise of a module</dfn> |promiseOfModule| with imports |importObject|, perform the following steps:
1. Let |promise| be [=a new promise=].
1. [=React=] to |promiseOfModule|:
* If |promiseOfModule| was fulfilled with value |module|:
1. [=asynchronously instantiate a WebAssembly module|Instantiate the WebAssembly module=] |module| importing |importObject|, and let |innerPromise| be the result.
1. [=React=] to |innerPromise|:
* If |innerPromise| was fulfilled with value |instance|.
1. Let |result| be the {{WebAssemblyInstantiatedSource}} value «[ "{{WebAssemblyInstantiatedSource/module}}" → |module|, "{{WebAssemblyInstantiatedSource/instance}}" → |instance| ]».
1. [=Resolve=] |promise| with |result|.
* If |innerPromise| was rejected with reason |reason|:
1. [=Reject=] |promise| with |reason|.
* If |promiseOfModule| was rejected with reason |reason|:
1. [=Reject=] |promise| with |reason|.
1. Return |promise|.
</div>
<div algorithm>
The <dfn method for="WebAssembly">instantiate(|bytes|, |importObject|, |options|)</dfn> 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| using |options| and let |promiseOfModule| be the result.
1. [=Instantiate a promise of a module|Instantiate=] |promiseOfModule| with imports |importObject| and return the result.
</div>
<div algorithm>
The <dfn method for="WebAssembly">instantiate(|moduleObject|, |importObject|)</dfn> 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.
</div>
Note: A follow-on streaming API is documented in the <a href="https://webassembly.github.io/spec/web-api/index.html">WebAssembly Web API</a>.
The getter of the <dfn attribute for="WebAssembly">JSTag</dfn> attribute of the {{WebAssembly}} Namespace, when invoked, performs the following steps:
1. Let |JSTagAddr| be the result of [=get the JavaScript exception tag|getting the JavaScript exception tag=].
1. Let |JSTagObject| be the result of [=create a Tag object|creating a Tag object=] from |JSTagAddr|.
1. Return |JSTagObject|.
<h3 id="modules">Modules</h3>
<pre class="idl">
enum ImportExportKind {
"function",
"table",
"memory",
"global",
"tag"
};
enum AddressType {
"i32",
"i64",
};
typedef any AddressValue;
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, optional WebAssemblyCompileOptions options = {});
static sequence&lt;ModuleExportDescriptor> exports(Module moduleObject);
static sequence&lt;ModuleImportDescriptor> imports(Module moduleObject);
static sequence&lt;ArrayBuffer> customSections(Module moduleObject, DOMString sectionName);
};
</pre>
<div algorithm>
The <dfn>string value of the extern type</dfn> |type| is
* "function" if |type| is of the form [=external-type/func=] <var ignore>functype</var>
* "table" if |type| is of the form [=external-type/table=] <var ignore>tabletype</var>
* "memory" if |type| is of the form [=external-type/mem=] <var ignore>memtype</var>
* "global" if |type| is of the form [=external-type/global=] <var ignore>globaltype</var>
* "tag" if |type| is of the form [=external-type/tag=] <var ignore>tag</var>
</div>
<div algorithm>
The <dfn method for="Module">exports(|moduleObject|)</dfn> 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|.
</div>
<div algorithm>
The <dfn method for="Module">imports(|moduleObject|)</dfn> method, when invoked, performs the following steps:
1. Let |module| be |moduleObject|.\[[Module]].
1. Let |builtinSetNames| be |moduleObject|.\[[BuiltinSets]].
1. Let |importedStringModule| be |moduleObject|.\[[ImportedStringModule]].
1. Let |imports| be « ».
1. [=list/iterate|For each=] (|moduleName|, |name|, |type|) of [=module_imports=](|module|),
1. If [=find a builtin=] for (|moduleName|, |name|, |type|) and |builtinSetNames| is not null, then [=iteration/continue=].
1. If |importedStringModule| is not null and |moduleName| equals |importedStringModule|, then [=iteration/continue=].
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|.
</div>
<div algorithm>
The <dfn method for="Module">customSections(|moduleObject|, |sectionName|)</dfn> 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 <code>name</code> 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|.
</div>
<div algorithm>
The <dfn constructor for="Module">Module(|bytes|, |options|)</dfn> 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. Let |builtinSetNames| be |options|["builtins"].
1. Let |importedStringModule| be |options|["importedStringConstants"].
1. If [=validate builtins and imported string for a WebAssembly module|validating builtins and imported strings=] for |module| with |builtinSetNames| and |importedStringModule| returns false, throw a {{CompileError}} exception.
1. Set **this**.\[[Module]] to |module|.
1. Set **this**.\[[Bytes]] to |stableBytes|.
1. Set **this**.\[[BuiltinSets]] to |builtinSetNames|.
1. Set **this**.\[[ImportedStringModule]] to |importedStringModule|.
Note: Some implementations enforce a size limitation on |bytes|. Use of this API is discouraged, in favor of asynchronous APIs.
</div>
<h3 id="instances">Instances</h3>
<pre class="idl">
[LegacyNamespace=WebAssembly, Exposed=*]
interface Instance {
constructor(Module module, optional object importObject);
readonly attribute object exports;
};
</pre>
<div algorithm>
The <dfn constructor for="Instance">Instance(|module|, |importObject|)</dfn> constructor, when invoked, runs the following steps:
1. Let |module| be |module|.\[[Module]].
1. Let |builtinSetNames| be |module|.\[[BuiltinSets]].
1. Let |importedStringModule| be |module|.\[[ImportedStringModule]].
1. [=Read the imports=] of |module| with imports |importObject|, |builtinSetNames|, and |importedStringModule|, 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.
</div>
<div algorithm>
The getter of the <dfn attribute for="Instance">exports</dfn> attribute of {{Instance}} returns **this**.\[[Exports]].
</div>
<h3 id="memories">Memories</h3>
<pre class="idl">
dictionary MemoryDescriptor {
required AddressValue initial;
AddressValue maximum;
AddressType address;
};
[LegacyNamespace=WebAssembly, Exposed=*]
interface Memory {
constructor(MemoryDescriptor descriptor);
AddressValue grow(AddressValue delta);
ArrayBuffer toFixedLengthBuffer();
ArrayBuffer toResizableBuffer();
readonly attribute ArrayBuffer buffer;
};
</pre>
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
<div algorithm>
To <dfn>create a fixed length memory buffer</dfn> 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}} with the internal slots \[[ArrayBufferData]], \[[ArrayBufferByteLength]], and \[[ArrayBufferDetachKey]].
1. Set |buffer|.\[[ArrayBufferData]] to |block|.
1. Set |buffer|.\[[ArrayBufferByteLength]] to the length of |block|.
1. Set |buffer|.\[[ArrayBufferDetachKey]] to "WebAssembly.Memory".
1. Return |buffer|.
</div>
<div algorithm>
To <dfn>create a resizable memory buffer</dfn> from a [=memory address=] |memaddr| and a |maxsize|, perform the following steps:
1. Let |block| be a [=Data Block=] which is [=identified with=] the underlying memory of |memaddr|.
1. Let |length| be the length of |block|.
1. Let |buffer| be a new {{ArrayBuffer}} with the internal slots \[[ArrayBufferData]], \[[ArrayBufferByteLength]], \[[ArrayBufferMaxByteLength]], and \[[ArrayBufferDetachKey]].
1. Set |buffer|.\[[ArrayBufferData]] to |block|.
1. Set |buffer|.\[[ArrayBufferByteLength]] to |length|.
1. Set |buffer|.\[[ArrayBufferMaxByteLength]] is |maxsize|.
1. Set |buffer|.\[[ArrayBufferDetachKey]] to "WebAssembly.Memory".
1. Return |buffer|.
</div>
<div algorithm>
To <dfn>initialize a memory object</dfn> |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 fixed length memory buffer|creating a fixed length memory buffer=] from |memaddr|.
1. Set |memory|.\[[Memory]] to |memaddr|.
1. Set |memory|.\[[BufferObject]] to |buffer|.
1. [=map/Set=] |map|[|memaddr|] to |memory|.
</div>
<div algorithm>
To <dfn>create a memory object</dfn> 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|.
</div>
<div algorithm>
The <dfn constructor for="Memory">Memory(|descriptor|)</dfn> constructor, when invoked, performs the following steps:
1. If |descriptor|["address"] [=map/exists=], let |addrtype| be |descriptor|["address"]; otherwise, let |addrtype| be "i32".
1. Let |initial| be [=?=] [=AddressValueToU64=](|descriptor|["initial"], |addrtype|).
1. If |descriptor|["maximum"] [=map/exists=], let |maximum| be [=?=] [=AddressValueToU64=](|descriptor|["maximum"], |addrtype|); otherwise, let |maximum| be empty.
1. Let |memtype| be [=memory type=] |addrtype| { **min** |initial|, **max** |maximum| }.
1. If |memtype| is not [=valid memtype|valid=], throw a {{RangeError}} exception.
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|.
</div>
<div algorithm>
To <dfn>refresh the Memory buffer</dfn> 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. Let |buffer| be |memory|.\[[BufferObject]].
1. If [=IsFixedLengthArrayBuffer=](|buffer|) is true,
1. Perform [=!=] [$DetachArrayBuffer$](|buffer|, "WebAssembly.Memory").
1. Let |buffer| be the result of [=create a fixed length memory buffer|creating a fixed length memory buffer=] from |memaddr|.
1. Set |memory|.\[[BufferObject]] to |buffer|.
1. Otherwise,
1. Let |block| be a [=Data Block=] which is [=identified with=] the underlying memory of |memaddr|.
1. Set |buffer|.\[[ArrayBufferData]] to |block|.
1. Set |buffer|.\[[ArrayBufferByteLength]] to the length of |block|.
</div>
<div algorithm>
To <dfn>grow the memory buffer</dfn> associated with a [=memory address=] |memaddr| by |delta|, perform the following steps:
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
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. [=Refresh the memory buffer=] of |memaddr|.
1. Return |ret|.
</div>
<div algorithm=dom-Memory-grow>
The <dfn method for="Memory">grow(|delta|)</dfn> method, when invoked, performs the following steps:
1. Let |memaddr| be **this**.\[[Memory]].
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
1. Let |addrtype| be the [=address type=] in [=mem_type=](|store|, |memaddr|).
1. Let |delta64| be [=?=] [=AddressValueToU64=](|delta|, |addrtype|).
1. Let |ret| be the result of [=grow the memory buffer|growing the memory buffer=] associated with |memaddr| by |delta64|.
1. Return [=U64ToAddressValue=](|ret|, |addrtype|).
</div>
Immediately after a WebAssembly [=memory.grow=] instruction executes, perform the following steps:
<div algorithm="memory.grow">
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. [=Refresh the memory buffer=] of |memaddr|.
</div>
<div algorithm=dom-Memory-toFixedLengthBuffer>
The <dfn method for="Memory">toFixedLengthBuffer()</dfn> method, when invoked, performs the following steps:
1. Let |buffer| be **this**.\[[BufferObject]].
1. If [=IsFixedLengthArrayBuffer=](|buffer|) is true, return |buffer|.
1. Let |memaddr| be **this**.\[[Memory]].
1. Let |fixedBuffer| be the result of [=create a fixed length memory buffer|creating a fixed length memory buffer=] from |memaddr|.
1. Perform [=!=] [$DetachArrayBuffer$](|buffer|, "WebAssembly.Memory").
1. Set **this**.\[[BufferObject]] to |fixedBuffer|.
1. Return |fixedBuffer|.
</div>
<div algorithm=dom-Memory-toResizableBuffer>
The <dfn method for="Memory">toResizableBuffer()</dfn> method, when invoked, performs the following steps:
1. Let |memaddr| be **this**.\[[Memory]].
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
1. Let |memtype| be [=mem_type=](|store|, |memaddr|).
1. If |memtype| does not have a max,
1. [=Throw=] a {{TypeError}} exception.
1. Let |buffer| be **this**.\[[BufferObject]].
1. If [=IsFixedLengthArrayBuffer=](|buffer|) is false, return |buffer|.
1. Assert: |memtype| has a max.
1. Let |maxsize| be the max value in |memtype| * 65536.
1. Let |resizableBuffer| be the result of [=create a resizable memory buffer|creating a resizable memory buffer=] from |memaddr| and |maxsize|.
1. Perform [=!=] [$DetachArrayBuffer$](|buffer|, "WebAssembly.Memory").
1. Set **this**.\[[BufferObject]] to |resizableBuffer|.
1. Return |resizableBuffer|.
</div>
{{ArrayBuffer}} objects returned by a {{Memory}} object must have a size that is a multiple of a WebAssembly [=page size=] (the constant 65536). For this reason [=HostResizeArrayBuffer=] is redefined as follows.
<div algorithm>
The <dfn id=HostResizeArrayBuffer export>abstract operation [=HostResizeArrayBuffer=]</dfn> takes arguments |buffer| (an {{ArrayBuffer}}) and |newLength|. It performs the following steps when called.
1. If |buffer|.\[[ArrayBufferDetachKey]] is "WebAssembly.Memory",
1. Let |map| be the [=surrounding agent=]'s associated [=Memory object cache=].
1. Assert: |buffer| is the \[[BufferObject]] of exactly one value in |map|.
1. [=map/iterate|For each=] |memaddr| &rarr; |mem| in |map|,
1. If [=SameValue=](|mem|.\[[BufferObject]], |buffer|) is true,
1. Assert: |buffer|.\[[ArrayBufferByteLength]] modulo 65536 is 0.
1. Let |lengthDelta| be |newLength| - |buffer|.\[[ArrayBufferByteLength]].
1. If |lengthDelta| &lt; 0 or |lengthDelta| modulo 65536 is not 0,
1. Throw a {{RangeError}} exception.
1. Let |delta| be |lengthDelta| &div; 65536.
1. [=Grow the memory buffer=] associated with |memaddr| by |delta|.
1. Return <emu-const>handled</emu-const>.
1. Otherwise, return <emu-const>unhandled</emu-const>.
</div>
<div algorithm>
The getter of the <dfn attribute for="Memory">buffer</dfn> attribute of {{Memory}} returns **this**.\[[BufferObject]].
</div>
<h3 id="tables">Tables</h3>
<pre class="idl">
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 AddressValue initial;
AddressValue maximum;
AddressType address;
};
[LegacyNamespace=WebAssembly, Exposed=*]
interface Table {
constructor(TableDescriptor descriptor, optional any value);
AddressValue grow(AddressValue delta, optional any value);
any get(AddressValue index);
undefined set(AddressValue index, optional any value);
readonly attribute AddressValue length;
};
</pre>
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=].
<div algorithm>
To <dfn>initialize a table object</dfn> |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|.
</div>
<div algorithm>
To <dfn>create a table object</dfn> 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|.
</div>
<div algorithm>
The <dfn constructor for="Table">Table(|descriptor|, |value|)</dfn> 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. If |descriptor|["address"] [=map/exists=], let |addrtype| be |descriptor|["address"]; otherwise, let |addrtype| be "i32".
1. Let |initial| be [=?=] [=AddressValueToU64=](|descriptor|["initial"], |addrtype|).
1. If |descriptor|["maximum"] [=map/exists=], let |maximum| be [=?=] [=AddressValueToU64=](|descriptor|["maximum"], |addrtype|); otherwise, let |maximum| be empty.
1. Let |type| be the [=table type=] |addrtype| { <b>[=limits|min=]</b> |initial|, <b>[=limits|max=]</b> |maximum| } |elementType|.
1. If |type| is not [=valid tabletype|valid=], throw a {{RangeError}} exception.
1. If |value| is missing,
1. Let |ref| be [=DefaultValue=](|elementtype|).
1. Assert: |ref| is not [=error=].
1. Otherwise,
1. Let |ref| be [=?=] [=ToWebAssemblyValue=](|value|, |elementType|).
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
1. Let (|store|, |tableaddr|) be [=table_alloc=](|store|, |type|, |ref|). If allocation fails, throw a {{RangeError}} exception.
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
1. [=initialize a table object|Initialize=] **this** from |tableaddr|.
</div>
<div algorithm=dom-Table-grow>
The <dfn method for="Table">grow(|delta|, |value|)</dfn> 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 (|addrtype|, <var ignore>limits</var>, |elementtype|) be [=table_type=](|store|, |tableaddr|).
1. Let |delta64| be [=?=] [=AddressValueToU64=](|delta|, |addrtype|).
1. If |value| is missing,
1. Let |ref| be [=DefaultValue=](|elementtype|).
1. If |ref| is [=error=], throw a {{TypeError}} exception.
1. Otherwise,
1. Let |ref| be [=?=] [=ToWebAssemblyValue=](|value|, |elementtype|).
1. Let |result| be [=table_grow=](|store|, |tableaddr|, |delta64|, |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|.
</div>
<div algorithm>
The getter of the <dfn attribute for="Table">length</dfn> 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. Let |addrtype| be the [=address type=] in [=table_type=](|store|, |tableaddr|).
1. Let |length64| be [=table_size=](|store|, |tableaddr|).
1. Return [=U64ToAddressValue=](|length64|, |addrtype|).
</div>
<div algorithm>
The <dfn method for="Table">get(|index|)</dfn> 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 (|addrtype|, <var ignore>limits</var>, |elementtype|) be [=table_type=](|store|, |tableaddr|).
1. If |elementtype| [=matches/reftype|matches=] [=exnref=],
1. Throw a {{TypeError}} exception.
1. Let |index64| be [=?=] [=AddressValueToU64=](|index|, |addrtype|).
1. Let |result| be [=table_read=](|store|, |tableaddr|, |index64|).
1. If |result| is [=error=], throw a {{RangeError}} exception.
1. Return [=ToJSValue=](|result|).
</div>
<div algorithm>
The <dfn method for="Table">set(|index|, |value|)</dfn> 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 (|addrtype|, <var ignore>limits</var>, |elementtype|) be [=table_type=](|store|, |tableaddr|).
1. If |elementtype| [=matches/reftype|matches=] [=exnref=],
1. Throw a {{TypeError}} exception.
1. Let |index64| be [=?=] [=AddressValueToU64=](|index|, |addrtype|).
1. If |value| is missing,
1. Let |ref| be [=DefaultValue=](|elementtype|).
1. If |ref| is [=error=], throw a {{TypeError}} exception.
1. Otherwise,
1. Let |ref| be [=?=] [=ToWebAssemblyValue=](|value|, |elementtype|).
1. Let |store| be [=table_write=](|store|, |tableaddr|, |index64|, |ref|).
1. If |store| is [=error=], throw a {{RangeError}} exception.
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
</div>
<h3 id="globals">Globals</h3>
<pre class="idl">
enum ValueType {
"i32",
"i64",
"f32",
"f64",
"v128",
"externref",
"anyfunc",
};
</pre>
Note: this type may be extended with additional cases in future versions of WebAssembly.
<pre class="idl">
dictionary GlobalDescriptor {
required ValueType value;
boolean mutable = false;
};
[LegacyNamespace=WebAssembly, Exposed=*]
interface Global {
constructor(GlobalDescriptor descriptor, optional any v);
any valueOf();
attribute any value;
};
</pre>
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=]
<div algorithm>
To <dfn>initialize a global object</dfn> |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|.
</div>
<div algorithm>
To <dfn>create a global object</dfn> from a [=global address=] |globaladdr|, perform the following steps:
1. Let |map| be the [=surrounding 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|.
</div>
<div algorithm>
The algorithm <dfn>ToValueType</dfn>(|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.
</div>
<div algorithm>
The algorithm <dfn>DefaultValue</dfn>(|valuetype|) performs the following steps:
1. If |valuetype| equals [=externref=], return [=ToWebAssemblyValue=](undefined, |valuetype|).
1. Return [=val_default=](|valuetype|).
</div>
<div algorithm>
The <dfn constructor for="Global">Global(|descriptor|, |v|)</dfn> constructor, when invoked, performs the following steps:
1. Let |mutable| be |descriptor|["mutable"].
1. Let |valuetype| be [=ToValueType=](|descriptor|["value"]).
1. If |valuetype| [=matches/valtype|matches=] [=v128=] or [=exnref=],
1. Throw a {{TypeError}} exception.
1. If |v| is missing,
1. Let |value| be [=DefaultValue=](|valuetype|).
1. Assert: |value| is not [=error=].
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|). <!-- TODO(littledan): Report allocation failure https://github.com/WebAssembly/spec/issues/584 -->
1. Set the current agent's [=associated store=] to |store|.
1. [=initialize a global object|Initialize=] **this** from |globaladdr|.
</div>
<div algorithm>
The algorithm <dfn>GetGlobalValue</dfn>({{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 <var ignore>mut</var> |valuetype| where |valuetype| [=matches/valtype|matches=] [=v128=] or [=exnref=], throw a {{TypeError}}.
1. Let |value| be [=global_read=](|store|, |globaladdr|).
1. Return [=ToJSValue=](|value|).
</div>
<div algorithm>
The getter of the <dfn attribute for="Global">value</dfn> 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| [=matches/valtype|matches=] [=v128=] or [=exnref=], 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|.
</div>
<div algorithm>
The <dfn method for="Global">valueOf()</dfn> method, when invoked, performs the following steps:
1. Return [=GetGlobalValue=](**this**).
</div>
<h3 id="exported-function-exotic-objects">Exported Functions</h3>
A WebAssembly function is made available in JavaScript as an <dfn>Exported Function</dfn>.
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=].
<div algorithm>
The <dfn>name of the WebAssembly function</dfn> |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 <var ignore>functype</var>, 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|).
</div>
<div algorithm>
To create <dfn>a new Exported Function</dfn> 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|] → [<var ignore>resultTypes</var>] 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|.
</div>
<div algorithm>
To <dfn>call an Exported Function</dfn> 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 any type in |parameters| or |results| [=matches/valtype|matches=] [=v128=] or [=exnref=], 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=] &gt; |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. 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 <a href="#errors">the WebAssembly error mapping</a>.
1. If |ret| is [=THROW=] [=ref.exn=] |exnaddr|, then
1. Let |tagaddr| be [=exn_tag=](|store|, |exnaddr|).
1. Let |payload| be [=exn_read=](|store|, |exnaddr|).
1. Let |jsTagAddr| be the result of [=get the JavaScript exception tag |getting the JavaScript exception tag=].
1. If |tagaddr| is equal to |jsTagAddr|,
1. Throw the result of [=retrieving a host value=] from |payload|[0].
1. Otherwise,
1. Let |exception| be [=create an Exception object|a new Exception=] created from |exnaddr|.
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|).
</div>
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.
<div algorithm>
To <dfn>run a host function</dfn> 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 any type in |parameters| or |results| [=matches/valtype|matches=] [=v128=] or [=exnref=], 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|, {{%Symbol.iterator%}}).
1. If |method| is undefined, [=throw=] a {{TypeError}}.
1. Let |values| be [=?=] [$IteratorToList$]([=?=] [$GetIteratorFromMethod$](|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|.
</div>
<div algorithm>
To <dfn>create a host function</dfn> from the JavaScript object |func| and type |functype|, perform the following steps:
1. Assert: [$IsCallable$](|func|).
1. Let |stored settings| be the <a spec=HTML>incumbent settings object</a>.
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 <emu-const>throw</emu-const> or <emu-const>normal</emu-const>.
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
1. If |result|.\[[Type]] is <emu-const>throw</emu-const>, then:
1. Let |v| be |result|.\[[Value]].
1. If |v| [=implements=] {{Exception}},
1. Let |address| be |v|.\[[Address]].
1. Otherwise,
1. Let |type| be the result of [=get the JavaScript exception tag |getting the JavaScript exception tag=].
1. Let |payload| be [=!=] [=ToWebAssemblyValue=](|v|, [=externref=]).
1. Let (|store|, |address|) be [=exn_alloc=](|store|, |type|, « |payload| »).
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
1. Execute the WebAssembly instructions ([=ref.exn=] |address|) ([=throw_ref=]).
1. Otherwise, return |result|.\[[Value]].
1. Let (|store|, |funcaddr|) be [=func_alloc=](|store|, |functype|, |hostfunc|).
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
1. Return |funcaddr|.
</div>
<div algorithm>
The algorithm <dfn>ToJSValue</dfn>(|w|) coerces a [=WebAssembly value=] to a JavaScript value by performing the following steps:
1. Assert: |w| is not of the form [=v128.const=] <var ignore>v128</var>.
1. Assert: |w| is not of the form [=ref.exn=] <var ignore>exnaddr</var>.
1. If |w| is of the form [=i64.const=] |u64|,
1. Let |i64| be [=signed_64=](|u64|).
1. Return [=ℤ=](|i64| interpreted as a [=mathematical value=]).
1. If |w| is of the form [=i32.const=] |u32|,
1. Let |i32| be [=signed_32=](|u32|).
2. Return [=𝔽=](|i32| interpreted as a [=mathematical value=]).
1. If |w| is of the form [=f32.const=] |f32|,
1. If |f32| is [=+∞=] or [=−∞=], return **+∞**<sub>𝔽</sub> or **-∞**<sub>𝔽</sub>, 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 **+∞**<sub>𝔽</sub> or **-∞**<sub>𝔽</sub>, 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=] <var ignore>t</var>, return null.
1. If |w| is of the form [=ref.i31=] |u31|,
1. Let |i31| be [=signed_31=](|u31|).
1. Let return [=𝔽=](|i31|).
1. If |w| is of the form [=ref.struct=] |structaddr|, return the result of creating [=a new Exported GC Object=] from |structaddr| and "struct".
1. If |w| is of the form [=ref.array=] |arrayaddr|, return the result of creating [=a new Exported GC Object=] from |arrayaddr| and "array".
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.host=] |hostaddr|, return the result of [=retrieving a host value=] from |hostaddr|.
1. If |w| is of the form [=ref.extern=] |ref|, return [=ToJSValue=](|ref|).
Note: Number values which are equal to NaN may have various observable NaN payloads; see [$NumericToRawBytes$] for details.
</div>
<div algorithm>
For <dfn>retrieving a host value</dfn> from an [=host address=] |hostaddr|, perform the following steps:
1. Let |map| be the [=surrounding agent=]'s associated [=host value cache=].
1. Assert: |map|[|hostaddr|] [=map/exists=].
1. Return |map|[|hostaddr|].
</div>
<div algorithm>
The algorithm <dfn>ToWebAssemblyValue</dfn>(|v|, |type|) coerces a JavaScript value to a [=WebAssembly value=] by performing the following steps:
1. Assert: |type| is not [=v128=].
1. Assert: |type| does not [=matches/valtype|match=] [=exnref=].
1. If |type| is [=i64=],
1. Let |i64| be [=?=] [$ToBigInt64$](|v|).
1. Let |u64| be the unsigned integer such that |i64| is [=signed_64=](|u64|).
1. Return [=i64.const=] |u64|.
1. If |type| is [=i32=],
1. Let |i32| be [=?=] [$ToInt32$](|v|).
1. Let |u32| be the unsigned integer such that |i32| is [=signed_32=](|u32|).
1. Return [=i32.const=] |u32|.
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=]<sub>32</sub> &leq; |n| &lt; 2<sup>[=signif=](32)</sup>.
1. Let |f32| be [=nan=](n).
1. Otherwise,
1. Let |f32| be |number| rounded to the nearest representable value using IEEE 754-2019 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=]<sub>64</sub> &leq; |n| &lt; 2<sup>[=signif=](64)</sup>.
1. Let |f64| be [=nan=](n).
1. Otherwise,
1. Let |f64| be |number|.
1. Return [=f64.const=] |f64|.
1. If |type| is of the form [=ref=] |null| |heaptype|,
1. If |v| is null,
1. Let |r| be [=ref.null=] |heaptype|.
1. Else if [=match_valtype=](|type|, [=ref=] |null| [=heap-type/extern=]),
1. Let |ref| be [=ToWebAssemblyValue=](|v|, [=ref=] [=heap-type/any=]).
1. Let |r| be [=ref.extern=] |ref|.
1. Else if |v| is an [=Exported Function=] and [=match_valtype=](|type|, [=ref=] |null| [=heap-type/func=]),
1. Let |funcaddr| be the value of |v|'s \[[FunctionAddress]] internal slot.
1. Let |r| be [=ref.func=] |funcaddr|.
1. Else if |v| [=is a Number=] and |v| is equal to [=?=] [$ToInt32$](|v|) and [=ℝ=](|v|) < 2<sup>30</sup> and [=ℝ=](|v|) ⩾ -2<sup>30</sup>,
1. Let |i31| [=?=] [$ToInt32$](|v|).
1. Let |u31| be the unsigned integer such that |i31| is [=signed_31=](|i31|).
1. Let |r| be [=ref.i31=] |u31|.
1. Else if |v| is an [=Exported GC Object=],
1. Let |objectaddr| be the value of |v|'s \[[ObjectAddress]] internal slot.
1. Let |objectkind| be the value of |v|'s \[[ObjectKind]] internal slot.
1. If |objectkind| is "array",
1. Let |r| be [=ref.array=] |objectaddr|.
1. If |objectkind| is "struct",
1. Let |r| be [=ref.struct=] |objectaddr|.
1. Else,
1. Let |map| be the [=surrounding agent=]'s associated [=host value cache=].
1. If a [=host address=] |hostaddr| exists such that |map|[|hostaddr|] is the same as |v|,
1. Return [=ref.host=] |hostaddr|.
1. Let [=host address=] |hostaddr| be the smallest address such that |map|[|hostaddr|] [=map/exists=] is false.
1. [=map/Set=] |map|[|hostaddr|] to |v|.
1. Let |r| be [=ref.host=] |hostaddr|.
1. Let |store| be the current agent's [=associated store=].
1. Let |actualtype| be [=ref_type=](|store|, |r|).
1. If [=match_valtype=](|actualtype|, |type|) is false,
1. Throw a {{TypeError}}.
1. Return |r|.
1. Assert: This step is not reached.
</div>
<div algorithm>
The algorithm <dfn>AddressValueToU64</dfn>(|v|, |addrtype|) converts a JavaScript value to a WebAssembly [=u64=] for use in embedding operations. It is designed to act like [=[EnforceRange]=] [=unsigned long=] for {{AddressType}} "i32", and to extend these semantics to {{AddressType}} "i64", by performing the following steps:
1. If |addrtype| is "i32",
1. Let |n| be [=?=] [$ConvertToInt$](|v|, 32, "unsigned"), where the destination type is associated with [=[EnforceRange]=].
Note: This is equivalent to the [=js-unsigned-long|JS conversion rules=] for [=[EnforceRange]=] [=unsigned long=].
1. Return [=ℝ=](|n|) as a WebAssembly [=u64=].
1. If |addrtype| is "i64",
1. Let |n| be [=?=] [$ToBigInt$](|v|).
1. If |n| &lt; 0 or |n| &gt; 2<sup>64</sup> &minus; 1, [=throw=] a {{TypeError}}.
Note: This operation is designed to emulate [=[EnforceRange]=].
1. Return [=ℝ=](|n|) as a WebAssembly [=u64=].
1. Assert: This step is not reached.
</div>
<div algorithm>
The algorithm <dfn>U64ToAddressValue</dfn>(|v|, |addrtype|) converts a [=u64=] value from a WebAssembly embedding operation to the correct variant of {{AddressValue}} for an {{AddressType}}, by performing the following steps:
1. If |addrtype| is "i32", return [=𝔽=](|v| interpreted as a [=mathematical value=]).
1. Else if |addrtype| is "i64", return [=ℤ=](|v| interpreted as a [=mathematical value=]).
1. Assert: This step is not reached.
</div>
<h3 id="tags">Tags</h3>
The <dfn>tag_alloc</dfn>(|store|, |parameters|) algorithm creates a new [=tag address=] for |parameters| in |store| and returns the updated store and the [=tag address=].
<h4 id="tag-types">Tag types</h4>
<pre class="idl">
dictionary TagType {
required sequence&lt;ValueType> parameters;
};
[LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)]
interface Tag {
constructor(TagType type);
};
</pre>
A {{Tag}} value represents an exception tag.
<div algorithm>
To <dfn>initialize a Tag object</dfn> |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|.
</div>
<div algorithm>
To <dfn>create a Tag object</dfn> 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|.
</div>
<div algorithm>
The <dfn constructor for="Tag" lt="Tag(type)">new Tag(|type|)</dfn> 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|.
</div>
<h3 id="gc-exotic-objects">Garbage Collected Objects</h3>
A WebAssembly struct or array is made available in JavaScript as an <dfn>Exported GC Object</dfn>.
An [=Exported GC Object=] is an exotic object that wraps a garbage collected WebAssembly reference value.
Most JavaScript operations on an [=Exported GC Object=] will throw an exception or return undefined.
Note: These operations may be refined in the future to allow richer interactions in JavaScript with WebAssembly structs and arrays.
An [=Exported GC Object=] contains an \[[ObjectAddress]] internal slot, which holds a [=object address=] relative to the [=surrounding agent=]'s [=associated store=],
and an \[[ObjectKind]] internal slot, which holds the string value "struct" or "array".
The internal methods of an [=Exported GC Object=] use the following implementations.
<div algorithm>
The <dfn>\[[GetPrototypeOf]] internal method of an Exported GC Object</dfn> <var ignore>O</var> takes no arguments and returns null. It performs the following steps when called:
1. Return null.
</div>
<div algorithm>
The <dfn>\[[SetPrototypeOf]] internal method of an Exported GC Object</dfn> <var ignore>O</var> takes argument <var ignore>V</var> (an Object or null) and returns a boolean. It performs the following steps when called:
1. Return false.
</div>
<div algorithm>
The <dfn>\[[IsExtensible]] internal method of an Exported GC Object</dfn> <var ignore>O</var> takes no arguments and returns a boolean. It performs the following steps when called:
1. Return false.
</div>
<div algorithm>
The <dfn>\[[PreventExtensions]] internal method of an Exported GC Object</dfn> <var ignore>O</var> takes no arguments and returns a boolean. It performs the following steps when called:
1. Return false.
</div>
<div algorithm>
The <dfn>\[[GetOwnProperty]] internal method of an Exported GC Object</dfn> <var ignore>O</var> takes argument <var ignore>P</var> (a property key) and returns undefined. It performs the following steps when called:
1. Return undefined.
</div>
<div algorithm>
The <dfn>\[[DefineOwnProperty]] internal method of an Exported GC Object</dfn> <var ignore>O</var> takes arguments <var ignore>P</var> (a property key) and <var ignore>Desc</var> (a property descriptor) and returns a boolean. It performs the following steps when called:
1. Return false.
</div>
<div algorithm>
The <dfn>\[[HasProperty]] internal method of an Exported GC Object</dfn> <var ignore>O</var> takes argument <var ignore>P</var> (a property key) and returns a boolean. It performs the following steps when called:
1. Return false.
</div>
<div algorithm>
The <dfn>\[[Get]] internal method of an Exported GC Object</dfn> <var ignore>O</var> takes arguments <var ignore>P</var> (a property key) and <var ignore>Receiver</var> (an ECMAScript language value) and returns undefined. It performs the following steps when called:
1. Return undefined.
</div>
<div algorithm>
The <dfn>\[[Set]] internal method of an Exported GC Object</dfn> <var ignore>O</var> takes arguments <var ignore>P</var> (a property key), <var ignore>V</var> (an ECMAScript language value), and <var ignore>Receiver</var> (an ECMAScript language value) and throws an exception. It performs the following steps when called:
1. Throw a {{TypeError}}.
</div>
<div algorithm>
The <dfn>\[[Delete]] internal method of an Exported GC Object</dfn> <var ignore>O</var> takes argument <var ignore>P</var> (a property key) and throws an exception. It performs the following steps when called:
1. Throw a {{TypeError}}.
</div>
<div algorithm>
The <dfn>\[[OwnPropertyKeys]] internal method of an Exported GC Object</dfn> <var ignore>O</var> takes no arguments and returns a list. It performs the following steps when called:
1. Let keys be a new empty list.
1. Return keys.
</div>
<div algorithm>
To create <dfn>a new Exported GC Object</dfn> from a WebAssembly [=object address=] |objectaddr| and a string |objectkind|, perform the following steps:
1. Assert: |objectkind| is either "array" or "struct".
1. Let |map| be the [=surrounding agent=]'s associated [=exported GC object cache=].
1. If |map|[|objectaddr|] [=map/exists=],
1. Return |map|[|objectaddr|].
1. Let |object| be [=MakeBasicObject=](« \[[ObjectAddress]] »).
1. Set |object|.\[[ObjectAddress]] to |objectaddr|.
1. Set |object|.\[[ObjectKind]] to |objectkind|.
1. Set |object|.\[[GetPrototypeOf]] as specified in [=[[GetPrototypeOf]] internal method of an Exported GC Object=].
1. Set |object|.\[[SetPrototypeOf]] as specified in [=[[SetPrototypeOf]] internal method of an Exported GC Object=].
1. Set |object|.\[[IsExtensible]] as specified in [=[[IsExtensible]] internal method of an Exported GC Object=].
1. Set |object|.\[[PreventExtensions]] as specified in [=[[PreventExtensions]] internal method of an Exported GC Object=].
1. Set |object|.\[[GetOwnProperty]] as specified in [=[[GetOwnProperty]] internal method of an Exported GC Object=].
1. Set |object|.\[[DefineOwnProperty]] as specified in [=[[DefineOwnProperty]] internal method of an Exported GC Object=].
1. Set |object|.\[[HasProperty]] as specified in [=[[HasProperty]] internal method of an Exported GC Object=].
1. Set |object|.\[[Get]] as specified in [=[[Get]] internal method of an Exported GC Object=].
1. Set |object|.\[[Set]] as specified in [=[[Set]] internal method of an Exported GC Object=].
1. Set |object|.\[[Delete]] as specified in [=[[Delete]] internal method of an Exported GC Object=].
1. Set |object|.\[[OwnPropertyKeys]] as specified in [=[[OwnPropertyKeys]] internal method of an Exported GC Object=].
1. [=map/Set=] |map|[|objectaddr|] to |object|.
1. Return |object|.
</div>
<h3 id="exceptions">Exceptions</h3>
<pre class="idl">
dictionary ExceptionOptions {
boolean traceStack = false;
};
[LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)]
interface Exception {
constructor(Tag exceptionTag, sequence&lt;any> payload, optional ExceptionOptions options = {});
any getArg([EnforceRange] unsigned long index);
boolean is(Tag exceptionTag);
readonly attribute (DOMString or undefined) stack;
};
</pre>
An {{Exception}} value represents an exception.
<div algorithm>
To <dfn>initialize an Exception object</dfn> |exn| from an [=Exception address=] |exnAddress|, perform the following steps:
1. Let |map| be the [=surrounding agent=]'s associated [=Exception object cache=].
1. Assert: |map|[|exnAddress|] doesn't [=map/exist=].
1. Set |exn|.\[[Address]] to |exnAddress|.
1. [=map/Set=] |map|[|exnAddress|] to |exn|.
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
1. Let |tagaddr| be [=exn_tag=](|store|, |exnAddress|).
1. Let |payload| be [=exn_read=](|store|, |exnAddress|).
1. Set |exn|.\[[Type]] to |tagaddr|.
1. Set |exn|.\[[Payload]] to |payload|.
1. Set |exn|.\[[Stack]] to undefined.
</div>
<div algorithm>
To <dfn>create an Exception object</dfn> from a [=exception address=] |exnAddress|, perform the following steps:
1. Let |map| be the [=surrounding agent=]'s associated [=Exception object cache=].
1. If |map|[|exnAddress|] [=map/exists=],
1. Return |map|[|exnAddress|].
1. Let |exn| be a [=new=] {{Exception}}.
1. [=initialize an Exception object|Initialize=] |exn| from |exnAddress|.
1. Return |exn|.
</div>
<div algorithm>
The <dfn constructor for=Exception
lt="Exception(exceptionTag, payload, options)">new Exception(|exceptionTag|, |payload|, |options|)</dfn>
constructor steps are:
1. Let |JSTagAddr| be the result of [=get the JavaScript exception tag|getting the JavaScript exception tag=].
1. If |exceptionTag|.\[[Address]] is equal to |JSTagAddr|,
1. Throw a {{TypeError}}.
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
1. Let [|types|] → [] be [=tag_type=](|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. If |resultType| [=matches/valtype|matches=] [=v128=] or [=exnref=],
1. Throw a {{TypeError}}.
1. [=list/Append=] [=?=] [=ToWebAssemblyValue=](|value|, |resultType|) to |wasmPayload|.
1. Let (|store|, |exceptionAddr|) be [=exn_alloc=](|store|, |exceptionTag|.\[[Address]], |wasmPayload|)
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
1. [=initialize an Exception object|Initialize=] **this** from |exceptionAddr|.
1. If |options|["traceStack"] is true,
1. Set **this**.\[[Stack]] to either a {{DOMString}} representation of the current call stack or undefined.
</div>
<div algorithm>
The <dfn method for="Exception">getArg(|index|)</dfn> method steps are:
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
1. Let |tagaddr| be [=exn_tag=](|store|, **this**.\[[Address]]).
1. Let |payload| be [=exn_read=](|store|, **this**.\[[Address]]).
1. Assert: |tagaddr| is equal to **this**.\[[Type]].
1. If |index| ≥ |payload|'s [=list/size=],
1. Throw a {{RangeError}}.
1. Let [|types|] → [] be [=tag_type=](|store|, |tagaddr|).
1. If |types|[|index|] [=matches/valtype|matches=] [=v128=] or [=exnref=],
1. Throw a {{TypeError}}.
1. Return [=ToJSValue=](|payload|[|index|]).
</div>
<div algorithm>
The <dfn method for="Exception">is(|exceptionTag|)</dfn> method steps are:
1. If **this**.\[[Type]] is not equal to |exceptionTag|.\[[Address]],
1. Return false.
1. Return true.
</div>
<div algorithm>
The <dfn attribute for="Exception">stack</dfn> getter steps are:
1. Return **this**.\[[Stack]].
</div>
<h4 id="js-exceptions">JavaScript exceptions</h4>
The <dfn>JavaScript exception tag</dfn> is a [=tag address=] associated with
the surrounding agent. It is allocated in the agent's [=associated store=] on
first use and cached. It always has the [=tag type=] « [=externref=] » → « ».
<div algorithm>
To <dfn>get the JavaScript exception tag</dfn>, perform the following steps:
1. If the [=surrounding agent=]'s associated [=JavaScript exception tag=] has been initialized,
1. return the [=surrounding agent=]'s associated [=JavaScript exception tag=]
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
1. Let (|store|, |tagAddress|) be [=tag_alloc=](|store|, « [=externref=] » → « »).
1. Set the current agent's [=associated store=] to |store|.
1. Set the current agent's associated [=JavaScript exception tag=] to |tagAddress|.
1. return |tagAddress|.
</div>
<h3 id="error-objects">Error Objects</h3>
WebAssembly defines the following Error classes: <dfn exception>CompileError</dfn>, <dfn exception>LinkError</dfn>, and <dfn exception>RuntimeError</dfn>.
<div algorithm="create the WebAssembly namespace object">
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 <var ignore>NativeError</var> set to |error|.
1. [=!=] [$DefineMethodProperty$](|namespaceObject|, |error|, |constructor|, false).
</div>
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.
<h2 id="builtins">Builtins</h2>
The JS-API defines sets of builtin functions which can be imported through {{WebAssemblyCompileOptions|options}} when compiling a module. WebAssembly builtin functions mirror existing JavaScript builtins, but adapt them to be useable directly as WebAssembly functions with minimal overhead.
All builtin functions are grouped into sets. Every builtin set has a <dfn for="builtin-set">|name|</dfn> that is used in {{WebAssemblyCompileOptions}}, and a <dfn for="builtin-set">|qualified name|</dfn> with a `wasm:` prefix that [=read the imports|is used during import lookup=].
<div algorithm>
To <dfn>get the builtins for a builtin set</dfn> with |builtinSetName|, perform the following steps:
1. Return a list of (|name|, |funcType|, |steps|) for the set with name |builtinSetName| defined within this section.
</div>
<div algorithm>
To <dfn>find a builtin</dfn> with |import| and enabled builtins |builtinSetNames|, perform the following steps:
1. Assert: [=validate builtin set names=] |builtinSetNames| is true.
1. Let |importModuleName| be |import|[0].
1. Let |importName| be |import|[1].
1. [=list/iterate|For each=] |builtinSetName| of |builtinSetNames|,
1. If |builtinSetName| does not refer to a builtin set, then [=iteration/continue=].
1. Let |builtinSetQualifiedName| be |builtinSetName| prefixed with "wasm:".
1. If |importModuleName| equals |builtinSetQualifiedName|,
1. Let |builtins| be the result of [=get the builtins for a builtin set=] |builtinSetName|.
1. [=list/iterate|For each=] |builtin| of |builtins|,
1. Let |builtinName| be |builtin|[0].
1. If |importName| equals |builtinName|, return (|builtinSetName|, |builtin|).
1. Return null.
</div>
<div algorithm>
To <dfn>validate builtin set names</dfn> with |builtinSetNames|, perform the following steps:
1. If |builtinSetNames| contains any duplicates, return false.
1. Return true.
</div>
<div algorithm>
To <dfn>create a builtin function</dfn> from type |funcType| and execution steps |steps|, perform the following steps:
1. Let |hostfunc| be a [=host function=] which executes |steps| when called.
1. Let (|store|, |funcaddr|) be [=func_alloc=](|store|, |functype|, |hostfunc|).
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
1. Return |funcaddr|.
</div>
<div algorithm>
To <dfn>instantiate a builtin set</dfn> with name |builtinSetName|, perform the following steps:
1. Let |builtins| be the result of [=get the builtins for a builtin set=] |builtinSetName|.
1. Let |exportsObject| be [=!=] [$OrdinaryObjectCreate$](null).
1. [=list/iterate|For each=] (|name|, |funcType|, |steps|) of |builtins|,
1. Let |funcaddr| be the result fo [=create a builtin function=] with |funcType| and |steps|.
1. Let |func| be the result of creating [=a new Exported Function=] from |funcaddr|.
1. Let |value| be |func|.
1. Let |status| be [=!=] [$CreateDataProperty$](|exportsObject|, |name|, |value|).
1. Assert: |status| is true.
1. Return |exportsObject|.
</div>
<div algorithm>
To <dfn>validate an import for builtins</dfn> with |import|, enabled builtins |builtinSetNames|, perform the following steps:
1. Assert: [=validate builtin set names=] |builtinSetNames| is true.
1. Let |maybeBuiltin| be the result of [=find a builtin|finding a builtin=] for |import| and |builtinSetNames|.
1. If |maybeBuiltin| is null, return true.
1. Let |importExternType| be |import|[2].
1. Let |builtinFuncType| be |maybeBuiltin|[0][1].
1. Let |builtinExternType| be `func |builtinFuncType|`.
1. Return [=match_externtype=](|builtinExternType|, |importExternType|).
</div>
<h3 id="builtins-js-string">String Builtins</h3>
String builtins adapt the interface of the [=String=] builtin object. The [=builtin-set/name=] for this set is `js-string`, and the [=builtin-set/qualified name=] is `wasm:js-string`.
Note: The algorithms in this section refer to JS builtins defined on [=String=]. These refer to the actual builtin and do not perform a dynamic lookup on the [=String=] object.
<h4 id="builtins-js-string-abstract-ops">Abstract operations</h4>
<div algorithm>
The <dfn abstract-op lt="UnwrapString">UnwrapString(|v|)</dfn> abstract operation, when invoked, performs the following steps:
1. If |v| [=is not a String=],
1. Throw a {{RuntimeError}} exception as if a [=trap=] was executed.
1. Return |v|
</div>
<div algorithm>
The <dfn abstract-op lt="FromCharCode">FromCharCode(|v|)</dfn> abstract operation, when invoked, performs the following steps:
1. Assert: |v| is of type [=i32=].
1. Return [=!=] [$Call$]([=String.fromCharCode=], undefined, « [=ToJSValue=](|v|) »).
</div>
<div algorithm>
The <dfn abstract-op lt="CharCodeAt">CharCodeAt(|string|, |index|)</dfn> abstract operation, when invoked, performs the following steps:
1. Assert: |index| is of type [=i32=].
1. Return [=!=] [$Call$]([=String.prototype.charCodeAt=], |string|, « [=ToJSValue=](|index|) »).
</div>
<h4 id="js-string-cast">cast</h4>
The |funcType| of this builtin is `(rec (type (func (param externref) (result externref)))).0`.
<div algorithm="js-string-cast">
When this builtin is invoked with parameter |v|, the following steps must be run:
1. Return [=?=] [$UnwrapString$](|v|)
</div>
<h4 id="js-string-test">test</h4>
The |funcType| of this builtin is `(rec (type (func (param externref) (result i32)))).0`.
<div algorithm="js-string-test">
When this builtin is invoked with parameter |v|, the following steps must be run:
1. If |v| [=is not a String=],
1. Return 0.
1. Return 1.
</div>
<h4 id="js-string-fromCharCodeArray">fromCharCodeArray</h4>
Let |arrayType| be `(rec (type (array (mut i16)))).0`.
The |funcType| of this builtin is `(rec (type (func (param (ref null arrayType) i32 i32) (result externref)))).0`.
<div algorithm="js-string-fromCharCodeArray">
When this builtin is invoked with parameters |array|, |start|, and |end|, the following steps must be run:
1. If |array| is null,
1. Throw a {{RuntimeError}} exception as if a [=trap=] was executed.
1. Let |length| be the number of elements in |array|.
1. If |start| > |end| or |end| > |length|,
1. Throw a {{RuntimeError}} exception as if a [=trap=] was executed.
1. Let |result| be the empty string.
1. Let |i| be |start|.
1. While |i| < |end|:
1. Let |charCode| be the value of the element stored at index |i| in |array|.
1. Let |charCodeString| be [$FromCharCode$](|charCode|).
1. Let |result| be the concatenation of |result| and |charCodeString|.
1. Set |i| to |i| + 1.
1. Return |result|.
</div>
<h4 id="js-string-intoCharCodeArray">intoCharCodeArray</h4>
Let |arrayType| be `(rec (type (array (mut i16)))).0`.
The |funcType| of this builtin is `(rec (type (func (param externref (ref null arrayType) i32) (result i32)))).0`.
<div algorithm="js-string-intoCharCodeArray">
When this builtin is invoked with parameters |string|, |array|, and |start|, the following steps must be run:
1. If |array| is null,
1. Throw a {{RuntimeError}} exception as if a [=trap=] was executed.
1. Let |string| be [=?=] [$UnwrapString$](|string|).
1. Let |stringLength| be the [=string/length=] of |string|.
1. Let |arrayLength| be the number of elements in |array|.
1. If |start| + |stringLength| > |arrayLength|,
1. Throw a {{RuntimeError}} exception as if a [=trap=] was executed.
1. Let |i| be 0.
1. While |i| < |stringLength|:
1. Let |charCode| be [$CharCodeAt$](|string|, |i|).
1. Set the element at index |start| + |i| in |array| to [=ToWebAssemblyValue=](|charCode|).
1. Set |i| to |i| + 1.
1. Return |stringLength|.
</div>
<h4 id="js-string-fromCharCode">fromCharCode</h4>
The |funcType| of this builtin is `(rec (type (func (param i32) (result externref)))).0`.
<div algorithm="js-string-fromCharCode">
When this builtin is invoked with parameter |v|, the following steps must be run:
1. Return [$FromCharCode$](|v|).
</div>
<h4 id="js-string-fromCodePoint">fromCodePoint</h4>
The |funcType| of this builtin is `(rec (type (func (param i32) (result externref)))).0`.
<div algorithm="js-string-fromCodePoint">
When this builtin is invoked with parameter |v|, the following steps must be run:
1. If |v| &gt; 0x10ffff,
1. Throw a {{RuntimeError}} exception as if a [=trap=] was executed.
1. Return [=!=] [$Call$]([=String.fromCodePoint=], undefined, « [=ToJSValue=](|v|) »).
</div>
<h4 id="js-string-charCodeAt">charCodeAt</h4>
The type of this function is `(rec (type (func (param externref i32) (result i32)))).0`.
<div algorithm="js-string-charCodeAt">
When this builtin is invoked with parameters |string| and |index|, the following steps must be run:
1. Let |string| be [=?=] [$UnwrapString$](|string|).
1. Let |length| be the [=string/length=] of |string|.
1. If |index| >= |length|,
1. Throw a {{RuntimeError}} exception as if a [=trap=] was executed.
1. Return [$CharCodeAt$](|string|, |index|).
</div>
<h4 id="js-string-codePointAt">codePointAt</h4>
The type of this function is `(rec (type (func (param externref i32) (result i32)))).0`.
<div algorithm="js-string-codePointAt">
When this builtin is invoked with parameters |string| and |index|, the following steps must be run:
1. Let |string| be [=?=] [$UnwrapString$](|string|).
1. Let |length| be the [=string/length=] of |string|.
1. If |index| >= |length|,
1. Throw a {{RuntimeError}} exception as if a [=trap=] was executed.
1. Return [=!=] [$Call$]([=String.prototype.codePointAt=], |string|, « [=ToJSValue=](|index|) »).
</div>
<h4 id="js-string-length">length</h4>
The |funcType| of this builtin is `(rec (type (func (param externref) (result i32)))).0`.
<div algorithm="js-string-length">
When this builtin is invoked with parameter |v|, the following steps must be run:
1. Let |string| be [=?=] [$UnwrapString$](|v|).
1. Return the [=string/length=] of |string|.
</div>
<h4 id="js-string-concat">concat</h4>
The |funcType| of this builtin is `(rec (type (func (param externref externref) (result externref)))).0`.
<div algorithm="js-string-concat">
When this builtin is invoked with parameters |first| and |second|, the following steps must be run:
1. Let |first| be [=?=] [$UnwrapString$](|first|).
1. Let |second| be [=?=] [$UnwrapString$](|second|).
1. Return [=!=] [$Call$]([=String.prototype.concat=], |first|, « |second| »).
</div>
<h4 id="js-string-substring">substring</h4>
The |funcType| of this builtin is `(rec (type (func (param externref i32 i32) (result externref)))).0`.
<div algorithm="js-string-substring">
When this builtin is invoked with parameters |string|, |start|, and |end|, the following steps must be run:
1. Let |string| be [=?=] [$UnwrapString$](|string|).
1. Let |length| be the [=string/length=] of |string|.
1. If |start| > |end| or |start| > |length|,
1. Return the empty string.
1. Return [=!=] [$Call$]([=String.prototype.substring=], |string|, « [=ToJSValue=](|start|), [=ToJSValue=](|end|) »).
</div>
<h4 id="js-string-equals">equals</h4>
The |funcType| of this builtin is `(rec (type (func (param externref externref) (result i32)))).0`.
Note: Explicitly allow null strings to be compared for equality as that is meaningful.
<div algorithm="js-string-equals">
When this builtin is invoked with parameters |first| and |second|, the following steps must be run:
1. If |first| is not null and |first| [=is not a String=],
1. Throw a {{RuntimeError}} exception as if a [=trap=] was executed.
1. If |second| is not null and |second| [=is not a String=],
1. Throw a {{RuntimeError}} exception as if a [=trap=] was executed.
1. If [=!=] [=IsStrictlyEqual=](|first|, |second|) is true,
1. Return 1.
1. Return 0.
</div>
<h4 id="js-string-compare">compare</h4>
The |funcType| of this builtin is `(rec (type (func (param externref externref) (result i32)))).0`.
<div algorithm="js-string-compare">
When this builtin is invoked with parameters |first| and |second|, the following steps must be run:
1. Let |first| be [=?=] [$UnwrapString$](|first|).
1. Let |second| be [=?=] [$UnwrapString$](|second|).
1. If [=!=] [=IsStrictlyEqual=](|first|, |second|) is true,
1. Return 0.
1. If [=!=] [=IsLessThan=](|first|, |second|, true) is true,
1. Return -1.
1. Return 1.
</div>
<h2 id="errors">Error Condition Mappings to JavaScript</h2>
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.
<h3 id="stack-overflow">Stack Overflow</h3>
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.
<h3 id="out-of-memory">Out of Memory</h3>
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.
<div class="issue">
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.
</div>
<h2 id="limits">Implementation-defined Limits</h2>
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.
<ul>
<li>The maximum size of a module is 1,073,741,824 bytes (1 GiB).</li>
<li>The maximum number of types defined in the types section is 1,000,000.</li>
<li>The maximum number of recursion groups defined in the types sections is 1,000,000.</li>
<li>The maximum number of types defined in a recursion group is 1,000,000.</li>
<li>The maximum depth of a defined subtype hierarchy is 63 (where a type defined with no supertype has depth 0).
<li>The maximum number of functions defined in a module is 1,000,000.</li>
<li>The maximum number of imports declared in a module is 1,000,000.</li>
<li>The maximum number of exports declared in a module is 1,000,000.</li>
<li>The maximum number of globals defined in a module is 1,000,000.</li>
<li>The maximum number of tags defined in a module is 1,000,000.</li>
<li>The maximum number of data segments defined in a module is 100,000.</li>
<li>The maximum number of tables, including declared or imported tables, is 100,000.</li>
<li>The maximum size of a table is 10,000,000.</li>
<li>The maximum number of table entries in any table initialization is 10,000,000.</li>
<li>The maximum number of memories, including defined and imported memories, is 100.</li>
<li>The maximum `min` or `max` field of a 32-bit memory is 65,536 pages (4 GiB).</li>
<li>The maximum `min` or `max` field of a 64-bit memory is 2^37-1 pages (2^53 - 2^16 bytes).</li>
<li>The maximum number of parameters to any function or block is 1,000.</li>
<li>The maximum number of return values for any function or block is 1,000.</li>
<li>The maximum size of a function body, including locals declarations, is 7,654,321 bytes.</li>
<li>The maximum number of locals declared in a function, including implicitly declared as parameters, is 50,000.</li>
<li>The maximum number of fields in a struct is 10,000.</li>
<li>The maximum number of operands to `array.new_fixed` is 10,000.</li>
</ul>
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.
<ul>
<li>The maximum size of a table is 10,000,000.</li>
<li>The maximum size of a 32-bit memory is 65,536 pages (4 GiB).</li>
<li>The maximum size of a 64-bit memory is 262,144 pages (16 GiB).</li>
</ul>
<h2 id="security-considerations">Security and Privacy Considerations</h2>
<p><em>This section is non-normative.</em></p>
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.
<h2 id="change-history">Change History</h2>
<p><em>This section is non-normative.</em></p>
<p>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.</p>
<h3 id="release-20">Release 2.0</h3>
<h4 id="changes-multivalue" class="no-toc heading settled">Multiple Values</h4>
Multiple values can be returned to and from JavaScript functions as an [=Array=] object.
<h4 id="changes-bigint" class="no-toc heading settled">BigInt Integration</h4>
WebAssembly [=i64=] values can be passed to and from JavaScript (via imported or exported globals, table get or set operations, function return values or arguments) as [=BigInt=] objects.
<h4 id="changes-reftypes" class="no-toc heading settled">Reference Types</h4>
JavaScript values can be passed to and from WebAssembly (via imported or exported globals, table set or get operations, and function arguments or return values) as [=externref=] values.
<h4 id="changes-multitable" class="no-toc heading settled">Multiple Tables</h4>
Multiple tables can be exported and imported to and from JavaScript.
<h3 id="release-30">Release 3.0</h3>
<h4 id="changes-multimemory" class="no-toc heading settled">Multiple Memories</h4>
Multiple memories can be exported and imported to and from JavaScript.
<h4 id="changes-js-sb" class="no-toc heading settled">JS String Builtins</h4>
Added a builtins option when compiling a module, and a collection of builtin functions for manipulating JS Strings.