Skip to content

Complex pipeline: sidecars, dynamic libraries, address prediction, init+runtime bytecode#11

Merged
GlebRadchenko merged 13 commits intomainfrom
complex-pipeline
Feb 6, 2026
Merged

Complex pipeline: sidecars, dynamic libraries, address prediction, init+runtime bytecode#11
GlebRadchenko merged 13 commits intomainfrom
complex-pipeline

Conversation

@GlebRadchenko
Copy link
Owner

@GlebRadchenko GlebRadchenko commented Feb 4, 2026


name: Pull Request
about: Submit a pull request

Description

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Transpiler fix (changes to venom_generator.py or related transpilation logic)
  • Backend fix (changes to vyper/ fork - requires justification)
  • Documentation update

Testing

  • Tests pass locally (cd foundry && forge test)
  • Transpilation works (python3.11 testing/test_framework.py --test-all)
  • New tests added (if applicable)

Benchmark Impact

Checklist

  • My code follows the project's coding style
  • I have performed a self-review
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

Related Issues

@GlebRadchenko GlebRadchenko requested a review from Copilot February 4, 2026 19:50
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

yul2venom/yul2venom.py

Lines 1625 to 1631 in 8979fbb

# Step 4: Write Output
if runtime_only:
# Runtime-only mode: just write runtime bytecode
if runtime_bytecode:
with open(output_path, "wb") as f:
f.write(runtime_bytecode)
print()

P2 Badge Append sidecars in runtime-only output

When --runtime-only is used, this block writes only runtime_bytecode and never appends sidecar_bytecodes. If the deployed runtime uses dataoffset()/datasize() to reference embedded sidecar bytecode (e.g., CREATE/CREATE2 in runtime), those references will now point past the end of the deployed code and the sidecar deployment will fail. The full bytecode path appends sidecars later, so runtime-only output should mirror that layout or sidecar-enabled contracts will break in bench/repro runs that use runtime-only artifacts.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR significantly refactors the Yul→Venom pipeline to handle complex immutable ID mapping, nested sidecars, and category-aware testing/transpilation, while also adding debugging and benchmarking tools and normalizing configs/paths.

Changes:

  • Reworked yul2venom.py to derive immutable IDs and deployment ordering directly from Yul, support nested sidecars (including two-pass init/runtime sizing and dataoffset/datasize fixes), and make Yul path handling/configs more robust.
  • Enhanced the testing framework with smarter contract discovery and category-aware transpilation (transpile_for_testing), added multi-return and inlining debug tools, and wired these into CI workflows.
  • Updated Vyper submodule, optimizer rules, IR conventions (ret/invoke), generator return handling, config JSONs (adding sidecar_nonce_start, order, and normalized deployers), test bytecode paths, and gitignore.

Reviewed changes

Copilot reviewed 74 out of 75 changed files in this pull request and generated no comments.

