From 3f51e688e57cacd878e77e9d41e28ebc5a98a19e Mon Sep 17 00:00:00 2001 From: Matthew Flatt Date: Tue, 17 Jan 2012 07:21:01 -0700 Subject: [PATCH] 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 f7c506471b48dbae676 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 ddd246232ee9161ce26f0bf5191edb3caba0811f) --- collects/tests/racket/basic.rktl | 1 + src/racket/src/jit.c | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/collects/tests/racket/basic.rktl b/collects/tests/racket/basic.rktl index 630e3c5f55..e503e0a9c8 100644 --- a/collects/tests/racket/basic.rktl +++ b/collects/tests/racket/basic.rktl @@ -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! diff --git a/src/racket/src/jit.c b/src/racket/src/jit.c index c72358f6cb..2d5f0fda66 100644 --- a/src/racket/src/jit.c +++ b/src/racket/src/jit.c @@ -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;