From 40ae3d825ad8638497f0d3e3e0566c3d32b81f48 Mon Sep 17 00:00:00 2001 From: varun-r-mallya Date: Sat, 4 Oct 2025 06:32:25 +0530 Subject: [PATCH] fix broken IR generation logic for globals --- pythonbpf/globals_pass.py | 7 ++-- tests/failing_tests/globals.py | 67 ++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 4 deletions(-) diff --git a/pythonbpf/globals_pass.py b/pythonbpf/globals_pass.py index 4178f0f..198d813 100644 --- a/pythonbpf/globals_pass.py +++ b/pythonbpf/globals_pass.py @@ -34,11 +34,11 @@ def emit_global(module: ir.Module, node, name): # constructor call like "return c_int64(0)" or dataclass(...) elif isinstance(init_val, ast.Call): - if len(init_val.args) == 1 and isinstance(init_val.args[0], ast.Constant): + if len(init_val.args) >= 1 and isinstance(init_val.args[0], ast.Constant): llvm_init = ir.Constant(ty, init_val.args[0].value) else: - raise ValueError(f"Complex constructor not supported: {ast.dump(init_val)}") - + logger.info("Defaulting to zero as no constant argument found") + llvm_init = ir.Constant(ty, 0) else: raise ValueError(f"Unsupported return expr {ast.dump(init_val)}") @@ -49,7 +49,6 @@ def emit_global(module: ir.Module, node, name): gvar.global_constant = False return gvar - def globals_processing(tree, module): """Process stuff decorated with @bpf and @bpfglobal except license and return the section name""" globals_sym_tab = [] diff --git a/tests/failing_tests/globals.py b/tests/failing_tests/globals.py index 05ac5fd..6b914fd 100644 --- a/tests/failing_tests/globals.py +++ b/tests/failing_tests/globals.py @@ -18,6 +18,73 @@ def somevalue2() -> c_int64: def somevalue1() -> c_int32: return c_int32(0) +import ast +from dataclasses import dataclass +from typing import List + +# --- Passing examples --- + +# Simple constant return +@bpf +@bpfglobal +def g1() -> c_int64: + return 42 + +# Constructor with one constant argument +@bpf +@bpfglobal +def g2() -> c_int64: + return c_int64(0) + + +# --- Failing examples --- + +# No return annotation +# @bpf +# @bpfglobal +# def g3(): +# return 42 + +# Return annotation is complex +# @bpf +# @bpfglobal +# def g4() -> List[int]: +# return [] + +# # Return is missing +# @bpf +# @bpfglobal +# def g5() -> c_int64: +# pass + +# # Return is a variable reference +# #TODO: maybe fix this sometime later. It defaults to 0 +CONST = 5 +@bpf +@bpfglobal +def g6() -> c_int64: + return c_int64(CONST) + +# Constructor with multiple args +#TODO: this is not working. should it work ? +@bpf +@bpfglobal +def g7() -> c_int64: + return c_int64(1, 2) + +# Dataclass call +#TODO: fails with dataclass +# @dataclass +# class Point: +# x: c_int64 +# y: c_int64 + +# @bpf +# @bpfglobal +# def g8() -> Point: +# return Point(1, 2) + + @bpf @section("tracepoint/syscalls/sys_enter_execve") def sometag(ctx: c_void_p) -> c_int64: