From 7aaf96911a5f9f6016f09b6de2323d33207e8653 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Thu, 25 Aug 2022 23:19:21 +0200 Subject: [PATCH] Add type annotation to call_ref --- .../core/appendix/gen-index-instructions.py | 2 +- document/core/appendix/index-instructions.rst | 2 +- document/core/binary/instructions.rst | 6 +- document/core/exec/instructions.rst | 6 +- document/core/syntax/instructions.rst | 2 +- document/core/text/instructions.rst | 2 +- document/core/valid/instructions.rst | 10 +- interpreter/binary/decode.ml | 4 +- interpreter/binary/encode.ml | 4 +- interpreter/exec/eval.ml | 10 +- interpreter/syntax/ast.ml | 4 +- interpreter/syntax/free.ml | 3 +- interpreter/syntax/operators.ml | 4 +- interpreter/text/arrange.ml | 4 +- interpreter/text/parser.mly | 4 +- interpreter/valid/valid.ml | 38 ++----- proposals/function-references/Overview.md | 24 ++-- test/core/br_on_non_null.wast | 8 +- test/core/br_on_null.wast | 8 +- test/core/call_ref.wast | 36 +++--- test/core/ref_as_non_null.wast | 4 +- test/core/return_call_ref.wast | 104 ++++++++++-------- 22 files changed, 148 insertions(+), 141 deletions(-) diff --git a/document/core/appendix/gen-index-instructions.py b/document/core/appendix/gen-index-instructions.py index 2f2a9175..77c2c019 100755 --- a/document/core/appendix/gen-index-instructions.py +++ b/document/core/appendix/gen-index-instructions.py @@ -81,7 +81,7 @@ def Instruction(name, opcode, type=None, validation=None, execution=None, operat Instruction(r'\CALLINDIRECT~x~y', r'\hex{11}', r'[t_1^\ast~\I32] \to [t_2^\ast]', r'valid-call_indirect', r'exec-call_indirect'), Instruction(None, r'\hex{12}'), Instruction(None, r'\hex{13}'), - Instruction(r'\CALLREF', r'\hex{14}', r'[t_1^\ast~(\REF~\NULL~x)] \to [t_2^\ast]', r'valid-call_ref', r'exec-call_ref'), + 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'), Instruction(None, r'\hex{15}'), Instruction(None, r'\hex{16}'), Instruction(None, r'\hex{17}'), diff --git a/document/core/appendix/index-instructions.rst b/document/core/appendix/index-instructions.rst index 67ffce6b..38f32d94 100644 --- a/document/core/appendix/index-instructions.rst +++ b/document/core/appendix/index-instructions.rst @@ -29,7 +29,7 @@ Instruction Binary Opcode :math:`\CALLINDIRECT~x~y` :math:`\hex{11}` :math:`[t_1^\ast~\I32] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` (reserved) :math:`\hex{12}` (reserved) :math:`\hex{13}` -:math:`\CALLREF` :math:`\hex{14}` :math:`[t_1^\ast~(\REF~\NULL~x)] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` +:math:`\CALLREF~x` :math:`\hex{14}` :math:`[t_1^\ast~(\REF~\NULL~x)] \to [t_2^\ast]` :ref:`validation ` :ref:`execution ` (reserved) :math:`\hex{15}` (reserved) :math:`\hex{16}` (reserved) :math:`\hex{17}` diff --git a/document/core/binary/instructions.rst b/document/core/binary/instructions.rst index 7f3f9019..e2f913cb 100644 --- a/document/core/binary/instructions.rst +++ b/document/core/binary/instructions.rst @@ -66,9 +66,9 @@ Control Instructions \hex{0F} &\Rightarrow& \RETURN \\ &&|& \hex{10}~~x{:}\Bfuncidx &\Rightarrow& \CALL~x \\ &&|& \hex{11}~~y{:}\Btypeidx~~x{:}\Btableidx &\Rightarrow& \CALLINDIRECT~x~y \\ &&|& - \hex{14} &\Rightarrow& \CALLREF \\ &&|& - \hex{D4}~~x{:}\Bfuncidx &\Rightarrow& \BRONNULL \\ &&|& - \hex{D6}~~x{:}\Bfuncidx &\Rightarrow& \BRONNONNULL \\ + \hex{14}~~x{:}\Btypeidx &\Rightarrow& \CALLREF~x \\ &&|& + \hex{D4}~~l{:}\Blabelidx &\Rightarrow& \BRONNULL~l \\ &&|& + \hex{D6}~~l{:}\Blabelidx &\Rightarrow& \BRONNONNULL~l \\ \end{array} .. note:: diff --git a/document/core/exec/instructions.rst b/document/core/exec/instructions.rst index d708b436..ee37c00b 100644 --- a/document/core/exec/instructions.rst +++ b/document/core/exec/instructions.rst @@ -2837,8 +2837,8 @@ Control Instructions .. _exec-call_ref: -:math:`\CALLREF` -................ +:math:`\CALLREF~x` +.................. 1. Assert: due to :ref:`validation `, a :ref:`function reference ` is on the top of the stack. @@ -2848,7 +2848,7 @@ Control Instructions .. math:: \begin{array}{lcl@{\qquad}l} - F; (\REFFUNCADDR~a)~\CALLREF &\stepto& F; (\INVOKE~a) + F; (\REFFUNCADDR~a)~\CALLREF~x &\stepto& F; (\INVOKE~a) \end{array} diff --git a/document/core/syntax/instructions.rst b/document/core/syntax/instructions.rst index c394bae5..4cde34c3 100644 --- a/document/core/syntax/instructions.rst +++ b/document/core/syntax/instructions.rst @@ -648,7 +648,7 @@ Instructions in this group affect the flow of control. \BRONNONNULL~\labelidx \\&&|& \RETURN \\&&|& \CALL~\funcidx \\&&|& - \CALLREF \\&&|& + \CALLREF~\typeidx \\&&|& \CALLINDIRECT~\tableidx~\typeidx \\ \end{array} diff --git a/document/core/text/instructions.rst b/document/core/text/instructions.rst index a1a7e34b..8b48c2c1 100644 --- a/document/core/text/instructions.rst +++ b/document/core/text/instructions.rst @@ -117,7 +117,7 @@ All other control instruction are represented verbatim. \text{br\_on\_non\_null}~~l{:}\Tlabelidx_I &\Rightarrow& \BRONNONNULL~l \\ &&|& \text{return} &\Rightarrow& \RETURN \\ &&|& \text{call}~~x{:}\Tfuncidx_I &\Rightarrow& \CALL~x \\ &&|& - \text{call\_ref} &\Rightarrow& \CALLREF \\ &&|& + \text{call\_ref}~~x{:}\Ttypeidx &\Rightarrow& \CALLREF~x \\ &&|& \text{call\_indirect}~~x{:}\Ttableidx~~y,I'{:}\Ttypeuse_I &\Rightarrow& \CALLINDIRECT~x~y & (\iff I' = \{\ILOCALS~(\epsilon)^\ast\}) \\ \end{array} diff --git a/document/core/valid/instructions.rst b/document/core/valid/instructions.rst index d9dc8453..b5cb94b9 100644 --- a/document/core/valid/instructions.rst +++ b/document/core/valid/instructions.rst @@ -1538,10 +1538,12 @@ Control Instructions .. _valid-call_ref: -:math:`\CALLREF` -................ +:math:`\CALLREF~x` +.................. + +* The type :math:`C.\CTYPES[x]` must be defined in the context. -* Let :math:`x` be some :ref:`type index ` for which :math:`C.\CTYPES[x]` is a :ref:`function type ` of the form :math:`[t_1^\ast] \to [t_2^\ast]`. +* Let :math:`[t_1^\ast] \to [t_2^\ast]` be the :ref:`function type ` :math:`C.\CTYPES[x]`. * Then the instruction is valid with type :math:`[t_1^\ast~(\REF~\NULL~x)] \to [t_2^\ast]`. @@ -1549,7 +1551,7 @@ Control Instructions \frac{ C.\CTYPES[x] = [t_1^\ast] \to [t_2^\ast] }{ - C \vdashinstr \CALLREF : [t_1^\ast~(\REF~\NULL~x)] \to [t_2^\ast] + C \vdashinstr \CALLREF~x : [t_1^\ast~(\REF~\NULL~x)] \to [t_2^\ast] } diff --git a/interpreter/binary/decode.ml b/interpreter/binary/decode.ml index 29d318e2..fdc128bf 100644 --- a/interpreter/binary/decode.ml +++ b/interpreter/binary/decode.ml @@ -318,8 +318,8 @@ let rec instr s = | 0x12 | 0x13 as b -> illegal s pos b (* return_call, return_call_indirect *) - | 0x14 -> call_ref - | 0x15 -> return_call_ref + | 0x14 -> call_ref (at var s) + | 0x15 -> return_call_ref (at var s) | 0x16 as b -> illegal s pos b diff --git a/interpreter/binary/encode.ml b/interpreter/binary/encode.ml index 60ed152b..139dbcd0 100644 --- a/interpreter/binary/encode.ml +++ b/interpreter/binary/encode.ml @@ -197,9 +197,9 @@ struct | BrOnNonNull x -> op 0xd6; var x | Return -> op 0x0f | Call x -> op 0x10; var x - | CallRef -> op 0x14 + | CallRef x -> op 0x14; var x | CallIndirect (x, y) -> op 0x11; var y; var x - | ReturnCallRef -> op 0x15 + | ReturnCallRef x -> op 0x15; var x | Drop -> op 0x1a | Select None -> op 0x1b diff --git a/interpreter/exec/eval.ml b/interpreter/exec/eval.ml index 5e9231ab..c67d467a 100644 --- a/interpreter/exec/eval.ml +++ b/interpreter/exec/eval.ml @@ -222,10 +222,10 @@ let rec step (c : config) : config = | Call x, vs -> vs, [Invoke (func c.frame.inst x) @@ e.at] - | CallRef, Ref (NullRef _) :: vs -> + | CallRef _x, Ref (NullRef _) :: vs -> vs, [Trapping "null function reference" @@ e.at] - | CallRef, Ref (FuncRef f) :: vs -> + | CallRef _x, Ref (FuncRef f) :: vs -> vs, [Invoke f @@ e.at] | CallIndirect (x, y), Num (I32 i) :: vs -> @@ -237,11 +237,11 @@ let rec step (c : config) : config = else vs, [Trapping "indirect call type mismatch" @@ e.at] - | ReturnCallRef, Ref (NullRef _) :: vs -> + | ReturnCallRef _x, Ref (NullRef _) :: vs -> vs, [Trapping "null function reference" @@ e.at] - | ReturnCallRef, vs -> - (match (step {c with code = (vs, [Plain CallRef @@ e.at])}).code with + | ReturnCallRef x, vs -> + (match (step {c with code = (vs, [Plain (CallRef x) @@ e.at])}).code with | vs', [{it = Invoke a; at}] -> vs', [ReturningInvoke (vs', a) @@ at] | vs', [{it = Trapping s; at}] -> vs', [Trapping s @@ at] | _ -> assert false diff --git a/interpreter/syntax/ast.ml b/interpreter/syntax/ast.ml index bbe17c6f..421cf103 100644 --- a/interpreter/syntax/ast.ml +++ b/interpreter/syntax/ast.ml @@ -153,9 +153,9 @@ and instr' = | BrOnNonNull of idx (* break on non-null *) | Return (* break from function body *) | Call of idx (* call function *) - | CallRef (* call function through reference *) + | CallRef of idx (* call function through reference *) | CallIndirect of idx * idx (* call function through table *) - | ReturnCallRef (* tail call through reference *) + | ReturnCallRef of idx (* tail call through reference *) | LocalGet of idx (* read local idxiable *) | LocalSet of idx (* write local idxiable *) | LocalTee of idx (* write local idxiable and keep value *) diff --git a/interpreter/syntax/free.ml b/interpreter/syntax/free.ml index 764e08b2..41ee6137 100644 --- a/interpreter/syntax/free.ml +++ b/interpreter/syntax/free.ml @@ -108,8 +108,9 @@ let rec instr (e : instr) = | If (bt, es1, es2) -> block_type bt ++ block es1 ++ block es2 | Br x | BrIf x | BrOnNull x | BrOnNonNull x -> labels (idx x) | BrTable (xs, x) -> list (fun x -> labels (idx x)) (x::xs) - | Return | CallRef | ReturnCallRef -> empty + | Return -> empty | Call x -> funcs (idx x) + | CallRef x | ReturnCallRef x -> types (idx x) | CallIndirect (x, y) -> tables (idx x) ++ types (idx y) | LocalGet x | LocalSet x | LocalTee x -> locals (idx x) | GlobalGet x | GlobalSet x -> globals (idx x) diff --git a/interpreter/syntax/operators.ml b/interpreter/syntax/operators.ml index ecc86a9b..5712b6a0 100644 --- a/interpreter/syntax/operators.ml +++ b/interpreter/syntax/operators.ml @@ -32,9 +32,9 @@ let br_on_non_null x = BrOnNonNull x let return = Return let call x = Call x -let call_ref = CallRef +let call_ref x = CallRef x let call_indirect x y = CallIndirect (x, y) -let return_call_ref = ReturnCallRef +let return_call_ref x = ReturnCallRef x let local_get x = LocalGet x let local_set x = LocalSet x diff --git a/interpreter/text/arrange.ml b/interpreter/text/arrange.ml index 027dcde7..1dd877b8 100644 --- a/interpreter/text/arrange.ml +++ b/interpreter/text/arrange.ml @@ -456,10 +456,10 @@ let rec instr e = | BrOnNonNull x -> "br_on_non_null " ^ var x, [] | Return -> "return", [] | Call x -> "call " ^ var x, [] - | CallRef -> "call_ref", [] + | CallRef x -> "call_ref " ^ var x, [] | CallIndirect (x, y) -> "call_indirect " ^ var x, [Node ("type " ^ var y, [])] - | ReturnCallRef -> "return_call_ref", [] + | ReturnCallRef x -> "return_call_ref " ^ var x, [] | LocalGet x -> "local.get " ^ var x, [] | LocalSet x -> "local.set " ^ var x, [] | LocalTee x -> "local.tee " ^ var x, [] diff --git a/interpreter/text/parser.mly b/interpreter/text/parser.mly index 1bf13ff2..0e687622 100644 --- a/interpreter/text/parser.mly +++ b/interpreter/text/parser.mly @@ -447,8 +447,8 @@ plain_instr : | BR_ON_NON_NULL var { fun c -> br_on_non_null ($2 c label) } | RETURN { fun c -> return } | CALL var { fun c -> call ($2 c func) } - | CALL_REF { fun c -> call_ref } - | RETURN_CALL_REF { fun c -> return_call_ref } + | CALL_REF var { fun c -> call_ref ($2 c type_) } + | RETURN_CALL_REF var { fun c -> return_call_ref ($2 c type_) } | LOCAL_GET var { fun c -> local_get ($2 c local) } | LOCAL_SET var { fun c -> local_set ($2 c local) } | LOCAL_TEE var { fun c -> local_tee ($2 c local) } diff --git a/interpreter/valid/valid.ml b/interpreter/valid/valid.ml index 9159037f..eaa80959 100644 --- a/interpreter/valid/valid.ml +++ b/interpreter/valid/valid.ml @@ -392,18 +392,9 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : infer_in let FuncT (ts1, ts2) = func c x in ts1 --> ts2, [] - | CallRef -> - (match peek_ref 0 s e.at with - | (_, DefHT x) -> - let FuncT (ts1, ts2) = func_type c (x @@ e.at) in - (ts1 @ [RefT (Null, DefHT x)]) --> ts2, [] - | (_, BotHT) -> - [RefT (Null, BotHT)] -->... [], [] - | rt -> - error e.at - ("type mismatch: instruction requires function reference type" ^ - " but stack has " ^ string_of_val_type (RefT rt)) - ) + | CallRef x -> + let FuncT (ts1, ts2) = func_type c x in + (ts1 @ [RefT (Null, DefHT x.it)]) --> ts2, [] | CallIndirect (x, y) -> let TableT (_lim, t) = table c x in @@ -413,22 +404,13 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : infer_in " but table has element type " ^ string_of_ref_type t); (ts1 @ [NumT I32T]) --> ts2, [] - | ReturnCallRef -> - (match peek_ref 0 s e.at with - | (_, DefHT x) -> - let FuncT (ts1, ts2) = func_type c (x @@ e.at) in - require (match_result_type c.types [] ts2 c.results) e.at - ("type mismatch: current function requires result type " ^ - string_of_result_type c.results ^ - " but callee returns " ^ string_of_result_type ts2); - (ts1 @ [RefT (Null, DefHT x)]) -->... [], [] - | (_, BotHT) -> - [RefT (Null, BotHT)] -->... [], [] - | rt -> - error e.at - ("type mismatch: instruction requires function reference type" ^ - " but stack has " ^ string_of_ref_type rt) - ) + | ReturnCallRef x -> + let FuncT (ts1, ts2) = func_type c x in + require (match_result_type c.types [] ts2 c.results) e.at + ("type mismatch: current function requires result type " ^ + string_of_result_type c.results ^ + " but callee returns " ^ string_of_result_type ts2); + (ts1 @ [RefT (Null, DefHT x.it)]) -->... [], [] | LocalGet x -> let LocalT (init, t) = local c x in diff --git a/proposals/function-references/Overview.md b/proposals/function-references/Overview.md index e3b93e9b..08c537cd 100644 --- a/proposals/function-references/Overview.md +++ b/proposals/function-references/Overview.md @@ -48,7 +48,7 @@ The function `$hof` takes a function pointer as parameter, and is invoked by `$c (type $i32-i32 (func (param i32) (result i32))) (func $hof (param $f (ref $i32-i32)) (result i32) - (i32.add (i32.const 10) (call_ref (i32.const 42) (local.get $f))) + (i32.add (i32.const 10) (call_ref $i32-i32 (i32.const 42) (local.get $f))) ) (func $inc (param $i i32) (result i32) @@ -204,13 +204,13 @@ Note: Extending block types with index sets to allow initialization status to la - iff `$f : $t` - this is a *constant instruction* -* `call_ref` calls a function through a reference - - `call_ref : [t1* (ref null $t)] -> [t2*]` +* `call_ref ` calls a function through a reference + - `call_ref $t : [t1* (ref null $t)] -> [t2*]` - iff `$t = [t1*] -> [t2*]` - traps on `null` * 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`: - - `return_call_ref : [t1* (ref null $t)] -> [t2*]` + - `return_call_ref $t : [t1* (ref null $t)] -> [t2*]` - iff `$t = [t1*] -> [t2*]` - and `t2* <: C.result` - traps on `null` @@ -218,7 +218,7 @@ Note: Extending block types with index sets to allow initialization status to la #### Optional References -* `ref.null` is generalised to take a `` immediate +* `ref.null ` is generalised to take a `` immediate - `ref.null ht: [] -> [(ref null ht)]` - iff `ht ok` @@ -227,13 +227,13 @@ Note: Extending block types with index sets to allow initialization status to la - iff `ht ok` - traps on `null` -* `br_on_null $l` checks for null and branches if present +* `br_on_null ` checks for null and branches if present - `br_on_null $l : [t* (ref null ht)] -> [t* (ref ht)]` - iff `$l : [t*]` - and `ht ok` - branches to `$l` on `null`, otherwise returns operand as non-null -* `br_on_non_null $l` checks for null and branches if not present +* `br_on_non_null ` checks for null and branches if not present - `br_on_non_null $l : [t* (ref null ht)] -> [t*]` - iff `$l : [t* (ref ht)]` - and `ht ok` @@ -246,15 +246,15 @@ Note: Extending block types with index sets to allow initialization status to la Typing of local instructions is updated to account for the initialization status of locals. -* `local.get $x` +* `local.get ` - `local.get $x : [] -> [t]` - iff `$x : set t` -* `local.set $x` +* `local.set ` - `local.set $x : [t] -> [] $x` - iff `$x : set? t` -* `local.tee $x` +* `local.tee ` - `local.tee $x : [t] -> [t] $x` - iff `$x : set? t` @@ -319,8 +319,8 @@ The opcode for heap types is encoded as an `s33`. | Opcode | Instruction | Immediates | | ------ | ------------------------ | ---------- | -| 0x14 | `call_ref` | | -| 0x15 | `return_call_ref` | | +| 0x14 | `call_ref $t` | `$t : u32` | +| 0x15 | `return_call_ref $t` | `$t : u32` | | 0xd3 | `ref.as_non_null` | | | 0xd4 | `br_on_null $l` | `$l : u32` | | 0xd6 | `br_on_non_null $l` | `$l : u32` | diff --git a/test/core/br_on_non_null.wast b/test/core/br_on_non_null.wast index 145b4f83..6cf7eff5 100644 --- a/test/core/br_on_non_null.wast +++ b/test/core/br_on_non_null.wast @@ -2,7 +2,7 @@ (type $t (func (result i32))) (func $nn (param $r (ref $t)) (result i32) - (call_ref + (call_ref $t (block $l (result (ref $t)) (br_on_non_null $l (local.get $r)) (return (i32.const -1)) @@ -10,7 +10,7 @@ ) ) (func $n (param $r (ref null $t)) (result i32) - (call_ref + (call_ref $t (block $l (result (ref $t)) (br_on_non_null $l (local.get $r)) (return (i32.const -1)) @@ -27,7 +27,7 @@ (func (export "unreachable") (result i32) (block $l - (return (call_ref (br_on_null $l (unreachable)))) + (return (call_ref $t (br_on_null $l (unreachable)))) ) (i32.const -1) ) @@ -53,7 +53,7 @@ (func $f (param i32) (result i32) (i32.mul (local.get 0) (local.get 0))) (func $a (param $n i32) (param $r (ref null $t)) (result i32) - (call_ref + (call_ref $t (block $l (result i32 (ref $t)) (return (br_on_non_null $l (local.get $n) (local.get $r))) ) diff --git a/test/core/br_on_null.wast b/test/core/br_on_null.wast index ec3471cc..c6505a3f 100644 --- a/test/core/br_on_null.wast +++ b/test/core/br_on_null.wast @@ -3,13 +3,13 @@ (func $nn (param $r (ref $t)) (result i32) (block $l - (return (call_ref (br_on_null $l (local.get $r)))) + (return (call_ref $t (br_on_null $l (local.get $r)))) ) (i32.const -1) ) (func $n (param $r (ref null $t)) (result i32) (block $l - (return (call_ref (br_on_null $l (local.get $r)))) + (return (call_ref $t (br_on_null $l (local.get $r)))) ) (i32.const -1) ) @@ -23,7 +23,7 @@ (func (export "unreachable") (result i32) (block $l - (return (call_ref (br_on_null $l (unreachable)))) + (return (call_ref $t (br_on_null $l (unreachable)))) ) (i32.const -1) ) @@ -50,7 +50,7 @@ (func $a (param $n i32) (param $r (ref null $t)) (result i32) (block $l (result i32) - (return (call_ref (br_on_null $l (local.get $n) (local.get $r)))) + (return (call_ref $t (br_on_null $l (local.get $n) (local.get $r)))) ) ) diff --git a/test/core/call_ref.wast b/test/core/call_ref.wast index 503c4e86..42533959 100644 --- a/test/core/call_ref.wast +++ b/test/core/call_ref.wast @@ -2,7 +2,7 @@ (type $ii (func (param i32) (result i32))) (func $apply (param $f (ref $ii)) (param $x i32) (result i32) - (call_ref (local.get $x) (local.get $f)) + (call_ref $ii (local.get $x) (local.get $f)) ) (func $f (type $ii) (i32.mul (local.get 0) (local.get 0))) @@ -15,11 +15,11 @@ (local $rg (ref null $ii)) (local.set $rf (ref.func $f)) (local.set $rg (ref.func $g)) - (call_ref (call_ref (local.get $x) (local.get $rf)) (local.get $rg)) + (call_ref $ii (call_ref $ii (local.get $x) (local.get $rf)) (local.get $rg)) ) (func (export "null") (result i32) - (call_ref (i32.const 1) (ref.null $ii)) + (call_ref $ii (i32.const 1) (ref.null $ii)) ) ;; Recursion @@ -36,7 +36,7 @@ (else (i64.mul (local.get 0) - (call_ref (i64.sub (local.get 0) (i64.const 1)) (global.get $fac)) + (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $fac)) ) ) ) @@ -49,7 +49,7 @@ (if (result i64) (i64.eqz (local.get 0)) (then (local.get 1)) (else - (call_ref + (call_ref $lll (i64.sub (local.get 0) (i64.const 1)) (i64.mul (local.get 0) (local.get 1)) (global.get $fac-acc) @@ -66,8 +66,8 @@ (then (i64.const 1)) (else (i64.add - (call_ref (i64.sub (local.get 0) (i64.const 2)) (global.get $fib)) - (call_ref (i64.sub (local.get 0) (i64.const 1)) (global.get $fib)) + (call_ref $ll (i64.sub (local.get 0) (i64.const 2)) (global.get $fib)) + (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $fib)) ) ) ) @@ -80,13 +80,13 @@ (func $even (export "even") (type $ll) (if (result i64) (i64.eqz (local.get 0)) (then (i64.const 44)) - (else (call_ref (i64.sub (local.get 0) (i64.const 1)) (global.get $odd))) + (else (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $odd))) ) ) (func $odd (export "odd") (type $ll) (if (result i64) (i64.eqz (local.get 0)) (then (i64.const 99)) - (else (call_ref (i64.sub (local.get 0) (i64.const 1)) (global.get $even))) + (else (call_ref $ll (i64.sub (local.get 0) (i64.const 1)) (global.get $even))) ) ) ) @@ -127,34 +127,37 @@ ;; Unreachable typing. (module + (type $t (func)) (func (export "unreachable") (result i32) (unreachable) - (call_ref) + (call_ref $t) ) ) (assert_trap (invoke "unreachable") "unreachable") (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (ref.func $f) - (call_ref) + (call_ref $t) ) ) (assert_trap (invoke "unreachable") "unreachable") (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (i32.const 0) (ref.func $f) - (call_ref) + (call_ref $t) (drop) (i32.const 0) ) @@ -164,13 +167,14 @@ (assert_invalid (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (i64.const 0) (ref.func $f) - (call_ref) + (call_ref $t) ) ) "type mismatch" @@ -179,12 +183,13 @@ (assert_invalid (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (ref.func $f) - (call_ref) + (call_ref $t) (drop) (i64.const 0) ) @@ -194,8 +199,9 @@ (assert_invalid (module + (type $t (func)) (func $f (param $r externref) - (call_ref (local.get $r)) + (call_ref $t (local.get $r)) ) ) "type mismatch" diff --git a/test/core/ref_as_non_null.wast b/test/core/ref_as_non_null.wast index ba5c4547..6b3380fc 100644 --- a/test/core/ref_as_non_null.wast +++ b/test/core/ref_as_non_null.wast @@ -2,10 +2,10 @@ (type $t (func (result i32))) (func $nn (param $r (ref $t)) (result i32) - (call_ref (ref.as_non_null (local.get $r))) + (call_ref $t (ref.as_non_null (local.get $r))) ) (func $n (param $r (ref null $t)) (result i32) - (call_ref (ref.as_non_null (local.get $r))) + (call_ref $t (ref.as_non_null (local.get $r))) ) (elem func $f) diff --git a/test/core/return_call_ref.wast b/test/core/return_call_ref.wast index 8e7aac82..353811f0 100644 --- a/test/core/return_call_ref.wast +++ b/test/core/return_call_ref.wast @@ -59,48 +59,48 @@ ;; Typing (func (export "type-i32") (result i32) - (return_call_ref (global.get $const-i32)) + (return_call_ref $-i32 (global.get $const-i32)) ) (func (export "type-i64") (result i64) - (return_call_ref (global.get $const-i64)) + (return_call_ref $-i64 (global.get $const-i64)) ) (func (export "type-f32") (result f32) - (return_call_ref (global.get $const-f32)) + (return_call_ref $-f32 (global.get $const-f32)) ) (func (export "type-f64") (result f64) - (return_call_ref (global.get $const-f64)) + (return_call_ref $-f64 (global.get $const-f64)) ) (func (export "type-first-i32") (result i32) - (return_call_ref (i32.const 32) (global.get $id-i32)) + (return_call_ref $i32-i32 (i32.const 32) (global.get $id-i32)) ) (func (export "type-first-i64") (result i64) - (return_call_ref (i64.const 64) (global.get $id-i64)) + (return_call_ref $i64-i64 (i64.const 64) (global.get $id-i64)) ) (func (export "type-first-f32") (result f32) - (return_call_ref (f32.const 1.32) (global.get $id-f32)) + (return_call_ref $f32-f32 (f32.const 1.32) (global.get $id-f32)) ) (func (export "type-first-f64") (result f64) - (return_call_ref (f64.const 1.64) (global.get $id-f64)) + (return_call_ref $f64-f64 (f64.const 1.64) (global.get $id-f64)) ) (func (export "type-second-i32") (result i32) - (return_call_ref (f32.const 32.1) (i32.const 32) (global.get $f32-i32)) + (return_call_ref $f32-i32 (f32.const 32.1) (i32.const 32) (global.get $f32-i32)) ) (func (export "type-second-i64") (result i64) - (return_call_ref (i32.const 32) (i64.const 64) (global.get $i32-i64)) + (return_call_ref $i32-i64 (i32.const 32) (i64.const 64) (global.get $i32-i64)) ) (func (export "type-second-f32") (result f32) - (return_call_ref (f64.const 64) (f32.const 32) (global.get $f64-f32)) + (return_call_ref $f64-f32 (f64.const 64) (f32.const 32) (global.get $f64-f32)) ) (func (export "type-second-f64") (result f64) - (return_call_ref (i64.const 64) (f64.const 64.1) (global.get $i64-f64)) + (return_call_ref $i64-f64 (i64.const 64) (f64.const 64.1) (global.get $i64-f64)) ) ;; Null (func (export "null") - (return_call_ref (ref.null $proc)) + (return_call_ref $proc (ref.null $proc)) ) ;; Recursion @@ -112,7 +112,7 @@ (if (result i64) (i64.eqz (local.get 0)) (then (local.get 1)) (else - (return_call_ref + (return_call_ref $i64i64-i64 (i64.sub (local.get 0) (i64.const 1)) (i64.mul (local.get 0) (local.get 1)) (global.get $fac-acc) @@ -128,7 +128,7 @@ (if (result i64) (i64.eqz (local.get 0)) (then (local.get 0)) (else - (return_call_ref + (return_call_ref $i64-i64 (i64.sub (local.get 0) (i64.const 1)) (global.get $count) ) @@ -144,7 +144,7 @@ (if (result i64) (i64.eqz (local.get 0)) (then (i64.const 44)) (else - (return_call_ref + (return_call_ref $i64-i64 (i64.sub (local.get 0) (i64.const 1)) (global.get $odd) ) @@ -156,7 +156,7 @@ (if (result i64) (i64.eqz (local.get 0)) (then (i64.const 99)) (else - (return_call_ref + (return_call_ref $i64-i64 (i64.sub (local.get 0) (i64.const 1)) (global.get $even) ) @@ -212,24 +212,29 @@ (module (type $t (func)) + (type $t1 (func (result (ref $t)))) + (type $t2 (func (result (ref null $t)))) + (type $t3 (func (result (ref func)))) + (type $t4 (func (result (ref null func)))) (elem declare func $f11 $f22 $f33 $f44) - (func $f11 (result (ref $t)) (return_call_ref (ref.func $f11))) - (func $f21 (result (ref null $t)) (return_call_ref (ref.func $f11))) - (func $f22 (result (ref null $t)) (return_call_ref (ref.func $f22))) - (func $f31 (result (ref func)) (return_call_ref (ref.func $f11))) - (func $f33 (result (ref func)) (return_call_ref (ref.func $f33))) - (func $f41 (result (ref null func)) (return_call_ref (ref.func $f11))) - (func $f42 (result (ref null func)) (return_call_ref (ref.func $f22))) - (func $f43 (result (ref null func)) (return_call_ref (ref.func $f33))) - (func $f44 (result (ref null func)) (return_call_ref (ref.func $f44))) + (func $f11 (result (ref $t)) (return_call_ref $t1 (ref.func $f11))) + (func $f21 (result (ref null $t)) (return_call_ref $t1 (ref.func $f11))) + (func $f22 (result (ref null $t)) (return_call_ref $t2 (ref.func $f22))) + (func $f31 (result (ref func)) (return_call_ref $t1 (ref.func $f11))) + (func $f33 (result (ref func)) (return_call_ref $t3 (ref.func $f33))) + (func $f41 (result (ref null func)) (return_call_ref $t1 (ref.func $f11))) + (func $f42 (result (ref null func)) (return_call_ref $t2 (ref.func $f22))) + (func $f43 (result (ref null func)) (return_call_ref $t3 (ref.func $f33))) + (func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44))) ) (assert_invalid (module (type $t (func)) + (type $t2 (func (result (ref null $t)))) (elem declare func $f22) - (func $f12 (result (ref $t)) (return_call_ref (ref.func $f22))) - (func $f22 (result (ref null $t)) (return_call_ref (ref.func $f22))) + (func $f12 (result (ref $t)) (return_call_ref $t2 (ref.func $f22))) + (func $f22 (result (ref null $t)) (return_call_ref $t2 (ref.func $f22))) ) "type mismatch" ) @@ -237,9 +242,10 @@ (assert_invalid (module (type $t (func)) + (type $t3 (func (result (ref func)))) (elem declare func $f33) - (func $f13 (result (ref $t)) (return_call_ref (ref.func $f33))) - (func $f33 (result (ref func)) (return_call_ref (ref.func $f33))) + (func $f13 (result (ref $t)) (return_call_ref $t3 (ref.func $f33))) + (func $f33 (result (ref func)) (return_call_ref $t3 (ref.func $f33))) ) "type mismatch" ) @@ -247,9 +253,10 @@ (assert_invalid (module (type $t (func)) + (type $t4 (func (result (ref null func)))) (elem declare func $f44) - (func $f14 (result (ref $t)) (return_call_ref (ref.func $f44))) - (func $f44 (result (ref null func)) (return_call_ref (ref.func $f44))) + (func $f14 (result (ref $t)) (return_call_ref $t4 (ref.func $f44))) + (func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44))) ) "type mismatch" ) @@ -257,9 +264,10 @@ (assert_invalid (module (type $t (func)) + (type $t3 (func (result (ref func)))) (elem declare func $f33) - (func $f23 (result (ref null $t)) (return_call_ref (ref.func $f33))) - (func $f33 (result (ref func)) (return_call_ref (ref.func $f33))) + (func $f23 (result (ref null $t)) (return_call_ref $t3 (ref.func $f33))) + (func $f33 (result (ref func)) (return_call_ref $t3 (ref.func $f33))) ) "type mismatch" ) @@ -267,18 +275,20 @@ (assert_invalid (module (type $t (func)) + (type $t4 (func (result (ref null func)))) (elem declare func $f44) - (func $f24 (result (ref null $t)) (return_call_ref (ref.func $f44))) - (func $f44 (result (ref null func)) (return_call_ref (ref.func $f44))) + (func $f24 (result (ref null $t)) (return_call_ref $t4 (ref.func $f44))) + (func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44))) ) "type mismatch" ) (assert_invalid (module + (type $t4 (func (result (ref null func)))) (elem declare func $f44) - (func $f34 (result (ref func)) (return_call_ref (ref.func $f44))) - (func $f44 (result (ref null func)) (return_call_ref (ref.func $f44))) + (func $f34 (result (ref func)) (return_call_ref $t4 (ref.func $f44))) + (func $f44 (result (ref null func)) (return_call_ref $t4 (ref.func $f44))) ) "type mismatch" ) @@ -287,34 +297,37 @@ ;; Unreachable typing. (module + (type $t (func (result i32))) (func (export "unreachable") (result i32) (unreachable) - (return_call_ref) + (return_call_ref $t) ) ) (assert_trap (invoke "unreachable") "unreachable") (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (ref.func $f) - (return_call_ref) + (return_call_ref $t) ) ) (assert_trap (invoke "unreachable") "unreachable") (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (i32.const 0) (ref.func $f) - (return_call_ref) + (return_call_ref $t) (i32.const 0) ) ) @@ -323,13 +336,14 @@ (assert_invalid (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (i64.const 0) (ref.func $f) - (return_call_ref) + (return_call_ref $t) ) ) "type mismatch" @@ -338,12 +352,13 @@ (assert_invalid (module (elem declare func $f) + (type $t (func (param i32) (result i32))) (func $f (param i32) (result i32) (local.get 0)) (func (export "unreachable") (result i32) (unreachable) (ref.func $f) - (return_call_ref) + (return_call_ref $t) (i64.const 0) ) ) @@ -352,8 +367,9 @@ (assert_invalid (module + (type $t (func)) (func $f (param $r externref) - (return_call_ref (local.get $r)) + (return_call_ref $t (local.get $r)) ) ) "type mismatch"