From: Mark Thom Date: Sat, 12 Apr 2025 07:22:29 +0000 (-0700) Subject: correct and simplify compute_pstr_size X-Git-Tag: v0.10.0~35^2~42 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=16b3bea48ea416edc903c604a6e1de5748cfc6b1;p=scryer-prolog.git correct and simplify compute_pstr_size --- diff --git a/src/machine/heap.rs b/src/machine/heap.rs index af26e4af..87f50732 100644 --- a/src/machine/heap.rs +++ b/src/machine/heap.rs @@ -92,7 +92,10 @@ pub struct HeapStringScan<'a> { // return the string at ptr and the tail location relative to ptr. unsafe fn scan_slice_to_str(heap_slice: &[u8]) -> HeapStringScan { - let string_len = heap_slice.iter().position(|b| *b == 0u8).unwrap(); + let string_len = heap_slice + .iter() + .position(|b| *b == 0u8) + .unwrap_or(heap_slice.len()); let zero_byte_addr = heap_slice.as_ptr().add(string_len); let sentinel_len = pstr_sentinel_length(zero_byte_addr as usize); @@ -889,44 +892,26 @@ impl Heap { /// Returns the number of bytes needed to store `src` as a `PStr`. /// Assumes the string will be allocated on a ALIGN-byte boundary. pub(crate) fn compute_pstr_size(src: &str) -> usize { - if src.is_empty() { - return 0; - } - let mut byte_size = 0; - let mut null_idx = 0; - - loop { - let src_bytes = src.as_bytes(); - - while null_idx < src_bytes.len() { - if src_bytes[null_idx] == 0u8 { - break; - } - - null_idx += 1; + let mut src_bytes = src.as_bytes(); + + while !src_bytes.is_empty() { + if src_bytes[0] == 0 { + // push a list_loc_as_cell! and null char atom to the heap and continue. + byte_size += heap_index!(2); + src_bytes = &src_bytes[1..]; + continue; } - byte_size += null_idx + pstr_sentinel_length(null_idx); - - // each partial string must be buffered from its tail cell - // by at least two null bytes so one of them may be used - // to mark partial strings e.g. during iteration - - if (null_idx + 1).next_multiple_of(ALIGN) == null_idx + 1 { - byte_size += 2 * size_of::(); - } else { - byte_size += size_of::(); - } + let HeapStringScan { string, tail_idx } = unsafe { scan_slice_to_str(src_bytes) }; - if null_idx + 1 >= src.len() { - break; - } else { - null_idx += 1; - } + src_bytes = &src_bytes[string.len()..]; + byte_size += heap_index!(tail_idx); } - byte_size + // add 1 cell to make up for the final tail cell. if src == "" it's written to the heap as + // empty_list_as_cell!() and the pstr_size is 0 + heap_index!(1). + byte_size + heap_index!(1) } pub(crate) const fn compute_functor_byte_size(functor: &[FunctorElement]) -> usize {