trame_runtime/live/
mod.rs1use crate::{IArena, IField, IHeap, IRuntime, IShape, IShapeStore, IStructType, Idx};
5use facet_core::{Field, Shape, StructType, Type, UserType};
6
7pub struct LRuntime;
9
10impl IRuntime for LRuntime {
11 type Shape = &'static Shape;
12 type Heap = LHeap;
13 type Arena<T> = LArena<T>;
14
15 fn heap() -> Self::Heap {
16 LHeap::new()
17 }
18
19 fn arena<T>() -> Self::Arena<T> {
20 LArena::new()
21 }
22}
23
24#[derive(Clone, Copy, Default)]
30pub struct LShapeStore;
31
32impl IShapeStore for LShapeStore {
33 type Handle = &'static Shape;
34 type View<'a>
35 = &'static Shape
36 where
37 Self: 'a;
38
39 fn get<'a>(&'a self, handle: Self::Handle) -> Self::View<'a> {
40 handle
41 }
42}
43
44impl IShape for &'static Shape {
45 type StructType = &'static StructType;
46 type Field = &'static Field;
47
48 #[inline]
49 fn layout(&self) -> Option<std::alloc::Layout> {
50 self.layout.sized_layout().ok()
51 }
52
53 #[inline]
54 fn is_struct(&self) -> bool {
55 matches!(self.ty, Type::User(UserType::Struct(_)))
56 }
57
58 #[inline]
59 fn as_struct(&self) -> Option<Self::StructType> {
60 match &self.ty {
61 Type::User(UserType::Struct(st)) => Some(st),
62 _ => None,
63 }
64 }
65}
66
67impl IStructType for &'static StructType {
68 type Field = &'static Field;
69
70 #[inline]
71 fn field_count(&self) -> usize {
72 self.fields.len()
73 }
74
75 #[inline]
76 fn field(&self, idx: usize) -> Option<Self::Field> {
77 self.fields.get(idx)
78 }
79}
80
81impl IField for &'static Field {
82 type Shape = &'static Shape;
83
84 #[inline]
85 fn offset(&self) -> usize {
86 self.offset
87 }
88
89 #[inline]
90 fn shape(&self) -> Self::Shape {
91 self.shape.get()
92 }
93}
94
95#[derive(Debug)]
101pub struct LHeap;
102
103impl LHeap {
104 pub const fn new() -> Self {
106 Self
107 }
108}
109
110impl Default for LHeap {
111 fn default() -> Self {
112 Self::new()
113 }
114}
115
116impl IHeap<&'static Shape> for LHeap {
117 type Ptr = *mut u8;
118
119 unsafe fn alloc(&mut self, shape: &'static Shape) -> *mut u8 {
120 let layout = shape.layout();
121 if let Some(layout) = layout {
122 if layout.size() == 0 {
123 core::ptr::NonNull::dangling().as_ptr()
131 } else {
132 let ptr = unsafe { std::alloc::alloc(layout) };
134 if ptr.is_null() {
135 std::alloc::handle_alloc_error(layout);
136 }
137 ptr
138 }
139 } else {
140 core::ptr::NonNull::dangling().as_ptr()
142 }
143 }
144
145 unsafe fn dealloc(&mut self, ptr: *mut u8, shape: &'static Shape) {
146 if let Some(layout) = shape.layout() {
147 if layout.size() > 0 {
148 unsafe { std::alloc::dealloc(ptr, layout) };
150 }
151 }
152 }
153
154 unsafe fn memcpy(&mut self, dst: *mut u8, src: *mut u8, len: usize) {
155 if len > 0 {
156 unsafe {
158 core::ptr::copy_nonoverlapping(src, dst, len);
159 }
160 }
161 }
162
163 unsafe fn drop_in_place(&mut self, ptr: *mut u8, shape: &'static Shape) {
164 unsafe { shape.call_drop_in_place(facet_core::PtrMut::new(ptr)) };
165 }
166
167 unsafe fn default_in_place(&mut self, ptr: *mut u8, shape: &'static Shape) -> bool {
168 unsafe {
169 shape
170 .call_default_in_place(facet_core::PtrMut::new(ptr).into())
171 .is_some()
172 }
173 }
174}
175
176pub struct LArena<T> {
182 slots: Vec<Option<T>>,
183 free_list: Vec<u32>,
184}
185
186impl<T> LArena<T> {
187 pub fn new() -> Self {
189 Self {
190 slots: vec![None], free_list: Vec::new(),
192 }
193 }
194}
195
196impl<T> Default for LArena<T> {
197 fn default() -> Self {
198 Self::new()
199 }
200}
201
202impl<T> IArena<T> for LArena<T> {
203 fn alloc(&mut self, value: T) -> Idx<T> {
204 let raw = if let Some(idx) = self.free_list.pop() {
205 debug_assert!(self.slots[idx as usize].is_none());
206 self.slots[idx as usize] = Some(value);
207 idx
208 } else {
209 let idx = self.slots.len();
210 assert!(idx < u32::MAX as usize, "arena full");
211 self.slots.push(Some(value));
212 idx as u32
213 };
214 Idx::from_raw(raw)
215 }
216
217 fn free(&mut self, id: Idx<T>) -> T {
218 debug_assert!(id.is_valid());
219 let value = self.slots[id.index()].take().expect("double-free");
220 self.free_list.push(id.raw);
221 value
222 }
223
224 fn get(&self, id: Idx<T>) -> &T {
225 debug_assert!(id.is_valid());
226 self.slots[id.index()].as_ref().expect("slot empty")
227 }
228
229 fn get_mut(&mut self, id: Idx<T>) -> &mut T {
230 debug_assert!(id.is_valid());
231 self.slots[id.index()].as_mut().expect("slot empty")
232 }
233}
234
235#[cfg(test)]
236mod tests;