Coverage Report

Created: 2026-10-26 06:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/solidity/libyul/backends/evm/EVMBuiltins.h
Line
Count
Source
1
/*
2
  This file is part of solidity.
3
4
  solidity is free software: you can redistribute it and/or modify
5
  it under the terms of the GNU General Public License as published by
6
  the Free Software Foundation, either version 3 of the License, or
7
  (at your option) any later version.
8
9
  solidity is distributed in the hope that it will be useful,
10
  but WITHOUT ANY WARRANTY; without even the implied warranty of
11
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
  GNU General Public License for more details.
13
14
  You should have received a copy of the GNU General Public License
15
  along with solidity.  If not, see <http://www.gnu.org/licenses/>.
16
*/
17
// SPDX-License-Identifier: GPL-3.0
18
19
#pragma once
20
21
#include <libyul/backends/evm/AbstractAssembly.h>
22
23
#include <libyul/Dialect.h>
24
#include <libyul/Scope.h>
25
26
#include <bitset>
27
#include <cstddef>
28
#include <map>
29
#include <optional>
30
#include <tuple>
31
#include <vector>
32
33
namespace solidity::yul
34
{
35
36
class Object;
37
38
/// Context used during code generation.
39
struct BuiltinContext
40
{
41
  Object const* currentObject = nullptr;
42
  /// Mapping from named objects to abstract assembly sub IDs.
43
  std::map<std::string, AbstractAssembly::SubID> subIDs;
44
45
  std::map<Scope::Function const*, AbstractAssembly::FunctionID> functionIDs;
46
};
47
48
struct BuiltinFunctionForEVM: public BuiltinFunction
49
{
50
  std::optional<evmasm::Instruction> instruction;
51
  /// Function to generate code for the given function call and append it to the abstract
52
  /// assembly. Expects all non-literal arguments of the call to be on stack in reverse order
53
  /// (i.e. right-most argument pushed first).
54
  /// Expects the caller to set the source location.
55
  std::function<void(FunctionCall const&, AbstractAssembly&, BuiltinContext&)> generateCode;
56
};
57
58
/// Collection of all possible EVM builtin functions.
59
/// Each builtin can have one (or multiple) scopes, which define whether, e.g., it requires object access.
60
/// Using this class as single source of truth for builtin functions makes sure that these are consistent over
61
/// EVM dialects. If the order were to depend on the EVM dialect - which can easily happen using conditionals -,
62
/// different dialects' builtin handles become inherently incompatible.
63
class EVMBuiltins
64
{
65
  static std::size_t constexpr instructionBit = 0;
66
  static std::size_t constexpr replacedInstructionBit = 1;
67
  static std::size_t constexpr objectAccessBit = 2;
68
69
public:
70
  struct Scopes
71
  {
72
    /// whether the corresponding evm builtin function is an instruction builtin
73
34.0M
    bool instruction() const { return value.test(instructionBit); }
74
    /// whether the corresponding evm builtin has been replaced by another builtin, ie, should be skipped
75
32.1M
    bool replaced() const { return value.test(replacedInstructionBit); }
76
    /// if true, the evm builtin function is only valid when object access is given
77
34.0M
    bool requiresObjectAccess() const { return value.test(objectAccessBit); }
78
79
    Scopes operator|(Scopes const& _other) const
80
0
    {
81
0
      Scopes result = *this;
82
0
      result |= _other;
83
0
      return result;
84
0
    }
85
86
    Scopes& operator|=(Scopes const& _other)
87
0
    {
88
0
      value |= _other.value;
89
0
      return *this;
90
0
    }
91
92
    std::bitset<3> value;
93
  };
94
95
  EVMBuiltins();
96
97
268k
  std::vector<std::tuple<Scopes, BuiltinFunctionForEVM>> const& functions() const { return m_scopesAndFunctions; }
98
99
  /// Creates a verbatim builtin function. These are not part of the usual builtin functions collection and
100
  /// must be cached in the dialect creating them.
101
  static BuiltinFunctionForEVM createVerbatimFunction(size_t _arguments, size_t _returnVariables);
102
  static SideEffects sideEffectsOfInstruction(evmasm::Instruction _instruction);
103
104
private:
105
  static Scopes constexpr instruction{1 << instructionBit};
106
  static Scopes constexpr replaced{1 << replacedInstructionBit};
107
  static Scopes constexpr objectAccess{1 << objectAccessBit};
108
109
  std::vector<std::tuple<Scopes, BuiltinFunctionForEVM>> m_scopesAndFunctions;
110
};
111
112
}