optionally read from machine stack in stackful pre-order iterator (#1812)

This commit is contained in:
Mark
2023-05-26 15:19:07 -06:00
parent dae34b6009
commit e0f49e8f43
6 changed files with 374 additions and 154 deletions

6
Cargo.lock generated
View File

@@ -524,6 +524,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
[[package]]
name = "funty"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]] [[package]]
name = "futf" name = "futf"
version = "0.1.5" version = "0.1.5"

View File

@@ -1,8 +1,9 @@
#[cfg(test)] #[cfg(test)]
pub(crate) use crate::machine::gc::{IteratorUMP, StacklessPreOrderHeapIter}; pub(crate) use crate::machine::gc::{IteratorUMP, StacklessPreOrderHeapIter};
use crate::machine::heap::*;
use crate::atom_table::*; use crate::atom_table::*;
use crate::machine::heap::*;
use crate::machine::stack::*;
use crate::types::*; use crate::types::*;
use modular_bitfield::prelude::*; use modular_bitfield::prelude::*;
@@ -18,28 +19,45 @@ enum IterStackLocTag {
PendingMark, PendingMark,
} }
#[derive(BitfieldSpecifier, Clone, Copy, Debug, PartialEq, Eq)]
#[bits = 1]
pub enum HeapOrStackTag {
Heap,
Stack,
}
#[bitfield] #[bitfield]
#[repr(u64)] #[repr(u64)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct IterStackLoc { pub struct IterStackLoc {
value: B62, pub value: B61,
tag: IterStackLocTag, tag: IterStackLocTag,
heap_or_stack: HeapOrStackTag,
} }
impl IterStackLoc { impl IterStackLoc {
#[inline] #[inline]
pub fn iterable_heap_loc(h: usize) -> Self { pub fn iterable_loc(h: usize, heap_or_stack: HeapOrStackTag) -> Self {
IterStackLoc::new().with_tag(IterStackLocTag::Iterable).with_value(h as u64) IterStackLoc::new()
.with_tag(IterStackLocTag::Iterable)
.with_heap_or_stack(heap_or_stack)
.with_value(h as u64)
} }
#[inline] #[inline]
pub fn mark_heap_loc(h: usize) -> Self { fn mark_loc(h: usize, heap_or_stack: HeapOrStackTag) -> Self {
IterStackLoc::new().with_tag(IterStackLocTag::Marked).with_value(h as u64) IterStackLoc::new()
.with_tag(IterStackLocTag::Marked)
.with_heap_or_stack(heap_or_stack)
.with_value(h as u64)
} }
#[inline] #[inline]
pub fn pending_mark_heap_loc(h: usize) -> Self { fn pending_mark_loc(h: usize, heap_or_stack: HeapOrStackTag) -> Self {
IterStackLoc::new().with_tag(IterStackLocTag::PendingMark).with_value(h as u64) IterStackLoc::new()
.with_tag(IterStackLocTag::PendingMark)
.with_heap_or_stack(heap_or_stack)
.with_value(h as u64)
} }
#[inline] #[inline]
@@ -51,38 +69,35 @@ impl IterStackLoc {
pub fn is_pending_mark(self) -> bool { pub fn is_pending_mark(self) -> bool {
self.tag() == IterStackLocTag::PendingMark self.tag() == IterStackLocTag::PendingMark
} }
}
#[inline] #[inline]
fn forward_if_referent_marked(heap: &mut [HeapCellValue], h: usize) { pub fn as_ref(self) -> Ref {
read_heap_cell!(heap[h], match self.heap_or_stack() {
(HeapCellValueTag::Str HeapOrStackTag::Heap => {
| HeapCellValueTag::Lis Ref::heap_cell(self.value() as usize)
| HeapCellValueTag::AttrVar }
| HeapCellValueTag::Var HeapOrStackTag::Stack => {
| HeapCellValueTag::PStrLoc, vh) => { Ref::stack_cell(self.value() as usize)
if heap[vh].get_mark_bit() {
heap[h].set_forwarding_bit(true);
} }
} }
_ => {} }
)
} }
#[derive(Debug)] #[derive(Debug)]
pub struct StackfulPreOrderHeapIter<'a> { pub struct StackfulPreOrderHeapIter<'a> {
pub heap: &'a mut Vec<HeapCellValue>, pub heap: &'a mut Vec<HeapCellValue>,
pub machine_stack: &'a mut Stack,
stack: Vec<IterStackLoc>, stack: Vec<IterStackLoc>,
h: usize, h: IterStackLoc,
} }
impl<'a> Drop for StackfulPreOrderHeapIter<'a> { impl<'a> Drop for StackfulPreOrderHeapIter<'a> {
fn drop(&mut self) { fn drop(&mut self) {
while let Some(h) = self.stack.pop() { while let Some(h) = self.stack.pop() {
let h = h.value() as usize; let cell = self.read_cell_mut(h);
self.heap[h].set_forwarding_bit(false); cell.set_forwarding_bit(false);
self.heap[h].set_mark_bit(false); cell.set_mark_bit(false);
} }
self.heap.pop(); self.heap.pop();
@@ -90,48 +105,93 @@ impl<'a> Drop for StackfulPreOrderHeapIter<'a> {
} }
pub trait FocusedHeapIter: Iterator<Item = HeapCellValue> { pub trait FocusedHeapIter: Iterator<Item = HeapCellValue> {
fn focus(&self) -> usize; fn focus(&self) -> IterStackLoc;
} }
impl<'a> FocusedHeapIter for StackfulPreOrderHeapIter<'a> { impl<'a> FocusedHeapIter for StackfulPreOrderHeapIter<'a> {
#[inline] #[inline]
fn focus(&self) -> usize { fn focus(&self) -> IterStackLoc {
self.h self.h
} }
} }
impl<'a> StackfulPreOrderHeapIter<'a> { impl<'a> StackfulPreOrderHeapIter<'a> {
#[inline] #[inline]
fn new(heap: &'a mut Vec<HeapCellValue>, cell: HeapCellValue) -> Self { fn new(heap: &'a mut Vec<HeapCellValue>, stack: &'a mut Stack, cell: HeapCellValue) -> Self {
let h = heap.len(); let h = IterStackLoc::iterable_loc(heap.len(), HeapOrStackTag::Heap);
heap.push(cell); heap.push(cell);
Self { Self {
heap, heap,
h, h,
stack: vec![IterStackLoc::iterable_heap_loc(h)], machine_stack: stack,
stack: vec![h],
} }
} }
#[inline] #[inline]
pub fn push_stack(&mut self, h: usize) { fn forward_if_referent_marked(&mut self, loc: IterStackLoc) {
self.stack.push(IterStackLoc::iterable_heap_loc(h)); read_heap_cell!(self.read_cell(loc),
(HeapCellValueTag::Str |
HeapCellValueTag::Lis |
HeapCellValueTag::AttrVar |
HeapCellValueTag::Var |
HeapCellValueTag::PStrLoc, vh) => {
if self.heap[vh].get_mark_bit() {
self.read_cell_mut(loc).set_forwarding_bit(true);
}
}
(HeapCellValueTag::StackVar, vs) => {
if self.machine_stack[vs].get_mark_bit() {
self.read_cell_mut(loc).set_forwarding_bit(true);
}
}
_ => {}
);
} }
#[inline] #[inline]
pub fn stack_last(&self) -> Option<usize> { pub fn push_stack(&mut self, h: IterStackLoc) {
self.stack.push(h);
}
#[inline]
pub fn read_cell_mut(&mut self, loc: IterStackLoc) -> &mut HeapCellValue {
match loc.heap_or_stack() {
HeapOrStackTag::Heap => {
&mut self.heap[loc.value() as usize]
}
HeapOrStackTag::Stack => {
&mut self.machine_stack[loc.value() as usize]
}
}
}
#[inline]
pub fn read_cell(&self, loc: IterStackLoc) -> HeapCellValue {
match loc.heap_or_stack() {
HeapOrStackTag::Heap => {
self.heap[loc.value() as usize]
}
HeapOrStackTag::Stack => {
self.machine_stack[loc.value() as usize]
}
}
}
#[inline]
pub fn stack_last(&self) -> Option<IterStackLoc> {
for h in self.stack.iter().rev() { for h in self.stack.iter().rev() {
let is_readable_marked = h.is_marked(); let is_readable_marked = h.is_marked();
let h = h.value() as usize; let cell = self.read_cell(*h);
let cell = self.heap[h];
if cell.get_forwarding_bit() { if cell.get_forwarding_bit() {
return Some(h); return Some(*h);
} else if cell.get_mark_bit() && !is_readable_marked { } else if cell.get_mark_bit() && !is_readable_marked {
continue; continue;
} }
return Some(h); return Some(*h);
} }
None None
@@ -141,10 +201,9 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
pub fn pop_stack(&mut self) -> Option<HeapCellValue> { pub fn pop_stack(&mut self) -> Option<HeapCellValue> {
while let Some(h) = self.stack.pop() { while let Some(h) = self.stack.pop() {
let is_readable_marked = h.is_marked(); let is_readable_marked = h.is_marked();
let h = h.value() as usize;
self.h = h;
let cell = &mut self.heap[h]; self.h = h;
let cell = self.read_cell_mut(h);
if cell.get_forwarding_bit() { if cell.get_forwarding_bit() {
cell.set_forwarding_bit(false); cell.set_forwarding_bit(false);
@@ -159,30 +218,29 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
None None
} }
fn push_if_unmarked(&mut self, h: usize) { fn push_if_unmarked(&mut self, loc: IterStackLoc) {
if !self.heap[h].get_mark_bit() { let cell = self.read_cell_mut(loc);
self.heap[h].set_mark_bit(true);
self.stack.push(IterStackLoc::iterable_heap_loc(h)); if !cell.get_mark_bit() {
cell.set_mark_bit(true);
self.stack.push(IterStackLoc::iterable_loc(loc.value() as usize, loc.heap_or_stack()));
} }
} }
fn follow(&mut self) -> Option<HeapCellValue> { fn follow(&mut self) -> Option<HeapCellValue> {
while let Some(h) = self.stack.pop() { while let Some(h) = self.stack.pop() {
if h.is_pending_mark() { if h.is_pending_mark() {
let h = h.value() as usize;
self.push_if_unmarked(h); self.push_if_unmarked(h);
self.stack.push(IterStackLoc::mark_heap_loc(h)); self.stack.push(IterStackLoc::mark_loc(h.value() as usize, h.heap_or_stack()));
forward_if_referent_marked(&mut self.heap, h); self.forward_if_referent_marked(h);
continue; continue;
} }
let is_readable_marked = h.is_marked();
let h = h.value() as usize;
self.h = h; self.h = h;
let cell = &mut self.heap[h];
let is_readable_marked = h.is_marked();
let cell = self.read_cell_mut(h);
if cell.get_forwarding_bit() { if cell.get_forwarding_bit() {
let copy = *cell; let copy = *cell;
@@ -195,50 +253,68 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
read_heap_cell!(*cell, read_heap_cell!(*cell,
(HeapCellValueTag::Str | HeapCellValueTag::PStrLoc, vh) => { (HeapCellValueTag::Str | HeapCellValueTag::PStrLoc, vh) => {
self.push_if_unmarked(vh); let loc = IterStackLoc::iterable_loc(vh, HeapOrStackTag::Heap);
self.stack.push(IterStackLoc::mark_heap_loc(vh));
self.push_if_unmarked(loc);
self.stack.push(IterStackLoc::mark_loc(vh, HeapOrStackTag::Heap));
} }
(HeapCellValueTag::Lis, vh) => { (HeapCellValueTag::Lis, vh) => {
self.push_if_unmarked(vh); let loc = IterStackLoc::iterable_loc(vh, HeapOrStackTag::Heap);
self.stack.push(IterStackLoc::pending_mark_heap_loc(vh + 1)); self.push_if_unmarked(loc);
self.stack.push(IterStackLoc::mark_heap_loc(vh));
forward_if_referent_marked(&mut self.heap, vh); self.stack.push(IterStackLoc::pending_mark_loc(vh + 1, HeapOrStackTag::Heap));
self.stack.push(IterStackLoc::mark_loc(vh, HeapOrStackTag::Heap));
return Some(self.heap[h]); self.forward_if_referent_marked(loc);
return Some(self.read_cell(h));
} }
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, vh) => { (HeapCellValueTag::AttrVar | HeapCellValueTag::Var, vh) => {
self.push_if_unmarked(vh); let loc = IterStackLoc::iterable_loc(vh, HeapOrStackTag::Heap);
self.stack.push(IterStackLoc::mark_heap_loc(vh));
forward_if_referent_marked(&mut self.heap, vh); 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.push_if_unmarked(loc);
self.stack.push(IterStackLoc::mark_loc(vs, HeapOrStackTag::Stack));
self.forward_if_referent_marked(loc);
} }
(HeapCellValueTag::PStrOffset, offset) => { (HeapCellValueTag::PStrOffset, offset) => {
self.push_if_unmarked(offset); self.push_if_unmarked(IterStackLoc::iterable_loc(offset, HeapOrStackTag::Heap));
self.stack.push(IterStackLoc::iterable_heap_loc(h+1)); self.stack.push(IterStackLoc::iterable_loc((h.value()+1) as usize, HeapOrStackTag::Heap));
return Some(self.heap[h]); return Some(self.read_cell(h));
} }
(HeapCellValueTag::PStr) => { (HeapCellValueTag::PStr) => {
self.push_if_unmarked(h); let tail_loc = IterStackLoc::iterable_loc((h.value()+1) as usize, HeapOrStackTag::Heap);
self.stack.push(IterStackLoc::iterable_heap_loc(h+1)); self.push_if_unmarked(IterStackLoc::iterable_loc(h.value() as usize, HeapOrStackTag::Heap));
forward_if_referent_marked(&mut self.heap, h+1); self.stack.push(tail_loc);
self.forward_if_referent_marked(tail_loc);
return Some(self.heap[h]); return Some(self.read_cell(h));
} }
(HeapCellValueTag::Atom, (_name, arity)) => { (HeapCellValueTag::Atom, (_name, arity)) => {
for h in (h + 2 .. h + arity + 1).rev() { let l = h.value() as usize;
self.stack.push(IterStackLoc::pending_mark_heap_loc(h));
for l in (l + 2 .. l + arity + 1).rev() {
self.stack.push(IterStackLoc::pending_mark_loc(l, HeapOrStackTag::Heap));
} }
if arity > 0 { if arity > 0 {
self.push_if_unmarked(h+1); let first_arg_loc = IterStackLoc::iterable_loc(l+1, HeapOrStackTag::Heap);
self.stack.push(IterStackLoc::mark_heap_loc(h+1));
forward_if_referent_marked(&mut self.heap, h+1); self.push_if_unmarked(first_arg_loc);
self.stack.push(IterStackLoc::mark_loc(l+1, HeapOrStackTag::Heap));
self.forward_if_referent_marked(first_arg_loc);
} }
return Some(self.heap[h]); return Some(self.read_cell(h));
} }
_ => { _ => {
return Some(*cell); return Some(*cell);
@@ -269,19 +345,20 @@ pub(crate) fn stackless_preorder_iter(
} }
#[inline(always)] #[inline(always)]
pub(crate) fn stackful_preorder_iter( pub(crate) fn stackful_preorder_iter<'a>(
heap: &mut Vec<HeapCellValue>, heap: &'a mut Vec<HeapCellValue>,
stack: &'a mut Stack,
cell: HeapCellValue, cell: HeapCellValue,
) -> StackfulPreOrderHeapIter { ) -> StackfulPreOrderHeapIter<'a> {
StackfulPreOrderHeapIter::new(heap, cell) StackfulPreOrderHeapIter::new(heap, stack, cell)
} }
#[derive(Debug)] #[derive(Debug)]
pub(crate) struct PostOrderIterator<Iter: FocusedHeapIter> { pub(crate) struct PostOrderIterator<Iter: FocusedHeapIter> {
focus: usize, focus: IterStackLoc,
base_iter: Iter, base_iter: Iter,
base_iter_valid: bool, base_iter_valid: bool,
parent_stack: Vec<(usize, HeapCellValue, usize)>, // number of children, parent node, focus. parent_stack: Vec<(usize, HeapCellValue, IterStackLoc)>, // number of children, parent node, focus.
} }
impl<Iter: FocusedHeapIter> Deref for PostOrderIterator<Iter> { impl<Iter: FocusedHeapIter> Deref for PostOrderIterator<Iter> {
@@ -295,7 +372,7 @@ impl<Iter: FocusedHeapIter> Deref for PostOrderIterator<Iter> {
impl<Iter: FocusedHeapIter> PostOrderIterator<Iter> { impl<Iter: FocusedHeapIter> PostOrderIterator<Iter> {
pub(crate) fn new(base_iter: Iter) -> Self { pub(crate) fn new(base_iter: Iter) -> Self {
PostOrderIterator { PostOrderIterator {
focus: 0, focus: IterStackLoc::iterable_loc(0, HeapOrStackTag::Heap),
base_iter, base_iter,
base_iter_valid: true, base_iter_valid: true,
parent_stack: vec![], parent_stack: vec![],
@@ -352,7 +429,7 @@ impl<Iter: FocusedHeapIter> Iterator for PostOrderIterator<Iter> {
impl<Iter: FocusedHeapIter> FocusedHeapIter for PostOrderIterator<Iter> { impl<Iter: FocusedHeapIter> FocusedHeapIter for PostOrderIterator<Iter> {
#[inline(always)] #[inline(always)]
fn focus(&self) -> usize { fn focus(&self) -> IterStackLoc {
self.focus self.focus
} }
} }
@@ -368,7 +445,8 @@ impl<Iter: FocusedHeapIter> PostOrderIterator<Iter> {
if let Some((_child_count, item, focus)) = self.parent_stack.last() { if let Some((_child_count, item, focus)) = self.parent_stack.last() {
read_heap_cell!(item, read_heap_cell!(item,
(HeapCellValueTag::Atom, (_name, arity)) => { (HeapCellValueTag::Atom, (_name, arity)) => {
return focus + arity >= idx_loc && *focus < idx_loc; let focus = focus.value() as usize;
return focus + arity >= idx_loc && focus < idx_loc;
} }
_ => {} _ => {}
); );
@@ -401,9 +479,10 @@ impl<'a> LeftistPostOrderHeapIter<'a> {
#[inline] #[inline]
pub(crate) fn stackful_post_order_iter<'a>( pub(crate) fn stackful_post_order_iter<'a>(
heap: &'a mut Heap, heap: &'a mut Heap,
stack: &'a mut Stack,
cell: HeapCellValue, cell: HeapCellValue,
) -> LeftistPostOrderHeapIter<'a> { ) -> LeftistPostOrderHeapIter<'a> {
PostOrderIterator::new(StackfulPreOrderHeapIter::new(heap, cell)) PostOrderIterator::new(StackfulPreOrderHeapIter::new(heap, stack, cell))
} }
#[cfg(test)] #[cfg(test)]
@@ -424,6 +503,7 @@ mod tests {
use super::*; use super::*;
use crate::machine::mock_wam::*; use crate::machine::mock_wam::*;
#[test] #[test]
fn heap_stackless_iter_tests() { fn heap_stackless_iter_tests() {
let mut wam = MockWAM::new(); let mut wam = MockWAM::new();
@@ -1381,7 +1461,11 @@ mod tests {
.extend(functor!(f_atom, [atom(a_atom), atom(b_atom)])); .extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
{ {
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, str_loc_as_cell!(0)); let mut iter = StackfulPreOrderHeapIter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
str_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),
@@ -1412,7 +1496,11 @@ mod tests {
)); ));
for _ in 0..20 { for _ in 0..20 {
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, str_loc_as_cell!(0)); let mut iter = StackfulPreOrderHeapIter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
str_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),
@@ -1440,7 +1528,12 @@ mod tests {
{ {
wam.machine_st.heap.push(heap_loc_as_cell!(0)); wam.machine_st.heap.push(heap_loc_as_cell!(0));
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = StackfulPreOrderHeapIter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
let mut var = heap_loc_as_cell!(0); let mut var = heap_loc_as_cell!(0);
// self-referencing variables are copied with their forwarding // self-referencing variables are copied with their forwarding
@@ -1462,7 +1555,11 @@ mod tests {
wam.machine_st.heap.push(heap_loc_as_cell!(1)); wam.machine_st.heap.push(heap_loc_as_cell!(1));
wam.machine_st.heap.push(heap_loc_as_cell!(0)); wam.machine_st.heap.push(heap_loc_as_cell!(0));
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = StackfulPreOrderHeapIter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),
@@ -1482,7 +1579,11 @@ mod tests {
wam.machine_st.heap.push(empty_list_as_cell!()); wam.machine_st.heap.push(empty_list_as_cell!());
{ {
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = StackfulPreOrderHeapIter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),
@@ -1514,7 +1615,11 @@ mod tests {
wam.machine_st.heap.push(heap_loc_as_cell!(0)); wam.machine_st.heap.push(heap_loc_as_cell!(0));
{ {
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = StackfulPreOrderHeapIter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
// the cycle will be iterated twice before being detected. // the cycle will be iterated twice before being detected.
assert_eq!( assert_eq!(
@@ -1542,7 +1647,11 @@ mod tests {
} }
{ {
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = StackfulPreOrderHeapIter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
// cut the iteration short to check that all cells are // cut the iteration short to check that all cells are
// unmarked and unforwarded by the Drop instance of // unmarked and unforwarded by the Drop instance of
@@ -1576,7 +1685,11 @@ mod tests {
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize]; let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
{ {
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = StackfulPreOrderHeapIter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell); assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
assert_eq!( assert_eq!(
@@ -1596,7 +1709,11 @@ mod tests {
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize]; let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
{ {
let mut iter = stackful_preorder_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = stackful_preorder_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell); assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell); assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell);
@@ -1615,7 +1732,12 @@ mod tests {
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0i64))); wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0i64)));
{ {
let mut iter = stackful_preorder_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0)); let mut iter = stackful_preorder_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
pstr_loc_as_cell!(0),
);
let pstr_offset_cell = pstr_offset_as_cell!(0); let pstr_offset_cell = pstr_offset_as_cell!(0);
// pstr_offset_cell.set_forwarding_bit(true); // pstr_offset_cell.set_forwarding_bit(true);
@@ -1640,7 +1762,12 @@ mod tests {
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(1i64))); wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(1i64)));
{ {
let mut iter = stackful_preorder_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0)); let mut iter = stackful_preorder_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
pstr_loc_as_cell!(0),
);
let pstr_offset_cell = pstr_offset_as_cell!(0); let pstr_offset_cell = pstr_offset_as_cell!(0);
// pstr_offset_cell.set_forwarding_bit(true); // pstr_offset_cell.set_forwarding_bit(true);
@@ -1653,7 +1780,7 @@ mod tests {
let h = iter.focus(); let h = iter.focus();
assert_eq!(h, 5); assert_eq!(h.value(), 5);
assert_eq!(unmark_cell_bits!(iter.heap[4]), pstr_offset_as_cell!(0)); assert_eq!(unmark_cell_bits!(iter.heap[4]), pstr_offset_as_cell!(0));
assert_eq!(unmark_cell_bits!(iter.heap[5]), fixnum_as_cell!(Fixnum::build_with(1i64))); assert_eq!(unmark_cell_bits!(iter.heap[5]), fixnum_as_cell!(Fixnum::build_with(1i64)));
@@ -1673,7 +1800,11 @@ mod tests {
wam.machine_st.heap.extend(functor); wam.machine_st.heap.extend(functor);
{ {
let mut iter = StackfulPreOrderHeapIter::new(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = StackfulPreOrderHeapIter::new(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),
@@ -1732,7 +1863,11 @@ mod tests {
wam.machine_st.heap[4] = list_loc_as_cell!(1); wam.machine_st.heap[4] = list_loc_as_cell!(1);
{ {
let mut iter = stackful_preorder_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = stackful_preorder_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),
@@ -1799,6 +1934,7 @@ mod tests {
{ {
let mut iter = StackfulPreOrderHeapIter::new( let mut iter = StackfulPreOrderHeapIter::new(
&mut wam.machine_st.heap, &mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0), heap_loc_as_cell!(0),
); );
@@ -1830,6 +1966,7 @@ mod tests {
{ {
let mut iter = stackful_preorder_iter( let mut iter = stackful_preorder_iter(
&mut wam.machine_st.heap, &mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0), heap_loc_as_cell!(0),
); );
@@ -1864,6 +2001,7 @@ mod tests {
{ {
let mut iter = stackful_preorder_iter( let mut iter = stackful_preorder_iter(
&mut wam.machine_st.heap, &mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0), heap_loc_as_cell!(0),
); );
@@ -1898,7 +2036,11 @@ mod tests {
.extend(functor!(f_atom, [atom(a_atom), atom(b_atom)])); .extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
{ {
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, str_loc_as_cell!(0)); let mut iter = stackful_post_order_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
str_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),
@@ -1929,7 +2071,11 @@ mod tests {
)); ));
for _ in 0..20 { // 0000 { for _ in 0..20 { // 0000 {
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, str_loc_as_cell!(0)); let mut iter = stackful_post_order_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
str_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),
@@ -1959,7 +2105,12 @@ mod tests {
{ {
wam.machine_st.heap.push(heap_loc_as_cell!(0)); wam.machine_st.heap.push(heap_loc_as_cell!(0));
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = stackful_post_order_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
let mut var = heap_loc_as_cell!(0); let mut var = heap_loc_as_cell!(0);
// self-referencing variables are copied with their forwarding // self-referencing variables are copied with their forwarding
@@ -1981,7 +2132,11 @@ mod tests {
wam.machine_st.heap.push(heap_loc_as_cell!(1)); wam.machine_st.heap.push(heap_loc_as_cell!(1));
wam.machine_st.heap.push(heap_loc_as_cell!(0)); wam.machine_st.heap.push(heap_loc_as_cell!(0));
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = stackful_post_order_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),
@@ -2001,7 +2156,11 @@ mod tests {
wam.machine_st.heap.push(empty_list_as_cell!()); wam.machine_st.heap.push(empty_list_as_cell!());
{ {
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = stackful_post_order_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),
@@ -2033,7 +2192,11 @@ mod tests {
wam.machine_st.heap.push(heap_loc_as_cell!(0)); wam.machine_st.heap.push(heap_loc_as_cell!(0));
{ {
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = stackful_post_order_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
// the cycle will be iterated twice before being detected. // the cycle will be iterated twice before being detected.
assert_eq!( assert_eq!(
@@ -2063,6 +2226,7 @@ mod tests {
{ {
let mut iter = stackful_post_order_iter( let mut iter = stackful_post_order_iter(
&mut wam.machine_st.heap, &mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0), heap_loc_as_cell!(0),
); );
@@ -2098,7 +2262,11 @@ mod tests {
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize]; let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
{ {
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0)); let mut iter = stackful_post_order_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
pstr_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),
@@ -2117,7 +2285,11 @@ mod tests {
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize]; let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
{ {
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0)); let mut iter = stackful_post_order_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
pstr_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),
@@ -2136,7 +2308,11 @@ mod tests {
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0i64))); wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0i64)));
{ {
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0)); let mut iter = stackful_post_order_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
pstr_loc_as_cell!(0),
);
assert_eq!(iter.next().unwrap(), fixnum_as_cell!(Fixnum::build_with(0i64))); assert_eq!(iter.next().unwrap(), fixnum_as_cell!(Fixnum::build_with(0i64)));
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0)); assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0));
@@ -2151,7 +2327,11 @@ mod tests {
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(1i64))); wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(1i64)));
{ {
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, pstr_loc_as_cell!(0)); let mut iter = stackful_post_order_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
pstr_loc_as_cell!(0),
);
assert_eq!(iter.next().unwrap(), fixnum_as_cell!(Fixnum::build_with(1i64))); assert_eq!(iter.next().unwrap(), fixnum_as_cell!(Fixnum::build_with(1i64)));
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0)); assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_as_cell!(0));
@@ -2175,7 +2355,11 @@ mod tests {
wam.machine_st.heap.extend(functor); wam.machine_st.heap.extend(functor);
{ {
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = stackful_post_order_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),
@@ -2235,7 +2419,11 @@ mod tests {
wam.machine_st.heap[4] = list_loc_as_cell!(1); wam.machine_st.heap[4] = list_loc_as_cell!(1);
{ {
let mut iter = stackful_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = stackful_post_order_iter(
&mut wam.machine_st.heap,
&mut wam.machine_st.stack,
heap_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),
@@ -2342,7 +2530,10 @@ mod tests {
)); ));
for _ in 0..20 { for _ in 0..20 {
let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, str_loc_as_cell!(0)); let mut iter = stackless_post_order_iter(
&mut wam.machine_st.heap,
str_loc_as_cell!(0),
);
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), str_loc_as_cell!(0)); assert_eq!(unmark_cell_bits!(iter.next().unwrap()), str_loc_as_cell!(0));
@@ -2372,7 +2563,10 @@ mod tests {
{ {
wam.machine_st.heap.push(heap_loc_as_cell!(0)); wam.machine_st.heap.push(heap_loc_as_cell!(0));
let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = stackless_post_order_iter(
&mut wam.machine_st.heap,
heap_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),
@@ -2388,7 +2582,10 @@ mod tests {
wam.machine_st.heap.push(heap_loc_as_cell!(1)); wam.machine_st.heap.push(heap_loc_as_cell!(1));
wam.machine_st.heap.push(heap_loc_as_cell!(0)); wam.machine_st.heap.push(heap_loc_as_cell!(0));
let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, heap_loc_as_cell!(0)); let mut iter = stackless_post_order_iter(
&mut wam.machine_st.heap,
heap_loc_as_cell!(0),
);
assert_eq!( assert_eq!(
unmark_cell_bits!(iter.next().unwrap()), unmark_cell_bits!(iter.next().unwrap()),

View File

@@ -14,6 +14,7 @@ use crate::machine::heap::*;
use crate::machine::machine_indices::*; use crate::machine::machine_indices::*;
use crate::machine::machine_state::pstr_loc_and_offset; use crate::machine::machine_state::pstr_loc_and_offset;
use crate::machine::partial_string::*; use crate::machine::partial_string::*;
use crate::machine::stack::*;
use crate::machine::streams::*; use crate::machine::streams::*;
use crate::types::*; use crate::types::*;
@@ -474,6 +475,7 @@ pub struct HCPrinter<'a, Outputter> {
outputter: Outputter, outputter: Outputter,
iter: StackfulPreOrderHeapIter<'a>, iter: StackfulPreOrderHeapIter<'a>,
atom_tbl: &'a mut AtomTable, atom_tbl: &'a mut AtomTable,
stack: &'a Stack,
op_dir: &'a OpDir, op_dir: &'a OpDir,
state_stack: Vec<TokenOrRedirect>, state_stack: Vec<TokenOrRedirect>,
toplevel_spec: Option<DirectedOp>, toplevel_spec: Option<DirectedOp>,
@@ -539,6 +541,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
pub fn new( pub fn new(
heap: &'a mut Heap, heap: &'a mut Heap,
atom_tbl: &'a mut AtomTable, atom_tbl: &'a mut AtomTable,
stack: &'a Stack,
op_dir: &'a OpDir, op_dir: &'a OpDir,
output: Outputter, output: Outputter,
cell: HeapCellValue, cell: HeapCellValue,
@@ -547,6 +550,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
outputter: output, outputter: output,
iter: stackful_preorder_iter(heap, cell), iter: stackful_preorder_iter(heap, cell),
atom_tbl, atom_tbl,
stack,
op_dir, op_dir,
state_stack: vec![], state_stack: vec![],
toplevel_spec: None, toplevel_spec: None,
@@ -1443,12 +1447,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
) { ) {
let negated_operand = negated_op_needs_bracketing(&self.iter, self.op_dir, &op); let negated_operand = negated_op_needs_bracketing(&self.iter, self.op_dir, &op);
let addr = match self.check_for_seen() { let print_struct = |printer: &mut Self, name: Atom, arity: usize| {
Some(addr) => addr,
None => return,
};
let print_atom = |printer: &mut Self, name: Atom, arity: usize| {
if name == atom!("[]") && arity == 0 { if name == atom!("[]") && arity == 0 {
if !printer.at_cdr("") { if !printer.at_cdr("") {
append_str!(printer, "[]"); append_str!(printer, "[]");
@@ -1496,29 +1495,33 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} }
}; };
let addr = match self.check_for_seen() {
Some(addr) => addr,
None => return,
};
read_heap_cell!(addr, read_heap_cell!(addr,
(HeapCellValueTag::Atom, (name, arity)) => { (HeapCellValueTag::Atom, (name, arity)) => {
print_atom(self, name, arity); print_struct(self, name, arity);
} }
(HeapCellValueTag::Char, c) => { (HeapCellValueTag::Char, c) => {
let name = self.atom_tbl.build_with(&String::from(c)); let name = self.atom_tbl.build_with(&String::from(c));
print_atom(self, name, 0); print_struct(self, name, 0);
// print_char!(self, self.quoted, c);
} }
(HeapCellValueTag::Str, s) => { (HeapCellValueTag::Str, s) => {
let (name, arity) = cell_as_atom_cell!(self.iter.heap[s]) let (name, arity) = cell_as_atom_cell!(self.iter.heap[s])
.get_name_and_arity(); .get_name_and_arity();
if let Some(spec) = fetch_op_spec(name, arity, self.op_dir) { if let Some(spec) = fetch_op_spec(name, arity, self.op_dir) {
self.handle_op_as_struct( self.handle_op_as_struct(
name, name,
arity, arity,
&op, &op,
is_functor_redirect, is_functor_redirect,
spec, spec,
negated_operand, negated_operand,
max_depth, max_depth,
); );
} else { } else {
push_space_if_amb!(self, name.as_str(), { push_space_if_amb!(self, name.as_str(), {
self.format_clause(max_depth, arity, name, None); self.format_clause(max_depth, arity, name, None);
@@ -1553,27 +1556,27 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
} }
(HeapCellValueTag::Cons, c) => { (HeapCellValueTag::Cons, c) => {
match_untyped_arena_ptr!(c, match_untyped_arena_ptr!(c,
(ArenaHeaderTag::Integer, n) => { (ArenaHeaderTag::Integer, n) => {
self.print_number(max_depth, NumberFocus::Unfocused(Number::Integer(n)), &op); self.print_number(max_depth, NumberFocus::Unfocused(Number::Integer(n)), &op);
} }
(ArenaHeaderTag::Rational, r) => { (ArenaHeaderTag::Rational, r) => {
self.print_number(max_depth, NumberFocus::Unfocused(Number::Rational(r)), &op); self.print_number(max_depth, NumberFocus::Unfocused(Number::Rational(r)), &op);
} }
(ArenaHeaderTag::Stream, stream) => { (ArenaHeaderTag::Stream, stream) => {
self.print_stream(stream, max_depth); self.print_stream(stream, max_depth);
} }
(ArenaHeaderTag::OssifiedOpDir, _op_dir) => { (ArenaHeaderTag::OssifiedOpDir, _op_dir) => {
self.print_impromptu_atom(atom!("$ossified_op_dir")); self.print_impromptu_atom(atom!("$ossified_op_dir"));
} }
(ArenaHeaderTag::Dropped, _value) => { (ArenaHeaderTag::Dropped, _value) => {
self.print_impromptu_atom(atom!("$dropped_value")); self.print_impromptu_atom(atom!("$dropped_value"));
} }
(ArenaHeaderTag::IndexPtr, index_ptr) => { (ArenaHeaderTag::IndexPtr, index_ptr) => {
self.print_index_ptr(*index_ptr, max_depth); self.print_index_ptr(*index_ptr, max_depth);
} }
_ => { _ => {
} }
); );
} }
_ => { _ => {
unreachable!() unreachable!()
@@ -1596,6 +1599,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
pub fn print(mut self) -> Outputter { pub fn print(mut self) -> Outputter {
let spec = self.toplevel_spec.take(); let spec = self.toplevel_spec.take();
self.iter.iterate_over_machine_stack(self.stack);
self.handle_heap_term(spec, false, self.max_depth); self.handle_heap_term(spec, false, self.max_depth);
while let Some(loc_data) = self.state_stack.pop() { while let Some(loc_data) = self.state_stack.pop() {
@@ -1667,6 +1672,7 @@ mod tests {
let printer = HCPrinter::new( let printer = HCPrinter::new(
&mut wam.machine_st.heap, &mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl, &mut wam.machine_st.atom_tbl,
&wam.machine_st.stack,
&wam.op_dir, &wam.op_dir,
PrinterOutputter::new(), PrinterOutputter::new(),
heap_loc_as_cell!(0) heap_loc_as_cell!(0)
@@ -1695,6 +1701,7 @@ mod tests {
let printer = HCPrinter::new( let printer = HCPrinter::new(
&mut wam.machine_st.heap, &mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl, &mut wam.machine_st.atom_tbl,
&wam.machine_st.stack,
&wam.op_dir, &wam.op_dir,
PrinterOutputter::new(), PrinterOutputter::new(),
heap_loc_as_cell!(0) heap_loc_as_cell!(0)
@@ -1718,6 +1725,7 @@ mod tests {
let printer = HCPrinter::new( let printer = HCPrinter::new(
&mut wam.machine_st.heap, &mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl, &mut wam.machine_st.atom_tbl,
&wam.machine_st.stack,
&wam.op_dir, &wam.op_dir,
PrinterOutputter::new(), PrinterOutputter::new(),
heap_loc_as_cell!(0) heap_loc_as_cell!(0)
@@ -1730,6 +1738,7 @@ mod tests {
let mut printer = HCPrinter::new( let mut printer = HCPrinter::new(
&mut wam.machine_st.heap, &mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl, &mut wam.machine_st.atom_tbl,
&wam.machine_st.stack,
&wam.op_dir, &wam.op_dir,
PrinterOutputter::new(), PrinterOutputter::new(),
heap_loc_as_cell!(0) heap_loc_as_cell!(0)
@@ -1760,6 +1769,7 @@ mod tests {
let printer = HCPrinter::new( let printer = HCPrinter::new(
&mut wam.machine_st.heap, &mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl, &mut wam.machine_st.atom_tbl,
&wam.machine_st.stack,
&wam.op_dir, &wam.op_dir,
PrinterOutputter::new(), PrinterOutputter::new(),
heap_loc_as_cell!(0), heap_loc_as_cell!(0),
@@ -1778,6 +1788,7 @@ mod tests {
let printer = HCPrinter::new( let printer = HCPrinter::new(
&mut wam.machine_st.heap, &mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl, &mut wam.machine_st.atom_tbl,
&wam.machine_st.stack,
&wam.op_dir, &wam.op_dir,
PrinterOutputter::new(), PrinterOutputter::new(),
heap_loc_as_cell!(0), heap_loc_as_cell!(0),
@@ -1794,6 +1805,7 @@ mod tests {
let mut printer = HCPrinter::new( let mut printer = HCPrinter::new(
&mut wam.machine_st.heap, &mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl, &mut wam.machine_st.atom_tbl,
&wam.machine_st.stack,
&wam.op_dir, &wam.op_dir,
PrinterOutputter::new(), PrinterOutputter::new(),
heap_loc_as_cell!(0) heap_loc_as_cell!(0)
@@ -1823,6 +1835,7 @@ mod tests {
let mut printer = HCPrinter::new( let mut printer = HCPrinter::new(
&mut wam.machine_st.heap, &mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl, &mut wam.machine_st.atom_tbl,
&wam.machine_st.stack,
&wam.op_dir, &wam.op_dir,
PrinterOutputter::new(), PrinterOutputter::new(),
heap_loc_as_cell!(0) heap_loc_as_cell!(0)
@@ -1845,6 +1858,7 @@ mod tests {
let printer = HCPrinter::new( let printer = HCPrinter::new(
&mut wam.machine_st.heap, &mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl, &mut wam.machine_st.atom_tbl,
&wam.machine_st.stack,
&wam.op_dir, &wam.op_dir,
PrinterOutputter::new(), PrinterOutputter::new(),
pstr_loc_as_cell!(0) pstr_loc_as_cell!(0)
@@ -1872,6 +1886,7 @@ mod tests {
let printer = HCPrinter::new( let printer = HCPrinter::new(
&mut wam.machine_st.heap, &mut wam.machine_st.heap,
&mut wam.machine_st.atom_tbl, &mut wam.machine_st.atom_tbl,
&wam.machine_st.stack,
&wam.op_dir, &wam.op_dir,
PrinterOutputter::new(), PrinterOutputter::new(),
heap_loc_as_cell!(0), heap_loc_as_cell!(0),

View File

@@ -1404,7 +1404,7 @@ impl MachineState {
let term_addr = self[r]; let term_addr = self[r];
let mut term_stack = vec![]; let mut term_stack = vec![];
let mut iter = stackful_post_order_iter(&mut self.heap, term_addr); let mut iter = stackful_post_order_iter(&mut self.heap, &mut self.stack, term_addr);
while let Some(addr) = iter.next() { while let Some(addr) = iter.next() {
let addr = unmark_cell_bits!(addr); let addr = unmark_cell_bits!(addr);

View File

@@ -765,6 +765,7 @@ impl MachineState {
let mut printer = HCPrinter::new( let mut printer = HCPrinter::new(
&mut self.heap, &mut self.heap,
&mut self.atom_tbl, &mut self.atom_tbl,
&mut self.stack,
op_dir, op_dir,
PrinterOutputter::new(), PrinterOutputter::new(),
term_to_be_printed, term_to_be_printed,

View File

@@ -62,6 +62,7 @@ impl MockWAM {
let mut printer = HCPrinter::new( let mut printer = HCPrinter::new(
&mut self.machine_st.heap, &mut self.machine_st.heap,
&mut self.machine_st.atom_tbl, &mut self.machine_st.atom_tbl,
&mut self.machine_st.stack,
&self.op_dir, &self.op_dir,
PrinterOutputter::new(), PrinterOutputter::new(),
heap_loc_as_cell!(term_write_result.heap_loc), heap_loc_as_cell!(term_write_result.heap_loc),