From 45e6ce5e5cf268a286cc3c56f8c426eb7f1762df Mon Sep 17 00:00:00 2001 From: Pragyansh Chaturvedi Date: Mon, 13 Oct 2025 04:01:27 +0530 Subject: [PATCH] Move deref_to_depth to expr/ir_ops.py --- pythonbpf/expr/__init__.py | 3 +- pythonbpf/expr/ir_ops.py | 50 ++++++++++++++++++++++++++++ pythonbpf/expr/type_normalization.py | 49 ++------------------------- 3 files changed, 54 insertions(+), 48 deletions(-) create mode 100644 pythonbpf/expr/ir_ops.py diff --git a/pythonbpf/expr/__init__.py b/pythonbpf/expr/__init__.py index 4b1dac8..4e8f82d 100644 --- a/pythonbpf/expr/__init__.py +++ b/pythonbpf/expr/__init__.py @@ -1,5 +1,6 @@ from .expr_pass import eval_expr, handle_expr, get_operand_value, CallHandlerRegistry -from .type_normalization import convert_to_bool, get_base_type_and_depth, deref_to_depth +from .type_normalization import convert_to_bool, get_base_type_and_depth +from .ir_ops import deref_to_depth __all__ = [ "eval_expr", diff --git a/pythonbpf/expr/ir_ops.py b/pythonbpf/expr/ir_ops.py new file mode 100644 index 0000000..70f7415 --- /dev/null +++ b/pythonbpf/expr/ir_ops.py @@ -0,0 +1,50 @@ +import logging +from llvmlite import ir + +logger = logging.getLogger(__name__) + + +def deref_to_depth(func, builder, val, target_depth): + """Dereference a pointer to a certain depth.""" + + cur_val = val + cur_type = val.type + + for depth in range(target_depth): + if not isinstance(val.type, ir.PointerType): + logger.error("Cannot dereference further, non-pointer type") + return None + + # dereference with null check + pointee_type = cur_type.pointee + null_check_block = builder.block + not_null_block = func.append_basic_block(name=f"deref_not_null_{depth}") + merge_block = func.append_basic_block(name=f"deref_merge_{depth}") + + null_ptr = ir.Constant(cur_type, None) + is_not_null = builder.icmp_signed("!=", cur_val, null_ptr) + logger.debug(f"Inserted null check for pointer at depth {depth}") + + builder.cbranch(is_not_null, not_null_block, merge_block) + + builder.position_at_end(not_null_block) + dereferenced_val = builder.load(cur_val) + logger.debug(f"Dereferenced to depth {depth - 1}, type: {pointee_type}") + builder.branch(merge_block) + + builder.position_at_end(merge_block) + phi = builder.phi(pointee_type, name=f"deref_result_{depth}") + + zero_value = ( + ir.Constant(pointee_type, 0) + if isinstance(pointee_type, ir.IntType) + else ir.Constant(pointee_type, None) + ) + phi.add_incoming(zero_value, null_check_block) + + phi.add_incoming(dereferenced_val, not_null_block) + + # Continue with phi result + cur_val = phi + cur_type = pointee_type + return cur_val diff --git a/pythonbpf/expr/type_normalization.py b/pythonbpf/expr/type_normalization.py index fec53a4..bb5e83b 100644 --- a/pythonbpf/expr/type_normalization.py +++ b/pythonbpf/expr/type_normalization.py @@ -1,6 +1,7 @@ -from llvmlite import ir import logging import ast +from llvmlite import ir +from .ir_ops import deref_to_depth logger = logging.getLogger(__name__) @@ -26,52 +27,6 @@ def get_base_type_and_depth(ir_type): return cur_type, depth -def deref_to_depth(func, builder, val, target_depth): - """Dereference a pointer to a certain depth.""" - - cur_val = val - cur_type = val.type - - for depth in range(target_depth): - if not isinstance(val.type, ir.PointerType): - logger.error("Cannot dereference further, non-pointer type") - return None - - # dereference with null check - pointee_type = cur_type.pointee - null_check_block = builder.block - not_null_block = func.append_basic_block(name=f"deref_not_null_{depth}") - merge_block = func.append_basic_block(name=f"deref_merge_{depth}") - - null_ptr = ir.Constant(cur_type, None) - is_not_null = builder.icmp_signed("!=", cur_val, null_ptr) - logger.debug(f"Inserted null check for pointer at depth {depth}") - - builder.cbranch(is_not_null, not_null_block, merge_block) - - builder.position_at_end(not_null_block) - dereferenced_val = builder.load(cur_val) - logger.debug(f"Dereferenced to depth {depth - 1}, type: {pointee_type}") - builder.branch(merge_block) - - builder.position_at_end(merge_block) - phi = builder.phi(pointee_type, name=f"deref_result_{depth}") - - zero_value = ( - ir.Constant(pointee_type, 0) - if isinstance(pointee_type, ir.IntType) - else ir.Constant(pointee_type, None) - ) - phi.add_incoming(zero_value, null_check_block) - - phi.add_incoming(dereferenced_val, not_null_block) - - # Continue with phi result - cur_val = phi - cur_type = pointee_type - return cur_val - - def _normalize_types(func, builder, lhs, rhs): """Normalize types for comparison."""