Skip to content

Convert verbatim into a single builtin with literal arguments #15805

@cameel

Description

@cameel
Member

Abstract

Currently we have a separate verbatim_<n>i_<m>o(c, ...) builtin for every combination of n and m. We should replace it with a single verbatim() builtin with the first 3 arguments being literal arguments.

Motivation

The current design complicates the implementation, because it has to be treated specially. Internally all other builtins always exist, while verbatim ones are generated on demand. This became problematic especially after #15520, because it makes it harder to give them fixed locations in an array. We rely on the fact that we can't have more than 10000 of them (m and n are limited to 99), but the limit is artificial and we're even considering lifting it eventually.

Yul builtins can have literal arguments - arguments that must always be literals, not variables or expressions, so that their values are known at compilation time. Such arguments can be used for m and n instead. This seems much simpler both for the implementation and for the user.

Open design questions

  • Should we keep the old names reserved or release them?

Specification

  • Remove verbatim_<n>i_<m>o(c, ...) builtins.
  • Define the equivalent verbatim(n, m, c, ...) builtin:
    • Mark the first 3 arguments as literal arguments.
    • Keep the range restrictions for now.
  • Update the docs.

Backwards Compatibility

This is a breaking change for Yul. Solidity and assembly import are unaffected, because verbatim is not available in inline assembly.

Due to not being available in inline assembly verbatim() does not seem widely used. We decided it does not need a deprecation period. We'll swap one version for another in a breaking release.

Activity

added
low effortThere is not much implementation work to be done. The task is very easy or tiny.
low impactChanges are not very noticeable or potential benefits are limited.
must have eventuallySomething we consider essential but not enough to prevent us from releasing Solidity 1.0 without it.
on Jan 31, 2025
changed the title [-]Replace `verbatim_<n>i_<m>o(c)` builtins with a single `verbatim(i, o, c)`[/-] [+]Convert `verbatim` into a single builtin with literal arguments[/+] on Jan 31, 2025
added this to the 0.9.0 milestone on Feb 17, 2025
moved this from Important to Important (needs more planning) in Solidity 0.9 Planningon Feb 17, 2025
moved this from Important (needs more planning) to Important in Solidity 0.9 Planningon Feb 17, 2025
cameel

cameel commented on Mar 10, 2025

@cameel
MemberAuthor

It's actually not clear to me why we went with the original design in the first place. The issue (#10869) did not mention it, while the PR (#11123) used it from the beginning. The other argument already is a literal argument so that option must have been considered. We could not come up with a good reason the last time we discussed it and it seems that there are no significant obstacles to changing it to work that way.

Well, it turns out that the reason is pretty obvious. Each builtin has a different number of arguments and outputs. The only alternative would be something with variadic args and we don't have that in Yul.

Only seeing this from the C++ implementation side and looking at the generated assembly I somehow missed the fact that in Yul you can't just put the inputs on the stack directly and they must be passed in via arguments. I should have realized this earlier, but TBH when I asked why it is the way it is no one else seemed to be able to explain it either.

In any case, we won't be able to do it the way I proposed here so I'm closing the issue. Unfortunately this still leaves us with a somewhat problematic mechanism for generating these builtins dynamically.

cameel

cameel commented on Mar 10, 2025

@cameel
MemberAuthor

After discussing with @ekpyron, it's actually still viable. Since the values of literal arguments are known ahead of time, we can make the function signature depend on them.

Having the literal args mixed in with normal ones makes it feel like a more dynamic mechanism, but we could get their values even during parsing if needed, so it really won't be that much different from extracting the numbers of inputs and outputs out of the function name.

IMO we should also consider introducing some special syntax for literal arguments.

reopened this on Mar 10, 2025
moved this from Done to Important in Solidity 0.9 Planningon Mar 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    breaking change ⚠️low effortThere is not much implementation work to be done. The task is very easy or tiny.low impactChanges are not very noticeable or potential benefits are limited.must have eventuallySomething we consider essential but not enough to prevent us from releasing Solidity 1.0 without it.

    Type

    No type

    Projects

    Status

    Important

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @cameel@ekpyron

        Issue actions

          Convert `verbatim` into a single builtin with literal arguments · Issue #15805 · ethereum/solidity