fix cyclic detection of partial strings in StackfulPreOrderHeapIter (#3050)
This commit is contained in:
@@ -445,24 +445,17 @@ impl<'a, ElideLists: ListElisionPolicy> StackfulPreOrderHeapIter<'a, ElideLists>
|
||||
let cell = *cell;
|
||||
let tail_idx = self.heap.scan_slice_to_str(vh).tail_idx;
|
||||
|
||||
// forward the current PStrLoc cell if the zero
|
||||
// byte at the end of the string buffer
|
||||
// is marked
|
||||
let buf_bytes = self.heap[tail_idx - 1].into_bytes();
|
||||
if self.heap[tail_idx - 1].get_mark_bit() {
|
||||
self.read_cell_mut(h).set_forwarding_bit(true);
|
||||
self.stack.push(h);
|
||||
|
||||
if buf_bytes[7] != 0u8 {
|
||||
let cell = self.read_cell_mut(h);
|
||||
cell.set_forwarding_bit(true);
|
||||
continue;
|
||||
} else {
|
||||
self.heap[tail_idx - 1].set_mark_bit(true);
|
||||
}
|
||||
|
||||
// now mark it as if were a HeapCellValue, even
|
||||
// though it's not! this is fine as long as its tag
|
||||
// is never inspected, which it isn't.
|
||||
|
||||
self.push_if_unmarked(
|
||||
IterStackLoc::iterable_loc(tail_idx - 1, HeapOrStackTag::Heap),
|
||||
);
|
||||
self.stack.push(IterStackLoc::mark_loc(tail_idx, HeapOrStackTag::Heap));
|
||||
self.stack.push(IterStackLoc::iterable_loc(tail_idx - 1, HeapOrStackTag::Heap));
|
||||
self.stack.push(IterStackLoc::pending_mark_loc(tail_idx, HeapOrStackTag::Heap));
|
||||
|
||||
return Some(cell);
|
||||
}
|
||||
@@ -1959,10 +1952,6 @@ mod tests {
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
pstr_loc_as_cell!(heap_index!(3) + 2)
|
||||
);
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
pstr_loc_as_cell!(heap_index!(3) + 2)
|
||||
);
|
||||
assert_eq!(iter.next(), None);
|
||||
}
|
||||
|
||||
@@ -2177,8 +2166,14 @@ mod tests {
|
||||
);
|
||||
|
||||
assert_eq!(iter.heap.slice_to_str(0, "a string".len()), "a string");
|
||||
assert_eq!(iter.next().unwrap(), pstr_loc_as_cell!(0));
|
||||
assert_eq!(iter.next().unwrap(), empty_list_as_cell!());
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
pstr_loc_as_cell!(0)
|
||||
);
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
empty_list_as_cell!()
|
||||
);
|
||||
assert_eq!(iter.next(), None);
|
||||
}
|
||||
|
||||
@@ -2554,10 +2549,6 @@ mod tests {
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
pstr_loc_as_cell!(heap_index!(3) + 2)
|
||||
);
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
pstr_loc_as_cell!(heap_index!(3) + 2)
|
||||
);
|
||||
assert_eq!(
|
||||
unmark_cell_bits!(iter.next().unwrap()),
|
||||
pstr_loc_as_cell!(heap_index!(3))
|
||||
|
||||
@@ -904,16 +904,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
debug_assert!(cell.is_ref());
|
||||
|
||||
let h = if cell.get_tag() == HeapCellValueTag::PStrLoc {
|
||||
self.iter.focus().value()
|
||||
self.state_stack
|
||||
.push(TokenOrRedirect::Atom(atom!("...")));
|
||||
return None;
|
||||
} else {
|
||||
cell.get_value()
|
||||
} as usize;
|
||||
|
||||
self.iter.push_stack(IterStackLoc::iterable_loc(
|
||||
h,
|
||||
HeapOrStackTag::Heap,
|
||||
));
|
||||
|
||||
// as usual, the WAM's
|
||||
// optimization of the Lis tag
|
||||
// (conflating the location of
|
||||
@@ -934,10 +931,17 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
||||
}
|
||||
}
|
||||
|
||||
self.iter.push_stack(IterStackLoc::iterable_loc(
|
||||
h,
|
||||
HeapOrStackTag::Heap,
|
||||
));
|
||||
|
||||
if let Some(cell) = self.iter.next() {
|
||||
orig_cell = cell;
|
||||
continue;
|
||||
}
|
||||
|
||||
return Some(cell);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user