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

Reply via email to