@@ -50,6 +50,7 @@ SemanticTest::SemanticTest(
5050 langutil::EVMVersion _evmVersion,
5151 vector<boost::filesystem::path> const & _vmPaths,
5252 bool _enforceViaYul,
53+ bool _enforceCompileToEwasm,
5354 bool _enforceGasCost,
5455 u256 _enforceGasCostMinValue
5556):
@@ -58,51 +59,43 @@ SemanticTest::SemanticTest(
5859 m_sources(m_reader.sources()),
5960 m_lineOffset(m_reader.lineNumber()),
6061 m_enforceViaYul(_enforceViaYul),
62+ m_enforceCompileToEwasm(_enforceCompileToEwasm),
6163 m_enforceGasCost(_enforceGasCost),
62- m_enforceGasCostMinValue(_enforceGasCostMinValue)
64+ m_enforceGasCostMinValue(std::move( _enforceGasCostMinValue) )
6365{
6466 initializeBuiltins ();
6567
66- string choice = m_reader. stringSetting ( " compileViaYul " , " default" ) ;
67- if (choice == " also" )
68- {
69- m_runWithYul = true ;
70- m_runWithoutYul = true ;
71- }
72- else if (choice == " true " )
73- {
74- m_runWithYul = true ;
75- m_runWithoutYul = false ;
76- }
77- 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" )
7880 {
79- m_runWithYul = false ;
80- m_runWithoutYul = true ;
81- // Do not try to run via yul if explicitly denied.
8281 m_enforceViaYul = false ;
82+ m_enforceCompileToEwasm = false ;
8383 }
84- else if (choice == " default" )
85- {
86- m_runWithYul = false ;
87- m_runWithoutYul = true ;
88- }
89- else
90- BOOST_THROW_EXCEPTION (runtime_error (" Invalid compileViaYul value: " + choice + " ." ));
9184
9285 string compileToEwasm = m_reader.stringSetting (" compileToEwasm" , " false" );
9386 if (compileToEwasm == " also" )
94- m_runWithEwasm = true ;
87+ m_testCaseWantsEwasmRun = true ;
9588 else if (compileToEwasm == " false" )
96- m_runWithEwasm = false ;
89+ m_testCaseWantsEwasmRun = false ;
9790 else
9891 BOOST_THROW_EXCEPTION (runtime_error (" Invalid compileToEwasm value: " + compileToEwasm + " ." ));
9992
100- if (m_runWithEwasm && !m_runWithYul )
93+ if (m_testCaseWantsEwasmRun && !m_testCaseWantsYulRun )
10194 BOOST_THROW_EXCEPTION (runtime_error (" Invalid compileToEwasm value: " + compileToEwasm + " , compileViaYul need to be enabled." ));
10295
103- // run ewasm tests only, if an ewasm evmc vm was defined
104- if (m_runWithEwasm && !m_supportsEwasm)
105- m_runWithEwasm = false ;
96+ // run ewasm tests only if an ewasm evmc vm was defined
97+ if (m_testCaseWantsEwasmRun && !m_supportsEwasm)
98+ m_testCaseWantsEwasmRun = false ;
10699
107100 m_runWithABIEncoderV1Only = m_reader.boolSetting (" ABIEncoderV1Only" , false );
108101 if (m_runWithABIEncoderV1Only && !solidity::test::CommonOptions::get ().useABIEncoderV1 )
@@ -136,49 +129,61 @@ void SemanticTest::initializeBuiltins()
136129TestCase::TestResult SemanticTest::run (ostream& _stream, string const & _linePrefix, bool _formatted)
137130{
138131 TestResult result = TestResult::Success;
139- bool compileViaYul = m_runWithYul || m_enforceViaYul;
140132
141- if (m_runWithoutYul )
133+ if (m_testCaseWantsLegacyRun )
142134 result = runTest (_stream, _linePrefix, _formatted, false , false );
143135
144- if (compileViaYul && result == TestResult::Success)
136+ if ((m_testCaseWantsYulRun || m_enforceViaYul) && result == TestResult::Success)
145137 result = runTest (_stream, _linePrefix, _formatted, true , false );
146138
147- if (m_runWithEwasm && result == TestResult::Success)
148- result = runTest (_stream, _linePrefix, _formatted, true , true );
149-
139+ if ((m_testCaseWantsEwasmRun || m_enforceCompileToEwasm) && result == TestResult::Success)
140+ {
141+ // TODO: Once we have full Ewasm support, we could remove try/catch here.
142+ try
143+ {
144+ result = runTest (_stream, _linePrefix, _formatted, true , true );
145+ }
146+ catch (...)
147+ {
148+ if (!m_enforceCompileToEwasm)
149+ throw ;
150+ }
151+ }
150152 return result;
151153}
152154
153155TestCase::TestResult SemanticTest::runTest (
154156 ostream& _stream,
155157 string const & _linePrefix,
156158 bool _formatted,
157- bool _compileViaYul,
158- bool _compileToEwasm
159- )
159+ bool _isYulRun,
160+ bool _isEwasmRun)
160161{
161162 bool success = true ;
162163 m_gasCostFailure = false ;
163164
164- if (_compileViaYul && _compileToEwasm)
165+ if (_isEwasmRun)
166+ {
167+ soltestAssert (_isYulRun, " " );
165168 selectVM (evmc_capabilities::EVMC_CAPABILITY_EWASM);
169+ }
166170 else
167171 selectVM (evmc_capabilities::EVMC_CAPABILITY_EVM1);
168172
169173 reset ();
170174
171- m_compileViaYul = _compileViaYul ;
172- if (_compileToEwasm )
175+ m_compileViaYul = _isYulRun ;
176+ if (_isEwasmRun )
173177 {
174178 soltestAssert (m_compileViaYul, " " );
175- m_compileToEwasm = _compileToEwasm ;
179+ m_compileToEwasm = _isEwasmRun ;
176180 }
177181
178- m_compileViaYulCanBeSet = false ;
182+ m_canEnableYulRun = false ;
183+ m_canEnableEwasmRun = false ;
179184
180- if (_compileViaYul )
181- AnsiColorized (_stream, _formatted, {BOLD, CYAN}) << _linePrefix << " Running via Yul: " << endl;
185+ if (_isYulRun )
186+ AnsiColorized (_stream, _formatted, {BOLD, CYAN}) << _linePrefix << " Running via Yul" << (_isEwasmRun ? " (ewasm): " : " : " ) << endl;
182187
183188 for (TestFunctionCall& test: m_tests)
184189 test.reset ();
@@ -230,7 +235,7 @@ TestCase::TestResult SemanticTest::runTest(
230235 {
231236 if (m_transactionSuccessful == test.call ().expectations .failure )
232237 success = false ;
233- if (success && !checkGasCostExpectation (test, _compileViaYul ))
238+ if (success && !checkGasCostExpectation (test, _isYulRun ))
234239 m_gasCostFailure = true ;
235240
236241 test.setFailure (!m_transactionSuccessful);
@@ -268,7 +273,7 @@ TestCase::TestResult SemanticTest::runTest(
268273 }
269274
270275 bool outputMismatch = (output != test.call ().expectations .rawBytes ());
271- if (!outputMismatch && !checkGasCostExpectation (test, _compileViaYul ))
276+ if (!outputMismatch && !checkGasCostExpectation (test, _isYulRun ))
272277 {
273278 success = false ;
274279 m_gasCostFailure = true ;
@@ -287,9 +292,9 @@ TestCase::TestResult SemanticTest::runTest(
287292 }
288293 }
289294
290- if (!m_runWithYul && _compileViaYul )
295+ if (!m_testCaseWantsYulRun && _isYulRun )
291296 {
292- m_compileViaYulCanBeSet = success;
297+ m_canEnableYulRun = success;
293298 string message = success ?
294299 " Test can pass via Yul, but marked with \" compileViaYul: false.\" " :
295300 " Test compiles via Yul, but it gives different test results." ;
@@ -299,8 +304,31 @@ TestCase::TestResult SemanticTest::runTest(
299304 return TestResult::Failure;
300305 }
301306
302- if (!success && (m_runWithYul || !_compileViaYul))
307+ // Right now we have sometimes different test results in Yul vs. Ewasm.
308+ // The main reason is that Ewasm just returns a failure in some cases.
309+ // TODO: If Ewasm support got fully implemented, we could implement this in the same way as above.
310+ if (success && !m_testCaseWantsEwasmRun && _isEwasmRun)
303311 {
312+ // TODO: There is something missing in Ewasm to support other types of revert strings:
313+ // for now, we just ignore test-cases that do not use RevertStrings::Default.
314+ if (m_revertStrings != RevertStrings::Default)
315+ return TestResult::Success;
316+
317+ m_canEnableEwasmRun = true ;
318+ AnsiColorized (_stream, _formatted, {BOLD, YELLOW}) <<
319+ _linePrefix << endl <<
320+ _linePrefix << " Test can pass via Yul (Ewasm), but marked with \" compileToEwasm: false.\" " << endl;
321+ return TestResult::Failure;
322+ }
323+
324+ if (!success)
325+ {
326+ // Ignore failing tests that can't yet get compiled to Ewasm:
327+ // if the test run was not successful and enforce compiling to ewasm was set,
328+ // but the test case did not want to get run with Ewasm, we just ignore this failure.
329+ if (m_enforceCompileToEwasm && !m_testCaseWantsEwasmRun)
330+ return TestResult::Success;
331+
304332 AnsiColorized (_stream, _formatted, {BOLD, CYAN}) << _linePrefix << " Expected result:" << endl;
305333 for (TestFunctionCall const & test: m_tests)
306334 {
@@ -331,13 +359,13 @@ TestCase::TestResult SemanticTest::runTest(
331359 AnsiColorized (_stream, _formatted, {BOLD, RED})
332360 << _linePrefix << endl
333361 << _linePrefix << " Attention: Updates on the test will apply the detected format displayed." << endl;
334- if (_compileViaYul && m_runWithoutYul )
362+ if (_isYulRun && m_testCaseWantsLegacyRun )
335363 {
336364 _stream << _linePrefix << endl << _linePrefix;
337365 AnsiColorized (_stream, _formatted, {RED_BACKGROUND}) << " Note that the test passed without Yul." ;
338366 _stream << endl;
339367 }
340- else if (!_compileViaYul && m_runWithYul )
368+ else if (!_isYulRun && m_testCaseWantsYulRun )
341369 AnsiColorized (_stream, _formatted, {BOLD, YELLOW})
342370 << _linePrefix << endl
343371 << _linePrefix << " Note that the test also has to pass via Yul." << endl;
@@ -451,15 +479,27 @@ void SemanticTest::printUpdatedExpectations(ostream& _stream, string const&) con
451479void SemanticTest::printUpdatedSettings (ostream& _stream, string const & _linePrefix)
452480{
453481 auto & settings = m_reader.settings ();
454- if (settings.empty () && !m_compileViaYulCanBeSet )
482+ if (settings.empty () && !m_canEnableYulRun )
455483 return ;
456484
457485 _stream << _linePrefix << " // ====" << endl;
458- if (m_compileViaYulCanBeSet)
486+ if (m_canEnableEwasmRun)
487+ {
488+ soltestAssert (m_canEnableYulRun || m_testCaseWantsYulRun, " " );
489+ string compileViaYul = m_reader.stringSetting (" compileViaYul" , " " );
490+ if (!compileViaYul.empty ())
491+ _stream << _linePrefix << " // compileViaYul: " << compileViaYul << " \n " ;
492+ _stream << _linePrefix << " // compileToEwasm: also\n " ;
493+ }
494+ else if (m_canEnableYulRun)
459495 _stream << _linePrefix << " // compileViaYul: also\n " ;
460- for (auto const & setting: settings)
461- if (!m_compileViaYulCanBeSet || setting.first != " compileViaYul" )
462- _stream << _linePrefix << " // " << setting.first << " : " << setting.second << endl;
496+
497+ for (auto const & [settingName, settingValue]: settings)
498+ if (
499+ !(settingName == " compileToEwasm" && m_canEnableEwasmRun) &&
500+ !(settingName == " compileViaYul" && (m_canEnableYulRun || m_canEnableEwasmRun))
501+ )
502+ _stream << _linePrefix << " // " << settingName << " : " << settingValue<< endl;
463503}
464504
465505void SemanticTest::parseExpectations (istream& _stream)
0 commit comments