mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-03-11 15:30:36 -07:00
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).
This commit is contained in:
parent
6c31313c07
commit
40ef71aa60
3 changed files with 57 additions and 29 deletions
23
CHANGELOG
23
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
|
||||
|
|
|
|||
|
|
@ -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<MT_N; j++)
|
||||
for (int j=1; j<MT_N; j++)
|
||||
mt[j] = (6364136223846793005ULL * (mt[j-1] ^ (mt[j-1] >> 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*')))
|
||||
|
|
|
|||
26
src/c/read.d
26
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);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue