@@ -22,7 +22,7 @@ def get_probe_string(func_node):
2222 return "helper"
2323
2424
25- def handle_assign (module , builder , stmt , map_sym_tab , local_sym_tab ):
25+ def handle_assign (func , module , builder , stmt , map_sym_tab , local_sym_tab ):
2626 """Handle assignment statements in the function body."""
2727 if len (stmt .targets ) != 1 :
2828 print ("Unsupported multiassignment" )
@@ -74,48 +74,113 @@ def handle_assign(module, builder, stmt, map_sym_tab, local_sym_tab):
7474 map_ptr = map_sym_tab [map_name ]
7575 if method_name in helper_func_list :
7676 handle_helper_call (
77- rval , module , builder , None , local_sym_tab , map_sym_tab )
77+ rval , module , builder , func , local_sym_tab , map_sym_tab )
7878 else :
7979 print ("Unsupported assignment call structure" )
8080 else :
8181 print ("Unsupported assignment call function type" )
8282
8383
84- def handle_if_statement (module , builder , stmt , map_sym_tab , local_sym_tab ):
85- pass
86-
87-
88- def handle_expr (module , builder , expr , local_sym_tab , map_sym_tab ):
84+ def handle_expr (func , module , builder , expr , local_sym_tab , map_sym_tab ):
8985 """Handle expression statements in the function body."""
9086 call = expr .value
87+ print (f"Handling expression: { ast .dump (call )} " )
9188 if isinstance (call , ast .Call ):
9289 if isinstance (call .func , ast .Name ):
9390 # check for helpers first
9491 if call .func .id in helper_func_list :
9592 handle_helper_call (
96- call , module , builder , None , local_sym_tab , map_sym_tab )
93+ call , module , builder , func , local_sym_tab , map_sym_tab )
9794 return
98- print ("Unsupported expression statement" )
95+ elif isinstance (call , ast .Name ):
96+ if call .id in local_sym_tab :
97+ var = local_sym_tab [call .id ]
98+ val = builder .load (var )
99+ return val
100+ else :
101+ print (f"Undefined variable { call .id } " )
102+ return None
103+ elif isinstance (call , ast .Constant ):
104+ if isinstance (call .value , int ):
105+ return ir .Constant (ir .IntType (64 ), call .value )
106+ elif isinstance (call .value , bool ):
107+ return ir .Constant (ir .IntType (1 ), int (call .value ))
108+ else :
109+ print ("Unsupported constant type" )
110+ return None
111+ else :
112+ print ("Unsupported expression statement" )
113+
114+
115+ def handle_cond (func , module , builder , cond , local_sym_tab , map_sym_tab ):
116+ if isinstance (cond , ast .Constant ):
117+ if isinstance (cond .value , bool ):
118+ return ir .Constant (ir .IntType (1 ), int (cond .value ))
119+ elif isinstance (cond .value , int ):
120+ return ir .Constant (ir .IntType (1 ), int (bool (cond .value )))
121+ else :
122+ print ("Unsupported constant type in condition" )
123+ return None
124+ elif isinstance (cond , ast .Name ):
125+ if cond .id in local_sym_tab :
126+ var = local_sym_tab [cond .id ]
127+ val = builder .load (var )
128+ return val
129+ else :
130+ print (f"Undefined variable { cond .id } in condition" )
131+ return None
132+ else :
133+ print ("Unsupported condition expression" )
134+ return None
99135
100136
101- def handle_if (module , builder , stmt , map_sym_tab , local_sym_tab ):
137+ def handle_if (func , module , builder , stmt , map_sym_tab , local_sym_tab ):
102138 """Handle if statements in the function body."""
103- func = builder .block .parent
139+ print ("Handling if statement" )
140+ start = builder .block .parent
104141 then_block = func .append_basic_block (name = "if.then" )
105142 merge_block = func .append_basic_block (name = "if.end" )
106143
107- cond = stmt .test
144+ cond = handle_cond (func , module , builder , stmt .test ,
145+ local_sym_tab , map_sym_tab )
108146
109147 builder .cbranch (cond , then_block , merge_block )
110148 builder .position_at_end (then_block )
111149 for s in stmt .body :
112- pass
150+ process_stmt (func , module , builder , s ,
151+ local_sym_tab , map_sym_tab , False )
113152 if not builder .block .is_terminated :
114153 builder .branch (merge_block )
115154
116155 builder .position_at_end (merge_block )
117156
118157
158+ def process_stmt (func , module , builder , stmt , local_sym_tab , map_sym_tab , did_return , ret_type = ir .IntType (64 )):
159+ print (f"Processing statement: { ast .dump (stmt )} " )
160+ if isinstance (stmt , ast .Expr ):
161+ handle_expr (func , module , builder , stmt , local_sym_tab , map_sym_tab )
162+ elif isinstance (stmt , ast .Assign ):
163+ handle_assign (func , module , builder , stmt , map_sym_tab , local_sym_tab )
164+ elif isinstance (stmt , ast .If ):
165+ handle_if (func , module , builder , stmt , map_sym_tab , local_sym_tab )
166+ elif isinstance (stmt , ast .Return ):
167+ if stmt .value is None :
168+ builder .ret (ir .Constant (ir .IntType (32 ), 0 ))
169+ did_return = True
170+ elif isinstance (stmt .value , ast .Call ) and isinstance (stmt .value .func , ast .Name ) and len (stmt .value .args ) == 1 and isinstance (stmt .value .args [0 ], ast .Constant ) and isinstance (stmt .value .args [0 ].value , int ):
171+ call_type = stmt .value .func .id
172+ if ctypes_to_ir (call_type ) != ret_type :
173+ raise ValueError ("Return type mismatch: expected"
174+ f"{ ctypes_to_ir (call_type )} , got { call_type } " )
175+ else :
176+ builder .ret (ir .Constant (
177+ ret_type , stmt .value .args [0 ].value ))
178+ did_return = True
179+ else :
180+ print ("Unsupported return value" )
181+ return did_return
182+
183+
119184def process_func_body (module , builder , func_node , func , ret_type , map_sym_tab ):
120185 """Process the body of a bpf function"""
121186 # TODO: A lot. We just have print -> bpf_trace_printk for now
@@ -124,27 +189,9 @@ def process_func_body(module, builder, func_node, func, ret_type, map_sym_tab):
124189 local_sym_tab = {}
125190
126191 for stmt in func_node .body :
127- if isinstance (stmt , ast .Expr ):
128- handle_expr (module , builder , stmt , local_sym_tab , map_sym_tab )
129- elif isinstance (stmt , ast .Assign ):
130- handle_assign (module , builder , stmt , map_sym_tab , local_sym_tab )
131- elif isinstance (stmt , ast .If ):
132- handle_if (module , builder , stmt , map_sym_tab , local_sym_tab )
133- elif isinstance (stmt , ast .Return ):
134- if stmt .value is None :
135- builder .ret (ir .Constant (ir .IntType (32 ), 0 ))
136- did_return = True
137- elif isinstance (stmt .value , ast .Call ) and isinstance (stmt .value .func , ast .Name ) and len (stmt .value .args ) == 1 and isinstance (stmt .value .args [0 ], ast .Constant ) and isinstance (stmt .value .args [0 ].value , int ):
138- call_type = stmt .value .func .id
139- if ctypes_to_ir (call_type ) != ret_type :
140- raise ValueError ("Return type mismatch: expected"
141- f"{ ctypes_to_ir (call_type )} , got { call_type } " )
142- else :
143- builder .ret (ir .Constant (
144- ret_type , stmt .value .args [0 ].value ))
145- did_return = True
146- else :
147- print ("Unsupported return value" )
192+ did_return = process_stmt (func , module , builder , stmt , local_sym_tab ,
193+ map_sym_tab , did_return , ret_type )
194+
148195 if not did_return :
149196 builder .ret (ir .Constant (ir .IntType (32 ), 0 ))
150197
0 commit comments