Example #1
0
/* Initializes the representations registry, building up all of the various
 * representations. */
void REPR_initialize_registry(PARROT_INTERP) {
    PMC *dyn_reg_func, *lookup_func;
    
    /* Allocate name to ID map, and anchor it with the GC. */
    repr_name_to_id_map = Parrot_pmc_new(interp, enum_class_Hash);
    Parrot_pmc_gc_register(interp, repr_name_to_id_map);

    /* Add all core representations. */
    register_repr(interp, Parrot_str_new_constant(interp, "KnowHOWREPR"), 
        KnowHOWREPR_initialize(interp));
    register_repr(interp, Parrot_str_new_constant(interp, "P6opaque"), 
        P6opaque_initialize(interp));
    register_repr(interp, Parrot_str_new_constant(interp, "P6int"), 
        P6int_initialize(interp));
    register_repr(interp, Parrot_str_new_constant(interp, "P6num"), 
        P6num_initialize(interp));
    register_repr(interp, Parrot_str_new_constant(interp, "P6str"), 
        P6str_initialize(interp));
    register_repr(interp, Parrot_str_new_constant(interp, "HashAttrStore"), 
        HashAttrStore_initialize(interp));
    register_repr(interp, Parrot_str_new_constant(interp, "Uninstantiable"),
        Uninstantiable_initialize(interp));
    register_repr(interp, Parrot_str_new_constant(interp, "NFA"),
        NFA_initialize(interp));
    register_repr(interp, Parrot_str_new_constant(interp, "VMArray"),
        VMArray_initialize(interp));
    register_repr(interp, Parrot_str_new_constant(interp, "VMHash"),
        VMHash_initialize(interp));
    register_repr(interp, Parrot_str_new_constant(interp, "VMIter"),
        VMIter_initialize(interp));

    /* Set up object for dynamically registering extra representations. */
    dyn_reg_func = Parrot_pmc_new(interp, enum_class_Pointer);
    VTABLE_set_pointer(interp, dyn_reg_func, REPR_register_dynamic);
    VTABLE_set_pmc_keyed_str(interp, interp->root_namespace,
        Parrot_str_new_constant(interp, "_REGISTER_REPR"), dyn_reg_func);

    /* Set up object for looking up the id of representations. */
    lookup_func = Parrot_pmc_new(interp, enum_class_Pointer);
    VTABLE_set_pointer(interp, lookup_func, REPR_name_to_id);
    VTABLE_set_pmc_keyed_str(interp, interp->root_namespace,
        Parrot_str_new_constant(interp, "_LOOKUP_REPR_ID"), lookup_func);
}
Example #2
0
static void
PackFile_Constant_dump(PARROT_INTERP, ARGIN(const PackFile_ConstTable *ct),
                       ARGIN(const PackFile_Constant *self))
{
    ASSERT_ARGS(PackFile_Constant_dump)
    PMC *key;
    size_t i;

    switch (self->type) {

    case PFC_NUMBER:
        Parrot_io_printf(interp, "    [ 'PFC_NUMBER', %g ],\n", self->u.number);
        break;

    case PFC_STRING:
        Parrot_io_printf(interp, "    [ 'PFC_STRING', {\n");
        pobj_flag_dump(interp, (long)PObj_get_FLAGS(self->u.string));
        Parrot_io_printf(interp, "        CHARSET  => %ld,\n",
                   self->u.string->charset);
        i = self->u.string->bufused;
        Parrot_io_printf(interp, "        SIZE     => %ld,\n",
                   (long)i);

        Parrot_io_printf(interp, "        DATA     => \"%Ss\"\n",
                       Parrot_str_escape(interp, self->u.string));
        Parrot_io_printf(interp, "    } ],\n");
        break;

    case PFC_KEY:
        for (i = 0, key = self->u.key; key; i++) {
            GETATTR_Key_next_key(interp, key, key);
        }
        /* number of key components */
        Parrot_io_printf(interp, "    [ 'PFC_KEY' (%ld items)\n", i);
        /* and now type / value per component */
        for (key = self->u.key; key;) {
            opcode_t type = PObj_get_FLAGS(key);

            Parrot_io_printf(interp, "       {\n");

            type &= KEY_type_FLAGS;
            pobj_flag_dump(interp, (long)PObj_get_FLAGS(key));
            switch (type) {
                case KEY_integer_FLAG:
                    Parrot_io_printf(interp, "        TYPE        => INTEGER\n");
                    Parrot_io_printf(interp, "        DATA        => %ld\n",
                            VTABLE_get_integer(interp, key));
                    Parrot_io_printf(interp, "       },\n");
                    break;
                case KEY_number_FLAG:
                    {
                    const PackFile_Constant *detail;
                    size_t ct_index;

                    Parrot_io_printf(interp, "        TYPE        => NUMBER\n");
                    ct_index = PackFile_find_in_const(interp, ct, key, PFC_NUMBER);
                    Parrot_io_printf(interp, "        PFC_OFFSET  => %ld\n", ct_index);
                    detail = ct->constants[ct_index];
                    Parrot_io_printf(interp, "        DATA        => %ld\n", detail->u.number);
                    Parrot_io_printf(interp, "       },\n");
                    }
                    break;
                case KEY_string_FLAG:
                    {
                    const PackFile_Constant *detail;
                    size_t ct_index;

                    Parrot_io_printf(interp, "        TYPE        => STRING\n");
                    ct_index = PackFile_find_in_const(interp, ct, key, PFC_STRING);
                    Parrot_io_printf(interp, "        PFC_OFFSET  => %ld\n", ct_index);
                    detail = ct->constants[ct_index];
                    Parrot_io_printf(interp, "        DATA        => '%Ss'\n",
                              detail->u.string);
                    Parrot_io_printf(interp, "       },\n");
                    }
                    break;
                case KEY_integer_FLAG | KEY_register_FLAG:
                    Parrot_io_printf(interp, "        TYPE        => I REGISTER\n");
                    Parrot_io_printf(interp, "        DATA        => %ld\n",
                            VTABLE_get_integer(interp, key));
                    Parrot_io_printf(interp, "       },\n");
                    break;
                case KEY_number_FLAG | KEY_register_FLAG:
                    Parrot_io_printf(interp, "        TYPE        => N REGISTER\n");
                    Parrot_io_printf(interp, "        DATA        => %ld\n",
                            VTABLE_get_integer(interp, key));
                    Parrot_io_printf(interp, "       },\n");
                    break;
                case KEY_string_FLAG | KEY_register_FLAG:
                    Parrot_io_printf(interp, "        TYPE        => S REGISTER\n");
                    Parrot_io_printf(interp, "        DATA        => %ld\n",
                            VTABLE_get_integer(interp, key));
                    Parrot_io_printf(interp, "       },\n");
                    break;
                case KEY_pmc_FLAG | KEY_register_FLAG:
                    Parrot_io_printf(interp, "        TYPE        => P REGISTER\n");
                    Parrot_io_printf(interp, "        DATA        => %ld\n",
                            VTABLE_get_integer(interp, key));
                    Parrot_io_printf(interp, "       },\n");
                    break;
                default:
                    Parrot_io_eprintf(NULL, "PackFile_Constant_pack: "
                            "unsupported constant type\n");
                    Parrot_exit(interp, 1);
            }
            GETATTR_Key_next_key(interp, key, key);
        }
        Parrot_io_printf(interp, "    ],\n");
        break;
    case PFC_PMC:
        Parrot_io_printf(interp, "    [ 'PFC_PMC', {\n");
        {
            PMC * const pmc = self->u.key;
            Parrot_Sub_attributes *sub;
            STRING * const null = Parrot_str_new_constant(interp, "(null)");
            STRING *namespace_description;

            pobj_flag_dump(interp, (long)PObj_get_FLAGS(pmc));
            switch (pmc->vtable->base_type) {
                case enum_class_FixedBooleanArray:
                case enum_class_FixedFloatArray:
                case enum_class_FixedPMCArray:
                case enum_class_FixedStringArray:
                case enum_class_ResizableBooleanArray:
                case enum_class_ResizableIntegerArray:
                case enum_class_ResizableFloatArray:
                case enum_class_ResizablePMCArray:
                case enum_class_ResizableStringArray:
                    {
                    const int n = VTABLE_get_integer(interp, pmc);
                    STRING* const out_buffer = VTABLE_get_repr(interp, pmc);
                    Parrot_io_printf(interp,
                            "\tclass => %Ss,\n"
                            "\telement count => %d,\n"
                            "\telements => %Ss,\n",
                            pmc->vtable->whoami,
                            n,
                            out_buffer);
                    }
                    break;
                case enum_class_Sub:
                case enum_class_Coroutine:
                    PMC_get_sub(interp, pmc, sub);
                    if (sub->namespace_name) {
                        switch (sub->namespace_name->vtable->base_type) {
                            case enum_class_String:
                                namespace_description = Parrot_str_new(interp, "'", 1);
                                namespace_description = Parrot_str_append(interp,
                                        namespace_description,
                                        VTABLE_get_string(interp, sub->namespace_name));
                                namespace_description = Parrot_str_append(interp,
                                        namespace_description,
                                        Parrot_str_new(interp, "'", 1));
                                break;
                            case enum_class_Key:
                                namespace_description =
                                    key_set_to_string(interp, sub->namespace_name);
                                break;
                            default:
                                namespace_description = sub->namespace_name->vtable->whoami;
                        }
                    }
                    else {
                        namespace_description = null;
                    }
                    Parrot_io_printf(interp,
                            "\tclass => %Ss,\n"
                            "\tstart_offs => %d,\n"
                            "\tend_offs => %d,\n"
                            "\tname    => '%Ss',\n"
                            "\tsubid   => '%Ss',\n"
                            "\tmethod  => '%Ss',\n"
                            "\tnsentry => '%Ss',\n"
                            "\tnamespace => %Ss\n"
                            "\tHLL_id => %d,\n",
                            pmc->vtable->whoami,
                            sub->start_offs,
                            sub->end_offs,
                            sub->name,
                            sub->subid,
                            sub->method_name,
                            sub->ns_entry_name,
                            namespace_description,
                            sub->HLL_id);
                    break;
                case enum_class_FixedIntegerArray:
                    Parrot_io_printf(interp,
                            "\tclass => %Ss,\n"
                            "\trepr => '%Ss'\n",
                            pmc->vtable->whoami,
                            VTABLE_get_repr(interp, pmc));
                    break;
                default:
                    Parrot_io_printf(interp, "\tno dump info for PMC %ld %Ss\n",
                            pmc->vtable->base_type, pmc->vtable->whoami);
                    Parrot_io_printf(interp, "\tclass => %Ss,\n", pmc->vtable->whoami);
            }
        }
        Parrot_io_printf(interp, "    } ],\n");
        break;
    default:
        Parrot_io_printf(interp, "    [ 'PFC_\?\?\?', type '0x%x' ],\n",
                self->type);
        break;
    }
}
Example #3
0
/* Locates all of the attributes. Puts them onto a flattened, ordered
 * list of attributes (populating the passed flat_list). Also builds
 * the index mapping for doing named lookups. Note index is not related
 * to the storage position. */
