Skip to content

Simplify arity implementation #2236

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 12, 2025

Conversation

alexcrichton
Copy link
Member

Originally the annotations in the for_each_operator! macro were intended to be used to implement the validator in addition to arity, but during the PR this part was removed and the annotations were only used for arity. As such the macro/annotations were a bit more complicated than they might otherwise need to be. Coupled with #2235 where some changes may be needed to arity calculations the macro was a bit difficult to understand. As a result this commit simplifies the arity annotations to either:

  • arity N -> N
  • arity custom

All "custom" instructions are now written as Rust functions in the arity.rs module. They delegate to each other internally as appropriate in a similar manner to how the macro calculated before.

Overall this passes tests but I can clarify that I only have a tenuous understanding at best of the previous macro. I did my best to faithfully translate it from what it used to be but it's possible I got something wrong along the way.

Originally the annotations in the `for_each_operator!` macro were
intended to be used to implement the validator in addition to arity, but
during the PR this part was removed and the annotations were only used
for arity. As such the macro/annotations were a bit more complicated
than they might otherwise need to be. Coupled with bytecodealliance#2235 where some
changes may be needed to arity calculations the macro was a bit
difficult to understand. As a result this commit simplifies the arity
annotations to either:

* `arity N -> N`
* `arity custom`

All "custom" instructions are now written as Rust functions in the
`arity.rs` module. They delegate to each other internally as appropriate
in a similar manner to how the macro calculated before.

Overall this passes tests but I can clarify that I only have a tenuous
understanding at best of the previous macro. I did my best to faithfully
translate it from what it used to be but it's possible I got something
wrong along the way.
@alexcrichton alexcrichton requested a review from a team as a code owner June 12, 2025 21:51
@alexcrichton alexcrichton requested review from dicej and removed request for a team June 12, 2025 21:51
@keithw
Copy link
Contributor

keithw commented Jun 12, 2025

On changing the macro, no real objection from me if you prefer this style. I did think there was some elegance in being able to define the arity of each instruction in terms of a small number of composable primitives, e.g.:

Block { blockty: $crate::BlockType } => visit_block (arity block -> ~block)`
Loop { blockty: $crate::BlockType } => visit_loop (arity block -> ~block)
If { blockty: $crate::BlockType } => visit_if (arity 1 block -> ~block)

vs.

Block { blockty: $crate::BlockType } => visit_block (arity custom)
Loop { blockty: $crate::BlockType } => visit_loop (arity custom)
If { blockty: $crate::BlockType } => visit_if (arity custom)

and having a separate custom function for each one of these. But I think this is a matter of taste, and I'm new to Rust, so fine with me if you want to change it to a less macro-heavy approach.

What I would prudentially maybe avoid is changing the FuncValidator code (that tests the correctness of the arity computation) at the same time as changing the arity computation itself. Although I realize it's a pretty small change here so the risk is low.

Copy link
Member

@fitzgen fitzgen left a comment

Choose a reason for hiding this comment

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

I find this version easier to follow, thanks!

@fitzgen fitzgen added this pull request to the merge queue Jun 12, 2025
Merged via the queue into bytecodealliance:main with commit ad9d38b Jun 12, 2025
32 checks passed
@alexcrichton alexcrichton deleted the simplify-arity branch June 13, 2025 14:21
@alexcrichton
Copy link
Member Author

@keithw for me and historically my experience in Rust has been that heavy usage of macros can lead to difficult-to-understand code so I try to avoid it where possible, and then if a big macro is necessary I try to keep it as simple as possible. In that sense I do agree with your sentiments but the way I would frame it is that the building blocks are the ModuleArity trait and instead of a custom DSL (e.g. block -> ~block) the definitions are now Rust functions. It's definitely wordier than before but understanding/modifying arity doesn't require first learning the DSL now which I think will be good for maintainability over time.

Also agreed on not changing FuncValidator! I improved the error message but otherwise have no intention on changing it more deeply.

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.

4 participants