1use crate::code_bld::CodeBuilder;
6use source_map_node::Node;
7use swamp_vm_types::types::{BasicTypeKind, BasicTypeRef, VmType, u16_type, u32_type};
8use swamp_vm_types::{AggregateMemoryLocation, CountU16, MemoryLocation};
9
10impl CodeBuilder<'_> {
11 pub(crate) fn emit_initialize_collections_in_type(
13 &mut self,
14 location: &AggregateMemoryLocation,
15 type_ref: &BasicTypeRef,
16 node: &Node,
17 comment: &str,
18 ) {
19 match &type_ref.kind {
20 BasicTypeKind::MapStorage { .. }
23 | BasicTypeKind::StringStorage { .. }
24 | BasicTypeKind::VecStorage(..)
25 | BasicTypeKind::GridStorage(..)
26 | BasicTypeKind::SparseStorage(..)
27 | BasicTypeKind::StackStorage(..)
28 | BasicTypeKind::QueueStorage(..)
29 | BasicTypeKind::FixedCapacityArray(..) => {
30 self.emit_initialize_collection_metadata(
32 &location.location,
33 node,
34 &format!("{comment} - emit_initialize_collections_in_type"),
35 );
36 }
37
38 BasicTypeKind::Struct(_) => {
40 self.initialize_struct_collection_fields(location, type_ref, node, comment);
41 }
42
43 BasicTypeKind::Tuple(tuple_info) => {
44 for (i, tuple_field) in tuple_info.fields.iter().enumerate() {
45 let tuple_field_location =
46 location.offset(tuple_field.offset, tuple_field.ty.clone());
47 self.emit_initialize_collections_in_type(
48 &tuple_field_location,
49 &tuple_field.ty,
50 node,
51 &format!("{comment} - emit_initialize_collections_in_type tuple field {i}"),
52 );
53 }
54 }
55
56 BasicTypeKind::TaggedUnion(union_info) => {
58 }
61
62 _ => {}
63 }
64 }
65
66 fn initialize_struct_collection_fields(
68 &mut self,
69 struct_location: &AggregateMemoryLocation,
70 struct_type: &BasicTypeRef,
71 node: &Node,
72 comment: &str,
73 ) {
74 match &struct_type.kind {
75 BasicTypeKind::Struct(struct_info) => {
76 for field in &struct_info.fields {
78 let field_location = struct_location.offset(field.offset, field.ty.clone());
80
81 self.emit_initialize_collections_in_type(
83 &field_location,
84 &field.ty,
85 node,
86 &format!("{comment} - field {}", field.name),
87 );
88 }
89 }
90 BasicTypeKind::Tuple(tuple_info) => {
92 for (i, tuple_field) in tuple_info.fields.iter().enumerate() {
93 let tuple_field_location =
94 struct_location.offset(tuple_field.offset, tuple_field.ty.clone());
95 self.emit_initialize_collections_in_type(
96 &tuple_field_location,
97 &tuple_field.ty,
98 node,
99 &format!("{comment} - tuple field {i}"),
100 );
101 }
102 }
103 BasicTypeKind::TaggedUnion(union_info) => {
104 }
107 _ => {}
108 }
109 }
110
111 pub fn emit_initialize_memory_for_any_type(
121 &mut self,
122 memory_location: &MemoryLocation,
123 node: &Node,
124 comment: &str,
125 ) {
126 let basic_type = memory_location.ty.basic_type();
127
128 if basic_type.is_collection() {
130 self.emit_initialize_collection_metadata(memory_location, node, comment);
131 return;
132 }
133
134 let aggregate_location = AggregateMemoryLocation {
136 location: memory_location.clone(),
137 };
138
139 self.emit_initialize_collections_in_type(&aggregate_location, basic_type, node, comment);
140 }
141
142 pub fn emit_initialize_collection_metadata(
150 &mut self,
151 memory_location: &MemoryLocation,
152 node: &Node,
153 comment: &str,
154 ) {
155 let basic_type = memory_location.ty.basic_type();
156 if !basic_type.is_collection() {
157 return; }
159
160 match &basic_type.kind {
161 BasicTypeKind::FixedCapacityArray(element_type, capacity) => {
162 let absolute_pointer = self
163 .emit_compute_effective_address_from_location_to_register(
164 memory_location,
165 node,
166 &format!("{comment} - compute address for vec init when pointer_location() is None"),
167 );
168
169 self.builder
170 .add_fixed_capacity_array_init_fill_capacity_and_len(
171 &absolute_pointer,
172 *capacity as u16,
173 &element_type.total_size,
174 node,
175 &format!("{comment} - initialize fixed capacity array init"),
176 );
177 }
178 BasicTypeKind::SparseStorage(element_type, capacity) => {
179 let absolute_pointer = self
180 .emit_compute_effective_address_from_location_to_register(
181 memory_location,
182 node,
183 &format!("{comment} - load effective address for sparse"),
184 );
185 self.builder.add_sparse_init(
186 &absolute_pointer,
187 element_type.total_size,
188 *capacity as u16,
189 node,
190 comment,
191 );
192 }
193 BasicTypeKind::GridStorage(element_type, width, height) => {
194 let hwm = self.temp_registers.save_mark();
195
196 let absolute_pointer = self
197 .emit_compute_effective_address_from_location_to_register(
198 memory_location,
199 node,
200 "compute address for grid init when pointer_location() is None",
201 );
202
203 let init_element_size = self.temp_registers.allocate(
204 VmType::new_contained_in_register(u16_type()),
205 &format!("{comment} - init grid init_element_size"),
206 );
207
208 self.builder.add_mov_32_immediate_value(
209 init_element_size.register(),
210 element_type.total_size.0,
211 node,
212 &format!("{comment} -set grid element size {memory_location}"),
213 );
214
215 self.builder.add_grid_init(
216 &absolute_pointer.ptr_reg,
217 &init_element_size.register,
218 *width as u16,
219 *height as u16,
220 node,
221 comment,
222 );
223
224 self.temp_registers.restore_to_mark(hwm);
225 }
226 BasicTypeKind::MapStorage {
227 logical_limit,
228 key_type,
229 value_type,
230 ..
231 } => {
232 let hwm = self.temp_registers.save_mark();
233
234 let unaligned_key_size = key_type.total_size;
235 let key_alignment = key_type.max_alignment;
236 let unaligned_value_size = value_type.total_size;
237 let value_alignment = value_type.max_alignment;
238
239 let init_key_size = self.temp_registers.allocate(
240 VmType::new_contained_in_register(u32_type()),
241 &format!("{comment} - init map key_size reg"),
242 );
243 self.builder.add_mov_32_immediate_value(
244 init_key_size.register(),
245 unaligned_key_size.0,
246 node,
247 &format!("{comment} -set init key_size value to {memory_location}"),
248 );
249
250 let init_value_size = self.temp_registers.allocate(
251 VmType::new_contained_in_register(u32_type()),
252 &format!("{comment} - init map value_size reg"),
253 );
254 self.builder.add_mov_32_immediate_value(
255 init_value_size.register(),
256 unaligned_value_size.0,
257 node,
258 &format!("{comment} -set init value_size value to {memory_location}"),
259 );
260
261 let map_pointer_location = self
262 .emit_compute_effective_address_from_location_to_register(
263 memory_location,
264 node,
265 "find location of map to init",
266 );
267
268 self.builder.add_map_init_set_capacity(
269 &map_pointer_location,
270 CountU16(*logical_limit as u16),
271 init_key_size.register(),
272 key_alignment,
273 init_value_size.register(),
274 value_alignment,
275 node,
276 &format!(
277 "{comment} - initialize map (capacity, key_size, total_key_and_value_size)"
278 ),
279 );
280
281 self.temp_registers.restore_to_mark(hwm);
282 }
283 BasicTypeKind::VecStorage(element_type, capacity)
284 | BasicTypeKind::StackStorage(element_type, capacity)
285 | BasicTypeKind::StringStorage {
286 element_type,
287 capacity,
288 ..
289 }
290 | BasicTypeKind::QueueStorage(element_type, capacity) => {
291 let absolute_pointer = self
292 .emit_compute_effective_address_from_location_to_register(
293 memory_location,
294 node,
295 "compute address for vec init when pointer_location() is None",
296 );
297 self.builder.add_vec_init_set_capacity(
298 &absolute_pointer,
299 CountU16(*capacity as u16),
300 &element_type.total_size,
301 node,
302 "initialize vec like (vec, stack, queue)",
303 );
304 }
305
306 _ => {}
307 }
308 }
309}