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
133
134
135
136
137
138
139
140
141
142
143
use crate::tag::Tag;
pub type Value = isize;
pub type Intnat = isize;
pub type Uintnat = usize;
pub type Size = Uintnat;
pub type Color = Uintnat;
pub type Mark = Uintnat;
pub type Header = Uintnat;
#[cfg(target_endian = "big")]
#[inline]
pub const unsafe fn tag_val(val: Value) -> Tag {
*(val as *const u8).offset(-1)
}
#[cfg(target_endian = "little")]
#[inline]
pub unsafe fn tag_val(val: Value) -> Tag {
*(val as *const u8).offset(-(core::mem::size_of::<Value>() as isize))
}
#[inline]
pub unsafe fn hd_val(val: Value) -> Header {
*(val as *const Header).offset(-1)
}
#[inline]
pub unsafe fn wosize_val(val: Value) -> Size {
hd_val(val) >> 10
}
pub const unsafe fn val_int(i: isize) -> Value {
((i as isize) << 1) + 1
}
pub const unsafe fn int_val(val: Value) -> isize {
((val as isize) >> 1) as isize
}
pub fn is_block(v: Value) -> bool {
(v & 1) == 0
}
pub const fn is_long(v: Value) -> bool {
(v & 1) != 0
}
pub const MAX_FIXNUM: Intnat = (1 << (8 * core::mem::size_of::<Intnat>() - 2)) - 1;
pub const MIN_FIXNUM: Intnat = -(1 << (8 * core::mem::size_of::<Intnat>() - 2));
pub unsafe fn field(block: Value, index: usize) -> *mut Value {
(block as *mut Value).add(index)
}
pub const UNIT: Value = unsafe { val_int(0) };
pub const NONE: Value = unsafe { val_int(0) };
pub const EMPTY_LIST: Value = unsafe { val_int(0) };
pub const TRUE: Value = unsafe { val_int(1) };
pub const FALSE: Value = unsafe { val_int(0) };
pub const TAG_CONS: Tag = 0;
pub const TAG_SOME: Tag = 0;
#[inline]
pub const unsafe fn bp_val(val: Value) -> *const u8 {
val as *const u8
}
#[inline]
pub const unsafe fn string_val(val: Value) -> *mut u8 {
val as *mut u8
}
extern "C" {
pub fn caml_string_length(value: Value) -> Size;
pub fn caml_array_length(value: Value) -> Size;
pub fn caml_hash_variant(tag: *const u8) -> Value;
pub fn caml_get_public_method(obj: Value, tag: Value) -> Value;
}