~ chicken-core (chicken-5) eb15ee6b6cc6a417fe4eea08edbb86d3ccf52115
commit eb15ee6b6cc6a417fe4eea08edbb86d3ccf52115
Author: Peter Bex <peter@more-magic.net>
AuthorDate: Fri Nov 20 18:50:54 2015 +0100
Commit: Mario Domenech Goulart <mario.goulart@gmail.com>
CommitDate: Sat Nov 28 09:56:05 2015 -0200
Fix equal? comparison of closures.
Even though you're not supposed to compare closures (the spec says it's
undefined), CHICKEN supports this to a degree. Two closures are
compared in such a way that the slots must be identical. In other
words, the function address and all the variables that are closed over
are eq? to one another on both sides.
The current implementation had an off-by-one which caused it to omit the
comparison of the last slot, which holds either the last argument or the
lambda-info in case we've compiled with lambda info. This caused the
equal? procedure to behave differently depending on whether the code was
compiled with the -no-lambda-info option or without it.
Thanks to Mario Goulart for finding this in ticket #1041.
Signed-off-by: Mario Domenech Goulart <mario.goulart@gmail.com>
diff --git a/NEWS b/NEWS
index eba4c910..33b4fa9a 100644
--- a/NEWS
+++ b/NEWS
@@ -42,6 +42,8 @@
- Runtime system:
- Compiled programs with large literals won't crash on startup (#1221).
+ - Comparisons of closures now behave in a stable way, whether or not
+ the code was compiled with the -no-lambda-info option (#1041).
- Compiler:
- Specializations on implicit "or" types like "number" or "boolean" now
diff --git a/runtime.c b/runtime.c
index 05fcd989..b8ada78a 100644
--- a/runtime.c
+++ b/runtime.c
@@ -4428,7 +4428,7 @@ C_regparm C_word C_fcall C_equalp(C_word x, C_word y)
if(bits & C_SPECIALBLOCK_BIT) {
/* do not recurse into closures */
if(C_header_bits(x) == C_CLOSURE_TYPE)
- return !C_memcmp((void *)x, (void *)y, n * sizeof(C_word));
+ return !C_memcmp(C_data_pointer(x), C_data_pointer(y), n * sizeof(C_word));
else if(C_block_item(x, 0) != C_block_item(y, 0)) return 0;
else ++i;
Trap