8
8
#include < array>
9
9
#include < cassert>
10
10
#include < limits>
11
+ #include < variant>
11
12
12
13
namespace evmone
13
14
{
@@ -21,7 +22,8 @@ constexpr uint8_t MAX_SECTION = DATA_SECTION;
21
22
22
23
using EOFSectionHeaders = std::array<uint16_t , MAX_SECTION + 1 >;
23
24
24
- std::pair<EOFSectionHeaders, EOFValidationError> validate_eof_headers (bytes_view container) noexcept
25
+ std::variant<EOFSectionHeaders, EOFValidationError> validate_eof_headers (
26
+ bytes_view container) noexcept
25
27
{
26
28
enum class State
27
29
{
@@ -46,54 +48,54 @@ std::pair<EOFSectionHeaders, EOFValidationError> validate_eof_headers(bytes_view
46
48
{
47
49
case TERMINATOR:
48
50
if (section_headers[CODE_SECTION] == 0 )
49
- return {{}, EOFValidationError::code_section_missing} ;
51
+ return EOFValidationError::code_section_missing;
50
52
state = State::terminated;
51
53
break ;
52
54
case DATA_SECTION:
53
55
if (section_headers[CODE_SECTION] == 0 )
54
- return {{}, EOFValidationError::code_section_missing} ;
56
+ return EOFValidationError::code_section_missing;
55
57
if (section_headers[DATA_SECTION] != 0 )
56
- return {{}, EOFValidationError::multiple_data_sections} ;
58
+ return EOFValidationError::multiple_data_sections;
57
59
state = State::section_size;
58
60
break ;
59
61
case CODE_SECTION:
60
62
if (section_headers[CODE_SECTION] != 0 )
61
- return {{}, EOFValidationError::multiple_code_sections} ;
63
+ return EOFValidationError::multiple_code_sections;
62
64
state = State::section_size;
63
65
break ;
64
66
default :
65
- return {{}, EOFValidationError::unknown_section_id} ;
67
+ return EOFValidationError::unknown_section_id;
66
68
}
67
69
break ;
68
70
}
69
71
case State::section_size:
70
72
{
71
73
const auto size_hi = *it++;
72
74
if (it == container_end)
73
- return {{}, EOFValidationError::incomplete_section_size} ;
75
+ return EOFValidationError::incomplete_section_size;
74
76
const auto size_lo = *it++;
75
77
const auto section_size = static_cast <uint16_t >((size_hi << 8 ) | size_lo);
76
78
if (section_size == 0 )
77
- return {{}, EOFValidationError::zero_section_size} ;
79
+ return EOFValidationError::zero_section_size;
78
80
79
81
section_headers[section_id] = section_size;
80
82
state = State::section_id;
81
83
break ;
82
84
}
83
85
case State::terminated:
84
- return {{}, EOFValidationError::impossible} ;
86
+ return EOFValidationError::impossible;
85
87
}
86
88
}
87
89
88
90
if (state != State::terminated)
89
- return {{}, EOFValidationError::section_headers_not_terminated} ;
91
+ return EOFValidationError::section_headers_not_terminated;
90
92
91
93
const auto section_bodies_size = section_headers[CODE_SECTION] + section_headers[DATA_SECTION];
92
94
const auto remaining_container_size = container_end - it;
93
95
if (section_bodies_size != remaining_container_size)
94
- return {{}, EOFValidationError::invalid_section_bodies_size} ;
96
+ return EOFValidationError::invalid_section_bodies_size;
95
97
96
- return { section_headers, EOFValidationError::success} ;
98
+ return section_headers;
97
99
}
98
100
99
101
EOFValidationError validate_instructions (evmc_revision rev, bytes_view code) noexcept
@@ -119,21 +121,22 @@ EOFValidationError validate_instructions(evmc_revision rev, bytes_view code) noe
119
121
return EOFValidationError::success;
120
122
}
121
123
122
- std::pair <EOF1Header, EOFValidationError> validate_eof1 (
124
+ std::variant <EOF1Header, EOFValidationError> validate_eof1 (
123
125
evmc_revision rev, bytes_view container) noexcept
124
126
{
125
- const auto [section_headers, error_header] = validate_eof_headers (container);
126
- if (error_header != EOFValidationError::success )
127
- return {{}, error_header} ;
127
+ const auto section_headers_or_error = validate_eof_headers (container);
128
+ if (const auto * error = std::get_if<EOFValidationError>(§ion_headers_or_error) )
129
+ return *error ;
128
130
131
+ const auto & section_headers = std::get<EOFSectionHeaders>(section_headers_or_error);
129
132
EOF1Header header{section_headers[CODE_SECTION], section_headers[DATA_SECTION]};
130
133
131
134
const auto error_instr =
132
135
validate_instructions (rev, {&container[header.code_begin ()], header.code_size });
133
136
if (error_instr != EOFValidationError::success)
134
- return {{}, error_instr} ;
137
+ return error_instr;
135
138
136
- return { header, EOFValidationError::success} ;
139
+ return header;
137
140
}
138
141
139
142
} // namespace
@@ -186,7 +189,12 @@ EOFValidationError validate_eof(evmc_revision rev, bytes_view container) noexcep
186
189
{
187
190
if (rev < EVMC_CANCUN)
188
191
return EOFValidationError::eof_version_unknown;
189
- return validate_eof1 (rev, container).second ;
192
+
193
+ const auto header_or_error = validate_eof1 (rev, container);
194
+ if (const auto * error = std::get_if<EOFValidationError>(&header_or_error))
195
+ return *error;
196
+ else
197
+ return EOFValidationError::success;
190
198
}
191
199
else
192
200
return EOFValidationError::eof_version_unknown;
0 commit comments