MCPcopy Create free account
hub / github.com/Bloom-Engine/engine / alloc_perry_string

Function alloc_perry_string

native/watchos/src/lib.rs:58–87  ·  view source on GitHub ↗

Allocate a Perry-side heap string (StringHeader + UTF-8 payload) and return its pointer as the i64 the FFI boundary expects. Mirrors `perry_str`'s layout so a string we hand back is read identically to one Perry passed us. Returning this (never 0) for a `returns:"string"` function is mandatory: Perry's inline `.length` dereferences the pointer, so a null segfaults the caller.

(s: &str)

Source from the content-addressed store, hash-verified

56/// Perry's inline `.length` dereferences the pointer, so a null segfaults the
57/// caller.
58fn alloc_perry_string(s: &str) -> i64 {
59 let bytes = s.as_bytes();
60 let byte_len = bytes.len();
61 let utf16_len = if bytes.iter().all(|&b| b < 0x80) {
62 byte_len
63 } else {
64 s.encode_utf16().count()
65 };
66 // A value RETURNED across the FFI boundary is consumed by Perry's internal
67 // string machinery, whose canonical StringHeader is 5×u32 = 20 bytes
68 // (utf16_len, byte_len, capacity, refcount, flags) with data at +20.
69 // (The local 16-byte `StringHeader`/`perry_str` above describe the *incoming*
70 // arg representation, which omits `flags`; don't conflate the two.)
71 const HEADER_SIZE: usize = 20;
72 let total = HEADER_SIZE + byte_len;
73 unsafe {
74 let layout = std::alloc::Layout::from_size_align(total, 4).unwrap();
75 let ptr = std::alloc::alloc(layout);
76 if ptr.is_null() {
77 return 0;
78 }
79 *(ptr.add(0) as *mut u32) = utf16_len as u32;
80 *(ptr.add(4) as *mut u32) = byte_len as u32;
81 *(ptr.add(8) as *mut u32) = byte_len as u32; // capacity
82 *(ptr.add(12) as *mut u32) = 1; // refcount = unique
83 *(ptr.add(16) as *mut u32) = 0; // flags
84 std::ptr::copy_nonoverlapping(bytes.as_ptr(), ptr.add(HEADER_SIZE), byte_len);
85 ptr as i64
86 }
87}
88
89use std::ffi::{c_char, c_void};
90use std::sync::atomic::{AtomicI64, AtomicU64, AtomicUsize, Ordering};

Callers 4

bloom_read_fileFunction · 0.70
bloom_read_fileFunction · 0.50

Calls 4

allMethod · 0.80
iterMethod · 0.80
as_ptrMethod · 0.80
countMethod · 0.45

Tested by

no test coverage detected