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;
}
/*