Author: leo
Date: Wed Nov  2 10:32:18 2005
New Revision: 9714

Modified:
   trunk/imcc/parser_util.c
   trunk/imcc/pbc.c
   trunk/imcc/unit.h
   trunk/t/pmc/exception.t
Log:
Variable-sized reg frames 25 - work around register corruption in exceptions

* during exception handling P5 is set to the exception object
* this did corrrupt arbitrary memory, like Int regs, if the call
  frame had less then 6 P registers
* workaround: allocate at least 6 P regs, if 'push_eh' is in that sub
* testcase

Thanks to Coke for detecting this bug.


Modified: trunk/imcc/parser_util.c
==============================================================================
--- trunk/imcc/parser_util.c    (original)
+++ trunk/imcc/parser_util.c    Wed Nov  2 10:32:18 2005
@@ -540,6 +540,9 @@ INS(Interp *interpreter, IMC_Unit * unit
     else if (!strcmp(name, "yield")) {
         cur_unit->instructions->r[0]->pcc_sub->calls_a_sub |= 1 |ITPCCYIELD;
     }
+    else if (!strcmp(name, "push_eh")) {
+        cur_unit->has_push_eh = 1;
+    }
     else if (!memcmp(name, "invoke", 6) ||
             !memcmp(name, "callmethod", 10)) {
         if (cur_unit->type & IMC_PCCSUB)

Modified: trunk/imcc/pbc.c
==============================================================================
--- trunk/imcc/pbc.c    (original)
+++ trunk/imcc/pbc.c    Wed Nov  2 10:32:18 2005
@@ -712,6 +712,12 @@ add_const_pmc_sub(Interp *interpreter, S
     for (i = 0; i < 4; ++i)
         sub->n_regs_used[i] = unit->n_regs_used[i];
     /*
+     * XXX work around implict P5 usage in exception handling code
+     *     need at least 6 PMC regs
+     */
+    if (unit->has_push_eh && sub->n_regs_used[REGNO_PMC] < 6)
+        sub->n_regs_used[REGNO_PMC] = 6;
+    /*
      * check if it's declared multi
      */
     if (r->pcc_sub->nmulti)

Modified: trunk/imcc/unit.h
==============================================================================
--- trunk/imcc/unit.h   (original)
+++ trunk/imcc/unit.h   Wed Nov  2 10:32:18 2005
@@ -50,6 +50,7 @@ typedef struct _IMC_Unit {
     INTVAL HLL_id;
     int n_vars_used[4];        /* INSP in PIR */
     int n_regs_used[4];        /* INSP in PBC */
+    int has_push_eh;
 } IMC_Unit;
 
 

Modified: trunk/t/pmc/exception.t
==============================================================================
--- trunk/t/pmc/exception.t     (original)
+++ trunk/t/pmc/exception.t     Wed Nov  2 10:32:18 2005
@@ -16,7 +16,7 @@ Tests C<Exception> and C<Exception_Handl
 
 =cut
 
-use Parrot::Test tests => 25;
+use Parrot::Test tests => 26;
 use Test::More;
 
 output_is(<<'CODE', <<'OUTPUT', "push_eh - clear_eh");
@@ -497,3 +497,22 @@ main
 foo
 back
 OUTPUT
+
+pir_output_is(<<'CODE', <<'OUTPUT', "register corruption - implicit P5");
+.sub main :main
+    null P0
+    null P1
+    null P2
+    null P3
+    I0 = 1
+    I1 = 2
+    push_eh coke
+    $P0 = global 'no coke'
+coke:
+    print_item I0
+    print_item I1
+    print_newline
+.end
+CODE
+1 2
+OUTPUT

Reply via email to