Author: leo
Date: Fri Jun 17 02:05:41 2005
New Revision: 8403

Modified:
   trunk/classes/sub.pmc
   trunk/t/op/calling.t
Log:
var_args 24 - tailcall; get_params twice

* fix argument passing to tail-called subs
* enable and test multiple get_params
* you can e.g. first get one argument and with a second get_param slurp some



Modified: trunk/classes/sub.pmc
==============================================================================
--- trunk/classes/sub.pmc       (original)
+++ trunk/classes/sub.pmc       Fri Jun 17 02:05:41 2005
@@ -520,6 +520,10 @@ Invokes the subroutine.
             if (PObj_get_FLAGS(ccont) & SUB_FLAG_TAILCALL) {
                 PObj_get_FLAGS(ccont) &= ~SUB_FLAG_TAILCALL;
                 assert(ccont == REG_PMC(1));
+                if (INTERP->current_args) {
+                    pc = parrot_pass_args(INTERP, sub, caller_regs,
+                            PARROT_OP_get_params_pc);
+                }
                 goto is_tail_call;
             }
         }

Modified: trunk/t/op/calling.t
==============================================================================
--- trunk/t/op/calling.t        (original)
+++ trunk/t/op/calling.t        Fri Jun 17 02:05:41 2005
@@ -16,7 +16,7 @@ Tests Parrot calling conventions.
 
 =cut
 
-use Parrot::Test tests => 20;
+use Parrot::Test tests => 24;
 use Test::More;
 
 # Test calling convention operations
@@ -653,3 +653,128 @@ CODE
 88
 back
 OUTPUT
+
+pir_output_is(<<'CODE', <<'OUTPUT', "tailcall 1");
+.sub main @MAIN
+    .const .Sub f = "foo"
+    print "main\n"
+    get_results "(0)", $S0
+    invokecc f
+    print $S0
+.end
+.sub foo
+    .const .Sub b = "bar"
+    print "foo\n"
+    set_returns "(0)", "foo_ret\n"
+    tailcall b
+.end
+.sub bar
+    print "bar\n"
+    set_returns "(0)", "bar_ret\n"
+    returncc
+.end
+CODE
+main
+foo
+bar
+bar_ret
+OUTPUT
+
+pir_output_is(<<'CODE', <<'OUTPUT', "tailcall 2 - pass arg");
+.sub main @MAIN
+    .const .Sub f = "foo"
+    print "main\n"
+    get_results "(0)", $S0
+    invokecc f
+    print $S0
+.end
+.sub foo
+    .const .Sub b = "bar"
+    print "foo\n"
+    set_args "(0)", "from_foo\n"
+    set_returns "(0)", "foo_ret\n"
+    tailcall b
+.end
+.sub bar
+    get_params "(0)", $S0
+    print "bar\n"
+    print $S0
+    set_returns "(0)", "bar_ret\n"
+    returncc
+.end
+CODE
+main
+foo
+bar
+from_foo
+bar_ret
+OUTPUT
+
+pir_output_is(<<'CODE', <<'OUTPUT', "tailcall 3 - pass arg");
+.sub main @MAIN
+    .const .Sub f = "foo"
+    print "main\n"
+    get_results "(0)", $S0
+    invokecc f
+    print $S0
+.end
+.sub foo
+    .const .Sub b = "bar"
+    print "foo\n"
+    set_args "(0)", "from_foo\n"
+    set_returns "(0)", "foo_ret\n"
+    tailcall b
+.end
+.sub bar
+    print "bar\n"
+    get_params "(0)", $S0
+    print $S0
+    set_returns "(0)", "bar_ret\n"
+    returncc
+.end
+CODE
+main
+foo
+bar
+from_foo
+bar_ret
+OUTPUT
+
+output_is(<<'CODE', <<'OUTPUT', "get_params twice");
+.pcc_sub main:
+    new P16, .String
+    set P16, "ok 1\n"
+    new P17, .String
+    set P17, "ok 2\n"
+    new P18, .String
+    set P18, "ok 3\n"
+    set_args "(0, 0, 0)", P16, P17, P18
+    find_name P1, "foo"
+    invokecc P1
+    print "back\n"
+    end
+.pcc_sub foo:
+    get_params "(0, 0x8)", P1, P2
+    print P1
+    set I0, P2
+    print I0
+    print "\n"
+    set S0, P2[0]
+    print S0
+    set S0, P2[1]
+    print S0
+    get_params "(0, 0, 0)", P1, P2, P3
+    print P1
+    print P2
+    print P3
+    returncc
+CODE
+ok 1
+2
+ok 2
+ok 3
+ok 1
+ok 2
+ok 3
+back
+OUTPUT

Reply via email to