Skip to content

Commit dd3fc74

Browse files
committed
Add support for tuple style multiiassignment in allocation_pass
1 parent 4a79f9b commit dd3fc74

File tree

1 file changed

+47
-34
lines changed

1 file changed

+47
-34
lines changed

pythonbpf/allocation_pass.py

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -25,41 +25,54 @@ def __iter__(self):
2525
def handle_assign_allocation(builder, stmt, local_sym_tab, structs_sym_tab):
2626
"""Handle memory allocation for assignment statements."""
2727

28-
# Validate assignment
29-
if len(stmt.targets) != 1:
30-
logger.warning("Multi-target assignment not supported, skipping allocation")
31-
return
32-
33-
target = stmt.targets[0]
34-
35-
# Skip non-name targets (e.g., struct field assignments)
36-
if isinstance(target, ast.Attribute):
37-
logger.debug(f"Struct field assignment to {target.attr}, no allocation needed")
38-
return
39-
40-
if not isinstance(target, ast.Name):
41-
logger.warning(f"Unsupported assignment target type: {type(target).__name__}")
42-
return
43-
44-
var_name = target.id
45-
rval = stmt.value
46-
47-
# Skip if already allocated
48-
if var_name in local_sym_tab:
49-
logger.debug(f"Variable {var_name} already allocated, skipping")
50-
return
51-
52-
# Determine type and allocate based on rval
53-
if isinstance(rval, ast.Call):
54-
_allocate_for_call(builder, var_name, rval, local_sym_tab, structs_sym_tab)
55-
elif isinstance(rval, ast.Constant):
56-
_allocate_for_constant(builder, var_name, rval, local_sym_tab)
57-
elif isinstance(rval, ast.BinOp):
58-
_allocate_for_binop(builder, var_name, local_sym_tab)
28+
logger.info(f"Handling assignment for allocation: {ast.dump(stmt)}")
29+
30+
# NOTE: Support multi-target assignments (e.g.: a, b = 1, 2)
31+
if isinstance(stmt.targets[0], ast.Tuple):
32+
if not isinstance(stmt.value, ast.Tuple):
33+
logger.warning("Mismatched multi-target assignment, skipping allocation")
34+
return
35+
targets = stmt.targets[0].elts
36+
rvals = stmt.value.elts
37+
if len(targets) != len(rvals):
38+
logger.warning("Mismatched multi-target assignment, skipping allocation")
39+
return
5940
else:
60-
logger.warning(
61-
f"Unsupported assignment value type for {var_name}: {type(rval).__name__}"
62-
)
41+
targets = stmt.targets
42+
rvals = [stmt.value]
43+
44+
for target, rval in zip(targets, rvals):
45+
# Skip non-name targets (e.g., struct field assignments)
46+
if isinstance(target, ast.Attribute):
47+
logger.debug(
48+
f"Struct field assignment to {target.attr}, no allocation needed"
49+
)
50+
continue
51+
52+
if not isinstance(target, ast.Name):
53+
logger.warning(
54+
f"Unsupported assignment target type: {type(target).__name__}"
55+
)
56+
continue
57+
58+
var_name = target.id
59+
60+
# Skip if already allocated
61+
if var_name in local_sym_tab:
62+
logger.debug(f"Variable {var_name} already allocated, skipping")
63+
continue
64+
65+
# Determine type and allocate based on rval
66+
if isinstance(rval, ast.Call):
67+
_allocate_for_call(builder, var_name, rval, local_sym_tab, structs_sym_tab)
68+
elif isinstance(rval, ast.Constant):
69+
_allocate_for_constant(builder, var_name, rval, local_sym_tab)
70+
elif isinstance(rval, ast.BinOp):
71+
_allocate_for_binop(builder, var_name, local_sym_tab)
72+
else:
73+
logger.warning(
74+
f"Unsupported assignment value type for {var_name}: {type(rval).__name__}"
75+
)
6376

6477

6578
def _allocate_for_call(builder, var_name, rval, local_sym_tab, structs_sym_tab):

0 commit comments

Comments
 (0)