Skip to content

Commit

Permalink
[PMC] Fixed co-recursion bug in NameSpace, when iterating through its…
Browse files Browse the repository at this point in the history
… 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.

git-svn-id: https://svn.parrot.org/parrot/trunk@30286 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information
chromatic committed Aug 17, 2008
1 parent 762d01c commit 94be2d8
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 14 deletions.
26 changes: 13 additions & 13 deletions src/pmc/namespace.pmc
Expand Up @@ -382,26 +382,26 @@ really a public API.
}

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,
Expand Down
2 changes: 1 addition & 1 deletion t/pmc/namespace.t
Expand Up @@ -1736,7 +1736,7 @@ CODE
/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
Expand Down

0 comments on commit 94be2d8

Please sign in to comment.