From 40ef71aa609f48a3fc777962a3f1507159932ddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kochma=C5=84ski?= Date: Fri, 6 May 2016 12:55:25 +0200 Subject: [PATCH] rng: make-random-state conformity and #$ macro fix `make-random-state' now accepts the conforming types of the arguments (ie not a fixnum nor simple-vector). Additionally we sanitize the vector provided to the #$ to be of the correct arity and type (#313 byte64 or #625 byte32 depending on the architecture). --- CHANGELOG | 23 ++++++++++++++++++++++- src/c/num_rand.d | 37 ++++++++++--------------------------- src/c/read.d | 26 +++++++++++++++++++++++++- 3 files changed, 57 insertions(+), 29 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6160ceff0..805cb544d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -28,13 +28,29 @@ parameter given to configure script). * Pending changes since 16.1.2 +** API changes +- make-random-state: fix problem with simple-vectors + +The correct initialization types for =make-random-state= are: +=(OR RANDOM-STATE (MEMBER T NIL))= + +Initializing a random state with an appropriate array (element type and +arity) or with a fixnum is now possible only with the #$ reader macro. + ** Enhancements - Removed 15000 lines of obsolete code - Files not included in the buildsystem but lingering in the codebase or options failing to build. All info is added in the new documentation in section "Removed interfaces". +- Indented C/C++ code to follow emacs's gnu C style +This is a first step towards coding standards in the +documentation. Additionally all in the src/c/ directory are listed in the +appropraite documentation section (new-doc). + +- Refactored =list_current_directory in unixfsys.d= +Function was obfuscated with ifdefs with non-even pairs of =#\{= and =#\}=. + ** Issues fixed - MOP: fix problemes when redefining non-standard and anonymous classes Bugs identified and fixed by Pascal Costanza. @@ -43,6 +59,11 @@ Bugs identified and fixed by Pascal Costanza. This fixes the regression, which crashed ECL at start when pathname exceeded 128 characters limit. +- make-random-state: fix problem with simple-vectors +Until now #$ reader macro accepted simple vectors as an argument, what lead +to bugs if vector didn't match specific requirements like the element type +or the arity. Now we sanitize this. + * 16.1.2 changes since 16.0.0 ** API changes diff --git a/src/c/num_rand.d b/src/c/num_rand.d index d3f981207..c519b0575 100644 --- a/src/c/num_rand.d +++ b/src/c/num_rand.d @@ -47,14 +47,13 @@ #define LOWER_MASK 0x7FFFFFFFULL /* least significant 31 bits */ #define ulong uint64_t -static cl_object +cl_object init_genrand(ulong seed) { cl_object array = ecl_alloc_simple_vector((MT_N + 1), ecl_aet_b64); ulong *mt = array->vector.self.b64; - int j; mt[0] = seed; - for (j=1; j> 62)) + j); mt[MT_N] = MT_N+1; @@ -129,14 +128,13 @@ generate_limb(cl_object state) #define LOWER_MASK 0x7fffffffUL /* least significant r bits */ #define ulong uint32_t -static cl_object +cl_object init_genrand(ulong seed) { cl_object array = ecl_alloc_simple_vector((MT_N + 1), ecl_aet_b32); ulong *mt = array->vector.self.b32; - int j; mt[0] = seed; - for (j=1; j < MT_N; j++) + for (int j=1; j < MT_N; j++) mt[j] = (1812433253UL * (mt[j-1] ^ (mt[j-1] >> 30)) + j); mt[MT_N] = MT_N+1; @@ -289,30 +287,15 @@ ecl_make_random_state(cl_object rs) if (Null(rs)) rs = ecl_symbol_value(@'*random-state*'); - switch (ecl_t_of(rs)) { - case t_random: + if (ecl_t_of(rs) == t_random) { z->random.value = cl_copy_seq(rs->random.value); - break; - case t_vector: - z->random.value = cl_copy_seq(rs); - break; - case t_fixnum: - /* XXX: If we'll decide to use 64-bit algorithm for - appropriate platforms then this will be replaced - with ecl_to_ulong_long from number.d, which takes - widest available type (32 or 64 bit) - automatically. */ - z->random.value = init_genrand(ecl_fixnum(rs)); - break; - default: { - const char *type - = "(OR RANDOM-STATE (SIMPLE-VECTOR *) (INTEGER 0 *))"; - FEwrong_type_only_arg(@[make-random-state], rs, - ecl_read_from_cstring(type)); - } + return z; } - return(z); + const char *type + = "(OR RANDOM-STATE FIXNUM (MEMBER T NIL))"; + FEwrong_type_only_arg(@[make-random-state], rs, + ecl_read_from_cstring(type)); } @(defun random (x &optional (rs ecl_symbol_value(@'*random-state*'))) diff --git a/src/c/read.d b/src/c/read.d index de3c5bd52..ad1e5e013 100644 --- a/src/c/read.d +++ b/src/c/read.d @@ -1383,7 +1383,31 @@ sharp_dollar_reader(cl_object in, cl_object c, cl_object d) if (d != ECL_NIL && !read_suppress) extra_argument('$', in, d); c = ecl_read_object(in); - rs = ecl_make_random_state(c); + + switch (ecl_t_of(c)) { + case t_vector: +#if ECL_FIXNUM_BITS > 32 + if (c->vector.dim == 313 && c->vector.elttype == ecl_aet_b64) { + rs = ecl_alloc_object(t_random); + rs->random.value = cl_copy_seq(c); + break; + } +#else /* 32 bit version */ + if (c->vector.dim == 625 && c->vector.elttype == ecl_aet_b32) { + rs = ecl_alloc_object(t_random); + rs->random.value = cl_copy_seq(c); + break; + } +#endif + case t_fixnum: + rs = ecl_alloc_object(t_random); + rs->random.value = init_genrand(ecl_fixnum(c)); + break; + default: + rs = ecl_make_random_state(c); + break; + } + @(return rs); }