Skip to content

Commit cdf2f00

Browse files
committed
[test] Add support for --enforce-compile-to-ewasm.
1 parent 982c4b7 commit cdf2f00

File tree

3 files changed

+69
-81
lines changed

3 files changed

+69
-81
lines changed

test/boostTest.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ int registerTests(
7979
_enforceViaYul,
8080
_enforceCompileToEwasm,
8181
solidity::test::CommonOptions::get().enforceGasTest,
82-
solidity::test::CommonOptions::get().enforceGasTestMinValue
82+
solidity::test::CommonOptions::get().enforceGasTestMinValue,
8383
};
8484
if (fs::is_directory(fullpath))
8585
{

test/libsolidity/SemanticTest.cpp

Lines changed: 62 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -61,51 +61,41 @@ SemanticTest::SemanticTest(
6161
m_enforceViaYul(_enforceViaYul),
6262
m_enforceCompileToEwasm(_enforceCompileToEwasm),
6363
m_enforceGasCost(_enforceGasCost),
64-
m_enforceGasCostMinValue(_enforceGasCostMinValue)
64+
m_enforceGasCostMinValue(std::move(_enforceGasCostMinValue))
6565
{
6666
initializeBuiltins();
6767

68-
string choice = m_reader.stringSetting("compileViaYul", "default");
69-
if (choice == "also")
70-
{
71-
m_runWithYul = true;
72-
m_runWithoutYul = true;
73-
}
74-
else if (choice == "true")
75-
{
76-
m_runWithYul = true;
77-
m_runWithoutYul = false;
78-
}
79-
else if (choice == "false")
68+
static set<string> const compileViaYulAllowedValues{"also", "true", "false", "default"};
69+
static set<string> const yulRunTriggers{"also", "true"};
70+
static set<string> const legacyRunTriggers{"also", "false", "default"};
71+
72+
string compileViaYul = m_reader.stringSetting("compileViaYul", "default");
73+
if (!contains(compileViaYulAllowedValues, compileViaYul))
74+
BOOST_THROW_EXCEPTION(runtime_error("Invalid compileViaYul value: " + compileViaYul + "."));
75+
m_testCaseWantsYulRun = contains(yulRunTriggers, compileViaYul);
76+
m_testCaseWantsLegacyRun = contains(legacyRunTriggers, compileViaYul);
77+
78+
// Do not enforce via yul and ewasm, if via yul was explicitly denied.
79+
if (compileViaYul == "false")
8080
{
81-
m_runWithYul = false;
82-
m_runWithoutYul = true;
83-
// Do not try to run via yul if explicitly denied.
8481
m_enforceViaYul = false;
8582
m_enforceCompileToEwasm = false;
8683
}
87-
else if (choice == "default")
88-
{
89-
m_runWithYul = false;
90-
m_runWithoutYul = true;
91-
}
92-
else
93-
BOOST_THROW_EXCEPTION(runtime_error("Invalid compileViaYul value: " + choice + "."));
9484

9585
string compileToEwasm = m_reader.stringSetting("compileToEwasm", "false");
9686
if (compileToEwasm == "also")
97-
m_runWithEwasm = true;
87+
m_testCaseWantsEwasmRun = true;
9888
else if (compileToEwasm == "false")
99-
m_runWithEwasm = false;
89+
m_testCaseWantsEwasmRun = false;
10090
else
10191
BOOST_THROW_EXCEPTION(runtime_error("Invalid compileToEwasm value: " + compileToEwasm + "."));
10292

103-
if (m_runWithEwasm && !m_runWithYul)
93+
if (m_testCaseWantsEwasmRun && !m_testCaseWantsYulRun)
10494
BOOST_THROW_EXCEPTION(runtime_error("Invalid compileToEwasm value: " + compileToEwasm + ", compileViaYul need to be enabled."));
10595

10696
// run ewasm tests only, if an ewasm evmc vm was defined
107-
if (m_runWithEwasm && !m_supportsEwasm)
108-
m_runWithEwasm = false;
97+
if (m_testCaseWantsEwasmRun && !m_supportsEwasm)
98+
m_testCaseWantsEwasmRun = false;
10999

110100
m_runWithABIEncoderV1Only = m_reader.boolSetting("ABIEncoderV1Only", false);
111101
if (m_runWithABIEncoderV1Only && !solidity::test::CommonOptions::get().useABIEncoderV1)
@@ -139,17 +129,16 @@ void SemanticTest::initializeBuiltins()
139129
TestCase::TestResult SemanticTest::run(ostream& _stream, string const& _linePrefix, bool _formatted)
140130
{
141131
TestResult result = TestResult::Success;
142-
bool compileViaYul = m_runWithYul || m_enforceViaYul;
143-
bool compileToEwasm = m_runWithEwasm || m_enforceCompileToEwasm;
144132

145-
if (m_runWithoutYul)
133+
if (m_testCaseWantsLegacyRun)
146134
result = runTest(_stream, _linePrefix, _formatted, false, false);
147135

148-
if (compileViaYul && result == TestResult::Success)
136+
if ((m_testCaseWantsYulRun || m_enforceViaYul) && result == TestResult::Success)
149137
result = runTest(_stream, _linePrefix, _formatted, true, false);
150138

151-
if (compileToEwasm && result == TestResult::Success)
139+
if ((m_testCaseWantsEwasmRun || m_enforceCompileToEwasm) && result == TestResult::Success)
152140
{
141+
// TODO: Once we have full Ewasm support, we could remove try/catch here.
153142
try
154143
{
155144
result = runTest(_stream, _linePrefix, _formatted, true, true);
@@ -167,32 +156,31 @@ TestCase::TestResult SemanticTest::runTest(
167156
ostream& _stream,
168157
string const& _linePrefix,
169158
bool _formatted,
170-
bool _compileViaYul,
171-
bool _compileToEwasm
172-
)
159+
bool _isYulRun,
160+
bool _isEwasmRun)
173161
{
174162
bool success = true;
175163
m_gasCostFailure = false;
176164

177-
if (_compileViaYul && _compileToEwasm)
165+
if (_isYulRun && _isEwasmRun)
178166
selectVM(evmc_capabilities::EVMC_CAPABILITY_EWASM);
179167
else
180168
selectVM(evmc_capabilities::EVMC_CAPABILITY_EVM1);
181169

182170
reset();
183171

184-
m_compileViaYul = _compileViaYul;
185-
if (_compileToEwasm)
172+
m_compileViaYul = _isYulRun;
173+
if (_isEwasmRun)
186174
{
187175
soltestAssert(m_compileViaYul, "");
188-
m_compileToEwasm = _compileToEwasm;
176+
m_compileToEwasm = _isEwasmRun;
189177
}
190178

191-
m_compileViaYulCanBeSet = false;
192-
m_compileToEwasmCanBeSet = false;
179+
m_canEnableYulRun = false;
180+
m_canEnableEwasmRun = false;
193181

194-
if (_compileViaYul)
195-
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Running via Yul:" << endl;
182+
if (_isYulRun)
183+
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Running via Yul" << (_isEwasmRun ? " (ewasm):" : ":") << endl;
196184

197185
for (TestFunctionCall& test: m_tests)
198186
test.reset();
@@ -244,7 +232,7 @@ TestCase::TestResult SemanticTest::runTest(
244232
{
245233
if (m_transactionSuccessful == test.call().expectations.failure)
246234
success = false;
247-
if (success && !checkGasCostExpectation(test, _compileViaYul))
235+
if (success && !checkGasCostExpectation(test, _isYulRun))
248236
m_gasCostFailure = true;
249237

250238
test.setFailure(!m_transactionSuccessful);
@@ -282,7 +270,7 @@ TestCase::TestResult SemanticTest::runTest(
282270
}
283271

284272
bool outputMismatch = (output != test.call().expectations.rawBytes());
285-
if (!outputMismatch && !checkGasCostExpectation(test, _compileViaYul))
273+
if (!outputMismatch && !checkGasCostExpectation(test, _isYulRun))
286274
{
287275
success = false;
288276
m_gasCostFailure = true;
@@ -301,9 +289,9 @@ TestCase::TestResult SemanticTest::runTest(
301289
}
302290
}
303291

304-
if (!m_runWithYul && _compileViaYul)
292+
if (!m_testCaseWantsYulRun && _isYulRun)
305293
{
306-
m_compileViaYulCanBeSet = success;
294+
m_canEnableYulRun = success;
307295
string message = success ?
308296
"Test can pass via Yul, but marked with \"compileViaYul: false.\"" :
309297
"Test compiles via Yul, but it gives different test results.";
@@ -313,21 +301,29 @@ TestCase::TestResult SemanticTest::runTest(
313301
return TestResult::Failure;
314302
}
315303

316-
if (success && !m_runWithEwasm && _compileToEwasm)
304+
// Right now we have sometimes different test results in Yul vs. Ewasm.
305+
// The main reason is that Ewasm just returns a failure in some cases.
306+
// TODO: If Ewasm support got fully implemented, we could implement this in the same way as above.
307+
if (success && !m_testCaseWantsEwasmRun && _isEwasmRun)
317308
{
309+
// TODO: There is something missing in Ewasm to support other types of revert strings:
310+
// for now, we just ignore test-cases that are different from RevertStrings::Default.
318311
if (m_revertStrings != RevertStrings::Default)
319312
return TestResult::Success;
320313

321-
m_compileToEwasmCanBeSet = true;
322-
AnsiColorized(_stream, _formatted, {BOLD, YELLOW})
323-
<< _linePrefix << endl
324-
<< _linePrefix << "Test can pass via Yul (ewasm), but marked with \"compileToEwasm: false.\"" << endl;
314+
m_canEnableEwasmRun = true;
315+
AnsiColorized(_stream, _formatted, {BOLD, YELLOW}) <<
316+
_linePrefix << endl <<
317+
_linePrefix << "Test can pass via Yul (Ewasm), but marked with \"compileToEwasm: false.\"" << endl;
325318
return TestResult::Failure;
326319
}
327320

328-
if (!success && (m_runWithYul || !_compileViaYul))
321+
if (!success)
329322
{
330-
if (!m_runWithEwasm && m_enforceCompileToEwasm)
323+
// Ignore failing tests that can't yet get compiled to Ewasm:
324+
// if the test run was not successful and enforce compiling to ewasm was set,
325+
// but the test case did not wanted to get run with Ewasm, we just ignore this failure.
326+
if (m_enforceCompileToEwasm && !m_testCaseWantsEwasmRun)
331327
return TestResult::Success;
332328

333329
AnsiColorized(_stream, _formatted, {BOLD, CYAN}) << _linePrefix << "Expected result:" << endl;
@@ -360,13 +356,13 @@ TestCase::TestResult SemanticTest::runTest(
360356
AnsiColorized(_stream, _formatted, {BOLD, RED})
361357
<< _linePrefix << endl
362358
<< _linePrefix << "Attention: Updates on the test will apply the detected format displayed." << endl;
363-
if (_compileViaYul && m_runWithoutYul)
359+
if (_isYulRun && m_testCaseWantsLegacyRun)
364360
{
365361
_stream << _linePrefix << endl << _linePrefix;
366362
AnsiColorized(_stream, _formatted, {RED_BACKGROUND}) << "Note that the test passed without Yul.";
367363
_stream << endl;
368364
}
369-
else if (!_compileViaYul && m_runWithYul)
365+
else if (!_isYulRun && m_testCaseWantsYulRun)
370366
AnsiColorized(_stream, _formatted, {BOLD, YELLOW})
371367
<< _linePrefix << endl
372368
<< _linePrefix << "Note that the test also has to pass via Yul." << endl;
@@ -460,32 +456,24 @@ void SemanticTest::printUpdatedExpectations(ostream& _stream, string const&) con
460456
void SemanticTest::printUpdatedSettings(ostream& _stream, string const& _linePrefix)
461457
{
462458
auto& settings = m_reader.settings();
463-
if (settings.empty() && !m_compileViaYulCanBeSet)
459+
if (settings.empty() && !m_canEnableYulRun)
464460
return;
465461

466462
_stream << _linePrefix << "// ====" << endl;
467-
if (m_compileToEwasmCanBeSet)
463+
if (m_canEnableEwasmRun)
468464
{
469-
// if test was already configured to run via yul,
470-
// we need to preserve the original settings.
471-
if (m_runWithYul)
472-
{
473-
// if test was also configured to run without yul.
474-
if (m_runWithoutYul)
475-
_stream << _linePrefix << "// compileViaYul: also\n";
476-
// if test was configured only to run with yul.
477-
else
478-
_stream << _linePrefix << "// compileViaYul: true\n";
479-
}
480-
465+
string compileViaYul = m_reader.stringSetting("compileViaYul", "");
466+
if (!compileViaYul.empty())
467+
_stream << _linePrefix << "// compileViaYul: " << compileViaYul << "\n";
481468
_stream << _linePrefix << "// compileToEwasm: also\n";
482469
}
483-
else if (m_compileViaYulCanBeSet)
470+
else if (m_canEnableYulRun)
484471
_stream << _linePrefix << "// compileViaYul: also\n";
485472

486473
for (auto const& setting: settings)
487-
if (!(m_compileViaYulCanBeSet || m_compileToEwasmCanBeSet) || setting.first != "compileViaYul")
488-
_stream << _linePrefix << "// " << setting.first << ": " << setting.second << endl;
474+
if (!(m_canEnableEwasmRun && setting.first == "compileToEwasm")
475+
&& (!((m_canEnableYulRun || m_canEnableEwasmRun) && setting.first == "compileViaYul")))
476+
_stream << _linePrefix << "// " << setting.first << ": " << setting.second << endl;
489477
}
490478

491479
void SemanticTest::parseExpectations(istream& _stream)

test/libsolidity/SemanticTest.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,21 +78,21 @@ class SemanticTest: public SolidityExecutionFramework, public EVMVersionRestrict
7878
bool deploy(std::string const& _contractName, u256 const& _value, bytes const& _arguments, std::map<std::string, solidity::test::Address> const& _libraries = {});
7979

8080
private:
81-
TestResult runTest(std::ostream& _stream, std::string const& _linePrefix, bool _formatted, bool _compileViaYul, bool _compileToEwasm);
81+
TestResult runTest(std::ostream& _stream, std::string const& _linePrefix, bool _formatted, bool _isYulRun, bool _isEwasmRun);
8282
bool checkGasCostExpectation(TestFunctionCall& io_test, bool _compileViaYul) const;
8383
void initializeBuiltins();
8484
SourceMap m_sources;
8585
std::size_t m_lineOffset;
8686
std::vector<TestFunctionCall> m_tests;
87-
bool m_runWithYul = false;
88-
bool m_runWithEwasm = false;
89-
bool m_runWithoutYul = true;
87+
bool m_testCaseWantsYulRun = false;
88+
bool m_testCaseWantsEwasmRun = false;
89+
bool m_testCaseWantsLegacyRun = true;
9090
bool m_enforceViaYul = false;
9191
bool m_enforceCompileToEwasm = false;
9292
bool m_runWithABIEncoderV1Only = false;
9393
bool m_allowNonExistingFunctions = false;
94-
bool m_compileViaYulCanBeSet = false;
95-
bool m_compileToEwasmCanBeSet = false;
94+
bool m_canEnableYulRun = false;
95+
bool m_canEnableEwasmRun = false;
9696
std::map<std::string, Builtin> m_builtins{};
9797

9898
bool m_gasCostFailure = false;

0 commit comments

Comments
 (0)