-
Notifications
You must be signed in to change notification settings - Fork 6.2k
Refactor compileViaYul
test setting
#15819
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
Thank you for your contribution to the Solidity compiler! A team member will follow up shortly. If you haven't read our contributing guidelines and our review checklist before, please do it now, this makes the reviewing process and accepting your contribution smoother. If you have any questions or need our help, feel free to post them in the PR or talk to us directly on the #solidity-dev channel on Matrix. |
Please also add the missing validation you found in #15666 (comment). |
compileViaYul
test setting
Ok. Do you want me to introduce similar change in |
61b065e
to
36bb4e8
Compare
Added but I think we should also use |
36bb4e8
to
cf8ed7c
Compare
test/libsolidity/SemanticTest.cpp
Outdated
std::string bytecodeFormatString = m_reader.stringSetting("bytecodeFormat", "unset"); | ||
if (bytecodeFormatString == ">=EOFv1" && compileViaYul == CompileViaYul::False) | ||
BOOST_THROW_EXCEPTION(std::runtime_error("Compilation to EOF requires using Yul IR")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should also use
enumSetting
forbytecodeFormat
and add a protected member to theEVMVersionRestrictedTestCase
class to avoid parsing this setting twice
Agreed, at least regarding exposing it on EVMVersionRestrictedTestCase
. But I'd expose it via a getter + private member to prevent accidental modification.
Checking on the raw setting technically requires reparsing the value again. It only works here without it because parsing is trivial right now (we hard-coded it for a few values) but this will change at some point.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As for enumSetting
, it's not the right type. The value in a general case is a list of ranges of values from an enumeration. Once fully implemented, it should be able to handle individual values, values with operators (like =
or >=
), and maybe even things like A-B
or A..B
. The EVMVersion
is the same kind of setting (just with different enumeration values) and there are a few other settings where this would be useful too.
But that's a bit more refactoring than I was expecting here, so unless you really want to do it (I wouldn't mind :)), IMO it would be enough to just keep it as a string setting and just expose the parsed value on EVMVersionRestrictedTestCase
as a set of enum values. E.g. legacy,>=EOFv1
should be parsed into {"legacy", "EOFv1"}
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed, at least regarding exposing it on EVMVersionRestrictedTestCase. But I'd expose it via a getter + private member to prevent accidental modification.
But unfortunately we cannot do it like this b/c reading this flag in Semantic test with default unset
is crucial here. We need to know if the flag was set or not. In case of moving this to EVMVersionRestrictedTestCase
members we don't have this inforamation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is another problem here. When I added compileViaYul
and bytecodeForamat
flags consistency check to SyntaxTests
some tests started failing. The reason is that in these tests compileViaYul
flag is not set and (when compiling to legacy) the default is false
. It's similar issue that we don't know at this point if the default was taken or not. I removed it for now but I think it needs refactoring of enumSetting
to additionally inform if the default was taken.
It works for SemanticTest
b/c the default in this case is Also
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But unfortunately we cannot do it like this b/c reading this flag in Semantic test with default
unset
is crucial here.
If I understand correctly, you want this because you don't want the validation to run when bytecodeFormat
is not set explicitly? Why is that necessary? With the default being legacy,>=EOFv1
currently the validation will always pass anyway.
And I think that in general things are simpler when you can assume that not providing an explicit value is exactly equivalent to using the default value. If the default needs a special behavior, it's always possible to achieve by defining a separate value for that behavior and using that as default.
The reason is that in these tests
compileViaYul
flag is not set and (when compiling to legacy) the default isfalse
.
Right. So this seems to be one of those cases where we need such a special value. Currently we use different defaults based on the value of --eof-version
, but we can just as well explicitly add a value like compileViaYul: onlyOnEOF
and set default in syntax tests to that.
Another option, would be to keep the dynamic default, but set it based on the value of bytecodeFormat
setting rather than --eof-version
. We'd set the default to true
when bytecodeFormat
includes any EOF version (regardless of whether it also includes legacy
or not). This would give us slightly different behavior (legacy tests that need to also work on EOF would now always compile via IR) but that would still be acceptable.
I think I'd go with the first option (onlyOnEOF
) personally. I initially suggested those dynamic defaults, because they seemed to be better than the alternative, but maybe that wasn't the best idea. We've already hit problems due to having layers of conditional defaults in optimizer settings (#15641) and I'd rather avoid creating a similar mess here :)
884cc27
to
b53af39
Compare
b53af39
to
e39a5a6
Compare
tests: Use enum setting for `compileViaYul`
e39a5a6
to
3e5c39c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, but needs some final cleanup.
I'd also try to just remove compileViaYul
from two of the tests. They probably work on both codegens now.
m_shouldRun = false; | ||
else if (bytecodeFormatString == ">=EOFv1" && !eofVersion.has_value()) | ||
else if (bytecodeFormat().contains(BytecodeFormat::EOFv1) && !eofVersion.has_value()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To clarify, this is what I meant by "same for the legacy
run" in #15819 (comment):
else if (bytecodeFormat().contains(BytecodeFormat::EOFv1) && !eofVersion.has_value()) | |
else if (!bytecodeFormat().contains(BytecodeFormat::Legacy) && !eofVersion.has_value()) |
solUnimplementedAssert(m_compileViaYul != CompileViaYul::Also, | ||
"'compileViaYul: also' is not yet supported in syntax tests."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One left from #15819 (comment):
solUnimplementedAssert(m_compileViaYul != CompileViaYul::Also, | |
"'compileViaYul: also' is not yet supported in syntax tests."); | |
if (m_compileViaYul == CompileViaYul::Also) | |
solUnimplemented("'compileViaYul: also' is not yet supported in syntax tests."); |
if (bytecodeFormat().contains(BytecodeFormat::EOFv1) && m_compileViaYul == CompileViaYul::False) | ||
BOOST_THROW_EXCEPTION(std::runtime_error("Compilation to EOF requires using Yul IR")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Still needs an assert.
While at it, let's also make the message a bit clearer. We should mention which settings it's about because the error won't point at a specific line in the test.
if (bytecodeFormat().contains(BytecodeFormat::EOFv1) && m_compileViaYul == CompileViaYul::False) | |
BOOST_THROW_EXCEPTION(std::runtime_error("Compilation to EOF requires using Yul IR")); | |
if (m_compileViaYul == CompileViaYul::False) | |
{ | |
soltestAssert(!eofEnabled); | |
if (bytecodeFormat().contains(BytecodeFormat::EOFv1)) | |
BOOST_THROW_EXCEPTION(std::runtime_error( | |
"Conflicting test settings: 'bytecodeFormat' includes EOF, which requires compilation via IR, but 'compileViaYul' is set to false." | |
)); | |
} |
if (bytecodeFormat().contains(BytecodeFormat::EOFv1) && compileViaYul == CompileViaYul::False) | ||
BOOST_THROW_EXCEPTION(std::runtime_error("Compilation to EOF requires using Yul IR")); | ||
|
||
if (compileViaYul == CompileViaYul::False && eofEnabled) | ||
m_shouldRun = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The eofEnabled
check should be converted to an assert, like in the syntax test. And we adjust the message the same way:
if (bytecodeFormat().contains(BytecodeFormat::EOFv1) && compileViaYul == CompileViaYul::False) | |
BOOST_THROW_EXCEPTION(std::runtime_error("Compilation to EOF requires using Yul IR")); | |
if (compileViaYul == CompileViaYul::False && eofEnabled) | |
m_shouldRun = false; | |
if (m_compileViaYul == CompileViaYul::False) | |
{ | |
soltestAssert(!eofEnabled); | |
if (bytecodeFormat().contains(BytecodeFormat::EOFv1)) | |
BOOST_THROW_EXCEPTION(std::runtime_error( | |
"Conflicting test settings: 'bytecodeFormat' includes EOF, which requires compilation via IR, but 'compileViaYul' is set to false." | |
)); | |
} |
@@ -67,6 +67,7 @@ contract C { | |||
|
|||
// ==== | |||
// compileViaYul: false | |||
// bytecodeFormat: legacy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// via yul disabled because of stack issues.
Can you try to remove compileViaYul: false
here? The code does compile on 0.8.29 for me. If it still fails, I'd also try onlyOnEOF
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for negative_stack_height.sol
.
This PRs refactors using of
compileViaYul
setting in semantic tests with usingenumSetting
Depends on: #15666Merged