Index: src/oo.c =================================================================== --- src/oo.c (revision 35862) +++ src/oo.c (working copy) @@ -436,6 +436,38 @@ /* +=item C + +Return the method name at the specified index in the vtable slot array. +Use this function when you cannot access Parrot_vtable_slot_names directly. + +=cut + +*/ + +PARROT_EXPORT +PARROT_PURE_FUNCTION +PARROT_CAN_RETURN_NULL +const char * +Parrot_get_vtable_name(PARROT_INTERP, INTVAL idx) +{ + ASSERT_ARGS(Parrot_get_vtable_name) + + INTVAL low = PARROT_VTABLE_LOW; + INTVAL high = NUM_VTABLE_FUNCTIONS + PARROT_VTABLE_LOW; + + PARROT_ASSERT(idx > 0); + + if (idx < low || idx > high) { + return NULL; + } + + return Parrot_vtable_slot_names[idx]; +} + + +/* + =item C Return the method name for the given MMD enum. Index: src/pmc/namespace.pmc =================================================================== --- src/pmc/namespace.pmc (revision 35862) +++ src/pmc/namespace.pmc (working copy) @@ -58,7 +58,9 @@ PMC * vtable = nsinfo->vtable; Parrot_sub * const sub = PMC_sub(value); PMC * const classobj = VTABLE_get_class(interp, self); + STRING * vtable_key = NULL; + /* Handle vtable methods with two underscores at the start. */ if (sub->vtable_index == -1) { if (string_str_index(interp, key, CONST_STRING(interp, "__"), 0) == 0) { @@ -71,8 +73,14 @@ if (sub->vtable_index != -1) { /* Insert it in class, if there is a class */ - if (!PMC_IS_NULL(classobj) && PObj_is_class_TEST(classobj)) - VTABLE_add_vtable_override(interp, classobj, key, value); + if (!PMC_IS_NULL(classobj) && PObj_is_class_TEST(classobj)) { + const char *vtable_key_c; + vtable_key_c = Parrot_get_vtable_name(interp, sub->vtable_index); + PARROT_ASSERT(vtable_key_c); + vtable_key = string_from_cstring(interp, vtable_key_c, + strlen(vtable_key_c)); + VTABLE_add_vtable_override(interp, classobj, vtable_key, value); + } /* Otherwise, store it in the namespace for the class to * retrieve later */ @@ -89,8 +97,14 @@ if (sub->comp_flags & SUB_COMP_FLAG_METHOD) { STRING *method_name = key; - if (0 != string_equal(interp, sub->method_name, CONST_STRING(interp, ""))) + if (0 == string_equal(interp, sub->method_name, CONST_STRING(interp, ""))) { + if (sub->vtable_index != -1 && vtable_key != NULL) { + method_name = string_copy(interp, vtable_key); + } + } + else { method_name = sub->method_name; + } add_to_class(interp, nsinfo, classobj, method_name, value); } Index: include/parrot/oo.h =================================================================== --- include/parrot/oo.h (revision 35862) +++ include/parrot/oo.h (working copy) @@ -105,6 +105,12 @@ __attribute__nonnull__(2); PARROT_EXPORT +PARROT_PURE_FUNCTION +PARROT_CAN_RETURN_NULL +const char * Parrot_get_vtable_name(PARROT_INTERP, INTVAL idx) + __attribute__nonnull__(1); + +PARROT_EXPORT void Parrot_invalidate_method_cache(PARROT_INTERP, ARGIN_NULLOK(STRING *_class)) __attribute__nonnull__(1); @@ -212,6 +218,8 @@ #define ASSERT_ARGS_Parrot_get_vtable_index __attribute__unused__ int _ASSERT_ARGS_CHECK = \ PARROT_ASSERT_ARG(interp) \ || PARROT_ASSERT_ARG(name) +#define ASSERT_ARGS_Parrot_get_vtable_name __attribute__unused__ int _ASSERT_ARGS_CHECK = \ + PARROT_ASSERT_ARG(interp) #define ASSERT_ARGS_Parrot_invalidate_method_cache \ __attribute__unused__ int _ASSERT_ARGS_CHECK = \ PARROT_ASSERT_ARG(interp)