Skip to content

Commit

Permalink
[OO] Check for an explicitly set vtable index when overriding a vtabl…
Browse files Browse the repository at this point in the history
…e method.

This resolves TT #185.


git-svn-id: https://svn.parrot.org/parrot/trunk@37803 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information
jhorwitz75 committed Mar 28, 2009
1 parent 3e8b61f commit da30436
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 3 deletions.
8 changes: 8 additions & 0 deletions include/parrot/oo.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,12 @@ INTVAL Parrot_get_vtable_index(PARROT_INTERP, ARGIN(const STRING *name))
__attribute__nonnull__(1)
__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))
Expand Down Expand Up @@ -201,6 +207,8 @@ INTVAL Parrot_oo_register_type(PARROT_INTERP,
#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)
Expand Down
32 changes: 32 additions & 0 deletions src/oo.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,38 @@ Parrot_get_vtable_index(PARROT_INTERP, ARGIN(const STRING *name))
}


/*
=item C<const char * Parrot_get_vtable_name>
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<const char* Parrot_MMD_method_name>
Expand Down
19 changes: 16 additions & 3 deletions src/pmc/namespace.pmc
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ ns_insert_sub_keyed_str(PARROT_INTERP, PMC *self, STRING *key, PMC *value)
Parrot_NameSpace_attributes * const nsinfo = PARROT_NAMESPACE(self);
PMC * vtable = nsinfo->vtable;
PMC * const classobj = VTABLE_get_class(interp, self);
STRING * vtable_key = NULL;
Parrot_sub *sub;

PMC_get_sub(interp, value, sub);
Expand All @@ -74,8 +75,14 @@ ns_insert_sub_keyed_str(PARROT_INTERP, PMC *self, STRING *key, PMC *value)

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 = Parrot_str_new(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 */
Expand All @@ -92,8 +99,14 @@ ns_insert_sub_keyed_str(PARROT_INTERP, PMC *self, STRING *key, PMC *value)
if (sub->comp_flags & SUB_COMP_FLAG_METHOD) {
STRING *method_name = key;

if (Parrot_str_not_equal(interp, sub->method_name, CONST_STRING(interp, "")))
if (Parrot_str_equal(interp, sub->method_name, CONST_STRING(interp, ""))) {
if (sub->vtable_index != -1 && vtable_key != NULL) {
method_name = Parrot_str_copy(interp, vtable_key);
}
}
else {
method_name = sub->method_name;
}
add_to_class(interp, nsinfo, classobj, method_name, value);
}

Expand Down

0 comments on commit da30436

Please sign in to comment.