Browse Source

JUMPI fix: an additional item was left on stack when condition is false

cl-refactor
Paweł Bylica 10 years ago
parent
commit
5152596cbd
  1. 6
      libevmjit/BasicBlock.h
  2. 26
      libevmjit/Compiler.cpp

6
libevmjit/BasicBlock.h

@ -66,6 +66,9 @@ public:
bool isJumpDest() const { return m_isJumpDest; }
llvm::Value* getJumpTarget() const { return m_jumpTarget; }
void setJumpTarget(llvm::Value* _jumpTarget) { m_jumpTarget = _jumpTarget; }
LocalStack& localStack() { return m_stack; }
/// Optimization: propagates values between local stacks in basic blocks
@ -112,6 +115,9 @@ private:
/// Is the basic block a valid jump destination.
/// JUMPDEST is the first instruction of the basic block.
bool const m_isJumpDest = false;
/// If block finishes with dynamic jump target index is stored here
llvm::Value* m_jumpTarget = nullptr;
};
}

26
libevmjit/Compiler.cpp

@ -100,7 +100,7 @@ llvm::BasicBlock* Compiler::getJumpTableBlock()
m_jumpTableBlock.reset(new BasicBlock("JumpTable", m_mainFunc, m_builder, true));
InsertPointGuard g{m_builder};
m_builder.SetInsertPoint(m_jumpTableBlock->llvm());
auto dest = m_jumpTableBlock->localStack().pop();
auto dest = m_builder.CreatePHI(Type::Word, 8, "target");
auto switchInstr = m_builder.CreateSwitch(dest, getBadJumpBlock());
for (auto&& p : m_basicBlocks)
{
@ -165,6 +165,26 @@ std::unique_ptr<llvm::Module> Compiler::compile(bytes const& _bytecode, std::str
removeDeadBlocks();
// Link jump table target index
if (m_jumpTableBlock)
{
auto phi = llvm::cast<llvm::PHINode>(&m_jumpTableBlock->llvm()->getInstList().front());
for (auto predIt = llvm::pred_begin(m_jumpTableBlock->llvm()); predIt != llvm::pred_end(m_jumpTableBlock->llvm()); ++predIt)
{
BasicBlock* pred = nullptr;
for (auto&& p : m_basicBlocks)
{
if (p.second.llvm() == *predIt)
{
pred = &p.second;
break;
}
}
phi->addIncoming(pred->getJumpTarget(), pred->llvm());
}
}
dumpCFGifRequired("blocks-init.dot");
if (m_options.optimizeStack)
@ -565,7 +585,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode
}
else
{
stack.push(target);
_basicBlock.setJumpTarget(target);
m_builder.CreateBr(getJumpTableBlock());
}
}
@ -581,7 +601,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode
}
else
{
stack.push(target);
_basicBlock.setJumpTarget(target);
m_builder.CreateCondBr(cond, getJumpTableBlock(), _nextBasicBlock);
}
}

Loading…
Cancel
Save