1. Sample API Usage
This 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. Internal storage
2.1. Interaction of the WebAssembly Store with JavaScript
Note: WebAssembly semantics are defined in terms of an abstract store, representing the state of the WebAssembly abstract machine. WebAssembly operations take a store and return an updated store.
Each agent has an associated store. When a new agent is created, its associated store is set to the result of store_init().
Note: In this specification, no WebAssembly-related objects, memory or addresses can be shared among agents in an agent cluster. In a future version of WebAssembly, this may change.
Elements of the WebAssembly store may be identified with JavaScript values. In particular, each WebAssembly memory instance with a corresponding Memory
object is identified with a JavaScript Data Block; modifications to this Data Block are identified to updating the agent’s store to a store which reflects those changes, and vice versa.
2.2. WebAssembly JS Object Caches
Note: There are several WebAssembly objects that may have a corresponding JavaScript object. The correspondence is stored in a per-agent mapping from WebAssembly 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 Global object cache, mapping global addresses to
Global
objects.
3. The WebAssembly Namespace
dictionary {
WebAssemblyInstantiatedSource required Module ;
module required Instance ; }; [
instance Exposed =(Window ,Worker ,Worklet )]namespace {
WebAssembly boolean validate (BufferSource );
bytes Promise <Module >compile (BufferSource );
bytes Promise <WebAssemblyInstantiatedSource >instantiate (BufferSource ,
bytes optional object );
importObject Promise <Instance >instantiate (Module ,
moduleObject optional object ); };
importObject
-
Let module be module_decode(bytes). If module is error, return error.
-
If module_validate(module) is error, return error.
-
Return module.
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.
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]].
-
Let moduleObject be a new
Module
object. -
Set moduleObject.[[Module]] to module.
-
Set moduleObject.[[Bytes]] to bytes.
-
Return moduleObject.
-
Let promise be a new promise.
-
Run the following steps in parallel:
-
Compile the WebAssembly module bytes and store the result as module.
-
Queue a task to perform the following steps. If taskSource was provided, queue the task on that task source.
-
If module is error, reject promise with a
CompileError
exception. -
Otherwise,
-
Construct a WebAssembly module object from module and bytes, and let moduleObject be the result.
-
Resolve promise with moduleObject.
-
-
-
-
Return promise.
compile(bytes)
method, when invoked, performs the following steps:
-
Let stableBytes be a copy of the bytes held by the buffer bytes.
-
Asynchronously compile a WebAssembly module from stableBytes and return the result.
-
If module.𝗂𝗆𝗉𝗈𝗋𝗍𝗌 is not an empty list, and importObject is undefined, throw a
TypeError
exception. -
Let imports be an empty list of external values.
-
For each (moduleName, componentName, externtype) in module_imports(module), do
-
Let o be ? Get(importObject, moduleName).
-
Let v be ? Get(o, componentName)
-
If externtype is of the form 𝖿𝗎𝗇𝖼 functype,
-
If IsCallable(v) is false, throw a
LinkError
exception. -
If v has a [[FunctionAddress]] internal slot, and therefore is an Exported Function,
-
Let funcaddr be the value of v’s [[FunctionAddress]] internal slot.
Note: The signature is checked by module_instantiate invoked below.
-
-
Otherwise,
-
Create a host function from v and functype, and let funcaddr be the result.
-
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 𝖿𝗎𝗇𝖼 funcaddr.
-
Append externfunc to imports.
-
-
If externtype is of the form 𝗀𝗅𝗈𝖻𝖺𝗅 mut valtype,
-
If Type(v) is Number,
-
Let value be ToWebAssemblyValue(v, valtype)
-
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.
-
If v is a
Global
instance,-
Let globaladdr be v.[[Global]]
-
-
Otherwise,
-
Throw a
LinkError
exception.
-
-
Let externglobal be 𝗀𝗅𝗈𝖻𝖺𝗅 globaladdr.
-
Append externglobal to imports.
-
-
If externtype is of the form 𝗆𝖾𝗆 memtype,
-
Note: module_instantiate invoked below will check the imported
Memory
's size against the importing module’s requirements. -
Let externmem be the external value 𝗆𝖾𝗆 v.[[Memory]].
-
Append externmem to imports.
-
Otherwise, externtype is of the form 𝗍𝖺𝖻𝗅𝖾 tabletype,
-
Note: The table’s length, etc. is checked by module_instantiate invoked below.
-
Let tableaddr be v.[[Table]]
-
Let externtable be the external value 𝗍𝖺𝖻𝗅𝖾 tableaddr.
-
Append externtable to imports.
-
-
Return imports.
-
Let exportsObject be ! ObjectCreate(null).
-
For each pair (name, externtype) in module_exports(module),
-
Let externval be instance_export(instance, name).
-
Assert: externval is not error.
-
If externtype is of the form 𝖿𝗎𝗇𝖼 functype,
-
Assert: externval is of the form 𝖿𝗎𝗇𝖼 funcaddr.
-
Let 𝖿𝗎𝗇𝖼 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 𝗀𝗅𝗈𝖻𝖺𝗅 globaltype,
-
Assert: externval is of the form 𝗀𝗅𝗈𝖻𝖺𝗅 globaladdr.
-
Let 𝗀𝗅𝗈𝖻𝖺𝗅 globaladdr be externval.
-
Let global be a new Global object created from globaladdr.
-
Let value be global.
-
-
If externtype is of the form 𝗆𝖾𝗆 memtype,
-
Assert: externval is of the form 𝗆𝖾𝗆 memaddr.
-
Let 𝗆𝖾𝗆 memaddr be externval.
-
Let memory be a new Memory object created from memaddr.
-
Let value be memory.
-
-
Otherwise, externtype is of the form 𝗍𝖺𝖻𝗅𝖾 tabletype,
-
Assert: externval is of the form 𝗍𝖺𝖻𝗅𝖾 tableaddr.
-
Let 𝗍𝖺𝖻𝗅𝖾 tableaddr be externval.
-
Let table be a new Table object created from tableaddr.
-
Let value be table.
-
-
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.
-
Create an exports object from module and instance and let exportsObject be the result.
-
Set instanceObject.[[Instance]] to instance.
-
Set instanceObject.[[Exports]] to exportsObject.
-
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.
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.
-
Queue a task to perform the following steps:
-
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.
Module
moduleObject and imports importObject, perform the following steps:
-
Let module be moduleObject.[[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 instanceObject from module and instance.
-
Return instanceObject.
-
Let promise be a new promise
-
Upon fulfillment of promiseOfModule with value module:
-
Instantiate the WebAssembly module module importing importObject, and let instance be the result. If this throws an exception, catch it, reject promise with the exception, and abort these substeps.
-
Let result be a
WebAssemblyInstantiatedSource
dictionary withmodule
set to module andinstance
set to instance. -
Resolve promise with result.
-
-
Upon rejection of promiseOfModule with reason reason:
-
Reject promise with reason.
-
-
Return promise.
Note: It would be valid to perform certain parts of the instantiation in parallel, but several parts need to happen in the event loop, including JavaScript operations to access the importObject and execution of the start function.
instantiate(bytes, importObject)
method, when invoked, performs the following steps:
-
Let stableBytes be a copy of the bytes held by the buffer bytes.
-
Asynchronously compile a WebAssembly module from stableBytes and let promiseOfModule be the result.
-
Instantiate promiseOfModule with imports importObject and return the result.
instantiate(moduleObject, importObject)
method, when invoked, performs the following steps:
-
Asynchronously instantiate the WebAssembly module moduleObject importing importObject, and return the result.
Note: A follow-on streaming API is documented in the WebAssembly Web API.
3.1. Modules
enum {
ImportExportKind ,
"function" ,
"table" ,
"memory" };
"global" dictionary {
ModuleExportDescriptor required USVString ;
name required ImportExportKind ; // Note: Other fields such as signature may be added in the future. };
kind dictionary {
ModuleImportDescriptor required USVString ;
module required USVString ;
name required ImportExportKind ; }; [
kind LegacyNamespace =WebAssembly ,Constructor (BufferSource ),
bytes Exposed =(Window ,Worker ,Worklet )]interface {
Module static sequence <ModuleExportDescriptor >exports (Module );
moduleObject static sequence <ModuleImportDescriptor >imports (Module );
moduleObject static sequence <ArrayBuffer >customSections (Module ,
moduleObject DOMString ); };
sectionName
exports(moduleObject)
method, when invoked, performs the following steps:
-
Let module be moduleObject.[[Module]].
-
Let exports be an empty list.
-
For each (name, type) in module_exports(module)
-
Let kind be the string value of the extern type type.
-
Let obj be a new
ModuleExportDescriptor
dictionary withname
name andkind
kind. -
Append obj to the end of exports.
-
-
Return exports.
imports(moduleObject)
method, when invoked, performs the following steps:
-
Let module be moduleObject.[[Module]].
-
Let imports be an empty list.
-
For each (moduleName, name, type) in module_imports(module),
-
Let kind be the string value of the extern type type.
-
Let obj be a new
ModuleImportDescriptor
dictionary withmodule
moduleName,name
name andkind
kind. -
Append obj to the end of imports.
-
-
Return imports.
customSections(moduleObject, sectionName)
method, when invoked, performs the following steps:
-
Let bytes be moduleObject.[[Bytes]].
-
Let customSections be an empty list of
ArrayBuffer
s. -
For each custom section customSection in 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.
-
-
-
Return customSections.
Module(bytes)
constructor, when invoked, performs the follwing 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.
3.2. Instances
[LegacyNamespace =WebAssembly ,Constructor (Module ,
module optional object ),
importObject Exposed =(Window ,Worker ,Worklet )]interface {
Instance readonly attribute object exports ; };
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.
exports
attribute of Instance
returns this.[[Exports]]. 3.3. Memories
dictionary {
MemoryDescriptor required [EnforceRange ]unsigned long ; [
initial EnforceRange ]unsigned long ; }; [
maximum LegacyNamespace =WebAssembly ,Constructor (MemoryDescriptor ),
descriptor Exposed =(Window ,Worker ,Worklet )]interface {
Memory unsigned long grow ([EnforceRange ]unsigned long );
delta readonly attribute ArrayBuffer buffer ; };
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
-
Let block be a Data Block which is identified with the underlying memory of memaddr.
-
Let buffer be a new
ArrayBuffer
whose [[ArrayBufferData]] is block and [[ArrayBufferByteLength]] is set to the length of block. -
Set buffer.[[ArrayBufferDetachKey]] to "WebAssembly.Memory".
-
Return buffer.
-
Let map be the surrounding agent's associated Memory object cache.
-
Assert: map[memaddr] doesn’t exist.
-
Let buffer be a the result of creating a memory buffer from memaddr.
-
Set memory.[[Memory]] to memaddr.
-
Set memory.[[BufferObject]] to buffer.
-
Set map[memaddr] to memory.
-
Let map be the surrounding agent's associated Memory object cache.
-
If map[memaddr] exists,
-
Return map[memaddr].
-
-
Initialize memory from memaddr.
-
Return memory.
Memory(descriptor)
constructor, when invoked, performs the following steps:
-
let initial be descriptor["initial"].
-
If descriptor["maximum"] is present, 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.
-
Let map be the surrounding agent's associated Memory object cache.
-
Assert: map[memaddr] exists.
-
Let memory be map[memaddr].
-
Perform ! DetachArrayBuffer(memory.[[BufferObject]], "WebAssembly.Memory").
-
Let buffer be a the result of creating a memory buffer from memaddr.
-
Set memory.[[BufferObject]] to buffer.
grow(delta)
method, when invoked, performs the following steps:
-
Let store be the surrounding agent's associated store.
-
Let memaddr be this.[[Memory]].
-
Let ret be the mem_size(store, memaddr).
-
Let store be mem_grow(store, memaddr, delta).
-
If store is error, throw a
RangeError
exception. -
Set the surrounding agent's associated store to store.
-
Reset the memory buffer of memaddr.
-
Return ret.
Immediately after a WebAssembly memory.grow instruction executes, perform the following steps:
-
If the top of the stack is not 𝗂𝟥𝟤.𝖼𝗈𝗇𝗌𝗍 (−1), then:
-
Let frame be the current frame.
-
Reset the memory buffer of memaddr.
-
buffer
attribute of Memory
returns this.[[BufferObject]]. 3.4. Tables
enum {
TableKind , // Note: More values may be added in future iterations, // e.g., typed function references, typed GC references };
"anyfunc" dictionary {
TableDescriptor required TableKind ;
element required [EnforceRange ]unsigned long ; [
initial EnforceRange ]unsigned long ; }; [
maximum LegacyNamespace =WebAssembly ,Constructor (TableDescriptor ),
descriptor Exposed =(Window ,Worker ,Worklet )]interface {
Table unsigned long grow ([EnforceRange ]unsigned long );
delta Function ?get ([EnforceRange ]unsigned long );
index void set ([EnforceRange ]unsigned long ,
index Function ?);
value readonly attribute unsigned long length ; };
Table
object represents a single table instance which can be simultaneously referenced by multiple Instance
objects. Each Table
object has the following internal slots:
-
[[Table]] : a table address
-
[[Values]] : a List whose elements are either null or Exported Functions.
-
Let map be the surrounding agent's associated Table object cache.
-
Assert: map[tableaddr] doesn’t exist.
-
Let store be the surrounding agent's associated store.
-
Let values be a list whose length is table_size(store, tableaddr) where each element is null.
-
Set table.[[Table]] to tableaddr.
-
Set table.[[Values]] to values.
-
Set map[tableaddr] to table.
-
Let map be the surrounding agent's associated Table object cache.
-
If map[tableaddr] exists,
-
Return map[tableaddr].
-
-
Initialize table from tableaddr.
-
Return table.
Table(descriptor)
constructor, when invoked, performs the following steps:
-
let initial be descriptor["initial"].
-
If descriptor["maximum"] is present, let maximum be descriptor["maximum"]; otherwise, let maximum be empty.
-
If maximum is not empty and maximum < initial, throw a
RangeError
exception. -
Let type be the table type {𝗆𝗂𝗇 n, 𝗆𝖺𝗑 maximum} 𝖺𝗇𝗒𝖿𝗎𝗇𝖼.
-
Let store be the surrounding agent's associated store.
-
Let (store, tableaddr) be table_alloc(store, type).
-
Set the surrounding agent's associated store to store.
-
Initialize this from tableaddr.
grow(delta)
method, when invoked, performs the following steps:
-
Let tableaddr be this.[[Table]].
-
Let initialSize be the length of this.[[Values]].
-
Let store be the surrounding agent's associated store.
-
Let result be table_grow(store, tableaddr, delta).
-
If result is error, throw a
RangeError
exception.Note: The above exception may happen due to either insufficient memory or an invalid size parameter.
-
Set the surrounding agent's associated store to result.
-
Append null to this.[[Values]] delta times.
-
Return initialSize.
length
attribute of Table
returns the length of this.[[Values]]. get(index)
method, when invoked, performs the following steps:
-
Let values be this.[[Values]].
-
Let size be the length of values.
-
If index ≥ size, throw a
RangeError
exception. -
Return values[index].
set(index, value)
method, when invoked, performs the following steps:
-
Let tableaddr be this.[[Table]].
-
Let values be this.[[Values]].
-
If value is null, let funcaddr be an empty function element.
-
Otherwise,
-
If value does not have a [[FunctionAddress]] internal slot, throw a
TypeError
exception. -
Let funcaddr be value.[[FunctionAddress]].
-
-
Let store be the surrounding agent's associated store.
-
Let store be table_write(store, tableaddr, index, funcaddr).
-
If store is error, throw a
RangeError
exception. -
Set the surrounding agent's associated store to store.
-
Set values[index] to value.
-
Return undefined.
3.5. Globals
enum {
ValueType ,
"i32" ,
"i64" ,
"f32" };
"f64"
Note: this type may be extended with additional cases in future versions of WebAssembly.
dictionary {
GlobalDescriptor required ValueType ;
value boolean =
mutable false ; }; [LegacyNamespace =WebAssembly ,Constructor (GlobalDescriptor ,
descriptor optional any ),
v Exposed =(Window ,Worker ,Worklet )]interface {
Global any valueOf ();attribute any value ; };
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
-
Let map be the surrounding agent's associated Global object cache.
-
Assert: map[globaladdr] doesn’t exist.
-
Set global.[[Global]] to globaladdr.
-
Set map[globaladdr] to global.
-
Let map be the current agent's associated Global object cache.
-
If map[globaladdr] exists,
-
Return map[globaladdr].
-
-
Initialize global from globaladdr.
-
Return global.
Global(descriptor, v)
constructor, when invoked, performs the following steps:
-
Let mutable be descriptor["mutable"].
-
Let valuetype be ToValueType(descriptor["value"]).
-
If v is undefined,
-
let value be DefaultValue(valuetype).
-
-
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.
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).
-
Let value be global_read(store, globaladdr).
-
Return ToJSValue(value).
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 globaltype be global_type(store, globaladdr), where globaltype is of the form mut valuetype.
-
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.
valueOf()
method, when invoked, performs the following steps:
-
Return GetGlobalValue(this).
3.6. Exported Functions
A WebAssembly function is made available in JavaScript as an Exported Function. Exported Functions are Built-in Function Objects which are not constructors, and which have a [[FunctionAddress]] internal slot. This slot holds a function address relative to the surrounding agent's associated store.
-
Let store be the surrounding agent's associated store.
-
Let funcinst be store.𝖿𝗎𝗇𝖼𝗌[funcaddr].
-
If funcinst is of the form {𝗍𝗒𝗉𝖾 functype, 𝗁𝗈𝗌𝗍𝖼𝗈𝖽𝖾 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.𝗆𝗈𝖽𝗎𝗅𝖾.
-
Assert: funcaddr is contained in moduleinst.𝖿𝗎𝗇𝖼𝖺𝖽𝖽𝗋𝗌.
-
Let index be the index of moduleinst.𝖿𝗎𝗇𝖼𝖺𝖽𝖽𝗋𝗌 where funcaddr is found.
-
-
Return ! ToString(index).
-
Let map be the surrounding agent's associated Exported Function cache.
-
If map[funcaddr] exists,
-
Return map[funcaddr].
-
-
Let steps be "call the Exported Function funcaddr with arguments."
-
Let realm be the current Realm.
-
Let function be CreateBuiltinFunction(realm, steps, %FunctionPrototype%, « [[FunctionAddress]] »).
-
Set function.[[FunctionAddress]] to funcaddr.
-
Let store be the surrounding agent's associated store.
-
Let functype be func_type(store, funcaddr).
-
Let [paramTypes] → [resultTypes] be functype.
-
Let arity be the length of paramTypes.
-
Perform ! SetFunctionLength(function, arity).
-
Let name be the name of the WebAssembly function funcaddr.
-
Perform ! SetFunctionName(function, name).
-
Set map[funcaddr] to function.
-
Return function.
-
Let store be the surrounding agent's associated store.
-
Let functype be func_type(store, funcaddr).
-
Let [parameters] → [results] be functype.
-
If parameters or results contains an 𝗂𝟨𝟦, throw a
TypeError
.Note: the above error is thrown each time the [[Call]] method is invoked.
-
Let args be an empty list of WebAssembly values.
-
Let i be 0.
-
For each type t of parameters,
-
If the length of argValues > i, let arg be argValues[i].
-
Otherwise, let arg be undefined.
-
Append ToWebAssemblyValue(arg, t) to args.
-
Set i to i + 1.
-
-
Let argsSeq be a WebAssembly sequence containing the elements of args.
-
Let (store, ret) be the result of func_invoke(store, funcaddr, argsSeq).
-
Set the surrounding agent's associated store to store.
-
If ret is error, throw an exception. This exception should be a WebAssembly
RuntimeError
exception, unless otherwise indicated by the WebAssembly error mapping. -
If ret is empty, return undefined.
-
Otherwise, return ToJSValue(v), where v is the singular element of ret.
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.
-
Let [parameters] → [results] be functype.
-
Assert: results’s size is at most one.
-
If either parameters or results contains 𝗂𝟨𝟦, throw a
TypeError
. -
Let arguments be a list of the arguments of the invocation of this function.
-
Let jsArguments be an empty list.
-
For each arg in arguments,
-
Let ret be ? Call(func, undefined, jsArguments).
-
If results is empty, return undefined.
-
Otherwise, return ? ToWebAssemblyValue(ret, results[0]).
-
Let hostfunc be a host function which performs the following steps when called:
-
Let result be the result of running a host function from func and functype.
-
Assert: result.[[Type]] is throw or return.
-
If result.[[Type]] is throw, then trigger a WebAssembly trap, and propagate result.[[Value]] to the enclosing JavaScript.
-
Otherwise, return result.[[Value]].
-
-
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
-
Assert: w is not of the form 𝗂𝟨𝟦.𝖼𝗈𝗇𝗌𝗍 i64.
-
If w is of the form 𝗂𝟥𝟤.𝖼𝗈𝗇𝗌𝗍 i32, return the Number value for signed_32(i32).
-
If w is of the form 𝖿𝟥𝟤.𝖼𝗈𝗇𝗌𝗍 f32, return the Number value for f32.
-
If w is of the form 𝖿𝟨𝟦.𝖼𝗈𝗇𝗌𝗍 f64, return the Number value for f64.
Note: Number values which are equal to NaN may have various observable NaN payloads; see NumberToRawBytes for details.
3.7. Error Objects
WebAssembly defines the following Error classes: CompileError
, LinkError
, and RuntimeError
. WebAssembly errors have the following custom bindings:
-
Unlike normal interface types, the interface prototype object for these exception classes must have as its [[Prototype]] the intrinsic object %ErrorPrototype%.
-
The constructor and properties of WebAssembly errors is as specified for
NativeError
. -
If an implementation gives native Error objects special powers or nonstandard properties (such as a stack property), it should also expose those on these exception instances.
[LegacyNamespace =WebAssembly ]interface { }; [
CompileError LegacyNamespace =WebAssembly ]interface { }; [
LinkError LegacyNamespace =WebAssembly ]interface { };
RuntimeError
4. Error Condition Mappings to JavaScript
Running WebAssembly programs encounter certain events which halt execution of the WebAssembly code. WebAssembly code (currently) has no way to catch these conditions and thus an exception will necessarily propagate to the enclosing non-WebAssembly caller (whether it is a browser, JavaScript or another runtime system) where it is handled like a normal JavaScript exception.
If WebAssembly calls JavaScript via import and the JavaScript throws an exception, the exception is propagated through the WebAssembly activation to the enclosing caller.
Because JavaScript exceptions can be handled, and JavaScript can continue to call WebAssembly exports after a trap has been handled, traps do not, in general, prevent future execution.
4.1. Stack Overflow
Whenever a stack overflow occurs in WebAssembly code, the same class of exception is thrown as for a stack overflow in JavaScript. The particular exception here is implementation-defined in both cases.
Note: ECMAScript doesn’t specify any sort of behavior on stack overflow; implementations have been observed to throw RangeError
, InternalError or Error. Any is valid here.
4.2. Out of Memory
Whenever validation, compilation or instantiation run out of memory, the same class of exception is thrown as for out of memory conditions in JavaScript. The particular exception here is implementation-defined in both cases.
Note: ECMAScript doesn’t specify any sort of behavior on out-of-memory conditions; implementations have been observed to throw OOMError and to crash. Either is valid here.
-
a
RangeError
, as specified in theMemory
grow()
andTable
grow()
operations -
returning -1 as the memory.grow instruction
-
UA-specific OOM behavior as described in this section.
See Issue 879 for further discussion.
5. Implementation-defined Limits
The WebAssembly core specification allows an implementation to define limits on the syntactic structure of the module.
While each embedding of WebAssembly may choose to define its own limits, for predictability the standard WebAssembly JavaScript Interface described in this document defines the following exact limits.
An implementation must reject a module that exceeds these limits with a CompileError
.
In practice, an implementation may run out of resources for valid modules below these limits.
- The maximum size of a module is 1073741824 bytes (1 GiB).
- The maximum number of types defined in the types section is 1000000.
- The maximum number of functions defined in a module is 1000000.
- The maximum number of imports declared in a module is 100000.
- The maximum number of exports declared in a module is 100000.
- The maximum number of globals defined in a module is 1000000.
- The maximum number of data segments defined in a module is 100000.
- The maximum number of tables, including declared or imported tables, is 1.
- The maximum size of a table is 10000000.
- The maximum number of table entries in any table initialization is 10000000.
- The maximum number of memories, including declared or imported memories, is 1.
- The initial or maximum number of pages for any memory, declared or imported, is at most 32767.
- The maximum number of parameters to any function is 1000.
- The maximum number of return values for any function is 1.
- The maximum size of a function body, including locals declarations, is 7654321 bytes.
- The maximum number of locals declared in a function, including implicitly declared as parameters, is 50000.
6. Security and Privacy Considerations
This section is non-normative.
This document defines a host environment for WebAssembly. It enables a WebAssembly instance to import JavaScript objects and functions from an import object, but otherwise provides no access to the embedding environment. Thus a WebAssembly instance is bounds to the same constraints as JavaScript.
Changes
Changes since the previous Working Draft:
-
Used
noun_verb
format from core embedding API (e.g.init_store
becomes store_init). -
Asynchronously compile a WebAssembly module. Clarified how operations run in parallel.
-
Create an exports object. Changed to share text between various module instantiation methods.
-
Used this where appropriate.
-
Separated initialization and creation of
Memory
,Table
, andGlobal
objects. -
Defined the
Memory
.buffer getter. -
ToValueType, DefaultValue. Removed unreachable throw steps.
-
§ 5 Implementation-defined Limits. Added Implementation-defined Limits section.
-
§ 6 Security and Privacy Considerations. Added Security and Privacy Considerations section.