roussillon_memory/
lib.rs

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        // println!("• {}", r.data_type().typename());
33        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        // println!("{:?} <=> {:?}", original_cell.borrow(), dereferenced.borrow());
42        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        // println!("\n{:?}", my_struct);
71
72        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        // println!("{:?}", heap);
84        assert_eq!(heap.current_generation(), None);
85
86
87        heap.next_generation();
88        // println!("{:?}", heap);
89        assert_eq!(heap.current_generation(), Some(0));
90
91        let my_struct = test_struct();
92        // println!("\n{:?}", my_struct);
93
94        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        // println!("{:?}", heap);
103
104        heap.next_generation();
105        assert_eq!(heap.current_generation().unwrap(), 1);
106        // println!("{:?}", heap);
107
108        heap.clear(0);
109        // println!("{:?}", heap);
110        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}