diff --git a/document/js-api/index.bs b/document/js-api/index.bs index 2648ff2563..f7679451f9 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -107,30 +107,32 @@ urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: df text: π–ΏπŸ¨πŸ¦.π–Όπ—ˆπ—‡π—Œπ— text: function index; url: syntax/modules.html#syntax-funcidx text: function instance; url: exec/runtime.html#function-instances - text: init_store; url: appendix/embedding.html#embed-init-store - text: decode_module; url: appendix/embedding.html#embed-decode-module - text: validate_module; url: appendix/embedding.html#embed-validate-module - text: instantiate_module; url: appendix/embedding.html#embed-instantiate-module - text: module_imports; url: appendix/embedding.html#embed-imports - text: get_export; url: appendix/embedding.html#embed-get-export - text: alloc_func; url: appendix/embedding.html#embed-alloc-func - text: type_func; url: appendix/embedding.html#embed-type-func - text: invoke_func; url: appendix/embedding.html#embed-invoke-func - text: alloc_table; url: appendix/embedding.html#embed-alloc-table - text: type_table; url: appendix/embedding.html#embed-type-table - text: read_table; url: appendix/embedding.html#embed-read-table - text: write_table; url: appendix/embedding.html#embed-write-table - text: grow_table; url: appendix/embedding.html#embed-grow-table - text: alloc_mem; url: appendix/embedding.html#embed-alloc-mem - text: type_mem; url: appendix/embedding.html#embed-type-mem - text: read_mem; url: appendix/embedding.html#embed-read-mem - text: write_mem; url: appendix/embedding.html#embed-write-mem - text: grow_mem; url: appendix/embedding.html#embed-grow-mem - text: alloc_global; url: appendix/embedding.html#embed-alloc-global - text: type_global; url: appendix/embedding.html#embed-type-global - text: read_global; url: appendix/embedding.html#embed-read-global - text: write_global; url: appendix/embedding.html#embed-write-global - text: module_exports; url: appendix/embedding.html#embed-exports + text: store_init; url: appendix/embedding.html#embed-store-init + text: module_decode; url: appendix/embedding.html#embed-module-decode + text: module_validate; url: appendix/embedding.html#embed-module-validate + text: module_instantiate; url: appendix/embedding.html#embed-module-instantiate + text: module_imports; url: appendix/embedding.html#embed-module-imports + text: module_exports; url: appendix/embedding.html#embed-module-exports + text: instance_export; url: appendix/embedding.html#embed-instance-export + text: func_alloc; url: appendix/embedding.html#embed-func-alloc + text: func_type; url: appendix/embedding.html#embed-func-type + text: func_invoke; url: appendix/embedding.html#embed-func-invoke + text: table_alloc; url: appendix/embedding.html#embed-table-alloc + text: table_type; url: appendix/embedding.html#embed-table-type + text: table_read; url: appendix/embedding.html#embed-table-read + text: table_write; url: appendix/embedding.html#embed-table-write + text: table_size; url: appendix/embedding.html#embed-table-size + text: table_grow; url: appendix/embedding.html#embed-table-grow + text: mem_alloc; url: appendix/embedding.html#embed-mem-alloc + text: mem_type; url: appendix/embedding.html#embed-mem-type + text: mem_read; url: appendix/embedding.html#embed-mem-read + text: mem_write; url: appendix/embedding.html#embed-mem-write + text: mem_size; url: appendix/embedding.html#embed-mem-size + text: mem_grow; url: appendix/embedding.html#embed-mem-grow + text: global_alloc; url: appendix/embedding.html#embed-global-alloc + text: global_type; url: appendix/embedding.html#embed-global-type + text: global_read; url: appendix/embedding.html#embed-global-read + text: global_write; url: appendix/embedding.html#embed-global-write text: error; url: appendix/embedding.html#embed-error text: store; url: exec/runtime.html#syntax-store text: table type; url: syntax/types.html#syntax-tabletype @@ -148,10 +150,9 @@ urlPrefix: https://webassembly.github.io/spec/core/; spec: WebAssembly; type: df text: external value; url: exec/runtime.html#syntax-externval text: host function; url: exec/runtime.html#syntax-hostfunc text: the instantiation algorithm; url: exec/modules.html#instantiation - text: size_table; url: appendix/embedding.html#embed-size-table - text: size_mem; url: appendix/embedding.html#embed-size-mem text: module; url: syntax/modules.html#syntax-module text: π—‚π—†π—‰π—ˆπ—‹π—π—Œ; url: syntax/modules.html#syntax-module + text: import; url: syntax/modules.html#syntax-import url: syntax/types.html#external-types text: external type text: π–Ώπ—Žπ—‡π–Ό @@ -221,7 +222,7 @@ fetch('demo.wasm').then(response => 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 [=init_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. @@ -229,7 +230,8 @@ Elements of the WebAssembly store may be identified with JavaScript v

WebAssembly JS Object Caches

-Note: There are several WebAssembly objects that may have a corresponding JavaScript object. The correspondence is stored in a per-agent mapping from WebAssembly [=address=]es to JavaScript objects. This mapping is used to ensure that, for a given [=agent=], there exists at most one JavaScript object for a particular WebAssembly address. +Note: There are several WebAssembly objects that may have a corresponding JavaScript object. The correspondence is stored in a per-agent mapping from WebAssembly [=address=]es to JavaScript objects. +This mapping is used to ensure that, for a given [=agent=], there exists at most one JavaScript object for a particular WebAssembly address. However, this property does not hold for shared objects. Each [=agent=] is associated with the following [=ordered map=]s: * The Memory object cache, mapping [=memory address=]es to {{Memory}} objects. @@ -270,8 +272,8 @@ Note:
To compile a WebAssembly module from source bytes |bytes|, perform the following steps: - 1. Let |module| be [=decode_module=](|bytes|). If |module| is [=error=], return [=error=]. - 1. If [=validate_module=](|module|) is [=error=], return [=error=]. + 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|.
@@ -303,12 +305,13 @@ A {{Module}} object represents a single WebAssembly module. Each {{Module}} obje To asynchronously compile a WebAssembly module from source bytes |bytes|, using optional [=task source=] |taskSource|, perform the following steps: 1. Let |promise| be [=a new promise=]. - 1. In parallel, [=compile a WebAssembly module|compile the WebAssembly module=] |bytes| and store the result as |module|. - 1. When the above operation completes, [=queue a task=] to perform the following steps. If |taskSource| was provided, queue the task on that task source. - 1. If |module| is [=error=], reject |promise| with a {{CompileError}} exception. - 1. Otherwise, - 1. [=Construct a WebAssembly module object=] from |module| and |bytes|, and let |moduleObject| be the result. - 1. [=Resolve=] |promise| with |moduleObject|. + 1. Run the following steps [=in parallel=]: + 1. [=compile a WebAssembly module|Compile the WebAssembly module=] |bytes| and store the result as |module|. + 1. [=Queue a task=] to perform the following steps. If |taskSource| was provided, queue the task on that task source. + 1. If |module| is [=error=], reject |promise| with a {{CompileError}} exception. + 1. Otherwise, + 1. [=Construct a WebAssembly module object=] from |module| and |bytes|, and let |moduleObject| be the result. + 1. [=Resolve=] |promise| with |moduleObject|. 1. Return |promise|. @@ -318,32 +321,31 @@ A {{Module}} object represents a single WebAssembly module. Each {{Module}} obje 1. [=Asynchronously compile a WebAssembly module=] from |stableBytes| and return the result. -
- To instantiate a WebAssembly module from a {{Module}} |moduleObject| and imports |importObject|, perform the following steps: - 1. Let |module| be |moduleObject|.\[[Module]]. +
+ To read the imports from a WebAssembly module |module| from imports object |importObject|, perform the following steps: 1. If |module|.[=π—‚π—†π—‰π—ˆπ—‹π—π—Œ=] is not an empty list, and |importObject| is undefined, throw a {{TypeError}} exception. 1. Let |imports| be an empty [=list=] of [=external value=]s. 1. For each (|moduleName|, |componentName|, |externtype|) in [=module_imports=](|module|), do 1. Let |o| be ? [=Get=](|importObject|, |moduleName|). - 1. If [=Type=](|o|) is not [=Object=], throw a {{TypeError}} exception. + 1. If [=Type=](|o|) is not Object, throw a {{TypeError}} exception. 1. Let |v| be ? [=Get=](|o|, |componentName|) 1. If |externtype| is of the form [=π–Ώπ—Žπ—‡π–Ό=] |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. - Note: The signature is checked by [=instantiate_module=] invoked below. + Note: The signature is checked by [=module_instantiate=] invoked below. 1. Otherwise, - 1. [=Create a host function=] from |v| and let |funcaddr| be the result. + 1. [=Create a host function=] from |v| and |functype|, and let |funcaddr| be the result. 1. Let |index| be the number of external functions in |imports|. This value |index| is known as the index of the host function |funcaddr|. 1. Let |externfunc| be the [=external value=] [=external value|π–Ώπ—Žπ—‡π–Ό=] |funcaddr|. 1. [=Append=] |externfunc| to |imports|. 1. If |externtype| is of the form [=π—€π—…π—ˆπ–»π–Ίπ—…=] mut |valtype|, - 1. If [=Type=](|v|) is [=Number=], + 1. If [=Type=](|v|) is Number, 1. If |valtype| is [=π—‚πŸ¨πŸ¦=], throw a {{LinkError}} exception. 1. Let |value| be [=ToWebAssemblyValue=](|v|, |valtype|) 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. - 1. Let (|store|, |globaladdr|) be [=alloc_global=](|store|, [=const=] |valtype|, |value|). + 1. Let (|store|, |globaladdr|) be [=global_alloc=](|store|, [=const=] |valtype|, |value|). 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. 1. If |v| is a {{Global}} instance, 1. Let |globaladdr| be |v|.\[[Global]] @@ -351,31 +353,27 @@ A {{Module}} object represents a single WebAssembly module. Each {{Module}} obje 1. Throw a {{LinkError}} exception. 1. Let |externglobal| be [=external value|π—€π—…π—ˆπ–»π–Ίπ—…=] |globaladdr|. 1. [=Append=] |externglobal| to |imports|. - 1. If |externtype| is of the form [=𝗆𝖾𝗆=] |memtype|, + 1. If |externtype| is of the form [=𝗆𝖾𝗆=] memtype, 1. If |v| is not a {{Memory}} object, throw a {{LinkError}} exception. - - Note: [=instantiate_module=] invoked below will check the imported {{Memory}}'s size against the importing module's requirements. - - 2. Let |externmem| be the [=external value=] [=external value|𝗆𝖾𝗆=] |v|.\[[Memory]]. + 1. Note: [=module_instantiate=] invoked below will check the imported {{Memory}}'s size against the importing module's requirements. + 1. Let |externmem| be the [=external value=] [=external value|𝗆𝖾𝗆=] |v|.\[[Memory]]. 1. [=Append=] |externmem| to |imports|. - 1. Otherwise, |externtype| is of the form [=𝗍𝖺𝖻𝗅𝖾=] |tabletype|, + 1. Otherwise, |externtype| is of the form [=𝗍𝖺𝖻𝗅𝖾=] tabletype, 1. If |v| is not a {{Table}} instance, throw a {{LinkError}} exception. - - Note: The table's length, etc. is checked by [=instantiate_module=] invoked below. - - 2. Let |tableaddr| be |v|.\[[Table]] + 1. Note: The table's length, etc. is checked by [=module_instantiate=] invoked below. + 1. Let |tableaddr| be |v|.\[[Table]] 1. Let |externtable| be the [=external value=] [=external value|𝗍𝖺𝖻𝗅𝖾=] |tableaddr|. 1. [=Append=] |externtable| to |imports|. - 1. Let (|store|, |instance|) be [=instantiate_module=](|store|, |module|, |imports|). - 1. If |instance| is [=error=], throw an appropriate exception type: - * A {{LinkError}} exception for most cases which occur during linking. - * If the error came when running the start function, throw a {{RuntimeError}} for most errors which occur from WebAssembly, or the error object propagated from inner ECMAScript code. - * Another error type if appropriate, for example an out-of-memory exception, as documented in the WebAssembly error mapping. + 1. Return |imports|. +
+ +
+ To create an exports object from a WebAssembly module |module| and instance |instance|, perform the following steps: 1. Let |exportsObject| be ! [=ObjectCreate=](null). 1. For each pair (|name|, |externtype|) in [=module_exports=](|module|), - 1. Let |externval| be [=get_export=](|instance|, |name|). + 1. Let |externval| be [=instance_export=](|instance|, |name|). 1. Assert: |externval| is not [=error=]. - 1. If |externtype| is of the form [=π–Ώπ—Žπ—‡π–Ό=] |functype|, + 1. If |externtype| is of the form [=π–Ώπ—Žπ—‡π–Ό=] functype, 1. Assert: |externval| is of the form [=external value|π–Ώπ—Žπ—‡π–Ό=] |funcaddr|. 1. Let [=external value|π–Ώπ—Žπ—‡π–Ό=] |funcaddr| be |externval|. 1. Let |func| be the result of creating [=a new Exported Function=] from |funcaddr|. @@ -385,12 +383,12 @@ A {{Module}} object represents a single WebAssembly module. Each {{Module}} obje 1. Let [=external value|π—€π—…π—ˆπ–»π–Ίπ—…=] |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 [=𝗆𝖾𝗆=] |memtype|, + 1. If |externtype| is of the form [=𝗆𝖾𝗆=] memtype, 1. Assert: |externval| is of the form [=external value|𝗆𝖾𝗆=] |memaddr|. 1. Let [=external value|𝗆𝖾𝗆=] |memaddr| be |externval|. 1. Let |memory| be [=create a memory object|a new Memory object=] created from |memaddr|. 1. Let |value| be |memory|. - 1. Otherwise, |externtype| is of the form [=𝗍𝖺𝖻𝗅𝖾=] |tabletype|, + 1. Otherwise, |externtype| is of the form [=𝗍𝖺𝖻𝗅𝖾=] tabletype, 1. Assert: |externval| is of the form [=external value|𝗍𝖺𝖻𝗅𝖾=] |tableaddr|. 1. Let [=external value|𝗍𝖺𝖻𝗅𝖾=] |tableaddr| be |externval|. 1. Let |table| be [=create a Table object|a new Table object=] created from |tableaddr|. @@ -400,7 +398,53 @@ A {{Module}} object represents a single WebAssembly module. Each {{Module}} obje 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. Let |instanceObject| be a new {{Instance}} object whose internal \[[Instance]] slot is set to |instance| and the \[[Exports]] slot to |exportsObject|. + 1. Return |exportsObject|. +
+ +
+ To initialize an instance object |instanceObject| from a WebAssembly module |module| and instance |instance|, perform the following steps: + + 1. [=Create an exports object=] from |module| and |instance| and let |exportsObject| be the result. + 1. Set |instanceObject|.\[[Instance]] to |instance|. + 1. Set |instanceObject|.\[[Exports]] to |exportsObject|. +
+ +
+ To instantiate the core of a WebAssembly module from a module |module| and imports |imports|, perform the following steps: + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Let |result| be [=module_instantiate=](|store|, |module|, |imports|). + 1. If |result| is [=error=], throw an appropriate exception type: + * A {{LinkError}} exception for most cases which occur during linking. + * If the error came when running the start function, throw a {{RuntimeError}} for most errors which occur from WebAssembly, or the error object propagated from inner ECMAScript code. + * Another error type if appropriate, for example an out-of-memory exception, as documented in the WebAssembly error mapping. + 1. Let (|store|, |instance|) be |result|. + 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. + 1. Return |instance|. +
+ +
+ To asynchronously instantiate a WebAssembly module from a {{Module}} |moduleObject| and imports |importObject|, perform the following steps: + 1. Let |promise| be [=a new promise=]. + 1. Let |module| be |moduleObject|.\[[Module]]. + 1. [=Read the imports=] of |module| with imports |importObject|, and let |imports| be the result. + If this operation throws an exception, catch it, [=reject=] |promise| with the exception, and return |promise|. + 1. [=Queue a task=] to perform the following steps: + 1. [=Instantiate the core of a WebAssembly module=] |module| with |imports|, and let |instance| be the result. + If this throws an exception, catch it, [=reject=] |promise| with the exception, and terminate these substeps. + 1. Let |instanceObject| be a [=/new=] {{Instance}}. + 1. [=initialize an instance object|Initialize=] |instanceObject| from |module| and |instance|. + If this throws an exception, catch it, [=reject=] |promise| with the exception, and terminate these substeps. + 1. [=Resolve=] |promise| with |instanceObject|. + 1. Return |promise|. +
+ +
+ To instantiate a WebAssembly module from a {{Module}} |moduleObject| and imports |importObject|, perform the following steps: + 1. Let |module| be |moduleObject|.\[[Module]]. + 1. [=Read the imports=] of |module| with imports |importObject|, and let |imports| be the result. + 1. [=Instantiate the core of a WebAssembly module=] |module| with |imports|, and let |instance| be the result. + 1. Let |instanceObject| be a [=/new=] {{Instance}}. + 1. [=initialize an instance object|Initialize=] |instanceObject| from |module| and |instance|. 1. Return |instanceObject|.
@@ -428,11 +472,7 @@ A {{Module}} object represents a single WebAssembly module. Each {{Module}} obje
The instantiate(|moduleObject|, |importObject|) method, when invoked, performs the following steps: - 1. Let |promise| be [=a new promise=]. - 1. [=Queue a task=] to perform the following steps: - 1. [=instantiate a WebAssembly module|Instantiate the WebAssembly module=] |moduleObject| importing |importObject|, and let |instance| be the result. If this throws an exception, catch it, and [=reject=] |promise| with the exception. - 1. [=Resolve=] |promise| with |instance|. - 1. Return |promise| + 1. [=asynchronously instantiate a WebAssembly module|Asynchronously instantiate the WebAssembly module=] |moduleObject| importing |importObject|, and return the result.
Note: A follow-on streaming API is documented in the WebAssembly Web API. @@ -463,7 +503,7 @@ dictionary ModuleImportDescriptor { interface Module { static sequence<ModuleExportDescriptor> exports(Module moduleObject); static sequence<ModuleImportDescriptor> imports(Module moduleObject); - static sequence<ArrayBuffer> customSections(Module moduleObject, USVString sectionName); + static sequence<ArrayBuffer> customSections(Module moduleObject, DOMString sectionName); }; @@ -515,7 +555,8 @@ interface Module { 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. [=Construct a WebAssembly module object=] from |module| and |stableBytes|, and return the result. + 1. Set **this**.\[[Module]] to |module|. + 1. Set **this**.\[[Bytes]] to |stableBytes|.

Instances

@@ -528,11 +569,15 @@ interface Instance {
- The Instance(|module|, |importObject|) constructor, when invoked, [=instantiate a WebAssembly module|instantiates the WebAssembly module=] |module| importing |importObject| and returns the result. + The Instance(|module|, |importObject|) constructor, when invoked, runs the following steps: + 1. Let |module| be |module|.\[[Module]]. + 1. [=Read the imports=] of |module| with imports |importObject|, and let |imports| be the result. + 1. [=Instantiate the core of a WebAssembly module=] |module| with |imports|, and let |instance| be the result. + 1. [=initialize an instance object|Initialize=] **this** from |module| and |instance|.
- The getter of the exports attribute of {{Instance}} returns the receiver's \[[Exports]] internal slot. + The getter of the exports attribute of {{Instance}} returns **this**.\[[Exports]].

Memories

@@ -568,15 +613,24 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each 1. Return |buffer|. +
+ To initialize a memory object |memory| from a [=memory address=] |memaddr|, perform the following steps: + 1. Let |map| be the [=surrounding agent=]'s associated [=Memory object cache=]. + 1. Assert: |map|[|memaddr|] doesn't [=map/exist=]. + 1. Let |buffer| be a the result of [=create a memory buffer|creating a memory buffer=] from |memaddr|. + 1. Set |memory|.\[[Memory]] to |memaddr|. + 1. Set |memory|.\[[BufferObject]] to |buffer|. + 1. [=map/Set=] |map|[|memaddr|] to |memory|. +
+
To create a memory object from a [=memory address=] |memaddr|, perform the following steps: 1. Let |map| be the [=surrounding agent=]'s associated [=Memory object cache=]. 1. If |map|[|memaddr|] [=map/exists=], 1. Return |map|[|memaddr|]. - 1. Let |buffer| be a the result of [=create a memory buffer|creating a memory buffer=] from |memaddr|. - 1. Let |memory| be a new {{Memory}} instance with \[[Memory]] set to |memaddr| and \[[BufferObject]] set to |buffer|. - 1. [=map/Set=] |map|[|memaddr|] to |memory|. + 1. Let |memory| be a [=/new=] {{Memory}}. + 1. [=initialize a memory object|Initialize=] |memory| from |memaddr|. 1. Return |memory|.
@@ -587,16 +641,16 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each 1. If |maximum| is not empty and |maximum| < |initial|, throw a {{RangeError}} exception. 1. Let |memtype| be { min |initial|, max |maximum| } 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. - 1. Let (|store|, |memaddr|) be [=alloc_mem=](|store|, |memtype|). If allocation fails, throw a {{RangeError}} exception. + 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. [=Create a memory object=] from the memory address |memaddr| and return the result. + 1. [=initialize a memory object|Initialize=] **this** from |memaddr|.
To reset the Memory buffer of |memaddr|, perform the following steps: 1. Let |map| be the [=surrounding agent=]'s associated [=Memory object cache=]. - 1. Assert: |map|[|memaddr|] [=map/exists=] + 1. Assert: |map|[|memaddr|] [=map/exists=]. 1. Let |memory| be |map|[|memaddr|]. 1. Perform ! [=DetachArrayBuffer=](|memory|.\[[BufferObject]], "WebAssembly.Memory"). 1. Let |buffer| be a the result of [=create a memory buffer|creating a memory buffer=] from |memaddr|. @@ -605,11 +659,10 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each
The grow(|delta|) method, when invoked, performs the following steps: - 1. Let |memory| be the Memory instance. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. - 1. Let |memaddr| be |memory|.\[[Memory]]. - 1. Let |ret| be the [=size_mem=](|store|, |memaddr|). - 1. Let |store| be [=grow_mem=](|store|, |memaddr|, |delta|). + 1. Let |memaddr| be **this**.\[[Memory]]. + 1. Let |ret| be the [=mem_size=](|store|, |memaddr|). + 1. Let |store| be [=mem_grow=](|store|, |memaddr|, |delta|). 1. If |store| is [=error=], throw a {{RangeError}} exception. 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. 1. [=Reset the memory buffer=] of |memaddr|. @@ -627,7 +680,7 @@ Immediately after a WebAssembly [=memory.grow=] instruction executes, perform th
- The getter of the buffer attribute of {{Memory}} returns the receiver's \[[BufferObject]] internal slot. + The getter of the buffer attribute of {{Memory}} returns **this**.\[[BufferObject]].

Tables

@@ -663,15 +716,24 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each * \[[Values]] : a List whose elements are either null or [=Exported Function=]s.
+
+ To initialize a table object |table| from a [=table address=] |tableaddr|, perform the following steps: + 1. Let |map| be the [=surrounding agent=]'s associated [=Table object cache=]. + 1. Assert: |map|[|tableaddr|] doesn't [=map/exist=]. + 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. + 1. Let |values| be a list whose length is [=table_size=](|store|, |tableaddr|) where each element is null. + 1. Set |table|.\[[Table]] to |tableaddr|. + 1. Set |table|.\[[Values]] to |values|. + 1. [=map/Set=] |map|[|tableaddr|] to |table|. +
+
To create a table object from a [=table address=] |tableaddr|, perform the following steps: 1. Let |map| be the [=surrounding agent=]'s associated [=Table object cache=]. 1. If |map|[|tableaddr|] [=map/exists=], 1. Return |map|[|tableaddr|]. - 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. - 1. Let |values| be a list whose length is [=size_table=](|store|, |tableaddr|) where each element is null. - 1. Let |table| be a new {{Table}} instance with \[[Table]] set to |tableaddr| and \[[Values]] set to |values|. - 1. [=map/Set=] |map|[|tableaddr|] to |table|. + 1. Let |table| be a [=/new=] {{Table}}. + 1. [=initialize a table object|Initialize=] |table| from |tableaddr|. 1. Return |table|.
@@ -682,33 +744,33 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each 1. If |maximum| is not empty and |maximum| < |initial|, throw a {{RangeError}} exception. 1. Let |type| be the [=table type=] {[=table type|𝗆𝗂𝗇=] n, [=table type|𝗆𝖺𝗑=] |maximum|} [=table type|π–Ίπ—‡π—’π–Ώπ—Žπ—‡π–Ό=]. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. - 1. Let (|store|, |tableaddr|) be [=alloc_table=](|store|, |type|). + 1. Let (|store|, |tableaddr|) be [=table_alloc=](|store|, |type|). 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. - 1. [=Create a table object=] from the table address |tableaddr| and return the result. + 1. [=initialize a table object|Initialize=] **this** from |tableaddr|.
The grow(|delta|) method, when invoked, performs the following steps: - 1. Let |tableaddr| be the Table instance's \[[Table]] internal slot. - 1. Let |initialSize| be the length of the Table instance's \[[Values]] internal slot. + 1. Let |tableaddr| be **this**.\[[Table]]. + 1. Let |initialSize| be the length of **this**.\[[Values]]. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. - 1. Let |result| be [=grow_table=](|store|, |tableaddr|, |delta|). + 1. Let |result| be [=table_grow=](|store|, |tableaddr|, |delta|). 1. If |result| is [=error=], throw a {{RangeError}} exception. Note: The above exception may happen due to either insufficient memory or an invalid size parameter. 1. Set the [=surrounding agent=]'s [=associated store=] to |result|. - 1. [=Append=] null to the Table instance's \[[Values]] internal slot |delta| times. + 1. [=Append=] null to **this**.\[[Values]] |delta| times. 1. Return |initialSize|.
- The getter of the length attribute of {{Table}} returns the length of the table's \[[Values]] internal slot. + The getter of the length attribute of {{Table}} returns the length of **this**.\[[Values]].
The get(|index|) method, when invoked, performs the following steps: - 1. Let |values| be the Table instance's \[[Values]] internal slot. + 1. Let |values| be **this**.\[[Values]]. 1. Let |size| be the length of |values|. 1. If |index| ≥ |size|, throw a {{RangeError}} exception. 1. Return |values|[|index|]. @@ -716,14 +778,14 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each
The set(|index|, |value|) method, when invoked, performs the following steps: - 1. Let |tableaddr| be the Table instance's \[[Table]] internal slot. - 1. Let |values| be the Table instance's \[[Values]] internal slot. + 1. Let |tableaddr| be **this**.\[[Table]]. + 1. Let |values| be **this**.\[[Values]]. 1. If |value| is null, let |funcaddr| be an empty [=function element=]. 1. Otherwise, 1. If |value| does not have a \[[FunctionAddress]] internal slot, throw a {{TypeError}} exception. 1. Let |funcaddr| be |value|.\[[FunctionAddress]]. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. - 1. Let |store| be [=write_table=](|store|, |tableaddr|, |index|, |funcaddr|). + 1. Let |store| be [=table_write=](|store|, |tableaddr|, |index|, |funcaddr|). 1. If |store| is [=error=], throw a {{RangeError}} exception. 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. 1. Set |values|[|index|] to |value|. @@ -732,9 +794,20 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each

Globals

+
+enum ValueType {
+  "i32",
+  "i64",
+  "f32",
+  "f64"
+};
+
+ +Note: this type may be extended with additional cases in future versions of WebAssembly. +
 dictionary GlobalDescriptor {
-  required USVString value;
+  required ValueType value;
   boolean mutable = false;
 };
 
@@ -753,13 +826,21 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each
     * \[[Global]] : a [=global address=]
 
+
+ To initialize a global object |global| from a [=global address=] |globaladdr|, perform the following steps: + 1. Let |map| be the [=surrounding agent=]'s associated [=Global object cache=]. + 1. Assert: |map|[|globaladdr|] doesn't [=map/exist=]. + 1. Set |global|.\[[Global]] to |globaladdr|. + 1. [=map/Set=] |map|[|globaladdr|] to |global|. +
+
To create a global object from a [=global address=] |globaladdr|, perform the following steps: 1. Let |map| be the current [=agent=]'s associated [=Global object cache=]. 1. If |map|[|globaladdr|] [=map/exists=], 1. Return |map|[|globaladdr|]. - 1. Let |global| be a new {{Global}} instance with \[[Global]] set to |globaladdr|. - 1. [=map/Set=] |map|[|globaladdr|] to |global|. + 1. Let |global| be a [=/new=] {{Global}}. + 1. [=initialize a global object|Initialize=] |global| from |globaladdr|. 1. Return |global|.
@@ -769,7 +850,6 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each 1. If |s| equals "i64", return [=π—‚πŸ¨πŸ¦=]. 1. If |s| equals "f32", return [=𝖿πŸ₯𝟀=]. 1. If |s| equals "f64", return [=π–ΏπŸ¨πŸ¦=]. - 1. Otherwise, throw a {{TypeError}} exception.
@@ -792,43 +872,40 @@ which can be simultaneously referenced by multiple {{Instance}} objects. Each 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 [=alloc_global=](|store|, |globaltype|, |value|). + 1. Let (|store|, |globaladdr|) be [=global_alloc=](|store|, |globaltype|, |value|). 1. Set the current agent's [=associated store=] to |store|. - 1. [=Create a global object=] from the global address |globaladdr| and return the result. + 1. [=initialize a global object|Initialize=] **this** from |globaladdr|.
The algorithm GetGlobalValue({{Global}} |global|) performs the following steps: 1. Let |store| be the current agent's [=associated store=]. 1. Let |globaladdr| be |global|.\[[Global]]. - 1. Let |globaltype| be [=type_global=](|store|, |globaladdr|). + 1. Let |globaltype| be [=global_type=](|store|, |globaladdr|). 1. If |globaltype| is of the form mut [=π—‚πŸ¨πŸ¦=], throw a {{TypeError}}. - 1. Let |value| be [=read_global=](|store|, |globaladdr|). + 1. Let |value| be [=global_read=](|store|, |globaladdr|). 1. Return [=ToJSValue=](|value|).
The getter of the value attribute of {{Global}}, when invoked, performs the following steps: - 1. Let |global| be the {{Global}} instance. - 1. Return [=GetGlobalValue=](|global|). + 1. Return [=GetGlobalValue=](**this**). - The setter of the value attribute of {{Global}}, when invoked with a value |v|, performs the following steps: - 1. Let |global| be the {{Global}} instance. + 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 |global|.\[[Global]]. - 1. Let |globaltype| be [=type_global=](|store|, |globaladdr|), where |globaltype| is of the form |mut| |valuetype|. + 1. Let |globaladdr| be **this**.\[[Global]]. + 1. Let |globaltype| be [=global_type=](|store|, |globaladdr|), where |globaltype| is of the form |mut| |valuetype|. 1. If |mut| is [=const=], throw a {{TypeError}}. 1. If |valuetype| is [=π—‚πŸ¨πŸ¦=], throw a {{TypeError}}. - 1. Let |value| be [=ToWebAssemblyValue=](|v|, |valuetype|). - 1. Let |store| be [=write_global=](|store|, |globaladdr|, |value|). + 1. Let |value| be [=ToWebAssemblyValue=](**the given value**, |valuetype|). + 1. Let |store| be [=global_write=](|store|, |globaladdr|, |value|). 1. If |store| is [=error=], throw a {{RangeError}} exception. 1. Set the current agent's [=associated store=] to |store|.
The valueOf() method, when invoked, performs the following steps: - 1. Let |global| be the {{Global}} instance. - 1. Return [=GetGlobalValue=](|global|). + 1. Return [=GetGlobalValue=](**this**).

Exported Functions

@@ -863,7 +940,7 @@ This slot holds a [=function address=] relative to the [=surrounding agent=]'s [ 1. Let |function| be [=CreateBuiltinFunction=](|realm|, |steps|, [=%FunctionPrototype%=], « \[[FunctionAddress]] »). 1. Set |function|.\[[FunctionAddress]] to |funcaddr|. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. - 1. Let |functype| be [=type_func=](|store|, |funcaddr|). + 1. Let |functype| be [=func_type=](|store|, |funcaddr|). 1. Let [|paramTypes|] β†’ [resultTypes] be |functype|. 1. Let |arity| be the length of |paramTypes|. 1. Perform ! [=SetFunctionLength=](|function|, |arity|). @@ -877,7 +954,7 @@ This slot holds a [=function address=] relative to the [=surrounding agent=]'s [ To call an Exported Function with [=function address=] |funcaddr| and a [=list=] of JavaScript arguments |argValues|, perform the following steps: 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. - 1. Let |functype| be [=type_func=](|store|, |funcaddr|). + 1. Let |functype| be [=func_type=](|store|, |funcaddr|). 1. Let [|parameters|] β†’ [|results|] be |functype|. 1. If |parameters| or |results| contains an [=π—‚πŸ¨πŸ¦=], throw a {{TypeError}}. @@ -891,7 +968,7 @@ This slot holds a [=function address=] relative to the [=surrounding agent=]'s [ 1. [=Append=] [=ToWebAssemblyValue=](|arg|, |t|) to |args|. 1. Set |i| to |i| + 1. 1. Let |argsSeq| be a WebAssembly [=sequence=] containing the elements of |args|. - 1. Let (|store|, |ret|) be the result of [=invoke_func=](|store|, |funcaddr|, |argsSeq|). + 1. Let (|store|, |ret|) be the result of [=func_invoke=](|store|, |funcaddr|, |argsSeq|). 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. 1. If |ret| is [=error=], throw an exception. This exception should be a WebAssembly {{RuntimeError}} exception, unless otherwise indicated by the WebAssembly error mapping. 1. Let |outArity| be the [=list/size=] of |ret|. @@ -908,29 +985,39 @@ Note: [=call an Exported Function|Calling an Exported Function=] executes in the Note: Exported Functions do not have a \[[Construct]] method and thus it is not possible to call one with the `new` operator.
- To create a host function from the JavaScript object |func|, perform the following steps: + To run a host function from the JavaScript object |func| and type |functype|, perform the following steps: + + 1. Let [|parameters|] β†’ [|results|] be |functype|. + 1. Assert: |results|'s [=list/size=] is at most one. + 1. If either |parameters| or |results| contains [=π—‚πŸ¨πŸ¦=], throw a {{TypeError}}. + 1. Let |arguments| be a [=list=] of the arguments of the invocation of this function. + 1. Let |jsArguments| be an empty [=list=]. + 1. For each |arg| in |arguments|, + 1. [=list/Append=] ! [=ToJSValue=](|arg|) to |jsArguments|. + 1. Let |ret| be ? [=Call=](|func|, undefined, |jsArguments|). + 1. If |results| [=list/is empty=], return undefined. + 1. Otherwise, if |results|'s [=list/size=] is 1, return ? [=ToWebAssemblyValue=](|ret|, |results|[0]). + 1. Otherwise, + 1. Let |method| be ? [=GetMethod=](|results|, @@iterator). + 1. If |method| is undefined, [=throw=] a {{TypeError}}. + 1. Let |values| be ? [=IterableToList=](|ret|, |method|). + 1. Let |wasmValues| be a new, empty [=list=]. + 1. Assert: |values| and |results| have the same length. + 1. For each |value| and |resultType| in |values| and |results|, paired linearly, + 1. [=list/Append=] [=ToWebAssemblyValue=](|value|, |resultType|) to |wasmValues|. + 1. Return |wasmValues|. +
+ +
+ To create a host function from the JavaScript object |func| and type |functype|, perform the following steps: 1. Let |hostfunc| be a [=host function=] which performs the following steps when called: - 1. If the signature contains an [=π—‚πŸ¨πŸ¦=] (as argument or result), the host function throws a {{TypeError}} when called. - 1. Let |arguments| be a [=list=] of the arguments of the invocation of this function. - 1. Let |jsArguments| be an empty [=list=]. - 1. For each |arg| in |arguments|, - 1. [=Append=] [=ToJSValue=](|arg|) to |jsArguments|. - 1. Let |ret| be ? [=Call=](|func|, undefined, |jsArguments|). If an exception is thrown, trigger a WebAssembly trap, and propagate the exception to the enclosing JavaScript. - 1. Let [parameters] β†’ [|results|] be |functype|. - 1. If |results| is empty, return undefined. - 1. Otherwise, if |results| contains a single element, return [=ToWebAssemblyValue=](|ret|, |results|[0]). - 1. Otherwise, - 1. Let |method| be ? [=GetMethod=](|results|, @@iterator). - 1. If |method| is undefined, [=throw=] a {{TypeError}}. - 1. Let |values| be ? [=IterableToList=](|ret|, |method|). - 1. Let |wasmValues| be a new, empty [=list=]. - 1. Assert: |values| and |results| have the same length. - 1. For each |value| and |resultType| in |values| and |results|, paired linearly, - 1. [=Append=] [=ToWebAssemblyValue=](|value|, |resultType|) to |wasmValues|. - 1. Return |wasmValues|. + 1. Let |result| be the result of [=run a host function|running a host function=] from |func| and |functype|. + 1. Assert: |result|.\[[Type]] is throw or return. + 1. If |result|.\[[Type]] is [=throw=], then trigger a WebAssembly trap, and propagate |result|.\[[Value]] to the enclosing JavaScript. + 1. Otherwise, return |result|.\[[Value]]. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. - 1. Let (|store|, |funcaddr|) be [=alloc_func=](|store|, |functype|, |hostfunc|). + 1. Let (|store|, |funcaddr|) be [=func_alloc=](|store|, |functype|, |hostfunc|). 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. 1. Return |funcaddr|
@@ -1048,8 +1135,14 @@ In practice, an implementation may run out of resources for valid modules below
  • 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 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.
  • + +

    Security and Privacy Considerations

    + +

    This section is non-normative.

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