From: Mark Date: Sat, 30 Sep 2023 21:24:30 +0000 (-0600) Subject: correct skipping of not fully visited lists in stackful heap iterator (#2056, #2063... X-Git-Tag: remove~67 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=25afc111680abfff959ba20f1d85c7ffc0111673;p=scryer-prolog.git correct skipping of not fully visited lists in stackful heap iterator (#2056, #2063, #2065) --- diff --git a/src/heap_iter.rs b/src/heap_iter.rs index fc5d3416..6005aa2e 100644 --- a/src/heap_iter.rs +++ b/src/heap_iter.rs @@ -127,9 +127,15 @@ impl<'a> StackfulPreOrderHeapIter<'a> { #[inline] fn forward_if_referent_marked(&mut self, loc: IterStackLoc) { - read_heap_cell!(self.read_cell(loc), + let cell = self.read_cell(loc); + + read_heap_cell!(cell, + (HeapCellValueTag::Lis, vh) => { + if cell.get_mark_bit() && self.heap[vh].get_mark_bit() { + self.read_cell_mut(loc).set_forwarding_bit(true); + } + } (HeapCellValueTag::Str | - HeapCellValueTag::Lis | HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::PStrLoc, vh) => { @@ -260,28 +266,27 @@ impl<'a> StackfulPreOrderHeapIter<'a> { (HeapCellValueTag::Lis, vh) => { let loc = IterStackLoc::iterable_loc(vh, HeapOrStackTag::Heap); + self.forward_if_referent_marked(loc); self.push_if_unmarked(loc); self.stack.push(IterStackLoc::pending_mark_loc(vh + 1, HeapOrStackTag::Heap)); self.stack.push(IterStackLoc::mark_loc(vh, HeapOrStackTag::Heap)); - self.forward_if_referent_marked(loc); - return Some(self.read_cell(h)); } (HeapCellValueTag::AttrVar | HeapCellValueTag::Var, vh) => { let loc = IterStackLoc::iterable_loc(vh, HeapOrStackTag::Heap); + self.forward_if_referent_marked(loc); self.push_if_unmarked(loc); self.stack.push(IterStackLoc::mark_loc(vh, HeapOrStackTag::Heap)); - self.forward_if_referent_marked(loc); } (HeapCellValueTag::StackVar, vs) => { let loc = IterStackLoc::iterable_loc(vs, HeapOrStackTag::Stack); + self.forward_if_referent_marked(loc); self.push_if_unmarked(loc); self.stack.push(IterStackLoc::mark_loc(vs, HeapOrStackTag::Stack)); - self.forward_if_referent_marked(loc); } (HeapCellValueTag::PStrOffset, offset) => { self.push_if_unmarked(IterStackLoc::iterable_loc(offset, HeapOrStackTag::Heap)); @@ -2059,6 +2064,10 @@ mod tests { ); assert_eq!(iter.next().unwrap(), cyclic_link); + assert_eq!(iter.next().unwrap(), cyclic_link); + + assert_eq!(iter.next().unwrap(), cyclic_link); + assert_eq!(iter.next(), None); }