Show a summary per file
File Description
yul2venom.py Core pipeline changes: Yul path handling, immutable ID discovery, sidecar support, dataoffset/datasize layout, config generation updates.
vyper Submodule bumped to a newer Vyper fork to align with updated IR/backend conventions.
testing/test_framework.py Adds contract discovery, bytecode-type-aware transpilation (transpile_for_testing), and refines test execution paths.
testing/debug_multi_return.py New CLI tool to debug multi-return/stack behavior and correlate with Forge tests.
testing/config_benchmark.py New script to benchmark different inlining configurations against representative contracts.
optimizer/yul_source_optimizer.py Adds/extends source-level Yul optimization rules for calldata checks, panics, address/type validation, and helpers.
ir/basicblock.py Adjusts operand ordering semantics in IR printing (no global reversal; special-case invoke).
generator/venom_generator.py Changes return generation to use temp vars via add and orders ret operands as values-first, PC-last.
foundry/test/StateTest.t.sol Updates runtime binary paths to ../output/... relative to foundry/.
foundry/test/SolcRefTest.t.sol Same output path normalization for solc reference runtime.
foundry/test/SolcComparisonTest.t.sol Normalizes paths for solc vs transpiler comparison binaries.
foundry/test/RuntimeInspectTest.t.sol Normalizes path to transpiled init+runtime binary.
foundry/test/OpcodeTest.t.sol Normalizes opcode test/runtime binary paths.
foundry/test/MinimalLoopTest.t.sol Normalizes path to minimal loop runtime binary.
foundry/test/LoopTraceTest.t.sol Normalizes path to loop trace init binary.
foundry/test/LoopDebugTest.t.sol Normalizes path to loop-debug init binary.
foundry/test/FeatureTest.t.sol Normalizes and clarifies usage of various feature test binaries (init and runtime).
foundry/test/ExtendedFeatureTest.t.sol Normalizes path to MissingFeatures runtime binary.
foundry/test/DebugLoopCheck.t.sol Normalizes path to LoopCheckCalldata runtime binary.
foundry/test/ControlFlowTest.t.sol Normalizes paths for loop-check runtime binaries (including alternate filename).
debug/raw_ir.vnm Updates stored raw VNM IR for multi-return debugging.
debug/opt_ir.vnm Updates optimized VNM IR snapshot for multi-return debugging.
debug/config_benchmark.json Adds stored benchmark results for inlining config comparison.
testing/**/*.json configs (many) Normalize deployers, add sidecar_nonce_start, order, and id metadata for immutables/sidecars.
configs/repro/LoopSwitchRepro.yul2venom.json Replaces deleted root config with repro-specific one and normalized deployment data.
configs/init/*.yul2venom.json Adds sidecar_nonce_start and richer constructor/auto-predicted metadata for init contracts.
configs/bench/*.yul2venom.json Adds sidecar_nonce_start and, where relevant, immutable ordering metadata for bench contracts.
configs/StorageMemory.yul2venom.json Removes redundant/old StorageMemory config (StorageMemoryTest config remains).
configs/Modifiers.yul2venom.json Removes duplicate bench Modifiers config in root; bench one retained under configs/bench.
configs/LoopSwitchRepro.yul2venom.json Removes root LoopSwitchRepro config in favor of configs/repro version.
configs/ControlFlow.yul2venom.json Removes root ControlFlow bench config in favor of configs/bench/ControlFlow.
configs/AdvancedFeatures.yul2venom.json Removes root AdvancedFeatures config in favor of bench config.
.gitignore Ignores per-config output dirs and VNM intermediates.
.github/workflows/transpile-test.yml Switches CI to test_framework.py --test-all for category-aware transpile+test.
.github/workflows/benchmark.yml Reuses transpile_for_testing() logic for benchmark setup when cache miss occurs.
Comments suppressed due to low confidence (6)

yul2venom.py:1

  • The fallback path for optimized Yul without @src comments only populates offset_to_id but never offset_to_name, so sorted_offsets and name_to_order remain empty and no constructor/auto-predicted entries get order or updated IDs in that case, contrary to the comment. To make the fallback effective, you should either also populate offset_to_name when using setimm_no_src_pattern (e.g., by deriving names from some other mapping) or guard the subsequent name_to_order and name-based update logic so it does not assume offset_to_name is non-empty.
    yul2venom.py:1
  • In transpile_object, failures compiling a sub-object are now logged but no longer cause the function to return an error or raise, so the pipeline can continue and emit bytecode even though some sub-objects failed to transpile. To preserve previous behavior and fail fast on such errors, either re-raise the exception here or return a sentinel error value (e.g., return 1) and have callers check for it before proceeding.
    testing/debug_multi_return.py:1
  • If subprocess.run raises (e.g., timeout), the function returns from the except block before restoring the working directory back to PROJECT_ROOT, leaving the process stuck in foundry/. Wrap the os.chdir(PROJECT_ROOT) in a finally block so the working directory is restored regardless of success or failure.
    testing/debug_multi_return.py:1
  • This code transpiles with --runtime-only (which typically only produces *_opt_runtime.bin) but then copies from output/MultiReturnTest_opt.bin, which may not exist under runtime-only mode and will cause the cp to fail. Either drop the --runtime-only flag here (so _opt.bin is produced) or change the source of the copy to the runtime-only filename that is actually generated.
    yul2venom.py:1
  • discover_sidecar_immutables(raw_yul, name_to_value) scans the entire Yul source with a regex on every sub-object iteration, even though the inputs (raw_yul, name_to_value) are constant for the whole transpilation run. To avoid redundant work, compute the mapping once outside the loop (or cache it) and reuse it per sub-object, optionally filtering per sub-object if needed.
    yul2venom.py:1
  • discover_sidecar_immutables(raw_yul, name_to_value) scans the entire Yul source with a regex on every sub-object iteration, even though the inputs (raw_yul, name_to_value) are constant for the whole transpilation run. To avoid redundant work, compute the mapping once outside the loop (or cache it) and reuse it per sub-object, optionally filtering per sub-object if needed.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 4, 2026

🔬 Yul2Venom CI Report

Stage Status
Tests ✅ passed
Benchmark ✅ success

✅ Test Results

  [core ] TinyCall                       ... ✓ 51 bytes [both] (347ms)
  [core ] TryCatchRepro                  ... ✓ 211 bytes [both] (367ms)
  [core ] VoidCall                       ... ✓ 42 bytes [both] (341ms)
  [init ] InitArrayTest                  ... ✓ 899 bytes [init] (608ms)
  [init ] InitCodeTest                   ... ✓ 147 bytes [init] (369ms)
  [init ] InitComplexTest                ... ✓ 646 bytes [init] (494ms)
  [init ] InitConstructorArgsTest        ... ✓ 485 bytes [init] (448ms)
  [init ] InitImmutableTest              ... ✓ 437 bytes [init] (434ms)
  [init ] InitInheritanceTest            ... ✓ 794 bytes [init] (512ms)
  [init ] InitMultiImmutableTest         ... ✓ 1027 bytes [init] (561ms)
  [init ] InitNewChildTest               ... ✓ 3569 bytes [init] (1302ms)
  [init ] InitPayableTest                ... ✓ 133 bytes [init] (365ms)
  [init ] InitStringTest                 ... ✓ 2323 bytes [init] (1151ms)
  [repro] CallOrderRepro                 ... ✓ 125 bytes [both] (350ms)
  [repro] LoopSwitchRepro                ... ✓ 470 bytes [both] (408ms)
============================================================
Results: 47 passed, 0 failed, 47 total
Results saved to /home/runner/work/yul2venom/yul2venom/debug/transpile_results.json
Running Forge tests...
Test Results: 358 passed, 0 failed

📊 Benchmark Results

Yul2Venom Benchmark Report

Generated: 2026-02-06 18:54:46
Baseline: default_200


Summary

  • Contracts benchmarked: 8
  • Transpilation success: 8/8
  • Optimization runs tested: [200]
  • Solc modes: ['default', 'via_ir', 'ir_optimized']

Bytecode Size (bytes)

Contract Transpiled default_200 via_ir_200 ir_optimized
Arithmetic 1586 1368 1368 1650
ControlFlow 1002 962 962 1043
StateManagement 2234 2686 2686 2981
DataStructures 1392 1576 1576 2031
Functions 2051 2452 2452 3477
Events 735 826 826 1163
Encoding 961 976 976 1264
Edge 2694 3112 3112 3787

Size Delta vs Baseline (default_200)

Contract Transpiled via_ir_200 ir_optimized
Arithmetic +15.9% +0.0% +20.6%
ControlFlow +4.2% +0.0% +8.4%
StateManagement -16.8% +0.0% +11.0%
DataStructures -11.7% +0.0% +28.9%
Functions -16.4% +0.0% +41.8%
Events -11.0% +0.0% +40.8%
Encoding -1.5% +0.0% +29.5%
Edge -13.4% +0.0% +21.7%

Gas Usage (avg gas per function call)

Arithmetic

Function Transpiled (aggressive+yul-o2) Native (Solc default_200) Delta
and_ 186 485 -61.6%
eq 201 287 -30.0%
gt 186 221 -15.8%
gte 189 642 -70.6%
iszero 160 770 -79.2%
lt 195 191 +2.1%
lte 189 796 -76.3%
not_ 160 707 -77.4%
or_ 201 331 -39.3%
safeAdd 244 799 -69.5%
safeDiv 246 697 -64.7%
safeExp 314 524 -40.1%
safeMod 208 477 -56.4%
safeMul 246 783 -68.6%
safeSub 221 601 -63.2%
sar 166 559 -70.3%
sgt 186 265 -29.8%
shl 209 529 -60.5%
shr 186 463 -59.8%
signExtend16 171 652 -73.8%
signExtend8 193 365 -47.1%
slt 186 353 -47.3%
unsafeAdd 186 309 -39.8%
unsafeDiv 208 653 -68.1%
unsafeExp 243 564 -56.9%
unsafeMod 254 741 -65.7%
unsafeMul 188 421 -55.3%
unsafeSub 186 551 -66.2%
xor_ 201 243 -17.3%

ControlFlow

Function Transpiled (aggressive+yul-o2) Native (Solc default_200) Delta
breakLoop 1306 1858 -29.7%
continueLoop 1503 1678 -10.4%
earlyReturn 181 354 -48.9%
ifElse 211 294 -28.2%
loopCount 8120 11415 -28.9%
loopSum 683 706 -3.3%
nestedLoop 1513 1778 -14.9%
ternary 229 347 -34.0%
whileLoop 3421 4872 -29.8%

StateManagement

Function Transpiled (aggressive+yul-o2) Native (Solc default_200) Delta
CONST_HASH 154 986 -84.4%
CONST_VALUE 154 876 -82.4%
balances 2358 2533 -6.9%
getArrayElement 443 547 -19.0%
getArrayLength 2253 2245 +0.4%
getMappingValue 2321 2912 -20.3%
getNestedMap 428 1191 -64.1%
getPackedAB 292 547 -46.6%
getStoredBool 2266 2507 -9.6%
getStoredUint 2281 2802 -18.6%
incrementBalance 20315 20593 -1.3%
memoryAlloc 349 726 -51.9%
memoryCopy 1768 3154 -43.9%
popArray 538 1329 -59.5%
pushArray 42450 42720 -0.6%
setMappingValue 20235 21055 -3.9%
setNestedMap 22379 22721 -1.5%
setPackedAB 22333 22998 -2.9%
setStoredBool 20294 20315 -0.1%
setStoredUint 20132 20179 -0.2%

DataStructures

Function Transpiled (aggressive+yul-o2) Native (Solc default_200) Delta
bytesConcat 572 851 -32.8%
bytesLength 224 385 -41.8%
createArray 1585 2099 -24.5%
createStruct 304 510 -40.4%
dynamicArraySum 618 896 -31.0%
fixedArraySum 712 964 -26.1%
processStruct 236 235 +0.4%
processStructArray 1448 2463 -41.2%

Functions

Function Transpiled (aggressive+yul-o2) Native (Solc default_200) Delta
callInternal 207 528 -60.8%
callSelf 692 1171 -40.9%
callVirtualA 142 594 -76.1%
callVirtualB 142 142 +0.0%
factorial 281 487 -42.3%
fibonacci 275 394 -30.2%
interfaceFunc 147 506 -70.9%
nestedInternal 198 302 -34.4%
returnMultiple 178 736 -75.8%
returnNothing 142 350 -59.4%
returnSingle 142 462 -69.3%
selfAdd 184 286 -35.7%

Events

Function Transpiled (aggressive+yul-o2) Native (Solc default_200) Delta
emitBytes 1852 2068 -10.4%
emitComplex 2920 3059 -4.5%
emitIndexed 1581 1676 -5.7%
emitMultiIndexed 2037 2094 -2.7%
emitMultiple 5583 5564 +0.3%
emitSimple 1168 1273 -8.2%
emitString 1822 1969 -7.5%

Encoding

Function Transpiled (aggressive+yul-o2) Native (Solc default_200) Delta
abiEncode 371 603 -38.5%
abiEncodePacked 394 537 -26.6%
abiEncodeWithSelector 356 557 -36.1%
decodePair 228 393 -42.0%
encodeMultiple 655 1005 -34.8%
encodePackedMixed 433 696 -37.8%
keccak256Encode 300 483 -37.9%
keccak256Hash 462 747 -38.2%
keccak256Packed 300 417 -28.1%

Edge

Function Transpiled (aggressive+yul-o2) Native (Solc default_200) Delta
assertCondition 203 565 -64.1%
checkGas 152 728 -79.1%
fallback 189 712 -73.5%
getBlockInfo 188 175 +7.4%
getMsgInfo 221 643 -65.6%
mayFail 302 799 -62.2%
requireTrue 273 598 -54.3%
requireValue 211 433 -51.3%
tryCall 766 1390 -44.9%

Configuration

Setting Value
Baseline default_200
Optimization Runs [200]
Solc Modes ['default', 'via_ir', 'ir_optimized']

Mode Descriptions

  • default: solc --optimize --optimizer-runs=N (traditional optimizer)
  • via_ir: solc --via-ir --optimize --optimizer-runs=N (Yul-based optimizer)
  • ir_optimized: solc --ir-optimized --optimize (outputs optimized Yul IR)
  • Transpiled: Yul → Venom IR → EVM via Yul2Venom

Interpretation

  • Negative delta = smaller than baseline (better)
  • Positive delta = larger than baseline (worse)
  • FAILED = compilation/transpilation failed

Commit: 22d130702ae33349771fa263ad507ed10512666c • 2026-02-06 18:54 UTC

@GlebRadchenko GlebRadchenko requested a review from Copilot February 4, 2026 22:52
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 97 out of 99 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (11)

yul2venom.py:1

  • Bare except ValueError: without handling. Consider logging the error or adding a comment explaining why ignoring is appropriate. If this is intentional (e.g., for hash parsing fallback), add a comment like # Ignore invalid hash format.
    yul2venom.py:1
  • The comment states sidecar_nonce_start is 'ALWAYS 1', but it's added as a configurable field. If there are cases where it might not be 1 (as the config structure suggests), clarify those cases in the comment. Otherwise, consider making it a constant rather than a config field.
    generator/venom_generator.py:1
  • Using add x, 0 to force materialization creates unnecessary ADD instructions. While the optimizer may eliminate these, consider using a dedicated 'materialize' helper or checking if the optimizer consistently removes these identity operations to avoid unnecessary bytecode bloat.
    generator/venom_generator.py:1
  • Duplicate pattern of using add x, 0 for materialization (also at lines 507-512). Consider extracting to a helper method like _materialize_for_ret(val, name) to reduce code duplication and ensure consistent behavior.
    testing/test_framework.py:1
  • Comment states tests need BOTH files, but the transpilation strategy only generates one type per category (init -> --with-init, others -> default). Clarify if 'default' mode generates both files or update the comment to match actual behavior.
    yul2venom.config.yaml:1
  • Comment 'Testing fix for parser compatibility' suggests a temporary debugging change. If this is the intended production value, update the comment to explain why aggressive is appropriate. Otherwise, revert to the documented default.
    generator/optimizations.py:1
  • Multiple bare except ValueError: clauses (5 instances) that silently ignore errors. Consider logging these failures or adding comments explaining why ignoring is safe (e.g., 'Invalid literal format, skip optimization').
    generator/optimizations.py:1
  • Multiple bare except ValueError: clauses (5 instances) that silently ignore errors. Consider logging these failures or adding comments explaining why ignoring is safe (e.g., 'Invalid literal format, skip optimization').
    generator/optimizations.py:1
  • Multiple bare except ValueError: clauses (5 instances) that silently ignore errors. Consider logging these failures or adding comments explaining why ignoring is safe (e.g., 'Invalid literal format, skip optimization').
    generator/optimizations.py:1
  • Multiple bare except ValueError: clauses (5 instances) that silently ignore errors. Consider logging these failures or adding comments explaining why ignoring is safe (e.g., 'Invalid literal format, skip optimization').
    generator/optimizations.py:1
  • Multiple bare except ValueError: clauses (5 instances) that silently ignore errors. Consider logging these failures or adding comments explaining why ignoring is safe (e.g., 'Invalid literal format, skip optimization').

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@GlebRadchenko GlebRadchenko changed the title Complex pipeline Complex pipeline: sidecars, dynamic libraries, address prediction, init+runtime bytecode Feb 4, 2026
@GlebRadchenko GlebRadchenko requested a review from Copilot February 4, 2026 23:01
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 97 out of 99 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (8)

yul2venom.py:1

  • The function docstring mentions 'sidecar's immutable IDs' but doesn't explain what a sidecar is in this context. Consider adding a brief definition (e.g., 'contracts deployed from parent constructor') for clarity.
    yul2venom.py:1
  • Bare except was correctly replaced with except ValueError, but consider whether other exception types (like AttributeError for missing attributes) should also be caught here.
    generator/venom_generator.py:1
  • Using add(x, 0) for all return values forces extra ADD operations that may not be eliminated by optimization. Consider whether this pattern is necessary for literals where stack ordering is already deterministic.
    yul2venom.py:1
  • The fallback pattern when @src comments are missing may fail to map variable names correctly. Consider logging a warning when falling back to this pattern, as it loses semantic information about variable names.
    testing/test_framework.py:1
  • The bytecode type detection relies on directory name matching ('init' in path.parts). This is fragile if directory structure changes. Consider using an explicit config field or convention (e.g., checking for constructor_args in config).
    generator/venom_generator.py:1
  • The 0xFFFF mask for 16-bit extraction is well-documented, but consider adding why this is necessary (prevents memory collision from earlier operations). The comment on line 1192-1193 covers this, but it could be more prominent.
    yul2venom.py:1
  • Excellent documentation of the bytecode layout calculation. No changes needed.
    optimizer/yul_source_optimizer.py:1
  • The improved brace matching using _find_matching_brace is a significant improvement over the previous regex. Well done on handling nested braces correctly.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +242 to +249
# Priority 1: Check yul2venom package directory (where this config.py lives)
package_dir = Path(__file__).parent
for name in DEFAULT_CONFIG_PATHS:
config_path = package_dir / name
if config_path.exists():
return config_path

# Priority 2: Search from CWD upwards (for project-specific overrides)
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The config search priority (package dir first, then CWD upwards) is well-designed. Consider documenting this priority in the docstring for clarity.

Copilot uses AI. Check for mistakes.
@@ -1,4 +1,5 @@
import sys
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The addition of break_sources to the loop stack tuple is necessary for proper SSA construction, but increases the tuple size from 5 to 6 elements. Consider using a named tuple or dataclass for better maintainability.

Copilot uses AI. Check for mistakes.
@GlebRadchenko GlebRadchenko requested a review from Copilot February 5, 2026 01:16
@GlebRadchenko
Copy link
Owner Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3625b3ee22

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

yul2venom.py Outdated
Comment on lines 1665 to 1667
# CRITICAL: Process deepest objects FIRST so their bytecode is available for parents
# Sort by depth descending (deepest first), then by name to ensure _deployed comes before parent
sorted_subobjects = sorted(all_subobjects, key=lambda x: (-x[2], x[1]))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Ensure _deployed subobjects compile before init

Sorting subobjects by name ascending does not guarantee _deployed comes before the init object when they share the same depth (e.g., Sidecar sorts before Sidecar_deployed). In that case the init sidecar is compiled first, the runtime entry is missing in data_map, and the code path falls back to the “No runtime found” branch, which produces incorrect datasize/dataoffset for sidecars. This breaks constructors that embed sidecars and rely on datasize("X_deployed")/dataoffset("X_deployed") in the init code. A custom sort (e.g., prioritizing names ending with _deployed) is needed to preserve the intended dependency order.

Useful? React with 👍 / 👎.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 103 out of 105 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (9)

yul2venom.py:1

  • The example command references 'MyContract' but the prepare command doesn't specify the output path or config location. Consider adding the full command sequence including the -c flag for the config path to make this example more actionable.
    yul2venom.py:1
  • The message references a --force flag that doesn't appear to be defined in the argument parser. Either add the flag or update the message to reflect the actual regeneration mechanism.
    generator/venom_generator.py:1
  • Using add x, 0 as a stack ordering forcing mechanism is fragile. This creates unnecessary instructions that depend on the optimizer eliminating them. Consider documenting why this specific pattern is required for stack ordering or implementing a more explicit ordering mechanism.
    generator/venom_generator.py:1
  • The mask value 0xFFFF (16 bits) should be defined as a named constant to clarify that this is masking a 2-byte label value. This makes the relationship to the copy_size = IRLiteral(2) above more explicit.
    yul2venom.py:1
  • Debug print statements should be removed or placed behind a debug flag before merging to production. These create noise in normal operation.
    testing/test_framework.py:1
  • This comment explains that 'all others' generate both files, but doesn't clarify that init/ contracts ONLY generate the init variant. The comment could be misleading about what files are actually produced for each category.
    optimizer/yul_source_optimizer.py:1
  • The regex pattern for matching balanced parentheses is complex and only handles 2 levels of nesting. For deeply nested expressions, this could fail to match. Consider using a recursive approach or documenting the nesting limitation.
    foundry/test/StateTest.t.sol:1
  • The path uses ../output/ which assumes the test is run from foundry/ directory. This breaks if tests are run from the project root. Consider using a more robust path resolution approach or documenting the required working directory.
    foundry/test/StateTest.t.sol:1
  • The path uses ../output/ which assumes the test is run from foundry/ directory. This breaks if tests are run from the project root. Consider using a more robust path resolution approach or documenting the required working directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@GlebRadchenko
Copy link
Owner Author

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7bbcd393a1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

yul2venom.py Outdated
Comment on lines 230 to 231
if not deployer or not main_nonce:
print(f" [WARN] compute_sidecar_addresses: missing deployment info", file=sys.stderr)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow nonce 0 when computing sidecar addresses

The guard if not deployer or not main_nonce treats nonce=0 as “missing” and returns early, which skips sidecar address recomputation for the common case of the deployer’s first CREATE. That means compute_sidecar_addresses won’t update auto_predicted for default configs where deployment.nonce is 0, so sidecar addresses stay stale even when Yul order changes. Consider only rejecting None/empty values, not zero.

Useful? React with 👍 / 👎.

Comment on lines 1916 to 1926
if runtime_only:
# Runtime-only mode: just write runtime bytecode
# Runtime-only mode: write runtime bytecode + sidecars
# Must match full bytecode layout for dataoffset()/datasize() references
if runtime_bytecode:
output_bytecode = runtime_bytecode

# Append sidecars to match deployed code layout
# This is critical for CREATE/CREATE2 contracts using dataoffset()/datasize()
if sidecar_bytecodes:
for sidecar_name, sidecar_bc in sidecar_bytecodes:
output_bytecode += sidecar_bc

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Runtime-only output can miscompute dataoffsets for multiple sidecars

This appends all sidecar blobs after the runtime and relies on runtime dataoffset() to resolve offsets. But the generator’s runtime path computes dataoffset as codesize - datasize (see VenomIRBuilder._handle_intrinsic), which only yields the start of the last appended blob. With multiple sidecars, any dataoffset("SidecarX") in runtime code will point to the last sidecar instead of the named one. This will break runtime-only tests/contracts that deploy multiple sidecars from runtime using dataoffset/datasize.

Useful? React with 👍 / 👎.

@GlebRadchenko GlebRadchenko merged commit 1b91343 into main Feb 6, 2026
4 checks passed
@GlebRadchenko GlebRadchenko deleted the complex-pipeline branch February 6, 2026 18:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant