/
serializationcontext.pmc
148 lines (128 loc) · 5.54 KB
/
serializationcontext.pmc
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
144
145
146
147
148
/* A serialization context is a container for a set of objects
* that exist per compilation unit and cross the compile-time /
* runtime boundary. */
#include "../6model/sixmodelobject.h"
static INTVAL smo_id = 0;
pmclass SerializationContext auto_attrs dynpmc group nqp {
/* The handle of this SC. */
ATTR STRING *handle;
/* The root set of objects that live in this SC. */
ATTR PMC *root_objects;
/* The root set of STables that live in this SC. */
ATTR PMC *root_stables;
/* The root set of code refs that live in this SC. */
ATTR PMC *root_codes;
/* Description (probably the file name) if any. */
ATTR STRING *description;
/* Repossession info. The following RIA and RPA have matching indexes, each
* representing the integer of an object in our root set along with the SC
* that the object was originally from. */
ATTR PMC *rep_indexes;
ATTR PMC *rep_scs;
VTABLE void init() {
PMC *root_objects = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
PMC *root_stables = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
PMC *root_codes = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
PMC *rep_indexes = Parrot_pmc_new(interp, enum_class_ResizableIntegerArray);
PMC *rep_scs = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
SET_ATTR_root_objects(interp, SELF, root_objects);
SET_ATTR_root_stables(interp, SELF, root_stables);
SET_ATTR_root_codes(interp, SELF, root_codes);
SET_ATTR_rep_indexes(interp, SELF, rep_indexes);
SET_ATTR_rep_scs(interp, SELF, rep_scs);
PObj_custom_mark_SET(SELF);
if (!smo_id)
smo_id = Parrot_pmc_get_type_str(interp, Parrot_str_new(interp, "SixModelObject", 0));
}
VTABLE void set_string_native(STRING *handle) {
SET_ATTR_handle(interp, SELF, handle);
}
VTABLE void mark() {
PMC *root_objects, *root_stables, *root_codes, *rep_indexes, *rep_scs;
STRING *handle, *description;
GET_ATTR_root_objects(interp, SELF, root_objects);
Parrot_gc_mark_PMC_alive(INTERP, root_objects);
GET_ATTR_root_stables(interp, SELF, root_stables);
Parrot_gc_mark_PMC_alive(INTERP, root_stables);
GET_ATTR_root_codes(interp, SELF, root_codes);
Parrot_gc_mark_PMC_alive(INTERP, root_codes);
GET_ATTR_handle(interp, SELF, handle);
Parrot_gc_mark_STRING_alive(INTERP, handle);
GET_ATTR_description(interp, SELF, description);
Parrot_gc_mark_STRING_alive(INTERP, description);
GET_ATTR_rep_indexes(interp, SELF, rep_indexes);
Parrot_gc_mark_PMC_alive(INTERP, rep_indexes);
GET_ATTR_rep_scs(interp, SELF, rep_scs);
Parrot_gc_mark_PMC_alive(INTERP, rep_scs);
}
VTABLE PMC* get_pmc_keyed_int(INTVAL idx) {
PMC *root_objects;
GET_ATTR_root_objects(interp, SELF, root_objects);
return VTABLE_get_pmc_keyed_int(interp, root_objects, idx);
}
VTABLE PMC* get_pmc_keyed(PMC *idx) {
PMC *root_objects;
GET_ATTR_root_objects(interp, SELF, root_objects);
return VTABLE_get_pmc_keyed(interp, root_objects, idx);
}
VTABLE void set_pmc_keyed_int(INTVAL idx, PMC *value) {
PMC *root_objects;
GET_ATTR_root_objects(interp, SELF, root_objects);
VTABLE_set_pmc_keyed_int(interp, root_objects, idx, value);
if (value->vtable->base_type == smo_id) {
/* Check if the STable is already owned; if not, take it
* for this SC. */
if (PMC_IS_NULL(STABLE(value)->sc)) {
PMC *root_stables;
GET_ATTR_root_stables(interp, SELF, root_stables);
STABLE(value)->sc = SELF;
VTABLE_push_pmc(interp, root_stables, STABLE_PMC(value));
}
}
}
VTABLE void set_pmc_keyed(PMC *idx, PMC *value) {
PMC *root_objects;
GET_ATTR_root_objects(interp, SELF, root_objects);
VTABLE_set_pmc_keyed(interp, root_objects, idx, value);
}
VTABLE INTVAL elements() {
PMC *root_objects;
GET_ATTR_root_objects(interp, SELF, root_objects);
return VTABLE_elements(interp, root_objects);
}
METHOD INTVAL elems() {
PMC *root_objects;
INTVAL elems;
GET_ATTR_root_objects(interp, SELF, root_objects);
elems = VTABLE_elements(interp, root_objects);
RETURN (INTVAL elems);
}
METHOD STRING* handle() {
STRING *handle;
GET_ATTR_handle(interp, SELF, handle);
RETURN (STRING* handle);
}
METHOD set_description(STRING *description) {
SET_ATTR_description(interp, SELF, description);
RETURN (STRING* description);
}
METHOD STRING* description() {
STRING *description;
GET_ATTR_description(interp, SELF, description);
RETURN (STRING* description);
}
METHOD INTVAL slot_index_for(PMC *obj) {
/* This is kinda stupid, but it'll do for now. */
PMC *root_objects;
INTVAL i, count;
GET_ATTR_root_objects(interp, SELF, root_objects);
count = VTABLE_elements(interp, root_objects);
for (i = 0; i < count; i++) {
if (VTABLE_get_pmc_keyed_int(interp, root_objects, i) == obj) {
RETURN (INTVAL i);
}
}
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"Object does not exist in serialization context");
}
}