예제 #1
0
파일: oo.c 프로젝트: ashgti/parrot
PARROT_EXPORT
PARROT_CAN_RETURN_NULL
PARROT_WARN_UNUSED_RESULT
PMC *
Parrot_oo_get_class(PARROT_INTERP, ARGIN(PMC *key))
{
    ASSERT_ARGS(Parrot_oo_get_class)
    PMC *classobj = PMCNULL;

    if (PMC_IS_NULL(key))
        return PMCNULL;

    if (PObj_is_class_TEST(key))
        classobj = key;
    else {
        /* Fast select of behavior based on type of the lookup key */
        switch (key->vtable->base_type) {
          case enum_class_NameSpace:
            classobj = VTABLE_get_class(interp, key);
            break;
          case enum_class_String:
          case enum_class_Key:
          case enum_class_ResizableStringArray:
            {
                PMC * const hll_ns = VTABLE_get_pmc_keyed_int(interp,
                                        interp->HLL_namespace,
                                        Parrot_pcc_get_HLL(interp, CURRENT_CONTEXT(interp)));
                PMC * const ns     = Parrot_ns_get_namespace_keyed(interp,
                                        hll_ns, key);

                if (!PMC_IS_NULL(ns))
                    classobj = VTABLE_get_class(interp, ns);
            }
          default:
            break;
        }
    }

    /* If the PMCProxy doesn't exist yet for the given key, we look up the
       type ID here and create a new one */
    if (PMC_IS_NULL(classobj)) {
        INTVAL type;
        const INTVAL base_type = key->vtable->base_type;

        /* This is a hack! All PMCs should be able to be handled through
           a single codepath, and all of them should be able to avoid
           stringification because it's so imprecise. */
        if (base_type == enum_class_Key
         || base_type == enum_class_ResizableStringArray
         || base_type == enum_class_String)
            type = Parrot_pmc_get_type(interp, key);
        else
            type = Parrot_pmc_get_type_str(interp, VTABLE_get_string(interp, key));

        classobj = get_pmc_proxy(interp, type);
    }

    return classobj;
}
예제 #2
0
파일: oo.c 프로젝트: ashgti/parrot
PARROT_INLINE
PARROT_CANNOT_RETURN_NULL
PARROT_WARN_UNUSED_RESULT
static PMC *
get_pmc_proxy(PARROT_INTERP, INTVAL type)
{
    ASSERT_ARGS(get_pmc_proxy)
    PMC * type_class;

    /* Check if not a PMC or invalid type number */
    if (type > interp->n_vtable_max || type <= 0)
        return PMCNULL;

    type_class = interp->vtables[type]->pmc_class;
    if (type != enum_class_Class
        && type_class->vtable->base_type == enum_class_Class) {
        return type_class;
    }
    else {
        PMC * const parrot_hll = Parrot_ns_get_namespace_keyed_str(interp, interp->root_namespace, CONST_STRING(interp, "parrot"));
        PMC * const pmc_ns =
            Parrot_ns_make_namespace_keyed_str(interp, parrot_hll,
                interp->vtables[type]->whoami);
        PMC * proxy = VTABLE_get_class(interp, pmc_ns);

        /* Create proxy if not found */
        if (PMC_IS_NULL(proxy)) {
            proxy = Parrot_pmc_new_init_int(interp, enum_class_PMCProxy, type);
            Parrot_pcc_invoke_method_from_c_args(interp, pmc_ns, CONST_STRING(interp, "set_class"), "P->", proxy);
        }
        return proxy;
    }
}
예제 #3
0
파일: bind.c 프로젝트: LittleForker/rakudo
/* Creates a Perl 6 object of the type given by C<classname> */
static PMC *
Rakudo_binding_create(PARROT_INTERP, STRING *classname) {
    PMC *ns        = Parrot_get_ctx_HLL_namespace(interp);
    PMC *class_ns  = Parrot_ns_get_namespace_keyed_str(interp, ns, classname);
    PMC *class_obj = VTABLE_get_class(interp, class_ns);
    PMC *result    = VTABLE_instantiate(interp, class_obj, PMCNULL);
    return result;
}
예제 #4
0
파일: bind.c 프로젝트: LittleForker/rakudo
/* Creates a Perl 6 Array. */
static PMC *
Rakudo_binding_create_positional(PARROT_INTERP, PMC *rest, STRING *type_str) {
    static PMC *truepmc = NULL;
    PMC *hll_ns    = Parrot_get_ctx_HLL_namespace(interp);
    PMC *arr_ns    = Parrot_ns_get_namespace_keyed_str(interp, hll_ns, type_str);
    PMC *arr_class = VTABLE_get_class(interp, arr_ns);
    PMC *result    = VTABLE_instantiate(interp, arr_class, PMCNULL);
    INTVAL type_id = pmc_type(interp, Parrot_str_new(interp, "P6opaque", 0));
    result->vtable = interp->vtables[type_id];
    if (!truepmc)
        truepmc = VTABLE_get_pmc_keyed_str(interp, hll_ns, Parrot_str_new(interp, "True", 0));
    VTABLE_set_attr_str(interp, result, Parrot_str_new(interp, "$!flat", 0), truepmc);
    VTABLE_set_attr_str(interp, result, Parrot_str_new(interp, "@!rest", 0), rest);
    return result;
}