Пример #1
0
/* Composes the representation. */
static void compose(PARROT_INTERP, STable *st, PMC *repr_info) {
    /* Compute allocation strategy. */
    CStructREPRData *repr_data = (CStructREPRData *) st->REPR_data;
    PMC *attr_info = VTABLE_get_pmc_keyed_str(interp, repr_info,
            Parrot_str_new_constant(interp, "attribute"));
    compute_allocation_strategy(interp, attr_info, repr_data);
    PARROT_GC_WRITE_BARRIER(interp, st->stable_pmc);
}
Пример #2
0
/* 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;
}
Пример #3
0
/* Serializes the REPR data. */
static void serialize_repr_data(PARROT_INTERP, STable *st, SerializationWriter *writer) {
    P6opaqueREPRData *repr_data = (P6opaqueREPRData *)st->REPR_data;
    INTVAL i, num_classes;
    
    if (!repr_data->allocation_size) {
        compute_allocation_strategy(interp, st->WHAT, repr_data);
        PARROT_GC_WRITE_BARRIER(interp, st->stable_pmc);
    }
    
    writer->write_int(interp, writer, repr_data->num_attributes);

    for (i = 0; i < repr_data->num_attributes; i++) {
        writer->write_int(interp, writer, repr_data->flattened_stables[i] != NULL);
        if (repr_data->flattened_stables[i])
            writer->write_stable_ref(interp, writer, repr_data->flattened_stables[i]);
    }
    
    writer->write_int(interp, writer, repr_data->mi);
    
    if (repr_data->auto_viv_values) {
        writer->write_int(interp, writer, 1);
        for (i = 0; i < repr_data->num_attributes; i++)
            writer->write_ref(interp, writer, repr_data->auto_viv_values[i]);
    }
    else {
        writer->write_int(interp, writer, 0);
    }
    
    writer->write_int(interp, writer, repr_data->unbox_int_slot);
    writer->write_int(interp, writer, repr_data->unbox_num_slot);
    writer->write_int(interp, writer, repr_data->unbox_str_slot);
    
    if (repr_data->unbox_slots) {
        writer->write_int(interp, writer, 1);
        for (i = 0; i < repr_data->num_attributes; i++) {
            writer->write_int(interp, writer, repr_data->unbox_slots[i].repr_id);
            writer->write_int(interp, writer, repr_data->unbox_slots[i].slot);
        }
    }
    else {
        writer->write_int(interp, writer, 0);
    }
    
    num_classes = i = 0;
    while (repr_data->name_to_index_mapping[i].class_key)
        num_classes++, i++;
    writer->write_int(interp, writer, num_classes);
    for (i = 0; i < num_classes; i++) {
        writer->write_ref(interp, writer, repr_data->name_to_index_mapping[i].class_key);
        writer->write_ref(interp, writer, repr_data->name_to_index_mapping[i].name_map);
    }
}
Пример #4
0
/* Creates a new instance based on the type object. */
static PMC * allocate(PARROT_INTERP, STable *st) {
    P6opaqueInstance * obj;

    /* Compute allocation strategy if we've not already done so. */
    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);
    }

    /* Allocate and set up object instance. */
    obj = (P6opaqueInstance *) Parrot_gc_allocate_fixed_size_storage(interp, repr_data->allocation_size);
    memset(obj, 0, repr_data->allocation_size);
    obj->common.stable = st->stable_pmc;

    return wrap_object(interp, obj);
}
Пример #5
0
Файл: P6opaque.c Проект: ruz/nqp
/* Creates a new instance based on the type object. */
static PMC * instance_of(PARROT_INTERP, PMC *WHAT) {
    P6opaqueInstance * obj;

    /* Compute allocation strategy if we've not already done so. */
    P6opaqueREPRData * repr_data = (P6opaqueREPRData *) STABLE(WHAT)->REPR_data;
    if (!repr_data->allocation_size) {
        compute_allocation_strategy(interp, WHAT, repr_data);
        PARROT_GC_WRITE_BARRIER(interp, STABLE_PMC(WHAT));
    }

    /* Allocate and set up object instance. */
    obj = (P6opaqueInstance *) Parrot_gc_allocate_fixed_size_storage(interp, repr_data->allocation_size);
    memset(obj, 0, repr_data->allocation_size);
    obj->common.stable = STABLE_PMC(WHAT);

    /* The spill slot gets set to PMCNULL; it not being (C) NULL is what
     * lets us know it's actually a real instance, not a type object. */
    obj->spill = PMCNULL;
    
    return wrap_object(interp, obj);
}
Пример #6
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));
    }
}
Пример #7
0
/* Performs a change of type, where possible. */
static void change_type(PARROT_INTERP, PMC *obj, PMC *new_type) {
    P6opaqueInstance *instance      = (P6opaqueInstance *)PMC_data(obj);
    P6opaqueREPRData *cur_repr_data = (P6opaqueREPRData *)STABLE(obj)->REPR_data;
    P6opaqueREPRData *new_repr_data = (P6opaqueREPRData *)STABLE(new_type)->REPR_data;
    STRING           *mro_str       = Parrot_str_new_constant(interp, "mro");
    PMC              *cur_mro, *new_mro;
    INTVAL            cur_mro_elems, new_mro_elems, mro_is_suffix;
    
    /* Ensure we're not trying to change the type of a type object. */
    if (PObj_flag_TEST(private0, obj))
        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
            "Cannot change the type of a type object");
    
    /* Ensure that the destination type REPR is P6opaque also. */
    if (REPR(obj) != REPR(new_type))
        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
            "P6opaque can only change type to another type with P6opaque REPR");

    /* Ensure that MRO of new type has current type's MRO as a suffix. */
    mro_is_suffix = 1;
    cur_mro = introspection_call(interp, STABLE(obj)->WHAT, STABLE(obj)->HOW, mro_str, 0);
    new_mro = introspection_call(interp, STABLE(new_type)->WHAT, STABLE(new_type)->HOW, mro_str, 0);
    cur_mro_elems = VTABLE_elements(interp, cur_mro);
    new_mro_elems = VTABLE_elements(interp, new_mro);
    if (new_mro_elems >= cur_mro_elems) {
        INTVAL start = new_mro_elems - cur_mro_elems;
        INTVAL i;
        for (i = 0; i < cur_mro_elems; i++) {
            PMC *cur_elem = VTABLE_get_pmc_keyed_int(interp, cur_mro, i);
            PMC *new_elem = VTABLE_get_pmc_keyed_int(interp, new_mro, i + start);
            if (decontainerize(interp, cur_elem) != decontainerize(interp, new_elem)) {
                mro_is_suffix = 0;
                break;
            }
        }
    }
    else {
        mro_is_suffix = 0;
    }
    if (!mro_is_suffix)
        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
            "P6opaque only supports type changes where the MRO of the original type is a suffix of the MRO of the new type");
    
    /* If the new REPR never calculated it's object layout, do so now. */
    if (!new_repr_data->allocation_size) {
        compute_allocation_strategy(interp, new_type, new_repr_data);
        PARROT_GC_WRITE_BARRIER(interp, STABLE_PMC(new_type));
    }
    
    /* Reallocate ourself to the new allocation size, if needed, and
     * ensure new chunk of the memory is zeroed. Note that we can't
     * really re-alloc, we need to go deal with the fixed size pool
     * allocator. */
    if (new_repr_data->allocation_size > cur_repr_data->allocation_size) {
        P6opaqueInstance *new_body = (P6opaqueInstance *) Parrot_gc_allocate_fixed_size_storage(interp, new_repr_data->allocation_size);
        memset(new_body, 0, new_repr_data->allocation_size);
        memcpy(new_body, instance, cur_repr_data->allocation_size);
        PMC_data(obj) = new_body;
        Parrot_gc_free_fixed_size_storage(interp, cur_repr_data->allocation_size, instance);
        instance = new_body;
    }
    
    /* Finally, we're ready to switch the S-Table pointer. */
    instance->common.stable = STABLE_PMC(new_type);
    PARROT_GC_WRITE_BARRIER(interp, obj);
}