Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Commit ba6b577

Browse files
committed
fixup! [js-api] Add support for exceptions.
1 parent 371f2ac commit ba6b577

File tree

1 file changed

+112
-18
lines changed

1 file changed

+112
-18
lines changed

document/js-api/index.bs

Lines changed: 112 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ urlPrefix: https://webassembly.github.io/reference-types/core/; spec: WebAssembl
111111
text: ref.null
112112
text: ref.func
113113
text: ref.extern
114+
text: ref.exn
114115
text: function index; url: syntax/modules.html#syntax-funcidx
115116
text: function instance; url: exec/runtime.html#function-instances
116117
text: store_init; url: appendix/embedding.html#embed-store-init
@@ -147,6 +148,7 @@ urlPrefix: https://webassembly.github.io/reference-types/core/; spec: WebAssembl
147148
text: memory address; url: exec/runtime.html#syntax-memaddr
148149
text: global address; url: exec/runtime.html#syntax-globaladdr
149150
text: extern address; url: exec/runtime.html#syntax-externaddr
151+
text: event address; url: exec/runtime.html#syntax-eventaddr
150152
url: syntax/types.html#syntax-numtype
151153
text: i32
152154
text: i64
@@ -155,9 +157,13 @@ urlPrefix: https://webassembly.github.io/reference-types/core/; spec: WebAssembl
155157
url: syntax/types.html#syntax-reftype
156158
text: funcref
157159
text: externref
160+
text: exnref
158161
text: function element; url: exec/runtime.html#syntax-funcelem
159162
text: import component; url: syntax/modules.html#imports
160-
text: external value; url: exec/runtime.html#syntax-externval
163+
url: exec/runtime.html#syntax-externval
164+
text: external value
165+
for: external value
166+
text: event
161167
text: host function; url: exec/runtime.html#syntax-hostfunc
162168
text: the instantiation algorithm; url: exec/modules.html#instantiation
163169
text: module; url: syntax/modules.html#syntax-module
@@ -169,6 +175,8 @@ urlPrefix: https://webassembly.github.io/reference-types/core/; spec: WebAssembl
169175
text: table
170176
text: mem
171177
text: global
178+
for: externtype
179+
text: event
172180
text: global type; url: syntax/types.html#syntax-globaltype
173181
url: syntax/types.html#syntax-mut
174182
text: var
@@ -180,6 +188,7 @@ urlPrefix: https://webassembly.github.io/reference-types/core/; spec: WebAssembl
180188
text: module; for: frame; url: exec/runtime.html#syntax-frame
181189
text: memaddrs; for: moduleinst; url: exec/runtime.html#syntax-moduleinst
182190
text: sequence; url: syntax/conventions.html#grammar-notation
191+
text: exception; for: eventtype/attribute; url: syntax/types.html#syntax-eventtype
183192
urlPrefix: https://heycam.github.io/webidl/; spec: WebIDL
184193
type: dfn
185194
text: create a namespace object; url: create-a-namespace-object
@@ -383,6 +392,12 @@ A {{Module}} object represents a single WebAssembly module. Each {{Module}} obje
383392
1. Let |tableaddr| be |v|.\[[Table]].
384393
1. Let |externtable| be the [=external value=] [=external value|table=] |tableaddr|.
385394
1. [=list/Append=] |externtable| to |imports|.
395+
1. If |externtype| is of the form [=externtype/event=] |attribute| <var ignore>functype</var>,
396+
1. Assert: |attribute| is [=eventtype/attribute/exception=].
397+
1. If |v| does not [=implement=] {{Exception}}, throw a {{LinkError}} exception.
398+
1. Let |tag| be |v|'s [=Exception/exception tag=].
399+
1. Let |extern| be the [=external value=] [=external value/event=] |tag|.
400+
1. [=list/Append=] |extern| to |imports|.
386401
1. Return |imports|.
387402

