~ 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