1use crate::constants::ConstantsManager;
6use crate::{ConstantInfo, FunctionIps, GenFunctionInfo};
7use seq_map::SeqMap;
8use source_map_node::Node;
9use swamp_semantic::{ConstantId, ConstantRef, InternalFunctionDefinitionRef, InternalFunctionId};
10use swamp_vm_debug_info::DebugInfo;
11use swamp_vm_layout::LayoutCache;
12use swamp_vm_types::types::{CompleteFunctionInfo, FunctionInfo, FunctionInfoKind, HeapPlacedType};
13use swamp_vm_types::{InstructionPosition, InstructionPositionOffset, PatchPosition};
14use tracing::info;
15
16pub struct GenOptions {
17 pub is_halt_function: bool,
18}
19
20pub struct FunctionFixup {
21 pub patch_position: PatchPosition,
22 pub fn_id: InternalFunctionId,
23 pub internal_function_definition: InternalFunctionDefinitionRef,
24}
25
26pub struct CodeGenState {
27 pub(crate) constants_manager: ConstantsManager,
28 pub(crate) constant_offsets: SeqMap<ConstantId, HeapPlacedType>,
29 pub(crate) constant_functions_in_order: SeqMap<ConstantId, ConstantInfo>,
30 pub function_infos: SeqMap<InternalFunctionId, GenFunctionInfo>,
31 pub function_ips: FunctionIps,
32 pub function_fixups: Vec<FunctionFixup>,
33 pub functions: SeqMap<usize, CompleteFunctionInfo>,
34 pub constants: SeqMap<usize, CompleteFunctionInfo>,
35 pub layout_cache: LayoutCache,
36
37 pub debug_info: DebugInfo,
38}
39
40impl CodeGenState {}
41
42impl Default for CodeGenState {
43 fn default() -> Self {
44 Self::new()
45 }
46}
47
48impl CodeGenState {
49 #[must_use]
50 pub fn new() -> Self {
51 Self {
52 constants_manager: ConstantsManager::new(32 * 1024 * 1024),
53 constant_offsets: SeqMap::default(),
54 function_infos: SeqMap::default(),
55 constant_functions_in_order: SeqMap::default(),
56 function_ips: FunctionIps::default(),
57 function_fixups: Vec::new(),
58 functions: SeqMap::default(),
59 constants: SeqMap::default(),
60 debug_info: DebugInfo::default(),
61 layout_cache: LayoutCache::new(),
62 }
63 }
64
65 pub fn add_function(
66 &mut self,
67 function_info: FunctionInfo,
68 node: &Node,
69 comment: &str,
70 ) -> CompleteFunctionInfo {
71 self.add_function_helper(function_info, node, comment)
72 }
73
74 pub fn add_function_helper(
77 &mut self,
78 function_info: FunctionInfo,
79 node: &Node,
80 comment: &str,
81 ) -> CompleteFunctionInfo {
82 let complete_info = CompleteFunctionInfo {
83 ip: function_info.ip_range.start,
84 size: InstructionPositionOffset(0),
85 info: function_info.clone(),
86 };
87 if let FunctionInfoKind::Constant(constant_id) = function_info.kind {
88 self.constants
89 .insert(constant_id, complete_info.clone())
90 .unwrap();
91 } else if let FunctionInfoKind::Normal(normal_id) = function_info.kind {
92 if self.functions.contains_key(&normal_id) {
93 info!("skipping");
95 } else {
96 self.functions
97 .insert(normal_id, complete_info.clone())
98 .unwrap();
99 }
100 }
101
102 complete_info
103 }
104
105 pub fn add_constant_function(
108 &mut self,
109 constant_info: FunctionInfo,
110 node: &Node,
111 comment: &str,
112 ) -> CompleteFunctionInfo {
113 let FunctionInfoKind::Constant(_id) = constant_info.kind else {
114 panic!("must be constant")
115 };
116
117 self.add_function_helper(constant_info, node, comment)
118 }
119
120 #[must_use]
121 pub const fn constant_functions(&self) -> &SeqMap<ConstantId, ConstantInfo> {
122 &self.constant_functions_in_order
123 }
124
125 #[must_use]
126 pub fn create_function_sections(&self) -> SeqMap<InstructionPosition, String> {
127 let mut lookups = SeqMap::new();
128 for (_func_id, function_info) in &self.function_infos {
129 let description = function_info
130 .internal_function_definition
131 .assigned_name
132 .clone();
133 lookups
134 .insert(function_info.ip_range.start, description)
135 .unwrap();
136 }
137
138 for (_func_id, function_info) in &self.constant_functions_in_order {
139 let description = format!("constant {}", function_info.constant_ref.assigned_name);
140 lookups
141 .insert(function_info.ip_range.start, description)
142 .unwrap();
143 }
144
145 lookups
146 }
147
148 pub fn reserve_space_for_constants(&mut self, constants: &[ConstantRef]) {
149 for constant in constants {
150 let heap_placed_type = self
151 .constants_manager
152 .allocator
153 .allocate(&mut self.layout_cache, &constant.resolved_type);
154
155 self.constant_offsets
156 .insert(constant.id, heap_placed_type)
157 .unwrap();
158 }
159 }
160}