22from llvmlite import ir
33from logging import Logger
44import logging
5+ from typing import Dict
56
67logger : Logger = logging .getLogger (__name__ )
78
89
10+ def _handle_name_expr (expr : ast .Name , local_sym_tab : Dict , builder : ir .IRBuilder ):
11+ """Handle ast.Name expressions."""
12+ if expr .id in local_sym_tab :
13+ var = local_sym_tab [expr .id ].var
14+ val = builder .load (var )
15+ return val , local_sym_tab [expr .id ].ir_type
16+ else :
17+ logger .info (f"Undefined variable { expr .id } " )
18+ return None
19+
20+
21+ def _handle_constant_expr (expr : ast .Constant ):
22+ """Handle ast.Constant expressions."""
23+ if isinstance (expr .value , int ):
24+ return ir .Constant (ir .IntType (64 ), expr .value ), ir .IntType (64 )
25+ elif isinstance (expr .value , bool ):
26+ return ir .Constant (ir .IntType (1 ), int (expr .value )), ir .IntType (1 )
27+ else :
28+ logger .info ("Unsupported constant type" )
29+ return None
30+
31+
32+ def _handle_attribute_expr (
33+ expr : ast .Attribute ,
34+ local_sym_tab : Dict ,
35+ structs_sym_tab : Dict ,
36+ builder : ir .IRBuilder ,
37+ ):
38+ """Handle ast.Attribute expressions for struct field access."""
39+ if isinstance (expr .value , ast .Name ):
40+ var_name = expr .value .id
41+ attr_name = expr .attr
42+ if var_name in local_sym_tab :
43+ var_ptr , var_type , var_metadata = local_sym_tab [var_name ]
44+ logger .info (f"Loading attribute { attr_name } from variable { var_name } " )
45+ logger .info (f"Variable type: { var_type } , Variable ptr: { var_ptr } " )
46+
47+ metadata = structs_sym_tab [var_metadata ]
48+ if attr_name in metadata .fields :
49+ gep = metadata .gep (builder , var_ptr , attr_name )
50+ val = builder .load (gep )
51+ field_type = metadata .field_type (attr_name )
52+ return val , field_type
53+ return None
54+
55+
56+ def _handle_deref_call (expr : ast .Call , local_sym_tab : Dict , builder : ir .IRBuilder ):
57+ """Handle deref function calls."""
58+ logger .info (f"Handling deref { ast .dump (expr )} " )
59+ if len (expr .args ) != 1 :
60+ logger .info ("deref takes exactly one argument" )
61+ return None
62+
63+ arg = expr .args [0 ]
64+ if (
65+ isinstance (arg , ast .Call )
66+ and isinstance (arg .func , ast .Name )
67+ and arg .func .id == "deref"
68+ ):
69+ logger .info ("Multiple deref not supported" )
70+ return None
71+
72+ if isinstance (arg , ast .Name ):
73+ if arg .id in local_sym_tab :
74+ arg_ptr = local_sym_tab [arg .id ].var
75+ else :
76+ logger .info (f"Undefined variable { arg .id } " )
77+ return None
78+ else :
79+ logger .info ("Unsupported argument type for deref" )
80+ return None
81+
82+ if arg_ptr is None :
83+ logger .info ("Failed to evaluate deref argument" )
84+ return None
85+
86+ # Load the value from pointer
87+ val = builder .load (arg_ptr )
88+ return val , local_sym_tab [arg .id ].ir_type
89+
90+
991def eval_expr (
1092 func ,
1193 module ,
@@ -17,64 +99,28 @@ def eval_expr(
1799):
18100 logger .info (f"Evaluating expression: { ast .dump (expr )} " )
19101 if isinstance (expr , ast .Name ):
20- if expr .id in local_sym_tab :
21- var = local_sym_tab [expr .id ].var
22- val = builder .load (var )
23- return val , local_sym_tab [expr .id ].ir_type # return value and type
24- else :
25- logger .info (f"Undefined variable { expr .id } " )
26- return None
102+ return _handle_name_expr (expr , local_sym_tab , builder )
27103 elif isinstance (expr , ast .Constant ):
28- if isinstance (expr .value , int ):
29- return ir .Constant (ir .IntType (64 ), expr .value ), ir .IntType (64 )
30- elif isinstance (expr .value , bool ):
31- return ir .Constant (ir .IntType (1 ), int (expr .value )), ir .IntType (1 )
32- else :
33- logger .info ("Unsupported constant type" )
34- return None
104+ return _handle_constant_expr (expr )
35105 elif isinstance (expr , ast .Call ):
106+ if isinstance (expr .func , ast .Name ) and expr .func .id == "deref" :
107+ return _handle_deref_call (expr , local_sym_tab , builder )
108+
36109 # delayed import to avoid circular dependency
37110 from pythonbpf .helper import HelperHandlerRegistry , handle_helper_call
38111
39- if isinstance (expr .func , ast .Name ):
40- # check deref
41- if expr .func .id == "deref" :
42- logger .info (f"Handling deref { ast .dump (expr )} " )
43- if len (expr .args ) != 1 :
44- logger .info ("deref takes exactly one argument" )
45- return None
46- arg = expr .args [0 ]
47- if (
48- isinstance (arg , ast .Call )
49- and isinstance (arg .func , ast .Name )
50- and arg .func .id == "deref"
51- ):
52- logger .info ("Multiple deref not supported" )
53- return None
54- if isinstance (arg , ast .Name ):
55- if arg .id in local_sym_tab :
56- arg = local_sym_tab [arg .id ].var
57- else :
58- logger .info (f"Undefined variable { arg .id } " )
59- return None
60- if arg is None :
61- logger .info ("Failed to evaluate deref argument" )
62- return None
63- # Since we are handling only name case, directly take type from sym tab
64- val = builder .load (arg )
65- return val , local_sym_tab [expr .args [0 ].id ].ir_type
66-
67- # check for helpers
68- if HelperHandlerRegistry .has_handler (expr .func .id ):
69- return handle_helper_call (
70- expr ,
71- module ,
72- builder ,
73- func ,
74- local_sym_tab ,
75- map_sym_tab ,
76- structs_sym_tab ,
77- )
112+ if isinstance (expr .func , ast .Name ) and HelperHandlerRegistry .has_handler (
113+ expr .func .id
114+ ):
115+ return handle_helper_call (
116+ expr ,
117+ module ,
118+ builder ,
119+ func ,
120+ local_sym_tab ,
121+ map_sym_tab ,
122+ structs_sym_tab ,
123+ )
78124 elif isinstance (expr .func , ast .Attribute ):
79125 logger .info (f"Handling method call: { ast .dump (expr .func )} " )
80126 if isinstance (expr .func .value , ast .Call ) and isinstance (
@@ -106,19 +152,7 @@ def eval_expr(
106152 structs_sym_tab ,
107153 )
108154 elif isinstance (expr , ast .Attribute ):
109- if isinstance (expr .value , ast .Name ):
110- var_name = expr .value .id
111- attr_name = expr .attr
112- if var_name in local_sym_tab :
113- var_ptr , var_type , var_metadata = local_sym_tab [var_name ]
114- logger .info (f"Loading attribute { attr_name } from variable { var_name } " )
115- logger .info (f"Variable type: { var_type } , Variable ptr: { var_ptr } " )
116- metadata = structs_sym_tab [var_metadata ]
117- if attr_name in metadata .fields :
118- gep = metadata .gep (builder , var_ptr , attr_name )
119- val = builder .load (gep )
120- field_type = metadata .field_type (attr_name )
121- return val , field_type
155+ return _handle_attribute_expr (expr , local_sym_tab , structs_sym_tab , builder )
122156 logger .info ("Unsupported expression evaluation" )
123157 return None
124158
0 commit comments