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
(* SPDX-License-Identifier: AGPL-3.0-or-later *)
(* Copyright © 2021-2024 OCamlPro *)
(* Written by the Owi programmers *)
open Types
open Fmt
type externref = E : 'a Type.Id.t * 'a -> externref
let cast_ref (type r) (E (rty, r) : externref) (ty : r Type.Id.t) : r option =
match Type.Id.provably_equal rty ty with None -> None | Some Equal -> Some r
type ref_value =
| Externref of externref option
| Funcref of Func_intf.t option
| Arrayref of unit Array.t option
let pp_ref_value fmt = function
| Externref _ -> pf fmt "externref"
| Funcref _ -> pf fmt "funcref"
| Arrayref _ -> pf fmt "array"
type t =
| I32 of Int32.t
| I64 of Int64.t
| F32 of Float32.t
| F64 of Float64.t
| Ref of ref_value
(* TODO: make a new kind of instr for this *)
let of_instr (i : binary instr) : t =
match i with
| I32_const c -> I32 c
| I64_const c -> I64 c
| F32_const c -> F32 c
| F64_const c -> F64 c
| _ -> assert false
let to_instr = function
| I32 c -> I32_const c
| I64 c -> I64_const c
| F32 c -> F32_const c
| F64 c -> F64_const c
| Ref _ -> assert false
let pp fmt = function
| I32 i -> pf fmt "i32.const %ld" i
| I64 i -> pf fmt "i64.const %Ld" i
| F32 f -> pf fmt "f32.const %a" Float32.pp f
| F64 f -> pf fmt "f64.const %a" Float64.pp f
| Ref r -> pp_ref_value fmt r
let ref_null' = function
| Func_ht -> Funcref None
| Extern_ht -> Externref None
| Array_ht -> Arrayref None
| Any_ht | None_ht | Eq_ht | I31_ht | Struct_ht | No_func_ht | No_extern_ht
| Def_ht _ ->
assert false
let ref_null typ = Ref (ref_null' typ)
let ref_func (f : Concrete_extern_func.t) : t = Ref (Funcref (Some f))
let ref_externref (type x) (t : x Type.Id.t) (v : x) : t =
Ref (Externref (Some (E (t, v))))
let ref_is_null = function
| Funcref None | Externref None | Arrayref None -> true
| Funcref (Some _) | Externref (Some _) | Arrayref (Some _) -> false