mimium_lang/runtime/vm/
primitives.rs1use crate::runtime::primitives::{RuntimePrimitives, Word, WordSize};
2
3use super::{Machine, StateOffset, heap};
4
5impl RuntimePrimitives for Machine {
6 type HeapRef = heap::HeapIdx;
7 type ArrayRef = Word; type StateOffset = StateOffset;
9 type TypeId = u8;
10
11 fn heap_alloc(&mut self, size_words: WordSize) -> Self::HeapRef {
12 self.heap.insert(heap::HeapObject::new(size_words as usize))
13 }
14
15 fn heap_retain(&mut self, obj: Self::HeapRef) {
16 heap::heap_retain(&mut self.heap, obj);
17 }
18
19 fn heap_release(&mut self, obj: Self::HeapRef) {
20 heap::heap_release(&mut self.heap, obj);
21 }
22
23 fn heap_load(&mut self, dst: &mut [Word], obj: Self::HeapRef, size_words: WordSize) {
24 let size = size_words as usize;
25 debug_assert!(dst.len() >= size);
26 let data = self
27 .heap
28 .get(obj)
29 .map(|heap_obj| &heap_obj.data[..size])
30 .expect("heap_load: invalid heap index");
31 dst[..size].copy_from_slice(data);
32 }
33
34 fn heap_store(&mut self, obj: Self::HeapRef, src: &[Word], size_words: WordSize) {
35 let size = size_words as usize;
36 debug_assert!(src.len() >= size);
37 let data = self
38 .heap
39 .get_mut(obj)
40 .map(|heap_obj| &mut heap_obj.data[..size])
41 .expect("heap_store: invalid heap index");
42 data.copy_from_slice(&src[..size]);
43 }
44
45 fn box_alloc(&mut self, src: &[Word], size_words: WordSize) -> Self::HeapRef {
46 let size = size_words as usize;
47 debug_assert!(src.len() >= size);
48 let data = src[..size].to_vec();
49 self.heap.insert(heap::HeapObject::with_data(data))
50 }
51
52 fn box_load(&mut self, dst: &mut [Word], obj: Self::HeapRef, size_words: WordSize) {
53 self.heap_load(dst, obj, size_words);
54 }
55
56 fn box_clone(&mut self, obj: Self::HeapRef) {
57 self.heap_retain(obj);
58 }
59
60 fn box_release(&mut self, obj: Self::HeapRef) {
61 self.heap_release(obj);
62 }
63
64 fn box_store(&mut self, obj: Self::HeapRef, src: &[Word], size_words: WordSize) {
65 self.heap_store(obj, src, size_words);
66 }
67
68 fn usersum_clone(&mut self, value: &mut [Word], size_words: WordSize, type_id: Self::TypeId) {
69 let size = size_words as usize;
70 let ty = self
71 .prog
72 .get_type_from_table(type_id)
73 .expect("usersum_clone: invalid type id");
74 let data = &value[..size];
75 Self::clone_usersum_recursive(data, &ty, &mut self.heap);
76 }
77
78 fn usersum_release(&mut self, value: &mut [Word], size_words: WordSize, type_id: Self::TypeId) {
79 let size = size_words as usize;
80 let ty = self
81 .prog
82 .get_type_from_table(type_id)
83 .expect("usersum_release: invalid type id");
84 let data = &value[..size];
85 let type_table = &self.prog.type_table;
86 Self::release_usersum_recursive(data, &ty, &mut self.heap, type_table);
87 }
88
89 fn closure_make(
90 &mut self,
91 _fn_index: Word,
92 _upvalue_count: WordSize,
93 _state_size: WordSize,
94 ) -> Self::HeapRef {
95 unimplemented!("closure_make is not used in VM backend (see MakeHeapClosure instruction)")
99 }
100
101 fn closure_close(&mut self, obj: Self::HeapRef) {
102 self.close_heap_upvalues(obj);
103 }
104
105 fn closure_call(
106 &mut self,
107 _obj: Self::HeapRef,
108 _args: &[Word],
109 _nargs_words: WordSize,
110 _ret: &mut [Word],
111 _nret_words: WordSize,
112 ) {
113 unimplemented!("closure_call is not used in VM backend (see CallIndirect instruction)")
117 }
118
119 fn state_push(&mut self, offset: Self::StateOffset) {
120 self.get_current_state().push_pos(offset);
121 }
122
123 fn state_pop(&mut self, offset: Self::StateOffset) {
124 self.get_current_state().pop_pos(offset);
125 }
126
127 fn state_get(&mut self, dst: &mut [Word], size_words: WordSize) {
128 let size = size_words as usize;
129 debug_assert!(dst.len() >= size);
130 let data = self.get_current_state().get_state(size_words);
131 dst[..size].copy_from_slice(&data[..size]);
132 }
133
134 fn state_set(&mut self, src: &[Word], size_words: WordSize) {
135 let size = size_words as usize;
136 debug_assert!(src.len() >= size);
137 let dst = self.get_current_state().get_state_mut(size);
138 dst.copy_from_slice(&src[..size]);
139 }
140
141 fn state_delay(&mut self, dst: &mut [Word], src: &[Word], time: &[Word], max_len: Word) {
142 let input = src.first().copied().unwrap_or_default();
143 let t = time.first().copied().unwrap_or_default();
144 let size_in_samples = max_len;
145 let mut ringbuf = self.get_current_state().get_as_ringbuffer(size_in_samples);
146 let res = ringbuf.process(input, t);
147 if let Some(dst_first) = dst.first_mut() {
148 *dst_first = Self::to_value(res);
149 }
150 }
151
152 fn state_mem(&mut self, dst: &mut [Word], src: &[Word]) {
153 let prev = self.get_current_state().get_state_mut(1)[0];
154 let next = src.first().copied().unwrap_or_default();
155 if let Some(dst_first) = dst.first_mut() {
156 *dst_first = prev;
157 }
158 self.get_current_state().get_state_mut(1)[0] = next;
159 }
160
161 fn array_alloc(&mut self, len: Word, elem_size_words: WordSize) -> Self::ArrayRef {
162 self.arrays.alloc_array(len, elem_size_words)
163 }
164
165 fn array_get_elem(
166 &mut self,
167 dst: &mut [Word],
168 arr: Self::ArrayRef,
169 index: Word,
170 elem_size_words: WordSize,
171 ) {
172 let elem_size = elem_size_words as usize;
173 debug_assert!(dst.len() >= elem_size);
174 let index_val = Self::get_as::<f64>(index) as usize;
175 let array = self.arrays.get_array(arr);
176 let start = index_val * elem_size;
177 debug_assert!(start + elem_size <= array.data.len());
178 let data = &array.data[start..start + elem_size];
179 dst[..elem_size].copy_from_slice(data);
180 }
181
182 fn array_set_elem(
183 &mut self,
184 arr: Self::ArrayRef,
185 index: Word,
186 src: &[Word],
187 elem_size_words: WordSize,
188 ) {
189 let elem_size = elem_size_words as usize;
190 debug_assert!(src.len() >= elem_size);
191 let index_val = Self::get_as::<f64>(index) as usize;
192 let array = self.arrays.get_array_mut(arr);
193 let start = index_val * elem_size;
194 debug_assert!(start + elem_size <= array.data.len());
195 array.data[start..start + elem_size].copy_from_slice(&src[..elem_size]);
196 }
197
198 fn runtime_get_now(&mut self) -> Word {
199 Self::to_value(0.0)
203 }
204
205 fn runtime_get_samplerate(&mut self) -> Word {
206 Self::to_value(48000.0)
209 }
210}