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 0e374c2e96
commit 462097d956
4 changed files with 93 additions and 42 deletions

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::*;
@@ -72,6 +73,7 @@ fn forward_if_referent_marked(heap: &mut [HeapCellValue], h: usize) {
#[derive(Debug)] #[derive(Debug)]
pub struct StackfulPreOrderHeapIter<'a> { pub struct StackfulPreOrderHeapIter<'a> {
pub heap: &'a mut Vec<HeapCellValue>, pub heap: &'a mut Vec<HeapCellValue>,
machine_stack: Option<&'a Stack>,
stack: Vec<IterStackLoc>, stack: Vec<IterStackLoc>,
h: usize, h: usize,
} }
@@ -109,10 +111,15 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
Self { Self {
heap, heap,
h, h,
machine_stack: None,
stack: vec![IterStackLoc::iterable_heap_loc(h)], stack: vec![IterStackLoc::iterable_heap_loc(h)],
} }
} }
pub fn iterate_over_machine_stack(&mut self, stack: &'a Stack) {
self.machine_stack = Some(stack);
}
#[inline] #[inline]
pub fn push_stack(&mut self, h: usize) { pub fn push_stack(&mut self, h: usize) {
self.stack.push(IterStackLoc::iterable_heap_loc(h)); self.stack.push(IterStackLoc::iterable_heap_loc(h));
@@ -166,6 +173,26 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
} }
} }
fn stack_deref(&self, s: usize) -> Option<HeapCellValue> {
if let Some(stack) = &self.machine_stack {
let mut cell = stack[s];
while cell.is_stack_var() {
let s = cell.get_value();
if cell == stack[s] {
break;
}
cell = stack[s];
}
return Some(cell);
}
None
}
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() {
@@ -193,7 +220,14 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
continue; continue;
} }
read_heap_cell!(*cell, let cell = if cell.get_tag() == HeapCellValueTag::StackVar {
let cell = *cell;
self.stack_deref(cell.get_value()).unwrap_or(cell)
} else {
*cell
};
read_heap_cell!(cell,
(HeapCellValueTag::Str | HeapCellValueTag::PStrLoc, vh) => { (HeapCellValueTag::Str | HeapCellValueTag::PStrLoc, vh) => {
self.push_if_unmarked(vh); self.push_if_unmarked(vh);
self.stack.push(IterStackLoc::mark_heap_loc(vh)); self.stack.push(IterStackLoc::mark_heap_loc(vh));
@@ -241,7 +275,7 @@ impl<'a> StackfulPreOrderHeapIter<'a> {
return Some(self.heap[h]); return Some(self.heap[h]);
} }
_ => { _ => {
return Some(*cell); return Some(cell);
} }
) )
} }

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,
@@ -1441,12 +1445,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, "[]");
@@ -1494,14 +1493,18 @@ 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])
@@ -1594,6 +1597,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() {
@@ -1665,6 +1670,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)
@@ -1693,6 +1699,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)
@@ -1716,6 +1723,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)
@@ -1728,6 +1736,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)
@@ -1825,6 +1837,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)
@@ -1847,6 +1860,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)
@@ -1874,6 +1888,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

@@ -766,6 +766,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),