]> Repositorios git - scryer-prolog.git/commitdiff
correct skipping of not fully visited lists in stackful heap iterator (#2056, #2063...
authorMark <[email protected]>
Sat, 30 Sep 2023 21:24:30 +0000 (15:24 -0600)
committerMark <[email protected]>
Sat, 30 Sep 2023 21:24:30 +0000 (15:24 -0600)
src/heap_iter.rs

index fc5d34163468fea9d82a93c3535c943b04b77e6e..6005aa2e714225767f752a3ac3afbad38f28c6fb 100644 (file)
@@ -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);
         }