~ chicken-core (chicken-5) 7ee034e3f2e6f8c9e433391dc4c02b6196052e7f
commit 7ee034e3f2e6f8c9e433391dc4c02b6196052e7f Author: felix <felix@call-with-current-continuation.org> AuthorDate: Sun Jan 2 11:38:34 2011 +0100 Commit: felix <felix@call-with-current-continuation.org> CommitDate: Sun Jan 2 11:38:34 2011 +0100 equal? and equal=? do not recurse into closures (CR #441) diff --git a/library.scm b/library.scm index c6874507..d5c99a88 100644 --- a/library.scm +++ b/library.scm @@ -124,6 +124,16 @@ fast_read_string_from_file(C_word dest, C_word port, C_word len, C_word pos) return C_fix (m); } + +static C_word +shallow_equal(C_word x, C_word y) +{ + /* assumes x and y are non-immediate */ + int i, len = C_header_size(x); + + if(C_header_size(y) != len) return C_SCHEME_FALSE; + else return C_mk_bool(!C_memcmp((void *)x, (void *)y, len * sizeof(C_word))); +} EOF ) ) @@ -1095,8 +1105,9 @@ EOF ((not (##core#inline "C_sametypep" x y)) #f) ((##core#inline "C_specialp" x) (and (##core#inline "C_specialp" y) - (not (##core#inline "C_closurep" x)) - (compare-slots x y 1))) + (if (##core#inline "C_closurep" x) + (##core#inline "shallow_equal" x y) + (compare-slots x y 1)))) ((##core#inline "C_byteblockp" x) (and (##core#inline "C_byteblockp" y) (let ((s1 (##sys#size x))) diff --git a/manual/Deviations from the standard b/manual/Deviations from the standard index 115ac941..ffda509e 100644 --- a/manual/Deviations from the standard +++ b/manual/Deviations from the standard @@ -90,10 +90,10 @@ lambda-expressions. === {{equal?}} compares all structured data recursively -{{equal?}} compares all structured data recursively, while R5RS -specifies that {{eqv?}} is used for data other than pairs, strings and -vectors. However, R5RS does not dictate the treatment of data types -that are not specified by R5RS. +{{equal?}} compares all structured data with the exception of +procedures recursively, while R5RS specifies that {{eqv?}} is used for +data other than pairs, strings and vectors. However, R5RS does not +dictate the treatment of data types that are not specified by R5RS === No built-in support for bignums diff --git a/runtime.c b/runtime.c index 409e7eff..e907c9a4 100644 --- a/runtime.c +++ b/runtime.c @@ -3891,7 +3891,10 @@ C_regparm C_word C_fcall C_equalp(C_word x, C_word y) n = header & C_HEADER_SIZE_MASK; if(bits & C_SPECIALBLOCK_BIT) { - if(C_u_i_car(x) != C_u_i_car(y)) return 0; + /* do not recurse into closures */ + if((bits & C_CLOSURE_TYPE) != 0) + return !C_memcmp(x, y, n * sizeof(C_word)); + else if(C_block_item(x, 0) != C_block_item(y, 0)) return 0; else ++i; if(n == 1) return 1;Trap