From 6d8c1099bd78778c4af398ae98cefd957a014ece Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Tue, 7 Nov 2017 16:47:06 +0100 Subject: [PATCH 1/2] [interpreter/test] Allow typeuse syntax for call_indirect --- interpreter/README.md | 2 +- interpreter/text/arrange.ml | 2 +- interpreter/text/parser.mly | 57 ++++++++- test/core/br.wast | 8 +- test/core/br_table.wast | 8 +- test/core/call_indirect.wast | 234 +++++++++++++++++++++++++++++------ test/core/elem.wast | 14 +-- test/core/func.wast | 16 +-- test/core/func_ptrs.wast | 6 +- test/core/imports.wast | 12 +- test/core/left-to-right.wast | 8 +- test/core/linking.wast | 6 +- test/core/return.wast | 16 ++- test/core/typecheck.wast | 4 +- test/core/unreachable.wast | 16 ++- 15 files changed, 321 insertions(+), 88 deletions(-) diff --git a/interpreter/README.md b/interpreter/README.md index fe4f2273a4..dc34b0446a 100644 --- a/interpreter/README.md +++ b/interpreter/README.md @@ -211,7 +211,7 @@ op: br_table + return call - call_indirect + call_indirect drop select get_local diff --git a/interpreter/text/arrange.ml b/interpreter/text/arrange.ml index 5dcf9d715b..c12d268b82 100644 --- a/interpreter/text/arrange.ml +++ b/interpreter/text/arrange.ml @@ -234,7 +234,7 @@ let rec instr e = "br_table " ^ String.concat " " (list var (xs @ [x])), [] | Return -> "return", [] | Call x -> "call " ^ var x, [] - | CallIndirect x -> "call_indirect " ^ var x, [] + | CallIndirect x -> "call_indirect", [Node ("type " ^ var x, [])] | Drop -> "drop", [] | Select -> "select", [] | GetLocal x -> "get_local " ^ var x, [] diff --git a/interpreter/text/parser.mly b/interpreter/text/parser.mly index 934bc59d27..71f9af1d8d 100644 --- a/interpreter/text/parser.mly +++ b/interpreter/text/parser.mly @@ -294,6 +294,7 @@ align_opt : instr : | plain_instr { let at = at () in fun c -> [$1 c @@ at] } + | call_instr { let at = at () in fun c -> let e, es = $1 c in (e @@ at) :: es } | block_instr { let at = at () in fun c -> [$1 c @@ at] } | expr { $1 } /* Sugar */ @@ -307,7 +308,6 @@ plain_instr : br_table xs x } | RETURN { fun c -> return } | CALL var { fun c -> call ($2 c func) } - | CALL_INDIRECT var { fun c -> call_indirect ($2 c type_) } | DROP { fun c -> drop } | SELECT { fun c -> select } | GET_LOCAL var { fun c -> get_local ($2 c local) } @@ -326,6 +326,34 @@ plain_instr : | BINARY { fun c -> $1 } | CONVERT { fun c -> $1 } +call_instr : + | CALL_INDIRECT call_instr_sig + { fun c -> let x, es = $2 c in call_indirect x, es } + +call_instr_sig : + | type_use call_instr_params + { let at1 = ati 1 in + fun c -> + match $2 c with + | FuncType ([], []), es -> $1 c type_, es + | ft, es -> inline_type_explicit c ($1 c type_) ft at1, es } + | call_instr_params + { let at1 = ati 1 in + fun c -> let ft, es = $1 c in inline_type c ft at1, es } + +call_instr_params : + | LPAR PARAM value_type_list RPAR call_instr_params + { fun c -> + let FuncType (ts1, ts2), es = $5 c in FuncType ($3 @ ts1, ts2), es } + | call_instr_results + { fun c -> let ts, es = $1 c in FuncType ([], ts), es } + +call_instr_results : + | LPAR RESULT value_type_list RPAR call_instr_results + { fun c -> let ts, es = $5 c in $3 @ ts, es } + | instr + { fun c -> [], $1 c } + block_instr : | BLOCK labeling_opt block END labeling_end_opt { fun c -> let c' = $2 c $5 in let ts, es = $3 c' in block ts es } @@ -351,6 +379,8 @@ expr : /* Sugar */ expr1 : /* Sugar */ | plain_instr expr_list { fun c -> $2 c, $1 c } + | CALL_INDIRECT call_expr_sig + { fun c -> let x, es = $2 c in es, call_indirect x } | BLOCK labeling_opt block { fun c -> let c' = $2 c [] in let ts, es = $3 c' in [], block ts es } | LOOP labeling_opt block @@ -359,6 +389,31 @@ expr1 : /* Sugar */ { fun c -> let c' = $2 c [] in let ts, (es, es1, es2) = $3 c c' in es, if_ ts es1 es2 } +call_expr_sig : + | type_use call_expr_params + { let at1 = ati 1 in + fun c -> + match $2 c with + | FuncType ([], []), es -> $1 c type_, es + | ft, es -> inline_type_explicit c ($1 c type_) ft at1, es } + | call_expr_params + { let at1 = ati 1 in + fun c -> let ft, es = $1 c in inline_type c ft at1, es } + +call_expr_params : + | LPAR PARAM value_type_list RPAR call_expr_params + { fun c -> + let FuncType (ts1, ts2), es = $5 c in FuncType ($3 @ ts1, ts2), es } + | call_expr_results + { fun c -> let ts, es = $1 c in FuncType ([], ts), es } + +call_expr_results : + | LPAR RESULT value_type_list RPAR call_expr_results + { fun c -> let ts, es = $5 c in $3 @ ts, es } + | expr_list + { fun c -> [], $1 c } + + if_block : | block_sig if_block { fun c c' -> let ts, ess = $2 c c' in $1 @ ts, ess } | if_ { fun c c' -> [], $1 c c' } diff --git a/test/core/br.wast b/test/core/br.wast index 77f781d4de..5e99209c78 100644 --- a/test/core/br.wast +++ b/test/core/br.wast @@ -147,7 +147,7 @@ (table anyfunc (elem $f)) (func (export "as-call_indirect-func") (result i32) (block (result i32) - (call_indirect $sig + (call_indirect (type $sig) (br 0 (i32.const 20)) (i32.const 1) (i32.const 2) (i32.const 3) ) @@ -155,7 +155,7 @@ ) (func (export "as-call_indirect-first") (result i32) (block (result i32) - (call_indirect $sig + (call_indirect (type $sig) (i32.const 0) (br 0 (i32.const 21)) (i32.const 2) (i32.const 3) ) @@ -163,7 +163,7 @@ ) (func (export "as-call_indirect-mid") (result i32) (block (result i32) - (call_indirect $sig + (call_indirect (type $sig) (i32.const 0) (i32.const 1) (br 0 (i32.const 22)) (i32.const 3) ) @@ -171,7 +171,7 @@ ) (func (export "as-call_indirect-last") (result i32) (block (result i32) - (call_indirect $sig + (call_indirect (type $sig) (i32.const 0) (i32.const 1) (i32.const 2) (br 0 (i32.const 23)) ) diff --git a/test/core/br_table.wast b/test/core/br_table.wast index c8d6082d72..9860892392 100644 --- a/test/core/br_table.wast +++ b/test/core/br_table.wast @@ -989,7 +989,7 @@ (table anyfunc (elem $f)) (func (export "as-call_indirect-first") (result i32) (block (result i32) - (call_indirect $sig + (call_indirect (type $sig) (br_table 0 (i32.const 20) (i32.const 1)) (i32.const 1) (i32.const 2) (i32.const 3) ) @@ -997,7 +997,7 @@ ) (func (export "as-call_indirect-mid") (result i32) (block (result i32) - (call_indirect $sig + (call_indirect (type $sig) (i32.const 0) (br_table 0 (i32.const 21) (i32.const 1)) (i32.const 2) (i32.const 3) ) @@ -1005,7 +1005,7 @@ ) (func (export "as-call_indirect-last") (result i32) (block (result i32) - (call_indirect $sig + (call_indirect (type $sig) (i32.const 0) (i32.const 1) (br_table 0 (i32.const 22) (i32.const 1)) (i32.const 3) ) @@ -1013,7 +1013,7 @@ ) (func (export "as-call_indirect-func") (result i32) (block (result i32) - (call_indirect $sig + (call_indirect (type $sig) (i32.const 0) (i32.const 1) (i32.const 2) (br_table 0 (i32.const 23) (i32.const 1)) ) diff --git a/test/core/call_indirect.wast b/test/core/call_indirect.wast index b9b152e822..db28f391d9 100644 --- a/test/core/call_indirect.wast +++ b/test/core/call_indirect.wast @@ -52,51 +52,87 @@ ) ) + ;; Syntax + + (func + (call_indirect (i32.const 0)) + (call_indirect (param i64) (i64.const 0) (i32.const 0)) + (call_indirect (param i64) (param) (param f64 i32 i64) + (i64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (i32.const 0) + ) + (call_indirect (result) (i32.const 0)) + (drop (i32.eqz (call_indirect (result i32) (i32.const 0)))) + (drop (i32.eqz (call_indirect (result i32) (result) (i32.const 0)))) + (drop (i32.eqz + (call_indirect (param i64) (result i32) (i64.const 0) (i32.const 0)) + )) + (drop (i32.eqz + (call_indirect + (param) (param i64) (param) (param f64 i32 i64) (param) (param) + (result) (result i32) (result) (result) + (i64.const 0) (f64.const 0) (i32.const 0) (i64.const 0) (i32.const 0) + ) + )) + (drop (i64.eqz + (call_indirect (type $over-i64) (param i64) (result i64) + (i64.const 0) (i32.const 0) + ) + )) + ) + ;; Typing - (func (export "type-i32") (result i32) (call_indirect $out-i32 (i32.const 0))) - (func (export "type-i64") (result i64) (call_indirect $out-i64 (i32.const 1))) - (func (export "type-f32") (result f32) (call_indirect $out-f32 (i32.const 2))) - (func (export "type-f64") (result f64) (call_indirect $out-f64 (i32.const 3))) + (func (export "type-i32") (result i32) + (call_indirect (type $out-i32) (i32.const 0)) + ) + (func (export "type-i64") (result i64) + (call_indirect (type $out-i64) (i32.const 1)) + ) + (func (export "type-f32") (result f32) + (call_indirect (type $out-f32) (i32.const 2)) + ) + (func (export "type-f64") (result f64) + (call_indirect (type $out-f64) (i32.const 3)) + ) (func (export "type-index") (result i64) - (call_indirect $over-i64 (i64.const 100) (i32.const 5)) + (call_indirect (type $over-i64) (i64.const 100) (i32.const 5)) ) (func (export "type-first-i32") (result i32) - (call_indirect $over-i32 (i32.const 32) (i32.const 4)) + (call_indirect (type $over-i32) (i32.const 32) (i32.const 4)) ) (func (export "type-first-i64") (result i64) - (call_indirect $over-i64 (i64.const 64) (i32.const 5)) + (call_indirect (type $over-i64) (i64.const 64) (i32.const 5)) ) (func (export "type-first-f32") (result f32) - (call_indirect $over-f32 (f32.const 1.32) (i32.const 6)) + (call_indirect (type $over-f32) (f32.const 1.32) (i32.const 6)) ) (func (export "type-first-f64") (result f64) - (call_indirect $over-f64 (f64.const 1.64) (i32.const 7)) + (call_indirect (type $over-f64) (f64.const 1.64) (i32.const 7)) ) (func (export "type-second-i32") (result i32) - (call_indirect $f32-i32 (f32.const 32.1) (i32.const 32) (i32.const 8)) + (call_indirect (type $f32-i32) (f32.const 32.1) (i32.const 32) (i32.const 8)) ) (func (export "type-second-i64") (result i64) - (call_indirect $i32-i64 (i32.const 32) (i64.const 64) (i32.const 9)) + (call_indirect (type $i32-i64) (i32.const 32) (i64.const 64) (i32.const 9)) ) (func (export "type-second-f32") (result f32) - (call_indirect $f64-f32 (f64.const 64) (f32.const 32) (i32.const 10)) + (call_indirect (type $f64-f32) (f64.const 64) (f32.const 32) (i32.const 10)) ) (func (export "type-second-f64") (result f64) - (call_indirect $i64-f64 (i64.const 64) (f64.const 64.1) (i32.const 11)) + (call_indirect (type $i64-f64) (i64.const 64) (f64.const 64.1) (i32.const 11)) ) ;; Dispatch (func (export "dispatch") (param i32 i64) (result i64) - (call_indirect $over-i64 (get_local 1) (get_local 0)) + (call_indirect (type $over-i64) (get_local 1) (get_local 0)) ) (func (export "dispatch-structural") (param i32) (result i64) - (call_indirect $over-i64-duplicate (i64.const 9) (get_local 0)) + (call_indirect (type $over-i64-duplicate) (i64.const 9) (get_local 0)) ) ;; Recursion @@ -107,7 +143,7 @@ (else (i64.mul (get_local 0) - (call_indirect $over-i64 + (call_indirect (type $over-i64) (i64.sub (get_local 0) (i64.const 1)) (i32.const 12) ) @@ -121,11 +157,11 @@ (then (i64.const 1)) (else (i64.add - (call_indirect $over-i64 + (call_indirect (type $over-i64) (i64.sub (get_local 0) (i64.const 2)) (i32.const 13) ) - (call_indirect $over-i64 + (call_indirect (type $over-i64) (i64.sub (get_local 0) (i64.const 1)) (i32.const 13) ) @@ -138,7 +174,7 @@ (if (result i32) (i32.eqz (get_local 0)) (then (i32.const 44)) (else - (call_indirect $over-i32 + (call_indirect (type $over-i32) (i32.sub (get_local 0) (i32.const 1)) (i32.const 15) ) @@ -149,7 +185,7 @@ (if (result i32) (i32.eqz (get_local 0)) (then (i32.const 99)) (else - (call_indirect $over-i32 + (call_indirect (type $over-i32) (i32.sub (get_local 0) (i32.const 1)) (i32.const 14) ) @@ -166,10 +202,10 @@ ;; implementations and be incompatible with implementations that don't do ;; it (or don't do it under the same circumstances). - (func $runaway (export "runaway") (call_indirect $proc (i32.const 16))) + (func $runaway (export "runaway") (call_indirect (type $proc) (i32.const 16))) - (func $mutual-runaway1 (export "mutual-runaway") (call_indirect $proc (i32.const 18))) - (func $mutual-runaway2 (call_indirect $proc (i32.const 17))) + (func $mutual-runaway1 (export "mutual-runaway") (call_indirect (type $proc) (i32.const 18))) + (func $mutual-runaway2 (call_indirect (type $proc) (i32.const 17))) ) (assert_return (invoke "type-i32") (i32.const 0x132)) @@ -231,12 +267,134 @@ (assert_exhaustion (invoke "mutual-runaway") "call stack exhausted") +;; Invalid syntax + +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (type $sig) (result i32) (param i32)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (param i32) (type $sig) (result i32)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (param i32) (result i32) (type $sig)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (result i32) (type $sig) (param i32)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (result i32) (param i32) (type $sig)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (result i32) (param i32) (i32.const 0) (i32.const 0))" + ")" + ) + "unexpected token" +) + +(assert_malformed + (module quote + "(table 0 anyfunc)" + "(func (call_indirect (param $x i32) (i32.const 0) (i32.const 0)))" + ) + "unexpected token" +) +(assert_malformed + (module quote + "(type $sig (func))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (type $sig) (result i32) (i32.const 0))" + ")" + ) + "inline function type" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (type $sig) (result i32) (i32.const 0))" + ")" + ) + "inline function type" +) +(assert_malformed + (module quote + "(type $sig (func (param i32) (result i32)))" + "(table 0 anyfunc)" + "(func" + " (call_indirect (type $sig) (param i32) (i32.const 0) (i32.const 0))" + ")" + ) + "inline function type" +) +(assert_malformed + (module quote + "(type $sig (func (param i32 i32) (result i32)))" + "(table 0 anyfunc)" + "(func (result i32)" + " (call_indirect (type $sig) (param i32) (result i32)" + " (i32.const 0) (i32.const 0)" + " )" + ")" + ) + "inline function type" +) + ;; Invalid typing (assert_invalid (module (type (func)) - (func $no-table (call_indirect 0 (i32.const 0))) + (func $no-table (call_indirect (type 0) (i32.const 0))) ) "unknown table" ) @@ -245,7 +403,7 @@ (module (type (func)) (table 0 anyfunc) - (func $type-void-vs-num (i32.eqz (call_indirect 0 (i32.const 0)))) + (func $type-void-vs-num (i32.eqz (call_indirect (type 0) (i32.const 0)))) ) "type mismatch" ) @@ -253,7 +411,7 @@ (module (type (func (result i64))) (table 0 anyfunc) - (func $type-num-vs-num (i32.eqz (call_indirect 0 (i32.const 0)))) + (func $type-num-vs-num (i32.eqz (call_indirect (type 0) (i32.const 0)))) ) "type mismatch" ) @@ -262,7 +420,7 @@ (module (type (func (param i32))) (table 0 anyfunc) - (func $arity-0-vs-1 (call_indirect 0 (i32.const 0))) + (func $arity-0-vs-1 (call_indirect (type 0) (i32.const 0))) ) "type mismatch" ) @@ -270,7 +428,7 @@ (module (type (func (param f64 i32))) (table 0 anyfunc) - (func $arity-0-vs-2 (call_indirect 0 (i32.const 0))) + (func $arity-0-vs-2 (call_indirect (type 0) (i32.const 0))) ) "type mismatch" ) @@ -278,7 +436,7 @@ (module (type (func)) (table 0 anyfunc) - (func $arity-1-vs-0 (call_indirect 0 (i32.const 1) (i32.const 0))) + (func $arity-1-vs-0 (call_indirect (type 0) (i32.const 1) (i32.const 0))) ) "type mismatch" ) @@ -287,7 +445,7 @@ (type (func)) (table 0 anyfunc) (func $arity-2-vs-0 - (call_indirect 0 (f64.const 2) (i32.const 1) (i32.const 0)) + (call_indirect (type 0) (f64.const 2) (i32.const 1) (i32.const 0)) ) ) "type mismatch" @@ -297,7 +455,7 @@ (module (type (func (param i32))) (table 0 anyfunc) - (func $type-func-void-vs-i32 (call_indirect 0 (i32.const 1) (nop))) + (func $type-func-void-vs-i32 (call_indirect (type 0) (i32.const 1) (nop))) ) "type mismatch" ) @@ -305,7 +463,7 @@ (module (type (func (param i32))) (table 0 anyfunc) - (func $type-func-num-vs-i32 (call_indirect 0 (i32.const 0) (i64.const 1))) + (func $type-func-num-vs-i32 (call_indirect (type 0) (i32.const 0) (i64.const 1))) ) "type mismatch" ) @@ -315,7 +473,7 @@ (type (func (param i32 i32))) (table 0 anyfunc) (func $type-first-void-vs-num - (call_indirect 0 (nop) (i32.const 1) (i32.const 0)) + (call_indirect (type 0) (nop) (i32.const 1) (i32.const 0)) ) ) "type mismatch" @@ -325,7 +483,7 @@ (type (func (param i32 i32))) (table 0 anyfunc) (func $type-second-void-vs-num - (call_indirect 0 (i32.const 1) (nop) (i32.const 0)) + (call_indirect (type 0) (i32.const 1) (nop) (i32.const 0)) ) ) "type mismatch" @@ -335,7 +493,7 @@ (type (func (param i32 f64))) (table 0 anyfunc) (func $type-first-num-vs-num - (call_indirect 0 (f64.const 1) (i32.const 1) (i32.const 0)) + (call_indirect (type 0) (f64.const 1) (i32.const 1) (i32.const 0)) ) ) "type mismatch" @@ -345,7 +503,7 @@ (type (func (param f64 i32))) (table 0 anyfunc) (func $type-second-num-vs-num - (call_indirect 0 (i32.const 1) (f64.const 1) (i32.const 0)) + (call_indirect (type 0) (i32.const 1) (f64.const 1) (i32.const 0)) ) ) "type mismatch" @@ -357,14 +515,14 @@ (assert_invalid (module (table 0 anyfunc) - (func $unbound-type (call_indirect 1 (i32.const 0))) + (func $unbound-type (call_indirect (type 1) (i32.const 0))) ) "unknown type" ) (assert_invalid (module (table 0 anyfunc) - (func $large-type (call_indirect 1012321300 (i32.const 0))) + (func $large-type (call_indirect (type 1012321300) (i32.const 0))) ) "unknown type" ) diff --git a/test/core/elem.wast b/test/core/elem.wast index c75e07b23e..da28f3f95c 100644 --- a/test/core/elem.wast +++ b/test/core/elem.wast @@ -20,10 +20,10 @@ (func $const-i32-a (type $out-i32) (i32.const 65)) (func $const-i32-b (type $out-i32) (i32.const 66)) (func (export "call-7") (type $out-i32) - (call_indirect $out-i32 (i32.const 7)) + (call_indirect (type $out-i32) (i32.const 7)) ) (func (export "call-9") (type $out-i32) - (call_indirect $out-i32 (i32.const 9)) + (call_indirect (type $out-i32) (i32.const 9)) ) ) @@ -40,7 +40,7 @@ (func $const-i32-a (type $out-i32) (i32.const 65)) (func $const-i32-b (type $out-i32) (i32.const 66)) (func (export "call-overwritten-element") (type $out-i32) - (call_indirect $out-i32 (i32.const 9)) + (call_indirect (type $out-i32) (i32.const 9)) ) ) @@ -108,7 +108,7 @@ (func $const-i32-a (type $out-i32) (i32.const 65)) (func $const-i32-b (type $out-i32) (i32.const 66)) (func (export "call-overwritten-element") (type $out-i32) - (call_indirect $out-i32 (i32.const 9)) + (call_indirect (type $out-i32) (i32.const 9)) ) ) @@ -172,13 +172,13 @@ (func $const-i32-a (type $out-i32) (i32.const 65)) (func $const-i32-b (type $out-i32) (i32.const 66)) (func (export "call-7") (type $out-i32) - (call_indirect $out-i32 (i32.const 7)) + (call_indirect (type $out-i32) (i32.const 7)) ) (func (export "call-8") (type $out-i32) - (call_indirect $out-i32 (i32.const 8)) + (call_indirect (type $out-i32) (i32.const 8)) ) (func (export "call-9") (type $out-i32) - (call_indirect $out-i32 (i32.const 9)) + (call_indirect (type $out-i32) (i32.const 9)) ) ) diff --git a/test/core/func.wast b/test/core/func.wast index c60782f0e1..768a924a20 100644 --- a/test/core/func.wast +++ b/test/core/func.wast @@ -333,24 +333,24 @@ ) (func (export "signature-explicit-reused") - (call_indirect $sig (i32.const 1)) - (call_indirect $sig (i32.const 4)) + (call_indirect (type $sig) (i32.const 1)) + (call_indirect (type $sig) (i32.const 4)) ) (func (export "signature-implicit-reused") ;; The implicit index 3 in this test depends on the function and ;; type definitions, and may need adapting if they change. - (call_indirect 3 + (call_indirect (type 3) (f64.const 0) (i64.const 0) (f64.const 0) (i64.const 0) (f64.const 0) (i64.const 0) (f32.const 0) (i32.const 0) (i32.const 0) ) - (call_indirect 3 + (call_indirect (type 3) (f64.const 0) (i64.const 0) (f64.const 0) (i64.const 0) (f64.const 0) (i64.const 0) (f32.const 0) (i32.const 0) (i32.const 2) ) - (call_indirect 3 + (call_indirect (type 3) (f64.const 0) (i64.const 0) (f64.const 0) (i64.const 0) (f64.const 0) (i64.const 0) (f32.const 0) (i32.const 0) (i32.const 3) @@ -358,16 +358,16 @@ ) (func (export "signature-explicit-duplicate") - (call_indirect $empty-sig-duplicate (i32.const 1)) + (call_indirect (type $empty-sig-duplicate) (i32.const 1)) ) (func (export "signature-implicit-duplicate") - (call_indirect $complex-sig-duplicate + (call_indirect (type $complex-sig-duplicate) (i64.const 0) (i64.const 0) (f64.const 0) (i64.const 0) (f64.const 0) (i64.const 0) (f32.const 0) (i32.const 0) (i32.const 5) ) - (call_indirect $complex-sig-duplicate + (call_indirect (type $complex-sig-duplicate) (i64.const 0) (i64.const 0) (f64.const 0) (i64.const 0) (f64.const 0) (i64.const 0) (f32.const 0) (i32.const 0) (i32.const 6) diff --git a/test/core/func_ptrs.wast b/test/core/func_ptrs.wast index ef54c5da0b..b8050a8339 100644 --- a/test/core/func_ptrs.wast +++ b/test/core/func_ptrs.wast @@ -60,11 +60,11 @@ (func $u2 (type $U) (i32.const 5)) (func (export "callt") (param $i i32) (result i32) - (call_indirect $T (get_local $i)) + (call_indirect (type $T) (get_local $i)) ) (func (export "callu") (param $i i32) (result i32) - (call_indirect $U (get_local $i)) + (call_indirect (type $U) (get_local $i)) ) ) @@ -98,7 +98,7 @@ (func $t2 (type $T) (i32.const 2)) (func (export "callt") (param $i i32) (result i32) - (call_indirect $T (get_local $i)) + (call_indirect (type $T) (get_local $i)) ) ) diff --git a/test/core/imports.wast b/test/core/imports.wast index e9a28dcdcc..f5a557dbcc 100644 --- a/test/core/imports.wast +++ b/test/core/imports.wast @@ -64,7 +64,7 @@ (call $print_i32 (get_local $i)) (call $print_i32-2 (get_local $i)) (call $print_f32 (get_local $x)) - (call_indirect $func_i32 (get_local $i) (i32.const 0)) + (call_indirect (type $func_i32) (get_local $i) (i32.const 0)) ) (func (export "print64") (param $i i64) @@ -80,7 +80,7 @@ ;; (call $print_i64 (get_local $i)) (call $print_f64 (get_local $x)) (call $print_f64-2 (get_local $x)) - (call_indirect $func_f64 (get_local $x) (i32.const 1)) + (call_indirect (type $func_f64) (get_local $x) (i32.const 1)) ) ) @@ -265,7 +265,9 @@ (import "spectest" "table" (table 10 20 anyfunc)) (elem 0 (i32.const 1) $f $g) - (func (export "call") (param i32) (result i32) (call_indirect 0 (get_local 0))) + (func (export "call") (param i32) (result i32) + (call_indirect (type 0) (get_local 0)) + ) (func $f (result i32) (i32.const 11)) (func $g (result i32) (i32.const 22)) ) @@ -282,7 +284,9 @@ (table (import "spectest" "table") 10 20 anyfunc) (elem 0 (i32.const 1) $f $g) - (func (export "call") (param i32) (result i32) (call_indirect 0 (get_local 0))) + (func (export "call") (param i32) (result i32) + (call_indirect (type 0) (get_local 0)) + ) (func $f (result i32) (i32.const 11)) (func $g (result i32) (i32.const 22)) ) diff --git a/test/core/left-to-right.wast b/test/core/left-to-right.wast index 6214d0d5ba..65d3809ac2 100644 --- a/test/core/left-to-right.wast +++ b/test/core/left-to-right.wast @@ -88,7 +88,7 @@ (func (export "i32_store8") (result i32) (call $reset) (i32.store8 (call $i32_left) (call $i32_right)) (call $get)) (func (export "i32_store16") (result i32) (call $reset) (i32.store16 (call $i32_left) (call $i32_right)) (call $get)) (func (export "i32_call") (result i32) (call $reset) (call $i32_dummy (call $i32_left) (call $i32_right)) (call $get)) - (func (export "i32_call_indirect") (result i32) (call $reset) (drop (call_indirect $i32_T (call $i32_left) (call $i32_right) (call $i32_callee))) (call $get)) + (func (export "i32_call_indirect") (result i32) (call $reset) (drop (call_indirect (type $i32_T) (call $i32_left) (call $i32_right) (call $i32_callee))) (call $get)) (func (export "i32_select") (result i32) (call $reset) (drop (select (call $i32_left) (call $i32_right) (call $i32_bool))) (call $get)) (func (export "i64_add") (result i32) (call $reset) (drop (i64.add (call $i64_left) (call $i64_right))) (call $get)) @@ -119,7 +119,7 @@ (func (export "i64_store16") (result i32) (call $reset) (i64.store16 (call $i32_left) (call $i64_right)) (call $get)) (func (export "i64_store32") (result i32) (call $reset) (i64.store32 (call $i32_left) (call $i64_right)) (call $get)) (func (export "i64_call") (result i32) (call $reset) (call $i64_dummy (call $i64_left) (call $i64_right)) (call $get)) - (func (export "i64_call_indirect") (result i32) (call $reset) (drop (call_indirect $i64_T (call $i64_left) (call $i64_right) (call $i64_callee))) (call $get)) + (func (export "i64_call_indirect") (result i32) (call $reset) (drop (call_indirect (type $i64_T) (call $i64_left) (call $i64_right) (call $i64_callee))) (call $get)) (func (export "i64_select") (result i32) (call $reset) (drop (select (call $i64_left) (call $i64_right) (call $i64_bool))) (call $get)) (func (export "f32_add") (result i32) (call $reset) (drop (f32.add (call $f32_left) (call $f32_right))) (call $get)) @@ -137,7 +137,7 @@ (func (export "f32_max") (result i32) (call $reset) (drop (f32.max (call $f32_left) (call $f32_right))) (call $get)) (func (export "f32_store") (result i32) (call $reset) (f32.store (call $i32_left) (call $f32_right)) (call $get)) (func (export "f32_call") (result i32) (call $reset) (call $f32_dummy (call $f32_left) (call $f32_right)) (call $get)) - (func (export "f32_call_indirect") (result i32) (call $reset) (drop (call_indirect $f32_T (call $f32_left) (call $f32_right) (call $f32_callee))) (call $get)) + (func (export "f32_call_indirect") (result i32) (call $reset) (drop (call_indirect (type $f32_T) (call $f32_left) (call $f32_right) (call $f32_callee))) (call $get)) (func (export "f32_select") (result i32) (call $reset) (drop (select (call $f32_left) (call $f32_right) (call $f32_bool))) (call $get)) (func (export "f64_add") (result i32) (call $reset) (drop (f64.add (call $f64_left) (call $f64_right))) (call $get)) @@ -155,7 +155,7 @@ (func (export "f64_max") (result i32) (call $reset) (drop (f64.max (call $f64_left) (call $f64_right))) (call $get)) (func (export "f64_store") (result i32) (call $reset) (f64.store (call $i32_left) (call $f64_right)) (call $get)) (func (export "f64_call") (result i32) (call $reset) (call $f64_dummy (call $f64_left) (call $f64_right)) (call $get)) - (func (export "f64_call_indirect") (result i32) (call $reset) (drop (call_indirect $f64_T (call $f64_left) (call $f64_right) (call $f64_callee))) (call $get)) + (func (export "f64_call_indirect") (result i32) (call $reset) (drop (call_indirect (type $f64_T) (call $f64_left) (call $f64_right) (call $f64_callee))) (call $get)) (func (export "f64_select") (result i32) (call $reset) (drop (select (call $f64_left) (call $f64_right) (call $f64_bool))) (call $get)) (func (export "br_if") (result i32) diff --git a/test/core/linking.wast b/test/core/linking.wast index b2f0dd3db1..73fbb93ba1 100644 --- a/test/core/linking.wast +++ b/test/core/linking.wast @@ -71,7 +71,7 @@ (func (export "h") (result i32) (i32.const -4)) (func (export "call") (param i32) (result i32) - (call_indirect 0 (get_local 0)) + (call_indirect (type 0) (get_local 0)) ) ) (register "Mt" $Mt) @@ -91,7 +91,7 @@ (call $f (get_local 0)) ) (func (export "call") (param i32) (result i32) - (call_indirect 1 (get_local 0)) + (call_indirect (type 1) (get_local 0)) ) ) @@ -127,7 +127,7 @@ (func $i (result i32) (i32.const 6)) (func (export "call") (param i32) (result i32) - (call_indirect 0 (get_local 0)) + (call_indirect (type 0) (get_local 0)) ) ) diff --git a/test/core/return.wast b/test/core/return.wast index 48964cffc2..d483b5e511 100644 --- a/test/core/return.wast +++ b/test/core/return.wast @@ -124,16 +124,24 @@ (type $sig (func (param i32 i32 i32) (result i32))) (table anyfunc (elem $f)) (func (export "as-call_indirect-func") (result i32) - (call_indirect $sig (return (i32.const 20)) (i32.const 1) (i32.const 2) (i32.const 3)) + (call_indirect (type $sig) + (return (i32.const 20)) (i32.const 1) (i32.const 2) (i32.const 3) + ) ) (func (export "as-call_indirect-first") (result i32) - (call_indirect $sig (i32.const 0) (return (i32.const 21)) (i32.const 2) (i32.const 3)) + (call_indirect (type $sig) + (i32.const 0) (return (i32.const 21)) (i32.const 2) (i32.const 3) + ) ) (func (export "as-call_indirect-mid") (result i32) - (call_indirect $sig (i32.const 0) (i32.const 1) (return (i32.const 22)) (i32.const 3)) + (call_indirect (type $sig) + (i32.const 0) (i32.const 1) (return (i32.const 22)) (i32.const 3) + ) ) (func (export "as-call_indirect-last") (result i32) - (call_indirect $sig (i32.const 0) (i32.const 1) (i32.const 2) (return (i32.const 23))) + (call_indirect (type $sig) + (i32.const 0) (i32.const 1) (i32.const 2) (return (i32.const 23)) + ) ) (func (export "as-set_local-value") (result i32) (local f32) diff --git a/test/core/typecheck.wast b/test/core/typecheck.wast index 72f6f621f1..b322b526fd 100644 --- a/test/core/typecheck.wast +++ b/test/core/typecheck.wast @@ -234,7 +234,7 @@ (func (type 0)) (table 0 anyfunc) (func - (call_indirect 0 (i32.const 0) (f32.const 0)))) + (call_indirect (type 0) (i32.const 0) (f32.const 0)))) "type mismatch") ;; call_indirect index @@ -243,7 +243,7 @@ (type (func)) (func (type 0)) (table 0 anyfunc) - (func (call_indirect 0 (f32.const 0)))) + (func (call_indirect (type 0) (f32.const 0)))) "type mismatch") ;; return diff --git a/test/core/unreachable.wast b/test/core/unreachable.wast index 30df789e21..f7fe4030f4 100644 --- a/test/core/unreachable.wast +++ b/test/core/unreachable.wast @@ -131,16 +131,24 @@ (type $sig (func (param i32 i32 i32))) (table anyfunc (elem $dummy3)) (func (export "as-call_indirect-func") - (call_indirect $sig (unreachable) (i32.const 1) (i32.const 2) (i32.const 3)) + (call_indirect (type $sig) + (unreachable) (i32.const 1) (i32.const 2) (i32.const 3) + ) ) (func (export "as-call_indirect-first") - (call_indirect $sig (i32.const 0) (unreachable) (i32.const 2) (i32.const 3)) + (call_indirect (type $sig) + (i32.const 0) (unreachable) (i32.const 2) (i32.const 3) + ) ) (func (export "as-call_indirect-mid") - (call_indirect $sig (i32.const 0) (i32.const 1) (unreachable) (i32.const 3)) + (call_indirect (type $sig) + (i32.const 0) (i32.const 1) (unreachable) (i32.const 3) + ) ) (func (export "as-call_indirect-last") - (call_indirect $sig (i32.const 0) (i32.const 1) (i32.const 2) (unreachable)) + (call_indirect (type $sig) + (i32.const 0) (i32.const 1) (i32.const 2) (unreachable) + ) ) (func (export "as-set_local-value") (local f32) From 3bc027c121cc89b1f574dd31352e879a0072be6f Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Thu, 9 Nov 2017 18:43:24 +0100 Subject: [PATCH 2/2] Tweak source position --- interpreter/text/parser.mly | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interpreter/text/parser.mly b/interpreter/text/parser.mly index 71f9af1d8d..b7c65a3d17 100644 --- a/interpreter/text/parser.mly +++ b/interpreter/text/parser.mly @@ -294,7 +294,7 @@ align_opt : instr : | plain_instr { let at = at () in fun c -> [$1 c @@ at] } - | call_instr { let at = at () in fun c -> let e, es = $1 c in (e @@ at) :: es } + | call_instr { fun c -> let e, es = $1 c in e :: es } | block_instr { let at = at () in fun c -> [$1 c @@ at] } | expr { $1 } /* Sugar */ @@ -328,7 +328,8 @@ plain_instr : call_instr : | CALL_INDIRECT call_instr_sig - { fun c -> let x, es = $2 c in call_indirect x, es } + { let at1 = ati 1 in + fun c -> let x, es = $2 c in call_indirect x @@ at1, es } call_instr_sig : | type_use call_instr_params