From ca27234275137715c2712114291661bf2a7940ec Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Tue, 15 Oct 2019 22:54:12 -0600 Subject: [PATCH] deallocate old stack frames (#201), start using tags, fix a panic! associated with partial strings --- Cargo.toml | 2 +- src/prolog/machine/and_stack.rs | 5 +++ src/prolog/machine/machine_state.rs | 9 +++++- src/prolog/machine/machine_state_impl.rs | 41 +++++++++++++++++------- 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b6d1fe8f..e58b5f87 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "scryer-prolog" -version = "0.8.109" +version = "0.8.110" authors = ["Mark Thom "] build = "build.rs" repository = "https://github.com/mthom/scryer-prolog" diff --git a/src/prolog/machine/and_stack.rs b/src/prolog/machine/and_stack.rs index 4f0d63f3..3a16f5c0 100644 --- a/src/prolog/machine/and_stack.rs +++ b/src/prolog/machine/and_stack.rs @@ -66,6 +66,11 @@ impl AndStack { } } } + + #[inline] + pub fn truncate(&mut self, len: usize) { + self.0.truncate(len); + } } impl Index for AndStack { diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index dc1051d6..813face9 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -419,11 +419,12 @@ pub(crate) trait CallPolicy: Any { machine_st.registers[i] = machine_st.or_stack[b][i].clone(); } - // necessary because of restore_snapshot. similarly for other choice instructions. machine_st.num_of_args = n; machine_st.e = machine_st.or_stack[b].e; machine_st.cp = machine_st.or_stack[b].cp.clone(); + machine_st.pop_stack_frames(); + machine_st.or_stack[b].bp = machine_st.p.clone() + offset; let old_tr = machine_st.or_stack[b].tr; @@ -468,6 +469,8 @@ pub(crate) trait CallPolicy: Any { machine_st.e = machine_st.or_stack[b].e; machine_st.cp = machine_st.or_stack[b].cp.clone(); + machine_st.pop_stack_frames(); + machine_st.or_stack[b].bp = machine_st.p.clone() + 1; let old_tr = machine_st.or_stack[b].tr; @@ -539,6 +542,8 @@ pub(crate) trait CallPolicy: Any { machine_st.b = machine_st.or_stack[b].b; machine_st.or_stack.truncate(machine_st.b); + machine_st.pop_stack_frames(); + machine_st.hb = machine_st.heap.h; machine_st.p += offset; @@ -584,6 +589,8 @@ pub(crate) trait CallPolicy: Any { machine_st.b = machine_st.or_stack[b].b; machine_st.or_stack.truncate(machine_st.b); + machine_st.pop_stack_frames(); + machine_st.hb = machine_st.heap.h; machine_st.p += 1; diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 4709a662..60587300 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -173,7 +173,7 @@ impl MachineState { } _ => { self.push_attr_var_binding(h, addr.clone()); - self.heap[h] = HeapCellValue::Addr(addr); + self.heap[h] = HeapCellValue::Addr(addr); self.trail(TrailRef::Ref(Ref::AttrVar(h))); } } @@ -1665,7 +1665,7 @@ impl MachineState { } else if s.is_expandable() { self.heap .push(HeapCellValue::Addr(Addr::Con(Constant::String(s.clone())))); - + self.s = h; self.mode = MachineMode::Read; } else { @@ -1711,8 +1711,8 @@ impl MachineState { _ => self.fail = true, }, addr @ Addr::AttrVar(_) - | addr @ Addr::StackCell(..) - | addr @ Addr::HeapCell(_) => { + | addr @ Addr::StackCell(..) + | addr @ Addr::HeapCell(_) => { let h = self.heap.h; self.heap.push(HeapCellValue::Addr(Addr::Lis(h + 1))); @@ -1860,8 +1860,12 @@ impl MachineState { let offset = match addr { Addr::HeapCell(_) | Addr::StackCell(..) | Addr::AttrVar(..) => v, Addr::Con(Constant::String(ref s)) if !self.flags.double_quotes.is_atom() => { - if s.is_empty() && !s.is_expandable() { - c + if s.is_empty() { + if s.is_expandable() { + v + } else { + c + } } else { l } @@ -1883,7 +1887,7 @@ impl MachineState { &IndexingInstruction::SwitchOnConstant(_, ref hm) => { let a1 = self.registers[1].clone(); let addr = self.store(self.deref(a1)); - + let offset = match addr { Addr::Con(constant) => match hm.get(&constant) { Some(offset) => *offset, @@ -2058,7 +2062,7 @@ impl MachineState { for i in 1..narity + 1 { self.registers[i] = self.heap[a + i].as_addr(a + i); } - + (name, narity) } else { self.fail = true; @@ -2268,7 +2272,7 @@ impl MachineState { (HeapCellValue::Addr(a1), HeapCellValue::Addr(a2)) => if a1 != a2 { return true; - }, + }, _ => return true, } } @@ -3111,7 +3115,7 @@ impl MachineState { let gi = self.next_global_index(); self.p += 1; - + if self.e + 1 < self.and_stack.len() { let and_gi = self.and_stack[self.e].global_index; let or_gi = self @@ -3147,6 +3151,21 @@ impl MachineState { self.p += 1; } + pub(super) fn pop_stack_frames(&mut self) { + if self.and_stack.len() > self.e { + let and_gi = self.and_stack[self.e].global_index; + let or_gi = self + .or_stack + .top() + .map(|or_fr| or_fr.global_index) + .unwrap_or(0); + + if and_gi > or_gi { + self.and_stack.truncate(self.e + 1); + } + } + } + fn handle_call_clause( &mut self, indices: &mut IndexStore, @@ -3166,7 +3185,7 @@ impl MachineState { self.fail = true; return; } - + let mut default_call_policy: Box = Box::new(DefaultCallPolicy {}); let call_policy = if use_default_cp { &mut default_call_policy -- 2.54.0