Test to make sure that LLLC is compiling all valid opcodes correctly#3002
Test to make sure that LLLC is compiling all valid opcodes correctly#3002axic merged 1 commit intoargotorg:developfrom
Conversation
test/liblll/Parser.cpp
Outdated
| }; | ||
|
|
||
| std::vector<std::string> opcodes_lll { | ||
| "{ (STOP) (RETURN 0x0 0x1) }", |
There was a problem hiding this comment.
return is dead code here after stop
test/liblll/Parser.cpp
Outdated
| "{ (XOR 0x00 0x00) (RETURN 0x0 0x0) }", | ||
| "{ (NOT 0x00) (RETURN 0x0 0x0) }", | ||
| "{ (BYTE 0 0x8050201008040201) (RETURN 0x0 0x0) }", | ||
| //"{ (SHA3 0x00 0x00) (RETURN 0x0 0x0) }", //SHA3 opcode not implemented |
There was a problem hiding this comment.
It is called keccak256 and not sha3.
test/liblll/Parser.cpp
Outdated
| "{ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff (return 0x0 0x0)}", | ||
| "{ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff (return 0x0 0x0)}", | ||
| "{ 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff (return 0x0 0x0)}", | ||
| "{ (DUP1 0xff) (return 0x0 0x0)}", |
There was a problem hiding this comment.
What is the point of the 0xff parameter for DUPs and SWAPs? They do not take parameters and this case (for some reason) gets compiled as pushes.
There was a problem hiding this comment.
Well to be honest, DUP and SWAP make no sense for the instructional form in LLL.
All these are also available as inline assembly:
(asm 1 2 3 DUP2 SWAP3)
test/liblll/Parser.cpp
Outdated
| "{ (EXTCODECOPY 0x1000000000000000000000000000000000000010 0 0 20) (RETURN 0x0 0x0) }", | ||
| "{ (RETURNDATASIZE) (RETURN 0x0 0x0) }", | ||
| "{ (RETURNDATACOPY 0x0 0x0 0x0) (RETURN 0x0 0x0) }", | ||
| "{ 0x00 (POP 0x00) (RETURN 0x0 0x0) }", |
There was a problem hiding this comment.
This seems to be a a push 0, push 0, pop, but not as an instruction as the rest of them.
There was a problem hiding this comment.
I'd argue having POP as a functional instruction is useless given every stray stack argument is popped anyway.
e.g.
(ORIGIN)
and
(POP (ORIGIN))
has the same stack result.
test/liblll/Parser.cpp
Outdated
| "{ (DELEGATECALL 100000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 0 0 0 0) (return 0x0 0x0) }", | ||
| "{ (STATICCALL 10000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 0 0 0 0) (return 0x0 0x0) }", | ||
| "{ (REVERT 0x0 0x0) (return 0x0 0x0)}", | ||
| "{ (SELFDESTRUCT (ORIGIN)) }" |
There was a problem hiding this comment.
If all the others used a PUSH for the argument, perhaps do the same here?
|
Some of the instructions are lowercase while others are uppercase. Also having |
test/liblll/Parser.cpp
Outdated
|
|
||
| if (!errors.empty()) { | ||
| BOOST_FAIL(opcodes_lll[i]); | ||
| } |
There was a problem hiding this comment.
For this part above you could copy the code from test/liblll/ExecutionFramework.h.
test/liblll/Parser.cpp
Outdated
| std::stringstream ss; | ||
|
|
||
| for (size_t i = 0; i < code.size(); i++) { | ||
| ss << boost::format("%02x") % (int)code[i]; |
There was a problem hiding this comment.
Could just use toHex(code) to achieve the same.
test/liblll/Parser.cpp
Outdated
| "{ (PC) (RETURN 0x0 0x0) }", | ||
| "{ (MSIZE) (RETURN 0x0 0x0) }", | ||
| "{ (GAS) (RETURN 0x0 0x0) }", | ||
| "{ (JUMPDEST) (RETURN 0x0 0x0) }", |
There was a problem hiding this comment.
This seems pointless too, should disable it in the compiler.
test/liblll/Parser.cpp
Outdated
| "{ (RETURN 0x0 0x0) }", | ||
| "{ (DELEGATECALL 100000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 0 0 0 0) (return 0x0 0x0) }", | ||
| "{ (STATICCALL 10000 0x0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6 0 0 0 0) (return 0x0 0x0) }", | ||
| "{ (REVERT 0x0 0x0) (return 0x0 0x0)}", |
test/liblll/Parser.cpp
Outdated
| "{ (CALLDATASIZE) (RETURN 0x0 0x0) }", | ||
| "{ (CALLDATACOPY 0x0 0x0 0x0) (RETURN 0x0 0x0) }", | ||
| "{ (CODESIZE) (RETURN 0x0 0x0) }", | ||
| "{ (CODECOPY 0x1 0x0 (CODESIZE)) [[ 0 ]] (MLOAD 0x1) (RETURN 0x0 0x0) }", |
There was a problem hiding this comment.
Why mix the built in notation of sstore with the rest? This code right now reads as
(CODECOPY 0x1 0x0 (CODESIZE))
(SSTORE 0 (MLOAD 0x1))
(RETURN 0x0 0x0)
is that intended?
|
Thanks for the review. Have a long day of flights today. I will address these points tomorrow. |
axic
left a comment
There was a problem hiding this comment.
I think you should add a second set of tests for using inline assembly, where all the opcodes are available: (asm 1 2 ADD BALANCE SUB)
|
These were pulled directly from a state test I wrote: https://github.com/ethereum/tests/blob/develop/GeneralStateTests/stTransactionTest/Opcodes_TransactionInit.json . Makes sense to re-write that as well. Having two tests (one for good opcodes, one for unused opcodes) is sensible here. |
|
Needs to be rebased for latest LLL fixes. |
84f3065 to
8b9fbc9
Compare
|
@axic I revised the test simplifying the code, added the use of |
|
Thanks @jwasinger. I think the functional tests were useful too. Not sure which one is used in test generation though. Also all these should move to |
886a98b to
040a561
Compare
|
I am not sure which one is used in ethereum/tests, |
949bbab to
dcb651a
Compare
|
I added a test for functional instructions. I think it should be ready to merge @axic |
test/liblll/Compiler.cpp
Outdated
| "{ (asm MSIZE) }", | ||
| "{ (asm GAS) }", | ||
| "{ (asm JUMPDEST) }", | ||
| "{ (asm PUSH1) }", |
There was a problem hiding this comment.
Hm, these actually seem to show another bug. They do insert the correct opcode, but there is no possible way to push an immediate, because having a number there will include the PUSH opcode too:
(asm PUSH1)-> 0x60(asm PUSH1 0x42)-> 0x60 0x60 0x42(asm 0x42)-> 0x60 0x42
There was a problem hiding this comment.
I'll push a patch which removes that from assembly, but these tests should be changed to not include PUSHnn, but rather have a literal each for all widths (0x42, 0x4242, ..)
test/liblll/Compiler.cpp
Outdated
| }; | ||
|
|
||
| for (size_t i = 0; i < opcodes_bytecode.size(); i++) { | ||
| std::vector<std::string> errors; |
There was a problem hiding this comment.
No need for the std prefix as the namespace is imported, vector<string> should be enough.
test/liblll/Compiler.cpp
Outdated
|
|
||
| if (!errors.empty()) { | ||
| BOOST_FAIL(opcodes_lll[i]); | ||
| } |
There was a problem hiding this comment.
I think this could be replaced with BOOST_REQUIRE_MESSAGE(errors.empty(), opcodes_lll[i]); though I'm not 100% sure.
There was a problem hiding this comment.
done. and yeah, it works.
dcb651a to
a9cbef7
Compare
|
I also added opcodes for environmental ops like (BLOCKHASH, TIMESTAMP, etc.) |
|
Rebased, indented, sorted instructions by opcode number and changed all parameters to be 0 to aid comparing the opcode itself. |
AFAIK
SHA3is the only opcode not currently implemented in LLLC.Related: ethereum/aleth#4519