Skip to content

Instantly share code, notes, and snippets.

@arnsholt
Created April 15, 2012 12:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arnsholt/2392558 to your computer and use it in GitHub Desktop.
Save arnsholt/2392558 to your computer and use it in GitHub Desktop.
/* Helper for finding a slot number. */
static INTVAL try_get_slot(PARROT_INTERP, CStructREPRData *repr_data, PMC *class_key, STRING *name, PMC **attrptr) {
INTVAL slot = -1;
if (repr_data->name_to_index_mapping) {
CStructNameMap *cur_map_entry = repr_data->name_to_index_mapping;
while (cur_map_entry->class_key != NULL) {
if (cur_map_entry->class_key == class_key) {
PMC *slot_pmc = VTABLE_get_pmc_keyed_str(interp, cur_map_entry->name_map, name);
if (!PMC_IS_NULL(slot_pmc)) {
slot = VTABLE_get_integer(interp, slot_pmc);
if(attrptr)
*attrptr = slot_pmc;
}
break;
}
cur_map_entry++;
}
}
return slot;
}
/* 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) {
CStructREPRData *repr_data = (CStructREPRData *)st->REPR_data;
CStructBody *body = (CStructBody *)data;
STRING *type_str = Parrot_str_new_constant(interp, "type");
INTVAL slot;
PMC *attr;
/* Look up slot, then offset and compute address. */
slot = hint >= 0 ? hint :
try_get_slot(interp, repr_data, class_handle, name, &attr);
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 = accessor_call(interp, attr, type_str);
return obj;
}
}
/* Otherwise, complain that the attribute doesn't exist. */
no_such_attribute(interp, "get", class_handle, name);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment