-
Notifications
You must be signed in to change notification settings - Fork 5.8k
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
Add RETURNDATACOPY and RETURNDATASIZE to assembly (and LLL) #2275
Conversation
libevmasm/Instruction.h
Outdated
@@ -49,6 +49,8 @@ enum class Instruction: uint8_t | |||
MULMOD, ///< unsigned modular multiplication | |||
EXP, ///< exponential operation | |||
SIGNEXTEND, ///< extend length of signed integer | |||
RETURNDATASIZE = 0xd, ///< get size of the last return data |
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.
We've agreed to a different opcode on the last call.
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.
Thank you for the info. I'll update my yellow paper PR, the test PR and this one.
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 moved them to 0x3d and 0x3e.
docs/assembly.rst
Outdated
@@ -182,6 +182,10 @@ In the grammar, opcodes are represented as pre-defined identifiers. | |||
+-------------------------+------+-----------------------------------------------------------------+ | |||
| signextend(i, x) | | sign extend from (i*8+7)th bit counting from least significant | | |||
+-------------------------+------+-----------------------------------------------------------------+ | |||
| returndatasize | | size of the last return data | |
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.
Please move this to the right location after the opcode is updated.
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.
done.
test/liblll/Parser.cpp
Outdated
@@ -174,6 +174,16 @@ BOOST_AUTO_TEST_CASE(list) | |||
BOOST_CHECK(!successParse("()")); | |||
} | |||
|
|||
BOOST_AUTO_TEST_CASE(returndatacopy) | |||
{ | |||
BOOST_CHECK(successParse("( returndatacopy 0 1 2 )")); |
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 do not think there's a need for parser test. The parser doesn't care.
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 agree. The test succeeded even before the change. So this does not add any 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.
So I removed this test and the next similar one.
test/liblll/EndToEndTest.cpp
Outdated
BOOST_AUTO_TEST_CASE(returndatasize_can_be_compiled) | ||
{ | ||
char const* sourceCode = R"( | ||
(returnlll |
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'm not sure this is needed (though probably cannot hurt), because LLL just exposes every single opcode. Potentially we should test for every single one? :)
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.
This was the motivation of the whole PR.
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 we do not test for 99% of the opcodes.
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.
Let me see if there is any other opcode tested this way.
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.
OK, I can guess from the other tests that opcodes are visible. I see sstore
, codecopy
, mstore8
, div
, exp
and so on. So I don't need this test.
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.
Please update the opcode.
It is also missing the changelog entry and the optimiser changes (GasMeter, SemanticInformation). |
I think I updated everything. |
libevmasm/Instruction.cpp
Outdated
@@ -203,6 +205,8 @@ static const std::map<Instruction, InstructionInfo> c_instructionInfo = | |||
{ Instruction::GASPRICE, { "GASPRICE", 0, 0, 1, false, Tier::Base } }, | |||
{ Instruction::EXTCODESIZE, { "EXTCODESIZE", 0, 1, 1, false, Tier::ExtCode } }, | |||
{ Instruction::EXTCODECOPY, { "EXTCODECOPY", 0, 4, 0, true, Tier::ExtCode } }, | |||
{ Instruction::RETURNDATASIZE, {"RETURNDATASIZE", 0, 0, 1, false, Tier::Base } }, |
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.
Indentation is wrong here
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.
fixed.
scripts/tests.sh
Outdated
@@ -71,9 +71,9 @@ sleep 2 | |||
# And then run the Solidity unit-tests (once without optimization, once with), | |||
# pointing to that IPC endpoint. | |||
echo "--> Running tests without optimizer..." | |||
"$REPO_ROOT"/build/test/soltest --show-progress -- --ipcpath /tmp/test/geth.ipc && \ | |||
"$REPO_ROOT"/build/test/soltest --show-progress -t '*/returndata*' -- --ipcpath /tmp/test/geth.ipc && \ |
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.
Shouldn't filter for returndata here :)
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.
Oh, sorry. This change is garbage.
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.
Reverted these changes.
9e414af
to
1bfae8d
Compare
docs/assembly.rst
Outdated
@@ -232,6 +232,10 @@ In the grammar, opcodes are represented as pre-defined identifiers. | |||
+-------------------------+------+-----------------------------------------------------------------+ | |||
| extcodecopy(a, t, f, s) | `-` | like codecopy(t, f, s) but take code at address a | | |||
+-------------------------+------+-----------------------------------------------------------------+ | |||
| returndatasize | | size of the last return data | | |||
+-------------------------+------+-----------------------------------------------------------------+ | |||
| returndatacopy(t, f, s) | `*` | copy s bytes from returndata at position f to mem at position t | |
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.
Either we should call it returndata
or return data
in both places.
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.
You're right.
I think we should have warnings in place if using these Metropolis instructions. This applies to |
Added warnings to the analyzer, will push it later the evening. |
Please add a warning if in the scope of an inline assembly block there is a solidity identifier called |
@@ -429,6 +429,16 @@ BOOST_AUTO_TEST_CASE(revert) | |||
BOOST_CHECK(successAssemble("{ revert(0, 0) }")); | |||
} | |||
|
|||
BOOST_AUTO_TEST_CASE(returndatasize) | |||
{ | |||
BOOST_CHECK(successAssemble("{ let r := returndatasize }")); |
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.
Also potentially this should be in "functional notation" to be in line with returndatacopy
/ revert
.
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 an exception that for an opcode x, if x()
is valid, you can omit the parentheses. We could make that more strict (it is more strict in julia already).
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.
Both are valid, it is only about consistency:
- do not test for these
- test with one notation only (but use the same for these "opcode tests")
- test with both notations (this has its own merits, given the code paths in the parser/analyzer are different)
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 test random styles on random instructions to catch different kinds of errors. I don't think we get coverage efficiently if we tested the same set of styles for all instructions.
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.
If we want to catch as many bugs as possible we should test for both notations.
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, if no other instruction is tested for "both styles", maybe now is a good time to do that for at least one instruction.
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.
It is the opposite, practically no "functional instructions" are tested in the assembler section.
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.
add
is already tested for both styles in functional
, but it has two arguments: not zero or three.
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.
You have to look at the SolidityInlineAssembler/Analysis
suite. The others don't assemble.
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.
Right, and at this point, it's easier to add both styles.
case solidity::Instruction::RETURNDATACOPY: | ||
m_errors.push_back(make_shared<Error>( | ||
Error::Type::Warning, | ||
"The RETURNDATASIZE/RETURNDATACOPY instructions are only available after " |
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.
Any better suggestion for wording?
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 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.
Doesn't STATICCALL
belong here?
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.
And CREATE2
(and REVERT
with a different message), but those are not merged yet.
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.
STATICCALL
has already been merged.
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.
It is pending as #2192?
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 I was seeing cpp-ethereum
. Sorry.
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 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.
This looks perfect to me. It should be a warning, it should mention Metropolis, and it should tell this and that instructions will become available with Metropolis.
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.
{ | ||
string instructionName{instruction.first}; // needs to copy because making it lower case. | ||
boost::algorithm::to_lower(instructionName); | ||
auto declarations = nameFromCurrentScope(instructionName); |
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.
Did you test whether this always reports the global sha3
?
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.
Right, that might be happening; there might be a warning about sha3
on every possible source code with inline assembly. I should add a test about that.
solAssert(!!declaration, ""); | ||
m_errorReporter.warning( | ||
declaration->location(), | ||
"Variable is shadowed in an inline assembly by an insturction of the same name" |
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.
"in an" -> "in" and "instruction" -> "instruction"?
Please merge when tests are green. |
Can you please squash some commits? The "fix typo" commit only fixed the code and there will be another one fixing the tests 😉 Could be merged into the original commit. |
@axic squashed a bit. |
This PR adds RETURNDATACOPY and RETURNDATASIZE in LLL so that Metropolis tests in
etheruem/tests
can be developed more easily. In passing, I added minimum documentation and tests about inline assembly.