tidepool_codegen/
nursery.rs1use crate::context::VMContext;
2
3pub struct Nursery {
8 buffer: Vec<u8>,
9}
10
11impl Nursery {
12 pub fn new(size: usize) -> Self {
14 Self {
15 buffer: vec![0u8; size],
16 }
17 }
18
19 pub fn start(&self) -> *const u8 {
21 self.buffer.as_ptr()
22 }
23
24 pub fn size(&self) -> usize {
26 self.buffer.len()
27 }
28
29 pub fn make_vmctx(&mut self, gc_trigger: unsafe extern "C" fn(*mut VMContext)) -> VMContext {
34 let start = self.buffer.as_mut_ptr();
35 let end = unsafe { start.add(self.buffer.len()) };
37 VMContext::new(start, end as *const u8, gc_trigger)
38 }
39}
40
41#[cfg(test)]
42mod tests {
43 use super::*;
44
45 extern "C" fn dummy_gc_trigger(_vmctx: *mut VMContext) {}
46
47 #[test]
48 fn test_nursery_new() {
49 let size = 1024;
50 let nursery = Nursery::new(size);
51 assert_eq!(nursery.buffer.len(), size);
52 assert!(nursery.buffer.iter().all(|&b| b == 0));
53 }
54
55 #[test]
56 fn test_make_vmctx() {
57 let size = 1024;
58 let mut nursery = Nursery::new(size);
59 let vmctx = nursery.make_vmctx(dummy_gc_trigger);
60
61 assert_eq!(vmctx.alloc_ptr, nursery.buffer.as_mut_ptr());
62 assert_eq!(vmctx.alloc_limit, unsafe {
64 nursery.buffer.as_ptr().add(size)
65 });
66 assert_eq!(
67 vmctx.gc_trigger as usize,
68 dummy_gc_trigger as *const () as usize
69 );
70 }
71
72 #[test]
73 fn test_vmctx_alignment() {
74 let size = 1024;
75 let mut nursery = Nursery::new(size);
76 let vmctx = nursery.make_vmctx(dummy_gc_trigger);
77
78 assert_eq!(vmctx.alloc_ptr as usize % 8, 0);
81 }
82
83 #[test]
84 fn test_multiple_vmctx() {
85 let size = 1024;
86 let mut nursery = Nursery::new(size);
87
88 let vmctx1 = nursery.make_vmctx(dummy_gc_trigger);
89 let vmctx2 = nursery.make_vmctx(dummy_gc_trigger);
90
91 assert_eq!(vmctx1.alloc_ptr, vmctx2.alloc_ptr);
92 assert_eq!(vmctx1.alloc_limit, vmctx2.alloc_limit);
93 }
94}