detect cyclic bindings in attr_vars_of_term (#1666)

This commit is contained in:
Mark Thom
2022-12-15 23:26:36 -07:00
parent b4b72a3166
commit 0a8fc70ba9
3 changed files with 88 additions and 79 deletions

View File

@@ -3354,71 +3354,6 @@ impl Machine {
}
}
#[inline(always)]
pub(crate) fn delete_attribute(&mut self) {
let ls0 = self.deref_register(1);
if let HeapCellValueTag::Lis = ls0.get_tag() {
let l1 = ls0.get_value();
let ls1 = self.machine_st.store(self.machine_st.deref(heap_loc_as_cell!(l1 + 1)));
if let HeapCellValueTag::Lis = ls1.get_tag() {
let l2 = ls1.get_value();
let old_addr = self.machine_st.store(self.machine_st.deref(self.machine_st.heap[l1+1]));
let tail = self.machine_st.store(self.machine_st.deref(heap_loc_as_cell!(l2 + 1)));
let tail = if tail.is_var() {
heap_loc_as_cell!(l1 + 1)
} else {
tail
};
let trail_ref = read_heap_cell!(old_addr,
(HeapCellValueTag::Var, h) => {
TrailRef::AttrVarHeapLink(h)
}
(HeapCellValueTag::Lis, l) => {
TrailRef::AttrVarListLink(l1 + 1, l)
}
_ => {
unreachable!()
}
);
self.machine_st.heap[l1 + 1] = tail;
self.machine_st.trail(trail_ref);
}
}
}
#[inline(always)]
pub(crate) fn delete_head_attribute(&mut self) {
let addr = self.deref_register(1);
debug_assert_eq!(addr.get_tag(), HeapCellValueTag::AttrVar);
let h = addr.get_value();
let addr = self.machine_st.store(self.machine_st.deref(self.machine_st.heap[h + 1]));
debug_assert_eq!(addr.get_tag(), HeapCellValueTag::Lis);
let l = addr.get_value();
let tail = self.machine_st.store(self.machine_st.deref(self.machine_st.heap[l + 1]));
let tail = if tail.is_var() {
self.machine_st.heap[h] = heap_loc_as_cell!(h);
self.machine_st.trail(TrailRef::Ref(Ref::attr_var(h)));
heap_loc_as_cell!(h + 1)
} else {
tail
};
self.machine_st.heap[h + 1] = tail;
self.machine_st.trail(TrailRef::AttrVarListLink(h + 1, l));
}
#[inline(always)]
pub(crate) fn dynamic_module_resolution(
&mut self,
@@ -3473,19 +3408,6 @@ impl Machine {
Ok((module_name, key))
}
#[inline(always)]
pub(crate) fn enqueue_attributed_var(&mut self) {
let addr = self.deref_register(1);
read_heap_cell!(addr,
(HeapCellValueTag::AttrVar, h) => {
self.machine_st.attr_var_init.attr_var_queue.push(h);
}
_ => {
}
);
}
#[inline(always)]
pub(crate) fn get_next_db_ref(&mut self) {
let a1 = self.deref_register(1);
@@ -4308,6 +4230,84 @@ impl Machine {
}
}
#[inline(always)]
pub(crate) fn enqueue_attributed_var(&mut self) {
let addr = self.deref_register(1);
read_heap_cell!(addr,
(HeapCellValueTag::AttrVar, h) => {
self.machine_st.attr_var_init.attr_var_queue.push(h);
}
_ => {
}
);
}
#[inline(always)]
pub(crate) fn delete_attribute(&mut self) {
let ls0 = self.deref_register(1);
if let HeapCellValueTag::Lis = ls0.get_tag() {
let l1 = ls0.get_value();
let ls1 = self.machine_st.store(self.machine_st.deref(heap_loc_as_cell!(l1 + 1)));
if let HeapCellValueTag::Lis = ls1.get_tag() {
let l2 = ls1.get_value();
let old_addr = self.machine_st.store(self.machine_st.deref(self.machine_st.heap[l1+1]));
let tail = self.machine_st.store(self.machine_st.deref(heap_loc_as_cell!(l2 + 1)));
let tail = if tail.is_var() {
heap_loc_as_cell!(l1 + 1)
} else {
tail
};
let trail_ref = read_heap_cell!(old_addr,
(HeapCellValueTag::Var, h) => {
TrailRef::AttrVarHeapLink(h)
}
(HeapCellValueTag::Lis, l) => {
TrailRef::AttrVarListLink(l1 + 1, l)
}
_ => {
unreachable!()
}
);
self.machine_st.heap[l1 + 1] = tail;
self.machine_st.trail(trail_ref);
}
}
}
#[inline(always)]
pub(crate) fn delete_head_attribute(&mut self) {
let addr = self.deref_register(1);
debug_assert_eq!(addr.get_tag(), HeapCellValueTag::AttrVar);
let h = addr.get_value();
let addr = self.machine_st.store(self.machine_st.deref(self.machine_st.heap[h + 1]));
debug_assert_eq!(addr.get_tag(), HeapCellValueTag::Lis);
let l = addr.get_value();
let tail = self.machine_st.store(self.machine_st.deref(self.machine_st.heap[l + 1]));
let tail = if tail.is_var() {
self.machine_st.heap[h] = heap_loc_as_cell!(h);
self.machine_st.trail(TrailRef::Ref(Ref::attr_var(h)));
heap_loc_as_cell!(h + 1)
} else {
tail
};
self.machine_st.heap[h + 1] = tail;
self.machine_st.trail(TrailRef::AttrVarListLink(h + 1, l));
}
#[inline(always)]
pub(crate) fn get_continuation_chunk(&mut self) {
let e = self.deref_register(1);