Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Teach P6num about different sizes.
  • Loading branch information
arnsholt committed Feb 1, 2013
1 parent 9b79426 commit e50b1c2
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 7 deletions.
116 changes: 109 additions & 7 deletions src/6model/reprs/P6num.c
Expand Up @@ -10,16 +10,25 @@
/* This representation's function pointer table. */
static REPROps *this_repr;

static void set_num(PARROT_INTERP, STable *st, void *data, FLOATVAL value);
static FLOATVAL get_num(PARROT_INTERP, STable *st, void *data);

/* 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. */
P6numInstance *obj = mem_allocate_zeroed_typed(P6numInstance);
P6numREPRData *repr_data = mem_allocate_zeroed_typed(P6numREPRData);

/* Build an STable. */
PMC *st_pmc = create_stable(interp, this_repr, HOW);
STable *st = STABLE_STRUCT(st_pmc);

/* Set default bit width value in the REPR data and attach it to the
* STable. */
repr_data->bits = sizeof(FLOATVAL)*8;
st->REPR_data = repr_data;

/* Create type object and point it back at the STable. */
obj->common.stable = st_pmc;
st->WHAT = wrap_object(interp, obj);
Expand All @@ -34,6 +43,18 @@ 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). */
P6numREPRData *repr_data = (P6numREPRData *) st->REPR_data;
PMC *info = VTABLE_get_pmc_keyed_str(interp, repr_info,
Parrot_str_new_constant(interp, "float"));

repr_data->bits = sizeof(FLOATVAL)*8;
if(!PMC_IS_NULL(info)) {
/* XXX: Make sure bits is a value we actually support. */
/* XXX: I should probably handle the case where no "bits" key is set
* as well, which would set it to 0 (I think?). */
repr_data->bits = VTABLE_get_integer_keyed_str(interp, info,
Parrot_str_new_constant(interp, "bits"));
}
}

/* Creates a new instance based on the type object. */
Expand All @@ -45,13 +66,25 @@ static PMC * allocate(PARROT_INTERP, STable *st) {

/* Initialize a new instance. */
static void initialize(PARROT_INTERP, STable *st, void *data) {
double x = 0.0;
((P6numBody *)data)->value = 0.0/x;
P6numREPRData *repr_data = (P6numREPRData *)st->REPR_data;

if (repr_data->bits == 32) {
float x = 0.0;
set_num(interp, st, data, 0.0/x);
}
else if (repr_data->bits == 64) {
double x = 0.0;
set_num(interp, st, data, 0.0/x);
}
else {
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"P6num can only handle 32 or 64 bit floats.");
}
}

/* Copies to the body of one object to another. */
static void copy_to(PARROT_INTERP, STable *st, void *src, void *dest) {
*((FLOATVAL *)dest) = *((FLOATVAL *)src);
set_num(interp, st, dest, get_num(interp, st, src));
}

/* Used with boxing. Sets an integer value, for representations that can hold
Expand All @@ -71,13 +104,35 @@ static INTVAL get_int(PARROT_INTERP, STable *st, void *data) {
/* Used with boxing. Sets a floating point value, for representations that can
* hold one. */
static void set_num(PARROT_INTERP, STable *st, void *data, FLOATVAL value) {
((P6numBody *)data)->value = value;
P6numREPRData *repr_data = (P6numREPRData *)st->REPR_data;

switch (repr_data->bits) {
case 32:
*(Parrot_Float4 *)data = value;
break;
case 64:
*(Parrot_Float8 *)data = value;
break;
default:
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"P6num can only handle 32 or 64 bit floats.");
}
}

/* Used with boxing. Gets a floating point value, for representations that can
* hold one. */
static FLOATVAL get_num(PARROT_INTERP, STable *st, void *data) {
return ((P6numBody *)data)->value;
P6numREPRData *repr_data = (P6numREPRData *)st->REPR_data;

switch (repr_data->bits) {
case 32:
return *(Parrot_Float4 *)data;
case 64:
return *(Parrot_Float8 *)data;
default:
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"P6num can only handle 32 or 64 bit floats.");
}
}

/* Used with boxing. Sets a string value, for representations that can hold
Expand Down Expand Up @@ -111,11 +166,32 @@ 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) {
storage_spec spec;
P6numREPRData *repr_data = (P6numREPRData *) st->REPR_data;
spec.inlineable = STORAGE_SPEC_INLINED;
spec.bits = sizeof(FLOATVAL) * 8;
spec.align = ALIGNOF1(void *);
spec.boxed_primitive = STORAGE_SPEC_BP_NUM;
spec.can_box = STORAGE_SPEC_CAN_BOX_NUM;

/*spec.bits = sizeof(FLOATVAL) * 8;
spec.align = ALIGNOF1(void *);*/
if (repr_data && repr_data->bits) {
spec.bits = repr_data->bits;
}
else {
spec.bits = sizeof(FLOATVAL)*8;
}

switch (spec.bits) {
case 32:
spec.align = ALIGNOF1(Parrot_Float4);
break;
case 64:
spec.align = ALIGNOF1(Parrot_Float8);
break;
default:
/* TODO: Throw exception for unknown sizes. */
break;
}

return spec;
}

Expand All @@ -129,6 +205,30 @@ static void deserialize(PARROT_INTERP, STable *st, void *data, SerializationRead
((P6numBody *)data)->value = reader->read_num(interp, reader);
}

/* Serializes the REPR data. */
static void serialize_repr_data(PARROT_INTERP, STable *st, SerializationWriter *writer) {
P6numREPRData *repr_data = (P6numREPRData *) st->REPR_data;

/* Don't serialize any REPR data in version 1. */
if (writer->root.version >= 2) {
writer->write_int(interp, writer, repr_data->bits);
}
}

/* Serializes the REPR data. */
static void deserialize_repr_data(PARROT_INTERP, STable *st, SerializationReader *reader) {
P6numREPRData *repr_data = (P6numREPRData *) (st->REPR_data = mem_allocate_zeroed_typed(P6numREPRData));

/* 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);
}
else {
repr_data->bits = sizeof(INTVAL)*8;
}
}

/* Initializes the P6num representation. */
REPROps * P6num_initialize(PARROT_INTERP) {
/* Allocate and populate the representation function table. */
Expand All @@ -150,5 +250,7 @@ REPROps * P6num_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;
}
5 changes: 5 additions & 0 deletions src/6model/reprs/P6num.h
Expand Up @@ -12,6 +12,11 @@ typedef struct {
P6numBody body;
} P6numInstance;

/* The bit width requirement is shared for all instances of the same type. */
typedef struct {
INTVAL bits;
} P6numREPRData;

/* Initializes the P6num REPR. */
REPROps * P6num_initialize(PARROT_INTERP);

Expand Down

0 comments on commit e50b1c2

Please sign in to comment.