Permalink
Browse files

Serialize and deserialize VMArrays.

  • Loading branch information...
1 parent e45782b commit 7399985defb17cf15b4fdcb3f05ab4e5513955bc @arnsholt arnsholt committed Mar 10, 2013
Showing with 186 additions and 151 deletions.
  1. +186 −151 src/6model/reprs/VMArray.c
View
@@ -7,6 +7,155 @@
/* This representation's function pointer table. */
static REPROps *this_repr;
+/* Wrapper functions to set and get an array offset to a value for the various
+ * types we support. */
+static void set_pos_int(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset, INTVAL val) {
+ switch(repr_data->elem_size) {
+ case 8:
+ ((Parrot_Int1 *) body->slots)[offset] = (Parrot_Int1) val;
+ break;
+ case 16:
+ ((Parrot_Int2 *) body->slots)[offset] = (Parrot_Int2) val;
+ break;
+ case 32:
+ ((Parrot_Int4 *) body->slots)[offset] = (Parrot_Int4) val;
+ break;
+ case 64:
+ ((Parrot_Int8 *) body->slots)[offset] = (Parrot_Int8) val;
+ break;
+ default:
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "VMArray: Only supports 8, 16, 32 and 64 bit integers.");
+ }
+}
+
+static void set_pos_float(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset, FLOATVAL val) {
+ switch(repr_data->elem_size) {
+ case 32:
+ ((Parrot_Float4 *) body->slots)[offset] = (Parrot_Float4) val;
+ break;
+ case 64:
+ ((Parrot_Float8 *) body->slots)[offset] = (Parrot_Float8) val;
+ break;
+ default:
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "VMArray: Only supports 32 and 64 bit floats.");
+ }
+}
+
+static void set_pos_pmc(PMC **slots, INTVAL offset, PMC *obj) { slots[offset] = obj; }
+
+/* Convenience method to set a given offset to a sensible NULL value. */
+static void null_pos(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset) {
+ if(!repr_data->elem_size) {
+ set_pos_pmc((PMC **) body->slots, offset, PMCNULL);
+ }
+ else if(repr_data->elem_kind == STORAGE_SPEC_BP_INT) {
+ set_pos_int(interp, body, repr_data, offset, 0);
+ }
+ else if(repr_data->elem_kind == STORAGE_SPEC_BP_NUM) {
+ set_pos_float(interp, body, repr_data, offset, 0.0);
+ }
+ else {
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "VMArray: unsupported elem_kind (%d) in null_pos", repr_data->elem_kind);
+ }
+}
+
+/* Ensure that the array has enough size */
+static void ensure_size(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL n) {
+ INTVAL elems = body->elems;
+ INTVAL start = body->start;
+ INTVAL ssize = body->ssize;
+ void *slots = body->slots;
+ INTVAL elem_size = repr_data->elem_size/8;
+
+ if(n < 0) {
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "VMArray: Can't resize to negative size");
+ }
+
+ if(n == elems) { return; }
+
+ /* If there aren't enough slots at the end, shift off empty slots
+ * from the beginning first */
+ if (start > 0 && n + start > ssize) {
+ if (elems > 0) {
+ void *src = ((char *) slots) + start*elem_size;
+ memmove(slots, src, elems * elem_size);
+ }
+ body->start = 0;
+ /* fill out any unused slots with PMCNULL pointers */
+ while (elems < ssize) {
+ null_pos(interp, body, repr_data, elems);
+ elems++;
+ }
+ }
+
+ body->elems = n;
+ if (n <= ssize) {
+ /* We already have n slots available, we can just return */
+ return;
+ }
+
+ /* We need more slots. If the current slot size is less
+ * than 8K, use the larger of twice the current slot size
+ * or the actual number of elements needed. Otherwise,
+ * grow the slots to the next multiple of 4096 (0x1000). */
+ if (ssize < 8192) {
+ ssize *= 2;
+ if (n > ssize) ssize = n;
+ if (ssize < 8) ssize = 8;
+ }
+ else {
+ ssize = (n + 0x1000) & ~0xfff;
+ }
+
+ /* Now allocate the new slot buffer */
+ slots = (slots)
+ ? mem_sys_realloc(slots, ssize*elem_size)
+ : mem_sys_allocate(ssize*elem_size);
+
+ /* Fill out any unused slots with PMCNULL pointers */
+ while (elems < ssize) {
+ null_pos(interp, body, repr_data, elems);
+ elems++;
+ }
+
+ body->ssize = ssize;
+ body->slots = slots;
+}
+
+static INTVAL get_pos_int(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset) {
+ switch(repr_data->elem_size) {
+ case 8:
+ return ((Parrot_Int1 *) body->slots)[offset];
+ case 16:
+ return ((Parrot_Int2 *) body->slots)[offset];
+ case 32:
+ return ((Parrot_Int4 *) body->slots)[offset];
+ case 64:
+ return ((Parrot_Int8 *) body->slots)[offset];
+ default:
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "VMArray: Only supports 8, 16, 32 and 64 bit integers.");
+ }
+}
+
+static FLOATVAL get_pos_float(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset) {
+ switch(repr_data->elem_size) {
+ case 32:
+ return ((Parrot_Float4 *) body->slots)[offset];
+ case 64:
+ return ((Parrot_Float8 *) body->slots)[offset];
+ default:
+ Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
+ "VMArray: Only supports 32 and 64 bit floats.");
+ }
+}
+
+static PMC *get_pos_pmc(PMC **slots, INTVAL offset) { return slots[offset]; }
+
/* Creates a new type object of this representation, and associates it with
* the given HOW. */
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) {
}
static void serialize(PARROT_INTERP, STable *st, void *data, SerializationWriter *writer) {
- /* TODO */
+ VMArrayBody *body = (VMArrayBody *) data;
+ VMArrayREPRData *repr_data = (VMArrayREPRData *) st->REPR_data;
+ INTVAL i;
+
+ writer->write_int(interp, writer, body->elems);
+ for(i = 0; i < body->elems; i++) {
+ INTVAL offset = body->start + i;
+ if(repr_data->elem_size && repr_data->elem_kind == STORAGE_SPEC_BP_INT) {
+ writer->write_int(interp, writer, get_pos_int(interp, body, repr_data, offset));
+ }
+ else if(repr_data->elem_size && repr_data->elem_kind == STORAGE_SPEC_BP_NUM) {
+ writer->write_num(interp, writer, get_pos_float(interp, body, repr_data, offset));
+ }
+ else {
+ writer->write_ref(interp, writer, get_pos_pmc((PMC **) body->slots, offset));
+ }
+ }
}
static void deserialize(PARROT_INTERP, STable *st, void *data, SerializationReader *reader) {
- /* TODO */
+ VMArrayBody *body = (VMArrayBody *) data;
+ VMArrayREPRData *repr_data = (VMArrayREPRData *) st->REPR_data;
+ INTVAL elems = reader->read_int(interp, reader);
+ INTVAL i;
+
+ ensure_size(interp, body, repr_data, elems);
+ body->elems = elems;
+
+ for(i = 0; i < body->elems; i++) {
+ INTVAL offset = body->start + i;
+ if(repr_data->elem_size && repr_data->elem_kind == STORAGE_SPEC_BP_INT) {
+ set_pos_int(interp, body, repr_data, offset, reader->read_int(interp, reader));
+ }
+ else if(repr_data->elem_size && repr_data->elem_kind == STORAGE_SPEC_BP_NUM) {
+ set_pos_float(interp, body, repr_data, offset, reader->read_num(interp, reader));
+ }
+ else {
+ set_pos_pmc((PMC **) body->slots, offset, reader->read_ref(interp, reader));
+ }
+ }
}
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
"VMArray: Can't perform boxed %s when containing native types", operation);
}
-/* Wrapper functions to set and get an array offset to a value for the various
- * types we support. */
-static void set_pos_int(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset, INTVAL val) {
- switch(repr_data->elem_size) {
- case 8:
- ((Parrot_Int1 *) body->slots)[offset] = (Parrot_Int1) val;
- break;
- case 16:
- ((Parrot_Int2 *) body->slots)[offset] = (Parrot_Int2) val;
- break;
- case 32:
- ((Parrot_Int4 *) body->slots)[offset] = (Parrot_Int4) val;
- break;
- case 64:
- ((Parrot_Int8 *) body->slots)[offset] = (Parrot_Int8) val;
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "VMArray: Only supports 8, 16, 32 and 64 bit integers.");
- }
-}
-
-static void set_pos_float(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset, FLOATVAL val) {
- switch(repr_data->elem_size) {
- case 32:
- ((Parrot_Float4 *) body->slots)[offset] = (Parrot_Float4) val;
- break;
- case 64:
- ((Parrot_Float8 *) body->slots)[offset] = (Parrot_Float8) val;
- break;
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "VMArray: Only supports 32 and 64 bit floats.");
- }
-}
-
-static void set_pos_pmc(PMC **slots, INTVAL offset, PMC *obj) { slots[offset] = obj; }
-
-static INTVAL get_pos_int(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset) {
- switch(repr_data->elem_size) {
- case 8:
- return ((Parrot_Int1 *) body->slots)[offset];
- case 16:
- return ((Parrot_Int2 *) body->slots)[offset];
- case 32:
- return ((Parrot_Int4 *) body->slots)[offset];
- case 64:
- return ((Parrot_Int8 *) body->slots)[offset];
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "VMArray: Only supports 8, 16, 32 and 64 bit integers.");
- }
-}
-
-static FLOATVAL get_pos_float(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset) {
- switch(repr_data->elem_size) {
- case 32:
- return ((Parrot_Float4 *) body->slots)[offset];
- case 64:
- return ((Parrot_Float8 *) body->slots)[offset];
- default:
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "VMArray: Only supports 32 and 64 bit floats.");
- }
-}
-
-static PMC *get_pos_pmc(PMC **slots, INTVAL offset) { return slots[offset]; }
-
static void gc_mark(PARROT_INTERP, STable *st, void *data) {
/* TODO: If we contain PMC, mark all of them that are non-NULL. */
VMArrayBody *body = (VMArrayBody *) data;
@@ -216,87 +332,6 @@ static void gc_free(PARROT_INTERP, PMC *obj) {
mem_sys_free(instance);
}
-/* Convenience method to set a given offset to a sensible NULL value. */
-static void null_pos(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL offset) {
- if(!repr_data->elem_size) {
- set_pos_pmc((PMC **) body->slots, offset, PMCNULL);
- }
- else if(repr_data->elem_kind == STORAGE_SPEC_BP_INT) {
- set_pos_int(interp, body, repr_data, offset, 0);
- }
- else if(repr_data->elem_kind == STORAGE_SPEC_BP_NUM) {
- set_pos_float(interp, body, repr_data, offset, 0.0);
- }
- else {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "VMArray: unsupported elem_kind (%d) in null_pos", repr_data->elem_kind);
- }
-}
-
-/* Ensure that the array has enough size */
-static void ensure_size(PARROT_INTERP, VMArrayBody *body, VMArrayREPRData *repr_data, INTVAL n) {
- INTVAL elems = body->elems;
- INTVAL start = body->start;
- INTVAL ssize = body->ssize;
- void *slots = body->slots;
- INTVAL elem_size = repr_data->elem_size/8;
-
- if(n < 0) {
- Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "VMArray: Can't resize to negative size");
- }
-
- if(n == elems) { return; }
-
- /* If there aren't enough slots at the end, shift off empty slots
- * from the beginning first */
- if (start > 0 && n + start > ssize) {
- if (elems > 0) {
- void *src = ((char *) slots) + start*elem_size;
- memmove(slots, src, elems * elem_size);
- }
- body->start = 0;
- /* fill out any unused slots with PMCNULL pointers */
- while (elems < ssize) {
- null_pos(interp, body, repr_data, elems);
- elems++;
- }
- }
-
- body->elems = n;
- if (n <= ssize) {
- /* We already have n slots available, we can just return */
- return;
- }
-
- /* We need more slots. If the current slot size is less
- * than 8K, use the larger of twice the current slot size
- * or the actual number of elements needed. Otherwise,
- * grow the slots to the next multiple of 4096 (0x1000). */
- if (ssize < 8192) {
- ssize *= 2;
- if (n > ssize) ssize = n;
- if (ssize < 8) ssize = 8;
- }
- else {
- ssize = (n + 0x1000) & ~0xfff;
- }
-
- /* Now allocate the new slot buffer */
- slots = (slots)
- ? mem_sys_realloc(slots, ssize*elem_size)
- : mem_sys_allocate(ssize*elem_size);
-
- /* Fill out any unused slots with PMCNULL pointers */
- while (elems < ssize) {
- null_pos(interp, body, repr_data, elems);
- elems++;
- }
-
- body->ssize = ssize;
- body->slots = slots;
-}
-
static void at_pos_native(PARROT_INTERP, STable *st, void *data, INTVAL index, NativeValue *value) {
VMArrayBody *body = (VMArrayBody *) data;
VMArrayREPRData *repr_data = (VMArrayREPRData *) st->REPR_data;

0 comments on commit 7399985

Please sign in to comment.