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
130
131
132
use std::marker;
pub mod tag;
pub type UIntnat = usize;
pub type Intnat = isize;
pub type RawOCaml = isize;
pub type MlsizeT = UIntnat;
pub struct OCamlList<A> {
_marker: marker::PhantomData<A>,
}
pub struct OCamlBytes {}
pub type OCamlInt = Intnat;
pub struct OCamlInt32 {}
pub struct OCamlInt64 {}
pub const UNIT: RawOCaml = unsafe { raw_ocaml_of_i64(0) };
pub const NONE: RawOCaml = unsafe { raw_ocaml_of_i64(0) };
pub const EMPTY_LIST: RawOCaml = unsafe { raw_ocaml_of_i64(0) };
pub const FALSE: RawOCaml = unsafe { raw_ocaml_of_i64(0) };
pub const TRUE: RawOCaml = unsafe { raw_ocaml_of_i64(1) };
#[inline]
pub fn is_block(x: RawOCaml) -> bool {
(x & 1) == 0
}
pub fn is_long(x: RawOCaml) -> bool {
(x & 1) != 0
}
pub const fn is_exception_result(val: RawOCaml) -> bool {
val & 3 == 2
}
pub const fn extract_exception(val: RawOCaml) -> RawOCaml {
val & !3
}
#[inline]
pub unsafe fn hd_val(x: RawOCaml) -> UIntnat {
assert!(is_block(x));
*(x as *const UIntnat).offset(-1)
}
#[inline]
pub unsafe fn wosize_val(x: RawOCaml) -> UIntnat {
hd_val(x) >> 10
}
#[cfg(target_endian = "big")]
#[inline]
pub unsafe fn tag_val(x: RawOCaml) -> tag::Tag {
*(x as *const u8).offset(-1)
}
#[cfg(target_endian = "little")]
#[inline]
pub unsafe fn tag_val(x: RawOCaml) -> tag::Tag {
*(x as *const u8).offset(-(core::mem::size_of::<RawOCaml>() as isize))
}
#[inline]
unsafe fn bp_val(val: RawOCaml) -> *mut u8 {
assert!(is_block(val));
val as *mut u8
}
#[inline]
pub unsafe fn string_val(val: RawOCaml) -> *mut u8 {
bp_val(val)
}
#[inline]
pub unsafe fn field_val(val: RawOCaml, i: UIntnat) -> *mut RawOCaml {
(val as *mut RawOCaml).add(i)
}
#[inline]
pub unsafe fn raw_ocaml_to_i64(raw: RawOCaml) -> i64 {
assert!(!is_block(raw));
(raw >> 1) as i64
}
#[inline]
pub const unsafe fn raw_ocaml_of_i64(n: i64) -> RawOCaml {
((n << 1) | 1) as RawOCaml
}