[svn:parrot] r37803 - in trunk: include/parrot src src/pmc

jhorwitz at svn.parrot.org jhorwitz at svn.parrot.org
Sat Mar 28 15:44:34 UTC 2009


Author: jhorwitz
Date: Sat Mar 28 15:44:33 2009
New Revision: 37803
URL: https://trac.parrot.org/parrot/changeset/37803

Log:
[OO] Check for an explicitly set vtable index when overriding a vtable method. 
This resolves TT #185.

Modified:
   trunk/include/parrot/oo.h
   trunk/src/oo.c
   trunk/src/pmc/namespace.pmc

Modified: trunk/include/parrot/oo.h
==============================================================================
--- trunk/include/parrot/oo.h	Sat Mar 28 15:37:17 2009	(r37802)
+++ trunk/include/parrot/oo.h	Sat Mar 28 15:44:33 2009	(r37803)
@@ -104,6 +104,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);
@@ -201,6 +207,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)

Modified: trunk/src/oo.c
==============================================================================
--- trunk/src/oo.c	Sat Mar 28 15:37:17 2009	(r37802)
+++ trunk/src/oo.c	Sat Mar 28 15:44:33 2009	(r37803)
@@ -436,6 +436,38 @@
 
 /*
 
+=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>
 
 Return the method name for the given MMD enum.

Modified: trunk/src/pmc/namespace.pmc
==============================================================================
--- trunk/src/pmc/namespace.pmc	Sat Mar 28 15:37:17 2009	(r37802)
+++ trunk/src/pmc/namespace.pmc	Sat Mar 28 15:44:33 2009	(r37803)
@@ -58,6 +58,7 @@
     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);
@@ -74,8 +75,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 = 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 */
@@ -92,8 +99,14 @@
     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);
     }
 


More information about the parrot-commits mailing list