Ejemplo n.º 1
0
static void setup_process_stdio(MVMThreadContext *tc, MVMObject *handle, uv_process_t *process,
        uv_stdio_container_t *stdio, int fd, MVMint64 flags, const char *op) {
    if (flags & MVM_PIPE_CAPTURE) {
        MVMIOSyncPipeData *pipedata;

        if (REPR(handle)->ID != MVM_REPR_ID_MVMOSHandle)
            MVM_exception_throw_adhoc(tc, "%s requires an object with REPR MVMOSHandle", op);

        pipedata           = (MVMIOSyncPipeData *)((MVMOSHandle *)handle)->body.data;
        pipedata->process  = process;

        stdio->flags       = UV_CREATE_PIPE | (fd == 0 ? UV_READABLE_PIPE : UV_WRITABLE_PIPE);
        stdio->data.stream = pipedata->ss.handle;
    }
    else if (flags & MVM_PIPE_INHERIT) {
        if (handle == tc->instance->VMNull) {
            stdio->flags   = UV_INHERIT_FD;
            stdio->data.fd = fd;
        }
        else {
            MVMOSHandleBody body = ((MVMOSHandle *)handle)->body;

            if (REPR(handle)->ID != MVM_REPR_ID_MVMOSHandle)
                MVM_exception_throw_adhoc(tc, "%s requires an object with REPR MVMOSHandle", op);

            body.ops->pipeable->bind_stdio_handle(tc, ((MVMOSHandle *)handle), stdio, process);
        }
    }
    else
        stdio->flags = UV_IGNORE;
}
Ejemplo n.º 2
0
MVMObject * MVM_repr_alloc_init(MVMThreadContext *tc, MVMObject *type) {
    MVMObject *obj = REPR(type)->allocate(tc, STABLE(type));

    if (REPR(obj)->initialize) {
        MVMROOT(tc, obj, {
            REPR(obj)->initialize(tc, STABLE(obj), obj, OBJECT_BODY(obj));
        });
Ejemplo n.º 3
0
/* Grabs a NativeCall body. */
static MVMNativeCallBody * get_nc_body(MVMThreadContext *tc, MVMObject *obj) {
    if (REPR(obj)->ID == MVM_REPR_ID_MVMNativeCall)
        return (MVMNativeCallBody *)OBJECT_BODY(obj);
    else
        return (MVMNativeCallBody *)REPR(obj)->box_funcs.get_boxed_ref(tc,
            STABLE(obj), obj, OBJECT_BODY(obj), MVM_REPR_ID_MVMNativeCall);
}
Ejemplo n.º 4
0
/* Creates a new type with this HOW as its meta-object. */
static void new_type(PARROT_INTERP, PMC *nci) {
    PMC * unused;
    /* We first create a new HOW instance. */
    PMC *capture = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
    PMC *self    = VTABLE_get_pmc_keyed_int(interp, capture, 0);
    PMC *HOW     = REPR(self)->allocate(interp, STABLE(self));
    
    /* See if we have a representation name; if not default to P6opaque. */
    STRING *repr_name = VTABLE_exists_keyed_str(interp, capture, repr_str) ?
        VTABLE_get_string_keyed_str(interp, capture, repr_str) :
        p6opaque_str;
        
    /* Create a new type object of the desired REPR. (Note that we can't
     * default to KnowHOWREPR here, since it doesn't know how to actually
     * store attributes, it's just for bootstrapping knowhow's. */
    REPROps *repr_to_use = REPR_get_by_name(interp, repr_name);
    PMC     *type_object = repr_to_use->type_object_for(interp, HOW);
    
    /* See if we were given a name; put it into the meta-object if so. */
    STRING *name = VTABLE_exists_keyed_str(interp, capture, name_str) ?
        VTABLE_get_string_keyed_str(interp, capture, name_str) :
        empty_str;
    REPR(HOW)->initialize(interp, STABLE(HOW), OBJECT_BODY(HOW));
    ((KnowHOWREPRInstance *)PMC_data(HOW))->body.name = name;
    PARROT_GC_WRITE_BARRIER(interp, HOW);
    
    /* Set .WHO to an empty hash. */
    STABLE(type_object)->WHO = Parrot_pmc_new(interp, enum_class_Hash);
    PARROT_GC_WRITE_BARRIER(interp, STABLE_PMC(type_object));

    /* Put it into capture to act as return value. */
    unused = Parrot_pcc_build_call_from_c_args(interp, capture, "P", type_object);
}
Ejemplo n.º 5
0
/* If we know the type of a significant operand, we might try to specialize by
 * representation. */
static void optimize_repr_op(MVMThreadContext *tc, MVMSpeshGraph *g, MVMSpeshBB *bb,
                             MVMSpeshIns *ins, MVMint32 type_operand) {
    MVMSpeshFacts *facts = MVM_spesh_get_facts(tc, g, ins->operands[type_operand]);
    if (facts->flags & MVM_SPESH_FACT_KNOWN_TYPE && facts->type)
        if (REPR(facts->type)->spesh)
            REPR(facts->type)->spesh(tc, STABLE(facts->type), g, bb, ins);
}
Ejemplo n.º 6
0
/* Attribute new method. */
static void attr_new(PARROT_INTERP, PMC *nci) {
    PMC * unused;
    PMC    *capture = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
    PMC    *type    = VTABLE_get_pmc_keyed_int(interp, capture, 0);
    STRING *name    = VTABLE_get_string_keyed_str(interp, capture, name_str);
    PMC    *self    = REPR(type)->allocate(interp, STABLE(type));
    REPR(self)->box_funcs->set_str(interp, STABLE(self), OBJECT_BODY(self), name);
    unused = Parrot_pcc_build_call_from_c_args(interp, capture, "P", self);
}
Ejemplo n.º 7
0
Archivo: frame.c Proyecto: mj41/MoarVM
/* Given the specified code object, copies it and returns a copy which
 * captures a closure over the current scope. */
MVMObject * MVM_frame_takeclosure(MVMThreadContext *tc, MVMObject *code) {
    MVMCode *closure;

    if (REPR(code)->ID != MVM_REPR_ID_MVMCode)
        MVM_exception_throw_adhoc(tc,
            "Can only perform takeclosure on object with representation MVMCode");

    MVMROOT(tc, code, {
        closure = (MVMCode *)REPR(code)->allocate(tc, STABLE(code));
    });
Ejemplo n.º 8
0
/* Marks a collectable item (object, type object, STable). */
void MVM_gc_mark_collectable(MVMThreadContext *tc, MVMGCWorklist *worklist, MVMCollectable *new_addr) {
    MVMuint16 i;

    MVM_gc_worklist_add(tc, worklist, &new_addr->sc);

    if (!(new_addr->flags & (MVM_CF_TYPE_OBJECT | MVM_CF_STABLE))) {
        /* Need to view it as an object in here. */
        MVMObject *new_addr_obj = (MVMObject *)new_addr;

        /* Add the STable to the worklist. */
        MVM_gc_worklist_add(tc, worklist, &new_addr_obj->st);

        /* If needed, mark it. This will add addresses to the worklist
         * that will need updating. Note that we are passing the address
         * of the object *after* copying it since those are the addresses
         * we care about updating; the old chunk of memory is now dead! */
        if (MVM_GC_DEBUG_ENABLED(MVM_GC_DEBUG_COLLECT) && !STABLE(new_addr_obj))
            MVM_panic(MVM_exitcode_gcnursery, "Found an outdated reference to address %p", new_addr);
        if (REPR(new_addr_obj)->gc_mark)
            REPR(new_addr_obj)->gc_mark(tc, STABLE(new_addr_obj), OBJECT_BODY(new_addr_obj), worklist);
    }
    else if (new_addr->flags & MVM_CF_TYPE_OBJECT) {
        /* Add the STable to the worklist. */
        MVM_gc_worklist_add(tc, worklist, &((MVMObject *)new_addr)->st);
    }
    else if (new_addr->flags & MVM_CF_STABLE) {
        /* Add all references in the STable to the work list. */
        MVMSTable *new_addr_st = (MVMSTable *)new_addr;
        MVM_gc_worklist_add(tc, worklist, &new_addr_st->HOW);
        MVM_gc_worklist_add(tc, worklist, &new_addr_st->WHAT);
        MVM_gc_worklist_add(tc, worklist, &new_addr_st->method_cache);
        for (i = 0; i < new_addr_st->vtable_length; i++)
            MVM_gc_worklist_add(tc, worklist, &new_addr_st->vtable[i]);
        for (i = 0; i < new_addr_st->type_check_cache_length; i++)
            MVM_gc_worklist_add(tc, worklist, &new_addr_st->type_check_cache[i]);
        if (new_addr_st->container_spec)
            if (new_addr_st->container_spec->gc_mark_data)
                new_addr_st->container_spec->gc_mark_data(tc, new_addr_st, worklist);
        if (new_addr_st->boolification_spec)
            MVM_gc_worklist_add(tc, worklist, &new_addr_st->boolification_spec->method);
        if (new_addr_st->invocation_spec) {
            MVM_gc_worklist_add(tc, worklist, &new_addr_st->invocation_spec->class_handle);
            MVM_gc_worklist_add(tc, worklist, &new_addr_st->invocation_spec->attr_name);
            MVM_gc_worklist_add(tc, worklist, &new_addr_st->invocation_spec->invocation_handler);
        }
        MVM_gc_worklist_add(tc, worklist, &new_addr_st->WHO);

        /* If it needs to have its REPR data marked, do that. */
        if (new_addr_st->REPR->gc_mark_repr_data)
            new_addr_st->REPR->gc_mark_repr_data(tc, new_addr_st, worklist);
    }
    else {
        MVM_panic(MVM_exitcode_gcnursery, "Internal error: impossible case encountered in GC marking");
    }
}
Ejemplo n.º 9
0
/* KnowHOW.new_type method. Creates a new type with this HOW as its meta-object. */
static void new_type(MVMThreadContext *tc, MVMCallsite *callsite, MVMRegister *args) {
    MVMObject *self, *HOW, *type_object, *BOOTHash, *stash;
    MVMArgInfo repr_arg, name_arg;
    MVMString *repr_name, *name;
    const MVMREPROps *repr_to_use;
    MVMInstance       *instance = tc->instance;

    /* Get arguments. */
    MVMArgProcContext arg_ctx; arg_ctx.named_used = NULL;
    MVM_args_proc_init(tc, &arg_ctx, callsite, args);
    MVM_args_checkarity(tc, &arg_ctx, 1, 1);
    self = MVM_args_get_pos_obj(tc, &arg_ctx, 0, MVM_ARG_REQUIRED).arg.o;
    repr_arg = MVM_args_get_named_str(tc, &arg_ctx, instance->str_consts.repr, MVM_ARG_OPTIONAL);
    name_arg = MVM_args_get_named_str(tc, &arg_ctx, instance->str_consts.name, MVM_ARG_OPTIONAL);
    MVM_args_proc_cleanup(tc, &arg_ctx);
    if (REPR(self)->ID != MVM_REPR_ID_KnowHOWREPR)
        MVM_exception_throw_adhoc(tc, "KnowHOW methods must be called on object with REPR KnowHOWREPR");

    /* See if we have a representation name; if not default to P6opaque. */
    repr_name = repr_arg.exists ? repr_arg.arg.s : instance->str_consts.P6opaque;
    repr_to_use = MVM_repr_get_by_name(tc, repr_name);

    MVM_gc_root_temp_push(tc, (MVMCollectable **)&name_arg);

    /* We first create a new HOW instance. */
    HOW = REPR(self)->allocate(tc, STABLE(self));
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&HOW);

    /* Create a new type object of the desired REPR. (Note that we can't
     * default to KnowHOWREPR here, since it doesn't know how to actually
     * store attributes, it's just for bootstrapping knowhow's. */
    type_object = repr_to_use->type_object_for(tc, HOW);
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&type_object);

    /* This may move name_arg.arg.s so do it first: */
    REPR(HOW)->initialize(tc, STABLE(HOW), HOW, OBJECT_BODY(HOW));
    /* See if we were given a name; put it into the meta-object if so. */
    name = name_arg.exists ? name_arg.arg.s : instance->str_consts.anon;
    MVM_ASSIGN_REF(tc, &(HOW->header), ((MVMKnowHOWREPR *)HOW)->body.name, name);

    /* Set .WHO to an empty hash. */
    BOOTHash = tc->instance->boot_types.BOOTHash;
    stash = REPR(BOOTHash)->allocate(tc, STABLE(BOOTHash));
    MVM_gc_root_temp_push(tc, (MVMCollectable **)&stash);
    MVM_ASSIGN_REF(tc, &(STABLE(type_object)->header), STABLE(type_object)->WHO, stash);

    /* Return the type object. */
    MVM_args_set_result_obj(tc, type_object, MVM_RETURN_CURRENT_FRAME);

    MVM_gc_root_temp_pop_n(tc, 4);
}
Ejemplo n.º 10
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) {
    CStructREPRData *repr_data = (CStructREPRData *)st->REPR_data;
    CStructBody     *body      = (CStructBody *)data;
    INTVAL           slot;

    /* Look up slot, then offset and compute address. */
    slot = hint >= 0 ? hint :
        try_get_slot(interp, repr_data, class_handle, name);
    if (slot >= 0) {
        INTVAL type      = repr_data->attribute_locations[slot] & CSTRUCT_ATTR_MASK;
        INTVAL real_slot = repr_data->attribute_locations[slot] >> CSTRUCT_ATTR_SHIFT;

        if(type == CSTRUCT_ATTR_IN_STRUCT)
            Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
                    "CStruct Can't perform boxed get on flattened attributes yet");
        else {
            PMC *obj = body->child_objs[real_slot];
            PMC *typeobj = repr_data->member_types[slot];

            if(!obj) {
                void *cobj = get_ptr_at_offset(body->cstruct, repr_data->struct_offsets[slot]);
                if(cobj) {
                    if(type == CSTRUCT_ATTR_CARRAY) {
                        obj = make_carray_result(interp, typeobj, cobj);
                    }
                    else if(type == CSTRUCT_ATTR_CSTRUCT) {
                        obj = make_cstruct_result(interp, typeobj, cobj);
                    }
                    else if(type == CSTRUCT_ATTR_CPTR) {
                        obj = make_cpointer_result(interp, typeobj, cobj);
                    }
                    else if(type == CSTRUCT_ATTR_STRING) {
                        char *cstr = (char *) cobj;
                        STRING *str  = Parrot_str_new_init(interp, cstr, strlen(cstr), Parrot_utf8_encoding_ptr, 0);

                        obj  = REPR(typeobj)->allocate(interp, STABLE(typeobj));
                        REPR(obj)->initialize(interp, STABLE(obj), OBJECT_BODY(obj));
                        REPR(obj)->box_funcs->set_str(interp, STABLE(obj), OBJECT_BODY(obj), str);
                        PARROT_GC_WRITE_BARRIER(interp, obj);
                    }

                    body->child_objs[real_slot] = obj;
                }
                else {
                    obj = typeobj;
                }
            }
            return obj;
        }
    }
Ejemplo n.º 11
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);
}
Ejemplo n.º 12
0
static void optimize_is_reprid(MVMThreadContext *tc, MVMSpeshGraph *g, MVMSpeshIns *ins) {
    MVMSpeshFacts *obj_facts = MVM_spesh_get_facts(tc, g, ins->operands[1]);
    MVMuint32 wanted_repr_id;
    MVMuint64 result_value;

    if (!(obj_facts->flags & MVM_SPESH_FACT_KNOWN_TYPE)) {
        return;
    }

    switch (ins->info->opcode) {
        case MVM_OP_islist: wanted_repr_id = MVM_REPR_ID_MVMArray; break;
        case MVM_OP_ishash: wanted_repr_id = MVM_REPR_ID_MVMHash; break;
        case MVM_OP_isint:  wanted_repr_id = MVM_REPR_ID_P6int; break;
        case MVM_OP_isnum:  wanted_repr_id = MVM_REPR_ID_P6num; break;
        case MVM_OP_isstr:  wanted_repr_id = MVM_REPR_ID_P6str; break;
        default:            return;
    }

    result_value = REPR(obj_facts->type)->ID == wanted_repr_id;

    if (result_value == 0) {
        MVMSpeshFacts *result_facts = MVM_spesh_get_facts(tc, g, ins->operands[0]);
        ins->info = MVM_op_get_op(MVM_OP_const_i64_16);
        ins->operands[1].lit_i16 = 0;
        result_facts->flags |= MVM_SPESH_FACT_KNOWN_VALUE;
        result_facts->value.i64 = 0;
    } else {
        ins->info = MVM_op_get_op(MVM_OP_isnonnull);
    }
}
Ejemplo n.º 13
0
MVMObject * MVM_hll_set_config(MVMThreadContext *tc, MVMString *name, MVMObject *config_hash) {
    MVMHLLConfig *config;

    config = MVM_hll_get_config_for(tc, name);

    if (!config_hash || REPR(config_hash)->ID != MVM_REPR_ID_MVMHash
            || !IS_CONCRETE(config_hash)) {
        MVM_exception_throw_adhoc(tc, "set hll config needs concrete hash");
    }

    /* MVM_string_utf8_decode() can potentially allocate, and hence gc. */
    MVMROOT(tc, config_hash, {
            check_config_key(tc, config_hash, "int_box", int_box_type, config);
            check_config_key(tc, config_hash, "num_box", num_box_type, config);
            check_config_key(tc, config_hash, "str_box", str_box_type, config);
            check_config_key(tc, config_hash, "slurpy_array", slurpy_array_type, config);
            check_config_key(tc, config_hash, "slurpy_hash", slurpy_hash_type, config);
            check_config_key(tc, config_hash, "array_iter", array_iterator_type, config);
            check_config_key(tc, config_hash, "hash_iter", hash_iterator_type, config);
            check_config_key(tc, config_hash, "foreign_type_int", foreign_type_int, config);
            check_config_key(tc, config_hash, "foreign_type_num", foreign_type_num, config);
            check_config_key(tc, config_hash, "foreign_type_str", foreign_type_str, config);
            check_config_key(tc, config_hash, "foreign_transform_array", foreign_transform_array, config);
            check_config_key(tc, config_hash, "foreign_transform_hash", foreign_transform_hash, config);
            check_config_key(tc, config_hash, "foreign_transform_code", foreign_transform_code, config);
            check_config_key(tc, config_hash, "null_value", null_value, config);
            check_config_key(tc, config_hash, "exit_handler", exit_handler, config);
            check_config_key(tc, config_hash, "bind_error", bind_error, config);
            check_config_key(tc, config_hash, "method_not_found_error", method_not_found_error, config);
        });
Ejemplo n.º 14
0
/* return an OSHandle representing one of the standard streams */
static MVMObject * MVM_file_get_stdstream(MVMThreadContext *tc, MVMuint8 type) {
    MVMOSHandle *result;
    apr_file_t  *handle;
    apr_status_t rv;
    MVMObject *type_object = tc->instance->boot_types->BOOTIO;

    result = (MVMOSHandle *)REPR(type_object)->allocate(tc, STABLE(type_object));

    /* need a temporary pool */
    if ((rv = apr_pool_create(&result->body.mem_pool, NULL)) != APR_SUCCESS) {
        MVM_exception_throw_apr_error(tc, rv, "get_stream failed to create pool: ");
    }

    switch(type) {
        case 0:
            apr_file_open_stdin(&handle, result->body.mem_pool);
            break;
        case 1:
            apr_file_open_stdout(&handle, result->body.mem_pool);
            break;
        case 2:
            apr_file_open_stderr(&handle, result->body.mem_pool);
            break;
    }
    result->body.file_handle = handle;
    result->body.handle_type = MVM_OSHANDLE_FILE;
    result->body.encoding_type = MVM_encoding_type_utf8;

    return (MVMObject *)result;
}
Ejemplo n.º 15
0
/* Attribute name introspection. */
static void attr_name(PARROT_INTERP, PMC *nci) {
    PMC * unused;
    PMC    *capture = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
    PMC    *self    = VTABLE_get_pmc_keyed_int(interp, capture, 0);
    STRING *name    = REPR(self)->box_funcs->get_str(interp, STABLE(self), OBJECT_BODY(self));
    unused = Parrot_pcc_build_call_from_c_args(interp, capture, "S", name);
}
Ejemplo n.º 16
0
Archivo: CStr.c Proyecto: Arcterus/nqp
static STRING *get_str(PARROT_INTERP, STable *st, void *data) {
    CStrBody *body = (CStrBody *) data;
    PMC *old_ctx, *cappy, *meth, *enc_pmc;
    STRING *enc;
    STR_VTABLE *encoding;

    if (!body->cstr)
        return (STRING *) NULL;

    /* Look up "encoding" method. */
    meth = VTABLE_find_method(interp, st->WHAT,
        Parrot_str_new_constant(interp, "encoding"));
    if (PMC_IS_NULL(meth))
        Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_INVALID_OPERATION,
            "CStr representation expects an 'encoding' method, specifying the encoding");

    old_ctx = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
    cappy   = Parrot_pmc_new(interp, enum_class_CallContext);
    VTABLE_push_pmc(interp, cappy, st->WHAT);
    Parrot_pcc_invoke_from_sig_object(interp, meth, cappy);
    cappy = Parrot_pcc_get_signature(interp, CURRENT_CONTEXT(interp));
    Parrot_pcc_set_signature(interp, CURRENT_CONTEXT(interp), old_ctx);
    enc_pmc = decontainerize(interp, VTABLE_get_pmc_keyed_int(interp, cappy, 0));
    enc = REPR(enc_pmc)->box_funcs->get_str(interp, STABLE(enc_pmc), OBJECT_BODY(enc_pmc));

    return new_from_cstring(interp, body->cstr, enc);
}
Ejemplo n.º 17
0
Archivo: P6opaque.c Proyecto: 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);
}
Ejemplo n.º 18
0
/* Creates a Perl 6 Hash. */
static PMC *
Rakudo_binding_create_hash(PARROT_INTERP, PMC *storage) {
    PMC *type = Rakudo_types_hash_get();
    PMC *hash = REPR(type)->allocate(interp, STABLE(type));
    VTABLE_set_attr_keyed(interp, hash, Rakudo_types_enummap_get(), STORAGE_str, storage);
    return hash;
}
Ejemplo n.º 19
0
/* Boxes a native value. */
static PMC *
create_box(PARROT_INTERP, Rakudo_BindVal bv) {
    PMC *box_type_obj = box_type(bv);
    PMC *boxed = REPR(box_type_obj)->allocate(interp, STABLE(box_type_obj));
    switch (bv.type) {
        case BIND_VAL_INT:
            REPR(boxed)->box_funcs->set_int(interp, STABLE(boxed), OBJECT_BODY(boxed), bv.val.i);
            break;
        case BIND_VAL_NUM:
            REPR(boxed)->box_funcs->set_num(interp, STABLE(boxed), OBJECT_BODY(boxed), bv.val.n);
            break;
        case BIND_VAL_STR:
            REPR(boxed)->box_funcs->set_str(interp, STABLE(boxed), OBJECT_BODY(boxed), bv.val.s);
            break;
    }
    return boxed;
}
Ejemplo n.º 20
0
/* This function gets shared with perl6.ops for the perl6_iter_from_rpa op. */
PMC *
Rakudo_binding_iter_from_rpa(PARROT_INTERP, PMC *rpa, PMC *list) {
    PMC *type = Rakudo_types_listiter_get();
    PMC *iter = REPR(type)->allocate(interp, STABLE(type));
    VTABLE_set_attr_keyed(interp, iter, type, REST_str, rpa);
    VTABLE_set_attr_keyed(interp, iter, type, LIST_str, list);
    return iter;
}
Ejemplo n.º 21
0
void MVM_coerce_smart_stringify(MVMThreadContext *tc, MVMObject *obj, MVMRegister *res_reg) {
    MVMObject *strmeth;
    const MVMStorageSpec *ss;

    /* Handle null case. */
    if (MVM_is_null(tc, obj)) {
        res_reg->s = tc->instance->str_consts.empty;
        return;
    }

    /* If it can unbox as a string, that wins right off. */
    ss = REPR(obj)->get_storage_spec(tc, STABLE(obj));
    if (ss->can_box & MVM_STORAGE_SPEC_CAN_BOX_STR && IS_CONCRETE(obj)) {
        res_reg->s = REPR(obj)->box_funcs.get_str(tc, STABLE(obj), obj, OBJECT_BODY(obj));
        return;
    }

    /* Check if there is a Str method. */
    strmeth = MVM_6model_find_method_cache_only(tc, obj,
        tc->instance->str_consts.Str);
    if (!MVM_is_null(tc, strmeth)) {
        /* We need to do the invocation; just set it up with our result reg as
         * the one for the call. */
        MVMObject *code = MVM_frame_find_invokee(tc, strmeth, NULL);
        MVMCallsite *inv_arg_callsite = MVM_callsite_get_common(tc, MVM_CALLSITE_ID_INV_ARG);

        MVM_args_setup_thunk(tc, res_reg, MVM_RETURN_STR, inv_arg_callsite);
        tc->cur_frame->args[0].o = obj;
        STABLE(code)->invoke(tc, code, inv_arg_callsite, tc->cur_frame->args);
        return;
    }

    /* Otherwise, guess something appropriate. */
    if (!IS_CONCRETE(obj))
        res_reg->s = tc->instance->str_consts.empty;
    else {
        if (REPR(obj)->ID == MVM_REPR_ID_MVMException)
            res_reg->s = ((MVMException *)obj)->body.message;
        else if (ss->can_box & MVM_STORAGE_SPEC_CAN_BOX_INT)
            res_reg->s = MVM_coerce_i_s(tc, REPR(obj)->box_funcs.get_int(tc, STABLE(obj), obj, OBJECT_BODY(obj)));
        else if (ss->can_box & MVM_STORAGE_SPEC_CAN_BOX_NUM)
            res_reg->s = MVM_coerce_n_s(tc, REPR(obj)->box_funcs.get_num(tc, STABLE(obj), obj, OBJECT_BODY(obj)));
        else
            MVM_exception_throw_adhoc(tc, "cannot stringify this");
    }
}
Ejemplo n.º 22
0
/* Takes two objects, which must be of VMArray representation and holding
 * 32-bit integers. Performs normalization to the specified form. */
