pub(crate) global_clock: usize,
pub(crate) dynamic_mode: FirstOrNext,
pub(crate) unify_fn: fn(&mut MachineState, Addr, Addr),
+ pub(crate) bind_fn: fn(&mut MachineState, Ref, Addr),
}
impl fmt::Debug for MachineState {
} else {
&"MachineState::unify_with_occurs_check_with_error"
})
+ .field("bind_fn",
+ if self.bind_fn as usize == MachineState::bind as usize {
+ &"MachineState::bind"
+ } else if self.bind_fn as usize == MachineState::bind_with_occurs_check_wrapper as usize {
+ &"MachineState::bind_with_occurs_check"
+ } else {
+ &"MachineState::bind_with_occurs_check_with_error_wrapper"
+ })
.finish()
}
}
global_clock: 0,
dynamic_mode: FirstOrNext::First,
unify_fn: MachineState::unify,
+ bind_fn: MachineState::bind,
}
}
}
#[inline]
- fn bind_with_occurs_check(&mut self, r: Ref, addr: Addr) -> bool {
+ pub(super) fn bind_with_occurs_check_with_error_wrapper(&mut self, r: Ref, addr: Addr) {
+ if self.bind_with_occurs_check(r, addr) {
+ let err = self.representation_error(
+ RepFlag::Term,
+ clause_name!("unify_with_occurs_check"),
+ 2,
+ );
+
+ self.throw_exception(err);
+ }
+ }
+
+ #[inline]
+ pub(super) fn bind_with_occurs_check_wrapper(&mut self, r: Ref, addr: Addr) {
+ self.bind_with_occurs_check(r, addr);
+ }
+
+ #[inline]
+ pub(super) fn bind_with_occurs_check(&mut self, r: Ref, addr: Addr) -> bool {
if let Ref::StackCell(..) = r {
// local variable optimization -- r cannot occur in the
// data structure bound to addr, so don't bother
}
Addr::Lis(l) => {
let addr = self.heap.put_constant(c.clone());
- (self.unify_fn)(self, Addr::Lis(l), addr);
+ self.unify(Addr::Lis(l), addr);
}
Addr::PStrLocation(h, n) => {
if let Constant::String(ref s2) = c {
if let Some(r) = addr.as_var() {
self.bind(r, c);
} else {
- (self.unify_fn)(self, addr, c);
+ self.unify(addr, c);
}
}
};
let h = self.heap.h();
self.heap.push(HeapCellValue::Addr(Addr::Str(h + 1)));
- self.heap
- .push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec()));
+ self.heap.push(HeapCellValue::NamedStr(arity, ct.name(), ct.spec()));
self.bind(addr.as_var().unwrap(), Addr::HeapCell(h));
self.increment_s_ptr(1);
}
MachineMode::Write => {
- let addr = self.deref(self[reg]);
+ let addr = self.store(self.deref(self[reg]));
let h = self.heap.h();
if let Addr::HeapCell(hc) = addr {
- if hc < h {
- let val = self.heap.clone(hc);
+ let val = self.heap.clone(hc);
- self.heap.push(val);
- self.increment_s_ptr(1);
+ self.heap.push(val);
+ self.increment_s_ptr(1);
- return;
- }
+ return;
}
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
- self.bind(Ref::HeapCell(h), addr);
+ (self.bind_fn)(self, Ref::HeapCell(h), addr);
}
};
}
let h = self.heap.h();
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
- self.bind(Ref::HeapCell(h), addr);
+ (self.bind_fn)(self, Ref::HeapCell(h), addr);
self.registers[arg] = self.heap[h].as_addr(h);
}
}
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h)));
- self.bind(Ref::HeapCell(h), addr);
+ (self.bind_fn)(self, Ref::HeapCell(h), addr);
}
&QueryInstruction::SetVariable(reg) => {
let h = self.heap.h();
self.heap.push(HeapCellValue::Addr(Addr::HeapCell(h + i)));
}
- self.bind(r, f_a);
+ (self.bind_fn)(self, r, f_a);
}
pub(super) fn try_functor(&mut self, op_dir: &OpDir) -> CallResult {
fn finalize_skip_max_list(&mut self, n: usize, addr: Addr) {
let target_n = self[temp_v!(1)];
- (self.unify_fn)(self, Addr::Usize(n), target_n);
+ self.unify(Addr::Usize(n), target_n);
if !self.fail {
let xs = self[temp_v!(4)];
- (self.unify_fn)(self, addr, xs);
+ self.unify(addr, xs);
}
}
let xs0 = self[temp_v!(3)];
let xs = self[temp_v!(4)];
- (self.unify_fn)(self, xs0, xs);
+ self.unify(xs0, xs);
} else {
self.skip_max_list_result(max_steps_n);
}
let xs0 = self[temp_v!(3)];
let xs = self[temp_v!(4)];
- (self.unify_fn)(self, xs0, xs);
+ self.unify(xs0, xs);
} else {
self.skip_max_list_result(max_steps_n);
}
}
&SystemClauseType::SetSTOAsUnify => {
self.unify_fn = MachineState::unify_with_occurs_check;
+ self.bind_fn = MachineState::bind_with_occurs_check_wrapper;
}
&SystemClauseType::SetNSTOAsUnify => {
self.unify_fn = MachineState::unify;
+ self.bind_fn = MachineState::bind;
}
&SystemClauseType::SetSTOWithErrorAsUnify => {
self.unify_fn = MachineState::unify_with_occurs_check_with_error;
+ self.bind_fn = MachineState::bind_with_occurs_check_with_error_wrapper;
}
&SystemClauseType::HomeDirectory => {
let path = match dirs_next::home_dir() {