On Sun, Aug 17, 2008 at 5:49 PM, <[EMAIL PROTECTED]> wrote: > Author: chromatic > Date: Sun Aug 17 14:49:39 2008 > New Revision: 30286 > > Modified: > trunk/src/pmc/namespace.pmc > trunk/t/pmc/namespace.t > > Log: > [PMC] Fixed co-recursion bug in NameSpace, when iterating through its > contents. > The problem is that, when the key is a Key and not a String, sometimes there's > an infinite loop when the Key isn't a string, integer, or PMC key -- the > default path for the switch in key_string() calls the get_string() vtable > entry > on the key, which calls key_string(), which.... > > The short-term solution is to call the parent PMC (Hash) implementation of > get_pmc_keyed() and return the results, if they're accurate. This fixes the > crash and keeps Rakudo working. Replacing the body of the vtable entry with > the SUPER() call breaks Rakudo. > > The long-term solution is to fix the Key PMC, which is poorly designed and > poorly implemented. > > See RT #57668 and RT #58040, for starters. > > Modified: trunk/src/pmc/namespace.pmc > ============================================================================== > --- trunk/src/pmc/namespace.pmc (original) > +++ trunk/src/pmc/namespace.pmc Sun Aug 17 14:49:39 2008 > @@ -382,26 +382,26 @@ > } > > VTABLE PMC *get_pmc_keyed(PMC *key) { > - PMC *ns = SELF; > + PMC *ns = SUPER(key); > > - if (key->vtable->base_type == enum_class_String) > - return SELF.get_pmc_keyed_str(VTABLE_get_string(INTERP, key)); > + if (!PMC_IS_NULL(ns)) > + return ns; > + > + ns = SELF; > > if (key->vtable->base_type == enum_class_Key) { > - while (key) { > - STRING * const part = key_string(INTERP, key); > - key = key_next(INTERP, key); > + STRING * const part = key_string(INTERP, key); > + key = key_next(INTERP, key); > > - if (!key) > - return VTABLE_get_pmc_keyed_str(INTERP, ns, part); > + if (!key) > + return VTABLE_get_pmc_keyed_str(INTERP, ns, part); > > - ns = Parrot_get_namespace_keyed_str(INTERP, ns, part); > + ns = Parrot_get_namespace_keyed_str(INTERP, ns, part); > > - if (PMC_IS_NULL(ns)) > - return PMCNULL; > - } > + if (PMC_IS_NULL(ns)) > + return PMCNULL; > > - return ns; > + return VTABLE_get_pmc_keyed(INTERP, ns, key); > } > > Parrot_ex_throw_from_c_args(INTERP, NULL, EXCEPTION_GLOBAL_NOT_FOUND, > > Modified: trunk/t/pmc/namespace.t > ============================================================================== > --- trunk/t/pmc/namespace.t (original) > +++ trunk/t/pmc/namespace.t Sun Aug 17 14:49:39 2008 > @@ -1736,7 +1736,7 @@ > /Null PMC access in get_string()/ > OUT > > -pir_output_is( <<'CODE', <<OUT, "RT #57668", todo => "iterate through a > NameSpace PMC, RT #57668" ); > +pir_output_is( <<'CODE', <<OUT, "iterate through a NameSpace PMC" ); > .namespace [ 'bar' ] > > .sub 'main' :main >
This causes languages/tcl/cmd_namespace.t to fail. (Reverting this one change locally allows the test to pass). -- Will "Coke" Coleda