2
2
from llvmlite import ir
3
3
from logging import Logger
4
4
import logging
5
+ from typing import Dict
5
6
6
7
logger : Logger = logging .getLogger (__name__ )
7
8
8
9
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
+
9
91
def eval_expr (
10
92
func ,
11
93
module ,
@@ -17,64 +99,28 @@ def eval_expr(
17
99
):
18
100
logger .info (f"Evaluating expression: { ast .dump (expr )} " )
19
101
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 )
27
103
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 )
35
105
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
+
36
109
# delayed import to avoid circular dependency
37
110
from pythonbpf .helper import HelperHandlerRegistry , handle_helper_call
38
111
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
+ )
78
124
elif isinstance (expr .func , ast .Attribute ):
79
125
logger .info (f"Handling method call: { ast .dump (expr .func )} " )
80
126
if isinstance (expr .func .value , ast .Call ) and isinstance (
@@ -106,19 +152,7 @@ def eval_expr(
106
152
structs_sym_tab ,
107
153
)
108
154
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 )
122
156
logger .info ("Unsupported expression evaluation" )
123
157
return None
124
158
0 commit comments