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