summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2012-04-05 09:18:14 -0700
committerKaz Kylheku <kaz@kylheku.com>2012-04-05 09:18:14 -0700
commitc162f73f9cfd0bb48675dc11bd56ac359451510b (patch)
tree5fda9e1835758135d39090ddc8ca79ec1070c5d9 /lib.c
parent1e5d313bafa78885490b3fa0759ba76436917d9b (diff)
downloadtxr-c162f73f9cfd0bb48675dc11bd56ac359451510b.tar.gz
txr-c162f73f9cfd0bb48675dc11bd56ac359451510b.tar.bz2
txr-c162f73f9cfd0bb48675dc11bd56ac359451510b.zip
The mut macro should only be used for vectors or vector-like objects
which hold direct references to other objects and must be used each time a mutation takes place. * eval.c (op_dohash): invocations of mut macro removed. Comment rewritten. * lib.c (sort_list): Use set macro for mutating assignment. Do not invoke mut on sorted list; it won't work anyway, because it doesn't mean what the code wants it to mean: that the list will be fully traversed during gc marking.
Diffstat (limited to 'lib.c')
-rw-r--r--lib.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/lib.c b/lib.c
index 77231478..ae6fd998 100644
--- a/lib.c
+++ b/lib.c
@@ -3781,7 +3781,11 @@ static val sort_list(val list, val lessfun, val keyfun)
return list;
} else {
val cons2 = cdr(list);
- *cdr_l(cons2) = list;
+ /* This assignent is a dangerous mutation since the list
+ may contain mixtures of old and new objects, and
+ so we could be reversing a newer->older pointer
+ relationship. */
+ set(*cdr_l(cons2), list);
*cdr_l(list) = nil;
return cons2;
}
@@ -3853,7 +3857,7 @@ val sort(val seq, val lessfun, val keyfun)
objects. Sorting the list could reverse some of the
pointers between the generations resulting in a backpointer.
Thus we better inform the collector about this object. */
- return mut(sort_list(seq, lessfun, keyfun));
+ return sort_list(seq, lessfun, keyfun);
}
sort_vec(seq, lessfun, keyfun);