/* Gets the current value for an attribute. */ static PMC * get_attribute(PARROT_INTERP, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint) { P6opaqueInstance *instance = (P6opaqueInstance *)PMC_data(obj); P6opaqueREPRData *repr_data = (P6opaqueREPRData *)STABLE(obj)->REPR_data; INTVAL slot; /* Ensure it is a defined object. */ if (!instance->spill) Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, "Cannot access attributes in a type object"); /* Try the slot allocation first. */ slot = try_get_slot(interp, repr_data, class_handle, name); if (slot >= 0) { PMC *result = get_pmc_at_offset(instance, repr_data->attribute_offsets[slot]); if (result) { return result; } else { /* Maybe we know how to auto-viv it to a container. */ if (repr_data->auto_viv_values) { PMC *value = repr_data->auto_viv_values[slot]; if (value != NULL) { value = REPR(value)->clone(interp, value); set_pmc_at_offset(instance, repr_data->attribute_offsets[slot], value); return value; } } return PMCNULL; } } /* Otherwise, complain that the attribute doesn't exist. */ no_such_attribute(interp, "get", class_handle, name); }
/* Binds the given value to the specified attribute. */ static void bind_attribute_boxed(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint, PMC *value) { P6opaqueREPRData *repr_data = (P6opaqueREPRData *)st->REPR_data; INTVAL slot; /* Try the slot allocation first. */ slot = hint >= 0 && !(repr_data->mi) ? hint : try_get_slot(interp, repr_data, class_handle, name); if (slot >= 0) { STable *st = repr_data->flattened_stables[slot]; if (st) { if (value->vtable->base_type == smo_id && st == STABLE(value)) st->REPR->copy_to(interp, st, OBJECT_BODY(value), (char *)data + repr_data->attribute_offsets[slot]); else Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, "Type mismatch when storing value to attribute '%Ss' on class '%Ss'", name, VTABLE_get_string(interp, introspection_call(interp, class_handle, STABLE(class_handle)->HOW, Parrot_str_new_constant(interp, "name"), 0))); } else { set_pmc_at_offset(data, repr_data->attribute_offsets[slot], value); } } else { /* Otherwise, complain that the attribute doesn't exist. */ no_such_attribute(interp, "bind", class_handle, name); } }
/* Checks if an attribute has been initialized. */ static INTVAL is_attribute_initialized(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint) { P6opaqueREPRData *repr_data = (P6opaqueREPRData *)st->REPR_data; INTVAL slot = try_get_slot(interp, repr_data, class_handle, name); if (slot >= 0) return NULL != get_pmc_at_offset(data, repr_data->attribute_offsets[slot]); else no_such_attribute(interp, "initializedness check", class_handle, name); }
/* Gets the hint for the given attribute ID. */ static INTVAL hint_for(PARROT_INTERP, STable *st, PMC *class_key, STRING *name) { INTVAL slot; P6opaqueREPRData *repr_data = (P6opaqueREPRData *)st->REPR_data; if (!repr_data->allocation_size) { compute_allocation_strategy(interp, st->WHAT, repr_data); PARROT_GC_WRITE_BARRIER(interp, st->stable_pmc); } slot = try_get_slot(interp, repr_data, class_key, name); return slot >= 0 ? slot : NO_HINT; }
static void * get_attribute_ref(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint) { P6opaqueREPRData *repr_data = (P6opaqueREPRData *)st->REPR_data; INTVAL slot; /* Look up slot, then offset and compute address. */ slot = hint >= 0 && !(repr_data->mi) ? hint : try_get_slot(interp, repr_data, class_handle, name); if (slot >= 0) return ((char *)data) + repr_data->attribute_offsets[slot]; /* Otherwise, complain that the attribute doesn't exist. */ no_such_attribute(interp, "get", class_handle, name); }
/* 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; 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 type = repr_data->attribute_locations[slot] & CSTRUCT_ATTR_MASK; INTVAL real_slot = repr_data->attribute_locations[slot] >> CSTRUCT_ATTR_SHIFT; if(type == 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]; PMC *typeobj = repr_data->member_types[slot]; if(!obj) { void *cobj = get_ptr_at_offset(body->cstruct, repr_data->struct_offsets[slot]); if(cobj) { if(type == CSTRUCT_ATTR_CARRAY) { obj = make_carray_result(interp, typeobj, cobj); } else if(type == CSTRUCT_ATTR_CSTRUCT) { obj = make_cstruct_result(interp, typeobj, cobj); } else if(type == CSTRUCT_ATTR_CPTR) { obj = make_cpointer_result(interp, typeobj, cobj); } else if(type == CSTRUCT_ATTR_STRING) { char *cstr = (char *) cobj; STRING *str = Parrot_str_new_init(interp, cstr, strlen(cstr), Parrot_utf8_encoding_ptr, 0); obj = REPR(typeobj)->allocate(interp, STABLE(typeobj)); REPR(obj)->initialize(interp, STABLE(obj), OBJECT_BODY(obj)); REPR(obj)->box_funcs->set_str(interp, STABLE(obj), OBJECT_BODY(obj), str); PARROT_GC_WRITE_BARRIER(interp, obj); } body->child_objs[real_slot] = obj; } else { obj = typeobj; } } return obj; } }
/* 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) { P6opaqueREPRData *repr_data = (P6opaqueREPRData *)st->REPR_data; INTVAL slot; /* Try the slot allocation first. */ slot = hint >= 0 && !(repr_data->mi) ? hint : try_get_slot(interp, repr_data, class_handle, name); if (slot >= 0) { if (!repr_data->flattened_stables[slot]) { PMC *result = get_pmc_at_offset(data, repr_data->attribute_offsets[slot]); if (result) { return result; } else { /* Maybe we know how to auto-viv it to a container. */ if (repr_data->auto_viv_values) { PMC *value = repr_data->auto_viv_values[slot]; if (value != NULL) { if (IS_CONCRETE(value)) { PMC *cloned = REPR(value)->allocate(interp, STABLE(value)); REPR(value)->copy_to(interp, STABLE(value), OBJECT_BODY(value), OBJECT_BODY(cloned)); PARROT_GC_WRITE_BARRIER(interp, cloned); set_pmc_at_offset(data, repr_data->attribute_offsets[slot], cloned); return cloned; } else { set_pmc_at_offset(data, repr_data->attribute_offsets[slot], value); return value; } } } return PMCNULL; } } else { /* Need to produce a boxed version of this attribute. */ STable *st = repr_data->flattened_stables[slot]; PMC *result = st->REPR->allocate(interp, st); st->REPR->copy_to(interp, st, (char *)data + repr_data->attribute_offsets[slot], OBJECT_BODY(result)); PARROT_GC_WRITE_BARRIER(interp, result); return result; } } /* Otherwise, complain that the attribute doesn't exist. */ no_such_attribute(interp, "get", class_handle, name); }
/* Checks if an attribute has been initialized. */ static INTVAL is_attribute_initialized(PARROT_INTERP, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint) { P6opaqueInstance *instance = (P6opaqueInstance *)PMC_data(obj); P6opaqueREPRData *repr_data = (P6opaqueREPRData *)STABLE(obj)->REPR_data; INTVAL slot; if (!instance->spill) Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, "Cannot access attributes in a type object"); slot = try_get_slot(interp, repr_data, class_handle, name); if (slot >= 0) return NULL != get_pmc_at_offset(instance, repr_data->attribute_offsets[slot]); else no_such_attribute(interp, "initializedness check", class_handle, name); }
static FLOATVAL get_attribute_num(PARROT_INTERP, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint) { P6opaqueInstance *instance = (P6opaqueInstance *)PMC_data(obj); P6opaqueREPRData *repr_data = (P6opaqueREPRData *)STABLE(obj)->REPR_data; INTVAL slot; /* Ensure it is a defined object. */ if (!instance->spill) Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, "Cannot access attributes in a type object"); /* Try the slot allocation first. */ slot = try_get_slot(interp, repr_data, class_handle, name); if (slot >= 0) return get_num_at_offset(instance, repr_data->attribute_offsets[slot]); /* Otherwise, complain that the attribute doesn't exist. */ no_such_attribute(interp, "get", class_handle, name); }
static void bind_attribute_ref(PARROT_INTERP, STable *st, void *data, PMC *class_handle, STRING *name, INTVAL hint, void *value) { P6opaqueREPRData *repr_data = (P6opaqueREPRData *)st->REPR_data; INTVAL slot; /* Try to find the slot. */ slot = hint >= 0 && !(repr_data->mi) ? hint : try_get_slot(interp, repr_data, class_handle, name); if (slot >= 0) { STable *st = repr_data->flattened_stables[slot]; if (st) st->REPR->copy_to(interp, st, value, (char *)data + repr_data->attribute_offsets[slot]); else Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION, "Can not bind by reference to non-flattened attribute '%Ss' on class '%Ss'", name, VTABLE_get_string(interp, introspection_call(interp, class_handle, STABLE(class_handle)->HOW, Parrot_str_new_constant(interp, "name"), 0))); } else { /* Otherwise, complain that the attribute doesn't exist. */ no_such_attribute(interp, "bind", class_handle, name); } }