static void assert_codepoint_array(MVMThreadContext *tc, MVMObject *arr, char *error) {
    if (IS_CONCRETE(arr) && REPR(arr)->ID == MVM_REPR_ID_MVMArray) {
        MVMuint8 slot_type = ((MVMArrayREPRData *)STABLE(arr)->REPR_data)->slot_type;
        if (slot_type == MVM_ARRAY_I32 || slot_type == MVM_ARRAY_U32)
            return;
    }
    MVM_exception_throw_adhoc(tc, "%s", error);
}
Ejemplo n.º 23
0
/* Casts to a handle, checking it's a directory handle along the way. */
static MVMOSHandle * get_dirhandle(MVMThreadContext *tc, MVMObject *oshandle, const char *msg) {
    MVMOSHandle *handle = (MVMOSHandle *)oshandle;
    if (REPR(oshandle)->ID != MVM_REPR_ID_MVMOSHandle)
        MVM_exception_throw_adhoc(tc, "%s requires an object with REPR MVMOSHandle", msg);
    if (handle->body.ops != &op_table)
        MVM_exception_throw_adhoc(tc, "%s got incorrect kind of handle", msg);
    return handle;
}
Ejemplo n.º 24
0
init_builtins ()
{
  long rule, alt;

  equal = get_builtin ("equal");
  if (meta_uniq_flag)
    *(REPR (equal)) = 'f';
  notequal = get_builtin ("notequal");
  if (meta_uniq_flag)
    *(REPR (notequal)) = 'f';

  endofsentence = get_builtin ("endofsentence");
  evalmeta = get_builtin ("evalmeta");
  explintersect = get_builtin ("explintersect_");
  falseip = get_builtin ("falseip_");
  getip = get_builtin ("getip_");
  initmeta = get_builtin ("initmeta");
  initmint = get_builtin ("initmint_");
  intersect = get_builtin ("intersect_");
  metaterminal = get_builtin ("metaterminal");
  metaterminal2 = get_builtin ("metaterminal2_");
  nestaralt = get_builtin ("nestaralt_");
  nestarset = get_builtin ("nestarset");
  detnestarset = get_builtin ("detnestarset");
  detprefix = get_builtin ("detprefix");
  detprefix2 = get_builtin ("detprefix2_");
  equalsempty = get_builtin ("equalsempty");
  nlcr = get_builtin ("nlcr");
  pair = get_builtin ("pair");
  repair = get_builtin ("repair");
  resetinputptr = get_builtin ("resetinputptr_");
  restoreip = get_builtin ("restoreip_");
  setinputptrto = get_builtin ("setinputptrto_");
  skip = get_builtin ("skip_");
  tltraditional = get_builtin ("tltraditional_");
  tltraditionalterm = get_builtin ("tltraditionalterm_");
  transformlattice = get_builtin ("transformlattice_");
  transformlatticeterm = get_builtin ("transformlatticeterm_");
  unpair = get_builtin ("unpair");
  where = get_builtin ("where");
  getlist_ = get_builtin ("getlist_");
  add_to = get_builtin ("addto");
  assign = get_builtin ("assign");

  meta_empty = get_meta_builtin ("empty");
}
Ejemplo n.º 25
0
/* Returns the body of a P6bigint, containing the bigint/smallint union, for
 * operations that want to explicitly handle the two. */
