$ show lac-dcc/honey-potion
Honey Potion is a compiler framework that translates a subset of the Elixir programming language into eBPF (extended Berkeley Packet Filter) programs, targeting both tracepoints and XDP. The system works as an Elixir library (published on Hex as `honey`) where users write eBPF logic in Elixir using macros like `@sec`, `defmap`, and `fuel`. At compile time, `__before_compile__` triggers a pipeline: static analysis, optimization (constant propagation, dead code elimination, type propagation), AST-to-C translation, boilerplate generation, and C compilation via `make`/`clang`/`llc`/`bpftool`. The generated C code includes a custom runtime with heap, tuple pool, and string pool implemented using BPF maps to overcome eBPF's stack and memory constraints. The repository includes 20+ example programs (system monitors, packet filters, data structure demos) and a comprehensive benchmark suite comparing hand-written C eBPF programs to Honey-generated ones, supporting a published research paper. Although classified as an application (a compiler library), the project has strong research characteristics with reproducible artifact scripts, optimizer variants, and performance comparisons.
The LLM identified 5 files worth highlighting for reuse:
Implements constant propagation on the Elixir AST using a refinement lattice, tracking variable values through basic blocks. Accepts an AST with type annotations and returns a new AST with constants folded. The module is self-contained (imports only `Honey.Type`, `Honey.TypeSet`, and `Honey.Utils.Guard`) and can be extracted as a standalone AST transformation library for any Elixir DSL compiler.
Performs forward type propagation on the Elixir AST, building a mapping of variables to their resolved types (from `Honey.Analysis.ElixirTypes` and `Honey.TypeSet`). Returns an AST annotated with type metadata that can drive code generation decisions. The `TPContext` struct manages variable type state across branches. This module is isolated enough to serve as a generic type inference pass for domain-specific compilers targeting typed languages.
Provides liveness analysis, scope detection, and dead variable identification on the Elixir AST. Outputs a set of live variables at each program point and a list of dead variable names. The analysis uses a backward pass over basic blocks and is fully self-contained (depends only on `Honey.Analysis.ASTSize` and basic Elixir AST traversal). This pattern is directly reusable for any Elixir compiler needing register allocation or dead code elimination.
Implements a custom runtime for executing Elixir-like data structures inside eBPF programs. Provides heap, string pool, and tuple pool as BPF maps, along with helper functions for allocation (`sum`, `equals`, `to_bool`, `store_in_heap`, `store_in_string_pool`, `store_in_tuple_pool`). All functions return an `OpResult` struct with an exception flag, enabling error handling via `goto CATCH`. Although generated code references specific struct names (`Generic`, `OpResult`), the pattern of using BPF maps as memory pools with bounds checking is a reusable design for any language targeting eBPF with complex data structures.
Implements the `fuel` macro for bounded recursion in eBPF-friendly code. The macro wraps a function call with a decrementing fuel counter and a guard that raises an exception when fuel runs out. This is a self-contained pattern (uses only Elixir macros and basic AST manipulation) that can be extracted as a general recursion limiter for any eBPF DSL or any environment where unbounded recursion is prohibited.