Draft
Conversation
c19da28 to
b72d7fd
Compare
sbillig
reviewed
Jan 22, 2026
| /// | ||
| /// For simple test files (no explicit contract): A wrapper function calls the entry | ||
| /// and then does `evm_stop`, preserving internal function call semantics. | ||
| fn create_objects(&mut self) -> Result<(), LowerError> { |
Collaborator
There was a problem hiding this comment.
- all functions reachable via calls from
%entrywill be automatically included.%includeis for including functions that don't appear in the call graph - to find the contract runtime and ini functions, you should look for the
contract_init(Foo)/contract_runtime(Foo)attributes (or whatever they are). Look elsewhere in MIR/codegen for how these are found, and share code. - contract init objects aren't currently being created
sbillig
reviewed
Jan 25, 2026
crates/codegen/Cargo.toml
Outdated
Comment on lines
14
to
16
| sonatina-ir = { path = "../../../sonatina/crates/ir" } | ||
| sonatina-triple = { path = "../../../sonatina/crates/triple" } | ||
| sonatina-codegen = { path = "../../../sonatina/crates/codegen" } |
Collaborator
Author
|
@sbillig quick heads up: if you want report bundles for failing Sonatina tests, run: That writes a single tarball with |
e086cd8 to
05f5287
Compare
Introduce codegen backend abstraction for multi-target support: - Backend trait with compile() method returning Yul or Bytecode - YulBackend wrapping existing emit_module_yul - SonatinaBackend stub (not yet implemented) - --backend flag for fe check command (yul/sonatina)
Implement the core structure for lowering Fe MIR to Sonatina IR: - Add sonatina-ir and sonatina-triple dependencies - Create sonatina module with ModuleLowerer for translating functions - Implement type mapping (all EVM values are I256) - Implement basic terminator lowering (Return, Goto, Branch) - Wire up SonatinaBackend to call the new compile_module function The lowering currently handles function declarations, block structure, and control flow. MIR instruction lowering is stubbed for Phase 2.
Add comprehensive MIR-to-Sonatina IR lowering: - Lower synthetic values (integers, booleans, bytes) to I256 immediates - Lower unary operations (not, minus, bitnot, plus) - Lower binary operations (arithmetic, comparison, logical) - Lower basic rvalues (ZeroInit, Value, Load) - Lower terminators with proper value resolution - Add num-bigint dependency for BigUint handling - Use EVM-specific division/modulo instructions (EvmSdiv, EvmSmod) Instruction lowering is scaffolded with TODOs for: - Function calls, memory allocation, intrinsics - Aggregate initialization, stores, discriminants - Control flow phi nodes
- Match MIR IntrinsicOp::Mload shape - Preserve local mapping when lowering terminators - Align shift operand order with EVM semantics - Use unsigned div/mod and big-endian bytes immediates - Use Osaka target triple and wire EvmExp
Add proper dispatching for load/store operations based on address space: - Memory: Mload/Mstore - Storage: EvmSload/EvmSstore - TransientStorage: EvmTload/EvmTstore - Calldata: EvmCalldataLoad (read-only) Places with projections are rejected for now.
Add name_map to track symbol name → FuncRef mappings, enabling calls to be resolved by their monomorphized symbol names. Lowers both regular arguments and effect arguments, emitting Sonatina Call instructions.
Add the full compilation pipeline from Fe MIR to EVM bytecode: - Add sonatina-codegen dependency for EVM code generation - Create Sonatina Objects with runtime sections after lowering - Wire up EvmObjectBackend and compile_object in SonatinaBackend - Extract bytecode from compiled runtime section artifact The Sonatina backend now produces actual EVM bytecode instead of returning an error stub.
ControlFlowResult values are converted to Local values during MIR lowering (in lower_if). If one reaches codegen, it indicates a bug in the MIR lowering pipeline, so return an error instead of silently returning zero.
Add support for projections in load/store operations: - Add lower_place_address function that walks projection paths - Handle Field, VariantField, Discriminant, and Index projections - Use slot-based offsets for storage, byte-based for memory - Support both constant and dynamic array indices - Thread database and layout through function signatures This enables the Sonatina backend to handle struct field access, enum variant access, and array indexing for both memory and storage.
Address reviewer feedback on the Sonatina backend: - Fix call signature mismatch: include effect_param_locals in signatures and argument mapping - Fix call return type: track callee return types instead of hardcoding I256 - Fix PlaceRef projections: use lower_place_address for full path computation - Make InitAggregate/SetDiscriminant return Unsupported instead of silent no-op - Fix Terminator::Unreachable to emit EvmInvalid instead of clean return - Fix ValueOrigin::FuncItem to error instead of silently returning 0 - Use body.place_address_space() instead of custom helper with wrong default - Thread db/target_layout through lower_value for projection address computation - Add TODO documentation for SSA phi nodes, entry block, and object semantics Also add docs/backend-equivalence-testing.md proposal for differential testing between Yul and Sonatina backends using revm and Halmos.
Add from_word and to_word conversions matching Yul emitter semantics: - from_word (after load): - bool: convert to 0 or 1 via Ne comparison - unsigned sub-word: Trunc then Zext to mask high bits - signed sub-word: Trunc then Sext for sign extension - to_word (before store): - bool: iszero(iszero(value)) to normalize - unsigned sub-word: Trunc then Zext to mask - signed: pass through (already sign-extended) Deep-copy for by-ref aggregates is not yet implemented and returns an Unsupported error. This matches the Yul emitter's recursive field-by-field copy logic which needs separate implementation.
Add emit_module_sonatina_ir() to export human-readable Sonatina IR text, and create snapshot tests for all 74 codegen fixtures. Snapshots are stored in fixtures/sonatina_ir/ to avoid conflicting with Yul snapshots. This provides visibility into the IR structure between MIR and bytecode, making it easier to debug lowering issues and review generated IR. 72 fixtures generate IR successfully; 2 are skipped due to missing intrinsics (create2, child contract init).
Contract runtime entrypoints (dispatch functions) are now executed directly by the EVM without a wrapper function. They emit `evm_stop` instead of internal `Return` since the EVM needs an explicit halt opcode. Simple test files still use the wrapper approach to preserve internal function call semantics for functions that return values. Also adds optional EVM instruction tracing via FE_TRACE_EVM env var.
Replace manual Solidity-style memory allocation (mload/mstore 0x40) with Sonatina's EvmMalloc instruction. This delegates memory management to Sonatina's codegen, avoiding conflicts with its stack frame handling. Note: EvmMalloc lowering is not yet implemented in Sonatina's EVM backend, so tests requiring memory allocation are temporarily disabled. Once Sonatina implements EvmMalloc, these tests should pass.
Sonatina's evm-codegen branch now implements EvmMalloc lowering, so struct_init and match_enum_with_data fixtures compile successfully.
Remove FE_TEST_SONATINA gating in contract-harness tests, fix StorageMap scratch memory for Sonatina runs, and add a build script to rerun codegen tests when fixtures change.
Add Sonatina test-module emission for , including runtime bytecode plumbing and necessary layout/codegen adjustments.
- Add `fe test` flags for Sonatina backend and debug outputs (EVM trace, symtab, stackify)\n- Write traces/symtabs to files via `--debug-dir` for easier human debugging\n- Adjust stdlib allocator to avoid backend-reserved memory\n- Update codegen snapshots and add Sonatina operand collection regression tests
- Sort code-region reachability and embeds for deterministic section layout\n- Sort cycle-detection traversal for stable errors\n- Ignore local stackify/trace artifacts
Set `SONATINA_DISABLE_TRANSIENT_MALLOC=1` for the `fe test --backend sonatina` runner to avoid transient-allocation overlap corrupting heap-backed values during Fe tests.
Only default `SONATINA_DISABLE_TRANSIENT_MALLOC=1` when not already set, so developers can repro transient-malloc issues with `SONATINA_DISABLE_TRANSIENT_MALLOC=0`.
Expose Sonatina's transient malloc analysis trace via `fe test` flags and support writing it to `--debug-dir/sonatina_transient_malloc_trace.txt`.
Stop forcing a Sonatina transient-malloc disable env var from ; the backend now handles allocation safety directly.
Make accept multiple files/directories (like ), and expand quoted glob patterns via the crate. Also namespace per-test EVM trace filenames by input suite to avoid collisions when running batches.
Add fe test --report[=<out.tar.gz>] to write a shareable report bundle containing inputs, Sonatina/Yul IR, compiled bytecode, and debug traces (EVM trace, Sonatina symtab, transient-malloc trace).
Add per-suite tarball reports for fe test (report-dir, report-failed-only), including MIR + backend artifacts; keep running on compile/codegen errors; capture codegen panics into the report. Add Sonatina IR layout validation (used in reports) and fix internal-call argument masking after ZST erasure.
Add "fe check --report" (tar.gz) and "--report-failed-only", sharing the same report helpers used by fe test. Reports include inputs, MIR, backend output (Yul or bytecode), Sonatina IR + validation, and captured codegen panics with backtraces.
Refresh Sonatina IR fixture snapshots after SSA/trivial-phi behavior changes upstream.
05f5287 to
1d65d28
Compare
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
No description provided.