}
impl<Iter: FocusedHeapIter> FocusedHeapIter for PostOrderIterator<Iter> {
- #[inline]
+ #[inline(always)]
fn focus(&self) -> usize {
self.focus
}
}
+impl<Iter: FocusedHeapIter> PostOrderIterator<Iter> {
+ /* return true if the term at heap offset idx_loc is a
+ * direct/inlined subterm of a structure at the focus of
+ * self.stack.last(). this function is used to determine, e.g.,
+ * ownership of inlined code indices.
+ */
+ #[inline]
+ pub(crate) fn direct_subterm_of_str(&self, idx_loc: usize) -> bool {
+ if let Some((_child_count, item, focus)) = self.parent_stack.last() {
+ read_heap_cell!(item,
+ (HeapCellValueTag::Atom, (_name, arity)) => {
+ return focus + arity >= idx_loc && *focus < idx_loc;
+ }
+ _ => {}
+ );
+ }
+
+ false
+ }
+}
+
pub(crate) type LeftistPostOrderHeapIter<'a> = PostOrderIterator<StackfulPreOrderHeapIter<'a>>;
impl<'a> LeftistPostOrderHeapIter<'a> {
let value = iter.heap[h + arity + 1];
if let Some(idx) = get_structure_index(value) {
- term_stack.push(
- Term::Literal(Cell::default(), Literal::CodeIndex(idx))
- );
+ // in the second condition, arity == 0,
+ // meaning idx cannot pertain to this atom
+ // if it is the direct subterm of a larger
+ // structure.
+ if arity > 0 || !iter.direct_subterm_of_str(h) {
+ term_stack.push(
+ Term::Literal(Cell::default(), Literal::CodeIndex(idx))
+ );
- arity += 1;
+ arity += 1;
+ }
}
}