-
Notifications
You must be signed in to change notification settings - Fork 3
Refactor assignment statement handling and the typing mechanism around it #40
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 40 commits
Commits
Show all changes
43 commits
Select commit
Hold shift + click to select a range
6008d98
Change loglevel of multi-assignment warning in handle_assign
r41k0u 84ed27f
Add handle_variable_assignment stub and boilerplate in handle_assign
r41k0u d7bfe86
Add handle_variable_assignment to assign_pass
r41k0u 054a834
Add failing assign test retype.py, with explanation
r41k0u c596213
Add cst_var_binop.py as passing assign test
r41k0u 23afb0b
Add deref_to_val to deref into final value and return the chain as we…
r41k0u 1253f51
Use deref_to_val instead of recursive_dereferencer in get_operand value
r41k0u 8bab07e
Remove recursive_dereferencer
r41k0u 489244a
Add store_through_chain
r41k0u 047f361
Allocate twice for map lookups
r41k0u 1d517d4
Add double_alloc in alloc_mem
r41k0u 99aacca
WIP: allow pointer assignments to var
r41k0u 9febadf
Add pointer handling to helper_utils, finish pointer assignment
r41k0u 7529820
Allow int** pointers to store binops of type int** op int
r41k0u a756f5e
Add passing helper test for assignment
r41k0u 3175756
Interpret bools as ints in binops
r41k0u cac88d1
Allow different int widths in binops
r41k0u c2c1774
Remove store_through_chain
r41k0u 91a3fe1
Remove unnecessary return artifacts from get_operand_value
r41k0u c9bbe1f
Call eval_expr properly within get_operand_value
r41k0u 8b7b1c0
Add struct_and_helper_binops passing test for assignments
r41k0u 8776d76
Add count_temps_in_call to call scratch space needed in a helper call
r41k0u 321415f
Add update_max_temps_for_stmt in allocate_mem
r41k0u 6bce29b
Allocate scratch space for temp vars at the end of allocate_mem
r41k0u 5dcf670
Add ScratchPoolManager and it's singleton
r41k0u 207f714
Use scratch space to store consts passed to helpers
r41k0u cd74e89
Allow binops as args to helpers accepting int*
r41k0u d66e6a6
Allow struct members as helper args
r41k0u 2cf68f6
Allow map-based helpers to be used as helper args / within binops whi…
r41k0u 4e33fd4
Add negation UnaryOp
r41k0u a3b4d09
Fix errorstring in _handle_unary_op
r41k0u e8026a1
Allow helpers to be called within themselves
r41k0u fa82dc7
Add comprehensive passing test for assignment
r41k0u b93f704
Tweak the comprehensive assignment test
r41k0u 933d2a5
Fix comprehensive assignment test
r41k0u 105c5a7
Cleanup handle_assign
r41k0u 3ad1b73
Add handle_struct_field_assignment to assign_pass
r41k0u 64e44d0
Use handle_struct_field_assignment in handle_assign
r41k0u 08c0ccf
Pass map_sym_tab to handle_struct_field_assign
r41k0u 0f6971b
Refactor allocate_mem
r41k0u 2f1aaa4
Fix typos
r41k0u 69bee5f
Seperate LocalSymbol from functions
r41k0u e0ad1bf
Move bulk of allocation logic to allocation_pass
r41k0u File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,108 @@ | ||
| import ast | ||
| import logging | ||
| from llvmlite import ir | ||
| from pythonbpf.expr import eval_expr | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
||
|
|
||
| def handle_struct_field_assignment( | ||
| func, module, builder, target, rval, local_sym_tab, map_sym_tab, structs_sym_tab | ||
| ): | ||
| """Handle struct field assignment (obj.field = value).""" | ||
|
|
||
| var_name = target.value.id | ||
| field_name = target.attr | ||
|
|
||
| if var_name not in local_sym_tab: | ||
| logger.error(f"Variable '{var_name}' not found in symbol table") | ||
| return | ||
|
|
||
| struct_type = local_sym_tab[var_name].metadata | ||
| struct_info = structs_sym_tab[struct_type] | ||
|
|
||
| if field_name not in struct_info.fields: | ||
| logger.error(f"Field '{field_name}' not found in struct '{struct_type}'") | ||
| return | ||
|
|
||
| # Get field pointer and evaluate value | ||
| field_ptr = struct_info.gep(builder, local_sym_tab[var_name].var, field_name) | ||
| val = eval_expr( | ||
| func, module, builder, rval, local_sym_tab, map_sym_tab, structs_sym_tab | ||
| ) | ||
|
|
||
| if val is None: | ||
| logger.error(f"Failed to evaluate value for {var_name}.{field_name}") | ||
| return | ||
|
|
||
| # TODO: Handle string assignment to char array (not a priority) | ||
| field_type = struct_info.field_type(field_name) | ||
| if isinstance(field_type, ir.ArrayType) and val[1] == ir.PointerType(ir.IntType(8)): | ||
| logger.warning( | ||
| f"String to char array assignment not implemented for {var_name}.{field_name}" | ||
| ) | ||
| return | ||
|
|
||
| # Store the value | ||
| builder.store(val[0], field_ptr) | ||
| logger.info(f"Assigned to struct field {var_name}.{field_name}") | ||
|
|
||
|
|
||
| def handle_variable_assignment( | ||
| func, module, builder, var_name, rval, local_sym_tab, map_sym_tab, structs_sym_tab | ||
| ): | ||
| """Handle single named variable assignment.""" | ||
|
|
||
| if var_name not in local_sym_tab: | ||
| logger.error(f"Variable {var_name} not declared.") | ||
| return False | ||
|
|
||
| var_ptr = local_sym_tab[var_name].var | ||
| var_type = local_sym_tab[var_name].ir_type | ||
|
|
||
| # NOTE: Special case for struct initialization | ||
| if isinstance(rval, ast.Call) and isinstance(rval.func, ast.Name): | ||
| struct_name = rval.func.id | ||
| if struct_name in structs_sym_tab and len(rval.args) == 0: | ||
| struct_info = structs_sym_tab[struct_name] | ||
| ir_struct = struct_info.ir_type | ||
|
|
||
| builder.store(ir.Constant(ir_struct, None), var_ptr) | ||
| logger.info(f"Initialized struct {struct_name} for variable {var_name}") | ||
| return True | ||
|
|
||
| val_result = eval_expr( | ||
| func, module, builder, rval, local_sym_tab, map_sym_tab, structs_sym_tab | ||
| ) | ||
| if val_result is None: | ||
| logger.error(f"Failed to evaluate value for {var_name}") | ||
| return False | ||
|
|
||
| val, val_type = val_result | ||
| logger.info(f"Evaluated value for {var_name}: {val} of type {val_type}, {var_type}") | ||
| if val_type != var_type: | ||
| if isinstance(val_type, ir.IntType) and isinstance(var_type, ir.IntType): | ||
| # Allow implicit int widening | ||
| if val_type.width < var_type.width: | ||
| val = builder.sext(val, var_type) | ||
| logger.info(f"Implicitly widened int for variable {var_name}") | ||
| elif val_type.width > var_type.width: | ||
| val = builder.trunc(val, var_type) | ||
| logger.info(f"Implicitly truncated int for variable {var_name}") | ||
| elif isinstance(val_type, ir.IntType) and isinstance(var_type, ir.PointerType): | ||
| # NOTE: This is assignment to a PTR_TO_MAP_VALUE_OR_NULL | ||
| logger.info( | ||
| f"Creating temporary variable for pointer assignment to {var_name}" | ||
| ) | ||
| var_ptr_tmp = local_sym_tab[f"{var_name}_tmp"].var | ||
| builder.store(val, var_ptr_tmp) | ||
| val = var_ptr_tmp | ||
| else: | ||
| logger.error( | ||
| f"Type mismatch for variable {var_name}: {val_type} vs {var_type}" | ||
| ) | ||
| return False | ||
|
|
||
| builder.store(val, var_ptr) | ||
| logger.info(f"Assigned value to variable {var_name}") | ||
| return True |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,10 @@ | ||
| from .expr_pass import eval_expr, handle_expr | ||
| from .type_normalization import convert_to_bool | ||
| from .type_normalization import convert_to_bool, get_base_type_and_depth, deref_to_depth | ||
|
|
||
| __all__ = ["eval_expr", "handle_expr", "convert_to_bool"] | ||
| __all__ = [ | ||
| "eval_expr", | ||
| "handle_expr", | ||
| "convert_to_bool", | ||
| "get_base_type_and_depth", | ||
| "deref_to_depth", | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.