fix JIT-generated code in case of arity mismatch

The generated code was checking arity after potentially copying
arguments to the start of the runstack (i.e., if the arguments
were not already there). If too few arguments are provided, then
the copy might access past the end of the given array.

The redundant arity check removed in commit f7c506471b
had previously masked this problem. (Or the check wasn't redundant
in that sense, but it's better this way.)

Merge to 5.2.1
(cherry picked from commit ddd246232e)
This commit is contained in:
Matthew Flatt 2012-01-17 07:21:01 -07:00 committed by Ryan Culpepper
parent 8c59a3a792
commit 3f51e688e5
2 changed files with 13 additions and 1 deletions

View File

@ -2072,6 +2072,7 @@
(test #t eq? (equal-hash-code l) (equal-hash-code (list 1 2 3)))
(hash-set! h1 l 'ok)
(test 'ok hash-ref h1 l)
(err/rt-test (hash-ref h1 'nonesuch (lambda (x) 'bad-proc)) exn:fail:contract:arity?)
(test #t hash-has-key? h1 l)
(test #f hash-has-key? h1 (cdr l))
(when hash-ref!

View File

@ -2996,7 +2996,7 @@ static void generate_function_prolog(mz_jit_state *jitter, void *code, int max_l
static int generate_function_getarg(mz_jit_state *jitter, int has_rest, int num_params)
{
int i, cnt;
GC_CAN_IGNORE jit_insn *ref;
GC_CAN_IGNORE jit_insn *ref, *ref2;
/* If rands == runstack, set runstack base to runstack + rands (and
don't copy rands), otherwise set base to runstack and copy
@ -3011,6 +3011,16 @@ static int generate_function_getarg(mz_jit_state *jitter, int has_rest, int num_
ref = jit_beqr_p(jit_forward(), JIT_RUNSTACK, JIT_R2);
__END_TINY_OR_SHORT_JUMPS__(num_params < 10, num_params < 100);
/* Since we're going to copy arguments, make sure argument
count is right; otherwise, the arity error can use the
arguments in the original location. */
__START_TINY_OR_SHORT_JUMPS__(num_params < 10, num_params < 100);
if (!has_rest)
ref2 = jit_bnei_i(jit_forward(), JIT_R1, num_params);
else
ref2 = jit_blti_i(jit_forward(), JIT_R1, (num_params - 1));
__END_TINY_OR_SHORT_JUMPS__(num_params < 10, num_params < 100);
#ifdef JIT_RUNSTACK_BASE
jit_movr_p(JIT_RUNSTACK_BASE, JIT_RUNSTACK);
#else
@ -3036,6 +3046,7 @@ static int generate_function_getarg(mz_jit_state *jitter, int has_rest, int num_
__START_TINY_OR_SHORT_JUMPS__(num_params < 10, num_params < 100);
mz_patch_branch(ref);
mz_patch_branch(ref2);
__END_TINY_OR_SHORT_JUMPS__(num_params < 10, num_params < 100);
return cnt;