diff --git a/interpreter/binary/decode.ml b/interpreter/binary/decode.ml index ca2ded7f4..eb8730dbe 100644 --- a/interpreter/binary/decode.ml +++ b/interpreter/binary/decode.ml @@ -62,6 +62,8 @@ let at f s = (* Generic values *) +let bit i n = n land (1 lsl i) <> 0 + let byte s = get s @@ -588,37 +590,40 @@ let rec instr s = | 0xfb as b -> (match u32 s with - | 0x01l -> struct_new_canon (at var s) - | 0x02l -> struct_new_canon_default (at var s) + | 0x01l -> struct_new (at var s) + | 0x02l -> struct_new_default (at var s) | 0x03l -> let x = at var s in let y = at var s in struct_get x y | 0x04l -> let x = at var s in let y = at var s in struct_get_s x y | 0x05l -> let x = at var s in let y = at var s in struct_get_u x y | 0x06l -> let x = at var s in let y = at var s in struct_set x y - | 0x11l -> array_new_canon (at var s) - | 0x12l -> array_new_canon_default (at var s) + | 0x11l -> array_new (at var s) + | 0x12l -> array_new_default (at var s) | 0x13l -> array_get (at var s) | 0x14l -> array_get_s (at var s) | 0x15l -> array_get_u (at var s) | 0x16l -> array_set (at var s) | 0x17l -> array_len - | 0x19l -> let x = at var s in let n = u32 s in array_new_canon_fixed x n - | 0x1bl -> let x = at var s in let y = at var s in array_new_canon_data x y - | 0x1cl -> let x = at var s in let y = at var s in array_new_canon_elem x y + | 0x19l -> let x = at var s in let n = u32 s in array_new_fixed x n + | 0x1bl -> let x = at var s in let y = at var s in array_new_data x y + | 0x1cl -> let x = at var s in let y = at var s in array_new_elem x y | 0x20l -> i31_new | 0x21l -> i31_get_s | 0x22l -> i31_get_u - | 0x40l -> ref_test (heap_type s) - | 0x41l -> ref_cast (heap_type s) - | 0x42l -> let x = at var s in br_on_cast x (heap_type s) - | 0x43l -> let x = at var s in br_on_cast_fail x (heap_type s) - | 0x48l -> ref_test_null (heap_type s) - | 0x49l -> ref_cast_null (heap_type s) - | 0x4al -> let x = at var s in br_on_cast_null x (heap_type s) - | 0x4bl -> let x = at var s in br_on_cast_fail_null x (heap_type s) + | 0x40l -> ref_test (NoNull, heap_type s) + | 0x41l -> ref_cast (NoNull, heap_type s) + | 0x48l -> ref_test (Null, heap_type s) + | 0x49l -> ref_cast (Null, heap_type s) + | 0x4el | 0x4fl as opcode -> + let flags = byte s in + require (flags land 0xfc = 0) s (pos + 2) "malformed br_on_cast flags"; + let x = at var s in + let rt1 = ((if bit 0 flags then Null else NoNull), heap_type s) in + let rt2 = ((if bit 1 flags then Null else NoNull), heap_type s) in + (if opcode = 0x4el then br_on_cast else br_on_cast_fail) x rt1 rt2 | 0x70l -> extern_internalize | 0x71l -> extern_externalize diff --git a/interpreter/binary/encode.ml b/interpreter/binary/encode.ml index 74df856b4..5fe4359e9 100644 --- a/interpreter/binary/encode.ml +++ b/interpreter/binary/encode.ml @@ -40,6 +40,8 @@ struct (* Generic values *) + let bit i b = (if b then 1 else 0) lsl i + let byte i = put s (Char.chr (i land 0xff)) let word16 i = byte (i land 0xff); byte (i lsr 8) let word32 i = @@ -241,10 +243,12 @@ struct | BrTable (xs, x) -> op 0x0e; vec var xs; var x | BrOnNull x -> op 0xd4; var x | BrOnNonNull x -> op 0xd6; var x - | BrOnCast (x, (NoNull, t)) -> op 0xfb; op 0x42; var x; heap_type t - | BrOnCast (x, (Null, t)) -> op 0xfb; op 0x4a; var x; heap_type t - | BrOnCastFail (x, (NoNull, t)) -> op 0xfb; op 0x43; var x; heap_type t - | BrOnCastFail (x, (Null, t)) -> op 0xfb; op 0x4b; var x; heap_type t + | BrOnCast (x, (nul1, t1), (nul2, t2)) -> + let flags = bit 0 (nul1 = Null) + bit 1 (nul2 = Null) in + op 0xfb; op 0x4e; byte flags; var x; heap_type t1; heap_type t2 + | BrOnCastFail (x, (nul1, t1), (nul2, t2)) -> + let flags = bit 0 (nul1 = Null) + bit 1 (nul2 = Null) in + op 0xfb; op 0x4f; byte flags; var x; heap_type t1; heap_type t2 | Return -> op 0x0f | Call x -> op 0x10; var x | CallRef x -> op 0x14; var x diff --git a/interpreter/exec/eval.ml b/interpreter/exec/eval.ml index 14551f1f9..56fc34e1b 100644 --- a/interpreter/exec/eval.ml +++ b/interpreter/exec/eval.ml @@ -215,16 +215,16 @@ let rec step (c : config) : config = | BrOnNonNull x, Ref r :: vs' -> Ref r :: vs', [Plain (Br x) @@ e.at] - | BrOnCast (x, rt), Ref r :: vs' -> - let rt' = dyn_ref_type c.frame.inst.types rt in - if Match.match_ref_type [] (type_of_ref r) rt' then + | BrOnCast (x, _rt1, rt2), Ref r :: vs' -> + let rt2' = dyn_ref_type c.frame.inst.types rt2 in + if Match.match_ref_type [] (type_of_ref r) rt2' then Ref r :: vs', [Plain (Br x) @@ e.at] else Ref r :: vs', [] - | BrOnCastFail (x, rt), Ref r :: vs' -> - let rt' = dyn_ref_type c.frame.inst.types rt in - if Match.match_ref_type [] (type_of_ref r) rt' then + | BrOnCastFail (x, _rt1, rt2), Ref r :: vs' -> + let rt2' = dyn_ref_type c.frame.inst.types rt2 in + if Match.match_ref_type [] (type_of_ref r) rt2' then Ref r :: vs', [] else Ref r :: vs', [Plain (Br x) @@ e.at] diff --git a/interpreter/syntax/ast.ml b/interpreter/syntax/ast.ml index d9a71ba10..04ef120fd 100644 --- a/interpreter/syntax/ast.ml +++ b/interpreter/syntax/ast.ml @@ -154,8 +154,8 @@ and instr' = | BrTable of idx list * idx (* indexed break *) | BrOnNull of idx (* break on type *) | BrOnNonNull of idx (* break on type inverted *) - | BrOnCast of idx * ref_type (* break on type *) - | BrOnCastFail of idx * ref_type (* break on type inverted *) + | BrOnCast of idx * ref_type * ref_type (* break on type *) + | BrOnCastFail of idx * ref_type * ref_type (* break on type inverted *) | Return (* break from function body *) | Call of idx (* call function *) | CallRef of idx (* call function through reference *) diff --git a/interpreter/syntax/free.ml b/interpreter/syntax/free.ml index 3ed781eb6..fdf4b989f 100644 --- a/interpreter/syntax/free.ml +++ b/interpreter/syntax/free.ml @@ -141,7 +141,8 @@ let rec instr (e : instr) = | Block (bt, es) | Loop (bt, es) -> block_type bt ++ block es | If (bt, es1, es2) -> block_type bt ++ block es1 ++ block es2 | Br x | BrIf x | BrOnNull x | BrOnNonNull x -> labels (idx x) - | BrOnCast (x, t) | BrOnCastFail (x, t) -> labels (idx x) ++ ref_type t + | BrOnCast (x, t1, t2) | BrOnCastFail (x, t1, t2) -> + labels (idx x) ++ ref_type t1 ++ ref_type t2 | BrTable (xs, x) -> list (fun x -> labels (idx x)) (x::xs) | Return -> empty | Call x | ReturnCall x -> funcs (idx x) diff --git a/interpreter/syntax/operators.ml b/interpreter/syntax/operators.ml index ce0d26ee3..fdad83b7f 100644 --- a/interpreter/syntax/operators.ml +++ b/interpreter/syntax/operators.ml @@ -29,10 +29,8 @@ let br_if x = BrIf x let br_table xs x = BrTable (xs, x) let br_on_null x = BrOnNull x let br_on_non_null x = BrOnNonNull x -let br_on_cast x t = BrOnCast (x, (NoNull, t)) -let br_on_cast_null x t = BrOnCast (x, (Null, t)) -let br_on_cast_fail x t = BrOnCastFail (x, (NoNull, t)) -let br_on_cast_fail_null x t = BrOnCastFail (x, (Null, t)) +let br_on_cast x t1 t2 = BrOnCast (x, t1, t2) +let br_on_cast_fail x t1 t2 = BrOnCastFail (x, t1, t2) let return = Return let call x = Call x @@ -106,26 +104,24 @@ let data_drop x = DataDrop x let ref_is_null = RefIsNull let ref_as_non_null = RefAsNonNull -let ref_test t = RefTest (NoNull, t) -let ref_test_null t = RefTest (Null, t) -let ref_cast t = RefCast (NoNull, t) -let ref_cast_null t = RefCast (Null, t) +let ref_test t = RefTest t +let ref_cast t = RefCast t let ref_eq = RefEq let i31_new = I31New let i31_get_u = I31Get ZX let i31_get_s = I31Get SX -let struct_new_canon x = StructNew (x, Explicit) -let struct_new_canon_default x = StructNew (x, Implicit) +let struct_new x = StructNew (x, Explicit) +let struct_new_default x = StructNew (x, Implicit) let struct_get x y = StructGet (x, y, None) let struct_get_u x y = StructGet (x, y, Some ZX) let struct_get_s x y = StructGet (x, y, Some SX) let struct_set x y = StructSet (x, y) -let array_new_canon x = ArrayNew (x, Explicit) -let array_new_canon_default x = ArrayNew (x, Implicit) -let array_new_canon_fixed x n = ArrayNewFixed (x, n) -let array_new_canon_elem x y = ArrayNewElem (x, y) -let array_new_canon_data x y = ArrayNewData (x, y) +let array_new x = ArrayNew (x, Explicit) +let array_new_default x = ArrayNew (x, Implicit) +let array_new_fixed x n = ArrayNewFixed (x, n) +let array_new_elem x y = ArrayNewElem (x, y) +let array_new_data x y = ArrayNewData (x, y) let array_get x = ArrayGet (x, None) let array_get_u x = ArrayGet (x, Some ZX) let array_get_s x = ArrayGet (x, Some SX) diff --git a/interpreter/text/arrange.ml b/interpreter/text/arrange.ml index b578acc3e..5d9bbc2f1 100644 --- a/interpreter/text/arrange.ml +++ b/interpreter/text/arrange.ml @@ -82,17 +82,10 @@ let var_type = function | DynX _ -> assert false | RecX x -> "rec." ^ nat32 x -let null = function - | NoNull -> "" - | Null -> "null " - let final = function | NoFinal -> "" | Final -> " final" -let ref_type_raw (nul, t) = - Atom (null nul ^ heap_type t) - let decls kind ts = tab kind (atom val_type) ts let field_type (FieldT (mut, t)) = @@ -512,8 +505,10 @@ let rec instr e = "br_table " ^ String.concat " " (list var (xs @ [x])), [] | BrOnNull x -> "br_on_null " ^ var x, [] | BrOnNonNull x -> "br_on_non_null " ^ var x, [] - | BrOnCast (x, t) -> "br_on_cast " ^ var x, [ref_type_raw t] - | BrOnCastFail (x, t) -> "br_on_cast_fail " ^ var x, [ref_type_raw t] + | BrOnCast (x, t1, t2) -> + "br_on_cast " ^ var x, [Atom (ref_type t1); Atom (ref_type t2)] + | BrOnCastFail (x, t1, t2) -> + "br_on_cast_fail " ^ var x, [Atom (ref_type t1); Atom (ref_type t2)] | Return -> "return", [] | Call x -> "call " ^ var x, [] | CallRef x -> "call_ref " ^ var x, [] @@ -552,19 +547,19 @@ let rec instr e = | RefFunc x -> "ref.func " ^ var x, [] | RefIsNull -> "ref.is_null", [] | RefAsNonNull -> "ref.as_non_null", [] - | RefTest t -> "ref.test", [ref_type_raw t] - | RefCast t -> "ref.cast", [ref_type_raw t] + | RefTest t -> "ref.test", [Atom (ref_type t)] + | RefCast t -> "ref.cast", [Atom (ref_type t)] | RefEq -> "ref.eq", [] | I31New -> "i31.new", [] | I31Get ext -> "i31.get" ^ extension ext, [] - | StructNew (x, op) -> "struct.new_canon" ^ initop op ^ " " ^ var x, [] + | StructNew (x, op) -> "struct.new" ^ initop op ^ " " ^ var x, [] | StructGet (x, y, exto) -> "struct.get" ^ opt_s extension exto ^ " " ^ var x ^ " " ^ var y, [] | StructSet (x, y) -> "struct.set " ^ var x ^ " " ^ var y, [] - | ArrayNew (x, op) -> "array.new_canon" ^ initop op ^ " " ^ var x, [] - | ArrayNewFixed (x, n) -> "array.new_canon_fixed " ^ var x ^ " " ^ nat32 n, [] - | ArrayNewElem (x, y) -> "array.new_canon_elem " ^ var x ^ " " ^ var y, [] - | ArrayNewData (x, y) -> "array.new_canon_data " ^ var x ^ " " ^ var y, [] + | ArrayNew (x, op) -> "array.new" ^ initop op ^ " " ^ var x, [] + | ArrayNewFixed (x, n) -> "array.new_fixed " ^ var x ^ " " ^ nat32 n, [] + | ArrayNewElem (x, y) -> "array.new_elem " ^ var x ^ " " ^ var y, [] + | ArrayNewData (x, y) -> "array.new_data " ^ var x ^ " " ^ var y, [] | ArrayGet (x, exto) -> "array.get" ^ opt_s extension exto ^ " " ^ var x, [] | ArraySet x -> "array.set " ^ var x, [] | ArrayLen -> "array.len", [] diff --git a/interpreter/text/lexer.mll b/interpreter/text/lexer.mll index 97715d492..7d7f88edb 100644 --- a/interpreter/text/lexer.mll +++ b/interpreter/text/lexer.mll @@ -187,10 +187,10 @@ rule token = parse | "br" -> BR | "br_if" -> BR_IF | "br_table" -> BR_TABLE - | "br_on_null" -> BR_ON_NULL - | "br_on_non_null" -> BR_ON_NON_NULL - | "br_on_cast" -> BR_ON_CAST (br_on_cast, br_on_cast_null) - | "br_on_cast_fail" -> BR_ON_CAST_FAIL (br_on_cast_fail, br_on_cast_fail_null) + | "br_on_null" -> BR_ON_NULL br_on_null + | "br_on_non_null" -> BR_ON_NULL br_on_non_null + | "br_on_cast" -> BR_ON_CAST br_on_cast + | "br_on_cast_fail" -> BR_ON_CAST br_on_cast_fail | "return" -> RETURN | "if" -> IF | "then" -> THEN @@ -316,26 +316,26 @@ rule token = parse | "ref.is_null" -> REF_IS_NULL | "ref.as_non_null" -> REF_AS_NON_NULL - | "ref.test" -> REF_TEST (ref_test, ref_test_null) - | "ref.cast" -> REF_CAST (ref_cast, ref_cast_null) + | "ref.test" -> REF_TEST + | "ref.cast" -> REF_CAST | "ref.eq" -> REF_EQ | "i31.new" -> I31_NEW | "i31.get_u" -> I31_GET i31_get_u | "i31.get_s" -> I31_GET i31_get_s - | "struct.new_canon" -> STRUCT_NEW struct_new_canon - | "struct.new_canon_default" -> STRUCT_NEW struct_new_canon_default + | "struct.new" -> STRUCT_NEW struct_new + | "struct.new_default" -> STRUCT_NEW struct_new_default | "struct.get" -> STRUCT_GET struct_get | "struct.get_u" -> STRUCT_GET struct_get_u | "struct.get_s" -> STRUCT_GET struct_get_s | "struct.set" -> STRUCT_SET - | "array.new_canon" -> ARRAY_NEW array_new_canon - | "array.new_canon_default" -> ARRAY_NEW array_new_canon_default - | "array.new_canon_fixed" -> ARRAY_NEW_FIXED - | "array.new_canon_elem" -> ARRAY_NEW_ELEM - | "array.new_canon_data" -> ARRAY_NEW_DATA + | "array.new" -> ARRAY_NEW array_new + | "array.new_default" -> ARRAY_NEW array_new_default + | "array.new_fixed" -> ARRAY_NEW_FIXED + | "array.new_elem" -> ARRAY_NEW_ELEM + | "array.new_data" -> ARRAY_NEW_DATA | "array.get" -> ARRAY_GET array_get | "array.get_u" -> ARRAY_GET array_get_u | "array.get_s" -> ARRAY_GET array_get_s diff --git a/interpreter/text/parser.mly b/interpreter/text/parser.mly index 4d1191549..93102e3fd 100644 --- a/interpreter/text/parser.mly +++ b/interpreter/text/parser.mly @@ -254,8 +254,9 @@ let inline_func_type_explicit (c : context) x ft at = %token MUT FIELD STRUCT ARRAY SUB FINAL REC %token UNREACHABLE NOP DROP SELECT %token BLOCK END IF THEN ELSE LOOP -%token BR BR_IF BR_TABLE BR_ON_NULL BR_ON_NON_NULL -%token<(Ast.idx -> Types.heap_type -> Ast.instr') * (Ast.idx -> Types.heap_type -> Ast.instr')> BR_ON_CAST BR_ON_CAST_FAIL +%token BR BR_IF BR_TABLE +%token Ast.instr'> BR_ON_NULL +%token Types.ref_type -> Types.ref_type -> Ast.instr'> BR_ON_CAST %token CALL CALL_REF CALL_INDIRECT %token RETURN RETURN_CALL RETURN_CALL_REF RETURN_CALL_INDIRECT %token LOCAL_GET LOCAL_SET LOCAL_TEE GLOBAL_GET GLOBAL_SET @@ -267,8 +268,7 @@ let inline_func_type_explicit (c : context) x ft at = %token Ast.instr' * Value.num> CONST %token UNARY BINARY TEST COMPARE CONVERT %token REF_NULL REF_FUNC REF_I31 REF_STRUCT REF_ARRAY REF_EXTERN REF_HOST -%token REF_EQ REF_IS_NULL REF_AS_NON_NULL -%token<(Types.heap_type -> Ast.instr') * (Types.heap_type -> Ast.instr')> REF_TEST REF_CAST +%token REF_EQ REF_IS_NULL REF_AS_NON_NULL REF_TEST REF_CAST %token I31_NEW %token I31_GET %token Ast.instr'> STRUCT_NEW ARRAY_NEW ARRAY_GET @@ -506,12 +506,8 @@ plain_instr : | BR_TABLE var var_list { fun c -> let xs, x = Lib.List.split_last ($2 c label :: $3 c label) in br_table xs x } - | BR_ON_NULL var { fun c -> br_on_null ($2 c label) } - | BR_ON_NON_NULL var { fun c -> br_on_non_null ($2 c label) } - | BR_ON_CAST var heap_type { fun c -> fst $1 ($2 c label) ($3 c) } - | BR_ON_CAST var NULL heap_type { fun c -> snd $1 ($2 c label) ($4 c) } - | BR_ON_CAST_FAIL var heap_type { fun c -> fst $1 ($2 c label) ($3 c) } - | BR_ON_CAST_FAIL var NULL heap_type { fun c -> snd $1 ($2 c label) ($4 c) } + | BR_ON_NULL var { fun c -> $1 ($2 c label) } + | BR_ON_CAST var ref_type ref_type { fun c -> $1 ($2 c label) ($3 c) ($4 c) } | RETURN { fun c -> return } | CALL var { fun c -> call ($2 c func) } | CALL_REF var { fun c -> call_ref ($2 c type_) } @@ -557,10 +553,8 @@ plain_instr : | REF_FUNC var { fun c -> ref_func ($2 c func) } | REF_IS_NULL { fun c -> ref_is_null } | REF_AS_NON_NULL { fun c -> ref_as_non_null } - | REF_TEST heap_type { fun c -> fst $1 ($2 c) } - | REF_CAST heap_type { fun c -> fst $1 ($2 c) } - | REF_TEST NULL heap_type { fun c -> snd $1 ($3 c) } - | REF_CAST NULL heap_type { fun c -> snd $1 ($3 c) } + | REF_TEST ref_type { fun c -> ref_test ($2 c) } + | REF_CAST ref_type { fun c -> ref_cast ($2 c) } | REF_EQ { fun c -> ref_eq } | I31_NEW { fun c -> i31_new } | I31_GET { fun c -> $1 } @@ -568,9 +562,9 @@ plain_instr : | STRUCT_GET var var { fun c -> $1 ($2 c type_) ($3 c field) } | STRUCT_SET var var { fun c -> struct_set ($2 c type_) ($3 c field) } | ARRAY_NEW var { fun c -> $1 ($2 c type_) } - | ARRAY_NEW_FIXED var nat32 { fun c -> array_new_canon_fixed ($2 c type_) $3 } - | ARRAY_NEW_ELEM var var { fun c -> array_new_canon_elem ($2 c type_) ($3 c elem) } - | ARRAY_NEW_DATA var var { fun c -> array_new_canon_data ($2 c type_) ($3 c data) } + | ARRAY_NEW_FIXED var nat32 { fun c -> array_new_fixed ($2 c type_) $3 } + | ARRAY_NEW_ELEM var var { fun c -> array_new_elem ($2 c type_) ($3 c elem) } + | ARRAY_NEW_DATA var var { fun c -> array_new_data ($2 c type_) ($3 c data) } | ARRAY_GET var { fun c -> $1 ($2 c type_) } | ARRAY_SET var { fun c -> array_set ($2 c type_) } | ARRAY_LEN { fun c -> array_len } diff --git a/interpreter/valid/valid.ml b/interpreter/valid/valid.ml index 915e07d31..e4aed7084 100644 --- a/interpreter/valid/valid.ml +++ b/interpreter/valid/valid.ml @@ -195,6 +195,11 @@ let check_type (c : context) (t : type_) : context = check_def_type c t.it t.at +let diff_ref_type (nul1, ht1) (nul2, ht2) = + match nul2 with + | Null -> (NoNull, ht1) + | NoNull -> (nul1, ht1) + (* Stack typing *) @@ -444,41 +449,38 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : infer_in " but label has " ^ string_of_result_type (label c x)); (ts0 @ [RefT (Null, ht)]) --> ts0, [] - | BrOnCast (x, rt) -> - let (_nul, ht) = rt in - let rt' = peek_ref 0 s e.at in - let tht = top_of_heap_type c.types ht in + | BrOnCast (x, rt1, rt2) -> + check_ref_type c rt1 e.at; + check_ref_type c rt2 e.at; require - (match_ref_type c.types rt' (Null, tht)) e.at - ("type mismatch: instruction requires type " ^ - string_of_ref_type (Null, tht) ^ - " but stack has " ^ string_of_ref_type rt'); + (match_ref_type c.types rt2 rt1) e.at + ("type mismatch on cast: type " ^ string_of_ref_type rt2 ^ + " does not match " ^ string_of_ref_type rt1); require (label c x <> []) e.at - ("type mismatch: instruction requires type " ^ string_of_ref_type rt ^ + ("type mismatch: instruction requires type " ^ string_of_ref_type rt2 ^ " but label has " ^ string_of_result_type (label c x)); let ts0, t1 = Lib.List.split_last (label c x) in - require (match_val_type c.types (RefT rt) t1) e.at - ("type mismatch: instruction requires type " ^ string_of_ref_type rt ^ + require (match_val_type c.types (RefT rt2) t1) e.at + ("type mismatch: instruction requires type " ^ string_of_ref_type rt2 ^ " but label has " ^ string_of_result_type (label c x)); - (ts0 @ [RefT rt']) --> (ts0 @ [RefT rt']), [] + (ts0 @ [RefT rt1]) --> (ts0 @ [RefT (diff_ref_type rt1 rt2)]), [] - | BrOnCastFail (x, rt) -> - let (_nul, ht) = rt in - let rt' = peek_ref 0 s e.at in - let tht = top_of_heap_type c.types ht in + | BrOnCastFail (x, rt1, rt2) -> + check_ref_type c rt1 e.at; + check_ref_type c rt2 e.at; + let rt1' = diff_ref_type rt1 rt2 in require - (match_ref_type c.types rt' (Null, tht)) e.at - ("type mismatch: instruction requires type " ^ - string_of_ref_type (Null, tht) ^ - " but stack has " ^ string_of_ref_type rt'); + (match_ref_type c.types rt2 rt1) e.at + ("type mismatch on cast: type " ^ string_of_ref_type rt2 ^ + " does not match " ^ string_of_ref_type rt1); require (label c x <> []) e.at - ("type mismatch: instruction requires type " ^ string_of_ref_type rt' ^ + ("type mismatch: instruction requires type " ^ string_of_ref_type rt1' ^ " but label has " ^ string_of_result_type (label c x)); let ts0, t1 = Lib.List.split_last (label c x) in - require (match_val_type c.types (RefT rt') t1) e.at - ("type mismatch: instruction requires type " ^ string_of_ref_type rt' ^ + require (match_val_type c.types (RefT rt1') t1) e.at + ("type mismatch: instruction requires type " ^ string_of_ref_type rt1' ^ " but label has " ^ string_of_result_type (label c x)); - (ts0 @ [RefT rt']) --> (ts0 @ [RefT rt]), [] + (ts0 @ [RefT rt1]) --> (ts0 @ [RefT rt2]), [] | Return -> c.results -->... [], [] @@ -664,7 +666,7 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : infer_in | RefCast rt -> check_ref_type c rt e.at; let (nul, ht) = rt in - [RefT (Null, top_of_heap_type c.types ht)] --> [RefT (nul, ht)], [] + [RefT (Null, top_of_heap_type c.types ht)] --> [RefT rt], [] | RefEq -> [RefT (Null, EqHT); RefT (Null, EqHT)] --> [NumT I32T], [] diff --git a/proposals/gc/MVP.md b/proposals/gc/MVP.md index c7eeccb3b..0e1dbceb4 100644 --- a/proposals/gc/MVP.md +++ b/proposals/gc/MVP.md @@ -429,7 +429,7 @@ Subtyping is not defined on type definitions. #### Runtime Types -* Runtime types (RTTs) are values representing concrete types at runtime. In the MVP, *canonical* RTTs are implicitly created by all instructions depending on runtime type information (recognisable by the suffix `_canon` in their mnemonics). In future versions, RTTs may become explicit values, and non-canonical versions of these instructions will be introduced. +* Runtime types (RTTs) are values representing concrete types at runtime. In the MVP, *canonical* RTTs are implicitly created by all instructions depending on runtime type information. In future versions, RTTs may become explicit values, and non-canonical versions of these instructions will be introduced. * An RTT value r1 is *equal* to another RTT value r2 iff they both represent the same static type. @@ -466,7 +466,7 @@ Then, `$rttA` would carry supertype vector `[$rttA]`, `$rttB` has `[$rttA, $rttB Now consider a function that casts a `$B` to a `$C`: ``` (func $castBtoC (param $x (ref $B)) (result (ref $C)) - (ref.cast_canon $C (local.get $x)) + (ref.cast $C (local.get $x)) ) ``` This can compile to machine code that (1) reads the RTT from `$x`, (2) checks that the length of its supertype table is >= 3, and (3) pointer-compares table[2] against `$rttC`. @@ -493,14 +493,14 @@ In particular, `ref.null` is typed as before, despite the introduction of `none` #### Structures -* `struct.new_canon ` allocates a structure with canonical [RTT](#values) and initialises its fields with given values - - `struct.new_canon $t : [t'*] -> [(ref $t)]` +* `struct.new ` allocates a structure with canonical [RTT](#values) and initialises its fields with given values + - `struct.new $t : [t'*] -> [(ref $t)]` - iff `expand($t) = struct (mut t'')*` - and `(t' = unpacked(t''))*` - this is a *constant instruction* -* `struct.new_canon_default ` allocates a structure of type `$t` with canonical [RTT](#values) and initialises its fields with default values - - `struct.new_canon_default $t : [] -> [(ref $t)]` +* `struct.new_default ` allocates a structure of type `$t` with canonical [RTT](#values) and initialises its fields with default values + - `struct.new_default $t : [] -> [(ref $t)]` - iff `expand($t) = struct (mut t')*` - and all `t'*` are defaultable - this is a *constant instruction* @@ -521,26 +521,26 @@ In particular, `ref.null` is typed as before, despite the introduction of `none` #### Arrays -* `array.new_canon ` allocates an array with canonical [RTT](#values) - - `array.new_canon $t : [t' i32] -> [(ref $t)]` +* `array.new ` allocates an array with canonical [RTT](#values) + - `array.new $t : [t' i32] -> [(ref $t)]` - iff `expand($t) = array (mut t'')` - and `t' = unpacked(t'')` - this is a *constant instruction* -* `array.new_canon_default ` allocates an array with canonical [RTT](#values) and initialises its fields with the default value - - `array.new_canon_default $t : [i32] -> [(ref $t)]` +* `array.new_default ` allocates an array with canonical [RTT](#values) and initialises its fields with the default value + - `array.new_default $t : [i32] -> [(ref $t)]` - iff `expand($t) = array (mut t')` - and `t'` is defaultable - this is a *constant instruction* -* `array.new_canon_fixed ` allocates an array with canonical [RTT](#values) of fixed size and initialises it from operands - - `array.new_canon_fixed $t N : [t^N] -> [(ref $t)]` +* `array.new_fixed ` allocates an array with canonical [RTT](#values) of fixed size and initialises it from operands + - `array.new_fixed $t N : [t^N] -> [(ref $t)]` - iff `expand($t) = array (mut t'')` - and `t' = unpacked(t'')` - this is a *constant instruction* -* `array.new_canon_data ` allocates an array with canonical [RTT](#values) and initialises it from a data segment - - `array.new_canon_data $t $d : [i32 i32] -> [(ref $t)]` +* `array.new_data ` allocates an array with canonical [RTT](#values) and initialises it from a data segment + - `array.new_data $t $d : [i32 i32] -> [(ref $t)]` - iff `expand($t) = array (mut t')` - and `t'` is numeric, vector, or packed - and `$d` is a defined data segment @@ -549,8 +549,8 @@ In particular, `ref.null` is typed as before, despite the introduction of `none` - traps if `offset + |t'|*size > len($d)` - note: for now, this is _not_ a constant instruction, in order to side-step issues of recursion between binary sections; this restriction will be lifted later -* `array.new_canon_elem ` allocates an array with canonical [RTT](#values) and initialises it from an element segment - - `array.new_canon_elem $t $e : [i32 i32] -> [(ref $t)]` +* `array.new_elem ` allocates an array with canonical [RTT](#values) and initialises it from an element segment + - `array.new_elem $t $e : [i32 i32] -> [(ref $t)]` - iff `expand($t) = array (mut t')` - and `$e : rt` - and `rt <: t'` @@ -609,31 +609,33 @@ Casts work for both abstract and concrete types. In the latter case, they test i * `ref.test ` tests whether a reference has a given type - `ref.test rt : [rt'] -> [i32]` - - iff `rt <: trt` and `rt' <: trt` for some `trt` + - iff `rt <: rt'` - if `rt` contains `null`, returns 1 for null, otherwise 0 * `ref.cast ` tries to convert a reference to a given type - `ref.cast rt : [rt'] -> [rt]` - - iff `rt <: trt` and `rt' <: trt` for some `trt` + - iff `rt <: rt'` - traps if reference is not of requested type - if `rt` contains `null`, a null operand is passed through, otherwise traps on null - equivalent to `(block $l (param trt) (result rt) (br_on_cast $l rt) (unreachable))` -* `br_on_cast ` branches if a reference has a given type - - `br_on_cast $l rt : [t0* rt'] -> [t0* rt']` - - iff `$l : [t0* t']` - - and `rt <: t'` - - and `rt <: trt` and `rt' <: trt` for some `trt` +* `br_on_cast ` branches if a reference has a given type + - `br_on_cast $l rt1 rt2 : [t0* rt1] -> [t0* rt1\rt2]` + - iff `$l : [t0* rt2]` + - and `rt2 <: rt1` - passes operand along with branch under target type, plus possible extra args - - if `rt` contains `null`, branches on null, otherwise does not + - if `rt2` contains `null`, branches on null, otherwise does not -* `br_on_cast_fail ` branches if a reference does not have a given type - - `br_on_cast_fail $l rt : [t0* rt'] -> [t0* rt]` - - iff `$l : [t0* t']` - - and `rt' <: t'` - - and `rt <: trt` and `rt' <: trt` for some `trt` +* `br_on_cast_fail ` branches if a reference does not have a given type + - `br_on_cast_fail $l rt1 rt2 : [t0* rt1] -> [t0* rt2]` + - iff `$l : [t0* rt1\rt2]` + - and `rt2 <: rt1` - passes operand along with branch, plus possible extra args - - if `rt` contains `null`, does not branch on null, otherwise does + - if `rt2` contains `null`, does not branch on null, otherwise does + +where: + - `(ref null1? ht1)\(ref null ht2) = (ref ht1)` + - `(ref null1? ht1)\(ref ht2) = (ref null1? ht1)` Note: Cast instructions do _not_ require the operand's source type to be a supertype of the target type. It can also be a "sibling" in the same hierarchy, i.e., they only need to have a common supertype (in practice, it is sufficient to test that both types share the same top heap type.). Allowing so is necessary to maintain subtype substitutability, i.e., the ability to maintain well-typedness when operands are replaced by subtypes. @@ -655,9 +657,9 @@ TODO: Should we remove the latter 3 from the typed function references proposal? In order to allow RTTs to be initialised as globals, the following extensions are made to the definition of *constant expressions*: * `i31.new` is a constant instruction -* `struct.new_canon` and `struct.new_canon_default` are constant instructions -* `array.new_canon`, `array.new_canon_default`, and `array.new_canon_fixed` are constant instructions - - Note: `array.new_canon_data` and `array.new_canon_elem` are not for the time being, see above +* `struct.new` and `struct.new_default` are constant instructions +* `array.new`, `array.new_default`, and `array.new_fixed` are constant instructions + - Note: `array.new_data` and `array.new_elem` are not for the time being, see above * `extern.internalize` and `extern.externalize` are constant instructions * `global.get` is a constant instruction and can access preceding (immutable) global definitions, not just imports as in the MVP @@ -749,36 +751,41 @@ The opcode for heap types is encoded as an `s33`. | ------ | --------------- | ---------- | | 0xd5 | `ref.eq` | | | 0xd6 | `br_on_non_null` | | -| 0xfb01 | `struct.new_canon $t` | `$t : typeidx` | -| 0xfb02 | `struct.new_canon_default $t` | `$t : typeidx` | +| 0xfb01 | `struct.new $t` | `$t : typeidx` | +| 0xfb02 | `struct.new_default $t` | `$t : typeidx` | | 0xfb03 | `struct.get $t i` | `$t : typeidx`, `i : fieldidx` | | 0xfb04 | `struct.get_s $t i` | `$t : typeidx`, `i : fieldidx` | | 0xfb05 | `struct.get_u $t i` | `$t : typeidx`, `i : fieldidx` | | 0xfb06 | `struct.set $t i` | `$t : typeidx`, `i : fieldidx` | -| 0xfb11 | `array.new_canon $t` | `$t : typeidx` | -| 0xfb12 | `array.new_canon_default $t` | `$t : typeidx` | +| 0xfb11 | `array.new $t` | `$t : typeidx` | +| 0xfb12 | `array.new_default $t` | `$t : typeidx` | | 0xfb13 | `array.get $t` | `$t : typeidx` | | 0xfb14 | `array.get_s $t` | `$t : typeidx` | | 0xfb15 | `array.get_u $t` | `$t : typeidx` | | 0xfb16 | `array.set $t` | `$t : typeidx` | | 0xfb17 | `array.len` | | -| 0xfb19 | `array.new_canon_fixed $t N` | `$t : typeidx`, `N : u32` | -| 0xfb1b | `array.new_canon_data $t $d` | `$t : typeidx`, `$d : dataidx` | -| 0xfb1c | `array.new_canon_elem $t $e` | `$t : typeidx`, `$e : elemidx` | +| 0xfb19 | `array.new_fixed $t N` | `$t : typeidx`, `N : u32` | +| 0xfb1b | `array.new_data $t $d` | `$t : typeidx`, `$d : dataidx` | +| 0xfb1c | `array.new_elem $t $e` | `$t : typeidx`, `$e : elemidx` | | 0xfb20 | `i31.new` | | | 0xfb21 | `i31.get_s` | | | 0xfb22 | `i31.get_u` | | -| 0xfb40 | `ref.test ht` | `ht : heaptype` | -| 0xfb41 | `ref.cast ht` | `ht : heaptype` | -| 0xfb42 | `br_on_cast $l ht` | `$l : labelidx`, `ht : heaptype` | -| 0xfb43 | `br_on_cast_fail $l ht` | `$l : labelidx`, `ht : heaptype` | -| 0xfb48 | `ref.test null ht` | `ht : heaptype` | -| 0xfb49 | `ref.cast null ht` | `ht : heaptype` | -| 0xfb4a | `br_on_cast $l null ht` | `$l : labelidx`, `ht : heaptype` | -| 0xfb4b | `br_on_cast_fail $l null ht` | `$l : labelidx`, `ht : heaptype` | +| 0xfb40 | `ref.test (ref ht)` | `ht : heaptype` | +| 0xfb41 | `ref.cast (ref ht)` | `ht : heaptype` | +| 0xfb48 | `ref.test (ref null ht)` | `ht : heaptype` | +| 0xfb49 | `ref.cast (ref null ht)` | `ht : heaptype` | +| 0xfb4e | `br_on_cast $l (ref null1? ht1) (ref null2? ht2)` | `flags : u8`, $l : labelidx`, `ht1 : heaptype`, `ht2 : heaptype` | +| 0xfb4f | `br_on_cast_fail $l (ref null1? ht1) (ref null2? ht2)` | `flags : u8`, $l : labelidx`, `ht1 : heaptype`, `ht2 : heaptype` | | 0xfb70 | `extern.internalize` | | | 0xfb71 | `extern.externalize` | | +Flag byte encoding for `br_on_cast(_fail)?`: + +| Bit | Function | +| --- | ------------- | +| 0 | null1 present | +| 1 | null2 present | + ## JS API @@ -795,7 +802,7 @@ See [GC JS API document](MVP-JS.md) . -## Appendix: Formal Rules +## Appendix: Formal Rules for Types ### Validity diff --git a/test/core/gc/array.wast b/test/core/gc/array.wast index 7ee75b205..0da7e8432 100644 --- a/test/core/gc/array.wast +++ b/test/core/gc/array.wast @@ -61,11 +61,11 @@ (type $vec (array f32)) (type $mvec (array (mut f32))) - (global (ref $vec) (array.new_canon $vec (f32.const 1) (i32.const 3))) - (global (ref $vec) (array.new_canon_default $vec (i32.const 3))) + (global (ref $vec) (array.new $vec (f32.const 1) (i32.const 3))) + (global (ref $vec) (array.new_default $vec (i32.const 3))) (func $new (export "new") (result (ref $vec)) - (array.new_canon_default $vec (i32.const 3)) + (array.new_default $vec (i32.const 3)) ) (func $get (param $i i32) (param $v (ref $vec)) (result f32) @@ -81,7 +81,7 @@ ) (func (export "set_get") (param $i i32) (param $y f32) (result f32) (call $set_get (local.get $i) - (array.new_canon_default $mvec (i32.const 3)) + (array.new_default $mvec (i32.const 3)) (local.get $y) ) ) @@ -107,10 +107,10 @@ (type $vec (array f32)) (type $mvec (array (mut f32))) - (global (ref $vec) (array.new_canon_fixed $vec 2 (f32.const 1) (f32.const 2))) + (global (ref $vec) (array.new_fixed $vec 2 (f32.const 1) (f32.const 2))) (func $new (export "new") (result (ref $vec)) - (array.new_canon_fixed $vec 2 (f32.const 1) (f32.const 2)) + (array.new_fixed $vec 2 (f32.const 1) (f32.const 2)) ) (func $get (param $i i32) (param $v (ref $vec)) (result f32) @@ -126,7 +126,7 @@ ) (func (export "set_get") (param $i i32) (param $y f32) (result f32) (call $set_get (local.get $i) - (array.new_canon_fixed $mvec 3 (f32.const 1) (f32.const 2) (f32.const 3)) + (array.new_fixed $mvec 3 (f32.const 1) (f32.const 2) (f32.const 3)) (local.get $y) ) ) @@ -155,7 +155,7 @@ (data $d "\00\01\02\03\04") (func $new (export "new") (result (ref $vec)) - (array.new_canon_data $vec $d (i32.const 1) (i32.const 3)) + (array.new_data $vec $d (i32.const 1) (i32.const 3)) ) (func $get (param $i i32) (param $v (ref $vec)) (result i32) @@ -171,7 +171,7 @@ ) (func (export "set_get") (param $i i32) (param $y i32) (result i32) (call $set_get (local.get $i) - (array.new_canon_data $mvec $d (i32.const 1) (i32.const 3)) + (array.new_data $mvec $d (i32.const 1) (i32.const 3)) (local.get $y) ) ) @@ -201,19 +201,19 @@ (type $avec (array (mut anyref))) (elem $e (ref $bvec) - (array.new_canon $bvec (i32.const 7) (i32.const 3)) - (array.new_canon_fixed $bvec 2 (i32.const 1) (i32.const 2)) + (array.new $bvec (i32.const 7) (i32.const 3)) + (array.new_fixed $bvec 2 (i32.const 1) (i32.const 2)) ) (func $new (export "new") (result (ref $vec)) - (array.new_canon_elem $vec $e (i32.const 0) (i32.const 2)) + (array.new_elem $vec $e (i32.const 0) (i32.const 2)) ) (func $sub1 (result (ref $nvec)) - (array.new_canon_elem $nvec $e (i32.const 0) (i32.const 2)) + (array.new_elem $nvec $e (i32.const 0) (i32.const 2)) ) (func $sub2 (result (ref $avec)) - (array.new_canon_elem $avec $e (i32.const 0) (i32.const 2)) + (array.new_elem $avec $e (i32.const 0) (i32.const 2)) ) (func $get (param $i i32) (param $j i32) (param $v (ref $vec)) (result i32) @@ -229,7 +229,7 @@ ) (func (export "set_get") (param $i i32) (param $j i32) (param $y i32) (result i32) (call $set_get (local.get $i) (local.get $j) - (array.new_canon_elem $mvec $e (i32.const 0) (i32.const 2)) + (array.new_elem $mvec $e (i32.const 0) (i32.const 2)) (local.get $y) ) ) @@ -269,7 +269,7 @@ (data $d "\00\01\02\03\04") (global (ref $bvec) - (array.new_canon_data $bvec $d (i32.const 1) (i32.const 3)) + (array.new_data $bvec $d (i32.const 1) (i32.const 3)) ) ) "constant expression required" @@ -283,7 +283,7 @@ (elem $e (ref $bvec) (ref.null $bvec)) (global (ref $vvec) - (array.new_canon_elem $vvec $e (i32.const 0) (i32.const 1)) + (array.new_elem $vvec $e (i32.const 0) (i32.const 1)) ) ) "constant expression required" diff --git a/test/core/gc/br_on_cast.wast b/test/core/gc/br_on_cast.wast index c73d5419f..a7b35949a 100644 --- a/test/core/gc/br_on_cast.wast +++ b/test/core/gc/br_on_cast.wast @@ -13,8 +13,8 @@ (func (export "init") (param $x externref) (table.set (i32.const 0) (ref.null any)) (table.set (i32.const 1) (i31.new (i32.const 7))) - (table.set (i32.const 2) (struct.new_canon $st (i32.const 6))) - (table.set (i32.const 3) (array.new_canon $at (i32.const 5) (i32.const 3))) + (table.set (i32.const 2) (struct.new $st (i32.const 6))) + (table.set (i32.const 3) (array.new $at (i32.const 5) (i32.const 3))) (table.set (i32.const 4) (extern.internalize (local.get $x))) ) @@ -27,20 +27,20 @@ ) (func (export "br_on_i31") (param $i i32) (result i32) (block $l (result (ref i31)) - (br_on_cast $l i31 (table.get (local.get $i))) + (br_on_cast $l anyref (ref i31) (table.get (local.get $i))) (return (i32.const -1)) ) (i31.get_u) ) (func (export "br_on_struct") (param $i i32) (result i32) (block $l (result (ref struct)) - (br_on_cast $l struct (table.get (local.get $i))) + (br_on_cast $l anyref (ref struct) (table.get (local.get $i))) (return (i32.const -1)) ) (block $l2 (param structref) (result (ref $st)) (block $l3 (param structref) (result (ref $at)) - (br_on_cast $l2 $st) - (br_on_cast $l3 $at) + (br_on_cast $l2 structref (ref $st)) + (br_on_cast $l3 anyref (ref $at)) (return (i32.const -2)) ) (return (array.get_u $at (i32.const 0))) @@ -49,11 +49,21 @@ ) (func (export "br_on_array") (param $i i32) (result i32) (block $l (result (ref array)) - (br_on_cast $l array (table.get (local.get $i))) + (br_on_cast $l anyref (ref array) (table.get (local.get $i))) (return (i32.const -1)) ) (array.len) ) + + (func (export "null-diff") (param $i i32) (result i32) + (block $l (result (ref null struct)) + (block (result (ref any)) + (br_on_cast $l (ref null any) (ref null struct) (table.get (local.get $i))) + ) + (return (i32.const 0)) + ) + (return (i32.const 1)) + ) ) (invoke "init" (ref.extern 0)) @@ -82,6 +92,12 @@ (assert_return (invoke "br_on_array" (i32.const 3)) (i32.const 3)) (assert_return (invoke "br_on_array" (i32.const 4)) (i32.const -1)) +(assert_return (invoke "null-diff" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "null-diff" (i32.const 1)) (i32.const 0)) +(assert_return (invoke "null-diff" (i32.const 2)) (i32.const 1)) +(assert_return (invoke "null-diff" (i32.const 3)) (i32.const 0)) +(assert_return (invoke "null-diff" (i32.const 4)) (i32.const 0)) + ;; Concrete Types @@ -98,59 +114,59 @@ (table 20 structref) (func $init - (table.set (i32.const 0) (struct.new_canon_default $t0)) - (table.set (i32.const 10) (struct.new_canon_default $t0')) - (table.set (i32.const 1) (struct.new_canon_default $t1)) - (table.set (i32.const 11) (struct.new_canon_default $t1')) - (table.set (i32.const 2) (struct.new_canon_default $t2)) - (table.set (i32.const 12) (struct.new_canon_default $t2')) - (table.set (i32.const 3) (struct.new_canon_default $t3)) - (table.set (i32.const 4) (struct.new_canon_default $t4)) + (table.set (i32.const 0) (struct.new_default $t0)) + (table.set (i32.const 10) (struct.new_default $t0')) + (table.set (i32.const 1) (struct.new_default $t1)) + (table.set (i32.const 11) (struct.new_default $t1')) + (table.set (i32.const 2) (struct.new_default $t2)) + (table.set (i32.const 12) (struct.new_default $t2')) + (table.set (i32.const 3) (struct.new_default $t3)) + (table.set (i32.const 4) (struct.new_default $t4)) ) (func (export "test-sub") (call $init) (block $l (result structref) ;; must succeed - (drop (block (result structref) (br_on_cast 0 $t0 (ref.null struct)))) - (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 0))))) - (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 1))))) - (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 2))))) - (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 3))))) - (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 4))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t0) (ref.null struct)))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 0))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 1))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 2))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 3))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 4))))) - (drop (block (result structref) (br_on_cast 0 $t1 (ref.null struct)))) - (drop (block (result structref) (br_on_cast 0 $t1 (table.get (i32.const 1))))) - (drop (block (result structref) (br_on_cast 0 $t1 (table.get (i32.const 2))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t1) (ref.null struct)))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t1) (table.get (i32.const 1))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t1) (table.get (i32.const 2))))) - (drop (block (result structref) (br_on_cast 0 $t2 (ref.null struct)))) - (drop (block (result structref) (br_on_cast 0 $t2 (table.get (i32.const 2))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t2) (ref.null struct)))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t2) (table.get (i32.const 2))))) - (drop (block (result structref) (br_on_cast 0 $t3 (ref.null struct)))) - (drop (block (result structref) (br_on_cast 0 $t3 (table.get (i32.const 3))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t3) (ref.null struct)))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t3) (table.get (i32.const 3))))) - (drop (block (result structref) (br_on_cast 0 $t4 (ref.null struct)))) - (drop (block (result structref) (br_on_cast 0 $t4 (table.get (i32.const 4))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t4) (ref.null struct)))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t4) (table.get (i32.const 4))))) ;; must not succeed - (br_on_cast $l $t1 (table.get (i32.const 0))) - (br_on_cast $l $t1 (table.get (i32.const 3))) - (br_on_cast $l $t1 (table.get (i32.const 4))) + (br_on_cast $l anyref (ref $t1) (table.get (i32.const 0))) + (br_on_cast $l anyref (ref $t1) (table.get (i32.const 3))) + (br_on_cast $l anyref (ref $t1) (table.get (i32.const 4))) - (br_on_cast $l $t2 (table.get (i32.const 0))) - (br_on_cast $l $t2 (table.get (i32.const 1))) - (br_on_cast $l $t2 (table.get (i32.const 3))) - (br_on_cast $l $t2 (table.get (i32.const 4))) + (br_on_cast $l anyref (ref $t2) (table.get (i32.const 0))) + (br_on_cast $l anyref (ref $t2) (table.get (i32.const 1))) + (br_on_cast $l anyref (ref $t2) (table.get (i32.const 3))) + (br_on_cast $l anyref (ref $t2) (table.get (i32.const 4))) - (br_on_cast $l $t3 (table.get (i32.const 0))) - (br_on_cast $l $t3 (table.get (i32.const 1))) - (br_on_cast $l $t3 (table.get (i32.const 2))) - (br_on_cast $l $t3 (table.get (i32.const 4))) + (br_on_cast $l anyref (ref $t3) (table.get (i32.const 0))) + (br_on_cast $l anyref (ref $t3) (table.get (i32.const 1))) + (br_on_cast $l anyref (ref $t3) (table.get (i32.const 2))) + (br_on_cast $l anyref (ref $t3) (table.get (i32.const 4))) - (br_on_cast $l $t4 (table.get (i32.const 0))) - (br_on_cast $l $t4 (table.get (i32.const 1))) - (br_on_cast $l $t4 (table.get (i32.const 2))) - (br_on_cast $l $t4 (table.get (i32.const 3))) + (br_on_cast $l anyref (ref $t4) (table.get (i32.const 0))) + (br_on_cast $l anyref (ref $t4) (table.get (i32.const 1))) + (br_on_cast $l anyref (ref $t4) (table.get (i32.const 2))) + (br_on_cast $l anyref (ref $t4) (table.get (i32.const 3))) (return) ) @@ -160,25 +176,25 @@ (func (export "test-canon") (call $init) (block $l - (drop (block (result structref) (br_on_cast 0 $t0' (table.get (i32.const 0))))) - (drop (block (result structref) (br_on_cast 0 $t0' (table.get (i32.const 1))))) - (drop (block (result structref) (br_on_cast 0 $t0' (table.get (i32.const 2))))) - (drop (block (result structref) (br_on_cast 0 $t0' (table.get (i32.const 3))))) - (drop (block (result structref) (br_on_cast 0 $t0' (table.get (i32.const 4))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t0') (table.get (i32.const 0))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t0') (table.get (i32.const 1))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t0') (table.get (i32.const 2))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t0') (table.get (i32.const 3))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t0') (table.get (i32.const 4))))) - (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 10))))) - (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 11))))) - (drop (block (result structref) (br_on_cast 0 $t0 (table.get (i32.const 12))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 10))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 11))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t0) (table.get (i32.const 12))))) - (drop (block (result structref) (br_on_cast 0 $t1' (table.get (i32.const 1))))) - (drop (block (result structref) (br_on_cast 0 $t1' (table.get (i32.const 2))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t1') (table.get (i32.const 1))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t1') (table.get (i32.const 2))))) - (drop (block (result structref) (br_on_cast 0 $t1 (table.get (i32.const 11))))) - (drop (block (result structref) (br_on_cast 0 $t1 (table.get (i32.const 12))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t1) (table.get (i32.const 11))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t1) (table.get (i32.const 12))))) - (drop (block (result structref) (br_on_cast 0 $t2' (table.get (i32.const 2))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t2') (table.get (i32.const 2))))) - (drop (block (result structref) (br_on_cast 0 $t2 (table.get (i32.const 12))))) + (drop (block (result structref) (br_on_cast 0 structref (ref $t2) (table.get (i32.const 12))))) (return) ) @@ -196,16 +212,13 @@ (type $t (struct)) (func (param (ref any)) (result (ref $t)) - (block (result (ref any)) (br_on_cast 1 $t (local.get 0))) (unreachable) + (block (result (ref any)) (br_on_cast 1 (ref any) (ref $t) (local.get 0))) (unreachable) ) (func (param (ref null any)) (result (ref $t)) - (block (result (ref null any)) (br_on_cast 1 $t (local.get 0))) (unreachable) - ) - (func (param (ref any)) (result (ref null $t)) - (block (result (ref any)) (br_on_cast 1 null $t (local.get 0))) (unreachable) + (block (result (ref null any)) (br_on_cast 1 (ref null any) (ref $t) (local.get 0))) (unreachable) ) (func (param (ref null any)) (result (ref null $t)) - (block (result (ref null any)) (br_on_cast 1 null $t (local.get 0))) (unreachable) + (block (result (ref null any)) (br_on_cast 1 (ref null any) (ref null $t) (local.get 0))) (unreachable) ) ) @@ -213,7 +226,16 @@ (module (type $t (struct)) (func (param (ref any)) (result (ref $t)) - (block (result (ref any)) (br_on_cast 1 null $t (local.get 0))) (unreachable) + (block (result (ref any)) (br_on_cast 1 (ref null any) (ref null $t) (local.get 0))) (unreachable) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (type $t (struct)) + (func (param (ref any)) (result (ref null $t)) + (block (result (ref any)) (br_on_cast 1 (ref any) (ref null $t) (local.get 0))) (unreachable) ) ) "type mismatch" @@ -222,7 +244,7 @@ (module (type $t (struct)) (func (param (ref null any)) (result (ref $t)) - (block (result (ref any)) (br_on_cast 1 $t (local.get 0))) (unreachable) + (block (result (ref any)) (br_on_cast 1 (ref null any) (ref $t) (local.get 0))) (unreachable) ) ) "type mismatch" diff --git a/test/core/gc/br_on_cast_fail.wast b/test/core/gc/br_on_cast_fail.wast index b85d34ca8..601de88af 100644 --- a/test/core/gc/br_on_cast_fail.wast +++ b/test/core/gc/br_on_cast_fail.wast @@ -13,8 +13,8 @@ (func (export "init") (param $x externref) (table.set (i32.const 0) (ref.null any)) (table.set (i32.const 1) (i31.new (i32.const 7))) - (table.set (i32.const 2) (struct.new_canon $st (i32.const 6))) - (table.set (i32.const 3) (array.new_canon $at (i32.const 5) (i32.const 3))) + (table.set (i32.const 2) (struct.new $st (i32.const 6))) + (table.set (i32.const 3) (array.new $at (i32.const 5) (i32.const 3))) (table.set (i32.const 4) (extern.internalize (local.get $x))) ) @@ -27,18 +27,18 @@ ) (func (export "br_on_non_i31") (param $i i32) (result i32) (block $l (result anyref) - (br_on_cast_fail $l i31 (table.get (local.get $i))) + (br_on_cast_fail $l anyref (ref i31) (table.get (local.get $i))) (return (i31.get_u)) ) (return (i32.const -1)) ) (func (export "br_on_non_struct") (param $i i32) (result i32) (block $l (result anyref) - (br_on_cast_fail $l struct (table.get (local.get $i))) + (br_on_cast_fail $l anyref (ref struct) (table.get (local.get $i))) (block $l2 (param structref) (result (ref $st)) (block $l3 (param structref) (result (ref $at)) - (br_on_cast $l2 $st) - (br_on_cast $l3 $at) + (br_on_cast $l2 structref (ref $st)) + (br_on_cast $l3 anyref (ref $at)) (return (i32.const -2)) ) (return (array.get_u $at (i32.const 0))) @@ -49,11 +49,21 @@ ) (func (export "br_on_non_array") (param $i i32) (result i32) (block $l (result anyref) - (br_on_cast_fail $l array (table.get (local.get $i))) + (br_on_cast_fail $l anyref (ref array) (table.get (local.get $i))) (return (array.len)) ) (return (i32.const -1)) ) + + (func (export "null-diff") (param $i i32) (result i32) + (block $l (result (ref any)) + (block (result (ref null struct)) + (br_on_cast_fail $l (ref null any) (ref null struct) (table.get (local.get $i))) + ) + (return (i32.const 1)) + ) + (return (i32.const 0)) + ) ) (invoke "init" (ref.extern 0)) @@ -82,6 +92,12 @@ (assert_return (invoke "br_on_non_array" (i32.const 3)) (i32.const 3)) (assert_return (invoke "br_on_non_array" (i32.const 4)) (i32.const -1)) +(assert_return (invoke "null-diff" (i32.const 0)) (i32.const 1)) +(assert_return (invoke "null-diff" (i32.const 1)) (i32.const 0)) +(assert_return (invoke "null-diff" (i32.const 2)) (i32.const 1)) +(assert_return (invoke "null-diff" (i32.const 3)) (i32.const 0)) +(assert_return (invoke "null-diff" (i32.const 4)) (i32.const 0)) + ;; Concrete Types @@ -98,75 +114,75 @@ (table 20 structref) (func $init - (table.set (i32.const 0) (struct.new_canon_default $t0)) - (table.set (i32.const 10) (struct.new_canon_default $t0)) - (table.set (i32.const 1) (struct.new_canon_default $t1)) - (table.set (i32.const 11) (struct.new_canon_default $t1')) - (table.set (i32.const 2) (struct.new_canon_default $t2)) - (table.set (i32.const 12) (struct.new_canon_default $t2')) - (table.set (i32.const 3) (struct.new_canon_default $t3 )) - (table.set (i32.const 4) (struct.new_canon_default $t4)) + (table.set (i32.const 0) (struct.new_default $t0)) + (table.set (i32.const 10) (struct.new_default $t0)) + (table.set (i32.const 1) (struct.new_default $t1)) + (table.set (i32.const 11) (struct.new_default $t1')) + (table.set (i32.const 2) (struct.new_default $t2)) + (table.set (i32.const 12) (struct.new_default $t2')) + (table.set (i32.const 3) (struct.new_default $t3 )) + (table.set (i32.const 4) (struct.new_default $t4)) ) (func (export "test-sub") (call $init) (block $l (result structref) ;; must not succeed - (br_on_cast_fail $l null $t0 (ref.null struct)) - (br_on_cast_fail $l null $t0 (table.get (i32.const 0))) - (br_on_cast_fail $l null $t0 (table.get (i32.const 1))) - (br_on_cast_fail $l null $t0 (table.get (i32.const 2))) - (br_on_cast_fail $l null $t0 (table.get (i32.const 3))) - (br_on_cast_fail $l null $t0 (table.get (i32.const 4))) - (br_on_cast_fail $l $t0 (table.get (i32.const 0))) - (br_on_cast_fail $l $t0 (table.get (i32.const 1))) - (br_on_cast_fail $l $t0 (table.get (i32.const 2))) - (br_on_cast_fail $l $t0 (table.get (i32.const 3))) - (br_on_cast_fail $l $t0 (table.get (i32.const 4))) - - (br_on_cast_fail $l null $t1 (ref.null struct)) - (br_on_cast_fail $l null $t1 (table.get (i32.const 1))) - (br_on_cast_fail $l null $t1 (table.get (i32.const 2))) - (br_on_cast_fail $l $t1 (table.get (i32.const 1))) - (br_on_cast_fail $l $t1 (table.get (i32.const 2))) - - (br_on_cast_fail $l null $t2 (ref.null struct)) - (br_on_cast_fail $l null $t2 (table.get (i32.const 2))) - (br_on_cast_fail $l $t2 (table.get (i32.const 2))) - - (br_on_cast_fail $l null $t3 (ref.null struct)) - (br_on_cast_fail $l null $t3 (table.get (i32.const 3))) - (br_on_cast_fail $l $t3 (table.get (i32.const 3))) - - (br_on_cast_fail $l null $t4 (ref.null struct)) - (br_on_cast_fail $l null $t4 (table.get (i32.const 4))) - (br_on_cast_fail $l $t4 (table.get (i32.const 4))) + (br_on_cast_fail $l structref (ref null $t0) (ref.null struct)) + (br_on_cast_fail $l structref (ref null $t0) (table.get (i32.const 0))) + (br_on_cast_fail $l structref (ref null $t0) (table.get (i32.const 1))) + (br_on_cast_fail $l structref (ref null $t0) (table.get (i32.const 2))) + (br_on_cast_fail $l structref (ref null $t0) (table.get (i32.const 3))) + (br_on_cast_fail $l structref (ref null $t0) (table.get (i32.const 4))) + (br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 0))) + (br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 1))) + (br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 2))) + (br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 3))) + (br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 4))) + + (br_on_cast_fail $l structref (ref null $t1) (ref.null struct)) + (br_on_cast_fail $l structref (ref null $t1) (table.get (i32.const 1))) + (br_on_cast_fail $l structref (ref null $t1) (table.get (i32.const 2))) + (br_on_cast_fail $l structref (ref $t1) (table.get (i32.const 1))) + (br_on_cast_fail $l structref (ref $t1) (table.get (i32.const 2))) + + (br_on_cast_fail $l structref (ref null $t2) (ref.null struct)) + (br_on_cast_fail $l structref (ref null $t2) (table.get (i32.const 2))) + (br_on_cast_fail $l structref (ref $t2) (table.get (i32.const 2))) + + (br_on_cast_fail $l structref (ref null $t3) (ref.null struct)) + (br_on_cast_fail $l structref (ref null $t3) (table.get (i32.const 3))) + (br_on_cast_fail $l structref (ref $t3) (table.get (i32.const 3))) + + (br_on_cast_fail $l structref (ref null $t4) (ref.null struct)) + (br_on_cast_fail $l structref (ref null $t4) (table.get (i32.const 4))) + (br_on_cast_fail $l structref (ref $t4) (table.get (i32.const 4))) ;; must succeed - (drop (block (result structref) (br_on_cast_fail 0 $t0 (ref.null struct)))) - - (drop (block (result structref) (br_on_cast_fail 0 $t1 (ref.null struct)))) - (drop (block (result structref) (br_on_cast_fail 0 $t1 (table.get (i32.const 0))))) - (drop (block (result structref) (br_on_cast_fail 0 $t1 (table.get (i32.const 3))))) - (drop (block (result structref) (br_on_cast_fail 0 $t1 (table.get (i32.const 4))))) - - (drop (block (result structref) (br_on_cast_fail 0 $t2 (ref.null struct)))) - (drop (block (result structref) (br_on_cast_fail 0 $t2 (table.get (i32.const 0))))) - (drop (block (result structref) (br_on_cast_fail 0 $t2 (table.get (i32.const 1))))) - (drop (block (result structref) (br_on_cast_fail 0 $t2 (table.get (i32.const 3))))) - (drop (block (result structref) (br_on_cast_fail 0 $t2 (table.get (i32.const 4))))) - - (drop (block (result structref) (br_on_cast_fail 0 $t3 (ref.null struct)))) - (drop (block (result structref) (br_on_cast_fail 0 $t3 (table.get (i32.const 0))))) - (drop (block (result structref) (br_on_cast_fail 0 $t3 (table.get (i32.const 1))))) - (drop (block (result structref) (br_on_cast_fail 0 $t3 (table.get (i32.const 2))))) - (drop (block (result structref) (br_on_cast_fail 0 $t3 (table.get (i32.const 4))))) - - (drop (block (result structref) (br_on_cast_fail 0 $t4 (ref.null struct)))) - (drop (block (result structref) (br_on_cast_fail 0 $t4 (table.get (i32.const 0))))) - (drop (block (result structref) (br_on_cast_fail 0 $t4 (table.get (i32.const 1))))) - (drop (block (result structref) (br_on_cast_fail 0 $t4 (table.get (i32.const 2))))) - (drop (block (result structref) (br_on_cast_fail 0 $t4 (table.get (i32.const 3))))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t0) (ref.null struct)))) + + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t1) (ref.null struct)))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t1) (table.get (i32.const 0))))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t1) (table.get (i32.const 3))))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t1) (table.get (i32.const 4))))) + + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t2) (ref.null struct)))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t2) (table.get (i32.const 0))))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t2) (table.get (i32.const 1))))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t2) (table.get (i32.const 3))))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t2) (table.get (i32.const 4))))) + + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t3) (ref.null struct)))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t3) (table.get (i32.const 0))))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t3) (table.get (i32.const 1))))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t3) (table.get (i32.const 2))))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t3) (table.get (i32.const 4))))) + + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t4) (ref.null struct)))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t4) (table.get (i32.const 0))))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t4) (table.get (i32.const 1))))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t4) (table.get (i32.const 2))))) + (drop (block (result structref) (br_on_cast_fail 0 structref (ref $t4) (table.get (i32.const 3))))) (return) ) @@ -176,24 +192,24 @@ (func (export "test-canon") (call $init) (block $l (result structref) - (br_on_cast_fail $l $t0 (table.get (i32.const 0))) - (br_on_cast_fail $l $t0 (table.get (i32.const 1))) - (br_on_cast_fail $l $t0 (table.get (i32.const 2))) - (br_on_cast_fail $l $t0 (table.get (i32.const 3))) - (br_on_cast_fail $l $t0 (table.get (i32.const 4))) - (br_on_cast_fail $l $t0 (table.get (i32.const 10))) - (br_on_cast_fail $l $t0 (table.get (i32.const 11))) - (br_on_cast_fail $l $t0 (table.get (i32.const 12))) + (br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 0))) + (br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 1))) + (br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 2))) + (br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 3))) + (br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 4))) + (br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 10))) + (br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 11))) + (br_on_cast_fail $l structref (ref $t0) (table.get (i32.const 12))) - (br_on_cast_fail $l $t1' (table.get (i32.const 1))) - (br_on_cast_fail $l $t1' (table.get (i32.const 2))) + (br_on_cast_fail $l structref (ref $t1') (table.get (i32.const 1))) + (br_on_cast_fail $l structref (ref $t1') (table.get (i32.const 2))) - (br_on_cast_fail $l $t1 (table.get (i32.const 11))) - (br_on_cast_fail $l $t1 (table.get (i32.const 12))) + (br_on_cast_fail $l structref (ref $t1) (table.get (i32.const 11))) + (br_on_cast_fail $l structref (ref $t1) (table.get (i32.const 12))) - (br_on_cast_fail $l $t2' (table.get (i32.const 2))) + (br_on_cast_fail $l structref (ref $t2') (table.get (i32.const 2))) - (br_on_cast_fail $l $t2 (table.get (i32.const 12))) + (br_on_cast_fail $l structref (ref $t2) (table.get (i32.const 12))) (return) ) @@ -211,16 +227,13 @@ (type $t (struct)) (func (param (ref any)) (result (ref any)) - (block (result (ref $t)) (br_on_cast_fail 1 $t (local.get 0))) + (block (result (ref $t)) (br_on_cast_fail 1 (ref any) (ref $t) (local.get 0))) ) (func (param (ref null any)) (result (ref null any)) - (block (result (ref $t)) (br_on_cast_fail 1 $t (local.get 0))) - ) - (func (param (ref any)) (result (ref any)) - (block (result (ref null $t)) (br_on_cast_fail 1 null $t (local.get 0))) (ref.as_non_null) + (block (result (ref $t)) (br_on_cast_fail 1 (ref null any) (ref $t) (local.get 0))) ) (func (param (ref null any)) (result (ref null any)) - (block (result (ref null $t)) (br_on_cast_fail 1 null $t (local.get 0))) + (block (result (ref null $t)) (br_on_cast_fail 1 (ref null any) (ref null $t) (local.get 0))) ) ) @@ -228,7 +241,16 @@ (module (type $t (struct)) (func (param (ref any)) (result (ref any)) - (block (result (ref $t)) (br_on_cast_fail 1 null $t (local.get 0))) + (block (result (ref $t)) (br_on_cast_fail 1 (ref null any) (ref null $t) (local.get 0))) + ) + ) + "type mismatch" +) +(assert_invalid + (module + (type $t (struct)) + (func (param (ref any)) (result (ref any)) + (block (result (ref null $t)) (br_on_cast_fail 1 (ref any) (ref null $t) (local.get 0))) (ref.as_non_null) ) ) "type mismatch" @@ -237,7 +259,7 @@ (module (type $t (struct)) (func (param (ref null any)) (result (ref any)) - (block (result (ref $t)) (br_on_cast_fail 1 $t (local.get 0))) + (block (result (ref $t)) (br_on_cast_fail 1 (ref null any) (ref $t) (local.get 0))) ) ) "type mismatch" diff --git a/test/core/gc/extern.wast b/test/core/gc/extern.wast index 1f32a0abe..f9b01f11e 100644 --- a/test/core/gc/extern.wast +++ b/test/core/gc/extern.wast @@ -11,8 +11,8 @@ (func (export "init") (param $x externref) (table.set (i32.const 0) (ref.null any)) (table.set (i32.const 1) (i31.new (i32.const 7))) - (table.set (i32.const 2) (struct.new_canon_default $st)) - (table.set (i32.const 3) (array.new_canon_default $at (i32.const 0))) + (table.set (i32.const 2) (struct.new_default $st)) + (table.set (i32.const 3) (array.new_default $at (i32.const 0))) (table.set (i32.const 4) (extern.internalize (local.get $x))) ) diff --git a/test/core/gc/ref_cast.wast b/test/core/gc/ref_cast.wast index b5bb163fd..0a1a0edea 100644 --- a/test/core/gc/ref_cast.wast +++ b/test/core/gc/ref_cast.wast @@ -13,8 +13,8 @@ (func (export "init") (param $x externref) (table.set (i32.const 0) (ref.null any)) (table.set (i32.const 1) (i31.new (i32.const 7))) - (table.set (i32.const 2) (struct.new_canon_default $st)) - (table.set (i32.const 3) (array.new_canon_default $at (i32.const 0))) + (table.set (i32.const 2) (struct.new_default $st)) + (table.set (i32.const 3) (array.new_default $at (i32.const 0))) (table.set (i32.const 4) (extern.internalize (local.get $x))) (table.set (i32.const 5) (ref.null i31)) (table.set (i32.const 6) (ref.null struct)) @@ -23,26 +23,26 @@ (func (export "ref_cast_non_null") (param $i i32) (drop (ref.as_non_null (table.get (local.get $i)))) - (drop (ref.cast null any (table.get (local.get $i)))) + (drop (ref.cast (ref null any) (table.get (local.get $i)))) ) (func (export "ref_cast_null") (param $i i32) - (drop (ref.cast null any (table.get (local.get $i)))) - (drop (ref.cast null struct (table.get (local.get $i)))) - (drop (ref.cast null array (table.get (local.get $i)))) - (drop (ref.cast null i31 (table.get (local.get $i)))) - (drop (ref.cast null none (table.get (local.get $i)))) + (drop (ref.cast anyref (table.get (local.get $i)))) + (drop (ref.cast structref (table.get (local.get $i)))) + (drop (ref.cast arrayref (table.get (local.get $i)))) + (drop (ref.cast i31ref (table.get (local.get $i)))) + (drop (ref.cast nullref (table.get (local.get $i)))) ) (func (export "ref_cast_i31") (param $i i32) - (drop (ref.cast i31 (table.get (local.get $i)))) - (drop (ref.cast null i31 (table.get (local.get $i)))) + (drop (ref.cast (ref i31) (table.get (local.get $i)))) + (drop (ref.cast i31ref (table.get (local.get $i)))) ) (func (export "ref_cast_struct") (param $i i32) - (drop (ref.cast struct (table.get (local.get $i)))) - (drop (ref.cast null struct (table.get (local.get $i)))) + (drop (ref.cast (ref struct) (table.get (local.get $i)))) + (drop (ref.cast structref (table.get (local.get $i)))) ) (func (export "ref_cast_array") (param $i i32) - (drop (ref.cast array (table.get (local.get $i)))) - (drop (ref.cast null array (table.get (local.get $i)))) + (drop (ref.cast (ref array) (table.get (local.get $i)))) + (drop (ref.cast arrayref (table.get (local.get $i)))) ) ) @@ -109,76 +109,76 @@ (table 20 (ref null struct)) (func $init - (table.set (i32.const 0) (struct.new_canon_default $t0)) - (table.set (i32.const 10) (struct.new_canon_default $t0)) - (table.set (i32.const 1) (struct.new_canon_default $t1)) - (table.set (i32.const 11) (struct.new_canon_default $t1')) - (table.set (i32.const 2) (struct.new_canon_default $t2)) - (table.set (i32.const 12) (struct.new_canon_default $t2')) - (table.set (i32.const 3) (struct.new_canon_default $t3)) - (table.set (i32.const 4) (struct.new_canon_default $t4)) + (table.set (i32.const 0) (struct.new_default $t0)) + (table.set (i32.const 10) (struct.new_default $t0)) + (table.set (i32.const 1) (struct.new_default $t1)) + (table.set (i32.const 11) (struct.new_default $t1')) + (table.set (i32.const 2) (struct.new_default $t2)) + (table.set (i32.const 12) (struct.new_default $t2')) + (table.set (i32.const 3) (struct.new_default $t3)) + (table.set (i32.const 4) (struct.new_default $t4)) ) (func (export "test-sub") (call $init) - (drop (ref.cast null $t0 (ref.null struct))) - (drop (ref.cast null $t0 (table.get (i32.const 0)))) - (drop (ref.cast null $t0 (table.get (i32.const 1)))) - (drop (ref.cast null $t0 (table.get (i32.const 2)))) - (drop (ref.cast null $t0 (table.get (i32.const 3)))) - (drop (ref.cast null $t0 (table.get (i32.const 4)))) + (drop (ref.cast (ref null $t0) (ref.null struct))) + (drop (ref.cast (ref null $t0) (table.get (i32.const 0)))) + (drop (ref.cast (ref null $t0) (table.get (i32.const 1)))) + (drop (ref.cast (ref null $t0) (table.get (i32.const 2)))) + (drop (ref.cast (ref null $t0) (table.get (i32.const 3)))) + (drop (ref.cast (ref null $t0) (table.get (i32.const 4)))) - (drop (ref.cast null $t0 (ref.null struct))) - (drop (ref.cast null $t1 (table.get (i32.const 1)))) - (drop (ref.cast null $t1 (table.get (i32.const 2)))) + (drop (ref.cast (ref null $t0) (ref.null struct))) + (drop (ref.cast (ref null $t1) (table.get (i32.const 1)))) + (drop (ref.cast (ref null $t1) (table.get (i32.const 2)))) - (drop (ref.cast null $t0 (ref.null struct))) - (drop (ref.cast null $t2 (table.get (i32.const 2)))) + (drop (ref.cast (ref null $t0) (ref.null struct))) + (drop (ref.cast (ref null $t2) (table.get (i32.const 2)))) - (drop (ref.cast null $t0 (ref.null struct))) - (drop (ref.cast null $t3 (table.get (i32.const 3)))) + (drop (ref.cast (ref null $t0) (ref.null struct))) + (drop (ref.cast (ref null $t3) (table.get (i32.const 3)))) - (drop (ref.cast null $t4 (table.get (i32.const 4)))) + (drop (ref.cast (ref null $t4) (table.get (i32.const 4)))) - (drop (ref.cast $t0 (table.get (i32.const 0)))) - (drop (ref.cast $t0 (table.get (i32.const 1)))) - (drop (ref.cast $t0 (table.get (i32.const 2)))) - (drop (ref.cast $t0 (table.get (i32.const 3)))) - (drop (ref.cast $t0 (table.get (i32.const 4)))) + (drop (ref.cast (ref $t0) (table.get (i32.const 0)))) + (drop (ref.cast (ref $t0) (table.get (i32.const 1)))) + (drop (ref.cast (ref $t0) (table.get (i32.const 2)))) + (drop (ref.cast (ref $t0) (table.get (i32.const 3)))) + (drop (ref.cast (ref $t0) (table.get (i32.const 4)))) - (drop (ref.cast $t1 (table.get (i32.const 1)))) - (drop (ref.cast $t1 (table.get (i32.const 2)))) + (drop (ref.cast (ref $t1) (table.get (i32.const 1)))) + (drop (ref.cast (ref $t1) (table.get (i32.const 2)))) - (drop (ref.cast $t2 (table.get (i32.const 2)))) + (drop (ref.cast (ref $t2) (table.get (i32.const 2)))) - (drop (ref.cast $t3 (table.get (i32.const 3)))) + (drop (ref.cast (ref $t3) (table.get (i32.const 3)))) - (drop (ref.cast $t4 (table.get (i32.const 4)))) + (drop (ref.cast (ref $t4) (table.get (i32.const 4)))) ) (func (export "test-canon") (call $init) - (drop (ref.cast $t0 (table.get (i32.const 0)))) - (drop (ref.cast $t0 (table.get (i32.const 1)))) - (drop (ref.cast $t0 (table.get (i32.const 2)))) - (drop (ref.cast $t0 (table.get (i32.const 3)))) - (drop (ref.cast $t0 (table.get (i32.const 4)))) + (drop (ref.cast (ref $t0) (table.get (i32.const 0)))) + (drop (ref.cast (ref $t0) (table.get (i32.const 1)))) + (drop (ref.cast (ref $t0) (table.get (i32.const 2)))) + (drop (ref.cast (ref $t0) (table.get (i32.const 3)))) + (drop (ref.cast (ref $t0) (table.get (i32.const 4)))) - (drop (ref.cast $t0 (table.get (i32.const 10)))) - (drop (ref.cast $t0 (table.get (i32.const 11)))) - (drop (ref.cast $t0 (table.get (i32.const 12)))) + (drop (ref.cast (ref $t0) (table.get (i32.const 10)))) + (drop (ref.cast (ref $t0) (table.get (i32.const 11)))) + (drop (ref.cast (ref $t0) (table.get (i32.const 12)))) - (drop (ref.cast $t1' (table.get (i32.const 1)))) - (drop (ref.cast $t1' (table.get (i32.const 2)))) + (drop (ref.cast (ref $t1') (table.get (i32.const 1)))) + (drop (ref.cast (ref $t1') (table.get (i32.const 2)))) - (drop (ref.cast $t1 (table.get (i32.const 11)))) - (drop (ref.cast $t1 (table.get (i32.const 12)))) + (drop (ref.cast (ref $t1) (table.get (i32.const 11)))) + (drop (ref.cast (ref $t1) (table.get (i32.const 12)))) - (drop (ref.cast $t2' (table.get (i32.const 2)))) + (drop (ref.cast (ref $t2') (table.get (i32.const 2)))) - (drop (ref.cast $t2 (table.get (i32.const 12)))) + (drop (ref.cast (ref $t2) (table.get (i32.const 12)))) ) ) diff --git a/test/core/gc/ref_eq.wast b/test/core/gc/ref_eq.wast index c8e090442..c30d7a5c1 100644 --- a/test/core/gc/ref_eq.wast +++ b/test/core/gc/ref_eq.wast @@ -15,10 +15,10 @@ (table.set (i32.const 2) (i31.new (i32.const 7))) (table.set (i32.const 3) (i31.new (i32.const 7))) (table.set (i32.const 4) (i31.new (i32.const 8))) - (table.set (i32.const 5) (struct.new_canon_default $st)) - (table.set (i32.const 6) (struct.new_canon_default $st)) - (table.set (i32.const 7) (array.new_canon_default $at (i32.const 0))) - (table.set (i32.const 8) (array.new_canon_default $at (i32.const 0))) + (table.set (i32.const 5) (struct.new_default $st)) + (table.set (i32.const 6) (struct.new_default $st)) + (table.set (i32.const 7) (array.new_default $at (i32.const 0))) + (table.set (i32.const 8) (array.new_default $at (i32.const 0))) ) (func (export "eq") (param $i i32) (param $j i32) (result i32) diff --git a/test/core/gc/ref_test.wast b/test/core/gc/ref_test.wast index da769b35b..31cf62897 100644 --- a/test/core/gc/ref_test.wast +++ b/test/core/gc/ref_test.wast @@ -17,8 +17,8 @@ (table.set $ta (i32.const 1) (ref.null struct)) (table.set $ta (i32.const 2) (ref.null none)) (table.set $ta (i32.const 3) (i31.new (i32.const 7))) - (table.set $ta (i32.const 4) (struct.new_canon_default $st)) - (table.set $ta (i32.const 5) (array.new_canon_default $at (i32.const 0))) + (table.set $ta (i32.const 4) (struct.new_default $st)) + (table.set $ta (i32.const 5) (array.new_default $at (i32.const 0))) (table.set $ta (i32.const 6) (extern.internalize (local.get $x))) (table.set $ta (i32.const 7) (extern.internalize (ref.null extern))) @@ -30,70 +30,70 @@ (table.set $te (i32.const 1) (ref.null extern)) (table.set $te (i32.const 2) (local.get $x)) (table.set $te (i32.const 3) (extern.externalize (i31.new (i32.const 8)))) - (table.set $te (i32.const 4) (extern.externalize (struct.new_canon_default $st))) + (table.set $te (i32.const 4) (extern.externalize (struct.new_default $st))) (table.set $te (i32.const 5) (extern.externalize (ref.null any))) ) (func (export "ref_test_null_data") (param $i i32) (result i32) (i32.add (ref.is_null (table.get $ta (local.get $i))) - (ref.test null none (table.get $ta (local.get $i))) + (ref.test nullref (table.get $ta (local.get $i))) ) ) (func (export "ref_test_any") (param $i i32) (result i32) (i32.add - (ref.test any (table.get $ta (local.get $i))) - (ref.test null any (table.get $ta (local.get $i))) + (ref.test (ref any) (table.get $ta (local.get $i))) + (ref.test anyref (table.get $ta (local.get $i))) ) ) (func (export "ref_test_eq") (param $i i32) (result i32) (i32.add - (ref.test eq (table.get $ta (local.get $i))) - (ref.test null eq (table.get $ta (local.get $i))) + (ref.test (ref eq) (table.get $ta (local.get $i))) + (ref.test eqref (table.get $ta (local.get $i))) ) ) (func (export "ref_test_i31") (param $i i32) (result i32) (i32.add - (ref.test i31 (table.get $ta (local.get $i))) - (ref.test null i31 (table.get $ta (local.get $i))) + (ref.test (ref i31) (table.get $ta (local.get $i))) + (ref.test i31ref (table.get $ta (local.get $i))) ) ) (func (export "ref_test_struct") (param $i i32) (result i32) (i32.add - (ref.test struct (table.get $ta (local.get $i))) - (ref.test null struct (table.get $ta (local.get $i))) + (ref.test (ref struct) (table.get $ta (local.get $i))) + (ref.test structref (table.get $ta (local.get $i))) ) ) (func (export "ref_test_array") (param $i i32) (result i32) (i32.add - (ref.test array (table.get $ta (local.get $i))) - (ref.test null array (table.get $ta (local.get $i))) + (ref.test (ref array) (table.get $ta (local.get $i))) + (ref.test arrayref (table.get $ta (local.get $i))) ) ) (func (export "ref_test_null_func") (param $i i32) (result i32) (i32.add (ref.is_null (table.get $tf (local.get $i))) - (ref.test null nofunc (table.get $tf (local.get $i))) + (ref.test (ref null nofunc) (table.get $tf (local.get $i))) ) ) (func (export "ref_test_func") (param $i i32) (result i32) (i32.add - (ref.test func (table.get $tf (local.get $i))) - (ref.test null func (table.get $tf (local.get $i))) + (ref.test (ref func) (table.get $tf (local.get $i))) + (ref.test funcref (table.get $tf (local.get $i))) ) ) (func (export "ref_test_null_extern") (param $i i32) (result i32) (i32.add (ref.is_null (table.get $te (local.get $i))) - (ref.test null noextern (table.get $te (local.get $i))) + (ref.test (ref null noextern) (table.get $te (local.get $i))) ) ) (func (export "ref_test_extern") (param $i i32) (result i32) (i32.add - (ref.test extern (table.get $te (local.get $i))) - (ref.test null extern (table.get $te (local.get $i))) + (ref.test (ref extern) (table.get $te (local.get $i))) + (ref.test externref (table.get $te (local.get $i))) ) ) ) @@ -192,105 +192,105 @@ (table 20 (ref null struct)) (func $init - (table.set (i32.const 0) (struct.new_canon_default $t0)) - (table.set (i32.const 10) (struct.new_canon_default $t0)) - (table.set (i32.const 1) (struct.new_canon_default $t1)) - (table.set (i32.const 11) (struct.new_canon_default $t1')) - (table.set (i32.const 2) (struct.new_canon_default $t2)) - (table.set (i32.const 12) (struct.new_canon_default $t2')) - (table.set (i32.const 3) (struct.new_canon_default $t3)) - (table.set (i32.const 4) (struct.new_canon_default $t4)) + (table.set (i32.const 0) (struct.new_default $t0)) + (table.set (i32.const 10) (struct.new_default $t0)) + (table.set (i32.const 1) (struct.new_default $t1)) + (table.set (i32.const 11) (struct.new_default $t1')) + (table.set (i32.const 2) (struct.new_default $t2)) + (table.set (i32.const 12) (struct.new_default $t2')) + (table.set (i32.const 3) (struct.new_default $t3)) + (table.set (i32.const 4) (struct.new_default $t4)) ) (func (export "test-sub") (call $init) (block $l ;; must hold - (br_if $l (i32.eqz (ref.test null $t0 (ref.null struct)))) - (br_if $l (i32.eqz (ref.test null $t0 (ref.null $t0)))) - (br_if $l (i32.eqz (ref.test null $t0 (ref.null $t1)))) - (br_if $l (i32.eqz (ref.test null $t0 (ref.null $t2)))) - (br_if $l (i32.eqz (ref.test null $t0 (ref.null $t3)))) - (br_if $l (i32.eqz (ref.test null $t0 (ref.null $t4)))) - (br_if $l (i32.eqz (ref.test null $t0 (table.get (i32.const 0))))) - (br_if $l (i32.eqz (ref.test null $t0 (table.get (i32.const 1))))) - (br_if $l (i32.eqz (ref.test null $t0 (table.get (i32.const 2))))) - (br_if $l (i32.eqz (ref.test null $t0 (table.get (i32.const 3))))) - (br_if $l (i32.eqz (ref.test null $t0 (table.get (i32.const 4))))) - - (br_if $l (i32.eqz (ref.test null $t1 (ref.null struct)))) - (br_if $l (i32.eqz (ref.test null $t1 (ref.null $t0)))) - (br_if $l (i32.eqz (ref.test null $t1 (ref.null $t1)))) - (br_if $l (i32.eqz (ref.test null $t1 (ref.null $t2)))) - (br_if $l (i32.eqz (ref.test null $t1 (ref.null $t3)))) - (br_if $l (i32.eqz (ref.test null $t1 (ref.null $t4)))) - (br_if $l (i32.eqz (ref.test null $t1 (table.get (i32.const 1))))) - (br_if $l (i32.eqz (ref.test null $t1 (table.get (i32.const 2))))) - - (br_if $l (i32.eqz (ref.test null $t2 (ref.null struct)))) - (br_if $l (i32.eqz (ref.test null $t2 (ref.null $t0)))) - (br_if $l (i32.eqz (ref.test null $t2 (ref.null $t1)))) - (br_if $l (i32.eqz (ref.test null $t2 (ref.null $t2)))) - (br_if $l (i32.eqz (ref.test null $t2 (ref.null $t3)))) - (br_if $l (i32.eqz (ref.test null $t2 (ref.null $t4)))) - (br_if $l (i32.eqz (ref.test null $t2 (table.get (i32.const 2))))) - - (br_if $l (i32.eqz (ref.test null $t3 (ref.null struct)))) - (br_if $l (i32.eqz (ref.test null $t3 (ref.null $t0)))) - (br_if $l (i32.eqz (ref.test null $t3 (ref.null $t1)))) - (br_if $l (i32.eqz (ref.test null $t3 (ref.null $t2)))) - (br_if $l (i32.eqz (ref.test null $t3 (ref.null $t3)))) - (br_if $l (i32.eqz (ref.test null $t3 (ref.null $t4)))) - (br_if $l (i32.eqz (ref.test null $t3 (table.get (i32.const 3))))) - - (br_if $l (i32.eqz (ref.test null $t4 (ref.null struct)))) - (br_if $l (i32.eqz (ref.test null $t4 (ref.null $t0)))) - (br_if $l (i32.eqz (ref.test null $t4 (ref.null $t1)))) - (br_if $l (i32.eqz (ref.test null $t4 (ref.null $t2)))) - (br_if $l (i32.eqz (ref.test null $t4 (ref.null $t3)))) - (br_if $l (i32.eqz (ref.test null $t4 (ref.null $t4)))) - (br_if $l (i32.eqz (ref.test null $t4 (table.get (i32.const 4))))) - - (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 0))))) - (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 1))))) - (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 2))))) - (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 3))))) - (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 4))))) - - (br_if $l (i32.eqz (ref.test $t1 (table.get (i32.const 1))))) - (br_if $l (i32.eqz (ref.test $t1 (table.get (i32.const 2))))) - - (br_if $l (i32.eqz (ref.test $t2 (table.get (i32.const 2))))) - - (br_if $l (i32.eqz (ref.test $t3 (table.get (i32.const 3))))) - - (br_if $l (i32.eqz (ref.test $t4 (table.get (i32.const 4))))) + (br_if $l (i32.eqz (ref.test (ref null $t0) (ref.null struct)))) + (br_if $l (i32.eqz (ref.test (ref null $t0) (ref.null $t0)))) + (br_if $l (i32.eqz (ref.test (ref null $t0) (ref.null $t1)))) + (br_if $l (i32.eqz (ref.test (ref null $t0) (ref.null $t2)))) + (br_if $l (i32.eqz (ref.test (ref null $t0) (ref.null $t3)))) + (br_if $l (i32.eqz (ref.test (ref null $t0) (ref.null $t4)))) + (br_if $l (i32.eqz (ref.test (ref null $t0) (table.get (i32.const 0))))) + (br_if $l (i32.eqz (ref.test (ref null $t0) (table.get (i32.const 1))))) + (br_if $l (i32.eqz (ref.test (ref null $t0) (table.get (i32.const 2))))) + (br_if $l (i32.eqz (ref.test (ref null $t0) (table.get (i32.const 3))))) + (br_if $l (i32.eqz (ref.test (ref null $t0) (table.get (i32.const 4))))) + + (br_if $l (i32.eqz (ref.test (ref null $t1) (ref.null struct)))) + (br_if $l (i32.eqz (ref.test (ref null $t1) (ref.null $t0)))) + (br_if $l (i32.eqz (ref.test (ref null $t1) (ref.null $t1)))) + (br_if $l (i32.eqz (ref.test (ref null $t1) (ref.null $t2)))) + (br_if $l (i32.eqz (ref.test (ref null $t1) (ref.null $t3)))) + (br_if $l (i32.eqz (ref.test (ref null $t1) (ref.null $t4)))) + (br_if $l (i32.eqz (ref.test (ref null $t1) (table.get (i32.const 1))))) + (br_if $l (i32.eqz (ref.test (ref null $t1) (table.get (i32.const 2))))) + + (br_if $l (i32.eqz (ref.test (ref null $t2) (ref.null struct)))) + (br_if $l (i32.eqz (ref.test (ref null $t2) (ref.null $t0)))) + (br_if $l (i32.eqz (ref.test (ref null $t2) (ref.null $t1)))) + (br_if $l (i32.eqz (ref.test (ref null $t2) (ref.null $t2)))) + (br_if $l (i32.eqz (ref.test (ref null $t2) (ref.null $t3)))) + (br_if $l (i32.eqz (ref.test (ref null $t2) (ref.null $t4)))) + (br_if $l (i32.eqz (ref.test (ref null $t2) (table.get (i32.const 2))))) + + (br_if $l (i32.eqz (ref.test (ref null $t3) (ref.null struct)))) + (br_if $l (i32.eqz (ref.test (ref null $t3) (ref.null $t0)))) + (br_if $l (i32.eqz (ref.test (ref null $t3) (ref.null $t1)))) + (br_if $l (i32.eqz (ref.test (ref null $t3) (ref.null $t2)))) + (br_if $l (i32.eqz (ref.test (ref null $t3) (ref.null $t3)))) + (br_if $l (i32.eqz (ref.test (ref null $t3) (ref.null $t4)))) + (br_if $l (i32.eqz (ref.test (ref null $t3) (table.get (i32.const 3))))) + + (br_if $l (i32.eqz (ref.test (ref null $t4) (ref.null struct)))) + (br_if $l (i32.eqz (ref.test (ref null $t4) (ref.null $t0)))) + (br_if $l (i32.eqz (ref.test (ref null $t4) (ref.null $t1)))) + (br_if $l (i32.eqz (ref.test (ref null $t4) (ref.null $t2)))) + (br_if $l (i32.eqz (ref.test (ref null $t4) (ref.null $t3)))) + (br_if $l (i32.eqz (ref.test (ref null $t4) (ref.null $t4)))) + (br_if $l (i32.eqz (ref.test (ref null $t4) (table.get (i32.const 4))))) + + (br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 0))))) + (br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 1))))) + (br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 2))))) + (br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 3))))) + (br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 4))))) + + (br_if $l (i32.eqz (ref.test (ref $t1) (table.get (i32.const 1))))) + (br_if $l (i32.eqz (ref.test (ref $t1) (table.get (i32.const 2))))) + + (br_if $l (i32.eqz (ref.test (ref $t2) (table.get (i32.const 2))))) + + (br_if $l (i32.eqz (ref.test (ref $t3) (table.get (i32.const 3))))) + + (br_if $l (i32.eqz (ref.test (ref $t4) (table.get (i32.const 4))))) ;; must not hold - (br_if $l (ref.test $t0 (ref.null struct))) - (br_if $l (ref.test $t1 (ref.null struct))) - (br_if $l (ref.test $t2 (ref.null struct))) - (br_if $l (ref.test $t3 (ref.null struct))) - (br_if $l (ref.test $t4 (ref.null struct))) - - (br_if $l (ref.test $t1 (table.get (i32.const 0)))) - (br_if $l (ref.test $t1 (table.get (i32.const 3)))) - (br_if $l (ref.test $t1 (table.get (i32.const 4)))) - - (br_if $l (ref.test $t2 (table.get (i32.const 0)))) - (br_if $l (ref.test $t2 (table.get (i32.const 1)))) - (br_if $l (ref.test $t2 (table.get (i32.const 3)))) - (br_if $l (ref.test $t2 (table.get (i32.const 4)))) - - (br_if $l (ref.test $t3 (table.get (i32.const 0)))) - (br_if $l (ref.test $t3 (table.get (i32.const 1)))) - (br_if $l (ref.test $t3 (table.get (i32.const 2)))) - (br_if $l (ref.test $t3 (table.get (i32.const 4)))) - - (br_if $l (ref.test $t4 (table.get (i32.const 0)))) - (br_if $l (ref.test $t4 (table.get (i32.const 1)))) - (br_if $l (ref.test $t4 (table.get (i32.const 2)))) - (br_if $l (ref.test $t4 (table.get (i32.const 3)))) + (br_if $l (ref.test (ref $t0) (ref.null struct))) + (br_if $l (ref.test (ref $t1) (ref.null struct))) + (br_if $l (ref.test (ref $t2) (ref.null struct))) + (br_if $l (ref.test (ref $t3) (ref.null struct))) + (br_if $l (ref.test (ref $t4) (ref.null struct))) + + (br_if $l (ref.test (ref $t1) (table.get (i32.const 0)))) + (br_if $l (ref.test (ref $t1) (table.get (i32.const 3)))) + (br_if $l (ref.test (ref $t1) (table.get (i32.const 4)))) + + (br_if $l (ref.test (ref $t2) (table.get (i32.const 0)))) + (br_if $l (ref.test (ref $t2) (table.get (i32.const 1)))) + (br_if $l (ref.test (ref $t2) (table.get (i32.const 3)))) + (br_if $l (ref.test (ref $t2) (table.get (i32.const 4)))) + + (br_if $l (ref.test (ref $t3) (table.get (i32.const 0)))) + (br_if $l (ref.test (ref $t3) (table.get (i32.const 1)))) + (br_if $l (ref.test (ref $t3) (table.get (i32.const 2)))) + (br_if $l (ref.test (ref $t3) (table.get (i32.const 4)))) + + (br_if $l (ref.test (ref $t4) (table.get (i32.const 0)))) + (br_if $l (ref.test (ref $t4) (table.get (i32.const 1)))) + (br_if $l (ref.test (ref $t4) (table.get (i32.const 2)))) + (br_if $l (ref.test (ref $t4) (table.get (i32.const 3)))) (return) ) @@ -300,25 +300,25 @@ (func (export "test-canon") (call $init) (block $l - (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 0))))) - (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 1))))) - (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 2))))) - (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 3))))) - (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 4))))) + (br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 0))))) + (br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 1))))) + (br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 2))))) + (br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 3))))) + (br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 4))))) - (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 10))))) - (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 11))))) - (br_if $l (i32.eqz (ref.test $t0 (table.get (i32.const 12))))) + (br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 10))))) + (br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 11))))) + (br_if $l (i32.eqz (ref.test (ref $t0) (table.get (i32.const 12))))) - (br_if $l (i32.eqz (ref.test $t1' (table.get (i32.const 1))))) - (br_if $l (i32.eqz (ref.test $t1' (table.get (i32.const 2))))) + (br_if $l (i32.eqz (ref.test (ref $t1') (table.get (i32.const 1))))) + (br_if $l (i32.eqz (ref.test (ref $t1') (table.get (i32.const 2))))) - (br_if $l (i32.eqz (ref.test $t1 (table.get (i32.const 11))))) - (br_if $l (i32.eqz (ref.test $t1 (table.get (i32.const 12))))) + (br_if $l (i32.eqz (ref.test (ref $t1) (table.get (i32.const 11))))) + (br_if $l (i32.eqz (ref.test (ref $t1) (table.get (i32.const 12))))) - (br_if $l (i32.eqz (ref.test $t2' (table.get (i32.const 2))))) + (br_if $l (i32.eqz (ref.test (ref $t2') (table.get (i32.const 2))))) - (br_if $l (i32.eqz (ref.test $t2 (table.get (i32.const 12))))) + (br_if $l (i32.eqz (ref.test (ref $t2) (table.get (i32.const 12))))) (return) ) diff --git a/test/core/gc/struct.wast b/test/core/gc/struct.wast index bbd2c94a0..e06fb8a25 100644 --- a/test/core/gc/struct.wast +++ b/test/core/gc/struct.wast @@ -55,18 +55,18 @@ (module (type $vec (struct (field f32) (field $y (mut f32)) (field $z f32))) - (global (ref $vec) (struct.new_canon $vec (f32.const 1) (f32.const 2) (f32.const 3))) - (global (ref $vec) (struct.new_canon_default $vec)) + (global (ref $vec) (struct.new $vec (f32.const 1) (f32.const 2) (f32.const 3))) + (global (ref $vec) (struct.new_default $vec)) (func (export "new") (result anyref) - (struct.new_canon_default $vec) + (struct.new_default $vec) ) (func $get_0 (param $v (ref $vec)) (result f32) (struct.get $vec 0 (local.get $v)) ) (func (export "get_0") (result f32) - (call $get_0 (struct.new_canon_default $vec)) + (call $get_0 (struct.new_default $vec)) ) (func $set_get_y (param $v (ref $vec)) (param $y f32) (result f32) @@ -74,7 +74,7 @@ (struct.get $vec $y (local.get $v)) ) (func (export "set_get_y") (param $y f32) (result f32) - (call $set_get_y (struct.new_canon_default $vec) (local.get $y)) + (call $set_get_y (struct.new_default $vec) (local.get $y)) ) (func $set_get_1 (param $v (ref $vec)) (param $y f32) (result f32) @@ -82,7 +82,7 @@ (struct.get $vec $y (local.get $v)) ) (func (export "set_get_1") (param $y f32) (result f32) - (call $set_get_1 (struct.new_canon_default $vec) (local.get $y)) + (call $set_get_1 (struct.new_default $vec) (local.get $y)) ) ) diff --git a/test/core/gc/type-subtyping.wast b/test/core/gc/type-subtyping.wast index fc5d3d6b3..94197027a 100644 --- a/test/core/gc/type-subtyping.wast +++ b/test/core/gc/type-subtyping.wast @@ -133,12 +133,12 @@ (block (result (ref null $t1)) (call_indirect (type $t1) (i32.const 2))) (block (result (ref null $t2)) (call_indirect (type $t2) (i32.const 2))) - (block (result (ref null $t0)) (ref.cast $t0 (table.get (i32.const 0)))) - (block (result (ref null $t0)) (ref.cast $t0 (table.get (i32.const 1)))) - (block (result (ref null $t0)) (ref.cast $t0 (table.get (i32.const 2)))) - (block (result (ref null $t1)) (ref.cast $t1 (table.get (i32.const 1)))) - (block (result (ref null $t1)) (ref.cast $t1 (table.get (i32.const 2)))) - (block (result (ref null $t2)) (ref.cast $t2 (table.get (i32.const 2)))) + (block (result (ref null $t0)) (ref.cast (ref $t0) (table.get (i32.const 0)))) + (block (result (ref null $t0)) (ref.cast (ref $t0) (table.get (i32.const 1)))) + (block (result (ref null $t0)) (ref.cast (ref $t0) (table.get (i32.const 2)))) + (block (result (ref null $t1)) (ref.cast (ref $t1) (table.get (i32.const 1)))) + (block (result (ref null $t1)) (ref.cast (ref $t1) (table.get (i32.const 2)))) + (block (result (ref null $t2)) (ref.cast (ref $t2) (table.get (i32.const 2)))) (br 0) ) @@ -156,15 +156,15 @@ ) (func (export "fail4") - (ref.cast $t1 (table.get (i32.const 0))) + (ref.cast (ref $t1) (table.get (i32.const 0))) (br 0) ) (func (export "fail5") - (ref.cast $t2 (table.get (i32.const 0))) + (ref.cast (ref $t2) (table.get (i32.const 0))) (br 0) ) (func (export "fail6") - (ref.cast $t2 (table.get (i32.const 1))) + (ref.cast (ref $t2) (table.get (i32.const 1))) (br 0) ) ) @@ -192,11 +192,11 @@ ) (func (export "fail3") - (ref.cast $t1 (table.get (i32.const 1))) + (ref.cast (ref $t1) (table.get (i32.const 1))) (drop) ) (func (export "fail4") - (ref.cast $t2 (table.get (i32.const 0))) + (ref.cast (ref $t2) (table.get (i32.const 0))) (drop) ) )