ITADN

MIR Lowering: Complete HIR→MIR for Complex Types

#699Closedgakonst 创建于 2026-01-14
C-enhancementE-hardA-semaA-codegen
G
gakonstcommented
## Summary Extend MIR lowering to fully handle Solidity's complex types: structs, arrays (fixed and dynamic), mappings, bytes, and string. **Parent issue:** #687 ## Context Current lowering handles basic expressions and some builtins, but complex types are stubbed out with placeholder `zero` values. Solidity's rich type system needs to be lowered to: - Pointer arithmetic for struct field access - Index computations for arrays - Keccak256-based slot computation for mappings - Proper memory/storage/calldata distinction ## Tasks ### MIR type & operation support - [ ] Ensure `Type` can represent: - Structs (named/anonymous) as memory/storage pointers - Static arrays (`T[N]`) and dynamic arrays (`T[]`) - Mappings as storage pointers - `bytes` and `string` as dynamic types - [ ] Add MIR ops/intrinsics for: - `load`/`store` in memory and storage - Array length access - Index computations with bounds checking ### Struct lowering - [ ] Compute struct layouts (field offsets, alignment) - [ ] Lower field access: `base_ptr + field_offset` - [ ] Handle nested structs - [ ] Memory vs storage struct semantics ### Array lowering - [ ] Fixed-size arrays: `base + index * element_size` - [ ] Dynamic arrays (storage): - Length stored at slot, data at `keccak256(slot)` - Index: `keccak256(slot) + index * element_size` - [ ] Dynamic arrays (memory): - Length at base, data at `base + 32` - [ ] Bounds checking (optional based on compiler flags) ### Mapping lowering - [ ] Storage slot computation: `keccak256(abi.encode(key, slot))` - [ ] Handle nested mappings: `keccak256(key2, keccak256(key1, slot))` - [ ] Support various key types (address, uint, bytes32, etc.) ### ABI-aware layout - [ ] Match Solidity's ABI/storage layout decisions exactly - [ ] Create `layout` module used by lowering - [ ] Handle packed storage (multiple values in one slot) ## Example: Mapping Access ```solidity mapping(address => uint256) balances; function get(address a) returns (uint256) { return balances[a]; } ``` Lowers to MIR: ``` entry: v0 = arg(0) ; address a v1 = const 0 ; storage slot of balances v2 = abi_encode(v0, v1) ; encode key and slot v3 = keccak256(v2) ; compute storage slot v4 = sload(v3) ; load value return v4 ``` ## Patterns to follow **From Sonatina:** - Clean modeling of aggregate types via MIR ops - Separation of layout logic and IR transformation **From Venom:** - Practical handling of memory/storage addresses - Masking/shifting as dedicated primitives ## Acceptance Criteria - [ ] Contracts with structs, arrays, mappings compile and run correctly - [ ] Behavior matches solc-compiled versions - [ ] MIR pretty-printer shows clear sequences for complex type ops - [ ] Storage layout matches solc exactly ## Estimated Complexity **Large** - Many type combinations, need exact compatibility with solc ## Dependencies - MIR structure (done) - #696 or #697 (Stack scheduling) should handle expanded instruction sequences
关闭于 2026-05-16 3 条评论