Skip to content

Instantly share code, notes, and snippets.

@arnsholt
Created January 27, 2013 14:40
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save arnsholt/4648660 to your computer and use it in GitHub Desktop.
diff --git a/src/6model/reprs/P6int.c b/src/6model/reprs/P6int.c
index ec9c1d2..c5fedd4 100644
--- a/src/6model/reprs/P6int.c
+++ b/src/6model/reprs/P6int.c
@@ -13,15 +13,20 @@ static REPROps *this_repr;
/* Creates a new type object of this representation, and associates it with
* the given HOW. */
static PMC * type_object_for(PARROT_INTERP, PMC *HOW) {
- /* Create new object instance. */
+ /* Create new object instance and REPR data. */
P6intInstance *obj = mem_allocate_zeroed_typed(P6intInstance);
+ P6intREPRData *repr_data = mem_allocate_zeroed_typed(P6intREPRData);
/* Build an STable. */
PMC *st_pmc = create_stable(interp, this_repr, HOW);
STable *st = STABLE_STRUCT(st_pmc);
- /* Attach a REPR data object to the STable. */
- st->REPR_data = mem_allocate_zeroed_typed(P6intREPRData);
+ /* Set default align and bit width values in the REPR data and attach it
+ * to the STable. */
+ repr_data->bits = sizeof(INTVAL)*8;
+ repr_data->align = ALIGNOF1(INTVAL);
+ st->REPR_data = repr_data;
+ printf("type_object_for: %ld/%ld\n", repr_data->bits, repr_data->align);
/* Create type object and point it back at the STable. */
obj->common.stable = st_pmc;
@@ -37,11 +42,40 @@ static PMC * type_object_for(PARROT_INTERP, PMC *HOW) {
/* Composes the representation. */
static void compose(PARROT_INTERP, STable *st, PMC *repr_info) {
/* Nothing to do yet (but later, size). */
- /* TODO: Set bit width and alignment requirements. */
P6intREPRData *repr_data = (P6intREPRData *) st->REPR_data;
- repr_data->bits = VTABLE_get_integer_keyed_str(interp, repr_info,
- Parrot_str_new_constant(interp, "bits"));
- printf("bits: %ld\n", repr_data->bits);
+ PMC *integer = VTABLE_get_pmc_keyed_str(interp, repr_info,
+ Parrot_str_new_constant(interp, "integer"));
+ INTVAL bits = sizeof(INTVAL)*8;
+ INTVAL align = 0;
+
+ printf("compose\n");
+ if(!PMC_IS_NULL(integer)) {
+ /* TODO: Handle possible unsigned key. How to handle it though, since
+ * Parrot's INTVAL is inherently signed? */
+ repr_data->bits = VTABLE_get_integer_keyed_str(interp, integer,
+ Parrot_str_new_constant(interp, "bits"));
+ }
+
+ switch (bits) {
+ case 8:
+ align = ALIGNOF1(Parrot_Int1);
+ break;
+ case 16:
+ align = ALIGNOF1(Parrot_Int2);
+ break;
+ case 32:
+ align = ALIGNOF1(Parrot_Int4);
+ break;
+ case 64:
+ align = ALIGNOF1(Parrot_Int8);
+ break;
+ default:
+ /* TODO: Throw exception for unknown sizes. */
+ break;
+ }
+
+ repr_data->bits = bits;
+ repr_data->align = align;
}
/* Creates a new instance based on the type object. */
@@ -117,11 +151,22 @@ static void gc_free(PARROT_INTERP, PMC *obj) {
/* Gets the storage specification for this representation. */
static storage_spec get_storage_spec(PARROT_INTERP, STable *st) {
+ P6intREPRData *repr_data = (P6intREPRData *) st->REPR_data;
storage_spec spec;
spec.inlineable = STORAGE_SPEC_INLINED;
- spec.bits = sizeof(INTVAL) * 8;
spec.boxed_primitive = STORAGE_SPEC_BP_INT;
spec.can_box = STORAGE_SPEC_CAN_BOX_INT;
+
+ printf("data: %p\n", repr_data);
+ if (repr_data) {
+ printf("data->bits: %ld\n", repr_data->bits);
+ spec.bits = repr_data->bits;
+ }
+ else {
+ spec.bits = sizeof(INTVAL)*8;
+ }
+ printf("bits: %ld\n", spec.bits);
+
return spec;
}
@@ -135,6 +180,35 @@ static void deserialize(PARROT_INTERP, STable *st, void *data, SerializationRead
((P6intBody *)data)->value = reader->read_int(interp, reader);
}
+/* Serializes the REPR data. */
+static void serialize_repr_data(PARROT_INTERP, STable *st, SerializationWriter *writer) {
+ P6intREPRData *repr_data = (P6intREPRData *) st->REPR_data;
+ printf("serialize_repr_data\n");
+
+ /* Don't serialize any REPR data in version 1. */
+ if (writer->root.version >= 2) {
+ writer->write_int(interp, writer, repr_data->bits);
+ writer->write_int(interp, writer, repr_data->align);
+ }
+}
+
+/* Serializes the REPR data. */
+static void deserialize_repr_data(PARROT_INTERP, STable *st, SerializationReader *reader) {
+ P6intREPRData *repr_data = (P6intREPRData *) (st->REPR_data = mem_allocate_zeroed_typed(P6intREPRData));
+ printf("deserialize_repr_data (%p)\n", repr_data);
+
+ /* Only read in REPR data for serialization format greater than version 1.
+ * In version 1, just set default values. */
+ if (reader->root.version >= 2) {
+ repr_data->bits = reader->read_int(interp, reader);
+ repr_data->align = reader->read_int(interp, reader);
+ }
+ else {
+ repr_data->bits = sizeof(INTVAL)*8;
+ repr_data->align = ALIGNOF1(INTVAL);
+ }
+}
+
/* Initializes the P6int representation. */
REPROps * P6int_initialize(PARROT_INTERP) {
/* Allocate and populate the representation function table. */
@@ -156,5 +230,7 @@ REPROps * P6int_initialize(PARROT_INTERP) {
this_repr->get_storage_spec = get_storage_spec;
this_repr->serialize = serialize;
this_repr->deserialize = deserialize;
+ this_repr->serialize_repr_data = serialize_repr_data;
+ this_repr->deserialize_repr_data = deserialize_repr_data;
return this_repr;
}
diff --git a/src/6model/serialization.c b/src/6model/serialization.c
index 3494dc3..30584ea 100644
--- a/src/6model/serialization.c
+++ b/src/6model/serialization.c
@@ -17,8 +17,10 @@
#define MAX(x, y) ((y) > (x) ? (y) : (x))
-/* Version of the serialization format that we are currently at. */
-#define CURRENT_VERSION 1
+/* Version of the serialization format that we are currently at and lowest
+ * version we support. */
+#define CURRENT_VERSION 2
+#define MIN_VERSION 1
/* Various sizes (in bytes). */
#define HEADER_SIZE 4 * 16
@@ -1332,9 +1334,11 @@ static void check_and_disect_input(PARROT_INTERP, SerializationReader *reader, S
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"Serialized data too short to read a version number (< 4 bytes)");
reader->root.version = read_int32(data, 0);
- if (reader->root.version != CURRENT_VERSION)
+ /*if (reader->root.version != CURRENT_VERSION)*/
+ if (reader->root.version < MIN_VERSION || reader->root.version > CURRENT_VERSION)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
- "Unknown serialization format version %d", reader->root.version);
+ "Unsupported serialization format version %d (current version is %d)",
+ reader->root.version, CURRENT_VERSION);
/* Ensure that the data is at least as long as the header is expected to be. */
if (data_len < HEADER_SIZE)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment