33from logging import Logger
44import logging
55
6- from pythonbpf .expr import get_base_type_and_depth , deref_to_depth
6+ from pythonbpf .expr import get_base_type_and_depth , deref_to_depth , eval_expr
77
88logger : Logger = logging .getLogger (__name__ )
99
1010
1111def get_operand_value (func , operand , builder , local_sym_tab ):
1212 """Extract the value from an operand, handling variables and constants."""
13+ logger .info (f"Getting operand value for: { ast .dump (operand )} " )
1314 if isinstance (operand , ast .Name ):
1415 if operand .id in local_sym_tab :
1516 var = local_sym_tab [operand .id ].var
@@ -27,6 +28,12 @@ def get_operand_value(func, operand, builder, local_sym_tab):
2728 elif isinstance (operand , ast .BinOp ):
2829 res = handle_binary_op_impl (func , operand , builder , local_sym_tab )
2930 return res , [res ], None
31+ elif isinstance (operand , ast .Call ):
32+ res = eval_expr (func , None , builder , operand , local_sym_tab , {}, {})
33+ if res is None :
34+ raise ValueError (f"Failed to evaluate call expression: { operand } " )
35+ val , val_type = res
36+ return val , [val ], None
3037 raise TypeError (f"Unsupported operand type: { type (operand )} " )
3138
3239
@@ -48,6 +55,14 @@ def handle_binary_op_impl(func, rval, builder, local_sym_tab):
4855
4956 logger .info (f"left chain: { lchain } , right chain: { rchain } " )
5057
58+ # NOTE: Before doing the operation, if the operands are integers
59+ # we always extend them to i64. The assignment to LHS will take
60+ # care of truncation if needed.
61+ if isinstance (left .type , ir .IntType ) and left .type .width < 64 :
62+ left = builder .sext (left , ir .IntType (64 ))
63+ if isinstance (right .type , ir .IntType ) and right .type .width < 64 :
64+ right = builder .sext (right , ir .IntType (64 ))
65+
5166 # Map AST operation nodes to LLVM IR builder methods
5267 op_map = {
5368 ast .Add : builder .add ,
0 commit comments