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

Commit d5fcf44

Browse files
authored
Spec return_call_ref (PR #89)
2 parents 300f214 + 42ea129 commit d5fcf44

File tree

10 files changed

+78
-15
lines changed

10 files changed

+78
-15
lines changed

document/core/appendix/gen-index-instructions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def Instruction(name, opcode, type=None, validation=None, execution=None, operat
9090
Instruction(r'\RETURNCALL~x', r'\hex{12}', r'[t_1^\ast] \to [t_2^\ast]', r'valid-return_call', r'exec-return_call'),
9191
Instruction(r'\RETURNCALLINDIRECT~x', r'\hex{13}', r'[t_1^\ast~\I32] \to [t_2^\ast]', r'valid-return_call_indirect', r'exec-return_call_indirect'),
9292
Instruction(r'\CALLREF~x', r'\hex{14}', r'[t_1^\ast~(\REF~\NULL~x)] \to [t_2^\ast]', r'valid-call_ref', r'exec-call_ref'),
93-
Instruction(None, r'\hex{15}'),
93+
Instruction(r'\RETURNCALLREF~x', r'\hex{15}', r'[t_1^\ast~(\REF~\NULL~x)] \to [t_2^\ast]', r'valid-return_call_ref', r'exec-return_call_ref'),
9494
Instruction(None, r'\hex{16}'),
9595
Instruction(None, r'\hex{17}'),
9696
Instruction(None, r'\hex{18}'),

document/core/appendix/index-instructions.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Instruction Binary Opcode
3030
:math:`\RETURNCALL~x` :math:`\hex{12}` :math:`[t_1^\ast] \to [t_2^\ast]` :ref:`validation <valid-return_call>` :ref:`execution <exec-return_call>`
3131
:math:`\RETURNCALLINDIRECT~x` :math:`\hex{13}` :math:`[t_1^\ast~\I32] \to [t_2^\ast]` :ref:`validation <valid-return_call_indirect>` :ref:`execution <exec-return_call_indirect>`
3232
:math:`\CALLREF~x` :math:`\hex{14}` :math:`[t_1^\ast~(\REF~\NULL~x)] \to [t_2^\ast]` :ref:`validation <valid-call_ref>` :ref:`execution <exec-call_ref>`
33-
(reserved) :math:`\hex{15}`
33+
:math:`\RETURNCALLREF~x` :math:`\hex{15}` :math:`[t_1^\ast~(\REF~\NULL~x)] \to [t_2^\ast]` :ref:`validation <valid-return_call_ref>` :ref:`execution <exec-return_call_ref>`
3434
(reserved) :math:`\hex{16}`
3535
(reserved) :math:`\hex{17}`
3636
(reserved) :math:`\hex{18}`

document/core/binary/instructions.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Control Instructions
7171
\hex{12}~~x{:}\Bfuncidx &\Rightarrow& \RETURNCALL~x \\ &&|&
7272
\hex{13}~~y{:}\Btypeidx~~x{:}\Btableidx &\Rightarrow& \RETURNCALLINDIRECT~x~y \\ &&|&
7373
\hex{14}~~x{:}\Btypeidx &\Rightarrow& \CALLREF~x \\ &&|&
74+
\hex{15}~~x{:}\Btypeidx &\Rightarrow& \RETURNCALLREF~x \\ &&|&
7475
\hex{D4}~~l{:}\Blabelidx &\Rightarrow& \BRONNULL~l \\ &&|&
7576
\hex{D6}~~l{:}\Blabelidx &\Rightarrow& \BRONNONNULL~l \\
7677
\end{array}

document/core/exec/instructions.rst

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2842,15 +2842,24 @@ Control Instructions
28422842
:math:`\CALLREF~x`
28432843
..................
28442844

2845-
1. Assert: due to :ref:`validation <valid-call_ref>`, a :ref:`function reference <syntax-ref>` is on the top of the stack.
2845+
1. Assert: due to :ref:`validation <valid-call_ref>`, a null or :ref:`function reference <syntax-ref>` is on the top of the stack.
28462846

2847-
2. Pop the value :math:`\REFFUNCADDR~a` from the stack.
2847+
2. Pop the reference value :math:`r` from the stack.
28482848

2849-
3. :ref:`Invoke <exec-invoke>` the function instance at address :math:`a`.
2849+
3. If :math:`r` is :math:`\REFNULL~\X{ht}`, then:
2850+
2851+
a. Trap.
2852+
2853+
4. Assert: due to :ref:`validation <valid-call_ref>`, :math:`r` is a :ref:`function reference <syntax-ref>`.
2854+
2855+
5. Let :math:`\REFFUNCADDR~a` be the reference :math:`r`.
2856+
2857+
6. :ref:`Invoke <exec-invoke>` the function instance at address :math:`a`.
28502858

28512859
.. math::
28522860
\begin{array}{lcl@{\qquad}l}
2853-
F; (\REFFUNCADDR~a)~\CALLREF~x &\stepto& F; (\INVOKE~a)
2861+
F; (\REFFUNCADDR~a)~(\CALLREF~x) &\stepto& F; (\INVOKE~a) \\
2862+
F; (\REFNULL~\X{ht})~(\CALLREF~x) &\stepto& F; \TRAP \\
28542863
\end{array}
28552864
28562865
@@ -2951,6 +2960,34 @@ Control Instructions
29512960
\end{array}
29522961
29532962
2963+
.. _exec-return_call_ref:
2964+
2965+
:math:`\RETURNCALLREF~x`
2966+
........................
2967+
2968+
1. Assert: due to :ref:`validation <valid-return_call_ref>`, a :ref:`function reference <syntax-ref>` is on the top of the stack.
2969+
2970+
2. Pop the reference value :math:`r` from the stack.
2971+
2972+
3. If :math:`r` is :math:`\REFNULL~\X{ht}`, then:
2973+
2974+
a. Trap.
2975+
2976+
4. Assert: due to :ref:`validation <valid-call_ref>`, :math:`r` is a :ref:`function reference <syntax-ref>`.
2977+
2978+
5. Let :math:`\REFFUNCADDR~a` be the reference :math:`r`.
2979+
2980+
6. :ref:`Tail-invoke <exec-return-invoke>` the function instance at address :math:`a`.
2981+
2982+
.. math::
2983+
\begin{array}{lcl@{\qquad}l}
2984+
\val~(\RETURNCALLREF~x) &\stepto& (\RETURNINVOKE~a)
2985+
& (\iff \val~(\CALLREF~x) \stepto (\INVOKE~a)) \\
2986+
\val~(\RETURNCALLREF~x) &\stepto& \TRAP
2987+
& (\iff \val~(\CALLREF~x) \stepto \TRAP) \\
2988+
\end{array}
2989+
2990+
29542991
.. _exec-return_call_indirect:
29552992

29562993
:math:`\RETURNCALLINDIRECT~x`

document/core/syntax/instructions.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -657,8 +657,9 @@ Instructions in this group affect the flow of control.
657657
\RETURN \\&&|&
658658
\CALL~\funcidx \\&&|&
659659
\CALLREF~\typeidx \\&&|&
660-
\CALLINDIRECT~\tableidx~\typeidx \\
660+
\CALLINDIRECT~\tableidx~\typeidx \\&&|&
661661
\RETURNCALL~\funcidx \\&&|&
662+
\RETURNCALLREF~\funcidx \\&&|&
662663
\RETURNCALLINDIRECT~\tableidx~\typeidx \\
663664
\end{array}
664665
@@ -708,7 +709,7 @@ The |CALLINDIRECT| instruction calls a function indirectly through an operand in
708709
Since it may contain functions of heterogeneous type,
709710
the callee is dynamically checked against the :ref:`function type <syntax-functype>` indexed by the instruction's second immediate, and the call is aborted with a :ref:`trap <trap>` if it does not match.
710711

711-
The |RETURNCALL| and |RETURNCALLINDIRECT| instructions are *tail-call* variants of the previous ones.
712+
The |RETURNCALL|, |RETURNCALLREF|, and |RETURNCALLINDIRECT| instructions are *tail-call* variants of the previous ones.
712713
That is, they first return from the current function before actually performing the respective call.
713714
It is guaranteed that no sequence of nested calls using only these instructions can cause resource exhaustion due to hitting an :ref:`implementation's limit <impl-exec>` on the number of active calls.
714715

document/core/text/instructions.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ All other control instruction are represented verbatim.
128128
\text{call\_indirect}~~x{:}\Ttableidx~~y,I'{:}\Ttypeuse_I &\Rightarrow& \CALLINDIRECT~x~y
129129
& (\iff I' = \{\ILOCALS~(\epsilon)^\ast\}) \\&&|&
130130
\text{return\_call}~~x{:}\Tfuncidx_I &\Rightarrow& \RETURNCALL~x \\ &&|&
131+
\text{return\_call\_ref}~~x{:}\Ttypeidx &\Rightarrow& \RETURNCALLREF~x \\ &&|&
131132
\text{return\_call\_indirect}~~x{:}\Ttableidx~~y,I'{:}\Ttypeuse_I &\Rightarrow& \RETURNCALLINDIRECT~x~y
132133
& (\iff I' = \{\ILOCALS~(\epsilon)^\ast\}) \\
133134
\end{array}

document/core/util/macros.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,7 @@
386386
.. |CALLREF| mathdef:: \xref{syntax/instructions}{syntax-instr-control}{\K{call\_ref}}
387387
.. |CALLINDIRECT| mathdef:: \xref{syntax/instructions}{syntax-instr-control}{\K{call\_indirect}}
388388
.. |RETURNCALL| mathdef:: \xref{syntax/instructions}{syntax-instr-control}{\K{return\_call}}
389+
.. |RETURNCALLREF| mathdef:: \xref{syntax/instructions}{syntax-instr-control}{\K{return\_call\_ref}}
389390
.. |RETURNCALLINDIRECT| mathdef:: \xref{syntax/instructions}{syntax-instr-control}{\K{return\_call\_indirect}}
390391

391392
.. |DROP| mathdef:: \xref{syntax/instructions}{syntax-instr-parametric}{\K{drop}}

document/core/valid/instructions.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,29 @@ Control Instructions
16181618
The |RETURNCALL| instruction is :ref:`stack-polymorphic <polymorphism>`.
16191619

16201620

1621+
.. _valid-return_call_ref:
1622+
1623+
:math:`\RETURNCALLREF~x`
1624+
........................
1625+
1626+
* The type :math:`C.\CTYPES[x]` must be defined in the context.
1627+
1628+
* Let :math:`[t_1^\ast] \to [t_2^\ast]` be the :ref:`function type <syntax-functype>` :math:`C.\CTYPES[x]`.
1629+
1630+
* The :ref:`result type <syntax-resulttype>` :math:`[t_2^\ast]` must be the same as :math:`C.\CRETURN`.
1631+
1632+
* Then the instruction is valid with type :math:`[t_1^\ast~(\REF~\NULL~x)] \to [t_2^\ast]`.
1633+
1634+
.. math::
1635+
\frac{
1636+
C.\CTYPES[x] = [t_1^\ast] \to [t_2^\ast]
1637+
\qquad
1638+
C.\CRETURN = [t_2^\ast]
1639+
}{
1640+
C \vdashinstr \CALLREF~x : [t_1^\ast~(\REF~\NULL~x)] \to [t_2^\ast]
1641+
}
1642+
1643+
16211644
.. _valid-return_call_indirect:
16221645

16231646
:math:`\RETURNCALLINDIRECT~x~y`

interpreter/README.md

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -254,14 +254,13 @@ op:
254254
br_if <var>
255255
br_table <var>+
256256
br_on_null <var> <heap_type>
257-
return
258-
return_call <var>
259-
return_call_indirect <func_type>
260257
call <var>
258+
call_ref <var>
261259
call_indirect <var>? <func_type>
262-
call_ref
263-
return_call_ref
264-
func.bind <func_type>
260+
return
261+
return_call <var>
262+
return_call_ref <var>
263+
return_call_indirect <var>? <func_type>
265264
local.get <var>
266265
local.set <var>
267266
local.tee <var>

proposals/function-references/Overview.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ Note: Extending block types with index sets to allow initialization status to la
209209
- iff `$t = [t1*] -> [t2*]`
210210
- traps on `null`
211211

212-
* With the [tail call proposal](https://github.com/WebAssembly/tail-call/blob/master/proposals/tail-call/Overview.md), there will also be `return_call_ref`:
212+
* `return_call_ref` tail-calls a function through a reference
213213
- `return_call_ref $t : [t1* (ref null $t)] -> [t2*]`
214214
- iff `$t = [t1*] -> [t2*]`
215215
- and `t2* <: C.result`

0 commit comments

Comments
 (0)