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
|
#ifndef IMB3_VALUE_H
#define IMB3_VALUE_H
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
/**
* Declared "for real" in gc.h.
*/
struct object;
struct value {
uintptr_t bits;
};
enum value_tag {
/**
* A big integer or the nil constant.
*/
TAG_BIGINT_OR_NIL = 0b000,
/**
* Fixnums, i.e. integers that are stored directly in the value rather than
* being pointed to. This is a two-bit tag rather than a three-bit tag...
*/
TAG_FIXNUM = 0b01,
/**
* A builtin-object.
*/
TAG_BUILTIN_OBJECT = 0b010,
/**
* A simple-array, i.e. an array of values without a fill-pointer.
*/
TAG_SIMPLE_ARRAY = 0b100,
/**
* A standard-object, effectively a pair of a class and a slot array.
*/
TAG_STANDARD_OBJECT = 0b110,
/**
* An tag that is _invalid_ for values, but may be used by the internals of
* the garbage collector.
*/
TAG_GC_INTERNAL = 0b111,
};
/**
* The nil constant.
*/
static const struct value NIL = {.bits = 0};
/**
* Allocates a builtin-object with the given class and slot count.
*/
struct value alloc_builtin_object(struct value class, size_t value_slot_count,
size_t untraced_slot_count);
/**
* Stores an intptr_t as a fixnum or a bignum.
*/
struct value integer_of_int(intptr_t);
/**
* Returns the tag of a value.
*/
enum value_tag get_tag(struct value);
/**
* Returns whether a value is a pointer.
*/
bool is_ptr(struct value);
/**
* Tags a pointer.
*/
struct value tag_ptr(struct object *, enum value_tag);
/**
* Untags a fixnum.
*/
intptr_t untag_fixnum(struct value);
/**
* Untags a pointer.
*/
struct object *untag_ptr(struct value);
struct value builtin_object_read_value_slot(const struct value, size_t);
uintptr_t builtin_object_read_untraced_slot(const struct value, size_t);
uint8_t builtin_object_read_untraced_byte(const struct value, size_t);
void builtin_object_write_value_slot(struct value, size_t, struct value);
void builtin_object_write_untraced_slot(struct value, size_t, uintptr_t);
void builtin_object_write_untraced_byte(struct value, size_t, uint8_t);
/**
* Bootstraps the class heirarchy. This should only be called once.
*/
void bootstrap(void);
#endif // IMB3_VALUE_H
|