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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
open Api
open Vectors
module Resolver = Map.Make (struct
type t = string * Types.Externkind.t
let compare (l1, l2) (r1, r2) =
match (String.compare l1 r1, Unsigned.UInt8.compare l2 r2) with
| 0, r -> r
| r, _ -> r
end)
type t = {resolved : Types.Extern.t Ctypes.ptr Resolver.t; clean : unit -> unit}
let from_instance inst =
let exports_vec = Module.exports inst.Instance.module_ in
let exports = Export_type_vector.to_list exports_vec in
let externs_vec = Extern_vector.empty () in
Functions.Instance.exports inst.instance (Ctypes.addr externs_vec) ;
let externs = Extern_vector.to_list externs_vec in
let resolved =
List.fold_right2
(fun export extern tail ->
let name = Export_type.name export in
let kind = Export_type.type_ export |> Functions.Externtype.kind in
Resolver.add (name, kind) extern tail)
exports
externs
Resolver.empty
in
Functions.Exporttype_vec.delete (Ctypes.addr exports_vec) ;
let clean () =
Functions.Extern_vec.delete (Ctypes.addr externs_vec)
in
{resolved; clean}
let delete exports = exports.clean ()
exception Export_not_found of {name : string; kind : Unsigned.uint8}
let () =
Printexc.register_printer (function
| Export_not_found {name; kind} ->
Some
(Format.asprintf
"Export %S (%i) not found"
name
(Unsigned.UInt8.to_int kind))
| _ -> None)
let fn exports name typ =
let kind = Types.Externkind.func in
let extern = Resolver.find_opt (name, kind) exports.resolved in
let extern =
match extern with
| None -> raise (Export_not_found {name; kind})
| Some extern -> extern
in
let func = Functions.Extern.as_func extern in
let f = Function.call func typ in
() ;
f
let mem_of_extern extern =
let mem = Functions.Extern.as_memory extern in
let mem_type = Functions.Memory.type_ mem in
let limits = Functions.Memory_type.limits mem_type in
let min, max =
let open Ctypes in
(!@(limits |-> Types.Limits.min), !@(limits |-> Types.Limits.max))
in
let max =
if Unsigned.UInt32.equal max Types.Limits.max_default then None
else Some max
in
let raw =
Ctypes.CArray.from_ptr
(Functions.Memory.data mem)
(Functions.Memory.data_size mem |> Unsigned.Size_t.to_int)
in
Functions.Memory_type.delete mem_type ;
Memory.{raw; min; max}
let mem exports name =
let kind = Types.Externkind.memory in
let extern = Resolver.find (name, kind) exports.resolved in
mem_of_extern extern
let mem0 exports =
let _, extern =
Resolver.bindings exports.resolved
|> List.find (fun ((_, kind), extern) -> kind = Types.Externkind.memory)
in
mem_of_extern extern