~ 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