diff --git a/document/js-api/index.bs b/document/js-api/index.bs index 1e4aa51d..1bd509b6 100644 --- a/document/js-api/index.bs +++ b/document/js-api/index.bs @@ -149,6 +149,7 @@ urlPrefix: https://webassembly.github.io/reference-types/core/; spec: WebAssembl text: memory address; url: exec/runtime.html#syntax-memaddr text: global address; url: exec/runtime.html#syntax-globaladdr text: extern address; url: exec/runtime.html#syntax-externaddr + text: tag address; url: exec/runtime.html#syntax-tagaddr url: syntax/types.html#syntax-numtype text: i32 text: i64 @@ -160,7 +161,10 @@ urlPrefix: https://webassembly.github.io/reference-types/core/; spec: WebAssembl text: externref text: function element; url: exec/runtime.html#syntax-funcelem text: import component; url: syntax/modules.html#imports - text: external value; url: exec/runtime.html#syntax-externval + url: exec/runtime.html#syntax-externval + text: external value + for: external value + text: tag text: host function; url: exec/runtime.html#syntax-hostfunc text: the instantiation algorithm; url: exec/modules.html#instantiation text: module; url: syntax/modules.html#syntax-module @@ -172,6 +176,8 @@ urlPrefix: https://webassembly.github.io/reference-types/core/; spec: WebAssembl text: table text: mem text: global + for: externtype + text: tag text: global type; url: syntax/types.html#syntax-globaltype url: syntax/types.html#syntax-mut text: var @@ -184,9 +190,12 @@ urlPrefix: https://webassembly.github.io/reference-types/core/; spec: WebAssembl text: memaddrs; for: moduleinst; url: exec/runtime.html#syntax-moduleinst text: signed_64; url: exec/numerics.html#aux-signed text: sequence; url: syntax/conventions.html#grammar-notation + text: exception; for: tagtype/attribute; url: syntax/types.html#syntax-tagtype urlPrefix: https://heycam.github.io/webidl/; spec: WebIDL type: dfn text: create a namespace object; url: create-a-namespace-object +urlPrefix: https://webassembly.github.io/js-types/js-api/; spec: WebAssembly JS API (JS Type Reflection) + type: abstract-op; text: FromValueType; url: abstract-opdef-fromvaluetype
@@ -391,6 +400,12 @@ A {{Module}} object represents a single WebAssembly module. Each {{Module}} obje 1. Let |tableaddr| be |v|.\[[Table]]. 1. Let |externtable| be the [=external value=] [=external value|table=] |tableaddr|. 1. [=list/Append=] |externtable| to |imports|. + 1. If |externtype| is of the form [=externtype/tag=] |attribute| functype, + 1. Assert: |attribute| is [=tagtype/attribute/exception=]. + 1. If |v| does not [=implement=] {{Tag}}, throw a {{LinkError}} exception. + 1. Let |tagaddr| be |v|.\[[Address]]. + 1. Let |externtag| be the [=external value=] [=external value/tag=] |tagaddr|. + 1. [=list/Append=] |externtag| to |imports|. 1. Return |imports|. Note: This algorithm only verifies the right kind of JavaScript values are passed. @@ -424,6 +439,12 @@ The verification of WebAssembly type requirements is deferred to the 1. Let [=external value|table=] |tableaddr| be |externval|. 1. Let |table| be [=create a Table object|a new Table object=] created from |tableaddr|. 1. Let |value| be |table|. + 1. If |externtype| is of the form [=externtype/tag=] |attribute| functype, + 1. Assert: |attribute| is [=tagtype/attribute/exception=]. + 1. Assert: |externval| is of the form [=external value/tag=] |tagaddr|. + 1. Let [=external value/tag=] |tagaddr| be |externval|. + 1. Let |exception| be [=create a Tag object|a new Tag object=] created from |tagaddr|. + 1. Let |value| be |exception|. 1. Let |status| be ! [=CreateDataProperty=](|exportsObject|, |name|, |value|). 1. Assert: |status| is true. @@ -515,7 +536,8 @@ enum ImportExportKind { "function", "table", "memory", - "global" + "global", + "tag" }; dictionary ModuleExportDescriptor { @@ -545,6 +567,7 @@ interface Module { * "table" if |type| is of the form [=table=] tabletype * "memory" if |type| is of the form [=mem=] memtype * "global" if |type| is of the form [=global=] globaltype + * "tag" if |type| is of the form [=externtype/tag=] tag@@ -1005,8 +1028,15 @@ This slot holds a [=function address=] relative to the [=surrounding agent=]'s [ 1. [=list/Append=] [=ToWebAssemblyValue=](|arg|, |t|) to |args|. 1. Set |i| to |i| + 1. 1. Let (|store|, |ret|) be the result of [=func_invoke=](|store|, |funcaddr|, |args|). + 1. Note: The expectation is that [=func_invoke=] will be updated to return (|store|, val* | [=error=] | (exception |exntag| |payload|)). 1. Set the [=surrounding agent=]'s [=associated store=] to |store|. 1. If |ret| is [=error=], throw an exception. This exception should be a WebAssembly {{RuntimeError}} exception, unless otherwise indicated by the WebAssembly error mapping. + 1. If |ret| is exception |exntag| |payload|, then + 1. If |exntag| is the [=JavaScript exception tag=], then + 1. Let « [=ref.extern=] |externaddr| » be |payload|. + 1. Throw the result of [=retrieving an extern value=] from |externaddr|. + 1. Let |exception| be [=create a RuntimeException object|a new RuntimeException=] for |exntag| and |payload|. + 1. Throw |exception|. 1. Let |outArity| be the [=list/size=] of |ret|. 1. If |outArity| is 0, return undefined. 1. Otherwise, if |outArity| is 1, return [=ToJSValue=](|ret|[0]). @@ -1057,7 +1087,14 @@ Note: Exported Functions do not have a \[[Construct]] method and thus it is not 1. [=Clean up after running a callback=] with |stored settings|. 1. [=Clean up after running script=] with |relevant settings|. 1. Assert: |result|.\[[Type]] is+throw ornormal . - 1. If |result|.\[[Type]] isthrow , then trigger a WebAssembly trap, and propagate |result|.\[[Value]] to the enclosing JavaScript. + 1. If |result|.\[[Type]] isthrow , then: + 1. If |v| [=implements=] {{RuntimeException}}, + 1. Let |type| be |v|.\[[Type]]. + 1. Let |payload| be |v|.\[[Payload]]. + 1. Otherwise, + 1. Let |type| be the [=JavaScript exception tag=]. + 1. Let |payload| be [=ToWebAssemblyValue=](|v|, [=externref=]). + 1. [=WebAssembly/Throw=] with |type| and |payload|. 1. Otherwise, return |result|.\[[Value]]. 1. Let |store| be the [=surrounding agent=]'s [=associated store=]. 1. Let (|store|, |funcaddr|) be [=func_alloc=](|store|, |functype|, |hostfunc|). @@ -1126,6 +1163,143 @@ The algorithm ToWebAssemblyValue(|v|, |type|) coerces a JavaScript vaTags
+ +The tag_parameters algorithm returns the [=list=] of types for a given +[=tag address=] in the given [=associated store=]. + +Exception types
+ ++dictionary TagType { + required sequence<ValueType> parameters; +}; + +[LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)] +interface Tag { + constructor(TagType type); + TagType type(); +}; ++ +An {{Tag}} value represents a type of exception. + ++ +To create a Tag object from a [=tag address=] |tagAddress|, perform the following steps: + +TODO: define cache. + +1. Let |tag| be a [=new=] {{Tag}}. +1. Set |tag|.\[[Address]] to |tagAddress|. +1. Return |tag|. + ++ ++ +The type() method steps are: + +1. Let |store| be the [=surrounding agent=]'s [=associated store=]. +1. Let |parameters| be [=tag_parameters=](|store|, **this**.\[[Address]]). +1. Let |idlParameters| be «». +1. [=list/iterate|For each=] |type| of |parameters|, + 1. [=list/Append=] [$FromValueType$](|type|) to |idlParameters|. +1. Return «[ "{{TagType/parameters}}" → |idlParameters| ]». + ++ +Runtime exceptions
+ ++[LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)] +interface RuntimeException { + constructor(Tag exceptionTag, sequence<any> payload); + any getArg(Tag exceptionTag, unsigned long index); + boolean is(Tag exceptionTag); +}; ++ +A {{RuntimeException}} value represents an exception. + ++ +To create a RuntimeException object from a [=tag address=] |tagAddress| and [=list=] +of WebAssembly values |payload|, perform the following steps: + +1. Let |store| be the [=surrounding agent=]'s [=associated store=]. +1. Let |types| be [=tag_parameters=](|store|, |tagAddress|). +1. Assert: |types|'s [=list/size=] is |payload|'s [=list/size=]. +1. [=list/iterate|For each=] |value| and |resultType| of |payload| and |types|, paired linearly, + 1. Assert: |value|'s type matches |resultType|. +1. Let |exception| be a [=new=] {{RuntimeException}}. +1. Set |exception|.\[[Type]] to |tagAddress|. +1. Set |exception|.\[[Payload]] to |payload|. +1. Return |exception|. + ++ ++ +The new RuntimeException(|exceptionTag|, |payload|) +constructor steps are: + +1. Let |types| be [=tag_parameters=](|exceptionTag|.\[[Address]]). +1. If |types|'s [=list/size=] is not |payload|'s [=list/size=], + 1. Throw a {{TypeError}}. +1. Let |wasmPayload| be « ». +1. [=list/iterate|For each=] |value| and |resultType| of |payload| and |types|, paired linearly, + 1. [=list/Append=] ? [=ToWebAssemblyValue=](|value|, |resultType|) to |wasmPayload|. +1. Set **this**.\[[Type]] to |exceptionTag|.\[[Address]]. +1. Set **this**.\[[Payload]] to |wasmPayload|. + ++ ++ +The getArg(|exceptionTag|, |index|) method steps are: + +1. If **this**.\[[Type]] is not equal to |exceptionTag|.\[[Address]], + 1. Throw a {{TypeError}}. +1. Let |payload| be **this**.\[[Payload]]. +1. If |index| ≥ |payload|'s [=list/size=], + 1. Throw a {{TypeError}}. +1. Return [=ToJSValue=](|payload|[|index|]). + ++ ++ +The is(|exceptionTag|) method steps are: + +1. If **this**.\[[Type]] is not equal to |exceptionTag|.\[[Address]], + 1. Return false. +1. Return true. + ++ +JavaScript exceptions
+ +The JavaScript exception tag is a [=tag address=] reserved by this +specification to distinguish exceptions originating from JavaScript. + +For any [=associated store=] |store|, the result of +[=tag_parameters=](|store|, [=JavaScript exception tag=]) must be « [=externref=] ». + + Issue: Should it be possible for `catch` to extract the payload from an exception with this tag? + + + +To throw with a [=tag address=] |type| and matching [=list=] of WebAssembly values |payload|, perform the following steps: + +1. Unwind the stack until reaching the *catching try block* given |type|. +1. Invoke the catch block with |payload|. + +Note: This algorithm is expected to be moved into the core specification. + ++Error Objects
WebAssembly defines the following Error classes: CompileError, LinkError, and RuntimeError.