JIT: fix array-size expression that is handled badly by xform

This bug (in xform, really) appears to be responsible for recent "JIT
buffer overflow" crashes. It could also cause other memory-corruption
crashes.

The bug could be triggered by any program that uses operators like
`+`, `<`, and `bitwise-ior` on more than 2 and less than 6 operands
(which is a lot of programs), but only if a certain allocation and
GC pattern happens at just the right time (which is why a crash was
relatively rare).

Merge to v6.1
(cherry picked from commit c72f441d93)
This commit is contained in:
Matthew Flatt 2014-07-13 18:04:29 +01:00 committed by Ryan Culpepper
parent dd6f973d5c
commit e6b1ffa1fb

View File

@ -2124,7 +2124,7 @@ int scheme_generate_extflonum_arith(mz_jit_state *jitter, Scheme_Object *rator,
} }
#define MAX_NON_SIMPLE_ARGS 5 #define MAX_NON_SIMPLE_ARGS 6
static int extract_nary_arg(int reg, int n, mz_jit_state *jitter, Scheme_App_Rec *app, static int extract_nary_arg(int reg, int n, mz_jit_state *jitter, Scheme_App_Rec *app,
Scheme_Object **alt_args, int old_short_jumps) Scheme_Object **alt_args, int old_short_jumps)
@ -2184,7 +2184,7 @@ int scheme_generate_nary_arith(mz_jit_state *jitter, Scheme_App_Rec *app,
int dest) int dest)
{ {
int c, i, non_simple_c = 0, stack_c, use_fx = 1, trigger_arg = 0; int c, i, non_simple_c = 0, stack_c, use_fx = 1, trigger_arg = 0;
Scheme_Object *non_simples[1+MAX_NON_SIMPLE_ARGS], **alt_args, *v; Scheme_Object *non_simples[MAX_NON_SIMPLE_ARGS], **alt_args, *v;
Branch_Info for_nary_branch; Branch_Info for_nary_branch;
Branch_Info_Addr nary_addrs[3]; Branch_Info_Addr nary_addrs[3];
GC_CAN_IGNORE jit_insn *refslow, *reffx, *refdone; GC_CAN_IGNORE jit_insn *refslow, *reffx, *refdone;
@ -2209,7 +2209,7 @@ int scheme_generate_nary_arith(mz_jit_state *jitter, Scheme_App_Rec *app,
for (i = 0; i < c; i++) { for (i = 0; i < c; i++) {
v = app->args[i+1]; v = app->args[i+1];
if (!scheme_is_constant_and_avoids_r1(v)) { if (!scheme_is_constant_and_avoids_r1(v)) {
if (non_simple_c < MAX_NON_SIMPLE_ARGS) if (non_simple_c < (MAX_NON_SIMPLE_ARGS-1))
non_simples[1+non_simple_c] = v; non_simples[1+non_simple_c] = v;
non_simple_c++; non_simple_c++;
} }
@ -2227,7 +2227,7 @@ int scheme_generate_nary_arith(mz_jit_state *jitter, Scheme_App_Rec *app,
} }
} }
if ((non_simple_c <= MAX_NON_SIMPLE_ARGS) && (non_simple_c < c)) { if ((non_simple_c <= (MAX_NON_SIMPLE_ARGS-1)) && (non_simple_c < c)) {
stack_c = non_simple_c; stack_c = non_simple_c;
alt_args = non_simples; alt_args = non_simples;
non_simples[0] = app->args[0]; non_simples[0] = app->args[0];