monkey_asm/
runtime_backend.rs1#[cfg(not(target_family = "wasm"))]
12use std::collections::HashMap;
13
14use crate::runtime_core::{HeapObject, Value, HEAP_TAG, PTR_TAG_MASK};
15
16pub type CodeHandle = u64;
19
20pub trait ValueStore {
21 fn alloc(&mut self, object: HeapObject) -> Value;
23 fn try_get(&self, value: Value) -> Option<&HeapObject>;
26 fn try_get_mut(&mut self, value: Value) -> Option<&mut HeapObject>;
27}
28
29#[derive(Default)]
32pub struct HandleStore {
33 arena: Vec<HeapObject>,
34}
35
36impl HandleStore {
37 pub fn new() -> HandleStore {
38 HandleStore::default()
39 }
40
41 fn index_of(value: Value) -> Option<usize> {
42 if value & PTR_TAG_MASK != HEAP_TAG {
43 return None;
44 }
45 Some((value >> 3) as usize)
46 }
47}
48
49impl ValueStore for HandleStore {
50 fn alloc(&mut self, object: HeapObject) -> Value {
51 self.arena.push(object);
52 (((self.arena.len() - 1) as u64) << 3) | HEAP_TAG
53 }
54
55 fn try_get(&self, value: Value) -> Option<&HeapObject> {
56 self.arena.get(Self::index_of(value)?)
57 }
58
59 fn try_get_mut(&mut self, value: Value) -> Option<&mut HeapObject> {
60 let index = Self::index_of(value)?;
61 self.arena.get_mut(index)
62 }
63}
64
65#[cfg(not(target_family = "wasm"))]
76#[repr(align(8))]
77struct HeapCell(HeapObject);
78
79#[cfg(not(target_family = "wasm"))]
80#[derive(Default)]
81pub struct PointerStore {
82 cells: HashMap<Value, Box<HeapCell>>,
83}
84
85#[cfg(not(target_family = "wasm"))]
86impl PointerStore {
87 pub fn new() -> PointerStore {
88 PointerStore::default()
89 }
90}
91
92#[cfg(not(target_family = "wasm"))]
93impl ValueStore for PointerStore {
94 fn alloc(&mut self, object: HeapObject) -> Value {
95 let cell = Box::new(HeapCell(object));
96 let address = cell.as_ref() as *const HeapCell as u64;
97 debug_assert_eq!(address & PTR_TAG_MASK, 0, "heap cells must be 8-byte aligned");
98 let value = address | HEAP_TAG;
99 let replaced = self.cells.insert(value, cell);
100 debug_assert!(replaced.is_none(), "live heap addresses must be unique");
101 value
102 }
103
104 fn try_get(&self, value: Value) -> Option<&HeapObject> {
105 if value & PTR_TAG_MASK != HEAP_TAG {
106 return None;
107 }
108 self.cells.get(&value).map(|cell| &cell.0)
109 }
110
111 fn try_get_mut(&mut self, value: Value) -> Option<&mut HeapObject> {
112 if value & PTR_TAG_MASK != HEAP_TAG {
113 return None;
114 }
115 self.cells.get_mut(&value).map(|cell| &mut cell.0)
116 }
117}