static PMC * index_mapping_and_flat_list(PARROT_INTERP, PMC *WHAT, P6opaqueREPRData *repr_data) {
    PMC    *flat_list      = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
    PMC    *class_list     = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
    PMC    *attr_map_list  = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
    STRING *attributes_str = Parrot_str_new_constant(interp, "attributes");
    STRING *parents_str    = Parrot_str_new_constant(interp, "parents");
    STRING *name_str       = Parrot_str_new_constant(interp, "name");
    STRING *mro_str        = Parrot_str_new_constant(interp, "mro");
    INTVAL  current_slot   = 0;
    
    INTVAL num_classes, i;
    P6opaqueNameMap * result = NULL;
    
    /* Get the MRO. */
    PMC   *mro     = introspection_call(interp, WHAT, STABLE(WHAT)->HOW, mro_str, 0);
    INTVAL mro_idx = VTABLE_elements(interp, mro);

    /* Walk through the parents list. */
    while (mro_idx)
    {
        /* Get current class in MRO. */
        PMC    *current_class = decontainerize(interp, VTABLE_get_pmc_keyed_int(interp, mro, --mro_idx));
        PMC    *HOW           = STABLE(current_class)->HOW;
        
        /* Get its local parents. */
        PMC    *parents     = introspection_call(interp, current_class, HOW, parents_str, 1);
        INTVAL  num_parents = VTABLE_elements(interp, parents);

        /* Get attributes and iterate over them. */
        PMC *attributes = introspection_call(interp, current_class, HOW, attributes_str, 1);
        PMC *attr_map   = PMCNULL;
        PMC *attr_iter  = VTABLE_get_iter(interp, attributes);
        while (VTABLE_get_bool(interp, attr_iter)) {
            /* Get attribute. */
            PMC * attr = VTABLE_shift_pmc(interp, attr_iter);

            /* Get its name. */
            PMC    *name_pmc = accessor_call(interp, attr, name_str);
            STRING *name     = VTABLE_get_string(interp, name_pmc);

            /* Allocate a slot. */
            if (PMC_IS_NULL(attr_map))
                attr_map = Parrot_pmc_new(interp, enum_class_Hash);
            VTABLE_set_pmc_keyed_str(interp, attr_map, name,
                Parrot_pmc_new_init_int(interp, enum_class_Integer, current_slot));
            current_slot++;

            /* Push attr onto the flat list. */
            VTABLE_push_pmc(interp, flat_list, attr);
        }

        /* Add to class list and map list. */
        VTABLE_push_pmc(interp, class_list, current_class);
        VTABLE_push_pmc(interp, attr_map_list, attr_map);

        /* If there's more than one parent, flag that we in an MI
         * situation. */
        if (num_parents > 1)
            repr_data->mi = 1;
    }

    /* We can now form the name map. */
    num_classes = VTABLE_elements(interp, class_list);
    result = (P6opaqueNameMap *) mem_sys_allocate_zeroed(sizeof(P6opaqueNameMap) * (1 + num_classes));
    for (i = 0; i < num_classes; i++) {
        result[i].class_key = VTABLE_get_pmc_keyed_int(interp, class_list, i);
        result[i].name_map  = VTABLE_get_pmc_keyed_int(interp, attr_map_list, i);
    }
    repr_data->name_to_index_mapping = result;

    return flat_list;
}
Example #4
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);
}
Example #5
0
=item C<static void set_cstring_prop(PARROT_INTERP, PMC *lib_pmc, const char
*what, STRING *name)>

Sets a property C<name> with value C<what> on the C<ParrotLibrary> C<lib_pmc>.

=cut

*/

static void
set_cstring_prop(PARROT_INTERP, ARGMOD(PMC *lib_pmc), ARGIN(const char *what),
        ARGIN(STRING *name))
{
    ASSERT_ARGS(set_cstring_prop)
    STRING * const key  = Parrot_str_new_constant(interp, what);
    PMC    * const prop = Parrot_pmc_new(interp, enum_class_String);

    VTABLE_set_string_native(interp, prop, name);
    Parrot_pmc_setprop(interp, lib_pmc, key, prop);
}


/*

=item C<static void store_lib_pmc(PARROT_INTERP, PMC *lib_pmc, STRING *path,
STRING *type, STRING *lib_name)>

Stores a C<ParrotLibrary> PMC in the interpreter's C<iglobals>.

=cut
Example #6
0
/* This works out an allocation strategy for the object. It takes care of
 * "inlining" storage of attributes that are natively typed, as well as
 * noting unbox targets. */
static void compute_allocation_strategy(PARROT_INTERP, PMC *WHAT, P6opaqueREPRData *repr_data) {
    STRING *type_str       = Parrot_str_new_constant(interp, "type");
    STRING *box_target_str = Parrot_str_new_constant(interp, "box_target");
    STRING *avcont_str     = Parrot_str_new_constant(interp, "auto_viv_container");
    PMC    *flat_list;

    /*
     * We have to block GC mark here. Because "repr" is assotiated with some
     * PMC which is not accessible in this function. And we have to write
     * barrier this PMC because we are poking inside it guts directly. We
     * do have WB in caller function, but it can be triggered too late is
     * any of allocation will cause GC run.
     *
     * This is kind of minor evil until after I'll find better solution.
     */
    Parrot_block_GC_mark(interp);

    /* Compute index mapping table and get flat list of attributes. */
    flat_list = index_mapping_and_flat_list(interp, WHAT, repr_data);
    
    /* If we have no attributes in the index mapping, then just the header. */
    if (repr_data->name_to_index_mapping[0].class_key == NULL) {
        repr_data->allocation_size = sizeof(P6opaqueInstance);
    }

    /* Otherwise, we need to compute the allocation strategy.  */
    else {
        /* We track the size of the body part, since that's what we want offsets into. */
        INTVAL cur_size = 0;
        
        /* Get number of attributes and set up various counters. */
        INTVAL num_attrs        = VTABLE_elements(interp, flat_list);
        INTVAL info_alloc       = num_attrs == 0 ? 1 : num_attrs;
        INTVAL cur_pmc_attr     = 0;
        INTVAL cur_init_slot    = 0;
        INTVAL cur_mark_slot    = 0;
        INTVAL cur_cleanup_slot = 0;
        INTVAL cur_unbox_slot   = 0;
        INTVAL i;

        /* Allocate offset array and GC mark info arrays. */
        repr_data->num_attributes      = num_attrs;
        repr_data->attribute_offsets   = (INTVAL *) mem_sys_allocate(info_alloc * sizeof(INTVAL));
        repr_data->flattened_stables   = (STable **) mem_sys_allocate_zeroed(info_alloc * sizeof(PMC *));
        repr_data->unbox_int_slot      = -1;
        repr_data->unbox_num_slot      = -1;
        repr_data->unbox_str_slot      = -1;

        /* Go over the attributes and arrange their allocation. */
        for (i = 0; i < num_attrs; i++) {
            PMC *attr = VTABLE_get_pmc_keyed_int(interp, flat_list, i);

            /* Fetch its type and box target flag, if available. */
            PMC *type       = accessor_call(interp, attr, type_str);
            PMC *box_target = accessor_call(interp, attr, box_target_str);
            PMC *av_cont    = accessor_call(interp, attr, avcont_str);

            /* Work out what unboxed type it is, if any. Default to a boxed. */
            INTVAL unboxed_type = STORAGE_SPEC_BP_NONE;
            INTVAL bits         = sizeof(PMC *) * 8;
            if (!PMC_IS_NULL(type)) {
                /* Get the storage spec of the type and see what it wants. */
                storage_spec spec = REPR(type)->get_storage_spec(interp, STABLE(type));
                if (spec.inlineable == STORAGE_SPEC_INLINED) {
                    /* Yes, it's something we'll flatten. */
                    unboxed_type = spec.boxed_primitive;
                    bits = spec.bits;
                    repr_data->flattened_stables[i] = STABLE(type);
                    
                    /* Does it need special initialization? */
                    if (REPR(type)->initialize) {
                        if (!repr_data->initialize_slots)
                            repr_data->initialize_slots = (INTVAL *) mem_sys_allocate_zeroed((info_alloc + 1) * sizeof(INTVAL));
                        repr_data->initialize_slots[cur_init_slot] = i;
                        cur_init_slot++;
                    }
                    
                    /* Does it have special GC needs? */
                    if (REPR(type)->gc_mark) {
                        if (!repr_data->gc_mark_slots)
                            repr_data->gc_mark_slots = (INTVAL *) mem_sys_allocate_zeroed((info_alloc + 1) * sizeof(INTVAL));
                        repr_data->gc_mark_slots[cur_mark_slot] = i;
                        cur_mark_slot++;
                    }
                    if (REPR(type)->gc_cleanup) {
                        if (!repr_data->gc_cleanup_slots)
                            repr_data->gc_cleanup_slots = (INTVAL *) mem_sys_allocate_zeroed((info_alloc + 1) * sizeof(INTVAL));
                        repr_data->gc_cleanup_slots[cur_cleanup_slot] = i;
                        cur_cleanup_slot++;
                    }

                    /* Is it a target for box/unbox operations? */
                    if (!PMC_IS_NULL(box_target) && VTABLE_get_bool(interp, box_target)) {
                        /* If it boxes a primitive, note that. */
                        switch (unboxed_type) {
                        case STORAGE_SPEC_BP_INT:
                            if (repr_data->unbox_int_slot >= 0)
                                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
                                        "Duplicate box_target for native int");
                            repr_data->unbox_int_slot = i;
                            break;
                        case STORAGE_SPEC_BP_NUM:
                            if (repr_data->unbox_num_slot >= 0)
                                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
                                        "Duplicate box_target for native num");
                            repr_data->unbox_num_slot = i;
                            break;
                        case STORAGE_SPEC_BP_STR:
                            if (repr_data->unbox_str_slot >= 0)
                                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
                                        "Duplicate box_target for native str");
                            repr_data->unbox_str_slot = i;
                            break;
                        default:
                            /* nothing, just suppress 'missing default' warning */
                            break;
                        }
                        
                        /* Also list in the by-repr unbox list. */
                        if (repr_data->unbox_slots == NULL)
                            repr_data->unbox_slots = (P6opaqueBoxedTypeMap *) mem_sys_allocate_zeroed(info_alloc * sizeof(P6opaqueBoxedTypeMap));
                        repr_data->unbox_slots[cur_unbox_slot].repr_id = REPR(type)->ID;
                        repr_data->unbox_slots[cur_unbox_slot].slot = i;
                        cur_unbox_slot++;
                    }
                }
            }

            /* Handle PMC attributes, which need marking and may have auto-viv needs. */
            if (unboxed_type == STORAGE_SPEC_BP_NONE) {
                if (!repr_data->gc_pmc_mark_offsets)
                    repr_data->gc_pmc_mark_offsets = (INTVAL *) mem_sys_allocate_zeroed(info_alloc * sizeof(INTVAL));
                repr_data->gc_pmc_mark_offsets[cur_pmc_attr] = cur_size;
                cur_pmc_attr++;
                if (!PMC_IS_NULL(av_cont)) {
                    if (!repr_data->auto_viv_values)
                        repr_data->auto_viv_values = (PMC **) mem_sys_allocate_zeroed(info_alloc * sizeof(PMC *));
                    repr_data->auto_viv_values[i] = av_cont;
                }
            }
            
            /* Do allocation. */
            /* XXX TODO Alignment! Important when we get int1, int8, etc. */
            repr_data->attribute_offsets[i] = cur_size;
            cur_size += bits / 8;
        }

        /* Finally, put computed allocation size in place; it's body size plus
         * header size. Also number of markables and sentinels. */
        repr_data->allocation_size = cur_size + sizeof(P6opaqueInstance);
        repr_data->gc_pmc_mark_offsets_count = cur_pmc_attr;
        if (repr_data->initialize_slots)
            repr_data->initialize_slots[cur_init_slot] = -1;
        if (repr_data->gc_mark_slots)
            repr_data->gc_mark_slots[cur_mark_slot] = -1;
        if (repr_data->gc_cleanup_slots)
            repr_data->gc_cleanup_slots[cur_cleanup_slot] = -1;
    }

    Parrot_unblock_GC_mark(interp);
}
Example #7
0
/* Bootstraps the KnowHOW. This is were things "bottom out" in the meta-model
 * so it's a tad loopy. Basically, we create a KnowHOW type object. We then
 * create an instance from that and add a bunch of methods to it. Returns the
 * bootstrapped object. */
PMC * SixModelObject_bootstrap_knowhow(PARROT_INTERP, PMC *sc) {
    /* Create our KnowHOW type object. Note we don't have a HOW just yet, so
     * pass in null. */
    REPROps *REPR        = REPR_get_by_name(interp, Parrot_str_new_constant(interp, "KnowHOWREPR"));
    PMC     *knowhow_pmc = REPR->type_object_for(interp, PMCNULL);

    /* We create a KnowHOW instance that can describe itself. This means
     * .HOW.HOW.HOW.HOW etc will always return that, which closes the model
     * up. Also pull out its underlying struct. */
    PMC *knowhow_how_pmc = REPR->allocate(interp, NULL);
    KnowHOWREPRInstance *knowhow_how = (KnowHOWREPRInstance *)PMC_data(knowhow_how_pmc);

    /* Need to give the knowhow_how a twiddled STable with a different
     * dispatcher, so things bottom out. */
    PMC *st_copy = create_stable(interp, REPR, knowhow_how_pmc);
    STABLE_STRUCT(st_copy)->WHAT = knowhow_pmc;
    STABLE_STRUCT(st_copy)->find_method = bottom_find_method;
    knowhow_how->common.stable = st_copy;

    /* Add various methods to the KnowHOW's HOW. */
    knowhow_how->body.methods = Parrot_pmc_new(interp, enum_class_Hash);
    knowhow_how->body.attributes = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
    VTABLE_set_pmc_keyed_str(interp, knowhow_how->body.methods,
        Parrot_str_new_constant(interp, "new_type"),
        wrap_c(interp, F2DPTR(new_type)));
    VTABLE_set_pmc_keyed_str(interp, knowhow_how->body.methods,
        Parrot_str_new_constant(interp, "find_method"),
        wrap_c(interp, F2DPTR(find_method)));
    VTABLE_set_pmc_keyed_str(interp, knowhow_how->body.methods,
        Parrot_str_new_constant(interp, "add_method"),
        wrap_c(interp, F2DPTR(add_method)));
    VTABLE_set_pmc_keyed_str(interp, knowhow_how->body.methods,
        Parrot_str_new_constant(interp, "add_attribute"),
        wrap_c(interp, F2DPTR(add_attribute)));
    VTABLE_set_pmc_keyed_str(interp, knowhow_how->body.methods,
        Parrot_str_new_constant(interp, "compose"),
        wrap_c(interp, F2DPTR(compose)));
    VTABLE_set_pmc_keyed_str(interp, knowhow_how->body.methods,
        Parrot_str_new_constant(interp, "parents"),
        wrap_c(interp, F2DPTR(parents)));
    VTABLE_set_pmc_keyed_str(interp, knowhow_how->body.methods,
        Parrot_str_new_constant(interp, "attributes"),
        wrap_c(interp, F2DPTR(attributes)));
    VTABLE_set_pmc_keyed_str(interp, knowhow_how->body.methods,
        Parrot_str_new_constant(interp, "methods"),
        wrap_c(interp, F2DPTR(methods)));
    VTABLE_set_pmc_keyed_str(interp, knowhow_how->body.methods,
        Parrot_str_new_constant(interp, "mro"),
        wrap_c(interp, F2DPTR(mro)));
    VTABLE_set_pmc_keyed_str(interp, knowhow_how->body.methods,
        Parrot_str_new_constant(interp, "name"),
        wrap_c(interp, F2DPTR(name)));

    /* Set name KnowHOW for the KnowHOW's HOW. */
    knowhow_how->body.name = Parrot_str_new_constant(interp, "KnowHOW");

    /* Set this built up HOW as the KnowHOW's HOW. */
    STABLE(knowhow_pmc)->HOW = knowhow_how_pmc;
    
    /* Give it an authoritative method cache and type check list. */
    STABLE(knowhow_pmc)->method_cache = knowhow_how->body.methods;
    STABLE(knowhow_pmc)->mode_flags   = METHOD_CACHE_AUTHORITATIVE;
    STABLE(knowhow_pmc)->type_check_cache_length = 1;
    STABLE(knowhow_pmc)->type_check_cache        = (PMC **)mem_sys_allocate(sizeof(PMC *));
    STABLE(knowhow_pmc)->type_check_cache[0]     = knowhow_pmc;

    /* Set up some string constants that the methods here use. */
    repr_str      = Parrot_str_new_constant(interp, "repr");
    name_str      = Parrot_str_new_constant(interp, "name");
    empty_str     = Parrot_str_new_constant(interp, "");
    p6opaque_str  = Parrot_str_new_constant(interp, "P6opaque");
    attribute_str = Parrot_str_new_constant(interp, "attribute");

    /* Associate the created objects with the intial core serialization
     * context. */
    VTABLE_set_pmc_keyed_int(interp, sc, 0, knowhow_pmc);
    SC_PMC(knowhow_pmc) = sc;
    VTABLE_set_pmc_keyed_int(interp, sc, 1, knowhow_how_pmc);
    SC_PMC(knowhow_how_pmc) = sc;
    STABLE(knowhow_pmc)->sc = sc;
    STABLE(knowhow_how_pmc)->sc = sc;

    return knowhow_pmc;
}
Example #8
0
int
main(int argc, const char *argv[])
{
    int nextarg;
    Parrot_Interp     interp;
    PDB_t *pdb;
    const char       *scriptname = NULL;

    interp = Parrot_interp_new(NULL);

    Parrot_debugger_init(interp);
    pdb = interp->pdb;
    pdb->state       = PDB_ENTER;

    Parrot_block_GC_mark(interp);
    Parrot_block_GC_sweep(interp);

    nextarg = 1;
    if (argv[nextarg] && strcmp(argv[nextarg], "--script") == 0) {
        scriptname = argv [++nextarg];
        ++nextarg;
    }

    if (argv[nextarg]) {
        const char * const filename = argv[nextarg];

        if (*filename == '-') {
            fprintf(stderr, "parrot_debugger takes no -x or --xxxx flag arguments\n");
            exit(1);
        }
        else {
            STRING *   const filename_str = Parrot_str_new(interp, filename, 0);
            PackFile * const pfraw        = Parrot_pf_read_pbc_file(interp, filename_str);
            Parrot_PackFile pf;

            if (pfraw == NULL)
                return 1;

            pf = Parrot_pf_get_packfile_pmc(interp, pfraw, filename_str);
            if (pf == NULL)
                return 1;

            Parrot_pf_set_current_packfile(interp, pf);
            Parrot_pf_prepare_packfile_init(interp, pf);
        }
    }
    else {
        /* Generate some code to be able to enter into runloop */
        STRING * const compiler_s = Parrot_str_new_constant(interp, "PIR");
        PMC *    const compiler   = Parrot_interp_get_compiler(interp, compiler_s);
        STRING * const source     = Parrot_str_new_constant(interp,
                                        ".sub aux :main\nexit 0\n.end\n");
        PMC *    const code       = Parrot_interp_compile_string(interp, compiler, source);

        if (PMC_IS_NULL(code))
            Parrot_warn(interp, PARROT_WARNINGS_NONE_FLAG,
                "Unexpected compiler problem at debugger start");
    }

    Parrot_unblock_GC_mark(interp);
    Parrot_unblock_GC_sweep(interp);

    if (scriptname)
        PDB_script_file(interp, scriptname);
    else
        PDB_printwelcome();

    Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "debugger"));
    PDB_run_code(interp, argc - nextarg, argv + nextarg);

    Parrot_x_exit(interp, 0);
}
Example #9
0
/* This works out an allocation strategy for the object. It takes care of
 * "inlining" storage of attributes that are natively typed, as well as
 * noting unbox targets. */
static void compute_allocation_strategy(PARROT_INTERP, PMC *repr_info, CStructREPRData *repr_data) {
    STRING *type_str = Parrot_str_new_constant(interp, "type");
    PMC    *flat_list;

    /*
     * We have to block GC mark here. Because "repr" is assotiated with some
     * PMC which is not accessible in this function. And we have to write
     * barrier this PMC because we are poking inside it guts directly. We
     * do have WB in caller function, but it can be triggered too late is
     * any of allocation will cause GC run.
     *
     * This is kind of minor evil until after I'll find better solution.
     */
    Parrot_block_GC_mark(interp);

    /* Compute index mapping table and get flat list of attributes. */
    flat_list = index_mapping_and_flat_list(interp, repr_info, repr_data);
    
    /* If we have no attributes in the index mapping, then just the header. */
    if (repr_data->name_to_index_mapping[0].class_key == NULL) {
        repr_data->struct_size = 1; /* avoid 0-byte malloc */
    }

    /* Otherwise, we need to compute the allocation strategy.  */
    else {
        /* We track the size of the struct, which is what we'll want offsets into. */
        INTVAL cur_size = 0;
        
        /* Get number of attributes and set up various counters. */
        INTVAL num_attrs        = VTABLE_elements(interp, flat_list);
        INTVAL info_alloc       = num_attrs == 0 ? 1 : num_attrs;
        INTVAL cur_obj_attr     = 0;
        INTVAL cur_str_attr     = 0;
        INTVAL cur_init_slot    = 0;
        INTVAL i;

        /* Allocate location/offset arrays and GC mark info arrays. */
        repr_data->num_attributes      = num_attrs;
        repr_data->attribute_locations = (INTVAL *) mem_sys_allocate(info_alloc * sizeof(INTVAL));
        repr_data->struct_offsets      = (INTVAL *) mem_sys_allocate(info_alloc * sizeof(INTVAL));
        repr_data->flattened_stables   = (STable **) mem_sys_allocate_zeroed(info_alloc * sizeof(PMC *));
        repr_data->member_types        = (PMC** )    mem_sys_allocate_zeroed(info_alloc * sizeof(PMC *));

        /* Go over the attributes and arrange their allocation. */
        for (i = 0; i < num_attrs; i++) {
            /* Fetch its type; see if it's some kind of unboxed type. */
            PMC    *attr         = VTABLE_get_pmc_keyed_int(interp, flat_list, i);
            PMC    *type         = VTABLE_get_pmc_keyed_str(interp, attr, type_str);
            INTVAL  type_id      = REPR(type)->ID;
            INTVAL  bits         = sizeof(void *) * 8;
            INTVAL  align        = ALIGNOF1(void *);
            if (!PMC_IS_NULL(type)) {
                /* See if it's a type that we know how to handle in a C struct. */
                storage_spec spec = REPR(type)->get_storage_spec(interp, STABLE(type));
                if (spec.inlineable == STORAGE_SPEC_INLINED &&
                        (spec.boxed_primitive == STORAGE_SPEC_BP_INT ||
                         spec.boxed_primitive == STORAGE_SPEC_BP_NUM)) {
                    /* It's a boxed int or num; pretty easy. It'll just live in the
                     * body of the struct. Instead of masking in i here (which
                     * would be the parallel to how we handle boxed types) we
                     * repurpose it to store the bit-width of the type, so
                     * that get_attribute_ref can find it later. */
                    bits = spec.bits;
                    align = spec.align;

                    if (bits % 8) {
                        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
                                "CStruct only supports native types that are a multiple of 8 bits wide (was passed: %ld)", bits);
                    }

                    repr_data->attribute_locations[i] = (bits << CSTRUCT_ATTR_SHIFT) | CSTRUCT_ATTR_IN_STRUCT;
                    repr_data->flattened_stables[i] = STABLE(type);
                    if (REPR(type)->initialize) {
                        if (!repr_data->initialize_slots)
                            repr_data->initialize_slots = (INTVAL *) mem_sys_allocate_zeroed((info_alloc + 1) * sizeof(INTVAL));
                        repr_data->initialize_slots[cur_init_slot] = i;
                        cur_init_slot++;
                    }
                }
                else if(spec.can_box & STORAGE_SPEC_CAN_BOX_STR) {
                    /* It's a string of some kind.  */
                    repr_data->num_child_objs++;
                    repr_data->attribute_locations[i] = (cur_obj_attr++ << CSTRUCT_ATTR_SHIFT) | CSTRUCT_ATTR_STRING;
                    repr_data->member_types[i] = type;
                }
                else if(type_id == get_ca_repr_id()) {
                    /* It's a CArray of some kind.  */
                    repr_data->num_child_objs++;
                    repr_data->attribute_locations[i] = (cur_obj_attr++ << CSTRUCT_ATTR_SHIFT) | CSTRUCT_ATTR_CARRAY;
                    repr_data->member_types[i] = type;
                }
                else if(type_id == get_cs_repr_id()) {
                    /* It's a CStruct. */
                    repr_data->num_child_objs++;
                    repr_data->attribute_locations[i] = (cur_obj_attr++ << CSTRUCT_ATTR_SHIFT) | CSTRUCT_ATTR_CSTRUCT;
                    repr_data->member_types[i] = type;
                }
                else if(type_id == get_cp_repr_id()) {
                    /* It's a CPointer. */
                    repr_data->num_child_objs++;
                    repr_data->attribute_locations[i] = (cur_obj_attr++ << CSTRUCT_ATTR_SHIFT) | CSTRUCT_ATTR_CPTR;
                    repr_data->member_types[i] = type;
                }
                else {
                    Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
                        "CStruct representation only implements native int and float members so far");
                }
            }
            else {
                Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
                    "CStruct representation requires the types of all attributes to be specified");
            }
            
            /* Do allocation. */
            /* C structure needs careful alignment. If cur_size is not aligned
             * to align bytes (cur_size % align), make sure it is before we
             * add the next element. */
            if (cur_size % align) {
                cur_size += align - cur_size % align;
            }

            repr_data->struct_offsets[i] = cur_size;
            cur_size += bits / 8;
        }

        /* Finally, put computed allocation size in place; it's body size plus
         * header size. Also number of markables and sentinels. */
        repr_data->struct_size = cur_size;
        if (repr_data->initialize_slots)
            repr_data->initialize_slots[cur_init_slot] = -1;
    }

    Parrot_unblock_GC_mark(interp);
}
Example #10
0
/* Locates all of the attributes. Puts them onto a flattened, ordered
 * list of attributes (populating the passed flat_list). Also builds
 * the index mapping for doing named lookups. Note index is not related
 * to the storage position. */
