-
Notifications
You must be signed in to change notification settings - Fork 33
Changes from 1 commit
2bed427
472ff1f
684e016
15762fc
71435f4
29c91d0
3e99426
b302023
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,14 +21,25 @@ The algorithm is expressed in typed pseudo code whose semantics is intended to b | |
Data Structures | ||
~~~~~~~~~~~~~~~ | ||
|
||
Types are representable as an enumeration. | ||
A simple subtyping check can be defined on them. | ||
|
||
.. code-block:: pseudo | ||
|
||
type val_type = I32 | I64 | F32 | F64 | Anyref | Anyfunc | Eqref | Nullref | ||
|
||
func is_ref(t : valtype) : bool = | ||
return t = Anyref || t = Anyfunc || t = Eqref | ||
|
||
func matches(t1 : val_type, t2 : val_type) : bool = | ||
return t1 = t2 || (t1 = Nullref && is_ref(t2)) || (is_ref(t1) && t2 = Anyref) | ||
|
||
The algorithm uses two separate stacks: the *operand stack* and the *control stack*. | ||
The former tracks the :ref:`types <syntax-valtype>` of operand values on the :ref:`stack <stack>`, | ||
the latter surrounding :ref:`structured control instructions <syntax-instr-control>` and their associated :ref:`blocks <syntax-instr-control>`. | ||
|
||
.. code-block:: pseudo | ||
|
||
type val_type = I32 | I64 | F32 | F64 | ||
|
||
type opd_stack = stack(val_type | Unknown) | ||
|
||
type ctrl_stack = stack(ctrl_frame) | ||
|
@@ -70,7 +81,7 @@ However, these variables are not manipulated directly by the main checking funct | |
let actual = pop_opd() | ||
if (actual = Unknown) return expect | ||
if (expect = Unknown) return actual | ||
error_if(actual =/= expect) | ||
error_if(not matches(actual, expect)) | ||
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. IIUC, according to the validation rules, 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. Ah, good catch! This is not just for nullref, subtyping generally changes the way select needs to be handled. To simplify things, I refactored the pseudo code somewhat to make Unknown act more like a bottom type (which has been your view all along, I think :) ). While fixing this I realised that subtyping also affects how br_table needs to be handled, so I incorporated respective changes as well. |
||
return actual | ||
|
||
func push_opds(types : list(val_type)) = foreach (t in types) push_opd(t) | ||
|
@@ -84,7 +95,7 @@ That can occur after an unconditional branch, when the stack is typed :ref:`poly | |
In that case, an unknown type is returned. | ||
|
||
A second function for popping an operand takes an expected type, which the actual operand type is checked against. | ||
The types may differ in case one of them is Unknown. | ||
The types may differ by subtyping or in case one of them is Unknown. | ||
The more specific type is returned. | ||
|
||
Finally, there are accumulative functions for pushing or popping multiple operand types. | ||
|
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.
nit:
val_type
(function parameter)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.