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; }
PARROT_WARN_UNUSED_RESULT PARROT_CANNOT_RETURN_NULL static STRING* trace_class_name(PARROT_INTERP, ARGIN(const PMC* pmc)) { ASSERT_ARGS(trace_class_name) STRING *class_name; if (PObj_is_class_TEST(pmc)) { SLOTTYPE * const class_array = (SLOTTYPE *)PMC_data(pmc); PMC * const class_name_pmc = get_attrib_num(class_array, PCD_CLASS_NAME); class_name = VTABLE_get_string(interp, class_name_pmc); } else class_name = pmc->vtable->whoami; return class_name; }