From a562793fce2f53c45fe00adaaf629ba1cd62dba1 Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Mon, 24 Jan 2022 18:47:53 -0700 Subject: [PATCH] don't read into the heap while incrementing self.s (#1233, #1245) --- src/examples/least_time.pl | 10 +-- src/machine/dispatch.rs | 16 +++-- src/machine/machine_state.rs | 1 + src/machine/machine_state_impl.rs | 100 ++++++++++++++++-------------- src/machine/partial_string.rs | 22 ------- 5 files changed, 71 insertions(+), 78 deletions(-) diff --git a/src/examples/least_time.pl b/src/examples/least_time.pl index 06eccd31..2b599b60 100644 --- a/src/examples/least_time.pl +++ b/src/examples/least_time.pl @@ -11,7 +11,7 @@ */ :- module(least_time, [find_min_time/2, - write_time_nl/1]). + write_time_nl/1]). :- use_module(library(dcgs)). @@ -27,10 +27,10 @@ valid_time([H1,H2,M1,M2], T) :- memberd_t(M2, [0,1,2,3,4,5,6,7,8,9], TM2), ( maplist(=(true), [TH1, TH2, TM1, TM2]) -> ( H1 =:= 2 -> - ( H2 =< 3 -> - T = true - ; T = false - ) + ( H2 =< 3 -> + T = true + ; T = false + ) ; T = true ) ; T = false diff --git a/src/machine/dispatch.rs b/src/machine/dispatch.rs index 546781c7..4c02ea8b 100644 --- a/src/machine/dispatch.rs +++ b/src/machine/dispatch.rs @@ -2769,6 +2769,7 @@ impl Machine { let (h, n) = pstr_loc_and_offset(&self.machine_st.heap, h); self.machine_st.s = HeapPtr::PStrChar(h, n.get_num() as usize); + self.machine_st.s_offset = 0; self.machine_st.mode = MachineMode::Read; } (HeapCellValueTag::CStr) => { @@ -2776,10 +2777,12 @@ impl Machine { self.machine_st.heap.push(store_v); self.machine_st.s = HeapPtr::PStrChar(h, 0); + self.machine_st.s_offset = 0; self.machine_st.mode = MachineMode::Read; } (HeapCellValueTag::Lis, l) => { self.machine_st.s = HeapPtr::HeapCell(l); + self.machine_st.s_offset = 0; self.machine_st.mode = MachineMode::Read; } (HeapCellValueTag::AttrVar | HeapCellValueTag::Var | HeapCellValueTag::StackVar) => { @@ -2827,6 +2830,7 @@ impl Machine { (HeapCellValueTag::Atom, (result_name, result_arity)) => { if arity == result_arity && name == result_name { self.machine_st.s = HeapPtr::HeapCell(a + 1); + self.machine_st.s_offset = 0; self.machine_st.mode = MachineMode::Read; } else { self.machine_st.backtrack(); @@ -2883,7 +2887,7 @@ impl Machine { self.machine_st.backtrack(); continue; } else { - self.machine_st.increment_s_ptr(1); + self.machine_st.s_offset += 1; } } MachineMode::Write => { @@ -2905,7 +2909,7 @@ impl Machine { self.machine_st.backtrack(); continue; } else { - self.machine_st.increment_s_ptr(1); + self.machine_st.s_offset += 1; } } MachineMode::Write => { @@ -2917,7 +2921,7 @@ impl Machine { let value = self.machine_st.heap[hc]; self.machine_st.heap.push(value); - self.machine_st.increment_s_ptr(1); + self.machine_st.s_offset += 1; } _ => { self.machine_st.heap.push(heap_loc_as_cell!(h)); @@ -2937,7 +2941,7 @@ impl Machine { match self.machine_st.mode { MachineMode::Read => { self.machine_st[reg] = self.machine_st.read_s(); - self.machine_st.increment_s_ptr(1); + self.machine_st.s_offset += 1; } MachineMode::Write => { let h = self.machine_st.heap.len(); @@ -2961,7 +2965,7 @@ impl Machine { self.machine_st.backtrack(); continue; } else { - self.machine_st.increment_s_ptr(1); + self.machine_st.s_offset += 1; } } MachineMode::Write => { @@ -2988,7 +2992,7 @@ impl Machine { &Instruction::UnifyVoid(n) => { match self.machine_st.mode { MachineMode::Read => { - self.machine_st.increment_s_ptr(n); + self.machine_st.s_offset += n; } MachineMode::Write => { let h = self.machine_st.heap.len(); diff --git a/src/machine/machine_state.rs b/src/machine/machine_state.rs index 11b2672a..27a35884 100644 --- a/src/machine/machine_state.rs +++ b/src/machine/machine_state.rs @@ -55,6 +55,7 @@ pub struct MachineState { pub arena: Arena, pub(super) pdl: Vec, pub(super) s: HeapPtr, + pub(super) s_offset: usize, pub(super) p: usize, pub(super) oip: u32, // first internal code ptr pub(super) iip : u32, // second internal code ptr diff --git a/src/machine/machine_state_impl.rs b/src/machine/machine_state_impl.rs index 6461f7f0..373f8704 100644 --- a/src/machine/machine_state_impl.rs +++ b/src/machine/machine_state_impl.rs @@ -28,6 +28,7 @@ impl MachineState { atom_tbl: AtomTable::new(), pdl: Vec::with_capacity(1024), s: HeapPtr::default(), + s_offset: 0, p: 0, oip: 0, iip: 0, @@ -77,6 +78,7 @@ impl MachineState { ) } + #[inline] pub fn deref(&self, mut addr: HeapCellValue) -> HeapCellValue { loop { let value = self.store(addr); @@ -1390,28 +1392,25 @@ impl MachineState { } pub(crate) fn read_s(&mut self) -> HeapCellValue { - match &self.s { - &HeapPtr::HeapCell(h) => self.deref(self.heap[h]), - &HeapPtr::PStrChar(h, n) => { + match &mut self.s { + &mut HeapPtr::HeapCell(h) => self.deref(self.heap[h + self.s_offset]), + &mut HeapPtr::PStrChar(h, n) if self.s_offset == 0 => { read_heap_cell!(self.heap[h], (HeapCellValueTag::PStr, pstr_atom) => { let pstr = PartialString::from(pstr_atom); if let Some(c) = pstr.as_str_from(n).chars().next() { char_as_cell!(c) - } else { // if has_tail { - self.deref(self.heap[h+1]) // heap_loc_as_cell!(h+1) + } else { + self.deref(self.heap[h+1]) } - // } else { - // empty_list_as_cell!() - // } } (HeapCellValueTag::CStr, cstr_atom) => { let pstr = PartialString::from(cstr_atom); if let Some(c) = pstr.as_str_from(n).chars().next() { char_as_cell!(c) - } else { // if has_tail { + } else { empty_list_as_cell!() } } @@ -1420,14 +1419,25 @@ impl MachineState { } ) } - &HeapPtr::PStrLocation(h, n) => { + &mut HeapPtr::PStrChar(h, ref mut n) | + &mut HeapPtr::PStrLocation(h, ref mut n) => { read_heap_cell!(self.heap[h], (HeapCellValueTag::PStr, pstr_atom) => { - if n < pstr_atom.len() { + let pstr = PartialString::from(pstr_atom); + let n_offset: usize = pstr.as_str_from(*n) + .chars() + .take(self.s_offset) + .map(|c| c.len_utf8()) + .sum(); + + self.s_offset = 0; + *n += n_offset; + + if *n < pstr_atom.len() { let h_len = self.heap.len(); self.heap.push(pstr_offset_as_cell!(h)); - self.heap.push(fixnum_as_cell!(Fixnum::build_with(n as i64))); + self.heap.push(fixnum_as_cell!(Fixnum::build_with(*n as i64))); pstr_loc_as_cell!(h_len) } else { @@ -1435,11 +1445,21 @@ impl MachineState { } } (HeapCellValueTag::CStr, cstr_atom) => { - if n < cstr_atom.len() { + let pstr = PartialString::from(cstr_atom); + let n_offset: usize = pstr.as_str_from(*n) + .chars() + .take(self.s_offset) + .map(|c| c.len_utf8()) + .sum(); + + self.s_offset = 0; + *n += n_offset; + + if *n < cstr_atom.len() { let h_len = self.heap.len(); self.heap.push(pstr_offset_as_cell!(h)); - self.heap.push(fixnum_as_cell!(Fixnum::build_with(n as i64))); + self.heap.push(fixnum_as_cell!(Fixnum::build_with(*n as i64))); pstr_loc_as_cell!(h_len) } else { @@ -1821,30 +1841,6 @@ impl MachineState { Some(Ordering::Equal) } - pub(crate) fn increment_s_ptr(&mut self, rhs: usize) { - match &mut self.s { - HeapPtr::HeapCell(ref mut h) => { - *h += rhs; - } - &mut HeapPtr::PStrChar(h, ref mut n) | &mut HeapPtr::PStrLocation(h, ref mut n) => { - read_heap_cell!(self.heap[h], - (HeapCellValueTag::PStr | HeapCellValueTag::CStr, pstr_atom) => { - let pstr = PartialString::from(pstr_atom); - - for c in pstr.as_str_from(*n).chars().take(rhs) { - *n += c.len_utf8(); - } - - self.s = HeapPtr::PStrLocation(h, *n); - } - _ => { - unreachable!() - } - ) - } - } - } - pub fn match_partial_string(&mut self, value: HeapCellValue, string: Atom, has_tail: bool) { let h = self.heap.len(); self.heap.push(value); @@ -1860,23 +1856,35 @@ impl MachineState { (HeapCellValueTag::PStr | HeapCellValueTag::CStr, pstr_atom) => { if has_tail { self.s = HeapPtr::PStrLocation(focus, offset); + self.s_offset = 0; self.mode = MachineMode::Read; } else if offset == pstr_atom.len() { - let focus_addr = heap_pstr_iter.focus; - unify!(self, focus_addr, empty_list_as_cell!()); + let focus = heap_pstr_iter.focus; + unify!(self, focus, empty_list_as_cell!()); } else { self.fail = true; } } (HeapCellValueTag::PStrLoc | HeapCellValueTag::PStrOffset, h) => { - if has_tail { - let (h, _) = pstr_loc_and_offset(&self.heap, h); + let (focus, _) = pstr_loc_and_offset(&self.heap, h); + let pstr_atom = read_heap_cell!(self.heap[focus], + (HeapCellValueTag::CStr | HeapCellValueTag::PStr, pstr_atom) => { + pstr_atom + } + _ => { + unreachable!() + } + ); - self.s = HeapPtr::PStrLocation(h, offset); + if has_tail { + self.s = HeapPtr::PStrLocation(focus, offset); + self.s_offset = 0; self.mode = MachineMode::Read; + } else if offset == pstr_atom.len() { + let focus = heap_pstr_iter.focus; + unify!(self, focus, empty_list_as_cell!()); } else { - let end_cell = heap_pstr_iter.focus; - self.fail = end_cell != empty_list_as_cell!(); + self.fail = true; } } _ => { @@ -1884,6 +1892,7 @@ impl MachineState { if has_tail { self.s = HeapPtr::HeapCell(focus); + self.s_offset = 0; self.mode = MachineMode::Read; } else { let focus = heap_pstr_iter.focus; @@ -1900,6 +1909,7 @@ impl MachineState { let target_cell = if has_tail { self.s = HeapPtr::HeapCell(h + 1); + self.s_offset = 0; self.mode = MachineMode::Read; put_partial_string( diff --git a/src/machine/partial_string.rs b/src/machine/partial_string.rs index ed1ad919..42184297 100644 --- a/src/machine/partial_string.rs +++ b/src/machine/partial_string.rs @@ -499,28 +499,6 @@ impl<'a> Iterator for PStrCharsIter<'a> { } } - /* - if !self.iter.at_string_terminator() { - // at a cycle. emit the final character. - match self.iter.step(self.iter.brent_st.hare) { - Some(PStrIterStep { iteratee: PStrIteratee::Char(_, c), .. }) => { - self.iter.focus = empty_list_as_cell!(); - return Some(c); - } - Some(PStrIterStep { iteratee: PStrIteratee::PStrSegment(_, pstr_atom, _), .. }) => { - self.iter.focus = empty_list_as_cell!(); - - let c = PartialString::from(pstr_atom).as_str_from(0).chars().next().unwrap(); - return Some(c); - } - _ => { - self.iter.focus = empty_list_as_cell!(); - return None; - } - } - } - */ - None } } -- 2.54.0