1pub mod region;
2#[cfg(feature = "heap")]
3pub mod heap;
4#[cfg(feature = "stack")]
5pub mod stack;
6
7#[cfg(test)]
8mod tests {
9 use std::rc::Rc;
10 use roussillon_type_system::{
11 types::{
12 concept::DataType,
13 primitive::Primitive,
14 },
15 value::{
16 concept::{DataValue, ValueCell},
17 boolean::Boolean,
18 byte::Bytes,
19 number::{Float, Integer},
20 record::Record,
21 reference::Reference,
22 },
23 };
24 use roussillon_type_system::factory::create_struct;
25 use roussillon_type_system::identity::LabelBank;
26 use roussillon_type_system::types::typedef::Structure;
27
28 use crate::heap::Heap;
29 use crate::region::{Allocator, Dereference, Region};
30
31 fn test_type(r: &Reference, typename: &str) {
32 assert_eq!(r.data_type().typename(), format!("&{}", typename));
34 }
35
36 fn test_cells(original_cell: &ValueCell, dereferenced: &ValueCell) {
37 let t1 = original_cell.borrow().data_type().typename();
38 let raw1 = original_cell.borrow().raw();
39 let t2 = dereferenced.borrow().data_type().typename();
40 let raw2 = dereferenced.borrow().raw();
41 assert_eq!(t1, t2);
43 assert_eq!(raw1, raw2);
44 }
45
46 fn test_struct() -> Rc<Structure> {
47 create_struct("MyStruct", LabelBank::from(&[
48 "field_a",
49 "field_b",
50 "field_c",
51 ]), &[
52 Primitive::Integer.to_rc(),
53 Primitive::Integer.to_rc(),
54 Primitive::Float.to_rc(),
55 ])
56 }
57
58 fn test_object(structure: Rc<Structure>) -> ValueCell {
59 Record::new(structure, &[
60 Integer::new(40).to_cell(),
61 Integer::new(96).to_cell(),
62 Float::new(40.0).to_cell()
63 ]).unwrap().to_cell()
64 }
65
66 #[test]
67 fn test_struct_reference() {
68 let mut memory = Region::default();
69 let my_struct = test_struct();
70 let original_object = test_object(my_struct.clone());
73
74 let reference = memory.allocate(original_object.clone());
75 test_type(&reference, "MyStruct");
76 let dereferenced_object = memory.dereference(reference).unwrap();
77 test_cells(&original_object, &dereferenced_object);
78 }
79
80 #[test]
81 fn test_heap() {
82 let mut heap = Heap::new();
83 assert_eq!(heap.current_generation(), None);
85
86
87 heap.next_generation();
88 assert_eq!(heap.current_generation(), Some(0));
90
91 let my_struct = test_struct();
92 let original_object = test_object(my_struct.clone());
95
96 let reference = heap.allocate(original_object.clone());
97 println!("{:?}", reference);
98
99 test_type(reference.reference(), "MyStruct");
100 let dereferenced_object = heap.dereference(reference.clone()).unwrap();
101 test_cells(&original_object, &dereferenced_object);
102 heap.next_generation();
105 assert_eq!(heap.current_generation().unwrap(), 1);
106 heap.clear(0);
109 assert!(!heap.validate(&reference));
111 }
112
113 #[test]
114 fn test_boolean_references() {
115 let mut memory = Region::default();
116
117 let original_true = Boolean::create_true().to_cell();
118 let original_false = Boolean::create_false().to_cell();
119 let reference_true = memory.allocate(original_true.clone());
120 let reference_false = memory.allocate(original_false.clone());
121 test_type(&reference_true, &Primitive::Boolean.typename());
122 test_type(&reference_false, &Primitive::Boolean.typename());
123 let dereferenced_true = memory.dereference(reference_true).unwrap();
124 let dereferenced_false = memory.dereference(reference_false).unwrap();
125 test_cells(&original_true, &dereferenced_true);
126 test_cells(&original_false, &dereferenced_false);
127 }
128
129 #[test]
130 fn test_float_reference() {
131 let mut memory = Region::default();
132
133 let original_cell = Float::new(std::f64::consts::PI).to_cell();
134 let reference = memory.allocate(original_cell.clone());
135 test_type(&reference, &Primitive::Float.typename());
136 let dereferenced = memory.dereference(reference).unwrap();
137 test_cells(&original_cell, &dereferenced);
138 }
139
140 #[test]
141 fn test_integer_reference() {
142 let mut memory = Region::default();
143
144 let original_cell = Integer::new(1415).to_cell();
145 let reference = memory.allocate(original_cell.clone());
146 test_type(&reference, &Primitive::Integer.typename());
147 let dereferenced = memory.dereference(reference).unwrap();
148 test_cells(&original_cell, &dereferenced);
149 }
150
151 #[test]
152 fn test_bytes_references() {
153 let mut memory = Region::default();
154
155 for (data, t) in [
156 (Bytes::Byte(77), Primitive::Byte.typename()),
157 (Bytes::Arch(16584), Primitive::Bytes(std::mem::size_of::<usize>()).typename()),
158 (Bytes::Word(16584), Primitive::Bytes(2).typename()),
159 (Bytes::Quad(998555), Primitive::Bytes(4).typename()),
160 (Bytes::Long(8855887455), Primitive::Bytes(8).typename()),
161 (Bytes::Wide(usize::MAX as u128 + 15550), Primitive::Bytes(16).typename()),
162 ] {
163 let original_cell = data.to_cell();
164 let reference = memory.allocate(original_cell.clone());
165 test_type(&reference, &t);
166 let dereferenced = memory.dereference(reference).unwrap();
167 test_cells(&original_cell, &dereferenced);
168 }
169 }
170}