diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-11-10 21:55:58 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-11-10 21:55:58 -0800 |
commit | b20f57e55eea53a570c1fb59961173035f00f8dc (patch) | |
tree | 0c76726cc90d5122ebb03fbeeb54aefe8b1f9c0c /eval.c | |
parent | 9b4a3ff6af6ce40a049d024ffa7db531f39a1fab (diff) | |
download | txr-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.c | 2 |
1 files changed, 1 insertions, 1 deletions
@@ -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)); |