On Mon, Aug 18, 2008 at 12:55 PM, Will Coleda <[EMAIL PROTECTED]> wrote: > 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 >
You can duplicate the error with: ../../parrot tcl.pbc -e "namespace exists a" The error occurs at line 141 of languages/tcl/runtime/builtin/namespace.pir. -- Will "Coke" Coleda