This API provides a way to access WebAssembly [WEBASSEMBLY] through a bridge to explicitly construct modules from JavaScript [ECMASCRIPT].
1. Sample API UsageThis section is non-normative.
Given demo.wat
(encoded to demo.wasm
):
(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:
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() );2. Notation
This specification depends on the Infra Standard. [INFRA]
The WebAssembly sequence type is equivalent to the list type defined there; values of one are treated as values of the other transparently.
3. Internal storage 3.1. Interaction of the WebAssembly Store with JavaScriptNote: WebAssembly semantics are defined in terms of an abstract store, representing the state of the WebAssembly abstract machine. WebAssembly operations take a store and return an updated store.
Each agent has an associated store. When a new agent is created, its associated store is set to the result of store_init().
Note: In this specification, no WebAssembly-related objects, memory or addresses can be shared among agents in an agent cluster. In a future version of WebAssembly, this may change.
Elements of the WebAssembly store may be identified with JavaScript values. In particular, each WebAssembly memory instance with a corresponding Memory
object is identified with a JavaScript Data Block; modifications to this Data Block are identified to updating the agent’s store to a store which reflects those changes, and vice versa.
Note: There are several WebAssembly objects that may have a corresponding JavaScript object. The correspondence is stored in a per-agent mapping from WebAssembly addresses 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 maps:
The Memory object cache, mapping memory addresses to Memory
objects.
The Table object cache, mapping table addresses to Table
objects.
The Exported Function cache, mapping function addresses to Exported Function objects.
The Exported GC Object cache, mapping struct addresses and array addresses to Exported GC Object objects.
The Global object cache, mapping global addresses to Global
objects.
The Tag object cache, mapping tag addresses to Tag
objects.
The Exception object cache, mapping exception addresses to Exception
objects.
The Host value cache, mapping host addresses to values.
Note: The Execution Context Status Map is used to enforce certain correspondences between JavaScript execution and WebAssembly execution; particularly in relation to the JavaScript Promise Integration API.
Each agent is associated with the following ordered map:
The Execution Context Status map is used to map execution contexts to stack status values.
dictionaryWebAssemblyInstantiatedSource
{ required Modulemodule
; required Instanceinstance
; }; [Exposed=*] namespaceWebAssembly
{ boolean validate(BufferSourcebytes
); Promise<Module> compile(BufferSourcebytes
); Promise<WebAssemblyInstantiatedSource> instantiate( BufferSourcebytes
, optional objectimportObject
); Promise<Instance> instantiate( ModulemoduleObject
, optional objectimportObject
); readonly attribute Tag JSTag; };
The
validate(bytes)
method, when invoked, performs the following steps:
Let stableBytes be a copy of the bytes held by the buffer bytes.
Compile stableBytes as a WebAssembly module and store the results as module.
If module is error, return false.
Return true.
A Module
object represents a single WebAssembly module. Each Module
object has the following internal slots:
[[Module]] : a WebAssembly module
[[Bytes]] : the source bytes of [[Module]].
To
construct a WebAssembly module objectfrom a module
moduleand source bytes
bytes, perform the following steps:
Let moduleObject be a new Module
object.
Set moduleObject.[[Module]] to module.
Set moduleObject.[[Bytes]] to bytes.
Return moduleObject.
To
read the importsfrom a WebAssembly module
modulefrom imports object
importObject, perform the following steps:
If module.imports is not empty, and importObject is undefined, throw a TypeError
exception.
Let imports be « ».
For each (moduleName, componentName, externtype) of module_imports(module),
If externtype is of the form func functype,
If IsCallable(v) is true,
If v has a [[FunctionAddress]] internal slot, and therefore is an Exported Function,
Let funcaddr be the value of v’s [[FunctionAddress]] internal slot.
Otherwise,
Create a host function from v and functype, and let funcaddr be the result.
Otherwise, if v has a [[WrappedFunction]] internal slot,
Let func be the value of v’s [[WrappedFunction]] internal slot.
Assert: IsCallable(func) is true.
create a suspending function from func and functype, and let funcaddr be the result.
Otherwise, throw a LinkError
exception.
Let index be the number of external functions in imports. This value index is known as the index of the host function funcaddr.
Let externfunc be the external value func funcaddr.
Append externfunc to imports.
If externtype is of the form global mut valtype,
If v implements Global
,
Let globaladdr be v.[[Global]].
Otherwise,
If valtype is i64 and Type(v) is not BigInt,
Throw a LinkError
exception.
If valtype is one of i32, f32 or f64 and Type(v) is not Number,
Throw a LinkError
exception.
If valtype is v128,
Throw a LinkError
exception.
Let value be ToWebAssemblyValue(v, valtype). If this operation throws a TypeError
, catch it, and throw a LinkError
exception.
Let store be the surrounding agent's associated store.
Let (store, globaladdr) be global_alloc(store, const valtype, value).
Set the surrounding agent's associated store to store.
Let externglobal be global globaladdr.
Append externglobal to imports.
If externtype is of the form mem memtype,
If externtype is of the form table tabletype,
If externtype is of the form tag attribute functype,
Return imports.
Note: This algorithm only verifies the right kind of JavaScript values are passed. The verification of WebAssembly type requirements is deferred to the "instantiate the core of a WebAssembly module" algorithm.
To
create an exports objectfrom a WebAssembly module
moduleand instance
instance, perform the following steps:
Let exportsObject be ! OrdinaryObjectCreate(null).
For each (name, externtype) of module_exports(module),
Let externval be instance_export(instance, name).
Assert: externval is not error.
If externtype is of the form func functype,
Assert: externval is of the form func funcaddr.
Let func funcaddr be externval.
Let func be the result of creating a new Exported Function from funcaddr.
Let value be func.
If externtype is of the form global mut globaltype,
Assert: externval is of the form global globaladdr.
Let global globaladdr be externval.
Let global be a new Global object created from globaladdr.
Let value be global.
If externtype is of the form mem memtype,
Assert: externval is of the form mem memaddr.
Let mem memaddr be externval.
Let memory be a new Memory object created from memaddr.
Let value be memory.
If externtype is of the form table tabletype,
Assert: externval is of the form table tableaddr.
Let table tableaddr be externval.
Let table be a new Table object created from tableaddr.
Let value be table.
If externtype is of the form tag attribute functype,
Assert: attribute is exception.
Assert: externval is of the form tag tagaddr.
Let tag tagaddr be externval.
Let tag be a new Tag object created from tagaddr.
Let value be tag.
Let status be ! CreateDataProperty(exportsObject, name, value).
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.
Perform ! SetIntegrityLevel(exportsObject, "frozen"
).
Return exportsObject.
To
initialize an instance object instanceObjectfrom a WebAssembly module
moduleand instance
instance, perform the following steps:
Create an exports object from module and instance and let exportsObject be the result.
Set instanceObject.[[Instance]] to instance.
Set instanceObject.[[Exports]] to exportsObject.
To
instantiate the core of a WebAssembly modulefrom a module
moduleand imports
imports, perform the following steps:
Let store be the surrounding agent's associated store.
Let result be module_instantiate(store, module, imports).
If result is error, throw an appropriate exception type:
A LinkError
exception for most cases which occur during linking.
If the error came when running the start function, throw a RuntimeError
for most errors which occur from WebAssembly, or the error object propagated from inner ECMAScript code.
Another error type if appropriate, for example an out-of-memory exception, as documented in the WebAssembly error mapping.
Let (store, instance) be result.
Set the surrounding agent's associated store to store.
Return instance.
To
asynchronously instantiate a WebAssembly modulefrom a
Module
moduleObject
and imports
importObject, perform the following steps:
Let promise be a new promise.
Let module be moduleObject.[[Module]].
Read the imports of module with imports importObject, and let imports be the result. If this operation throws an exception, catch it, reject promise with the exception, and return promise.
Run the following steps in parallel:
Queue a task to perform the following steps: Note: Implementation-specific work may be performed here.
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.
Initialize instanceObject from module and instance. If this throws an exception, catch it, reject promise with the exception, and terminate these substeps.
Resolve promise with instanceObject.
Return promise.
Note: A follow-on streaming API is documented in the WebAssembly Web API.
The getter of the JSTag
attribute of the WebAssembly
Namespace, when invoked, performs the following steps:
Let JSTagAddr be the result of getting the JavaScript exception tag.
Let JSTagObject be the result of creating a Tag object from JSTagAddr.
Return JSTagObject.
enumImportExportKind
{"function"
,"table"
,"memory"
,"global"
,"tag"
}; dictionaryModuleExportDescriptor
{ required USVStringname
; required ImportExportKindkind
; // Note: Other fields such as signature may be added in the future. }; dictionaryModuleImportDescriptor
{ required USVStringmodule
; required USVStringname
; required ImportExportKindkind
; }; [LegacyNamespace=WebAssembly, Exposed=*] interfaceModule
{ constructor(BufferSourcebytes
); static sequence<ModuleExportDescriptor> exports(ModulemoduleObject
); static sequence<ModuleImportDescriptor> imports(ModulemoduleObject
); static sequence<ArrayBuffer> customSections(ModulemoduleObject
, DOMStringsectionName
); };
The
string value of the extern type typeis
"function" if type is of the form func functype
"table" if type is of the form table tabletype
"memory" if type is of the form mem memtype
"global" if type is of the form global globaltype
"tag" if type is of the form tag tag
The
customSections(moduleObject, sectionName)
method, when invoked, performs the following steps:
Let bytes be moduleObject.[[Bytes]].
Let customSections be « ».
For each custom section customSection of bytes, interpreted according to the module grammar,
Let name be the name
of customSection, decoded as UTF-8.
Assert: name is not failure (moduleObject.[[Module]] is valid).
If name equals sectionName as string values,
Append a new ArrayBuffer
containing a copy of the bytes in bytes for the range matched by this customsec production to customSections.
Return customSections.
The
Module(bytes)
constructor, when invoked, performs the following steps:
Let stableBytes be a copy of the bytes held by the buffer bytes.
Compile the WebAssembly module stableBytes and store the result as module.
If module is error, throw a CompileError
exception.
Set this.[[Module]] to module.
Set this.[[Bytes]] to stableBytes.
Note: Some implementations enforce a size limitation on bytes. Use of this API is discouraged, in favor of asynchronous APIs.
4.2. Instances[LegacyNamespace=WebAssembly, Exposed=*] interfaceInstance
{ constructor(Modulemodule
, optional objectimportObject
); readonly attribute object exports; };
The
Instance(module, importObject)
constructor, when invoked, runs the following steps:
Let module be module.[[Module]].
Read the imports of module with imports importObject, and let imports be the result.
Instantiate the core of a WebAssembly module module with imports, and let instance be the result.
Initialize this from module and instance.
Note: The use of this synchronous API is discouraged, as some implementations sometimes do long-running compilation work when instantiating.
The getter of the
exports
attribute of
Instance
returns
this.[[Exports]].
4.3. MemoriesdictionaryMemoryDescriptor
{ required [EnforceRange] unsigned longinitial
; [EnforceRange] unsigned longmaximum
; }; [LegacyNamespace=WebAssembly, Exposed=*] interfaceMemory
{ constructor(MemoryDescriptordescriptor
); unsigned long grow([EnforceRange] unsigned longdelta
); ArrayBuffer toFixedLengthBuffer(); ArrayBuffer toResizableBuffer(); readonly attribute ArrayBuffer buffer; };
A Memory
object represents a single memory instance which can be simultaneously referenced by multiple Instance
objects. Each Memory
object has the following internal slots:
[[Memory]] : a memory address
[[BufferObject]] : an ArrayBuffer
whose Data Block is identified with the above memory address
To
create a fixed length memory bufferfrom a
memory address memaddr, perform the following steps:
Let block be a Data Block which is identified with the underlying memory of memaddr.
Let buffer be a new ArrayBuffer
with the internal slots [[ArrayBufferData]], [[ArrayBufferByteLength]], and [[ArrayBufferDetachKey]].
Set buffer.[[ArrayBufferData]] to block.
Set buffer.[[ArrayBufferByteLength]] to the length of block.
Set buffer.[[ArrayBufferDetachKey]] to "WebAssembly.Memory".
Return buffer.
To
create a resizable memory bufferfrom a
memory address memaddrand a
maxsize, perform the following steps:
Let block be a Data Block which is identified with the underlying memory of memaddr.
Let length be the length of block.
If maxsize > (65536 × 65536),
Throw a RangeError
exception.
Let buffer be a new ArrayBuffer
with the internal slots [[ArrayBufferData]], [[ArrayBufferByteLength]], [[ArrayBufferMaxByteLength]], and [[ArrayBufferDetachKey]].
Set buffer.[[ArrayBufferData]] to block.
Set buffer.[[ArrayBufferByteLength]] to length.
Set buffer.[[ArrayBufferMaxByteLength]] is maxsize.
Set buffer.[[ArrayBufferDetachKey]] to "WebAssembly.Memory".
Return buffer.
The
Memory(descriptor)
constructor, when invoked, performs the following steps:
Let initial be descriptor["initial"].
If descriptor["maximum"] exists, let maximum be descriptor["maximum"]; otherwise, let maximum be empty.
If maximum is not empty and maximum < initial, throw a RangeError
exception.
Let memtype be { min initial, max maximum }.
Let store be the surrounding agent's associated store.
Let (store, memaddr) be mem_alloc(store, memtype). If allocation fails, throw a RangeError
exception.
Set the surrounding agent's associated store to store.
Initialize this from memaddr.
The
grow(delta)
method, when invoked, performs the following steps:
Let memaddr be this.[[Memory]].
Return the result of growing the memory buffer associated with memaddr by delta.
Immediately after a WebAssembly memory.grow instruction executes, perform the following steps:
The
toFixedLengthBuffer()
method, when invoked, performs the following steps:
Let buffer be this.[[BufferObject]].
If IsFixedLengthArrayBuffer(buffer) is true, return buffer.
Let memaddr be this.[[Memory]].
Let fixedBuffer be the result of creating a fixed length memory buffer from memaddr.
Perform ! DetachArrayBuffer(buffer, "WebAssembly.Memory").
Set this.[[BufferObject]] to fixedBuffer.
Return fixedBuffer.
The
toResizableBuffer()
method, when invoked, performs the following steps:
Let buffer be this.[[BufferObject]].
If IsFixedLengthArrayBuffer(buffer) is false, return buffer.
Let memaddr be this.[[Memory]].
Let store be the surrounding agent's associated store.
Let memtype be mem_type(store, memaddr).
If memtype has a max,
Let maxsize be the max value in memtype.
Otherwise,
Let maxsize be 65536 × 65536.
Let resizableBuffer be the result of creating a resizable memory buffer from memaddr and maxsize.
Perform ! DetachArrayBuffer(buffer, "WebAssembly.Memory").
Set this.[[BufferObject]] to resizableBuffer.
Return resizableBuffer.
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.
The abstract operation HostResizeArrayBuffer takes arguments buffer (an ArrayBuffer
) and newLength. It performs the following steps when called.
If buffer.[[ArrayBufferDetachKey]] is "WebAssembly.Memory",
Let map be the surrounding agent's associated Memory object cache.
Assert: buffer is the [[BufferObject]] of exactly one value in map.
For each memaddr → mem in map,
If SameValue(mem.[[BufferObject]], buffer) is true,
Assert: buffer.[[ArrayBufferByteLength]] modulo 65536 is 0.
Let lengthDelta be newLength - buffer.[[ArrayBufferByteLength]].
If lengthDelta < 0 or lengthDelta modulo 65536 is not 0,
Throw a RangeError
exception.
Let delta be lengthDelta ÷ 65536.
Grow the memory buffer associated with memaddr by delta.
Return handled .
Otherwise, return unhandled .
The getter of the
buffer
attribute of
Memory
returns
this.[[BufferObject]].
4.4. TablesenumTableKind
{"externref"
,"anyfunc"
, // Note: More values may be added in future iterations, // e.g., typed function references, typed GC references }; dictionaryTableDescriptor
{ required TableKindelement
; required [EnforceRange] unsigned longinitial
; [EnforceRange] unsigned longmaximum
; }; [LegacyNamespace=WebAssembly, Exposed=*] interfaceTable
{ constructor(TableDescriptordescriptor
, optional anyvalue
); unsigned long grow([EnforceRange] unsigned longdelta
, optional anyvalue
); any get([EnforceRange] unsigned longindex
); undefined set([EnforceRange] unsigned longindex
, optional anyvalue
); readonly attribute unsigned long length; };
A Table
object represents a single table instance which can be simultaneously referenced by multiple Instance
objects. Each Table
object has a [[Table]] internal slot, which is a table address.
The
Table(descriptor, value)
constructor, when invoked, performs the following steps:
Let elementType be ToValueType(descriptor["element"]).
If elementType is not a reftype,
Throw a TypeError
exception.
Let initial be descriptor["initial"].
If descriptor["maximum"] exists, let maximum be descriptor["maximum"]; otherwise, let maximum be empty.
If maximum is not empty and maximum < initial, throw a RangeError
exception.
If value is missing,
Let ref be DefaultValue(elementType).
Assert: ref is not error.
Otherwise,
Let ref be ? ToWebAssemblyValue(value, elementType).
Let type be the table type {min initial, max maximum} elementType.
Let store be the surrounding agent's associated store.
Let (store, tableaddr) be table_alloc(store, type, ref).
Set the surrounding agent's associated store to store.
Initialize this from tableaddr.
The
grow(delta, value)
method, when invoked, performs the following steps:
Let tableaddr be this.[[Table]].
Let store be the surrounding agent's associated store.
Let initialSize be table_size(store, tableaddr).
Let (limits, elementType) be table_type(tableaddr).
If value is missing,
Let ref be DefaultValue(elementType).
Otherwise,
Let ref be ? ToWebAssemblyValue(value, elementType).
Let result be table_grow(store, tableaddr, delta, ref).
If result is error, throw a RangeError
exception.
Note: The above exception can happen due to either insufficient memory or an invalid size parameter.
Set the surrounding agent's associated store to result.
Return initialSize.
The
set(index, value)
method, when invoked, performs the following steps:
Let tableaddr be this.[[Table]].
Let store be the surrounding agent's associated store.
Let (limits, elementType) be table_type(store, tableaddr).
If elementType is exnref,
Throw a TypeError
exception.
If value is missing,
Let ref be DefaultValue(elementType).
Otherwise,
Let ref be ? ToWebAssemblyValue(value, elementType).
Let store be the surrounding agent's associated store.
Let store be table_write(store, tableaddr, index, ref).
If store is error, throw a RangeError
exception.
Set the surrounding agent's associated store to store.
enumValueType
{"i32"
,"i64"
,"f32"
,"f64"
,"v128"
,"externref"
,"anyfunc"
, };
Note: this type may be extended with additional cases in future versions of WebAssembly.
dictionaryGlobalDescriptor
{ required ValueTypevalue
; booleanmutable
= false; }; [LegacyNamespace=WebAssembly, Exposed=*] interfaceGlobal
{ constructor(GlobalDescriptordescriptor
, optional anyv
); any valueOf(); attribute any value; };
A Global
object represents a single global instance which can be simultaneously referenced by multiple Instance
objects. Each Global
object has one internal slot:
[[Global]] : a global address
The algorithm
ToValueType(
s) performs the following steps:
If s equals "i32", return i32.
If s equals "i64", return i64.
If s equals "f32", return f32.
If s equals "f64", return f64.
If s equals "v128", return v128.
If s equals "anyfunc", return funcref.
If s equals "externref", return externref.
Assert: This step is not reached.
The
Global(descriptor, v)
constructor, when invoked, performs the following steps:
Let mutable be descriptor["mutable"].
Let valuetype be ToValueType(descriptor["value"]).
If valuetype is v128 or exnref,
Throw a TypeError
exception.
If v is missing,
Let value be DefaultValue(valuetype).
Assert: value is not error.
Otherwise,
Let value be ToWebAssemblyValue(v, valuetype).
If mutable is true, let globaltype be var valuetype; otherwise, let globaltype be const valuetype.
Let store be the current agent’s associated store.
Let (store, globaladdr) be global_alloc(store, globaltype, value).
Set the current agent’s associated store to store.
Initialize this from globaladdr.
The algorithm
GetGlobalValue(
Global
global
) performs the following steps:
Let store be the current agent’s associated store.
Let globaladdr be global.[[Global]].
Let globaltype be global_type(store, globaladdr).
If globaltype is of the form mut valuetype where valuetype is v128 or exnref, throw a TypeError
.
Let value be global_read(store, globaladdr).
Return ToJSValue(value).
The getter of the
value
attribute of
Global
, when invoked, performs the following steps:
Return GetGlobalValue(this).
The setter of the value attribute of Global
, when invoked, performs the following steps:
Let store be the current agent’s associated store.
Let globaladdr be this.[[Global]].
Let mut valuetype be global_type(store, globaladdr).
Let value be ToWebAssemblyValue(the given value, valuetype).
Let store be global_write(store, globaladdr, value).
If store is error, throw a RangeError
exception.
Set the current agent’s associated store to store.
The
valueOf()
method, when invoked, performs the following steps:
Return GetGlobalValue(this).
A WebAssembly function is made available in JavaScript as an Exported Function. Exported Functions are Built-in Function Objects which are not constructors, and which have a [[FunctionAddress]] internal slot. This slot holds a function address relative to the surrounding agent's associated store.
The
name of the WebAssembly function funcaddris found by performing the following steps:
Let store be the surrounding agent's associated store.
Let funcinst be store.funcs[funcaddr].
If funcinst is of the form {type functype, hostcode hostfunc},
Assert: hostfunc is a JavaScript object and IsCallable(hostfunc) is true.
Let index be the index of the host function funcaddr.
Otherwise,
Let moduleinst be funcinst.module.
Assert: funcaddr is contained in moduleinst.funcaddrs.
Let index be the index of moduleinst.funcaddrs where funcaddr is found.
To
coerce JavaScript argumentsfrom a
functypeand a
listof JavaScript arguments
argValues, perform the following steps
Let [parameters] → [results] be functype.
If parameters or results contain v128 or exnref, throw a TypeError
. Note: the above error is thrown each time the [[Call]] method is invoked.
Let args be « ».
Let i be 0.
For each t of parameters,
If argValues’s size > i, let arg be argValues[i].
Otherwise, let arg be undefined.
Append ToWebAssemblyValue(arg, t) to args.
Set i to i + 1.
return args.
To
call an Exported Functionwith
function address funcaddrand a
listof JavaScript arguments
argValues, perform the following steps:
Let store be the surrounding agent's associated store.
Let functype be func_type(store, funcaddr).
Let args be the result of coercing arguments (functype,argValues).
Let (store, ret) be the result of func_invoke(store, funcaddr, args).
Set the surrounding agent's associated store to store.
If ret is error, throw an exception. This exception must be a WebAssembly RuntimeError
exception, unless otherwise indicated by the WebAssembly error mapping.
If ret is THROW ref.exn exnaddr, then:
Let tagaddr be exn_tag(store, exnaddr).
Let payload be exn_read(store, exnaddr).
Let jsTagAddr be the result of getting the JavaScript exception tag.
If tagaddr is equal to jsTagAddr,
Throw the result of retrieving a host value from payload[0].
Otherwise,
Let exception be a new Exception created from exnaddr.
Throw exception.
Let outArity be the size of ret.
If outArity is 0, return undefined.
Otherwise, if outArity is 1, return ToJSValue(ret[0]).
Otherwise,
Let values be « ».
For each r of ret,
Return CreateArrayFromList(values).
Note: Calling an Exported Function executes in the [[Realm]] of the callee Exported Function, as per the definition of built-in function objects.
Note: Exported Functions do not have a [[Construct]] method and thus it is not possible to call one with the new
operator.
To
coerce WebAssembly argumentsfrom a
listof
parameterTypesand a
listof JavaScript arguments
arguments, perform the following steps
Let jsArguments be « ».
For each arg of arguments,
Return jsArguments.
To
coerce a JavaScript returnfrom a JavaScript
retand a list of
resultstypes, perform the following steps:
Let resultsSize be results’s size.
If resultsSize is 0, return « ».
Otherwise, if resultsSize is 1, return « ? ToWebAssemblyValue(ret, results[0]) ».
Otherwise,
Let method be ? GetMethod(ret, %Symbol.iterator%
).
Let values be ? IteratorToList(? GetIteratorFromMethod(ret, method)).
Let wasmValues be a new, empty list.
If values’s size is not resultsSize, throw a TypeError
exception.
For each value and resultType in values and results, paired linearly,
Append ToWebAssemblyValue(value, resultType) to wasmValues.
Return wasmValues.
The algorithm
ToJSValue(
w) coerces a
WebAssembly valueto a JavaScript value by performing the following steps:
Assert: w is not of the form v128.const v128.
Assert: w is not of the form ref.exn exnaddr.
If w is of the form i64.const u64,
If w is of the form i32.const i32,
If w is of the form f32.const f32,
If w is of the form f64.const f64,
If w is of the form ref.null t, return null.
If w is of the form ref.i31 u31,
If w is of the form ref.struct structaddr, return the result of creating a new Exported GC Object from structaddr and "struct".
If w is of the form ref.array arrayaddr, return the result of creating a new Exported GC Object from arrayaddr and "array".
If w is of the form ref.func funcaddr, return the result of creating a new Exported Function from funcaddr.
If w is of the form ref.host hostaddr, return the result of retrieving a host value from hostaddr.
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.
The algorithm
ToWebAssemblyValue(
v,
type) coerces a JavaScript value to a
WebAssembly valueby performing the following steps:
Assert: type is not v128.
Assert: type is not exnref.
If type is i64,
Let i64 be ? ToBigInt64(v).
Let u64 be the unsigned integer such that i64 is signed_64(u64).
Return i64.const u64.
If type is i32,
If type is f32,
If type is f64,
If type is of the form ref null heaptype,
If v is null,
Let r be ref.null heaptype.
Else if match_valtype(type, ref null extern),
Let ref be ToWebAssemblyValue(v, ref any).
Let r be ref.extern ref.
Else if v is an Exported Function and match_valtype(type, ref null func),
Let funcaddr be the value of v’s [[FunctionAddress]] internal slot.
Let r be ref.func funcaddr.
Else if v is a Number and v is equal to ? ToInt32(v) and ℝ(v) < 230 and ℝ(v) ⩾ -230,
Else if v is an Exported GC Object,
Let objectaddr be the value of v’s [[ObjectAddress]] internal slot.
Let objectkind be the value of v’s [[ObjectKind]] internal slot.
If objectkind is "array",
Let r be ref.array objectaddr.
If objectkind is "struct",
Let r be ref.struct objectaddr.
Else,
Let map be the surrounding agent's associated host value cache.
If a host address hostaddr exists such that map[hostaddr] is the same as v,
Return ref.host hostaddr.
Let host address hostaddr be the smallest address such that map[hostaddr] exists is false.
Set map[hostaddr] to v.
Let r be ref.host hostaddr.
Let store be the current agent’s associated store.
Let actualtype be ref_type(store, r).
If match_valtype(actualtype, type) is false,
Throw a TypeError
.
Return r.
Assert: This step is not reached.
Note: The JavaScript Promise Integration API (JSPI) allows WebAssembly functions to suspend and resume their execution -- based on the behavior of JavaScript functions that return Promise objects.
A Suspending
marker object represents a JavaScript function whose calls via WebAssembly imports should be suspended when they return a Promise object. Each Suspending
marker object has a [[WrappedFunction]] internal slot which holds a JavaScript function.
In addition, the promising
function takes as argument a WebAssembly function and returns a JavaScript function that returns a Promise that is resolved when the WebAssembly function completes.
Each agent maintains a Execution Context Status map, mapping from execution contexts to a status symbol. The purpose of this map is to ensure that applications do not try to suspend JavaScript frames and also to ensure that calls to imports marked with a Suspending
marker object are properly balanced by corresponding uses of WebAssembly.promising
.
If present, a status can be one of two stack status values:
active. This signals that the associated execution context is actively executing and has the potential to be paused.
paused. This signals that the associated execution is not currently involved in computation and has been paused.
If an execution context is not present in the status mapping, then it may not be paused or reentered.
When a new agent is created, its status mapping is set to the empty map.
[Exposed=*] partial namespace WebAssembly { Function promising(FunctionwasmFunc
); }; [LegacyNamespace=WebAssembly, Exposed=*] interfaceSuspending
{ constructor(FunctionjsFun
); };
The algorithm to
run a Promising functionfrom the JavaScript object
wasmFuncand a
listof
WebAssembly values argumentsconsists of the following steps:
Let promise be a new PromiseCapabilityRecord.
Let funcaddr be the value of wasmFunc’s [[FunctionAddress]] internal slot.
Let runner be a new AbstractClosure with no parameters that captures promise, funcaddr, and arguments and performs the following steps when called:
Perform evaluate a Promising function(promise,funcaddr,arguments).
Perform ?AsyncFunctionStart(promise,runner).
Return promise.
The algorithm to
evaluate a Promising function(
promise,
funcaddr,
arguments) consists of the following steps:
Let store be the surrounding agent's associated store.
Let functype be func_type(store, funcaddr).
Let args be the result of coercing arguments (functype,arguments).
Let map be the surrounding agent's associated Execution Context Status map.
Let ec be the currently executing execution context, i.e., the execution context that is at the top of the surrounding agent's current execution context stack.
Assert: map does not contain any entry for ec.
Add an entry mapping ec to active in map.
Let (store, result) be the result of func_invoke(store, funcaddr, args).
Assert: If control reaches here, we have done waiting for suspended imports.
If the entry for ec in map is not active then throw a WebAssembly SuspendError
exception. Otherwise, remove the entry for ec from map.
Set the surrounding agent's associated store to store.
If result is error, throw a WebAssembly RuntimeError
exception, unless otherwise indicated by the WebAssembly error mapping.
Otherwise, if result is of the form throw exnaddr,
Reject promise with result.
Otherwise,
Assert: result is a list of WebAssembly values.
Let outArity be the size of result.
If outArity is 0, return undefined.
Otherwise, if outArity is 1, let jsReturnValue be ToJSValue(result[0]).
Otherwise,
Let values be « ».
For each r of result,
Let jsReturnValue be CreateArrayFromList(values).
Resolve promise with jsReturnValue.
Return UNUSED.
The
Suspending(jsFun)
constructor, when invoked, performs the following steps:
If IsCallable(jsFun) is false, throw a TypeError
.
Let suspendingProto be \[[%WebAssembly.Suspending.prototype%]].
Let susp be the result of OrdinaryObjectCreate(suspendingProto,«[[WrappedFunction]]»).
Set susp.[[WrappedFunction]] to jsFun.
Return susp.
To
create a suspending functionfrom a JavaScript function
func, with type
functypeperform the following steps:
Assert: IsCallable(func).
Let stored settings be the incumbent settings object.
Let hostfunc be a host function which performs the following steps when called with arguments arguments:
Let realm be func’s associated Realm.
Let relevant settings be realm’s settings object.
Let async_context be the surrounding agent's running execution context.
Let map be the surrounding agent's associated Execution Context Status map.
If the entry for async_context in map is not active, then:
Perform throw a JavaScript exception with a SuspendError
exception.
Prepare to run script with relevant settings.
Prepare to run a callback with stored settings.
Let [parameters] → [resultTypes] be functype.
Let jsArguments be the result of coerce WebAssembly arguments(parameters,arguments).
Let ret be Completion(Call(func, undefined, jsArguments)).
Clean up after running a callback with stored settings.
Clean up after running script with relevant settings.
Assert: ret.[[Type]] is throw or normal .
If ret.[[Type]] is throw , then:
Let type, payload and opaqueData be the result of coercing the JavaScript exception ret.[[Value]].
Throw with type, payload and opaqueData.
Otherwise, if size of ret is 1 and IsPromise(ret.[[Value]][0]):
Let promise be ret.[[Value]][0].
Set the entry for async_context in map to paused.
Let awaitResult be the result of performing Completion(Await(promise)).
Note: We only invoke Await if the call to func has returned a Promise object.
Note: This will suspend both this algorithm, and the WebAssembly function being invoked by the evaluate a Promising function algorithm. On return, ret will be either a normal completion or a throw completion.
If the entry for async_context in map is not paused then:
Perform throw a JavaScript exception with a SuspendError
.
Otherwise, set the entry to active.
If awaitResult.[[Type]] is throw , then:
Let type, payload and opaqueData be the result of coercing the JavaScript exception ret.[[Value]].
Throw with type, payload and opaqueData.
Otherwise, return the result of performing coerce a JavaScript return on resultTypes and awaitResult.
Otherwise, return the result of performing coerce a JavaScript return on resultTypes and ret.
Let store be the surrounding agent's associated store.
Let (store, funcaddr) be func_alloc(store, functype, hostfunc).
Set the surrounding agent's associated store to store.
Return funcaddr.
The tag_alloc(store, parameters) algorithm creates a new tag address for parameters in store and returns the updated store and the tag address.
4.8.1. Tag typesdictionaryTagType
{ required sequence<ValueType>parameters
; }; [LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)] interfaceTag
{ constructor(TagTypetype
); };
A Tag
value represents an exception tag.
A WebAssembly struct or array is made available in JavaScript as an Exported GC Object. 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.
The
[[GetPrototypeOf]] internal method of an Exported GC Object Otakes no arguments and returns null. It performs the following steps when called:
Return null.
The
[[SetPrototypeOf]] internal method of an Exported GC Object Otakes argument
V(an Object or null) and returns a boolean. It performs the following steps when called:
Return false.
The
[[IsExtensible]] internal method of an Exported GC Object Otakes no arguments and returns a boolean. It performs the following steps when called:
Return false.
The
[[PreventExtensions]] internal method of an Exported GC Object Otakes no arguments and returns a boolean. It performs the following steps when called:
Return false.
The
[[GetOwnProperty]] internal method of an Exported GC Object Otakes argument
P(a property key) and returns undefined. It performs the following steps when called:
Return undefined.
The
[[DefineOwnProperty]] internal method of an Exported GC Object Otakes arguments
P(a property key) and
Desc(a property descriptor) and returns a boolean. It performs the following steps when called:
Return false.
The
[[HasProperty]] internal method of an Exported GC Object Otakes argument
P(a property key) and returns a boolean. It performs the following steps when called:
Return false.
The
[[Get]] internal method of an Exported GC Object Otakes arguments
P(a property key) and
Receiver(an ECMAScript language value) and returns undefined. It performs the following steps when called:
Return undefined.
The
[[Set]] internal method of an Exported GC Object Otakes arguments
P(a property key),
V(an ECMAScript language value), and
Receiver(an ECMAScript language value) and throws an exception. It performs the following steps when called:
Throw a TypeError
.
The
[[Delete]] internal method of an Exported GC Object Otakes argument
P(a property key) and throws an exception. It performs the following steps when called:
Throw a TypeError
.
The
[[OwnPropertyKeys]] internal method of an Exported GC Object Otakes no arguments and returns a list. It performs the following steps when called:
Let keys be a new empty list.
Return keys.
dictionaryExceptionOptions
{ booleantraceStack
= false; }; [LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)] interfaceException
{ constructor(TagexceptionTag
, sequence<any>payload
, optional ExceptionOptionsoptions
= {}); any getArg([EnforceRange] unsigned longindex
); boolean is(TagexceptionTag
); readonly attribute (DOMString or undefined) stack; };
An Exception
value represents an exception.
The new Exception(exceptionTag, payload, options)
constructor steps are:
Let JSTagAddr be the result of getting the JavaScript exception tag.
If exceptionTag.[[Address]] is equal to JSTagAddr,
Throw a TypeError
.
Let store be the surrounding agent's associated store.
Let [types] → [] be tag_type(store, exceptionTag.[[Address]]).
If types’s size is not payload’s size,
Throw a TypeError
.
Let wasmPayload be « ».
For each value and resultType of payload and types, paired linearly,
Let (store, exceptionAddr) be exn_alloc(store, exceptionTag.[[Address]], wasmPayload).
Set the surrounding agent's associated store to store.
Initialize this from exceptionAddr.
If options["traceStack"] is true,
Set this.[[Stack]] to either a DOMString
representation of the current call stack or undefined.
The is(exceptionTag)
method steps are:
If this.[[Type]] is not equal to exceptionTag.[[Address]],
Return false.
Return true.
The stack
getter steps are:
Return this.[[Stack]].
The JavaScript exception tag 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 » → « ».
4.11. Error ObjectsWebAssembly defines the following Error classes: CompileError
, LinkError
, RuntimeError
, and SuspendError
.
When the
namespace objectfor the
WebAssembly
namespace is
created, the following steps must be run:
Let namespaceObject be the namespace object.
For each error of « "CompileError", "LinkError", "RuntimeError", "SuspendError" »,
Let constructor be a new object, implementing the NativeError Object Structure, with NativeError set to error.
! DefineMethodProperty(namespaceObject, error, constructor, false).
Note: This defines CompileError
, LinkError
, RuntimeError
, and SuspendError
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.
5. Error Condition Mappings to JavaScriptRunning 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.
5.1. Stack OverflowWhenever 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.
Whenever validation, compilation or instantiation run out of memory, the same class of exception is thrown as for out of memory conditions in JavaScript. The particular exception here is implementation-defined in both cases.
Note: ECMAScript doesn’t specify any sort of behavior on out-of-memory conditions; implementations have been observed to throw OOMError and to crash. Either is valid here.
A failed allocation of a large table or memory may either result in
a RangeError
, as specified in the Memory
grow()
and 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 for further discussion.
6. Implementation-defined LimitsThe 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.
array.new_fixed
is 10,000.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.
This section is non-normative.
This document defines a host environment for WebAssembly. It enables a WebAssembly instance to import JavaScript objects and functions from an import object, but otherwise provides no access to the embedding environment. Thus a WebAssembly instance is bound to the same constraints as JavaScript.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4