]> Repositorios git - scryer-prolog.git/commitdiff
Add scan_slice_to_str_from_start
authorbakaq <[email protected]>
Mon, 5 May 2025 00:01:50 +0000 (21:01 -0300)
committerMark Thom <[email protected]>
Tue, 8 Jul 2025 05:38:12 +0000 (22:38 -0700)
src/machine/heap.rs

index 8d832f291937c0f7a495bfa97e7eaa5df7a5f1fc..7711b3b2c31e5672889cf2c5e71663852ad3b80a 100644 (file)
@@ -89,7 +89,7 @@ pub struct HeapStringScan<'a> {
     pub tail_idx: usize,
 }
 
-// return the string at ptr and the tail location relative to ptr.
+// The heap_slice should be inside the heap
 unsafe fn scan_slice_to_str(heap_slice: &[u8]) -> HeapStringScan {
     let string_len = heap_slice
         .iter()
@@ -111,6 +111,28 @@ unsafe fn scan_slice_to_str(heap_slice: &[u8]) -> HeapStringScan {
     }
 }
 
+// Same as scan_slice_to_str but assumes that the slice is from the start of a string.
+// Can be used on strings out of the heap.
+unsafe fn scan_slice_to_str_from_start(heap_slice: &[u8]) -> HeapStringScan {
+    let string_len = heap_slice
+        .iter()
+        .position(|b| *b == 0u8)
+        .unwrap_or(heap_slice.len());
+
+    let sentinel_len = pstr_sentinel_length(string_len);
+    let tail_idx = cell_index!(
+        (string_len + sentinel_len).next_multiple_of(ALIGN)
+            + if sentinel_len <= 1 { heap_index!(1) } else { 0 }
+    );
+
+    let str_slice = &heap_slice[..string_len];
+
+    HeapStringScan {
+        string: std::str::from_utf8_unchecked(str_slice),
+        tail_idx,
+    }
+}
+
 #[derive(Debug, Clone, Copy)]
 pub(crate) enum PStrContinuable {
     PStrOffset(usize),
@@ -904,7 +926,8 @@ impl Heap {
                 continue;
             }
 
-            let HeapStringScan { string, tail_idx } = unsafe { scan_slice_to_str(src_bytes) };
+            let HeapStringScan { string, tail_idx } =
+                unsafe { scan_slice_to_str_from_start(src_bytes) };
 
             src_bytes = &src_bytes[string.len()..];
             byte_size += heap_index!(tail_idx);