nova_interpreter/
primitives.rs1use std::alloc::{self, Layout};
2
3use vera_prim_macro::prim;
4
5use crate as nova_interpreter;
6use crate::utils::PrimitiveFn;
7
8use crate::utils::interner::Interner;
9
10pub struct Builtins<'a> {
13 pub builtins: &'a mut Vec<(Box<[usize]>, PrimitiveFn)>,
14}
15
16impl<'a> Builtins<'a> {
17 pub fn new(builtins: &'a mut Vec<(Box<[usize]>, PrimitiveFn)>) -> Self {
18 Builtins { builtins }
19 }
20
21 pub fn add_builtin(&mut self, conditions: Vec<usize>, prim: PrimitiveFn) {
22 self.builtins.push((conditions.into_boxed_slice(), prim))
23 }
24}
25
26pub fn add_memory_manipulation_builtins(interner: &mut Interner<String>, builtins: &mut Builtins) {
28 prim!(
29 mem_alloc,
30 |mem_bytes| {
31 let bytes = mem_bytes;
32 let layout_size = size_of::<Layout>();
33
34 let layout = Layout::from_size_align(bytes + layout_size, 8).unwrap();
35 let mem = unsafe { alloc::alloc(layout) };
36
37 unsafe { *(mem as *mut Layout) = layout };
38
39 (mem as usize + layout_size,)
40 },
41 (mem_pointer,)
42 );
43
44 prim!(
45 mem_write,
46 |mem_value, mem_pointer| {
47 unsafe { *(mem_pointer as *mut u8) = mem_value as u8 };
48 },
49 ()
50 );
51
52 prim!(
53 mem_read,
54 |mem_pointer| { (unsafe { *(mem_pointer as *mut u8) as usize },) },
55 (mem_value,)
56 );
57
58 prim!(
59 mem_copy,
60 |mem_src, mem_dest, mem_bytes| unsafe {
61 std::ptr::copy_nonoverlapping(mem_src as *mut u8, mem_dest as *mut u8, mem_bytes)
62 },
63 ()
64 );
65
66 prim!(
67 mem_free,
68 |mem_pointer| {
69 let layout_size = size_of::<Layout>();
70
71 let ptr = (mem_pointer - layout_size) as *mut u8;
72 let layout = unsafe { *(ptr as *mut Layout) };
73 unsafe { alloc::dealloc(ptr, layout) }
74 },
75 ()
76 );
77}