summaryrefslogtreecommitdiffstats
path: root/eval.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-11-10 21:55:58 -0800
committerKaz Kylheku <kaz@kylheku.com>2016-11-10 21:55:58 -0800
commitb20f57e55eea53a570c1fb59961173035f00f8dc (patch)
tree0c76726cc90d5122ebb03fbeeb54aefe8b1f9c0c /eval.c
parent9b4a3ff6af6ce40a049d024ffa7db531f39a1fab (diff)
downloadtxr-b20f57e55eea53a570c1fb59961173035f00f8dc.tar.gz
txr-b20f57e55eea53a570c1fb59961173035f00f8dc.tar.bz2
txr-b20f57e55eea53a570c1fb59961173035f00f8dc.zip
Fix some gc-unsafe mutations found by inspection.
* eval.c (force): When replacing the promise by a forced value, we must use the set macro. Only the deref assignments which store symbols are safe, not the one storing ret. * lib.c (alist_nremove, alist_nremove1): We must use the set macro here instead of assigning through deref. Even though these assignments preserve the direction of the list (they just splice out nodes), it's possible that the list already contains a "wrong-way" reference (old generation to new) and that the node making this reference is appropriately marked to be processed properly in the next GC cycle. If we remove *that* node, we then cause its predecessor to point to the new generation node and that predecessor could be old generation.
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/eval.c b/eval.c
index 06df270d..a0c610c9 100644
--- a/eval.c
+++ b/eval.c
@@ -4469,7 +4469,7 @@ static val force(val promise)
deref(pstate) = promise_inprogress_s;
ret = funcall(deref(pval));
deref(pstate) = promise_forced_s;
- deref(pval) = ret;
+ set(pval, ret);
return ret;
} else if (deref(pstate) == promise_inprogress_s) {
val form = second(cdr(cd));