From 3f1cfd29957dc0b71e404b9eadca0c9aa476f748 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 28 Feb 2021 16:19:06 -0700 Subject: [PATCH] introduce bind_fn, use in applicable Fact/Query instructions (#841) --- src/machine/machine_state.rs | 9 ++++++ src/machine/machine_state_impl.rs | 48 ++++++++++++++++++++----------- src/machine/system_calls.rs | 11 ++++--- 3 files changed, 48 insertions(+), 20 deletions(-) diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index 77a0d368..ee48340a 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -304,6 +304,7 @@ pub(crate) struct MachineState { 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 { @@ -343,6 +344,14 @@ 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() } } diff --git a/src/machine/machine_state_impl.rs b/src/machine/machine_state_impl.rs index 6ca1341a..b1d8dde7 100644 --- a/src/machine/machine_state_impl.rs +++ b/src/machine/machine_state_impl.rs @@ -57,6 +57,7 @@ impl MachineState { global_clock: 0, dynamic_mode: FirstOrNext::First, unify_fn: MachineState::unify, + bind_fn: MachineState::bind, } } @@ -154,7 +155,25 @@ impl MachineState { } #[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 @@ -871,7 +890,7 @@ impl MachineState { } 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 { @@ -889,7 +908,7 @@ impl MachineState { if let Some(r) = addr.as_var() { self.bind(r, c); } else { - (self.unify_fn)(self, addr, c); + self.unify(addr, c); } } }; @@ -1222,8 +1241,7 @@ impl MachineState { 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)); @@ -1283,22 +1301,20 @@ impl MachineState { 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); } }; } @@ -1569,7 +1585,7 @@ impl MachineState { 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); } @@ -1611,7 +1627,7 @@ impl MachineState { } 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(); @@ -2466,7 +2482,7 @@ impl MachineState { 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 { diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index 6793c085..dfe0411f 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -253,11 +253,11 @@ impl MachineState { 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); } } @@ -313,7 +313,7 @@ impl MachineState { 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); } @@ -323,7 +323,7 @@ impl MachineState { 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); } @@ -5456,12 +5456,15 @@ impl MachineState { } &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() { -- 2.54.0