ghostscope_compiler/ebpf/codegen/
statements.rs1use super::*;
2
3impl<'ctx, 'dw> EbpfContext<'ctx, 'dw> {
4 pub fn compile_program_with_staged_transmission(
6 &mut self,
7 program: &Program,
8 _variable_types: HashMap<String, TypeKind>,
9 ) -> Result<TraceContext> {
10 info!("Compiling program with staged transmission system");
11
12 self.send_trace_event_header()?;
14 info!("Sent TraceEventHeader");
15
16 let trace_id = self.current_trace_id.map(|id| id as u64).unwrap_or(0);
18 self.send_trace_event_message(trace_id)?;
19 info!("Sent TraceEventMessage");
20
21 self.store_flag_value("_gs_any_fail", 0)?;
23 self.store_flag_value("_gs_any_success", 0)?;
24
25 let mut instruction_count = 0u16;
27 for statement in &program.statements {
28 instruction_count += self.compile_statement(statement)?;
29 }
30
31 self.write_end_instruction(instruction_count)?;
34 self.finish_event_after_instructions()?;
35 info!(
36 "Sent EndInstruction with {} total instructions",
37 instruction_count
38 );
39
40 Ok(self.trace_context.clone())
42 }
43
44 pub fn compile_statement(&mut self, statement: &Statement) -> Result<u16> {
46 debug!("Compiling statement: {:?}", statement);
47
48 match statement {
49 Statement::AliasDeclaration { name, target } => {
50 info!("Registering alias variable: {} = {:?}", name, target);
51 self.declare_name_in_current_scope(name)?;
53 self.set_alias_variable(name, target.clone());
54 Ok(0)
55 }
56 Statement::VarDeclaration { name, value } => {
57 info!("Processing variable declaration: {} = {:?}", name, value);
58 self.declare_name_in_current_scope(name)?;
60 if self.is_alias_candidate_expr(value) {
62 self.set_alias_variable(name, value.clone());
63 tracing::debug!(var=%name, "Registered DWARF alias variable");
64 Ok(0)
65 } else {
66 match value {
69 crate::script::Expr::String(s) => {
70 let mut bytes = s.as_bytes().to_vec();
71 bytes.push(0); self.set_string_variable_bytes(name, bytes);
73 }
74 crate::script::Expr::Variable(ref nm) => {
75 if self
76 .get_variable_type(nm)
77 .is_some_and(|t| matches!(t, crate::script::VarType::String))
78 {
79 if let Some(b) = self.get_string_variable_bytes(nm).cloned() {
80 self.set_string_variable_bytes(name, b);
81 }
82 }
83 }
84 _ => {}
85 }
86 let compiled_value = self.compile_expr(value)?;
87 if let BasicValueEnum::PointerValue(_) = compiled_value {
89 let allow_string_var_copy = match value {
91 crate::script::Expr::String(_) => true,
92 crate::script::Expr::Variable(ref nm) => self
93 .get_variable_type(nm)
94 .is_some_and(|t| matches!(t, crate::script::VarType::String)),
95 _ => false,
96 };
97 if !allow_string_var_copy {
98 return Err(CodeGenError::TypeError(
99 "script variables cannot store pointer values; use DWARF alias (let v = &expr) or keep it as a string".to_string(),
100 ));
101 }
102 }
103 self.store_variable(name, compiled_value)?;
104 Ok(0) }
106 }
107 Statement::Print(print_stmt) => self.compile_print_statement(print_stmt),
108 Statement::Backtrace(backtrace_stmt) => {
109 self.generate_backtrace_instruction(backtrace_stmt)?;
110 Ok(1)
111 }
112 Statement::If {
113 condition,
114 then_body,
115 else_body,
116 } => {
117 let entry_event_bytes = self.compile_time_event_bytes_upper_bound;
118 let expr_text = self.expr_to_name(condition);
121 let expr_index = self.trace_context.add_string(expr_text);
122 self.condition_context_active = true;
124 self.reset_condition_error()?;
125
126 let cond_value = self.compile_expr(condition)?;
128
129 let cond_bool = match cond_value {
131 BasicValueEnum::IntValue(int_val) => {
132 self.builder
134 .build_int_compare(
135 inkwell::IntPredicate::NE,
136 int_val,
137 int_val.get_type().const_zero(),
138 "cond_bool",
139 )
140 .map_err(|e| {
141 CodeGenError::LLVMError(format!("Failed to create condition: {e}"))
142 })?
143 }
144 _ => {
145 return Err(CodeGenError::LLVMError(
146 "Condition must evaluate to integer".to_string(),
147 ));
148 }
149 };
150
151 let current_function = self
153 .builder
154 .get_insert_block()
155 .ok_or_else(|| CodeGenError::LLVMError("No current basic block".to_string()))?
156 .get_parent()
157 .ok_or_else(|| CodeGenError::LLVMError("No parent function".to_string()))?;
158
159 let then_block = self
161 .context
162 .append_basic_block(current_function, "then_block");
163 let else_block = self
164 .context
165 .append_basic_block(current_function, "else_block");
166 let merge_block = self
167 .context
168 .append_basic_block(current_function, "merge_block");
169 let err_block = self
170 .context
171 .append_basic_block(current_function, "cond_err_block");
172 let ok_block = self
173 .context
174 .append_basic_block(current_function, "cond_ok_block");
175 self.condition_context_active = false;
177
178 let cond_err_pred = self.build_condition_error_predicate()?;
180 self.builder
181 .build_conditional_branch(cond_err_pred, err_block, ok_block)
182 .map_err(|e| {
183 CodeGenError::LLVMError(format!("Failed to branch on cond_err: {e}"))
184 })?;
185
186 self.builder.position_at_end(err_block);
188 self.compile_time_event_bytes_upper_bound = entry_event_bytes;
189 self.emit_current_condition_exprerror(expr_index, "cond")?;
190 let goto_else = matches!(else_body.as_deref(), Some(Statement::If { .. }));
193 let err_path_event_bytes = self.compile_time_event_bytes_upper_bound;
194 if goto_else {
195 self.builder
196 .build_unconditional_branch(else_block)
197 .map_err(|e| {
198 CodeGenError::LLVMError(format!(
199 "Failed to branch to else on error: {e}"
200 ))
201 })?;
202 } else {
203 self.builder
204 .build_unconditional_branch(merge_block)
205 .map_err(|e| {
206 CodeGenError::LLVMError(format!(
207 "Failed to branch to merge on error: {e}"
208 ))
209 })?;
210 }
211
212 self.builder.position_at_end(ok_block);
214 self.compile_time_event_bytes_upper_bound = entry_event_bytes;
215 self.builder
216 .build_conditional_branch(cond_bool, then_block, else_block)
217 .map_err(|e| {
218 CodeGenError::LLVMError(format!("Failed to create branch: {e}"))
219 })?;
220
221 self.builder.position_at_end(then_block);
223 self.compile_time_event_bytes_upper_bound = entry_event_bytes;
224 let mut then_instructions = 0u16;
225 self.enter_scope();
226 for stmt in then_body {
227 then_instructions += self.compile_statement(stmt)?;
228 }
229 self.exit_scope();
230 let then_event_bytes = self.compile_time_event_bytes_upper_bound;
231 self.builder
232 .build_unconditional_branch(merge_block)
233 .map_err(|e| {
234 CodeGenError::LLVMError(format!("Failed to branch to merge: {e}"))
235 })?;
236
237 self.builder.position_at_end(else_block);
239 let else_entry_event_bytes = if goto_else {
240 entry_event_bytes.max(err_path_event_bytes)
241 } else {
242 entry_event_bytes
243 };
244 self.compile_time_event_bytes_upper_bound = else_entry_event_bytes;
245 let mut else_instructions = 0u16;
246 if let Some(else_stmt) = else_body {
247 self.enter_scope();
248 else_instructions += self.compile_statement(else_stmt)?;
249 self.exit_scope();
250 }
251 self.builder
252 .build_unconditional_branch(merge_block)
253 .map_err(|e| {
254 CodeGenError::LLVMError(format!("Failed to branch to merge: {e}"))
255 })?;
256 let else_event_bytes = self.compile_time_event_bytes_upper_bound;
257
258 self.builder.position_at_end(merge_block);
260 self.compile_time_event_bytes_upper_bound = if goto_else {
261 then_event_bytes.max(else_event_bytes)
262 } else {
263 then_event_bytes
264 .max(else_event_bytes)
265 .max(err_path_event_bytes)
266 };
267
268 Ok(std::cmp::max(then_instructions, else_instructions))
270 }
271 Statement::Block(nested_statements) => {
272 let mut total_instructions = 0u16;
273 self.enter_scope();
274 for stmt in nested_statements {
275 total_instructions += self.compile_statement(stmt)?;
276 }
277 self.exit_scope();
278 Ok(total_instructions)
279 }
280 Statement::TracePoint { pattern: _, body } => {
281 let mut total_instructions = 0u16;
282 self.enter_scope();
284 for stmt in body {
285 total_instructions += self.compile_statement(stmt)?;
286 }
287 self.exit_scope();
288 Ok(total_instructions)
289 }
290 _ => {
291 warn!("Unsupported statement type: {:?}", statement);
292 Ok(0)
293 }
294 }
295 }
296
297 pub fn compile_print_statement(&mut self, print_stmt: &PrintStatement) -> Result<u16> {
299 info!("Compiling print statement: {:?}", print_stmt);
300
301 match print_stmt {
302 PrintStatement::String(s) => {
303 info!("Processing string literal: {}", s);
304 let string_index = self.trace_context.add_string(s.to_string());
306 self.generate_print_string_index(string_index)?;
308 Ok(1) }
310 PrintStatement::Variable(var_name) => {
311 info!("Processing variable: {}", var_name);
312 let expr = crate::script::Expr::Variable(var_name.clone());
313 let arg = self.resolve_expr_to_arg(&expr)?;
314 let n = self.emit_print_from_arg(arg)?;
315 tracing::trace!(
316 var_name = %var_name,
317 instructions = n,
318 "compile_print_statement: emitted via unified resolver"
319 );
320 Ok(n)
321 }
322 PrintStatement::ComplexVariable(expr) => {
323 info!("Processing complex variable: {:?}", expr);
324 let arg = self.compile_print_expr_with_builtin_exprerror(expr, |ctx| {
325 ctx.resolve_expr_to_arg(expr)
326 })?;
327 let n = self.emit_print_from_arg(arg)?;
328 tracing::trace!(
329 instructions = n,
330 "compile_print_statement: emitted via unified resolver"
331 );
332 Ok(n)
333 }
334 PrintStatement::Formatted { format, args } => {
335 info!(
336 "Processing formatted print: '{}' with {} args",
337 format,
338 args.len()
339 );
340 self.compile_formatted_print(format, args)
341 }
342 }
343 }
344}