Skip to main content

oxilean_runtime/object/
rtobject_type.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use oxilean_kernel::Name;
6
7use super::functions::{TAG_ARRAY, TAG_EXTERNAL, TAG_IO_ACTION, TAG_STRING, TAG_TASK, TAG_THUNK};
8use super::types::{
9    ArrayData, BoxedFloatData, ByteArrayData, ConstructorData, ExternalData, HeapObject,
10    IoActionData, IoActionKind, ObjectHeader, ObjectStore, StringData, TaskData, TaskState,
11    ThunkData, ThunkState, TypeTag,
12};
13
14/// The core runtime value representation.
15///
16/// `RtObject` uses a tagged encoding to store small values inline
17/// (in the u64 itself) and reference heap-allocated objects for
18/// larger values. This avoids allocation for common cases like
19/// small naturals, booleans, and unit.
20#[derive(Clone)]
21pub struct RtObject {
22    /// The raw tagged bits.
23    pub(super) bits: u64,
24}
25impl RtObject {
26    /// Access the heap object for this reference (if heap-allocated).
27    pub fn with_heap<R>(&self, f: impl FnOnce(&HeapObject) -> R) -> Option<R> {
28        if self.is_inline() {
29            return None;
30        }
31        let id = self.payload() as usize;
32        ObjectStore::global_store(|store| store.get(id).map(f))
33    }
34    /// Access the heap object mutably.
35    pub fn with_heap_mut<R>(&self, f: impl FnOnce(&mut HeapObject) -> R) -> Option<R> {
36        if self.is_inline() {
37            return None;
38        }
39        let id = self.payload() as usize;
40        ObjectStore::global_store(|store| store.get_mut(id).map(f))
41    }
42    /// Create a string object.
43    pub fn string(s: String) -> Self {
44        let heap = HeapObject::StringObj(StringData {
45            header: ObjectHeader::new(TypeTag::StringObj, ((s.len() + 7) / 8 + 1) as u16),
46            value: s,
47            cached_hash: None,
48        });
49        RtObject::from_heap_with_tag(heap, TAG_STRING)
50    }
51    /// Create an array object.
52    pub fn array(elements: Vec<RtObject>) -> Self {
53        let cap = elements.capacity();
54        let heap = HeapObject::Array(ArrayData {
55            header: ObjectHeader::new(TypeTag::Array, (elements.len() + 1) as u16),
56            elements,
57            capacity: cap,
58        });
59        RtObject::from_heap_with_tag(heap, TAG_ARRAY)
60    }
61    /// Create a constructor object with fields.
62    pub fn constructor(ctor_index: u32, fields: Vec<RtObject>) -> Self {
63        let num_fields = fields.len() as u16;
64        let heap = HeapObject::Constructor(ConstructorData {
65            header: ObjectHeader::new(TypeTag::Constructor, (fields.len() + 2) as u16),
66            ctor_index,
67            num_fields,
68            scalar_fields: Vec::new(),
69            object_fields: fields,
70            name: None,
71        });
72        RtObject::from_heap(heap)
73    }
74    /// Create a named constructor object.
75    pub fn named_constructor(name: Name, ctor_index: u32, fields: Vec<RtObject>) -> Self {
76        let num_fields = fields.len() as u16;
77        let heap = HeapObject::Constructor(ConstructorData {
78            header: ObjectHeader::new(TypeTag::Constructor, (fields.len() + 2) as u16),
79            ctor_index,
80            num_fields,
81            scalar_fields: Vec::new(),
82            object_fields: fields,
83            name: Some(name),
84        });
85        RtObject::from_heap(heap)
86    }
87    /// Create a thunk (lazy value).
88    pub fn thunk(closure: RtObject) -> Self {
89        let heap = HeapObject::Thunk(ThunkData {
90            header: ObjectHeader::new(TypeTag::Thunk, 2),
91            state: ThunkState::Unevaluated { closure },
92        });
93        RtObject::from_heap_with_tag(heap, TAG_THUNK)
94    }
95    /// Create an IO action.
96    pub fn io_pure(value: RtObject) -> Self {
97        let heap = HeapObject::IoAction(IoActionData {
98            header: ObjectHeader::new(TypeTag::IoAction, 2),
99            kind: IoActionKind::Pure(value),
100        });
101        RtObject::from_heap_with_tag(heap, TAG_IO_ACTION)
102    }
103    /// Create a task object.
104    pub fn task(task_id: u64) -> Self {
105        let heap = HeapObject::Task(TaskData {
106            header: ObjectHeader::new(TypeTag::Task, 2),
107            state: TaskState::Pending,
108            task_id,
109        });
110        RtObject::from_heap_with_tag(heap, TAG_TASK)
111    }
112    /// Create an external object.
113    pub fn external(type_name: String, payload: Vec<u8>) -> Self {
114        let heap = HeapObject::External(ExternalData {
115            header: ObjectHeader::new(TypeTag::External, 2),
116            type_name,
117            payload,
118        });
119        RtObject::from_heap_with_tag(heap, TAG_EXTERNAL)
120    }
121    /// Create a boxed float.
122    pub fn boxed_float(value: f64) -> Self {
123        let heap = HeapObject::BoxedFloat(BoxedFloatData {
124            header: ObjectHeader::new(TypeTag::BoxedFloat, 2),
125            value,
126        });
127        RtObject::from_heap(heap)
128    }
129    /// Create a byte array.
130    pub fn byte_array(bytes: Vec<u8>) -> Self {
131        let heap = HeapObject::ByteArray(ByteArrayData {
132            header: ObjectHeader::new(TypeTag::ByteArray, ((bytes.len() + 7) / 8 + 1) as u16),
133            bytes,
134        });
135        RtObject::from_heap(heap)
136    }
137}