예제 #1
0
파일: P6opaque.c 프로젝트: fgomezrdz/nqp
/* 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);
}
예제 #2
0
파일: P6opaque.c 프로젝트: fgomezrdz/nqp
/* 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);
    }
}
예제 #3
0
파일: P6opaque.c 프로젝트: ruz/nqp
/* 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);
}
예제 #4
0
파일: P6opaque.c 프로젝트: fgomezrdz/nqp
/* 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));
    }
}
예제 #5
0
파일: P6opaque.c 프로젝트: ruz/nqp
/* 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);
}