Browse Source

Merge pull request #1875 from chriseth/sol_invertIf

Reverse if and else body.
cl-refactor
Gav Wood 10 years ago
parent
commit
c10980c126
  1. 12
      libsolidity/Compiler.cpp
  2. 59
      test/libsolidity/SolidityCompiler.cpp

12
libsolidity/Compiler.cpp

@ -377,12 +377,16 @@ bool Compiler::visit(IfStatement const& _ifStatement)
StackHeightChecker checker(m_context); StackHeightChecker checker(m_context);
CompilerContext::LocationSetter locationSetter(m_context, _ifStatement); CompilerContext::LocationSetter locationSetter(m_context, _ifStatement);
compileExpression(_ifStatement.getCondition()); compileExpression(_ifStatement.getCondition());
eth::AssemblyItem trueTag = m_context.appendConditionalJump(); m_context << eth::Instruction::ISZERO;
eth::AssemblyItem falseTag = m_context.appendConditionalJump();
eth::AssemblyItem endTag = falseTag;
_ifStatement.getTrueStatement().accept(*this);
if (_ifStatement.getFalseStatement()) if (_ifStatement.getFalseStatement())
{
endTag = m_context.appendJumpToNew();
m_context << falseTag;
_ifStatement.getFalseStatement()->accept(*this); _ifStatement.getFalseStatement()->accept(*this);
eth::AssemblyItem endTag = m_context.appendJumpToNew(); }
m_context << trueTag;
_ifStatement.getTrueStatement().accept(*this);
m_context << endTag; m_context << endTag;
checker.check(); checker.check();

59
test/libsolidity/SolidityCompiler.cpp

@ -116,36 +116,35 @@ BOOST_AUTO_TEST_CASE(ifStatement)
bytes code = compileContract(sourceCode); bytes code = compileContract(sourceCode);
unsigned shift = 60; unsigned shift = 60;
unsigned boilerplateSize = 73; unsigned boilerplateSize = 73;
bytes expectation({byte(Instruction::JUMPDEST), bytes expectation({
byte(Instruction::PUSH1), 0x0, byte(Instruction::JUMPDEST),
byte(Instruction::DUP1), byte(Instruction::PUSH1), 0x0,
byte(Instruction::PUSH1), byte(0x1b + shift), // "true" target byte(Instruction::DUP1),
byte(Instruction::JUMPI), byte(Instruction::ISZERO),
// new check "else if" condition byte(Instruction::PUSH1), byte(0x0f + shift), // "false" target
byte(Instruction::DUP1), byte(Instruction::JUMPI),
byte(Instruction::ISZERO), // "if" body
byte(Instruction::PUSH1), byte(0x13 + shift), byte(Instruction::PUSH1), 0x4d,
byte(Instruction::JUMPI), byte(Instruction::POP),
// "else" body byte(Instruction::PUSH1), byte(0x21 + shift),
byte(Instruction::PUSH1), 0x4f, byte(Instruction::JUMP),
byte(Instruction::POP), // new check "else if" condition
byte(Instruction::PUSH1), byte(0x17 + shift), // exit path of second part byte(Instruction::JUMPDEST),
byte(Instruction::JUMP), byte(Instruction::DUP1),
// "else if" body byte(Instruction::ISZERO),
byte(Instruction::JUMPDEST), byte(Instruction::ISZERO),
byte(Instruction::PUSH1), 0x4e, byte(Instruction::PUSH1), byte(0x1c + shift),
byte(Instruction::POP), byte(Instruction::JUMPI),
byte(Instruction::JUMPDEST), // "else if" body
byte(Instruction::PUSH1), byte(0x1f + shift), byte(Instruction::PUSH1), 0x4e,
byte(Instruction::JUMP), byte(Instruction::POP),
// "if" body byte(Instruction::PUSH1), byte(0x20 + shift),
byte(Instruction::JUMPDEST), byte(Instruction::JUMP),
byte(Instruction::PUSH1), 0x4d, // "else" body
byte(Instruction::POP), byte(Instruction::JUMPDEST),
byte(Instruction::JUMPDEST), byte(Instruction::PUSH1), 0x4f,
byte(Instruction::JUMPDEST), byte(Instruction::POP),
byte(Instruction::POP), });
byte(Instruction::JUMP)});
checkCodePresentAt(code, expectation, boilerplateSize); checkCodePresentAt(code, expectation, boilerplateSize);
} }

Loading…
Cancel
Save