diff --git a/interpreter/binary/decode.ml b/interpreter/binary/decode.ml index bd18dad73..afe6f0468 100644 --- a/interpreter/binary/decode.ml +++ b/interpreter/binary/decode.ml @@ -543,20 +543,20 @@ let rec instr s = | 0xfb as b -> (match vu32 s with - | 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 (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 (at var s) + | 0x01l -> struct_new + | 0x02l -> struct_new_default + | 0x03l -> struct_get (at var s) + | 0x04l -> struct_get_s (at var s) + | 0x05l -> struct_get_u (at var s) + | 0x06l -> struct_set (at var s) + + | 0x11l -> array_new + | 0x12l -> array_new_default + | 0x13l -> array_get + | 0x14l -> array_get_s + | 0x15l -> array_get_u + | 0x16l -> array_set + | 0x17l -> array_len | 0x20l -> i31_new | 0x21l -> i31_get_s diff --git a/interpreter/binary/encode.ml b/interpreter/binary/encode.ml index 48928757b..eadc7fd95 100644 --- a/interpreter/binary/encode.ml +++ b/interpreter/binary/encode.ml @@ -315,20 +315,20 @@ struct | I31Get SX -> op 0xfb; op 0x21 | I31Get ZX -> op 0xfb; op 0x22 - | StructNew (x, Explicit) -> op 0xfb; op 0x01; var x - | StructNew (x, Implicit) -> op 0xfb; op 0x02; var x - | StructGet (x, y, None) -> op 0xfb; op 0x03; var x; var y - | StructGet (x, y, Some SX) -> op 0xfb; op 0x04; var x; var y - | StructGet (x, y, Some ZX) -> op 0xfb; op 0x05; var x; var y - | StructSet (x, y) -> op 0xfb; op 0x06; var x; var y - - | ArrayNew (x, Explicit) -> op 0xfb; op 0x11; var x - | ArrayNew (x, Implicit) -> op 0xfb; op 0x12; var x - | ArrayGet (x, None) -> op 0xfb; op 0x13; var x - | ArrayGet (x, Some SX) -> op 0xfb; op 0x14; var x - | ArrayGet (x, Some ZX) -> op 0xfb; op 0x15; var x - | ArraySet x -> op 0xfb; op 0x16; var x - | ArrayLen x -> op 0xfb; op 0x17; var x + | StructNew Explicit -> op 0xfb; op 0x01 + | StructNew Implicit -> op 0xfb; op 0x02 + | StructGet (x, None) -> op 0xfb; op 0x03; var x + | StructGet (x, Some SX) -> op 0xfb; op 0x04; var x + | StructGet (x, Some ZX) -> op 0xfb; op 0x05; var x + | StructSet x -> op 0xfb; op 0x06; var x + + | ArrayNew Explicit -> op 0xfb; op 0x11 + | ArrayNew Implicit -> op 0xfb; op 0x12 + | ArrayGet None -> op 0xfb; op 0x13 + | ArrayGet (Some SX) -> op 0xfb; op 0x14 + | ArrayGet (Some ZX) -> op 0xfb; op 0x15 + | ArraySet -> op 0xfb; op 0x16 + | ArrayLen -> op 0xfb; op 0x17 | RttCanon x -> op 0xfb; op 0x30; var x | RttSub x -> op 0xfb; op 0x31; var x diff --git a/interpreter/exec/eval.ml b/interpreter/exec/eval.ml index 1a87a611e..c3a1913ad 100644 --- a/interpreter/exec/eval.ml +++ b/interpreter/exec/eval.ml @@ -98,8 +98,6 @@ let data (inst : module_inst) x = lookup "data segment" inst.datas x let local (frame : frame) x = lookup "local" frame.locals x let func_type (inst : module_inst) x = as_func_def_type (def_of (type_ inst x)) -let struct_type (inst : module_inst) x = as_struct_def_type (def_of (type_ inst x)) -let array_type (inst : module_inst) x = as_array_def_type (def_of (type_ inst x)) let any_ref inst x i at = try Table.load (table inst x) i with Table.Bounds -> @@ -670,85 +668,93 @@ let rec step (c : config) : config = | I31Get ext, Ref (I31.I31Ref i) :: vs' -> Num (I32 (I31.to_i32 ext i)) :: vs', [] - | StructNew (x, initop), Ref (Rtt.RttRef rtt) :: vs' -> - let StructType fts = struct_type c.frame.inst x in - let args, vs'' = - match initop with - | Explicit -> - let args, vs'' = split (List.length fts) vs' e.at in - List.rev args, vs'' - | Implicit -> - let ts = List.map unpacked_field_type fts in - try List.map default_value ts, vs' - with Failure _ -> Crash.error e.at "non-defaultable type" - in - let data = - try Data.alloc_struct (type_ c.frame.inst x) rtt args - with Failure _ -> Crash.error e.at "type mismatch packing value" - in Ref (Data.DataRef data) :: vs'', [] + | StructNew initop, Ref (Rtt.RttRef rtt) :: vs' -> + (match Rtt.def_type_of rtt with + | StructDefType (StructType fts) -> + let args, vs'' = + match initop with + | Explicit -> + let args, vs'' = split (List.length fts) vs' e.at in + List.rev args, vs'' + | Implicit -> + let ts = List.map unpacked_field_type fts in + try List.map default_value ts, vs' + with Failure _ -> Crash.error e.at "non-defaultable type" + in + let data = + try Data.alloc_struct (Rtt.type_inst_of rtt) rtt args + with Failure _ -> Crash.error e.at "type mismatch packing value" + in Ref (Data.DataRef data) :: vs'', [] + | _ -> + Crash.error e.at "wrong RTT type" + ) - | StructGet (x, y, exto), Ref (NullRef _) :: vs' -> + | StructGet (x, exto), Ref (NullRef _) :: vs' -> vs', [Trapping "null structure reference" @@ e.at] - | StructGet (x, y, exto), Ref Data.(DataRef (Struct (_, _, fs))) :: vs' -> + | StructGet (x, exto), Ref Data.(DataRef (Struct (_, _, fs))) :: vs' -> let f = - try Lib.List32.nth fs y.it - with Failure _ -> Crash.error y.at "undefined field" + try Lib.List32.nth fs x.it + with Failure _ -> Crash.error x.at "undefined field" in (try Data.read_field f exto :: vs', [] with Failure _ -> Crash.error e.at "type mismatch reading field") - | StructSet (x, y), v :: Ref (NullRef _) :: vs' -> + | StructSet x, v :: Ref (NullRef _) :: vs' -> vs', [Trapping "null structure reference" @@ e.at] - | StructSet (x, y), v :: Ref Data.(DataRef (Struct (_, _, fs))) :: vs' -> + | StructSet x, v :: Ref Data.(DataRef (Struct (_, _, fs))) :: vs' -> let f = - try Lib.List32.nth fs y.it - with Failure _ -> Crash.error y.at "undefined field" + try Lib.List32.nth fs x.it + with Failure _ -> Crash.error x.at "undefined field" in (try Data.write_field f v; vs', [] with Failure _ -> Crash.error e.at "type mismatch writing field") - | ArrayNew (x, initop), Ref (Rtt.RttRef rtt) :: Num (I32 n) :: vs' -> - let ArrayType (FieldType (st, _)) = array_type c.frame.inst x in - let arg, vs'' = - match initop with - | Explicit -> List.hd vs', List.tl vs' - | Implicit -> - try default_value (unpacked_storage_type st), vs' - with Failure _ -> Crash.error e.at "non-defaultable type" - in - let data = - try Data.alloc_array (type_ c.frame.inst x) rtt n arg - with Failure _ -> Crash.error e.at "type mismatch packing value" - in Ref (Data.DataRef data) :: vs'', [] + | ArrayNew initop, Ref (Rtt.RttRef rtt) :: Num (I32 n) :: vs' -> + (match Rtt.def_type_of rtt with + | ArrayDefType (ArrayType (FieldType (st, _))) -> + let arg, vs'' = + match initop with + | Explicit -> List.hd vs', List.tl vs' + | Implicit -> + try default_value (unpacked_storage_type st), vs' + with Failure _ -> Crash.error e.at "non-defaultable type" + in + let data = + try Data.alloc_array (Rtt.type_inst_of rtt) rtt n arg + with Failure _ -> Crash.error e.at "type mismatch packing value" + in Ref (Data.DataRef data) :: vs'', [] + | _ -> + Crash.error e.at "wrong RTT type" + ) - | ArrayGet (x, exto), Num (I32 i) :: Ref (NullRef _) :: vs' -> + | ArrayGet exto, Num (I32 i) :: Ref (NullRef _) :: vs' -> vs', [Trapping "null array reference" @@ e.at] - | ArrayGet (x, exto), Num (I32 i) :: Ref Data.(DataRef (Array (_, _, fs))) :: vs' + | ArrayGet exto, Num (I32 i) :: Ref Data.(DataRef (Array (_, _, fs))) :: vs' when I32.ge_u i (Lib.List32.length fs) -> vs', [Trapping "out of bounds array access" @@ e.at] - | ArrayGet (x, exto), Num (I32 i) :: Ref Data.(DataRef (Array (_, _, fs))) :: vs' -> + | ArrayGet exto, Num (I32 i) :: Ref Data.(DataRef (Array (_, _, fs))) :: vs' -> (try Data.read_field (Lib.List32.nth fs i) exto :: vs', [] with Failure _ -> Crash.error e.at "type mismatch reading array") - | ArraySet x, v :: Num (I32 i) :: Ref (NullRef _) :: vs' -> + | ArraySet, v :: Num (I32 i) :: Ref (NullRef _) :: vs' -> vs', [Trapping "null array reference" @@ e.at] - | ArraySet x, v :: Num (I32 i) :: Ref (Data.DataRef (Data.Array (_, _, fs))) :: vs' + | ArraySet, v :: Num (I32 i) :: Ref (Data.DataRef (Data.Array (_, _, fs))) :: vs' when I32.ge_u i (Lib.List32.length fs) -> vs', [Trapping "out of bounds array access" @@ e.at] - | ArraySet x, v :: Num (I32 i) :: Ref (Data.DataRef (Data.Array (_, _, fs))) :: vs' -> + | ArraySet, v :: Num (I32 i) :: Ref (Data.DataRef (Data.Array (_, _, fs))) :: vs' -> (try Data.write_field (Lib.List32.nth fs i) v; vs', [] with Failure _ -> Crash.error e.at "type mismatch writing array") - | ArrayLen x, Ref (NullRef _) :: vs' -> + | ArrayLen, Ref (NullRef _) :: vs' -> vs', [Trapping "null array reference" @@ e.at] - | ArrayLen x, Ref (Data.DataRef (Data.Array (_, _, svs))) :: vs' -> + | ArrayLen, Ref (Data.DataRef (Data.Array (_, _, svs))) :: vs' -> Num (I32 (Lib.List32.length svs)) :: vs', [] | RttCanon x, vs -> diff --git a/interpreter/syntax/ast.ml b/interpreter/syntax/ast.ml index e7bca1cc1..cfa2427f4 100644 --- a/interpreter/syntax/ast.ml +++ b/interpreter/syntax/ast.ml @@ -132,13 +132,13 @@ and instr' = | RefEq (* reference equality *) | I31New (* allocate scalar *) | I31Get of extension (* read scalar *) - | StructNew of idx * initop (* allocate structure *) - | StructGet of idx * idx * extension option (* read structure field *) - | StructSet of idx * idx (* write structure field *) - | ArrayNew of idx * initop (* allocate array *) - | ArrayGet of idx * extension option (* read array slot *) - | ArraySet of idx (* write array slot *) - | ArrayLen of idx (* read array length *) + | StructNew of initop (* allocate structure *) + | StructGet of idx * extension option (* read structure field *) + | StructSet of idx (* write structure field *) + | ArrayNew of initop (* allocate array *) + | ArrayGet of extension option (* read array slot *) + | ArraySet (* write array slot *) + | ArrayLen (* read array length *) | RttCanon of idx (* allocate RTT *) | RttSub of idx (* alllocate sub-RTT *) diff --git a/interpreter/syntax/free.ml b/interpreter/syntax/free.ml index f8ae13219..b3c1b7ab7 100644 --- a/interpreter/syntax/free.ml +++ b/interpreter/syntax/free.ml @@ -114,9 +114,8 @@ let rec instr (e : instr) = | RefNull t -> heap_type t | RefFunc x -> funcs (idx x) | I31New | I31Get _ -> empty - | StructNew (x, _) | ArrayNew (x, _) -> types (idx x) - | StructGet (x, _, _) | StructSet (x, _) -> types (idx x) - | ArrayGet (x, _) | ArraySet x | ArrayLen x -> types (idx x) + | StructNew _ | StructGet _ | StructSet _ -> empty + | ArrayNew _ | ArrayGet _ | ArraySet | ArrayLen -> empty | RttCanon x | RttSub x -> types (idx x) | Const _ | Test _ | Compare _ | Unary _ | Binary _ | Convert _ -> empty | Block (bt, es) | Loop (bt, es) -> block_type bt ++ block es diff --git a/interpreter/syntax/operators.ml b/interpreter/syntax/operators.ml index d2a87c82c..5bcff35f1 100644 --- a/interpreter/syntax/operators.ml +++ b/interpreter/syntax/operators.ml @@ -119,19 +119,19 @@ let ref_eq = RefEq let i31_new = I31New let i31_get_u = I31Get ZX let i31_get_s = I31Get SX -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 x = ArrayNew (x, Explicit) -let array_new_default x = ArrayNew (x, Implicit) -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) -let array_set x = ArraySet x -let array_len x = ArrayLen x +let struct_new = StructNew Explicit +let struct_new_default = StructNew Implicit +let struct_get x = StructGet (x, None) +let struct_get_u x = StructGet (x, Some ZX) +let struct_get_s x = StructGet (x, Some SX) +let struct_set x = StructSet x +let array_new = ArrayNew Explicit +let array_new_default = ArrayNew Implicit +let array_get = ArrayGet None +let array_get_u = ArrayGet (Some ZX) +let array_get_s = ArrayGet (Some SX) +let array_set = ArraySet +let array_len = ArrayLen let rtt_canon x = RttCanon x let rtt_sub x = RttSub x diff --git a/interpreter/text/arrange.ml b/interpreter/text/arrange.ml index 2c4d33c17..7826466bf 100644 --- a/interpreter/text/arrange.ml +++ b/interpreter/text/arrange.ml @@ -323,14 +323,14 @@ let rec instr e = | RefEq -> "ref.eq", [] | I31New -> "i31.new", [] | I31Get ext -> "i31.get" ^ extension ext, [] - | 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" ^ initop op ^ " " ^ var x, [] - | ArrayGet (x, exto) -> "array.get" ^ opt_s extension exto ^ " " ^ var x, [] - | ArraySet x -> "array.set " ^ var x, [] - | ArrayLen x -> "array.len " ^ var x, [] + | StructNew op -> "struct.new" ^ initop op, [] + | StructGet (x, exto) -> + "struct.get" ^ opt_s extension exto ^ " " ^ var x, [] + | StructSet x -> "struct.set " ^ var x, [] + | ArrayNew op -> "array.new" ^ initop op, [] + | ArrayGet exto -> "array.get" ^ opt_s extension exto, [] + | ArraySet -> "array.set", [] + | ArrayLen -> "array.len", [] | RttCanon x -> "rtt.canon " ^ var x, [] | RttSub x -> "rtt.sub " ^ var x, [] | Const n -> constop n ^ " " ^ num n, [] diff --git a/interpreter/text/parser.mly b/interpreter/text/parser.mly index f648a4063..558e54330 100644 --- a/interpreter/text/parser.mly +++ b/interpreter/text/parser.mly @@ -252,9 +252,9 @@ let inline_func_type_explicit (c : context) x ft at = %token REF_TEST REF_CAST %token Ast.instr'> BR_CAST BR_CAST_FAIL %token I31_GET -%token Ast.idx -> Ast.instr'> STRUCT_GET -%token Ast.instr'> ARRAY_GET -%token Ast.instr'> STRUCT_NEW ARRAY_NEW +%token Ast.instr'> STRUCT_GET +%token ARRAY_GET +%token STRUCT_NEW ARRAY_NEW %token Ast.instr' * Value.num> CONST %token UNARY %token BINARY @@ -507,13 +507,13 @@ plain_instr : | REF_EQ { fun c -> ref_eq } | I31_NEW { fun c -> i31_new } | I31_GET { fun c -> $1 } - | STRUCT_NEW var { fun c -> $1 ($2 c type_) } - | 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_GET var { fun c -> $1 ($2 c type_) } - | ARRAY_SET var { fun c -> array_set ($2 c type_) } - | ARRAY_LEN var { fun c -> array_len ($2 c type_) } + | STRUCT_NEW { fun c -> $1 } + | STRUCT_GET var { fun c -> $1 ($2 c field) } + | STRUCT_SET var { fun c -> struct_set ($2 c field) } + | ARRAY_NEW { fun c -> $1 } + | ARRAY_GET { fun c -> $1 } + | ARRAY_SET { fun c -> array_set } + | ARRAY_LEN { fun c -> array_len } | RTT_CANON var { fun c -> rtt_canon ($2 c type_) } | RTT_SUB var { fun c -> rtt_sub ($2 c type_) } | CONST num { fun c -> fst (num $1 $2) } diff --git a/interpreter/valid/valid.ml b/interpreter/valid/valid.ml index 561c7fc28..33957c82d 100644 --- a/interpreter/valid/valid.ml +++ b/interpreter/valid/valid.ml @@ -229,6 +229,16 @@ let peek_rtt i s at = ("type mismatch: instruction requires RTT reference type" ^ " but stack has " ^ string_of_value_type (RefType rt)) +let peek_def kind i s at = + let rt = peek_ref i s at in + match rt with + | _, DefHeapType (SynVar x) -> Some x + | _, BotHeapType -> None + | _ -> + error at + ("type mismatch: instruction requires " ^ kind ^ " reference type" ^ + " but stack has " ^ string_of_value_type (RefType rt)) + (* Type Synthesis *) @@ -490,16 +500,12 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : op_type ts1 --> ts2 | CallRef -> - (match peek_ref 0 s e.at with - | (nul, DefHeapType (SynVar x)) -> + (match peek_def "function" 0 s e.at with + | Some x -> let FuncType (ts1, ts2) = func_type c (x @@ e.at) in - (ts1 @ [RefType (nul, DefHeapType (SynVar x))]) --> ts2 - | (_, BotHeapType) as rt -> - [RefType rt] -->... [] - | rt -> - error e.at - ("type mismatch: instruction requires function reference type" ^ - " but stack has " ^ string_of_value_type (RefType rt)) + (ts1 @ [RefType (Nullable, DefHeapType (SynVar x))]) --> ts2 + | None -> + [RefType (Nullable, BotHeapType)] -->... [] ) | CallIndirect (x, y) -> @@ -511,25 +517,21 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : op_type (ts1 @ [NumType I32Type]) --> ts2 | ReturnCallRef -> - (match peek_ref 0 s e.at with - | (nul, DefHeapType (SynVar x)) -> + (match peek_def "function" 0 s e.at with + | Some x -> let FuncType (ts1, ts2) = func_type c (x @@ e.at) in require (match_result_type c.types [] ts2 c.results) e.at ("type mismatch: current function requires result type " ^ string_of_result_type c.results ^ " but callee returns " ^ string_of_result_type ts2); - (ts1 @ [RefType (nul, DefHeapType (SynVar x))]) -->... [] - | (_, BotHeapType) as rt -> - [RefType rt] -->... [] - | rt -> - error e.at - ("type mismatch: instruction requires function reference type" ^ - " but stack has " ^ string_of_value_type (RefType rt)) + (ts1 @ [RefType (Nullable, DefHeapType (SynVar x))]) -->... [] + | None -> + [RefType (Nullable, BotHeapType)] -->... [] ) | FuncBind x -> - (match peek_ref 0 s e.at with - | (nul, DefHeapType (SynVar y)) -> + (match peek_def "function" 0 s e.at with + | Some y -> let FuncType (ts1, ts2) = func_type c (y @@ e.at) in let FuncType (ts1', _) as ft' = func_type c x in require (List.length ts1 >= List.length ts1') x.at @@ -537,14 +539,11 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : op_type let ts11, ts12 = Lib.List.split (List.length ts1 - List.length ts1') ts1 in require (match_func_type c.types [] (FuncType (ts12, ts2)) ft') e.at "type mismatch in function type"; - (ts11 @ [RefType (nul, DefHeapType (SynVar y))]) --> + (ts11 @ [RefType (Nullable, DefHeapType (SynVar y))]) --> + [RefType (NonNullable, DefHeapType (SynVar x.it))] + | None -> + [RefType (Nullable, BotHeapType)] -->.. [RefType (NonNullable, DefHeapType (SynVar x.it))] - | (_, BotHeapType) as rt -> - [RefType rt] -->.. [RefType (NonNullable, DefHeapType (SynVar x.it))] - | rt -> - error e.at - ("type mismatch: instruction requires function reference type" ^ - " but stack has " ^ string_of_value_type (RefType rt)) ) | LocalGet x -> @@ -686,61 +685,105 @@ let rec check_instr (c : context) (e : instr) (s : infer_result_type) : op_type | I31Get ext -> [RefType (Nullable, I31HeapType)] --> [NumType I32Type] - | StructNew (x, initop) -> - let StructType fts = struct_type c x in - require - ( initop = Explicit || List.for_all (fun ft -> - defaultable_value_type (unpacked_field_type ft)) fts ) e.at - ("field type is not defaultable"); - let ts = if initop = Implicit then [] else List.map unpacked_field_type fts in - (ts @ [RefType (NonNullable, RttHeapType (SynVar x.it, None))]) --> - [RefType (NonNullable, DefHeapType (SynVar x.it))] - - | StructGet (x, y, exto) -> - let StructType fts = struct_type c x in - require (y.it < Lib.List32.length fts) y.at - ("unknown field " ^ I32.to_string_u y.it); - let FieldType (st, _) = Lib.List32.nth fts y.it in - require ((exto <> None) == is_packed_storage_type st) y.at - ("field is " ^ (if exto = None then "packed" else "unpacked")); - let t = unpacked_storage_type st in - [RefType (Nullable, DefHeapType (SynVar x.it))] --> [t] - - | StructSet (x, y) -> - let StructType fts = struct_type c x in - require (y.it < Lib.List32.length fts) y.at - ("unknown field " ^ I32.to_string_u y.it); - let FieldType (st, mut) = Lib.List32.nth fts y.it in - require (mut == Mutable) y.at "field is immutable"; - let t = unpacked_storage_type st in - [RefType (Nullable, DefHeapType (SynVar x.it)); t] --> [] - - | ArrayNew (x, initop) -> - let ArrayType ft = array_type c x in - require - ( initop = Explicit || - defaultable_value_type (unpacked_field_type ft) ) e.at - ("array type is not defaultable"); - let ts = if initop = Implicit then [] else [unpacked_field_type ft] in - (ts @ [NumType I32Type; RefType (NonNullable, RttHeapType (SynVar x.it, None))]) --> - [RefType (NonNullable, DefHeapType (SynVar x.it))] - - | ArrayGet (x, exto) -> - let ArrayType (FieldType (st, _)) = array_type c x in - require ((exto <> None) == is_packed_storage_type st) e.at - ("array is " ^ (if exto = None then "packed" else "unpacked")); - let t = unpacked_storage_type st in - [RefType (Nullable, DefHeapType (SynVar x.it)); NumType I32Type] --> [t] - - | ArraySet x -> - let ArrayType (FieldType (st, mut)) = array_type c x in - require (mut == Mutable) e.at "array is immutable"; - let t = unpacked_storage_type st in - [RefType (Nullable, DefHeapType (SynVar x.it)); NumType I32Type; t] --> [] - - | ArrayLen x -> - let ArrayType _ = array_type c x in - [RefType (Nullable, DefHeapType (SynVar x.it))] --> [NumType I32Type] + | StructNew initop -> + (match peek_rtt 0 s e.at with + | _, DefHeapType (SynVar x) -> + let StructType fts = struct_type c (x @@ e.at) in + require + ( initop = Explicit || List.for_all (fun ft -> + defaultable_value_type (unpacked_field_type ft)) fts ) e.at + ("field type is not defaultable"); + let ts = if initop = Implicit then [] else List.map unpacked_field_type fts in + (ts @ [RefType (NonNullable, RttHeapType (SynVar x, None))]) --> + [RefType (NonNullable, DefHeapType (SynVar x))] + | _, BotHeapType -> + if initop = Implicit then + [NumType I32Type; RefType (NonNullable, BotHeapType)] --> + [RefType (NonNullable, BotHeapType)] + else + [NumType I32Type; RefType (NonNullable, BotHeapType)] -->.. + [RefType (NonNullable, BotHeapType)] + | _ -> assert false + ) + + | StructGet (y, exto) -> + (match peek_def "struct" 0 s e.at with + | Some x -> + let StructType fts = struct_type c (x @@ e.at) in + require (y.it < Lib.List32.length fts) y.at + ("unknown field " ^ I32.to_string_u y.it); + let FieldType (st, _) = Lib.List32.nth fts y.it in + require ((exto <> None) == is_packed_storage_type st) y.at + ("field is " ^ (if exto = None then "packed" else "unpacked")); + let t = unpacked_storage_type st in + [RefType (Nullable, DefHeapType (SynVar x))] --> [t] + | None -> + [RefType (Nullable, BotHeapType)] --> [BotType] + ) + + | StructSet y -> + (match peek_def "struct" 1 s e.at with + | Some x -> + let StructType fts = struct_type c (x @@ e.at) in + require (y.it < Lib.List32.length fts) y.at + ("unknown field " ^ I32.to_string_u y.it); + let FieldType (st, mut) = Lib.List32.nth fts y.it in + require (mut == Mutable) y.at "field is immutable"; + let t = unpacked_storage_type st in + [RefType (Nullable, DefHeapType (SynVar x)); t] --> [] + | None -> + [RefType (Nullable, BotHeapType); BotType] --> [] + ) + + | ArrayNew initop -> + (match peek_rtt 0 s e.at with + | _, DefHeapType (SynVar x) -> + let ArrayType ft = array_type c (x @@ e.at) in + require + ( initop = Explicit || + defaultable_value_type (unpacked_field_type ft) ) e.at + ("array type is not defaultable"); + let ts = if initop = Implicit then [] else [unpacked_field_type ft] in + (ts @ [NumType I32Type; RefType (NonNullable, RttHeapType (SynVar x, None))]) --> + [RefType (NonNullable, DefHeapType (SynVar x))] + | _, BotHeapType -> + let ts = if initop = Implicit then [] else [BotType] in + (ts @ [NumType I32Type; RefType (NonNullable, BotHeapType)]) --> + [RefType (NonNullable, BotHeapType)] + | _ -> assert false + ) + + | ArrayGet exto -> + (match peek_def "array" 1 s e.at with + | Some x -> + let ArrayType (FieldType (st, _)) = array_type c (x @@ e.at) in + require ((exto <> None) == is_packed_storage_type st) e.at + ("array is " ^ (if exto = None then "packed" else "unpacked")); + let t = unpacked_storage_type st in + [RefType (Nullable, DefHeapType (SynVar x)); NumType I32Type] --> [t] + | None -> + [RefType (Nullable, BotHeapType); NumType I32Type] --> [BotType] + ) + + | ArraySet -> + (match peek_def "array" 2 s e.at with + | Some x -> + let ArrayType (FieldType (st, mut)) = array_type c (x @@ e.at) in + require (mut == Mutable) e.at "array is immutable"; + let t = unpacked_storage_type st in + [RefType (Nullable, DefHeapType (SynVar x)); NumType I32Type; t] --> [] + | None -> + [RefType (Nullable, BotHeapType); NumType I32Type; BotType] --> [] + ) + + | ArrayLen -> + (match peek_def "array" 0 s e.at with + | Some x -> + let ArrayType _ = array_type c (x @@ e.at) in + [RefType (Nullable, DefHeapType (SynVar x))] --> [NumType I32Type] + | None -> + [RefType (Nullable, BotHeapType)] --> [NumType I32Type] + ) | RttCanon x -> ignore (type_ c x); diff --git a/proposals/gc/MVP.md b/proposals/gc/MVP.md index 9df1bb86d..6253b8e47 100644 --- a/proposals/gc/MVP.md +++ b/proposals/gc/MVP.md @@ -246,24 +246,24 @@ This can compile to machine code that (1) reads the RTT from `$x`, (2) checks th #### Structures -* `struct.new_with_rtt ` allocates a structure with RTT information determining its [runtime type](#values) and initialises its fields with given values - - `struct.new_with_rtt $t : [t'* (rtt n $t)] -> [(ref $t)]` +* `struct.new_with_rtt` allocates a structure with RTT information determining its [runtime type](#values) and initialises its fields with given values + - `struct.new_with_rtt : [t'* (rtt n $t)] -> [(ref $t)]` - iff `$t = struct (mut t')*` -* `struct.new_default_with_rtt ` allocates a structure of type `$t` and initialises its fields with default values - - `struct.new_default_with_rtt $t : [(rtt n $t)] -> [(ref $t)]` +* `struct.new_default_with_rtt` allocates a structure of type `$t` and initialises its fields with default values + - `struct.new_default_with_rtt : [(rtt n $t)] -> [(ref $t)]` - iff `$t = struct (mut t')*` - and all `t'*` are defaultable -* `struct.get_? ` reads field `i` from a structure - - `struct.get_? $t i : [(ref null $t)] -> [t]` +* `struct.get_? ` reads field `i` from a structure + - `struct.get_? i : [(ref null $t)] -> [t]` - iff `$t = struct (mut1 t1)^i (mut ti) (mut2 t2)*` - and `t = unpacked(ti)` - and `_` present iff `t =/= ti` - traps on `null` -* `struct.set ` writes field `i` of a structure - - `struct.set $t i : [(ref null $t) ti] -> []` +* `struct.set ` writes field `i` of a structure + - `struct.set i : [(ref null $t) ti] -> []` - iff `$t = struct (mut1 t1)^i (var ti) (mut2 t2)*` - and `t = unpacked(ti)` - traps on `null` @@ -271,30 +271,30 @@ This can compile to machine code that (1) reads the RTT from `$x`, (2) checks th #### Arrays -* `array.new_with_rtt ` allocates an array with RTT information determining its [runtime type](#values) - - `array.new_with_rtt $t : [t' i32 (rtt n $t)] -> [(ref $t)]` +* `array.new_with_rtt` allocates an array with RTT information determining its [runtime type](#values) + - `array.new_with_rtt : [t' i32 (rtt n $t)] -> [(ref $t)]` - iff `$t = array (var t')` * `array.new_default_with_rtt ` allocates an array and initialises its fields with the default value - - `array.new_default_with_rtt $t : [i32 (rtt n $t)] -> [(ref $t)]` + - `array.new_default_with_rtt : [i32 (rtt n $t)] -> [(ref $t)]` - iff `$t = array (var t')` - and `t'` is defaultable -* `array.get_? ` reads an element from an array - - `array.get_? $t : [(ref null $t) i32] -> [t]` +* `array.get_?` reads an element from an array + - `array.get_? : [(ref null $t) i32] -> [t]` - iff `$t = array (mut t')` - and `t = unpacked(t')` - and `_` present iff `t =/= t'` - traps on `null` or if the dynamic index is out of bounds -* `array.set ` writes an element to an array - - `array.set $t : [(ref null $t) i32 t] -> []` +* `array.set` writes an element to an array + - `array.set : [(ref null $t) i32 t] -> []` - iff `$t = array (var t')` - and `t = unpacked(t')` - traps on `null` or if the dynamic index is out of bounds -* `array.len ` inquires the length of an array - - `array.len $t : [(ref null $t)] -> [i32]` +* `array.len` inquires the length of an array + - `array.len : [(ref null $t)] -> [i32]` - iff `$t = array (mut t)` - traps on `null` @@ -510,19 +510,19 @@ The opcode for heap types is encoded as an `s33`. | ------ | --------------- | ---------- | | 0xd5 | `ref.eq` | | | 0xd6 | `br_on_non_null` | | -| 0xfb01 | `struct.new_with_rtt $t` | `$t : typeidx` | -| 0xfb02 | `struct.new_default_with_rtt $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_with_rtt $t` | `$t : typeidx` | -| 0xfb12 | `array.new_default_with_rtt $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 $t` | `$t : typeidx` | +| 0xfb01 | `struct.new_with_rtt` | | +| 0xfb02 | `struct.new_default_with_rtt` | | +| 0xfb03 | `struct.get i` | `i : fieldidx` | +| 0xfb04 | `struct.get_s i` | `i : fieldidx` | +| 0xfb05 | `struct.get_u i` | `i : fieldidx` | +| 0xfb06 | `struct.set i` | `i : fieldidx` | +| 0xfb11 | `array.new_with_rtt` | | +| 0xfb12 | `array.new_default_with_rtt` | | +| 0xfb13 | `array.get` | | +| 0xfb14 | `array.get_s` | | +| 0xfb15 | `array.get_u` | | +| 0xfb16 | `array.set` | | +| 0xfb17 | `array.len` | | | 0xfb20 | `i31.new` | | | 0xfb21 | `i31.get_s` | | | 0xfb22 | `i31.get_u` | | diff --git a/test/core/array.wast b/test/core/array.wast index 48a58108b..a688d0c5d 100644 --- a/test/core/array.wast +++ b/test/core/array.wast @@ -64,30 +64,30 @@ (type $mvec (array (mut f32))) (func $get (param $i i32) (param $v (ref $vec)) (result f32) - (array.get $vec (local.get $v) (local.get $i)) + (array.get (local.get $v) (local.get $i)) ) (func (export "get") (param $i i32) (result f32) (call $get (local.get $i) - (array.new_default $vec (i32.const 3) (rtt.canon $vec)) + (array.new_default (i32.const 3) (rtt.canon $vec)) ) ) (func $set_get (param $i i32) (param $v (ref $mvec)) (param $y f32) (result f32) - (array.set $mvec (local.get $v) (local.get $i) (local.get $y)) - (array.get $mvec (local.get $v) (local.get $i)) + (array.set (local.get $v) (local.get $i) (local.get $y)) + (array.get (local.get $v) (local.get $i)) ) (func (export "set_get") (param $i i32) (param $y f32) (result f32) (call $set_get (local.get $i) - (array.new_default $mvec (i32.const 3) (rtt.canon $mvec)) + (array.new_default (i32.const 3) (rtt.canon $mvec)) (local.get $y) ) ) (func $len (param $v (ref $vec)) (result i32) - (array.len $vec (local.get $v)) + (array.len (local.get $v)) ) (func (export "len") (result i32) - (call $len (array.new_default $vec (i32.const 3) (rtt.canon $vec))) + (call $len (array.new_default (i32.const 3) (rtt.canon $vec))) ) ) @@ -102,7 +102,7 @@ (module (type $a (array i64)) (func (export "array.set-immutable") (param $a (ref $a)) - (array.set $a (local.get $a) (i32.const 0) (i64.const 1)) + (array.set (local.get $a) (i32.const 0) (i64.const 1)) ) ) "array is immutable" @@ -114,10 +114,10 @@ (module (type $t (array (mut i32))) (func (export "array.get-null") - (local (ref null $t)) (drop (array.get $t (local.get 0) (i32.const 0))) + (local (ref null $t)) (drop (array.get (local.get 0) (i32.const 0))) ) (func (export "array.set-null") - (local (ref null $t)) (array.set $t (local.get 0) (i32.const 0) (i32.const 0)) + (local (ref null $t)) (array.set (local.get 0) (i32.const 0) (i32.const 0)) ) ) @@ -128,7 +128,7 @@ (module (type $t (array i32)) (func (export "array.new-null") - (local (ref null (rtt $t))) (drop (array.new_default $t (i32.const 1) (i32.const 3) (local.get 0))) + (local (ref null (rtt $t))) (drop (array.new_default (i32.const 1) (i32.const 3) (local.get 0))) ) ) "type mismatch" @@ -137,7 +137,7 @@ (module (type $t (array (mut i32))) (func (export "array.new_default-null") - (local (ref null (rtt $t))) (drop (array.new_default $t (i32.const 3) (local.get 0))) + (local (ref null (rtt $t))) (drop (array.new_default (i32.const 3) (local.get 0))) ) ) "type mismatch" diff --git a/test/core/br_on.wast b/test/core/br_on.wast index 370eb9396..05447b6b8 100644 --- a/test/core/br_on.wast +++ b/test/core/br_on.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 $st (i32.const 6) (rtt.canon $st))) - (table.set (i32.const 3) (array.new $at (i32.const 5) (i32.const 1) (rtt.canon $at))) + (table.set (i32.const 2) (struct.new (i32.const 6) (rtt.canon $st))) + (table.set (i32.const 3) (array.new (i32.const 5) (i32.const 1) (rtt.canon $at))) (table.set (i32.const 4) (ref.func $f)) (table.set (i32.const 5) (rtt.canon $ft)) (table.set (i32.const 6) (local.get $x)) @@ -43,9 +43,9 @@ (br_on_cast $l3 (rtt.canon $at)) (return (i32.const -2)) ) - (return (array.get_u $at (i32.const 0))) + (return (array.get_u (i32.const 0))) ) - (struct.get_s $st 0) + (struct.get_s 0) ) (func (export "br_on_func") (param $i i32) (result i32) (block $l (result (ref func)) diff --git a/test/core/br_on_cast.wast b/test/core/br_on_cast.wast index 89ebc608a..83ef7ac94 100644 --- a/test/core/br_on_cast.wast +++ b/test/core/br_on_cast.wast @@ -18,14 +18,14 @@ (table 20 dataref) (func $init - (table.set (i32.const 0) (struct.new_default $t0 (global.get $t0))) - (table.set (i32.const 10) (struct.new_default $t0 (global.get $t0'))) - (table.set (i32.const 1) (struct.new_default $t1 (global.get $t1))) - (table.set (i32.const 11) (struct.new_default $t1' (global.get $t1'))) - (table.set (i32.const 2) (struct.new_default $t2 (global.get $t2))) - (table.set (i32.const 12) (struct.new_default $t2' (global.get $t2'))) - (table.set (i32.const 3) (struct.new_default $t3 (global.get $t3))) - (table.set (i32.const 4) (struct.new_default $t3 (global.get $t4))) + (table.set (i32.const 0) (struct.new_default (global.get $t0))) + (table.set (i32.const 10) (struct.new_default (global.get $t0'))) + (table.set (i32.const 1) (struct.new_default (global.get $t1))) + (table.set (i32.const 11) (struct.new_default (global.get $t1'))) + (table.set (i32.const 2) (struct.new_default (global.get $t2))) + (table.set (i32.const 12) (struct.new_default (global.get $t2'))) + (table.set (i32.const 3) (struct.new_default (global.get $t3))) + (table.set (i32.const 4) (struct.new_default (global.get $t4))) ) (func (export "test-sub") diff --git a/test/core/br_on_cast_fail.wast b/test/core/br_on_cast_fail.wast index 1864c1f4a..ce93a4d34 100644 --- a/test/core/br_on_cast_fail.wast +++ b/test/core/br_on_cast_fail.wast @@ -18,14 +18,14 @@ (table 20 dataref) (func $init - (table.set (i32.const 0) (struct.new_default $t0 (global.get $t0))) - (table.set (i32.const 10) (struct.new_default $t0 (global.get $t0'))) - (table.set (i32.const 1) (struct.new_default $t1 (global.get $t1))) - (table.set (i32.const 11) (struct.new_default $t1' (global.get $t1'))) - (table.set (i32.const 2) (struct.new_default $t2 (global.get $t2))) - (table.set (i32.const 12) (struct.new_default $t2' (global.get $t2'))) - (table.set (i32.const 3) (struct.new_default $t3 (global.get $t3))) - (table.set (i32.const 4) (struct.new_default $t3 (global.get $t4))) + (table.set (i32.const 0) (struct.new_default (global.get $t0))) + (table.set (i32.const 10) (struct.new_default (global.get $t0'))) + (table.set (i32.const 1) (struct.new_default (global.get $t1))) + (table.set (i32.const 11) (struct.new_default (global.get $t1'))) + (table.set (i32.const 2) (struct.new_default (global.get $t2))) + (table.set (i32.const 12) (struct.new_default (global.get $t2'))) + (table.set (i32.const 3) (struct.new_default (global.get $t3))) + (table.set (i32.const 4) (struct.new_default (global.get $t4))) ) (func (export "test-sub") diff --git a/test/core/br_on_non.wast b/test/core/br_on_non.wast index 2353a4c4f..788001941 100644 --- a/test/core/br_on_non.wast +++ b/test/core/br_on_non.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 $st (i32.const 6) (rtt.canon $st))) - (table.set (i32.const 3) (array.new $at (i32.const 5) (i32.const 1) (rtt.canon $at))) + (table.set (i32.const 2) (struct.new (i32.const 6) (rtt.canon $st))) + (table.set (i32.const 3) (array.new (i32.const 5) (i32.const 1) (rtt.canon $at))) (table.set (i32.const 4) (ref.func $f)) (table.set (i32.const 5) (rtt.canon $ft)) (table.set (i32.const 6) (local.get $x)) @@ -41,9 +41,9 @@ (br_on_cast $l3 (rtt.canon $at)) (return (i32.const -2)) ) - (return (array.get_u $at (i32.const 0))) + (return (array.get_u (i32.const 0))) ) - (return (struct.get_s $st 0)) + (return (struct.get_s 0)) ) (return (i32.const -1)) ) diff --git a/test/core/ref_as.wast b/test/core/ref_as.wast index 47064c328..01080b6bd 100644 --- a/test/core/ref_as.wast +++ b/test/core/ref_as.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_default $st (rtt.canon $st))) - (table.set (i32.const 3) (array.new_default $at (i32.const 0) (rtt.canon $at))) + (table.set (i32.const 2) (struct.new_default (rtt.canon $st))) + (table.set (i32.const 3) (array.new_default (i32.const 0) (rtt.canon $at))) (table.set (i32.const 4) (ref.func $f)) (table.set (i32.const 5) (rtt.canon $ft)) (table.set (i32.const 6) (local.get $x)) diff --git a/test/core/ref_cast.wast b/test/core/ref_cast.wast index 9a74a2800..594070250 100644 --- a/test/core/ref_cast.wast +++ b/test/core/ref_cast.wast @@ -18,14 +18,14 @@ (table 20 dataref) (func $init - (table.set (i32.const 0) (struct.new_default $t0 (global.get $t0))) - (table.set (i32.const 10) (struct.new_default $t0 (global.get $t0'))) - (table.set (i32.const 1) (struct.new_default $t1 (global.get $t1))) - (table.set (i32.const 11) (struct.new_default $t1' (global.get $t1'))) - (table.set (i32.const 2) (struct.new_default $t2 (global.get $t2))) - (table.set (i32.const 12) (struct.new_default $t2' (global.get $t2'))) - (table.set (i32.const 3) (struct.new_default $t3 (global.get $t3))) - (table.set (i32.const 4) (struct.new_default $t3 (global.get $t4))) + (table.set (i32.const 0) (struct.new_default (global.get $t0))) + (table.set (i32.const 10) (struct.new_default (global.get $t0'))) + (table.set (i32.const 1) (struct.new_default (global.get $t1))) + (table.set (i32.const 11) (struct.new_default (global.get $t1'))) + (table.set (i32.const 2) (struct.new_default (global.get $t2))) + (table.set (i32.const 12) (struct.new_default (global.get $t2'))) + (table.set (i32.const 3) (struct.new_default (global.get $t3))) + (table.set (i32.const 4) (struct.new_default (global.get $t4))) ) (func (export "test-sub") diff --git a/test/core/ref_eq.wast b/test/core/ref_eq.wast index 5542f264a..cf74d0766 100644 --- a/test/core/ref_eq.wast +++ b/test/core/ref_eq.wast @@ -11,10 +11,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_default $st (rtt.canon $st))) - (table.set (i32.const 6) (struct.new_default $st (rtt.canon $st))) - (table.set (i32.const 7) (array.new_default $at (i32.const 0) (rtt.canon $at))) - (table.set (i32.const 8) (array.new_default $at (i32.const 0) (rtt.canon $at))) + (table.set (i32.const 5) (struct.new_default (rtt.canon $st))) + (table.set (i32.const 6) (struct.new_default (rtt.canon $st))) + (table.set (i32.const 7) (array.new_default (i32.const 0) (rtt.canon $at))) + (table.set (i32.const 8) (array.new_default (i32.const 0) (rtt.canon $at))) (table.set (i32.const 9) (rtt.canon $st)) (table.set (i32.const 10) (rtt.canon $st)) (table.set (i32.const 11) (rtt.canon $at)) diff --git a/test/core/ref_is.wast b/test/core/ref_is.wast index bfdc728e0..1ea9be9cc 100644 --- a/test/core/ref_is.wast +++ b/test/core/ref_is.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_default $st (rtt.canon $st))) - (table.set (i32.const 3) (array.new_default $at (i32.const 0) (rtt.canon $at))) + (table.set (i32.const 2) (struct.new_default (rtt.canon $st))) + (table.set (i32.const 3) (array.new_default (i32.const 0) (rtt.canon $at))) (table.set (i32.const 4) (ref.func $f)) (table.set (i32.const 5) (rtt.canon $ft)) (table.set (i32.const 6) (local.get $x)) diff --git a/test/core/ref_test.wast b/test/core/ref_test.wast index 701293957..b630b89a5 100644 --- a/test/core/ref_test.wast +++ b/test/core/ref_test.wast @@ -18,14 +18,14 @@ (table 20 dataref) (func $init - (table.set (i32.const 0) (struct.new_default $t0 (global.get $t0))) - (table.set (i32.const 10) (struct.new_default $t0 (global.get $t0'))) - (table.set (i32.const 1) (struct.new_default $t1 (global.get $t1))) - (table.set (i32.const 11) (struct.new_default $t1' (global.get $t1'))) - (table.set (i32.const 2) (struct.new_default $t2 (global.get $t2))) - (table.set (i32.const 12) (struct.new_default $t2' (global.get $t2'))) - (table.set (i32.const 3) (struct.new_default $t3 (global.get $t3))) - (table.set (i32.const 4) (struct.new_default $t3 (global.get $t4))) + (table.set (i32.const 0) (struct.new_default (global.get $t0))) + (table.set (i32.const 10) (struct.new_default (global.get $t0'))) + (table.set (i32.const 1) (struct.new_default (global.get $t1))) + (table.set (i32.const 11) (struct.new_default (global.get $t1'))) + (table.set (i32.const 2) (struct.new_default (global.get $t2))) + (table.set (i32.const 12) (struct.new_default (global.get $t2'))) + (table.set (i32.const 3) (struct.new_default (global.get $t3))) + (table.set (i32.const 4) (struct.new_default (global.get $t4))) ) (func (export "test-sub") diff --git a/test/core/struct.wast b/test/core/struct.wast index 50a0e1d5c..017b410cf 100644 --- a/test/core/struct.wast +++ b/test/core/struct.wast @@ -54,26 +54,26 @@ (type $vec (struct (field f32) (field $y (mut f32)) (field $z f32))) (func $get_0 (param $v (ref $vec)) (result f32) - (struct.get $vec 0 (local.get $v)) + (struct.get 0 (local.get $v)) ) (func (export "get_0") (result f32) - (call $get_0 (struct.new_default $vec (rtt.canon $vec))) + (call $get_0 (struct.new_default (rtt.canon $vec))) ) (func $set_get_y (param $v (ref $vec)) (param $y f32) (result f32) - (struct.set $vec $y (local.get $v) (local.get $y)) - (struct.get $vec $y (local.get $v)) + (struct.set $y (local.get $v) (local.get $y)) + (struct.get $y (local.get $v)) ) (func (export "set_get_y") (param $y f32) (result f32) - (call $set_get_y (struct.new_default $vec (rtt.canon $vec)) (local.get $y)) + (call $set_get_y (struct.new_default (rtt.canon $vec)) (local.get $y)) ) (func $set_get_1 (param $v (ref $vec)) (param $y f32) (result f32) - (struct.set $vec 1 (local.get $v) (local.get $y)) - (struct.get $vec $y (local.get $v)) + (struct.set 1 (local.get $v) (local.get $y)) + (struct.get $y (local.get $v)) ) (func (export "set_get_1") (param $y f32) (result f32) - (call $set_get_1 (struct.new_default $vec (rtt.canon $vec)) (local.get $y)) + (call $set_get_1 (struct.new_default (rtt.canon $vec)) (local.get $y)) ) ) @@ -85,7 +85,7 @@ (module (type $s (struct (field i64))) (func (export "struct.set-immutable") (param $s (ref $s)) - (struct.set $s 0 (local.get $s) (i64.const 1)) + (struct.set 0 (local.get $s) (i64.const 1)) ) ) "field is immutable" @@ -97,10 +97,10 @@ (module (type $t (struct (field i32 (mut i32)))) (func (export "struct.get-null") - (local (ref null $t)) (drop (struct.get $t 1 (local.get 0))) + (local (ref null $t)) (drop (struct.get 1 (local.get 0))) ) (func (export "struct.set-null") - (local (ref null $t)) (struct.set $t 1 (local.get 0) (i32.const 0)) + (local (ref null $t)) (struct.set 1 (local.get 0) (i32.const 0)) ) ) @@ -111,7 +111,7 @@ (module (type $t (struct (field i32 (mut i32)))) (func (export "struct.new-null") - (local (ref null (rtt $t))) (drop (struct.new $t (i32.const 1) (i32.const 2) (local.get 0))) + (local (ref null (rtt $t))) (drop (struct.new (i32.const 1) (i32.const 2) (local.get 0))) ) ) "type mismatch" @@ -120,7 +120,7 @@ (module (type $t (struct (field i32 (mut i32)))) (func (export "struct.new_default-null") - (local (ref null (rtt $t))) (drop (struct.new_default $t (local.get 0))) + (local (ref null (rtt $t))) (drop (struct.new_default (local.get 0))) ) ) "type mismatch"