mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
JUMPI fix: an additional item was left on stack when condition is false
This commit is contained in:
parent
0f53e2153a
commit
5152596cbd
2 changed files with 29 additions and 3 deletions
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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…
Reference in a new issue