This repository was archived by the owner on Apr 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 36
Combine throw and create #43
Merged
Merged
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,9 +69,8 @@ can't be stored into linear memory. The rationale for this is twofold: | |
Hence, while an exception reference is a new first class type, this proposal | ||
disallows their usage in linear memory. | ||
|
||
A WebAssembly exception is created by the `except` instruction. Once an | ||
exception is created, you can throw it with the `throw` instruction. Thrown | ||
exceptions are handled as follows: | ||
A WebAssembly exception is created when you throw it with the `throw` | ||
instruction. Thrown exceptions are handled as follows: | ||
|
||
1. They can be caught by a catch block in an enclosing try block of a function | ||
body. The caught exception is pushed onto the stack. | ||
|
@@ -87,35 +86,41 @@ exceptions are handled as follows: | |
An `exception` is an internal construct in WebAssembly that is maintained by the | ||
host. WebAssembly exceptions (as opposed to host exceptions) are defined by a | ||
new `exception section` of a WebAssembly module. The exception section is a list | ||
of exception types, from which exceptions can be created. | ||
of exception definitions, from which exceptions can be created. | ||
|
||
Each exception type has a `type signature`. The type signature defines the list | ||
of values associated with the exception. | ||
Each exception definition describe the structure of corresponding exception | ||
values that can be generated from it. Exception definitions may also appear in | ||
the import section of a module. | ||
|
||
Within the module, exception types are identified by an index into the | ||
[exception index space](#exception-index-space). This index is referred to as | ||
the `exception tag`. The `tagged exception type` is the corresponding | ||
exception type refered to by the exception tag. | ||
Each exception definition has a `type signature`. The type signature defines the | ||
list of values associated with corresponding thrown exception values. | ||
|
||
Exception types can be imported and exported by adding the appropriate entries | ||
to the import and export sections of the module. All imported/exported exception | ||
types must be named to reconcile exception tags between modules. | ||
Within the module, exception definitions are identified by an index into the | ||
[exception index space](#exception-index-space). This static index refers to the | ||
corresponding runtime tag that uniquely identifies exception values created | ||
using the exception definition, and is called the `exception tag`. | ||
|
||
Exception tags are used by: | ||
Each exception definition within a module (i.e. in the exception and import | ||
section) are associated with unique exception tags. | ||
|
||
1. The `except` instruction which creates a WebAssembly instance of the | ||
corresponding tagged exception type, and pushes a reference to it onto the | ||
stack. | ||
Exception tags can also be exported by adding the appropriate descriptors in the | ||
export section of the module. All imported/exported indices must be named to | ||
reconcile the corresponding exception tag referenced by exception indices | ||
between modules. | ||
|
||
2. The `if_except` instruction that queries an exception to see if it is an | ||
instance of the corresponding tagged exception class, and if true it pushes | ||
the corresponding values of the exception onto the stack. | ||
Exception indices are used by: | ||
|
||
1. The `throw` instruction which creates a WebAssembly exception value | ||
with the corresponding exception tag, and then throws it. | ||
|
||
2. The `if_except` instruction that queries an exception value to see if the | ||
exception tag corresponding to the module's exception index. If true it | ||
pushes the corresponding values of the exception onto the stack. | ||
|
||
### The exception reference data type | ||
|
||
Data types are extended to have a new `except_ref` type. The representation of | ||
an exception type is left to the host VM, but its size must be fixed. The actual | ||
number of bytes it takes to represent any `except_ref` is left to the host VM. | ||
an exception value is left to the host VM. | ||
|
||
### Try and catch blocks | ||
|
||
|
@@ -143,22 +148,19 @@ block. | |
|
||
In the initial implementation, try blocks may only yield 0 or 1 values. | ||
|
||
### Exception creation | ||
### Throwing an exception | ||
|
||
A `except` instruction has a single immediate argument, an exception tag. The | ||
corresponding tagged exception type is used to define the data fields of the | ||
created exception. The values for the data fields must be on top of the operand | ||
stack, and must correspond to the exception's type signature. These values are | ||
popped off the stack and an instance of the exception is then created. A | ||
reference to the created exception is then pushed onto the stack. | ||
The `throw` instruction takes an exception index as an immediate argument. That | ||
index is used to identify the exception tag to use to create and throw the | ||
corresponding exception value. | ||
|
||
### Throws | ||
The values on top of the stack must correspond to the the type signature | ||
associated with the exception index. These values are popped of the stack and | ||
are used (along with the corresponding exception tag) to create the | ||
corresponding exception value. That exception value is then thrown. | ||
|
||
The `throw` throws the exception on top of the stack. The exception is popped | ||
off the top of the stack before throwing. | ||
|
||
When an exception is thrown, the host VM searches for nearest enclosing try | ||
block body that execution is in. That try block is called the _catching_ try | ||
When an exception value is thrown, the host VM searches for nearest enclosing | ||
try block body that execution is in. That try block is called the _catching_ try | ||
block. | ||
|
||
If the throw appears within the body of a try block, it is the catching try | ||
|
@@ -174,9 +176,10 @@ A throw inside the body of a catch block is never caught by the corresponding | |
try block of the catch block, since instructions in the body of the catch block | ||
are not in the body of the try block. | ||
|
||
Once a catching try block is found for the throw, the operand stack is popped back | ||
to the size the operand stack had when the try block was entered, and then | ||
the caught exception is pushed onto the stack. | ||
Once a catching try block is found for the thrown exception value, the operand | ||
stack is popped back to the size the operand stack had when the try block was | ||
entered, and then the values of the caught exception value is pushed onto the | ||
stack. | ||
|
||
If control is transferred to the body of a catch block, and the last instruction | ||
in the body is executed, control then exits the try block. | ||
|
@@ -185,16 +188,24 @@ If the selected catch block does not throw an exception, it must yield the | |
value(s) expected by the corresponding catching try block. This includes popping | ||
the caught exception. | ||
|
||
Note that a caught exception can be rethrown using the `throw` instruction. | ||
Note that a caught exception value can be rethrown using the `throw` | ||
instruction. | ||
|
||
### Rethrowing an exception | ||
|
||
The `rethrow` instruction takes the exception value associated with the | ||
`except_ref` on top of the stack, and rethrows the exception. A rethrow has the | ||
same effect as a throw, other than an exception is not created. Rather, the | ||
referenced exception value on top of the stack is popped and then thrown. | ||
|
||
### Exception data extraction | ||
|
||
The `if_except block` defines a conditional query of the exception on top of the | ||
stack. The exception is not popped when queried. The if_except block has two | ||
subblocks, the `then` and `else` subblocks, like that of an `if` block. The then | ||
block is a sequence of instructions following the `if_except` instruction. The | ||
else block is optional, and if it appears, it begins with the `else` | ||
instruction. The scope of the if_except block is from the `if_except` | ||
The `if_except block` defines a conditional query of the exception value on top | ||
of the stack. The exception value is not popped when queried. The if_except | ||
block has two subblocks, the `then` and `else` subblocks, like that of an `if` | ||
block. The then block is a sequence of instructions following the `if_except` | ||
instruction. The else block is optional, and if it appears, it begins with the | ||
`else` instruction. The scope of the if_except block is from the `if_except` | ||
instruction to the corresponding `end` instruction. | ||
|
||
That is, the forms of an if_except block is: | ||
|
@@ -211,13 +222,12 @@ else | |
end | ||
``` | ||
|
||
The conditional query of an exception succeeds when the exception on the top of | ||
the stack is an instance of the corresponding tagged exception type (defined by | ||
`except_index`). | ||
The conditional query of an exception succeeds when the exception value on the | ||
top of the stack has the corresponding exception tag (defined by `except_index`). | ||
|
||
If the query succeeds, the data values (associated with the type signature of | ||
the exception class) are extracted and pushed onto the stack, and control | ||
transfers to the instructions in the then block. | ||
If the query succeeds, the values (associated with the exception value) are | ||
extracted and pushed onto the stack, and control transfers to the instructions | ||
in the then block. | ||
|
||
If the query fails, it either enters the else block, or transfer control to the | ||
end of the if_except block if there is no else block. | ||
|
@@ -244,7 +254,8 @@ The following rules are added to *instructions*: | |
``` | ||
try resulttype instruction* catch instruction* end | | ||
except except_index | | ||
throw | | ||
throw except_index | | ||
rethrow | | ||
if_except resulttype except_index then instruction* end | | ||
if_except resulttype except_index then instruction* else instruction* end | ||
``` | ||
|
@@ -253,9 +264,10 @@ Like the `block`, `loop`, and `if` instructions, the `try` and `if_except` | |
instructions are *structured* control flow instructions, and can be | ||
labeled. This allows branch instructions to exit try and `if_except` blocks. | ||
|
||
The `except_index` of the `except` and `if_except` instructions defines the | ||
exception type to create/extract form. See [exception index | ||
space](#exception-index-space) for further clarification of exception tags. | ||
The `except_index` of the `throw` and `if_except` instructions defines the | ||
exception value (and hence, exception tag) to create/extract form. See | ||
[exception index space](#exception-index-space) for further clarification of | ||
exception tags. | ||
|
||
## Changes to Modules document. | ||
|
||
|
@@ -270,6 +282,15 @@ defined in the import and exception sections. Thus, the index space starts at | |
zero with imported exceptions followed by internally-defined exceptions in | ||
the [exception section](#exception-section). | ||
|
||
The exception index space defines the (module) static version of runtine | ||
exception tags. For exception indicies that are not imported/exported, the | ||
corresponding exception tag is guaranteed to be unique over all loaded | ||
modules. | ||
|
||
For exception indices imported/exported, unique exception tags are created for | ||
each unique name imported/exported, and are aliased to the corresponding | ||
exception index defined in each module. | ||
|
||
## Changes to the binary model | ||
|
||
This section describes changes in | ||
|
@@ -281,7 +302,7 @@ the | |
|
||
#### except_ref | ||
|
||
An exception reference pointing to an instance of an exception. The size | ||
An exception reference points to an exception value. The size | ||
is fixed, but unknown in WebAssembly (the host defines the size in bytes). | ||
|
||
### Language Types | ||
|
@@ -299,14 +320,17 @@ encoded above. | |
|
||
##### except_type | ||
|
||
An exception is described by its exception type signature, which corresponds to | ||
the data fields of the exception. | ||
Each exception definition (defining an exception tag) has a type signature, | ||
which corresponds to the data fields of the exception. | ||
|
||
| Field | Type | Description | | ||
|-------|------|-------------| | ||
| `count` | `varuint32` | The number of types in the signature | | ||
| `type` | `value_type*` | The type of each element in the signature | | ||
|
||
Note: An `except_type` is not actually a type, just an exception definition that | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, the exception type in an exn def is indeed the type of the defined tag, so I believe this note isn't necessary (and probably misleading). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed. |
||
corresponds to an exception tag. It is listed under `Other types` for | ||
simplicity. | ||
|
||
##### external_kind | ||
|
||
|
@@ -317,30 +341,29 @@ or defined: | |
* `1` indicating a `Table` [import](Modules.md#imports) or [definition](Modules.md#table-section) | ||
* `2` indicating a `Memory` [import](Modules.md#imports) or [definition](Modules.md#linear-memory-section) | ||
* `3` indicating a `Global` [import](Modules.md#imports) or [definition](Modules.md#global-section) | ||
* `4` indicating an `Exception` [import](#import-section) or [definition](#exception-sectio) | ||
* `4` indicating an `Exception` [import](#import-section) or [definition](#exception-section) | ||
|
||
### Module structure | ||
|
||
#### High-level structure | ||
|
||
A new `exception` section is introduced and is named `exception`. If included, | ||
it must appear between the `Export` and `Start` sections of the module. | ||
|
||
it must appear after immediately after the global section. | ||
|
||
##### Exception section | ||
|
||
The `exception` section is the named section 'exception'. The exception section | ||
declares exception types using exception type signatures. | ||
declares a list of exception definitions, defining corresponding exception tags. | ||
|
||
| Field | Type | Description | | ||
|-------|------|-------------| | ||
| count | `varuint32` | count of the number of exceptions to follow | | ||
| sig | `except_type*` | The type signature of the data fields for each exception | | ||
| sig | `except_type*` | The type signature of the data fields for the tagged exception value | | ||
|
||
|
||
##### Import section | ||
|
||
The import section is extended to include exception types by extending an | ||
The import section is extended to include exception definitions by extending an | ||
`import_entry` as follows: | ||
|
||
If the `kind` is `Exception`: | ||
|
@@ -351,11 +374,11 @@ If the `kind` is `Exception`: | |
|
||
##### Export section | ||
|
||
The export section is extended to include exception types by extending an | ||
`export_entry` as follows: | ||
The export section is extended to reference exception definitions by by | ||
extending an `export_entry` as follows: | ||
|
||
If the `kind` is `Exception`, then the `index` is into the corresponding | ||
exception in the [exception index space](#exception-index-space). | ||
exception index in the [exception index space](#exception-index-space). | ||
|
||
|
||
##### Name section | ||
|
@@ -384,9 +407,9 @@ throws, and rethrows as follows: | |
| ---- | ---- | ---- | ---- | | ||
| `try` | `0x06` | sig : `block_type` | begins a block which can handle thrown exceptions | | ||
| `catch` | `0x07` | | begins the catch block of the try block | | ||
| `throw` | `0x08` | |Throws the exception on top of the stack | | ||
| `except` | `0x09` | tag : `varuint32` | Creates an exception defined by the exception tag and pushes reference on stack | | ||
| `if_except` | `0x0a` | sig : `block_type` , tag : `varuint32` | Begin exception data extraction if exception on stack was created using the corresponding exception tag | | ||
| `throw` | `0x08` | index : `varint32` | Creates an exception defined by the exception `index`and then throws it | | ||
| `rethrow` | `0x09` | | Pops the `except_ref` on top of the stack and throws it | | ||
| `if_except` | `0x0a` | sig : `block_type` , index : `varuint32` | Begin exception data extraction if exception on stack was created using the corresponding exception `index` | | ||
|
||
The *sig* fields of `block`, `if`, `try` and `if_except` operators are block | ||
signatures which describe their use of the operand stack. |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo:
rethrow
instruction?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done