oxilean_runtime/object/
rtobject_type.rs1use 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#[derive(Clone)]
21pub struct RtObject {
22 pub(super) bits: u64,
24}
25impl RtObject {
26 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 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 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 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 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 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 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 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 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 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 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 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}