388403
Note: This algorithm only verifies the right kind of JavaScript values are passed.
@@ -411,11 +426,17 @@ The verification of WebAssembly type requirements is deferred to the
411426
1. Let [=external value|mem=] |memaddr| be |externval|.
412427
1. Let |memory| be [=create a memory object|a new Memory object=] created from |memaddr|.
413428
1. Let |value| be |memory|.
414-
1. Otherwise, |externtype| is of the form [=table=] <var ignore>tabletype</var>,
429+
1. If |externtype| is of the form [=table=] <var ignore>tabletype</var>,
415430
1. Assert: |externval| is of the form [=external value|table=] |tableaddr|.
416431
1. Let [=external value|table=] |tableaddr| be |externval|.
417432
1. Let |table| be [=create a Table object|a new Table object=] created from |tableaddr|.
418433
1. Let |value| be |table|.
434+
1. If |externtype| is of the form [=externtype/event=] |attribute| <var ignore>functype</var>,
435+
1. Assert: |attribute| is [=eventtype/attribute/exception=].
436+
1. Assert: |externval| is of the form [=external value/event=] |eventaddr|.
437+
1. Let [=external value/event=] |eventaddr| be |externval|.
438+
1. Let |exception| be [=create an Exception object|a new Exception object=] created from |eventaddr|.
439+
1. Let |value| be |exception|.
419440
1. Let |status| be ! [=CreateDataProperty=](|exportsObject|, |name|, |value|).
420441
1. Assert: |status| is true.
421442

@@ -507,7 +528,8 @@ enum ImportExportKind {
507528
"function",
508529
"table",
509530
"memory",
510-
"global"
531+
"global",
532+
"event"
511533
};
512534

