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

Remove redundant typeidx on gc instructions #241

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions interpreter/binary/decode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 14 additions & 14 deletions interpreter/binary/encode.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
100 changes: 53 additions & 47 deletions interpreter/exec/eval.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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 ->
Expand Down Expand Up @@ -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 ->
Expand Down
14 changes: 7 additions & 7 deletions interpreter/syntax/ast.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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 *)

Expand Down
5 changes: 2 additions & 3 deletions interpreter/syntax/free.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
26 changes: 13 additions & 13 deletions interpreter/syntax/operators.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 8 additions & 8 deletions interpreter/text/arrange.ml
Original file line number Diff line number Diff line change
Expand Up @@ -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, []
Expand Down
20 changes: 10 additions & 10 deletions interpreter/text/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -252,9 +252,9 @@ let inline_func_type_explicit (c : context) x ft at =
%token<Ast.instr'> REF_TEST REF_CAST
%token<Ast.idx -> Ast.instr'> BR_CAST BR_CAST_FAIL
%token<Ast.instr'> I31_GET
%token<Ast.idx -> Ast.idx -> Ast.instr'> STRUCT_GET
%token<Ast.idx -> Ast.instr'> ARRAY_GET
%token<Ast.idx -> Ast.instr'> STRUCT_NEW ARRAY_NEW
%token<Ast.idx -> Ast.instr'> STRUCT_GET
%token<Ast.instr'> ARRAY_GET
%token<Ast.instr'> STRUCT_NEW ARRAY_NEW
%token<string Source.phrase -> Ast.instr' * Value.num> CONST
%token<Ast.instr'> UNARY
%token<Ast.instr'> BINARY
Expand Down Expand Up @@ -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) }
Expand Down
Loading