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
open Fmt
type 'a get_ref =
| Null
| Ref_value of 'a
| Type_mismatch
module Extern = struct
type t = E : 'a Type.Id.t * 'a -> t
let cast (type r) (E (rty, r) : t) (ty : r Type.Id.t) : r option =
match Type.Id.provably_equal rty ty with
| None -> None
| Some Equal -> Some r
end
type t =
| Extern of Extern.t option
| Func of Kind.func option
| NullExn
| NullRef
let pp fmt = function
| Extern None -> pf fmt "externref none"
| Extern _ -> pf fmt "externref"
| Func _ -> pf fmt "funcref"
| NullExn -> pf fmt "nullexnref"
| NullRef -> pf fmt "nullref"
(* TODO: Is this the same as Symbolic_ref.null? *)
let null = function
| Binary.Func_ht | NoFunc_ht | TypeUse _ -> Func None
(* TODO: is this correct? Are all nulls equal? *)
| Extern_ht | NoExtern_ht -> Extern None
| Any_ht | None_ht -> NullRef
| Exn_ht | NoExn_ht -> NullExn
let func (f : Kind.func) = Func (Some f)
let extern (type x) (t : x Type.Id.t) (v : x) : t = Extern (Some (E (t, v)))
let is_null = function
| Func None | Extern None | NullExn | NullRef -> true
| Func (Some _) | Extern (Some _) -> false
let get_func (r : t) : Kind.func get_ref =
match r with
| Func (Some f) -> Ref_value f
| Func None -> Null
| _ -> Type_mismatch
let get_extern (type x) (r : t) (typ : x Type.Id.t) : x get_ref =
match r with
| Extern (Some (E (ety, v))) -> (
match Type.Id.provably_equal typ ety with
| None -> assert false
| Some Equal -> Ref_value v )
| _ -> assert false