/* 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); }
/* 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); } }
/* 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); }
/* Deserializes the data. */ static void deserialize(PARROT_INTERP, STable *st, void *data, SerializationReader *reader) { P6opaqueREPRData *repr_data = (P6opaqueREPRData *)st->REPR_data; INTVAL num_attributes = repr_data->num_attributes; INTVAL i; for (i = 0; i < num_attributes; i++) { INTVAL a_offset = repr_data->attribute_offsets[i]; STable *a_st = repr_data->flattened_stables[i]; if (a_st) a_st->REPR->deserialize(interp, a_st, (char *)data + a_offset, reader); else set_pmc_at_offset(data, a_offset, reader->read_ref(interp, reader)); } }
/* Binds the given value to the specified attribute. */ static void bind_attribute(PARROT_INTERP, PMC *obj, PMC *class_handle, STRING *name, INTVAL hint, PMC *value) { 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) { set_pmc_at_offset(instance, repr_data->attribute_offsets[slot], value); return; } /* Otherwise, complain that the attribute doesn't exist. */ no_such_attribute(interp, "bind", class_handle, name); }