From: Bob Rogers <[EMAIL PROTECTED]> Date: Sat, 3 Dec 2005 23:11:32 -0500
If you try to call a sub with a :slurpy parameter and give it a :flat argument, parrot r10337 just hangs, chewing up CPU time . . . Turns out this is because of "premature optimization" -- and all flattening is affected, depending only on the PMC class of the :flat array, and not whether there is a :slurpy parameter (hence another test case). When starting to flatten, st->src.slurp_n is initialized with a result from a hacked version of VTABLE_elements, which could return garbage (i.e. something that looks like a PMC *). If a PerlArray is being flattened, then the parrot_pass_args loop attempts to copy 1e8 or so Undef values to an insatiable destination array, leading to the appearance of an unbounded loop. I changed the array class in the new test cases to a plain Array, which will die much sooner with an "out of bounds" error if this should ever regress. TIA, -- Bob Rogers http://rgrjr.dyndns.org/
Index: src/inter_call.c =================================================================== --- src/inter_call.c (revision 10384) +++ src/inter_call.c (working copy) @@ -25,7 +25,7 @@ #include "parrot/oplib/ops.h" #include "inter_call.str" -#define PREMATURE_OPT +/* #define PREMATURE_OPT */ #ifdef PREMATURE_OPT Index: t/op/calling.t =================================================================== --- t/op/calling.t (revision 10384) +++ t/op/calling.t (working copy) @@ -1106,6 +1106,55 @@ ok 2 OUTPUT +pir_output_is(<<'CODE', <<'OUTPUT', "call :slurpy with :flat"); +.sub _fn1 + .param pmc rest_arg :slurpy + print "[in _fn1]\n" + print rest_arg + print "\n" +.end +.sub main :main + $P34 = new Array + $P34 = 0 + ## normal flattening direct call, non-slurpy returns + $P35 = _fn1($P34 :flat) +.end +CODE +[in _fn1] +0 +OUTPUT + +pir_output_is(<<'CODE', <<'OUTPUT', "call with :flat in the middle"); +.sub _fn1 + .param int arg1 + .param int arg2 + .param int arg3 + .param int arg4 + print arg1 + print ' ' + print arg2 + print ' ' + print arg3 + print ' ' + print arg4 + print "\n" +.end +.sub main :main + $P30 = new Integer + $P30 = 2 + $P31 = new Integer + $P31 = 3 + $P34 = new Array + $P34 = 2 + $P34[0] = $P30 + $P34[1] = $P31 + $I4 = 4 + $P35 = _fn1(1, $P34 :flat, $I4) +.end +CODE +1 2 3 4 +OUTPUT + pir_output_is(<<'CODE', <<'OUTPUT', "tailcall to NCI"); .sub main :main .local pmc s @@ -1425,5 +1474,5 @@ ## remember to change the number of tests :-) -BEGIN { plan tests => 52; } +BEGIN { plan tests => 54; }