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