1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
(* SPDX-License-Identifier: AGPL-3.0-or-later *)
(* Copyright © 2021-2026 OCamlPro *)
(* Written by the Owi programmers *)

module IntMap = Map.Make (Int)

type t =
  { data : Symbolic_value.t Symbolic_ref.t IntMap.t
  ; limits : Binary.Table.Type.limits
  ; typ : Binary.ref_type
  }

let pp_map =
  Fmt.braces
    (Fmt.iter_bindings ~sep:Fmt.semi IntMap.iter (fun ppf (k, v) ->
       Fmt.pf ppf "%d -> %a" k Symbolic_ref.pp v ) )

let pp ppf t = Fmt.pf ppf "%a" pp_map t.data

let get t i =
  match IntMap.find_opt i t.data with Some v -> v | None -> assert false

let set tbl i v =
  let data = IntMap.add i v tbl.data in
  { tbl with data }

let size t = IntMap.cardinal t.data

let typ t = t.typ

let max_size t =
  match t.limits with
  | I32 { max; _ } -> Option.map (fun maxv -> Int32.to_int maxv) max
  | I64 { max; _ } ->
    Option.map
      (fun maxv ->
        let max2int = Int64.to_int maxv in
        assert (Int64.(eq maxv (Int64.of_int max2int)));
        max2int )
      max

let grow t _new_size _x =
  (* TODO
     let new_size = Int32.to_int new_size in
     let new_table = Array.make new_size x in
     Array.blit t.data 0 new_table 0 (Array.length t.data);
     t.data <- new_table
  *)
  Log.warn (fun m -> m "used dummy table.grow implementation");
  t

let fill t pos len x =
  let pos = Int32.to_int pos in
  let len = Int32.to_int len in
  let rec loop i data =
    if i < pos + len then
      let data = IntMap.add i x t.data in
      loop (i + 1) data
    else { t with data }
  in
  loop pos t.data

let copy ~t_src ~t_dst ~src ~dst ~len =
  let src = Int32.to_int src in
  let dst = Int32.to_int dst in
  let len = Int32.to_int len in
  let rec loop i j l src_map dst_map =
    if l > 0 then
      let dst_map =
        match IntMap.find_opt i src_map with
        | Some v -> IntMap.add j v dst_map
        | None -> dst_map
      in
      loop (i + 1) (j + 1) (l - 1) src_map dst_map
    else { t_dst with data = dst_map }
  in
  loop src dst len t_src.data t_dst.data

let get_min : Binary.Table.Type.limits -> int = function
  | I32 { min; _ } -> Int32.to_int min
  | I64 { min; _ } -> Int64.to_int min

let init (typ : Binary.Table.Type.t) : t =
  let limits, ((_null, heap_type) as typ) = typ in
  let size = get_min limits in
  let l = List.init size (fun i -> (i, Symbolic_ref.null heap_type)) in
  let data =
    List.fold_left (fun data (i, v) -> IntMap.add i v data) IntMap.empty l
  in
  { data; limits; typ }

let get_type _ = assert false