513535
dictionary ModuleExportDescriptor {
@@ -537,6 +559,7 @@ interface Module {
537559
* "table" if |type| is of the form [=table=] tabletype
538560
* "memory" if |type| is of the form [=mem=] memtype
539561
* "global" if |type| is of the form [=global=] globaltype
562+
* "event" if |type| is of the form [=externtype/event=] <var ignore>event</var>
540563
</div>
541564

542565
<div algorithm>
@@ -1017,14 +1040,8 @@ This slot holds a [=function address=] relative to the [=surrounding agent=]'s [
10171040
1. Let (|store|, |ret|) be the result of [=func_invoke=](|store|, |funcaddr|, |argsSeq|).
10181041
1. Set the [=surrounding agent=]'s [=associated store=] to |store|.
10191042
1. If |ret| is [=error=], throw an exception. This exception should be a WebAssembly {{RuntimeError}} exception, unless otherwise indicated by <a href="#errors">the WebAssembly error mapping</a>.
1020-
1. If |ret| is exception [=exnref=] |exception|,
1021-
1. If |exception|'s [=exnref/exception tag=] is the [=JavaScript exception tag=], then
1022-
1. Let [=ref.extern=] |externaddr| be |exception|'s [=exnref/payload=].
1023-
1. Let |jsException| be the result of [=retrieving an extern value=] from |externaddr|.
1024-
1. Throw |jsException|.
1025-
1. Throw a {{RuntimeError}} exception.
1026-
1027-
Issue: Probably shouldn't be a {{RuntimeError}}.
1043+
1. If |ret| is exception |exnaddr|,
1044+
1. Throw [=ToJSValue=]([=ref.exn=] |exnaddr|).
10281045
1. Let |outArity| be the [=list/size=] of |ret|.
10291046
1. If |outArity| is 0, return undefined.
10301047
1. Otherwise, if |outArity| is 1, return [=ToJSValue=](|ret|[0]).
@@ -1069,7 +1086,7 @@ Note: Exported Functions do not have a \[[Construct]] method and thus it is not
10691086
1. Let |result| be the result of [=run a host function|running a host function=] from |func|, |functype|, and |arguments|.
10701087
1. Assert: |result|.\[[Type]] is <emu-const>throw</emu-const> or <emu-const>return</emu-const>.
10711088
1. If |result|.\[[Type]] is <emu-const>throw</emu-const>, then:
1072-
1. Let |exception| be [=ToWebAssemblyValue=](|result|.\[[Value]], [=anyref=]).
1089+
1. Let |exception| be [=ToWebAssemblyValue=](|result|.\[[Value]], [=exnref=]).
10731090
1. [=WebAssembly/Throw=] |exception| with the [=JavaScript exception tag=].
10741091
1. Otherwise, return |result|.\[[Value]].
10751092
1. Let |store| be the [=surrounding agent=]'s [=associated store=].
@@ -1088,6 +1105,11 @@ The algorithm <dfn>ToJSValue</dfn>(|w|) coerces a [=WebAssembly value=] to a Jav
10881105
1. If |w| is of the form [=ref.null=] <var ignore>t</var>, return null.
10891106
1. If |w| is of the form [=ref.func=] |funcaddr|, return the result of creating [=a new Exported Function=] from |funcaddr|.
10901107
1. If |w| is of the form [=ref.extern=] |externaddr|, return the result of [=retrieving an extern value=] from |externaddr|.
1108+
1. If |w| is of the form [=ref.exn=] |exntag| |payload|, then
1109+
1. If |exntag| is the [=JavaScript exception tag=], then
1110+
1. Let « [=ref.extern=] |externaddr| » be |payload|.
1111+
1. Return the result of [=retrieving an extern value=] from |externaddr|.
1112+
1. Return a {{RuntimeException}} whose [=RuntimeException/internal exception=] is |exnaddr|.
10911113

10921114
<!-- If the WebAssembly value is optional, then given `None`, return JavaScript value `undefined`. -->
10931115

@@ -1115,6 +1137,15 @@ The algorithm <dfn>ToWebAssemblyValue</dfn>(|v|, |type|) coerces a JavaScript va
11151137
1. If |type| is [=f64=],
11161138
1. Let |f64| be ? [=ToNumber=](|v|).
11171139
1. Return [=f64.const=] |f64|.
1140+
1. If |type| is [=exnref=],
1141+
1. If |v| [=implements=] {{RuntimeException}},
1142+
1. Let |exnaddr| be |v|'s [=RuntimeException/internal exception=].
1143+
1. Otherwise,
1144+
1. Let |payload| be [=ToWebAssemblyValue=](|v|, [=anyref=]).
1145+
1. Let |exnaddr| be a new [=event address=] referencing |payload| and the [=JavaScript exception tag=].
1146+
1. Return [=ref.exn=] |exnaddr|.
1147+
1148+
Note: There is no way to compare [=exnref=] values by reference.
11181149
1. If |type| is [=funcref=],
11191150
1. If |v| is null,
11201151
1. Return [=ref.null=] [=funcref=].
@@ -1138,22 +1169,85 @@ The algorithm <dfn>ToWebAssemblyValue</dfn>(|v|, |type|) coerces a JavaScript va
11381169

11391170
<h3 id="exceptions">Exceptions</h3>
11401171

1141-
A new type <dfn>exnref</dfn> is introduced for references to exceptions.
1142-
Values of this type have an <dfn for=exnref>exception tag</dfn> and a <dfn for=exnref>payload</dfn>
1172+
Values of the [=exnref=] type have an <dfn for=exnref>exception tag</dfn> and a
1173+
<dfn for=exnref>payload</dfn>
11431174
(whose type is dependent on the value of the [=exnref/exception tag=]).
11441175
The concrete representation of values of this type is undefined.
11451176

1177+
<h4 id="runtime-exceptions">Exception types</h4>
1178+
1179+
<pre class="idl">
1180+
[LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)]
1181+
interface Exception {
1182+
};
1183+
</pre>
1184+
1185+
An {{Exception}} value represents a type of exception.
1186+
{{Exception}} values have an <dfn for=Exception>exception tag</dfn>.
1187+
1188+
The <dfn for=Exception>payload types</dfn> of an {{Exception}} is the [=list=] of types of
1189+
1190+
1191+
<h4 id="runtime-exceptions">Runtime exceptions</h4>
1192+
1193+
<pre class="idl">
1194+
[LegacyNamespace=WebAssembly, Exposed=(Window,Worker,Worklet)]
1195+
interface RuntimeException {
1196+
constructor(Exception exceptionType, sequence&lt;any> payload);
1197+
sequence&lt;any> arguments(Exception exceptionType);
1198+
};
1199+
</pre>
1200+
1201+
A {{RuntimeException}} value represents an [=exnref=] value.
1202+
{{RuntimeException}} values have an <dfn for=RuntimeException>internal exception</dfn>, which
1203+
is an [=event address=].
1204+
1205+
Issue: Should it be possible to construct {{RuntimeException}} objects from JavaScript? Only with
1206+
the [=JavaScript exception tag=] or also with others? How?
1207+
<div algorithm>
1208+
1209+
The <dfn constructor for=RuntimeException
1210+
lt="RuntimeException(exceptionType, payload)">new RuntimeException(|exceptionType|, |payload|)</dfn>
1211+
constructor steps are:
1212+
1213+
1. Let |types| be |exceptionType|'s [=Exception/exception tag=]'s [=list=] of types.
1214+
1. If |types|'s [=list/size=] is not |payload|'s [=list/size=],
1215+
1. Throw a {{TypeError}}.
1216+
1. Let |wasmPayload| be « ».
1217+
1. [=list/iterate|For each=] |value| and |resultType| of |payload| and |types|, paired linearly,
1218+
1. [=list/Append=] [=ToWebAssemblyValue=](|value|, |resultType|) to |wasmPayload|.
1219+
1. Let |exception| be a new [=exnref=] with [=exnref/exception tag=] set to |exceptionType|'s
1220+
[=Exception/exception tag=], and [=exnref/payload=] |wasmPayload|.
1221+
1. Set **this**'s [=RuntimeException/internal exception=] to |exception|.
1222+
1223+
</div>
1224+
1225+
<div algorithm>
1226+
1227+
The <dfn method for="RuntimeException">arguments(|exceptionType|)</dfn> method steps are:
1228+
1229+
1. Let |internal| be **this**'s [=RuntimeException/internal exception=].
1230+
1. If |internal|'s [=exnref/exception tag=] is not equal to |exceptionType|'s [=Exception/exception tag=],
1231+
1. Throw a {{TypeError}}.
1232+
1. Let |payload| be |internal|'s [=exnref/payload=].
1233+
1. Let |result| be « ».
1234+
1. [=list/iterate|For each=] |value| of |payload|,
1235+
1. [=list/Append=] [=ToJSValue=](|value|) to |result|.
1236+
1. Return |result|.
1237+
1238+
</div>
1239+
1240+
<h4 id="js-exceptions">JavaScript exceptions</h4>
1241+
11461242
The <dfn>JavaScript exception tag</dfn> is an [=exnref/exception tag=] reserved by this
11471243
specification to distinguish exceptions originating from JavaScript.
11481244

1149-
Issue: Should it be possible for `br_on_exn` to extract the payload from an exception with this tag.
1245+
Issue: Should it be possible for `br_on_exn` to extract the payload from an exception with this tag?
11501246

11511247
<div algorithm>
11521248

1153-
To <dfn for=WebAssembly>throw</dfn> a WebAssembly value |payload| given an [=exception tag=] |tag|,
1154-
perform the following steps:
1249+
To <dfn for=WebAssembly>throw</dfn> an [=exnref=] |exception|, perform the following steps:
11551250

1156-
1. Let |exception| be a new [=exnref=] value with |payload| and |tag|.
11571251
1. Unwind the stack until reaching the *catching try block*.
11581252
1. Push |exception| onto the operand stack.
11591253
1. Transfer control to the catch block.

0 commit comments

Comments
 (0)