From f0493b337617d403dc572975784f1a54c741a76e Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Fri, 17 Dec 2021 20:02:46 -0800 Subject: iter-reset: gc problem. * lib.c (iter_reset): When we reinitialize the iterator, it can allocate a new secondary object, e.g. using hash_begin, which is stored into the iterator. This is potentially a wrong-way assignment in terms of GC generations and so we must call mut(iter) to indicate that the object has been suspiciously mutated. We only do this if the iterator has a mark function. If it doesn't have one, then it isn't wrapping a heap object, and so doesn't have this issue. (seq_reset): This has the same issue, and the fix is the same. Since ths function is obsolescent, we don't bother doing the si->ops->mark check; we optimize for code size instead. --- lib.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'lib.c') diff --git a/lib.c b/lib.c index 15909c6c..dca7474d 100644 --- a/lib.c +++ b/lib.c @@ -1183,6 +1183,7 @@ val seq_reset(val iter, val obj) struct seq_iter *si = coerce(struct seq_iter *, cobj_handle(self, iter, seq_iter_cls)); seq_iter_init(self, si, obj); + mut(iter); return iter; } @@ -1350,6 +1351,8 @@ val iter_reset(val iter, val obj) { struct seq_iter *si = coerce(struct seq_iter *, iter->co.handle); seq_iter_init_with_info(self, si, sinf, 0); + if (si->ops->mark) + mut(iter); return iter; } /* fallthrough */ -- cgit v1.2.3