|
7 | 7 | /* This representation's function pointer table. */
|
8 | 8 | static REPROps *this_repr;
|
9 | 9 |
|
| 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 | + |
10 | 159 | /* Creates a new type object of this representation, and associates it with
|
11 | 160 | * the given HOW. */
|
12 | 161 | 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) {
|
70 | 219 | }
|
71 | 220 |
|
72 | 221 | 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 | + } |
74 | 239 | }
|
75 | 240 |
|
76 | 241 | 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 | + } |
78 | 262 | }
|
79 | 263 |
|
80 | 264 | 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
|
121 | 305 | "VMArray: Can't perform boxed %s when containing native types", operation);
|
122 | 306 | }
|
123 | 307 |
|
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 |
| - |
192 | 308 | static void gc_mark(PARROT_INTERP, STable *st, void *data) {
|
193 | 309 | /* TODO: If we contain PMC, mark all of them that are non-NULL. */
|
194 | 310 | VMArrayBody *body = (VMArrayBody *) data;
|
@@ -216,87 +332,6 @@ static void gc_free(PARROT_INTERP, PMC *obj) {
|
216 | 332 | mem_sys_free(instance);
|
217 | 333 | }
|
218 | 334 |
|
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 |
| - |
300 | 335 | static void at_pos_native(PARROT_INTERP, STable *st, void *data, INTVAL index, NativeValue *value) {
|
301 | 336 | VMArrayBody *body = (VMArrayBody *) data;
|
302 | 337 | VMArrayREPRData *repr_data = (VMArrayREPRData *) st->REPR_data;
|
|
0 commit comments