static MVMP6bigintBody * get_bigint_body(MVMThreadContext *tc, MVMObject *obj) {
    if (IS_CONCRETE(obj))
        return (MVMP6bigintBody *)REPR(obj)->box_funcs.get_boxed_ref(tc,
            STABLE(obj), obj, OBJECT_BODY(obj), MVM_REPR_ID_P6bigint);
    else
        MVM_exception_throw_adhoc(tc,
            "Can only perform big integer operations on concrete objects");
}
Ejemplo n.º 26
0
/* Adds a method into the KnowHOW.HOW method table. */
static void add_knowhow_how_method(MVMThreadContext *tc, MVMKnowHOWREPR *knowhow_how,
        char *name, void (*func) (MVMThreadContext *, MVMCallsite *, MVMRegister *)) {
    MVMObject *BOOTCCode, *code_obj, *method_table, *name_str;
    
    /* Create string for name. */
    name_str = (MVMObject *)MVM_string_ascii_decode_nt(tc,
        tc->instance->VMString, name);
    
    /* Allocate a BOOTCCode and put pointer in. */
    BOOTCCode = tc->instance->boot_types->BOOTCCode;
    code_obj = REPR(BOOTCCode)->allocate(tc, STABLE(BOOTCCode));
    ((MVMCFunction *)code_obj)->body.func = func;
    
    /* Add into the table. */
    method_table = knowhow_how->body.methods;
    REPR(method_table)->ass_funcs->bind_key_boxed(tc, STABLE(method_table),
        method_table, OBJECT_BODY(method_table), name_str, code_obj);
}
Ejemplo n.º 27
0
static void verify_filehandle_type(MVMThreadContext *tc, MVMObject *oshandle, MVMOSHandle **handle, const char *msg) {
    /* work on only MVMOSHandle of type MVM_OSHANDLE_FILE */
    if (REPR(oshandle)->ID != MVM_REPR_ID_MVMOSHandle) {
        MVM_exception_throw_adhoc(tc, "%s requires an object with REPR MVMOSHandle", msg);
    }
    *handle = (MVMOSHandle *)oshandle;
    if ((*handle)->body.handle_type != MVM_OSHANDLE_FILE) {
        MVM_exception_throw_adhoc(tc, "%s requires an MVMOSHandle of type file handle", msg);
    }
}
Ejemplo n.º 28
0
/* This function gets shared with perl6.ops for the perl6_list_from_rpa op. */
PMC *
Rakudo_binding_list_from_rpa(PARROT_INTERP, PMC *rpa, PMC *type, PMC *flattens) {
    PMC *list = REPR(type)->allocate(interp, STABLE(type));
    PMC *List = Rakudo_types_list_get();
    if (!PMC_IS_NULL(rpa)) 
        VTABLE_set_attr_keyed(interp, list, List, NEXTITER_str,
            Rakudo_binding_iter_from_rpa(interp, rpa, list));
    VTABLE_set_attr_keyed(interp, list, List, FLATTENS_str, flattens);
    return list;
}
Ejemplo n.º 29
0
/* Creates a new timer. */
MVMObject * MVM_io_timer_create(MVMThreadContext *tc, MVMObject *queue,
                                MVMObject *schedulee, MVMint64 timeout,
                                MVMint64 repeat, MVMObject *async_type) {
    MVMAsyncTask *task;
    TimerInfo *timer_info;

    /* Validate REPRs. */
    if (REPR(queue)->ID != MVM_REPR_ID_ConcBlockingQueue)
        MVM_exception_throw_adhoc(tc,
            "timer target queue must have ConcBlockingQueue REPR");
    if (REPR(async_type)->ID != MVM_REPR_ID_MVMAsyncTask)
        MVM_exception_throw_adhoc(tc,
            "timer result type must have REPR AsyncTask");

    /* Create async task handle. */
    MVMROOT(tc, queue, {
    MVMROOT(tc, schedulee, {
        task = (MVMAsyncTask *)MVM_repr_alloc_init(tc, async_type);
    });
    });
Ejemplo n.º 30
0
void MVM_coerce_smart_stringify(MVMThreadContext *tc, MVMObject *obj, MVMRegister *res_reg) {
    MVMObject *strmeth;

    /* Handle null case. */
    if (!obj) {
        res_reg->s = tc->instance->str_consts->empty;
        return;
    }

    /* Check if there is a Str method. */
    strmeth = MVM_6model_find_method_cache_only(tc, obj,
              tc->instance->str_consts->Str);
    if (strmeth) {
        /* We need to do the invocation; just set it up with our result reg as
         * the one for the call. */
        MVMObject *code = MVM_frame_find_invokee(tc, strmeth);
        tc->cur_frame->return_value   = res_reg;
        tc->cur_frame->return_type    = MVM_RETURN_STR;
        tc->cur_frame->return_address = *(tc->interp_cur_op);
        tc->cur_frame->args[0].o = obj;
        STABLE(code)->invoke(tc, code, get_inv_callsite(), tc->cur_frame->args);
        return;
    }

    /* Otherwise, guess something appropriate. */
    if (!IS_CONCRETE(obj))
        res_reg->s = tc->instance->str_consts->empty;
    else {
        MVMStorageSpec ss = REPR(obj)->get_storage_spec(tc, STABLE(obj));
        if (REPR(obj)->ID == MVM_REPR_ID_MVMString)
            res_reg->s = (MVMString *)obj;
        else if (ss.can_box & MVM_STORAGE_SPEC_CAN_BOX_STR)
            res_reg->s = REPR(obj)->box_funcs->get_str(tc, STABLE(obj), obj, OBJECT_BODY(obj));
        else if (ss.can_box & MVM_STORAGE_SPEC_CAN_BOX_INT)
            res_reg->s = MVM_coerce_i_s(tc, REPR(obj)->box_funcs->get_int(tc, STABLE(obj), obj, OBJECT_BODY(obj)));
        else if (ss.can_box & MVM_STORAGE_SPEC_CAN_BOX_NUM)
            res_reg->s = MVM_coerce_n_s(tc, REPR(obj)->box_funcs->get_num(tc, STABLE(obj), obj, OBJECT_BODY(obj)));
        else
            MVM_exception_throw_adhoc(tc, "cannot stringify this");
    }
}