static PMC * index_mapping_and_flat_list(PARROT_INTERP, PMC *mro, CStructREPRData *repr_data) {
    PMC    *flat_list      = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
    PMC    *class_list     = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
    PMC    *attr_map_list  = Parrot_pmc_new(interp, enum_class_ResizablePMCArray);
    STRING *name_str       = Parrot_str_new_constant(interp, "name");
    INTVAL  current_slot   = 0;
    
    INTVAL num_classes, i;
    CStructNameMap * result = NULL;
    
    /* Walk through the parents list. */
    INTVAL mro_idx = VTABLE_elements(interp, mro);
    while (mro_idx)
    {
        /* Get current class in MRO. */
        PMC    *type_info     = VTABLE_get_pmc_keyed_int(interp, mro, --mro_idx);
        PMC    *current_class = decontainerize(interp, VTABLE_get_pmc_keyed_int(interp, type_info, 0));
        
        /* Get its local parents; make sure we're not doing MI. */
        PMC    *parents     = VTABLE_get_pmc_keyed_int(interp, type_info, 2);
        INTVAL  num_parents = VTABLE_elements(interp, parents);
        if (num_parents <= 1) {
            /* Get attributes and iterate over them. */
            PMC *attributes = VTABLE_get_pmc_keyed_int(interp, type_info, 1);
            PMC *attr_map   = PMCNULL;
            PMC *attr_iter  = VTABLE_get_iter(interp, attributes);
            while (VTABLE_get_bool(interp, attr_iter)) {
                /* Get attribute. */
                PMC * attr = VTABLE_shift_pmc(interp, attr_iter);

                /* Get its name. */
                PMC    *name_pmc = VTABLE_get_pmc_keyed_str(interp, attr, name_str);
                STRING *name     = VTABLE_get_string(interp, name_pmc);

                /* Allocate a slot. */
                if (PMC_IS_NULL(attr_map))
                    attr_map = Parrot_pmc_new(interp, enum_class_Hash);
                VTABLE_set_pmc_keyed_str(interp, attr_map, name,
                    Parrot_pmc_new_init_int(interp, enum_class_Integer, current_slot));
                current_slot++;

                /* Push attr onto the flat list. */
                VTABLE_push_pmc(interp, flat_list, attr);
            }

            /* Add to class list and map list. */
            VTABLE_push_pmc(interp, class_list, current_class);
            VTABLE_push_pmc(interp, attr_map_list, attr_map);
        }
        else {
            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
                "CStruct representation does not support multiple inheritance");
        }
    }

    /* We can now form the name map. */
    num_classes = VTABLE_elements(interp, class_list);
    result = (CStructNameMap *) mem_sys_allocate_zeroed(sizeof(CStructNameMap) * (1 + num_classes));
    for (i = 0; i < num_classes; i++) {
        result[i].class_key = VTABLE_get_pmc_keyed_int(interp, class_list, i);
        result[i].name_map  = VTABLE_get_pmc_keyed_int(interp, attr_map_list, i);
    }
    repr_data->name_to_index_mapping = result;

    return flat_list;
}
Example #11
0
void
parrot_init_library_paths(PARROT_INTERP)
{
    ASSERT_ARGS(parrot_init_library_paths)
    PMC    *paths;
    STRING *entry;
    STRING *versionlib      = NULL;
    STRING *builddir        = NULL;
    PMC * const iglobals    = interp->iglobals;
    PMC * const config_hash = VTABLE_get_pmc_keyed_int(interp, iglobals,
                                (INTVAL)IGLOBALS_CONFIG_HASH);

    /* create the lib_paths array */
    PMC * const lib_paths   = Parrot_pmc_new_init_int(interp,
            enum_class_FixedPMCArray, PARROT_LIB_PATH_SIZE);
    VTABLE_set_pmc_keyed_int(interp, iglobals,
            IGLOBALS_LIB_PATHS, lib_paths);

    if (VTABLE_elements(interp, config_hash)) {
        STRING * const libkey      = CONST_STRING(interp, "libdir");
        STRING * const verkey      = CONST_STRING(interp, "versiondir");
        STRING * const builddirkey = CONST_STRING(interp, "build_dir");
        STRING * const installed   = CONST_STRING(interp, "installed");

        versionlib = VTABLE_get_string_keyed_str(interp, config_hash, libkey);
        entry      = VTABLE_get_string_keyed_str(interp, config_hash, verkey);
        versionlib = Parrot_str_concat(interp, versionlib, entry);

        if (!VTABLE_get_integer_keyed_str(interp, config_hash, installed))
            builddir = VTABLE_get_string_keyed_str(interp,
                                config_hash, builddirkey);
    }

    /* each is an array of strings */
    /* define include paths */
    paths = Parrot_pmc_new(interp, enum_class_ResizableStringArray);
    VTABLE_set_pmc_keyed_int(interp, lib_paths,
            PARROT_LIB_PATH_INCLUDE, paths);
    { /* EXPERIMENTAL: add include path from environment */
        const char *envvar = Parrot_getenv(interp,
                                           Parrot_str_new_constant(interp, "PARROT_INCLUDE"));
        if (envvar != NULL  && envvar[0]) {
            entry = Parrot_str_new(interp, envvar, 0);
            VTABLE_push_string(interp, paths, entry);
        }
    }
    if (!STRING_IS_NULL(builddir)) {
        entry = Parrot_str_concat(interp, builddir, CONST_STRING(interp, "/"));
        VTABLE_push_string(interp, paths, entry);
        entry = Parrot_str_concat(interp, builddir, CONST_STRING(interp, "/runtime/parrot/include/"));
        VTABLE_push_string(interp, paths, entry);
    }
    entry = CONST_STRING(interp, "./");
    VTABLE_push_string(interp, paths, entry);
    if (!STRING_IS_NULL(versionlib)) {
        entry = Parrot_str_concat(interp, versionlib, CONST_STRING(interp, "/include/"));
        VTABLE_push_string(interp, paths, entry);
    }

    /* define library paths */
    paths = Parrot_pmc_new(interp, enum_class_ResizableStringArray);
    VTABLE_set_pmc_keyed_int(interp, lib_paths,
            PARROT_LIB_PATH_LIBRARY, paths);
    { /* EXPERIMENTAL: add library path from environment */
        const char *envvar = Parrot_getenv(interp,
                                           Parrot_str_new_constant(interp, "PARROT_LIBRARY"));
        if (envvar != NULL && envvar[0]) {
            entry = Parrot_str_new(interp, envvar, 0);
            VTABLE_push_string(interp, paths, entry);
        }
    }
    if (!STRING_IS_NULL(builddir)) {
        entry = Parrot_str_concat(interp, builddir, CONST_STRING(interp, "/runtime/parrot/library/"));
        VTABLE_push_string(interp, paths, entry);
    }
    entry = CONST_STRING(interp, "./");
    VTABLE_push_string(interp, paths, entry);
    if (!STRING_IS_NULL(versionlib)) {
        entry = Parrot_str_concat(interp, versionlib, CONST_STRING(interp, "/library/"));
        VTABLE_push_string(interp, paths, entry);
    }

    /* define languages paths */
    paths = Parrot_pmc_new(interp, enum_class_ResizableStringArray);
    VTABLE_set_pmc_keyed_int(interp, lib_paths,
            PARROT_LIB_PATH_LANG, paths);
    if (!STRING_IS_NULL(builddir)) {
        entry = Parrot_str_concat(interp, builddir, CONST_STRING(interp, "/runtime/parrot/languages/"));
        VTABLE_push_string(interp, paths, entry);
    }
    entry = CONST_STRING(interp, "./");
    VTABLE_push_string(interp, paths, entry);
    if (!STRING_IS_NULL(versionlib)) {
        entry = Parrot_str_concat(interp, versionlib, CONST_STRING(interp, "/languages/"));
        VTABLE_push_string(interp, paths, entry);
    }

    /* define dynext paths */
    paths = Parrot_pmc_new(interp, enum_class_ResizableStringArray);
    VTABLE_set_pmc_keyed_int(interp, lib_paths,
            PARROT_LIB_PATH_DYNEXT, paths);
    if (!STRING_IS_NULL(builddir)) {
        entry = Parrot_str_concat(interp, builddir, CONST_STRING(interp, "/runtime/parrot/dynext/"));
        VTABLE_push_string(interp, paths, entry);
    }
    entry = CONST_STRING(interp, "dynext/");
    VTABLE_push_string(interp, paths, entry);
    if (!STRING_IS_NULL(versionlib)) {
        entry = Parrot_str_concat(interp, versionlib, CONST_STRING(interp, "/dynext/"));
        VTABLE_push_string(interp, paths, entry);
    }

    /* shared exts */
    paths = Parrot_pmc_new(interp, enum_class_ResizableStringArray);
    VTABLE_set_pmc_keyed_int(interp, lib_paths,
            PARROT_LIB_DYN_EXTS, paths);
    /* no CONST_STRING here - the c2str.pl preprocessor needs "real strs" */
    entry = Parrot_str_new_constant(interp, PARROT_LOAD_EXT);
    VTABLE_push_string(interp, paths, entry);
    /* OS/X has .dylib and .bundle */
    if (!STREQ(PARROT_LOAD_EXT, PARROT_SHARE_EXT)) {
        entry = Parrot_str_new_constant(interp, PARROT_SHARE_EXT);
        VTABLE_push_string(interp, paths, entry);
    }

#ifdef PARROT_PLATFORM_LIB_PATH_INIT_HOOK
    PARROT_PLATFORM_LIB_PATH_INIT_HOOK(interp, lib_paths);
#endif
}
Example #12
0
File: main.c Project: kapace/parrot
int
main(int argc, const char *argv[])
{
    int nextarg;
    Parrot_Interp     interp;
    PDB_t *pdb;
    const char       *scriptname = NULL;
    const unsigned char * configbytes = Parrot_get_config_hash_bytes();
    const int configlength = Parrot_get_config_hash_length();

    interp = Parrot_new(NULL);

    Parrot_set_executable_name(interp, Parrot_str_new(interp, argv[0], 0));

    Parrot_set_configuration_hash_legacy(interp, configlength, configbytes);

    Parrot_debugger_init(interp);
    pdb = interp->pdb;
    pdb->state       = PDB_ENTER;

    Parrot_block_GC_mark(interp);
    Parrot_block_GC_sweep(interp);

    nextarg = 1;
    if (argv[nextarg] && strcmp(argv[nextarg], "--script") == 0)
    {
        scriptname = argv [++nextarg];
        ++nextarg;
    }

    if (argv[nextarg]) {
        const char *filename = argv[nextarg];
        const char *ext      = strrchr(filename, '.');

        if (ext && STREQ(ext, ".pbc")) {
            Parrot_PackFile pf = Parrot_pbc_read(interp, filename, 0);

            if (!pf)
                return 1;

            Parrot_pbc_load(interp, pf);
            PackFile_fixup_subs(interp, PBC_MAIN, NULL);
        }
        else {
            STRING          *errmsg = NULL;
            Parrot_PackFile  pf     = PackFile_new(interp, 0);

            Parrot_pbc_load(interp, pf);
            Parrot_compile_file(interp, filename, &errmsg);
            if (errmsg)
                Parrot_ex_throw_from_c_args(interp, NULL, 1, "%S", errmsg);
            PackFile_fixup_subs(interp, PBC_POSTCOMP, NULL);

            /* load the source for debugger list */
            PDB_load_source(interp, filename);

            PackFile_fixup_subs(interp, PBC_MAIN, NULL);
        }

    }
    else {
        /* Generate some code to be able to enter into runloop */

        STRING *compiler = Parrot_str_new_constant(interp, "PIR");
        STRING *errstr = NULL;
        const char source []= ".sub aux :main\nexit 0\n.end\n";
        Parrot_compile_string(interp, compiler, source, &errstr);

        if (!STRING_IS_NULL(errstr))
            Parrot_io_eprintf(interp, "%Ss\n", errstr);
    }

    Parrot_unblock_GC_mark(interp);
    Parrot_unblock_GC_sweep(interp);

    if (scriptname)
        PDB_script_file(interp, scriptname);
    else
        PDB_printwelcome();

    Parrot_runcore_switch(interp, Parrot_str_new_constant(interp, "debugger"));
    PDB_run_code(interp, argc - nextarg, argv + nextarg);

    Parrot_x_exit(interp, 0);
}
Example #13
0
void
parrot_init_library_paths(PARROT_INTERP)
{
    ASSERT_ARGS(parrot_init_library_paths)
    PMC    *paths;
    STRING *entry;
    PMC * const iglobals    = interp->iglobals;

    /* create the lib_paths array */
    PMC * const lib_paths   = Parrot_pmc_new_init_int(interp,
            enum_class_FixedPMCArray, PARROT_LIB_PATH_SIZE);
    VTABLE_set_pmc_keyed_int(interp, iglobals,
            IGLOBALS_LIB_PATHS, lib_paths);

    /* each is an array of strings */
    /* define include paths */
    paths = Parrot_pmc_new(interp, enum_class_ResizableStringArray);
    VTABLE_set_pmc_keyed_int(interp, lib_paths,
            PARROT_LIB_PATH_INCLUDE, paths);
    { /* EXPERIMENTAL: add include path from environment */
        STRING *envvar = Parrot_getenv(interp, CONST_STRING(interp, "PARROT_INCLUDE"));
        Parrot_warn_experimental(interp, "PARROT_INCLUDE environment variable is experimental");
        if (!STRING_IS_NULL(envvar) && !STRING_IS_EMPTY(envvar))
            VTABLE_push_string(interp, paths, envvar);
    }
    entry = CONST_STRING(interp, "./");
    VTABLE_push_string(interp, paths, entry);

    /* define library paths */
    paths = Parrot_pmc_new(interp, enum_class_ResizableStringArray);
    VTABLE_set_pmc_keyed_int(interp, lib_paths,
            PARROT_LIB_PATH_LIBRARY, paths);
    { /* EXPERIMENTAL: add library path from environment */
        STRING *envvar = Parrot_getenv(interp, CONST_STRING(interp, "PARROT_LIBRARY"));
        Parrot_warn_experimental(interp, "PARROT_LIBRARY environment variable is experimental");
        if (!STRING_IS_NULL(envvar) && !STRING_IS_EMPTY(envvar))
            VTABLE_push_string(interp, paths, envvar);
    }
    entry = CONST_STRING(interp, "./");
    VTABLE_push_string(interp, paths, entry);

    /* define languages paths */
    paths = Parrot_pmc_new(interp, enum_class_ResizableStringArray);
    VTABLE_set_pmc_keyed_int(interp, lib_paths,
            PARROT_LIB_PATH_LANG, paths);
    entry = CONST_STRING(interp, "./");
    VTABLE_push_string(interp, paths, entry);

    /* define dynext paths */
    paths = Parrot_pmc_new(interp, enum_class_ResizableStringArray);
    VTABLE_set_pmc_keyed_int(interp, lib_paths,
            PARROT_LIB_PATH_DYNEXT, paths);
    entry = CONST_STRING(interp, "dynext/");
    VTABLE_push_string(interp, paths, entry);

    /* shared exts */
    paths = Parrot_pmc_new(interp, enum_class_ResizableStringArray);
    VTABLE_set_pmc_keyed_int(interp, lib_paths,
            PARROT_LIB_DYN_EXTS, paths);
    /* no CONST_STRING here - the c2str.pl preprocessor needs "real strs" */
    entry = Parrot_str_new_constant(interp, PARROT_LOAD_EXT);
    VTABLE_push_string(interp, paths, entry);
    /* OS/X has .dylib and .bundle */
    if (!STREQ(PARROT_LOAD_EXT, PARROT_SHARE_EXT)) {
        entry = Parrot_str_new_constant(interp, PARROT_SHARE_EXT);
        VTABLE_push_string(interp, paths, entry);
    }

#ifdef PARROT_PLATFORM_LIB_PATH_INIT_HOOK
    PARROT_PLATFORM_LIB_PATH_INIT_HOOK(interp, lib_paths);
#endif
}
Example #14
0
/* Initializes our cached versions of some strings and type IDs that we
 * use very commonly. For strings, this should mean we only compute their
 * hash value once, rather than every time we create and consume them. */
