Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Implement getting reference type members in CStruct.
  • Loading branch information
arnsholt committed Apr 15, 2012
1 parent 7ff1038 commit f6a394e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
32 changes: 30 additions & 2 deletions src/6model/reprs/CStruct.c
Expand Up @@ -193,6 +193,7 @@ static void compute_allocation_strategy(PARROT_INTERP, PMC *WHAT, CStructREPRDat
repr_data->attribute_locations = (INTVAL *) mem_sys_allocate(info_alloc * sizeof(INTVAL));
repr_data->struct_offsets = (INTVAL *) mem_sys_allocate(info_alloc * sizeof(INTVAL));
repr_data->flattened_stables = (STable **) mem_sys_allocate_zeroed(info_alloc * sizeof(PMC *));
repr_data->member_types = (PMC** ) mem_sys_allocate_zeroed(info_alloc * sizeof(PMC *));

/* Go over the attributes and arrange their allocation. */
for (i = 0; i < num_attrs; i++) {
Expand All @@ -208,7 +209,9 @@ static void compute_allocation_strategy(PARROT_INTERP, PMC *WHAT, CStructREPRDat
spec.boxed_primitive == STORAGE_SPEC_BP_NUM)) {
/* It's a boxed int or num; pretty easy. It'll just live in the
* body of the struct. */
repr_data->attribute_locations[i] = 0;
/* XXX: We could mask in i here as well, but it's not
* really necessary. */
repr_data->attribute_locations[i] = CSTRUCT_ATTR_IN_STRUCT;
bits = spec.bits;
repr_data->flattened_stables[i] = STABLE(type);
if (REPR(type)->initialize) {
Expand All @@ -221,6 +224,8 @@ static void compute_allocation_strategy(PARROT_INTERP, PMC *WHAT, CStructREPRDat
else if(STRING_equal(interp, REPR(type)->name, carray_str)) {
/* It's a CArray of some kind. */
repr_data->num_child_objs++;
repr_data->attribute_locations[i] = (cur_obj_attr++ << CSTRUCT_ATTR_SHIFT) | CSTRUCT_ATTR_CARRAY;
repr_data->member_types[i] = type;
}
else {
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
Expand Down Expand Up @@ -401,7 +406,30 @@ static void die_no_attrs(PARROT_INTERP) {

/* Gets the current value for an attribute. */
static PMC * get_attribute_boxed(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint) {
die_no_attrs(interp);
CStructREPRData *repr_data = (CStructREPRData *)st->REPR_data;
CStructBody *body = (CStructBody *)data;
INTVAL slot;

/* Look up slot, then offset and compute address. */
slot = hint >= 0 ? hint :
try_get_slot(interp, repr_data, class_handle, name);
if (slot >= 0) {
INTVAL placement = repr_data->attribute_locations[slot] & CSTRUCT_ATTR_MASK;
INTVAL real_slot = repr_data->attribute_locations[slot] >> CSTRUCT_ATTR_SHIFT;

if(placement == CSTRUCT_ATTR_IN_STRUCT)
Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
"CStruct Can't perform boxed get on flattened attributes yet");
else {
PMC *obj = body->child_objs[real_slot];
if(!obj)
obj = repr_data->member_types[slot];
return obj;
}
}

/* Otherwise, complain that the attribute doesn't exist. */
no_such_attribute(interp, "get", class_handle, name);
}
static void * get_attribute_ref(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint) {
CStructREPRData *repr_data = (CStructREPRData *)st->REPR_data;
Expand Down
7 changes: 7 additions & 0 deletions src/6model/reprs/CStruct.h
Expand Up @@ -32,12 +32,15 @@ typedef struct {
PMC *name_map;
} CStructNameMap;

/* TODO: Better description here. */
/* Attribute location flags. */
#define CSTRUCT_ATTR_IN_STRUCT 0
#define CSTRUCT_ATTR_CSTRUCT 1
#define CSTRUCT_ATTR_CARRAY 2
#define CSTRUCT_ATTR_CPTR 3
#define CSTRUCT_ATTR_MASK 3
/* Bits to shift a slot position to make room for CSTRUCT_ATTR_*. */
#define CSTRUCT_ATTR_SHIFT 2

/* The CStruct REPR data contains info we need to do allocations, look up
* attributes and so forth. */
Expand Down Expand Up @@ -72,6 +75,10 @@ typedef struct {
* for attributes that are reference types. */
STable **flattened_stables;

/* For reference type members, we cache the relevant type objects.
* Flattened types have NULL here. */
PMC **member_types;

/* A table mapping attribute names to indexes (which can then be looked
* up in the offset table). Uses a final null entry as a sentinel. */
CStructNameMap *name_to_index_mapping;
Expand Down

0 comments on commit f6a394e

Please sign in to comment.