From ce258d402ed99ba0cfe357d0729d2baa7ce322f3 Mon Sep 17 00:00:00 2001 From: Andreas Rossberg Date: Wed, 8 Jun 2022 19:21:00 +0200 Subject: [PATCH] [interpreter] Factor data and element segments into abstract types --- interpreter/exec/eval.ml | 23 ++++++++++++----------- interpreter/exec/ixx.ml | 4 ++-- interpreter/runtime/data.ml | 7 +++++++ interpreter/runtime/data.mli | 7 +++++++ interpreter/runtime/elem.ml | 7 +++++++ interpreter/runtime/elem.mli | 9 +++++++++ interpreter/runtime/instance.ml | 8 ++++---- 7 files changed, 48 insertions(+), 17 deletions(-) create mode 100644 interpreter/runtime/data.ml create mode 100644 interpreter/runtime/data.mli create mode 100644 interpreter/runtime/elem.ml create mode 100644 interpreter/runtime/elem.mli diff --git a/interpreter/exec/eval.ml b/interpreter/exec/eval.ml index 74e7f1a72e..3a112ce49e 100644 --- a/interpreter/exec/eval.ml +++ b/interpreter/exec/eval.ml @@ -134,7 +134,7 @@ let mem_oob frame x i n = let data_oob frame x i n = I64.gt_u (I64.add (I64_convert.extend_i32_u i) (I64_convert.extend_i32_u n)) - (I64.of_int_u (String.length !(data frame.inst x))) + (Data.size (data frame.inst x)) let table_oob frame x i n = I64.gt_u (I64.add (I64_convert.extend_i32_u i) (I64_convert.extend_i32_u n)) @@ -142,7 +142,7 @@ let table_oob frame x i n = let elem_oob frame x i n = I64.gt_u (I64.add (I64_convert.extend_i32_u i) (I64_convert.extend_i32_u n)) - (I64.of_int_u (List.length !(elem frame.inst x))) + (I64_convert.extend_i32_u (Elem.size (elem frame.inst x))) let rec step (c : config) : config = let {frame; code = vs, es; _} = c in @@ -302,10 +302,10 @@ let rec step (c : config) : config = else if n = 0l then vs', [] else - let seg = !(elem frame.inst y) in + let seg = elem frame.inst y in vs', List.map (at e.at) [ Plain (Const (I32 d @@ e.at)); - Refer (List.nth seg (Int32.to_int s)); + Refer (Elem.load seg s); Plain (TableSet x); Plain (Const (I32 (I32.add d 1l) @@ e.at)); Plain (Const (I32 (I32.add s 1l) @@ e.at)); @@ -315,7 +315,7 @@ let rec step (c : config) : config = | ElemDrop x, vs -> let seg = elem frame.inst x in - seg := []; + Elem.drop seg; vs, [] | Load {offset; ty; pack; _}, Num (I32 i) :: vs' -> @@ -465,11 +465,12 @@ let rec step (c : config) : config = else if n = 0l then vs', [] else - let seg = !(data frame.inst x) in - let b = Int32.of_int (Char.code seg.[Int32.to_int s]) in + let seg = data frame.inst x in + let a = I64_convert.extend_i32_u s in + let b = Data.load seg a in vs', List.map (at e.at) [ Plain (Const (I32 d @@ e.at)); - Plain (Const (I32 b @@ e.at)); + Plain (Const (I32 (I32.of_int_u (Char.code b)) @@ e.at)); Plain (Store {ty = I32Type; align = 0; offset = 0l; pack = Some Pack8}); Plain (Const (I32 (I32.add d 1l) @@ e.at)); @@ -480,7 +481,7 @@ let rec step (c : config) : config = | DataDrop x, vs -> let seg = data frame.inst x in - seg := ""; + Data.drop seg; vs, [] | RefNull t, vs' -> @@ -715,11 +716,11 @@ let create_export (inst : module_inst) (ex : export) : export_inst = let create_elem (inst : module_inst) (seg : elem_segment) : elem_inst = let {etype; einit; _} = seg.it in - ref (List.map (fun c -> as_ref (eval_const inst c)) einit) + Elem.alloc (List.map (fun c -> as_ref (eval_const inst c)) einit) let create_data (inst : module_inst) (seg : data_segment) : data_inst = let {dinit; _} = seg.it in - ref dinit + Data.alloc dinit let add_import (m : module_) (ext : extern) (im : import) (inst : module_inst) diff --git a/interpreter/exec/ixx.ml b/interpreter/exec/ixx.ml index 18f8b7d060..0a13d22b6e 100644 --- a/interpreter/exec/ixx.ml +++ b/interpreter/exec/ixx.ml @@ -30,8 +30,8 @@ sig val of_int : int -> t val to_int : t -> int - val of_int64: int64 -> t - val to_int64: t -> int64 + val of_int64 : int64 -> t + val to_int64 : t -> int64 val to_string : t -> string val to_hex_string : t -> string diff --git a/interpreter/runtime/data.ml b/interpreter/runtime/data.ml new file mode 100644 index 0000000000..e73cd2f311 --- /dev/null +++ b/interpreter/runtime/data.ml @@ -0,0 +1,7 @@ +type data = string ref +type t = data + +let alloc bs = ref bs +let size seg = I64.of_int_u (String.length !seg) +let load seg i = (!seg).[Int64.to_int i] +let drop seg = seg := "" diff --git a/interpreter/runtime/data.mli b/interpreter/runtime/data.mli new file mode 100644 index 0000000000..498c45149f --- /dev/null +++ b/interpreter/runtime/data.mli @@ -0,0 +1,7 @@ +type data +type t = data + +val alloc : string -> data +val size : data -> Memory.address +val load : data -> Memory.address -> char +val drop : data -> unit diff --git a/interpreter/runtime/elem.ml b/interpreter/runtime/elem.ml new file mode 100644 index 0000000000..fe89974827 --- /dev/null +++ b/interpreter/runtime/elem.ml @@ -0,0 +1,7 @@ +type elem = Values.ref_ list ref +type t = elem + +let alloc rs = ref rs +let size seg = Lib.List32.length !seg +let load seg i = Lib.List32.nth !seg i +let drop seg = seg := [] diff --git a/interpreter/runtime/elem.mli b/interpreter/runtime/elem.mli new file mode 100644 index 0000000000..5eb0c0e56e --- /dev/null +++ b/interpreter/runtime/elem.mli @@ -0,0 +1,9 @@ +open Values + +type elem +type t = elem + +val alloc : ref_ list -> elem +val size : elem -> Table.size +val load : elem -> Table.index -> ref_ +val drop : elem -> unit diff --git a/interpreter/runtime/instance.ml b/interpreter/runtime/instance.ml index 4d4fece078..0ae878c377 100644 --- a/interpreter/runtime/instance.ml +++ b/interpreter/runtime/instance.ml @@ -7,18 +7,18 @@ type module_inst = tables : table_inst list; memories : memory_inst list; globals : global_inst list; - exports : export_inst list; elems : elem_inst list; datas : data_inst list; + exports : export_inst list; } and func_inst = module_inst ref Func.t and table_inst = Table.t and memory_inst = Memory.t and global_inst = Global.t +and elem_inst = Elem.t +and data_inst = Data.t and export_inst = Ast.name * extern -and elem_inst = Values.ref_ list ref -and data_inst = string ref and extern = | ExternFunc of func_inst @@ -55,7 +55,7 @@ let () = let empty_module_inst = { types = []; funcs = []; tables = []; memories = []; globals = []; - exports = []; elems = []; datas = [] } + elems = []; datas = []; exports = [] } let extern_type_of = function | ExternFunc func -> ExternFuncType (Func.type_of func)