]> Repositorios git - scryer-prolog.git/commitdiff
copy partial string blocks properly in all solutions predicates
authorMark Thom <[email protected]>
Tue, 4 Mar 2025 08:17:20 +0000 (00:17 -0800)
committerMark Thom <[email protected]>
Wed, 23 Apr 2025 06:32:32 +0000 (23:32 -0700)
src/machine/heap.rs
src/machine/system_calls.rs

index fc5177403e145160937480e0d829befaa64e4768..11d0fcea6e5aef1f7c83633b85b2832dcbcf2943 100644 (file)
@@ -225,7 +225,6 @@ impl ReservedHeapSection {
             );
 
             let zero_region_idx = heap_index!(self.heap_cell_len) + str_byte_len;
-
             let align_offset = pstr_sentinel_length(zero_region_idx);
 
             ptr::write_bytes(self.heap_ptr.add(zero_region_idx), 0u8, align_offset);
@@ -266,13 +265,13 @@ impl ReservedHeapSection {
         }
 
         loop {
-            let null_char_idx = src.find('\u{0}').unwrap_or_else(|| src.len());
+            let null_char_idx = src.find('\u{0}').unwrap_or(src.len());
             let cells_written = self.push_pstr_segment(&src[0..null_char_idx]);
-            let tail_idx = self.cell_len();
 
             if cells_written == 0 {
                 return None;
             } else if null_char_idx + 1 < src.len() {
+                let tail_idx = self.cell_len();
                 self.push_cell(pstr_loc_as_cell!(heap_index!(tail_idx + 1)));
                 src = &src[null_char_idx + 1..];
             } else {
@@ -311,15 +310,15 @@ impl ReservedHeapSection {
                         &FunctorElement::Cell(cell) => {
                             section.push_cell(cell + cell_offset);
                         }
-                        &FunctorElement::String(_cell_len, ref string) => {
-                            if section.push_pstr(&string).is_some() {
+                        FunctorElement::String(_cell_len, string) => {
+                            if section.push_pstr(string).is_some() {
                                 section.push_cell(empty_list_as_cell!());
                             }
                         }
                         FunctorElement::InnerFunctor(_inner_size, succ_functor) => {
                             if cursor + 1 < functor.len() {
                                 functor_stack.push(FunctorData {
-                                    functor: &functor,
+                                    functor,
                                     cell_offset,
                                     cursor: cursor + 1,
                                 });
index 1dfd8f464642e62e44d58f4104866a978dea125e..79595d37098edb3ac6dff50f87bde1a4a9cdfa52 100644 (file)
@@ -570,6 +570,44 @@ pub(crate) struct FindallCopyInfo {
 }
 
 impl MachineState {
+    fn copy_lifted_heap_from_offset(&mut self, offset: usize, lh_offset: usize) {
+        let reserve_size = self.lifted_heap.cell_len() - lh_offset;
+        let mut writer = step_or_resource_error!(self, self.heap.reserve(reserve_size));
+
+        writer.write_with(|section| {
+            let mut lh_offset = lh_offset;
+
+            while lh_offset + 4 < self.lifted_heap.cell_len() {
+                let cell_threshold =
+                    cell_as_fixnum!(self.lifted_heap[lh_offset + 3]).get_num() as usize;
+                let pstr_upper_threshold =
+                    cell_as_fixnum!(self.lifted_heap[lh_offset + 4]).get_num() as usize;
+
+                for idx in lh_offset..cell_threshold {
+                    section.push_cell(self.lifted_heap[idx] + offset);
+                }
+
+                let mut pstr_threshold = heap_index!(cell_threshold);
+
+                while pstr_threshold < heap_index!(pstr_upper_threshold) {
+                    let HeapStringScan { string, tail_idx } =
+                        self.lifted_heap.scan_slice_to_str(pstr_threshold);
+
+                    section.push_pstr(string);
+                    section.push_cell(self.lifted_heap[tail_idx] + offset);
+
+                    pstr_threshold = heap_index!(tail_idx + 1);
+                }
+
+                lh_offset = pstr_upper_threshold;
+            }
+
+            for idx in lh_offset..self.lifted_heap.cell_len() {
+                section.push_cell(self.lifted_heap[idx] + offset);
+            }
+        });
+    }
+
     #[inline(always)]
     pub(crate) fn unattributed_var(&mut self) {
         let attr_var = self.store(self.deref(self.registers[1]));
@@ -858,13 +896,14 @@ impl MachineState {
         copy_target: HeapCellValue,
     ) -> Result<FindallCopyInfo, usize> {
         let threshold = self.lifted_heap.cell_len() - lh_offset;
-
-        let mut writer = self.lifted_heap.reserve(3)?;
+        let mut writer = self.lifted_heap.reserve(5)?;
 
         writer.write_with(|section| {
             section.push_cell(list_loc_as_cell!(threshold + 1));
-            section.push_cell(heap_loc_as_cell!(threshold + 3));
+            section.push_cell(heap_loc_as_cell!(threshold + 5));
             section.push_cell(heap_loc_as_cell!(threshold + 2));
+            section.push_cell(fixnum_as_cell!(Fixnum::build_with(0)));
+            section.push_cell(fixnum_as_cell!(Fixnum::build_with(0)));
         });
 
         let old_lifted_cell_len = self.lifted_heap.cell_len();
@@ -3946,6 +3985,12 @@ impl Machine {
             self.machine_st.lifted_heap[idx] -= self.machine_st.heap.cell_len() + lh_offset;
         }
 
+        self.machine_st.lifted_heap[old_threshold + 1] =
+            fixnum_as_cell!(Fixnum::build_with(pstr_threshold as i64));
+        self.machine_st.lifted_heap[old_threshold + 2] = fixnum_as_cell!(Fixnum::build_with(
+            self.machine_st.lifted_heap.cell_len() as i64
+        ));
+
         let mut pstr_threshold = heap_index!(pstr_threshold);
 
         while pstr_threshold < heap_index!(self.machine_st.lifted_heap.cell_len()) {
@@ -5726,38 +5771,7 @@ impl Machine {
             }
         });
 
-        /*
-        let mut addrs = vec![];
-
-        for idx in 1..num_cells + 1 {
-            let addr = self.machine_st.stack[stack_loc!(AndFrame, e, idx)];
-            let addr = self.machine_st.store(self.machine_st.deref(addr));
-
-            // avoid pushing stack variables to the heap where they
-            // must not go.
-            if addr.is_stack_var() {
-                let h = self.machine_st.heap.cell_len();
-
-                self.machine_st.heap.push(heap_loc_as_cell!(h));
-                self.machine_st.bind(Ref::heap_cell(h), addr);
-
-                addrs.push(heap_loc_as_cell!(h));
-            } else {
-                addrs.push(addr);
-            }
-        }
-        */
-
         let chunk = str_loc_as_cell!(self.machine_st.heap.cell_len());
-
-        /*
-        self.machine_st
-            .heap
-            .push(atom_as_cell!(atom!("cont_chunk"), 1 + num_cells));
-        self.machine_st.heap.push(p_functor_cell);
-        self.machine_st.heap.extend(addrs);
-        */
-
         unify!(self.machine_st, self.machine_st.registers[3], chunk);
     }
 
@@ -5774,18 +5788,7 @@ impl Machine {
             unify_fn!(self.machine_st, solutions, diff);
         } else {
             let h = self.machine_st.heap.cell_len();
-            let reserve_size = self.machine_st.lifted_heap.cell_len() - lh_offset;
-
-            let mut writer = step_or_resource_error!(
-                self.machine_st,
-                self.machine_st.heap.reserve(reserve_size)
-            );
-
-            writer.write_with(|section| {
-                for idx in lh_offset..self.machine_st.lifted_heap.cell_len() {
-                    section.push_cell(self.machine_st.lifted_heap[idx] + h);
-                }
-            });
+            self.machine_st.copy_lifted_heap_from_offset(h, lh_offset);
 
             let diff = self.machine_st.registers[3];
             unify_fn!(
@@ -5812,19 +5815,8 @@ impl Machine {
             unify_fn!(self.machine_st, solutions, empty_list_as_cell!());
         } else {
             let h = self.machine_st.heap.cell_len();
-            let reserve_size = self.machine_st.lifted_heap.cell_len() - lh_offset;
-
-            let mut writer = step_or_resource_error!(
-                self.machine_st,
-                self.machine_st.heap.reserve(reserve_size)
-            );
-
-            writer.write_with(|section| {
-                for idx in lh_offset..self.machine_st.lifted_heap.cell_len() {
-                    section.push_cell(self.machine_st.lifted_heap[idx] + h);
-                }
-            });
 
+            self.machine_st.copy_lifted_heap_from_offset(h, lh_offset);
             self.machine_st.lifted_heap.truncate(lh_offset);
 
             let solutions = self.machine_st.registers[2];