mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #2399 from ethereum/lll-if
LLL: Replace obsolete assembly code
This commit is contained in:
commit
1c54ce2a2c
@ -55,9 +55,6 @@ void Assembly::append(Assembly const& _a)
|
||||
m_subs += _a.m_subs;
|
||||
for (auto const& lib: _a.m_libraries)
|
||||
m_libraries.insert(lib);
|
||||
|
||||
assert(!_a.m_baseDeposit);
|
||||
assert(!_a.m_totalDeposit);
|
||||
}
|
||||
|
||||
void Assembly::append(Assembly const& _a, int _deposit)
|
||||
|
@ -85,12 +85,6 @@ public:
|
||||
AssemblyItem const& back() const { return m_items.back(); }
|
||||
std::string backString() const { return m_items.size() && m_items.back().type() == PushString ? m_strings.at((h256)m_items.back().data()) : std::string(); }
|
||||
|
||||
void onePath() { assertThrow(!m_totalDeposit && !m_baseDeposit, InvalidDeposit, ""); m_baseDeposit = m_deposit; m_totalDeposit = INT_MAX; }
|
||||
void otherPath() { donePath(); m_totalDeposit = m_deposit; m_deposit = m_baseDeposit; }
|
||||
void donePaths() { donePath(); m_totalDeposit = m_baseDeposit = 0; }
|
||||
void ignored() { m_baseDeposit = m_deposit; }
|
||||
void endIgnored() { m_deposit = m_baseDeposit; m_baseDeposit = 0; }
|
||||
|
||||
void injectStart(AssemblyItem const& _i);
|
||||
int deposit() const { return m_deposit; }
|
||||
void adjustDeposit(int _adjustment) { m_deposit += _adjustment; assertThrow(m_deposit >= 0, InvalidDeposit, ""); }
|
||||
@ -121,7 +115,6 @@ protected:
|
||||
/// returns the replaced tags.
|
||||
std::map<u256, u256> optimiseInternal(bool _enable, bool _isCreation, size_t _runs);
|
||||
|
||||
void donePath() { if (m_totalDeposit != INT_MAX && m_totalDeposit != m_deposit) BOOST_THROW_EXCEPTION(InvalidDeposit()); }
|
||||
unsigned bytesRequired(unsigned subTagSize) const;
|
||||
|
||||
private:
|
||||
@ -144,8 +137,6 @@ protected:
|
||||
mutable std::vector<size_t> m_tagPositionsInBytecode;
|
||||
|
||||
int m_deposit = 0;
|
||||
int m_baseDeposit = 0;
|
||||
int m_totalDeposit = 0;
|
||||
|
||||
SourceLocation m_currentSourceLocation;
|
||||
};
|
||||
|
@ -439,15 +439,21 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
|
||||
int minDep = min(code[1].m_asm.deposit(), code[2].m_asm.deposit());
|
||||
|
||||
m_asm.append(code[0].m_asm);
|
||||
auto pos = m_asm.appendJumpI();
|
||||
m_asm.onePath();
|
||||
auto mainBranch = m_asm.appendJumpI();
|
||||
|
||||
/// The else branch.
|
||||
int startDeposit = m_asm.deposit();
|
||||
m_asm.append(code[2].m_asm, minDep);
|
||||
auto end = m_asm.appendJump();
|
||||
m_asm.otherPath();
|
||||
m_asm << pos.tag();
|
||||
int deposit = m_asm.deposit();
|
||||
m_asm.setDeposit(startDeposit);
|
||||
|
||||
/// The main branch.
|
||||
m_asm << mainBranch.tag();
|
||||
m_asm.append(code[1].m_asm, minDep);
|
||||
m_asm << end.tag();
|
||||
m_asm.donePaths();
|
||||
if (m_asm.deposit() != deposit)
|
||||
error<InvalidDeposit>();
|
||||
}
|
||||
else if (us == "WHEN" || us == "UNLESS")
|
||||
{
|
||||
@ -458,11 +464,8 @@ void CodeFragment::constructOperation(sp::utree const& _t, CompilerState& _s)
|
||||
if (us == "WHEN")
|
||||
m_asm.append(Instruction::ISZERO);
|
||||
auto end = m_asm.appendJumpI();
|
||||
m_asm.onePath();
|
||||
m_asm.otherPath();
|
||||
m_asm.append(code[1].m_asm, 0);
|
||||
m_asm << end.tag();
|
||||
m_asm.donePaths();
|
||||
}
|
||||
else if (us == "WHILE" || us == "UNTIL")
|
||||
{
|
||||
|
@ -57,6 +57,68 @@ BOOST_AUTO_TEST_CASE(panic)
|
||||
BOOST_REQUIRE(m_output.empty());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(when)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(when (= (calldatasize) 0) (return 1))
|
||||
(when (!= (calldatasize) 0) (return 2))))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(2)));
|
||||
BOOST_CHECK(callFallback() == toBigEndian(u256(1)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(unless)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(unless (!= (calldatasize) 0) (return 1))
|
||||
(unless (= (calldatasize) 0) (return 2))))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(2)));
|
||||
BOOST_CHECK(callFallback() == toBigEndian(u256(1)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(conditional_literal)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(return (if (= (calldatasize) 0) 1 2))))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(2)));
|
||||
BOOST_CHECK(callFallback() == toBigEndian(u256(1)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(conditional)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(if (= (calldatasize) 0) (return 1) (return 2))))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(2)));
|
||||
BOOST_CHECK(callFallback() == toBigEndian(u256(1)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(conditional_seq)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
(returnlll
|
||||
(seq
|
||||
(return (if (= (calldatasize) 0) { 0 2 1 } { 0 1 2 }))))
|
||||
)";
|
||||
compileAndRun(sourceCode);
|
||||
BOOST_CHECK(callContractFunction("test()") == encodeArgs(u256(2)));
|
||||
BOOST_CHECK(callFallback() == toBigEndian(u256(1)));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(exp_operator_const)
|
||||
{
|
||||
char const* sourceCode = R"(
|
||||
|
Loading…
Reference in New Issue
Block a user