Example #1
0
File: P6opaque.c Project: 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);
}
Example #2
0
/* 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);
}
Example #3
0
File: P6opaque.c Project: ruz/nqp
/* This Parrot-specific addition to the API is used to mark an object. */
static void gc_mark(PARROT_INTERP, PMC *obj) {
    P6opaqueInstance *instance = (P6opaqueInstance *)PMC_data(obj);
    
    /* Mark STable and SC. */
    if (!PMC_IS_NULL(instance->common.stable))
        Parrot_gc_mark_PMC_alive(interp, instance->common.stable);
    if (!PMC_IS_NULL(instance->common.sc))
        Parrot_gc_mark_PMC_alive(interp, instance->common.sc);

    /* If there's spill storage, mark that. */
    if (!PMC_IS_NULL(instance->spill))
        Parrot_gc_mark_PMC_alive(interp, instance->spill);
    
    /* Mark contained PMC and string attributes, provided this is a
     * real object. */
    if (instance->spill) {
        P6opaqueREPRData *repr_data = (P6opaqueREPRData *)STABLE(obj)->REPR_data;
        INTVAL i;

        /* Mark PMCs. */
        if (repr_data->gc_pmc_mark_offsets) {
            for (i = 0; i < repr_data->num_attributes; i++) {
                INTVAL offset = repr_data->gc_pmc_mark_offsets[i];
                if (offset) {
                    PMC *to_mark = get_pmc_at_offset(instance, offset);
                    if (!PMC_IS_NULL(to_mark))
                        Parrot_gc_mark_PMC_alive(interp, to_mark);
                }
                else {
                    break;
                }
            }
        }

        /* Mark strings. */
        if (repr_data->gc_str_mark_offsets) {
            for (i = 0; i < repr_data->num_attributes; i++) {
                INTVAL offset = repr_data->gc_str_mark_offsets[i];
                if (offset) {
                    STRING *to_mark = get_str_at_offset(instance, offset);
                    if (to_mark)
                        Parrot_gc_mark_STRING_alive(interp, to_mark);
                }
                else {
                    break;
                }
            }
        }
    }
}
Example #4
0
/* 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);
}
Example #5
0
File: P6opaque.c Project: ruz/nqp
/* 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);
}
Example #6
0
/* This Parrot-specific addition to the API is used to mark an object. */
static void gc_mark(PARROT_INTERP, STable *st, void *data) {
    P6opaqueREPRData *repr_data = (P6opaqueREPRData *)st->REPR_data;
    INTVAL i;

    /* Mark PMCs. */
    if (repr_data->gc_pmc_mark_offsets) {
        for (i = 0; i < repr_data->gc_pmc_mark_offsets_count; i++) {
            INTVAL offset = repr_data->gc_pmc_mark_offsets[i];
            PMC *to_mark  = get_pmc_at_offset(data, offset);
            if (!PMC_IS_NULL(to_mark))
                Parrot_gc_mark_PMC_alive(interp, to_mark);
        }
    }

    /* Mark any nested reprs that need it. */
    if (repr_data->gc_mark_slots) {
        for (i = 0; repr_data->gc_mark_slots[i] >= 0; i++) {
            INTVAL  offset = repr_data->attribute_offsets[repr_data->gc_mark_slots[i]];
            STable *st     = repr_data->flattened_stables[repr_data->gc_mark_slots[i]];
            st->REPR->gc_mark(interp, st, (char *)data + offset);
        }
    }
}
Example #7
0
/* Serializes the data. */
static void serialize(PARROT_INTERP, STable *st, void *data, SerializationWriter *writer) {
    P6opaqueREPRData *repr_data = (P6opaqueREPRData *)st->REPR_data;
    INTVAL num_attributes, i;
    
    if (!repr_data->allocation_size) {
        compute_allocation_strategy(interp, st->WHAT, repr_data);
        PARROT_GC_WRITE_BARRIER(interp, st->stable_pmc);
    }
    
    num_attributes = repr_data->num_attributes;
    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) {
            if (a_st->REPR->serialize)
                a_st->REPR->serialize(interp, a_st, (char *)data + a_offset, writer);
            else
                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
                    "Missing serialize REPR function");
        }
        else
            writer->write_ref(interp, writer, get_pmc_at_offset(data, a_offset));
    }
}