1use polka::Value;
2use alloc::{string::String, vec::Vec};
3use crate::memory::Heap;
4
5#[inline]
11pub fn string_word_count(byte_len: usize) -> usize {
12 1 + (byte_len + 7) / 8
13}
14
15pub fn alloc_string(heap: &mut Heap, s: &str) -> Result<Value, String> {
16 let bytes = s.as_bytes();
17 let size = string_word_count(bytes.len());
18 let (slot, gen_) = heap.try_alloc(size)?;
19 let dst = heap.cell_data_mut(slot, gen_)?;
20 dst[0] = bytes.len() as u64;
21 if !bytes.is_empty() {
22 let dst_ptr = dst[1..].as_mut_ptr() as *mut u8;
23 unsafe { core::ptr::copy_nonoverlapping(bytes.as_ptr(), dst_ptr, bytes.len()); }
24 }
25 Ok(Value::from_handle(slot, gen_))
26}
27
28pub fn read_string(heap: &Heap, val: Value) -> Option<String> {
29 if val.is_handle_none() { return None; }
30 let (slot, gen_) = val.as_handle();
31 let data = heap.cell_data(slot, gen_).ok()?;
32 if data.is_empty() { return None; }
33 let len = data[0] as usize;
34 let mut out = Vec::with_capacity(len);
35 let mut remaining = len;
36 for i in 1..data.len() {
37 if remaining == 0 { break; }
38 let word = data[i].to_le_bytes();
39 let take = remaining.min(8);
40 out.extend_from_slice(&word[..take]);
41 remaining -= take;
42 }
43 String::from_utf8(out).ok()
44}