develooper Front page | perl.cvs.parrot | Postings from December 2008

[svn:parrot] r33520 - trunk/src/pmc

From:
jonathan
Date:
December 5, 2008 10:44
Subject:
[svn:parrot] r33520 - trunk/src/pmc
Message ID:
20081205184441.C8E76CB9AF@x12.develooper.com
Author: jonathan
Date: Fri Dec  5 10:44:41 2008
New Revision: 33520

Modified:
   trunk/src/pmc/pmcproxy.pmc

Log:
[core] PMCProxy wasn't yet building and keeping an MRO nor a parent list. This amongst other things meant if we had an object inheriting from a PMC that inherited from another PMC, and we tried to use that highest type in :multi(...), it failed to see instances of the object at the bottom as matching.

Modified: trunk/src/pmc/pmcproxy.pmc
==============================================================================
--- trunk/src/pmc/pmcproxy.pmc	(original)
+++ trunk/src/pmc/pmcproxy.pmc	Fri Dec  5 10:44:41 2008
@@ -114,6 +114,7 @@
     VTABLE void init_pmc(PMC *init_data) {
         const INTVAL type_num = VTABLE_get_integer(interp, init_data);
         Parrot_Class_attributes *proxy_info;
+        INTVAL mro_length, i;
 
         /* Ensure that it's a valid type number. */
         if (type_num > interp->n_vtable_max || type_num <= 0)
@@ -129,7 +130,22 @@
         proxy_info->name       = interp->vtables[type_num]->whoami;
         proxy_info->_namespace = interp->vtables[type_num]->_namespace;
 
-        /* XXX Parents and MRO still todo. */
+        /* Build MRO (skip ourself). */
+        mro_length = VTABLE_elements(interp, interp->vtables[type_num]->mro);
+        for (i = 1; i < mro_length; i++) {
+            PMC    *pclass = VTABLE_get_pmc_keyed_int(interp, interp->vtables[type_num]->mro, i);
+            STRING *cname  = pclass->vtable->whoami;
+            if (string_equal(interp, cname, CONST_STRING(interp, "scalar")) != 0) {
+                PMC *pproxy = Parrot_oo_get_class_str(interp, cname);
+                VTABLE_push_pmc(interp, proxy_info->all_parents, pproxy);
+            }
+        }
+
+        /* PMCs just do single inheritance, so we'll assume that if we have a
+         * second entry in our MRO, it goes in the parents list. */
+        if (VTABLE_elements(interp, proxy_info->all_parents) >= 2)
+            VTABLE_push_pmc(interp, proxy_info->parents,
+                    VTABLE_get_pmc_keyed_int(interp, proxy_info->all_parents, 1));
 
         if (!PMC_IS_NULL(proxy_info->_namespace) &&
             PMC_IS_NULL(VTABLE_get_class(interp, proxy_info->_namespace))) {
@@ -286,12 +302,20 @@
 */
 
     VTABLE INTVAL isa(STRING *classname) {
+        Parrot_Class_attributes * const _proxy = PARROT_CLASS(SELF);
         const STRING * const pmc_proxy = CONST_STRING(interp, "PMCProxy");
 
         if (string_equal(INTERP, classname, pmc_proxy) == 0)
             return 1;
 
-        return SUPER(classname);
+        if (SUPER(classname))
+            return 1;
+
+        /* Look in the isa hash. */
+        if (parrot_hash_exists(interp, interp->vtables[_proxy->id]->isa_hash, classname))
+            return 1;
+
+        return 0;
     }
 
 /*



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About