Skip to content

Thread length into static array ABI hashing#1864

Merged
Th0rgal merged 1 commit into
mainfrom
codex/abi-static-array-length-arg
May 14, 2026
Merged

Thread length into static array ABI hashing#1864
Th0rgal merged 1 commit into
mainfrom
codex/abi-static-array-length-arg

Conversation

@Th0rgal
Copy link
Copy Markdown
Member

@Th0rgal Th0rgal commented May 14, 2026

Summary

  • change abiEncodeStaticArray to take the array length as an explicit expression argument
  • update feature tests for the length-threaded ECM shape

This avoids the zero-argument ecmCall source-surface edge case while preserving the ABI layout helper added in #1863.

Verification

  • lake build Compiler.Modules.Hashing Compiler.CompilationModelFeatureTest
  • lake build PrintAxioms
  • python3 scripts/generate_print_axioms.py --check
  • python3 scripts/check_axioms.py
  • git diff --check

Note

Medium Risk
Medium risk because it changes the abiEncodeStaticArray ECM call surface/arity and threads length through codegen, which could break callers or alter hashing if the wrong length expression is provided.

Overview
abiEncodeStaticArray is refactored so the ECM takes the dynamic array length as an explicit expression argument (numArgs 0→1) instead of implicitly reading {arrayParam}_length, and the generated Yul now uses that provided length when writing the ABI head/length and computing payload byte size.

Feature tests are updated to pass Expr.arrayLength into Compiler.Modules.Hashing.abiEncodeStaticArray, and the bad-arity regression now expects the new 1-arg ECM shape (updated compile-error message/inputs).

Reviewed by Cursor Bugbot for commit b511cec. Bugbot is set up for automated code reviews on this repo. Configure here.

@Th0rgal Th0rgal merged commit 12522e3 into main May 14, 2026
2 of 3 checks passed
@Th0rgal Th0rgal deleted the codex/abi-static-array-length-arg branch May 14, 2026 11:13
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b511cec. Configure here.

]),
YulStmt.let_ dataBytesName (YulExpr.call "mul" [
YulExpr.ident s!"{arrayParam}_length",
arrayLengthExpr,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Array length expression inlined twice without binding

Low Severity

arrayLengthExpr is used twice in the generated Yul block (in mstore at the first use and mul at the second) without being bound to a Yul let variable first. The old code was inherently safe because it hardcoded YulExpr.ident s!"{arrayParam}_length", always a simple variable reference. The new code accepts an arbitrary compiled YulExpr, which gets duplicated in the AST. Other modules in the same file (e.g., abiEncodePackedWordsModule) use packedWordBindings to bind each argument expression to a local before use. Introducing a let binding for the length expression would match the established convention and prevent double evaluation if a non-trivial expression is ever supplied.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b511cec. Configure here.

@github-actions
Copy link
Copy Markdown
Contributor

\n### CI Failure Hints\n\nFailed jobs: `checks`\n\nCopy-paste local triage:\n```bash\nmake check\nlake build\nFOUNDRY_PROFILE=difftest forge test -vv\n```

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