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