Skip to content

Commit 7399985

Browse files
committed
Serialize and deserialize VMArrays.
1 parent e45782b commit 7399985

File tree

1 file changed

+186
-151
lines changed

1 file changed

+186
-151
lines changed

src/6model/reprs/VMArray.c

Lines changed: 186 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,155 @@
77
/* This representation's function pointer table. */
88
static REPROps *this_repr;
99

10+
/* Wrapper functions to set and get an array offset to a value for the various
11+
* types we support. */
12+
static void set_pos_int(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset, INTVAL val) {
13+
switch(repr_data->elem_size) {
14+
case 8:
15+
((Parrot_Int1 *) body->slots)[offset] = (Parrot_Int1) val;
16+
break;
17+
case 16:
18+
((Parrot_Int2 *) body->slots)[offset] = (Parrot_Int2) val;
19+
break;
20+
case 32:
21+
((Parrot_Int4 *) body->slots)[offset] = (Parrot_Int4) val;
22+
break;
23+
case 64:
24+
((Parrot_Int8 *) body->slots)[offset] = (Parrot_Int8) val;
25+
break;
26+
default:
27+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
28+
"VMArray: Only supports 8, 16, 32 and 64 bit integers.");
29+
}
30+
}
31+
32+
static void set_pos_float(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset, FLOATVAL val) {
33+
switch(repr_data->elem_size) {
34+
case 32:
35+
((Parrot_Float4 *) body->slots)[offset] = (Parrot_Float4) val;
36+
break;
37+
case 64:
38+
((Parrot_Float8 *) body->slots)[offset] = (Parrot_Float8) val;
39+
break;
40+
default:
41+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
42+
"VMArray: Only supports 32 and 64 bit floats.");
43+
}
44+
}
45+
46+
static void set_pos_pmc(PMC **slots, INTVAL offset, PMC *obj) { slots[offset] = obj; }
47+
48+
/* Convenience method to set a given offset to a sensible NULL value. */
49+
static void null_pos(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset) {
50+
if(!repr_data->elem_size) {
51+
set_pos_pmc((PMC **) body->slots, offset, PMCNULL);
52+
}
53+
else if(repr_data->elem_kind == STORAGE_SPEC_BP_INT) {
54+
set_pos_int(interp, body, repr_data, offset, 0);
55+
}
56+
else if(repr_data->elem_kind == STORAGE_SPEC_BP_NUM) {
57+
set_pos_float(interp, body, repr_data, offset, 0.0);
58+
}
59+
else {
60+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
61+
"VMArray: unsupported elem_kind (%d) in null_pos", repr_data->elem_kind);
62+
}
63+
}
64+
65+
/* Ensure that the array has enough size */
66+
static void ensure_size(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL n) {
67+
INTVAL elems = body->elems;
68+
INTVAL start = body->start;
69+
INTVAL ssize = body->ssize;
70+
void *slots = body->slots;
71+
INTVAL elem_size = repr_data->elem_size/8;
72+
73+
if(n < 0) {
74+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
75+
"VMArray: Can't resize to negative size");
76+
}
77+
78+
if(n == elems) { return; }
79+
80+
/* If there aren't enough slots at the end, shift off empty slots
81+
* from the beginning first */
82+
if (start > 0 && n + start > ssize) {
83+
if (elems > 0) {
84+
void *src = ((char *) slots) + start*elem_size;
85+
memmove(slots, src, elems * elem_size);
86+
}
87+
body->start = 0;
88+
/* fill out any unused slots with PMCNULL pointers */
89+
while (elems < ssize) {
90+
null_pos(interp, body, repr_data, elems);
91+
elems++;
92+
}
93+
}
94+
95+
body->elems = n;
96+
if (n <= ssize) {
97+
/* We already have n slots available, we can just return */
98+
return;
99+
}
100+
101+
/* We need more slots. If the current slot size is less
102+
* than 8K, use the larger of twice the current slot size
103+
* or the actual number of elements needed. Otherwise,
104+
* grow the slots to the next multiple of 4096 (0x1000). */
105+
if (ssize < 8192) {
106+
ssize *= 2;
107+
if (n > ssize) ssize = n;
108+
if (ssize < 8) ssize = 8;
109+
}
110+
else {
111+
ssize = (n + 0x1000) & ~0xfff;
112+
}
113+
114+
/* Now allocate the new slot buffer */
115+
slots = (slots)
116+
? mem_sys_realloc(slots, ssize*elem_size)
117+
: mem_sys_allocate(ssize*elem_size);
118+
119+
/* Fill out any unused slots with PMCNULL pointers */
120+
while (elems < ssize) {
121+
null_pos(interp, body, repr_data, elems);
122+
elems++;
123+
}
124+
125+
body->ssize = ssize;
126+
body->slots = slots;
127+
}
128+
129+
static INTVAL get_pos_int(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset) {
130+
switch(repr_data->elem_size) {
131+
case 8:
132+
return ((Parrot_Int1 *) body->slots)[offset];
133+
case 16:
134+
return ((Parrot_Int2 *) body->slots)[offset];
135+
case 32:
136+
return ((Parrot_Int4 *) body->slots)[offset];
137+
case 64:
138+
return ((Parrot_Int8 *) body->slots)[offset];
139+
default:
140+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
141+
"VMArray: Only supports 8, 16, 32 and 64 bit integers.");
142+
}
143+
}
144+
145+
static FLOATVAL get_pos_float(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset) {
146+
switch(repr_data->elem_size) {
147+
case 32:
148+
return ((Parrot_Float4 *) body->slots)[offset];
149+
case 64:
150+
return ((Parrot_Float8 *) body->slots)[offset];
151+
default:
152+
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
153+
"VMArray: Only supports 32 and 64 bit floats.");
154+
}
155+
}
156+
157+
static PMC *get_pos_pmc(PMC **slots, INTVAL offset) { return slots[offset]; }
158+
10159
/* Creates a new type object of this representation, and associates it with
11160
* the given HOW. */
12161
static PMC * type_object_for(PARROT_INTERP, PMC *HOW) {
@@ -70,11 +219,46 @@ static void copy_to(PARROT_INTERP, STable *st, void *src, void *dest) {
70219
}
71220

72221
static void serialize(PARROT_INTERP, STable *st, void *data, SerializationWriter *writer) {
73-
/* TODO */
222+
VMArrayBody *body = (VMArrayBody *) data;
223+
VMArrayREPRData *repr_data = (VMArrayREPRData *) st->REPR_data;
224+
INTVAL i;
225+
226+
writer->write_int(interp, writer, body->elems);
227+
for(i = 0; i < body->elems; i++) {
228+
INTVAL offset = body->start + i;
229+
if(repr_data->elem_size && repr_data->elem_kind == STORAGE_SPEC_BP_INT) {
230+
writer->write_int(interp, writer, get_pos_int(interp, body, repr_data, offset));
231+
}
232+
else if(repr_data->elem_size && repr_data->elem_kind == STORAGE_SPEC_BP_NUM) {
233+
writer->write_num(interp, writer, get_pos_float(interp, body, repr_data, offset));
234+
}
235+
else {
236+
writer->write_ref(interp, writer, get_pos_pmc((PMC **) body->slots, offset));
237+
}
238+
}
74239
}
75240

76241
static void deserialize(PARROT_INTERP, STable *st, void *data, SerializationReader *reader) {
77-
/* TODO */
242+
VMArrayBody *body = (VMArrayBody *) data;
243+
VMArrayREPRData *repr_data = (VMArrayREPRData *) st->REPR_data;
244+
INTVAL elems = reader->read_int(interp, reader);
245+
INTVAL i;
246+
247+
ensure_size(interp, body, repr_data, elems);
248+
body->elems = elems;
249+
250+
for(i = 0; i < body->elems; i++) {
251+
INTVAL offset = body->start + i;
252+
if(repr_data->elem_size && repr_data->elem_kind == STORAGE_SPEC_BP_INT) {
253+
set_pos_int(interp, body, repr_data, offset, reader->read_int(interp, reader));
254+
}
255+
else if(repr_data->elem_size && repr_data->elem_kind == STORAGE_SPEC_BP_NUM) {
256+
set_pos_float(interp, body, repr_data, offset, reader->read_num(interp, reader));
257+
}
258+
else {
259+
set_pos_pmc((PMC **) body->slots, offset, reader->read_ref(interp, reader));
260+
}
261+
}
78262
}
79263

80264
static void serialize_repr_data(PARROT_INTERP, STable *st, SerializationWriter *writer) {
@@ -121,74 +305,6 @@ PARROT_DOES_NOT_RETURN static void die_no_boxed(PARROT_INTERP, const char *opera
121305
"VMArray: Can't perform boxed %s when containing native types", operation);
122306
}
123307

124-
/* Wrapper functions to set and get an array offset to a value for the various
125-
* types we support. */
126-
static void set_pos_int(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset, INTVAL val) {
127-
switch(repr_data->elem_size) {
128-
case 8:
129-
((Parrot_Int1 *) body->slots)[offset] = (Parrot_Int1) val;
130-
break;
131-
case 16:
132-
((Parrot_Int2 *) body->slots)[offset] = (Parrot_Int2) val;
133-
break;
134-
case 32:
135-
((Parrot_Int4 *) body->slots)[offset] = (Parrot_Int4) val;
136-
break;
137-
case 64:
138-
((Parrot_Int8 *) body->slots)[offset] = (Parrot_Int8) val;
139-
break;
140-
default:
141-
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
142-
"VMArray: Only supports 8, 16, 32 and 64 bit integers.");
143-
}
144-
}
145-
146-
static void set_pos_float(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset, FLOATVAL val) {
147-
switch(repr_data->elem_size) {
148-
case 32:
149-
((Parrot_Float4 *) body->slots)[offset] = (Parrot_Float4) val;
150-
break;
151-
case 64:
152-
((Parrot_Float8 *) body->slots)[offset] = (Parrot_Float8) val;
153-
break;
154-
default:
155-
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
156-
"VMArray: Only supports 32 and 64 bit floats.");
157-
}
158-
}
159-
160-
static void set_pos_pmc(PMC **slots, INTVAL offset, PMC *obj) { slots[offset] = obj; }
161-
162-
static INTVAL get_pos_int(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset) {
163-
switch(repr_data->elem_size) {
164-
case 8:
165-
return ((Parrot_Int1 *) body->slots)[offset];
166-
case 16:
167-
return ((Parrot_Int2 *) body->slots)[offset];
168-
case 32:
169-
return ((Parrot_Int4 *) body->slots)[offset];
170-
case 64:
171-
return ((Parrot_Int8 *) body->slots)[offset];
172-
default:
173-
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
174-
"VMArray: Only supports 8, 16, 32 and 64 bit integers.");
175-
}
176-
}
177-
178-
static FLOATVAL get_pos_float(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset) {
179-
switch(repr_data->elem_size) {
180-
case 32:
181-
return ((Parrot_Float4 *) body->slots)[offset];
182-
case 64:
183-
return ((Parrot_Float8 *) body->slots)[offset];
184-
default:
185-
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
186-
"VMArray: Only supports 32 and 64 bit floats.");
187-
}
188-
}
189-
190-
static PMC *get_pos_pmc(PMC **slots, INTVAL offset) { return slots[offset]; }
191-
192308
static void gc_mark(PARROT_INTERP, STable *st, void *data) {
193309
/* TODO: If we contain PMC, mark all of them that are non-NULL. */
194310
VMArrayBody *body = (VMArrayBody *) data;
@@ -216,87 +332,6 @@ static void gc_free(PARROT_INTERP, PMC *obj) {
216332
mem_sys_free(instance);
217333
}
218334

219-
/* Convenience method to set a given offset to a sensible NULL value. */
220-
static void null_pos(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset) {
221-
if(!repr_data->elem_size) {
222-
set_pos_pmc((PMC **) body->slots, offset, PMCNULL);
223-
}
224-
else if(repr_data->elem_kind == STORAGE_SPEC_BP_INT) {
225-
set_pos_int(interp, body, repr_data, offset, 0);
226-
}
227-
else if(repr_data->elem_kind == STORAGE_SPEC_BP_NUM) {
228-
set_pos_float(interp, body, repr_data, offset, 0.0);
229-
}
230-
else {
231-
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
232-
"VMArray: unsupported elem_kind (%d) in null_pos", repr_data->elem_kind);
233-
}
234-
}
235-
236-
/* Ensure that the array has enough size */
237-
static void ensure_size(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL n) {
238-
INTVAL elems = body->elems;
239-
INTVAL start = body->start;
240-
INTVAL ssize = body->ssize;
241-
void *slots = body->slots;
242-
INTVAL elem_size = repr_data->elem_size/8;
243-
244-
if(n < 0) {
245-
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
246-
"VMArray: Can't resize to negative size");
247-
}
248-
249-
if(n == elems) { return; }
250-
251-
/* If there aren't enough slots at the end, shift off empty slots
252-
* from the beginning first */
253-
if (start > 0 && n + start > ssize) {
254-
if (elems > 0) {
255-
void *src = ((char *) slots) + start*elem_size;
256-
memmove(slots, src, elems * elem_size);
257-
}
258-
body->start = 0;
259-
/* fill out any unused slots with PMCNULL pointers */
260-
while (elems < ssize) {
261-
null_pos(interp, body, repr_data, elems);
262-
elems++;
263-
}
264-
}
265-
266-
body->elems = n;
267-
if (n <= ssize) {
268-
/* We already have n slots available, we can just return */
269-
return;
270-
}
271-
272-
/* We need more slots. If the current slot size is less
273-
* than 8K, use the larger of twice the current slot size
274-
* or the actual number of elements needed. Otherwise,
275-
* grow the slots to the next multiple of 4096 (0x1000). */
276-
if (ssize < 8192) {
277-
ssize *= 2;
278-
if (n > ssize) ssize = n;
279-
if (ssize < 8) ssize = 8;
280-
}
281-
else {
282-
ssize = (n + 0x1000) & ~0xfff;
283-
}
284-
285-
/* Now allocate the new slot buffer */
286-
slots = (slots)
287-
? mem_sys_realloc(slots, ssize*elem_size)
288-
: mem_sys_allocate(ssize*elem_size);
289-
290-
/* Fill out any unused slots with PMCNULL pointers */
291-
while (elems < ssize) {
292-
null_pos(interp, body, repr_data, elems);
293-
elems++;
294-
}
295-
296-
body->ssize = ssize;
297-
body->slots = slots;
298-
}
299-
300335
static void at_pos_native(PARROT_INTERP, STable *st, void *data, INTVAL index, NativeValue *value) {
301336
VMArrayBody *body = (VMArrayBody *) data;
302337
VMArrayREPRData *repr_data = (VMArrayREPRData *) st->REPR_data;

0 commit comments

Comments
 (0)