~ chicken-core (chicken-5) 97c470e8bd08cf3ffe2bb27d04a748499f0eae21
commit 97c470e8bd08cf3ffe2bb27d04a748499f0eae21 Author: felix <felix@call-with-current-continuation.org> AuthorDate: Fri Nov 3 14:43:48 2017 +0100 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Fri Nov 3 14:43:48 2017 +0100 move error checks for random-* into C to allow specializing for the fixnum type diff --git a/extras.scm b/extras.scm index 63f49ed6..f4cccce5 100644 --- a/extras.scm +++ b/extras.scm @@ -649,31 +649,24 @@ (import scheme chicken chicken.time chicken.io foreign) (define (set-pseudo-random-seed! buf #!optional n) + ;; doesn't enforce size of buf being at least 4 bytes (if n (##sys#check-fixnum n 'set-pseudo-random-seed!) (set! n (##sys#size buf))) (unless (##core#inline "C_byteblockp" buf) - (##sys#error 'set-pseudo-random-seed! - "invalid buffer type" buf)) + (##sys#error 'set-pseudo-random-seed! "invalid buffer type" buf)) (##core#inline "C_set_random_seed" buf (##core#inline "C_i_fixnum_min" n (##sys#size buf)))) (define (pseudo-random-integer n) - (define (badrange) - (##sys#error 'pseudo-random-integer "invalid range" n)) (cond ((##core#inline "C_fixnump" n) - (if (##core#inline "C_fixnum_lessp" n 0) - (badrange) - (##core#inline "C_random_fixnum" n))) + (##core#inline "C_random_fixnum" n)) ((not (##core#inline "C_i_bignump" n)) (##sys#error 'pseudo-random-integer "bad argument type" n)) (else - (if (##core#inline "C_i_lessp" n 0) - (badrange) - (##core#inline_allocate ("C_s_a_u_i_random_int" 2) - n))))) + (##core#inline_allocate ("C_s_a_u_i_random_int" 2) n)))) (define random-bytes (let ((in #f) diff --git a/runtime.c b/runtime.c index 60803e01..c9f5f3f5 100644 --- a/runtime.c +++ b/runtime.c @@ -12590,6 +12590,16 @@ static C_u32 random_word(void) C_regparm C_word C_random_fixnum(C_word n) { C_u32 r = random_word(); + C_word nf; + + if (!(n & C_FIXNUM_BIT)) + barf(C_BAD_ARGUMENT_TYPE_NO_FIXNUM_ERROR, "pseudo-random-integer", n); + + nf = C_unfix(n); + + if(nf < 0) + barf(C_OUT_OF_RANGE_ERROR, "pseudo-random-integer", n, C_fix(0)); + return C_fix(((double)r / 0xffffffffUL) * C_unfix(n)); } @@ -12598,6 +12608,10 @@ C_regparm C_word C_fcall C_s_a_u_i_random_int(C_word **ptr, C_word n, C_word rn) { C_uword *start, *end; + + if(C_bignum_negativep(rn)) + barf(C_OUT_OF_RANGE_ERROR, "pseudo-random-integer", rn, C_fix(0)); + int len = integer_length_abs(rn); C_word size = C_fix(C_BIGNUM_BITS_TO_DIGITS(len)); C_word result = C_allocate_scratch_bignum(ptr, size, C_SCHEME_FALSE, C_SCHEME_FALSE);Trap