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