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; }
 

Reply via email to