static void setup_binder_statics(PARROT_INTERP) {
    ACCEPTS          = Parrot_str_new_constant(interp, "ACCEPTS");
    HOW              = Parrot_str_new_constant(interp, "HOW");
    DO_str           = Parrot_str_new_constant(interp, "$!do");
    NAME_str         = Parrot_str_new_constant(interp, "name");
    SELF_str         = Parrot_str_new_constant(interp, "self");
    BLOCK_str        = Parrot_str_new_constant(interp, "Block");
    CAPTURE_str      = Parrot_str_new_constant(interp, "Capture");
    STORAGE_str      = Parrot_str_new_constant(interp, "$!storage");
    REST_str         = Parrot_str_new_constant(interp, "$!rest");
    LIST_str         = Parrot_str_new_constant(interp, "$!list");
    HASH_str         = Parrot_str_new_constant(interp, "$!hash");
    FLATTENS_str     = Parrot_str_new_constant(interp, "$!flattens");
    NEXTITER_str     = Parrot_str_new_constant(interp, "$!nextiter");
    HASH_SIGIL_str   = Parrot_str_new_constant(interp, "%");
    ARRAY_SIGIL_str  = Parrot_str_new_constant(interp, "@");
    BANG_TWIGIL_str  = Parrot_str_new_constant(interp, "!");
    SCALAR_SIGIL_str = Parrot_str_new_constant(interp, "$");
    NAMED_str        = Parrot_str_new_constant(interp, "named");
    INSTANTIATE_GENERIC_str = Parrot_str_new_constant(interp, "instantiate_generic");
    
    smo_id  = Parrot_pmc_get_type_str(interp, Parrot_str_new(interp, "SixModelObject", 0));
    p6l_id  = Parrot_pmc_get_type_str(interp, Parrot_str_new(interp, "Perl6LexPad", 0));
    qrpa_id = Parrot_pmc_get_type_str(interp, Parrot_str_new(interp, "QRPA", 0));
}
Example #15
0
PARROT_EXPORT
void
Parrot_disassemble(PARROT_INTERP,
                   ARGIN_NULLOK(const char *outfile), Parrot_disassemble_options options)
{
    ASSERT_ARGS(Parrot_disassemble)
    PDB_line_t *line;
    PDB_t * const pdb   = mem_gc_allocate_zeroed_typed(interp, PDB_t);
    int num_mappings    = 0;
    int curr_mapping    = 0;
    int op_code_seq_num = 0;
    int debugs;
    PMC *output;

    if (outfile != NULL) {
        output = Parrot_io_open_handle(interp, PMCNULL,
                Parrot_str_new(interp, outfile, 0),
                Parrot_str_new_constant(interp, "tw"));
    }
    else
        output = Parrot_io_stdhandle(interp, PIO_STDOUT_FILENO, PMCNULL);

    interp->pdb     = pdb;
    pdb->cur_opcode = interp->code->base.data;

    PDB_disassemble(interp, NULL);

    line   = pdb->file->line;
    debugs = (interp->code->debugs != NULL);

    print_constant_table(interp, output);
    if (options & enum_DIS_HEADER)
        return;

    if (!(options & enum_DIS_BARE))
        Parrot_io_fprintf(interp, output, "# %12s-%12s", "Seq_Op_Num", "Relative-PC");

    if (debugs) {
        if (!(options & enum_DIS_BARE))
            Parrot_io_fprintf(interp, output, " %6s:\n", "SrcLn#");
        num_mappings = interp->code->debugs->num_mappings;
    }
    else {
        Parrot_io_fprintf(interp, output, "\n");
    }

    while (line->next) {
        const char *c;

        /* Parrot_io_fprintf(interp, output, "%i < %i %i == %i \n", curr_mapping,
         * num_mappings, op_code_seq_num,
         * interp->code->debugs->mappings[curr_mapping].offset); */

        if (debugs && curr_mapping < num_mappings) {
            if (op_code_seq_num == interp->code->debugs->mappings[curr_mapping].offset) {
                const int filename_const_offset =
                    interp->code->debugs->mappings[curr_mapping].filename;
                Parrot_io_fprintf(interp, output, "# Current Source Filename '%Ss'\n",
                        interp->code->const_table->str.constants[filename_const_offset]);
                ++curr_mapping;
            }
        }

        if (!(options & enum_DIS_BARE))
            Parrot_io_fprintf(interp, output, "%012i-%012i",
                             op_code_seq_num, line->opcode - interp->code->base.data);

        if (debugs && !(options & enum_DIS_BARE))
            Parrot_io_fprintf(interp, output, " %06i: ",
                    interp->code->debugs->base.data[op_code_seq_num]);

        /* If it has a label print it */
        if (line->label)
            Parrot_io_fprintf(interp, output, "L%li:\t", line->label->number);
        else
            Parrot_io_fprintf(interp, output, "\t");

        c = pdb->file->source + line->source_offset;

        while (c && *c != '\n')
            Parrot_io_fprintf(interp, output, "%c", *(c++));

        Parrot_io_fprintf(interp, output, "\n");
        line = line->next;
        ++op_code_seq_num;
    }
    if (outfile != NULL)
        Parrot_io_close_handle(interp, output);

    return;
}
Example #16
0
/* Wraps up a C function as a raw NCI method. */
static PMC * wrap_c(PARROT_INTERP, void *func) {
    PMC * const wrapped = Parrot_pmc_new(interp, enum_class_NativePCCMethod);
    VTABLE_set_pointer_keyed_str(interp, wrapped, Parrot_str_new_constant(interp, "->"), func);
    return wrapped;
}
Example #17
0
/* Initializes our cached versions of some strings and type IDs that we
 * use very commonly. For strings, this should mean we only compute their
 * hash value once, rather than every time we create and consume them. */
static void setup_binder_statics(PARROT_INTERP) {

    ACCEPTS          = Parrot_str_new_constant(interp, "ACCEPTS");
    HOW              = Parrot_str_new_constant(interp, "HOW");
    DO_str           = Parrot_str_new_constant(interp, "$!do");
    RW_str           = Parrot_str_new_constant(interp, "rw");
    PUN_str          = Parrot_str_new_constant(interp, "!pun");
    PERL_str         = Parrot_str_new_constant(interp, "perl");
    HASH_str         = Parrot_str_new_constant(interp, "Hash");
    LIST_str         = Parrot_str_new_constant(interp, "List");
    SELF_str         = Parrot_str_new_constant(interp, "self");
    ARRAY_str        = Parrot_str_new_constant(interp, "Array");
    BLOCK_str        = Parrot_str_new_constant(interp, "Block");
    STORE_str        = Parrot_str_new_constant(interp, "!STORE");
    CREATE_str       = Parrot_str_new_constant(interp, "CREATE");
    SCALAR_str       = Parrot_str_new_constant(interp, "scalar");
    SELECT_str       = Parrot_str_new_constant(interp, "!select");
    CAPTURE_str      = Parrot_str_new_constant(interp, "Capture");
    SNAPCAP_str      = Parrot_str_new_constant(interp, "!snapshot_capture");
    STORAGE_str      = Parrot_str_new_constant(interp, "$!storage");
    JUNCTION_str     = Parrot_str_new_constant(interp, "Junction");
    P6_SCALAR_str    = Parrot_str_new_constant(interp, "Perl6Scalar");
    SHORTNAME_str    = Parrot_str_new_constant(interp, "shortname");
    HASH_SIGIL_str   = Parrot_str_new_constant(interp, "%");
    ARRAY_SIGIL_str  = Parrot_str_new_constant(interp, "@");
    BANG_TWIGIL_str  = Parrot_str_new_constant(interp, "!");
    CALLCONTEXT_str  = Parrot_str_new_constant(interp, "CallContext");
    SCALAR_SIGIL_str = Parrot_str_new_constant(interp, "$");

    or_id  = pmc_type(interp, Parrot_str_new(interp, "ObjectRef", 0));
    lls_id = pmc_type(interp, Parrot_str_new(interp, "P6LowLevelSig", 0));
    p6s_id = pmc_type(interp, P6_SCALAR_str);
    p6r_id = pmc_type(interp, Parrot_str_new(interp, "P6role", 0));
    p6o_id = pmc_type(interp, Parrot_str_new(interp, "P6opaque", 0));
}