Browse Source

Create bad jump block on demand

cl-refactor
Paweł Bylica 10 years ago
parent
commit
024639bef6
  1. 28
      libevmjit/Compiler.cpp
  2. 10
      libevmjit/Compiler.h

28
libevmjit/Compiler.cpp

@ -94,13 +94,12 @@ void Compiler::createBasicBlocks(bytes const& _bytecode)
} }
m_stopBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Stop", m_mainFunc); m_stopBB = llvm::BasicBlock::Create(m_mainFunc->getContext(), "Stop", m_mainFunc);
m_badJumpBlock = std::unique_ptr<BasicBlock>(new BasicBlock("BadJumpBlock", m_mainFunc, m_builder));
for (auto it = indirectJumpTargets.cbegin(); it != indirectJumpTargets.cend(); ++it) for (auto it = indirectJumpTargets.cbegin(); it != indirectJumpTargets.cend(); ++it)
basicBlocks.find(*it)->second.markAsJumpDest(); basicBlocks.find(*it)->second.markAsJumpDest();
} }
BasicBlock& Compiler::getJumpTableBlock() llvm::BasicBlock* Compiler::getJumpTableBlock()
{ {
if (!m_jumpTableBlock) if (!m_jumpTableBlock)
{ {
@ -108,14 +107,26 @@ BasicBlock& Compiler::getJumpTableBlock()
InsertPointGuard g{m_builder}; InsertPointGuard g{m_builder};
m_builder.SetInsertPoint(m_jumpTableBlock->llvm()); m_builder.SetInsertPoint(m_jumpTableBlock->llvm());
auto dest = m_jumpTableBlock->localStack().pop(); auto dest = m_jumpTableBlock->localStack().pop();
auto switchInstr = m_builder.CreateSwitch(dest, m_badJumpBlock->llvm()); auto switchInstr = m_builder.CreateSwitch(dest, getBadJumpBlock());
for (auto&& p : basicBlocks) for (auto&& p : basicBlocks)
{ {
if (p.second.isJumpDest()) if (p.second.isJumpDest())
switchInstr->addCase(Constant::get(p.first), p.second.llvm()); switchInstr->addCase(Constant::get(p.first), p.second.llvm());
} }
} }
return *m_jumpTableBlock; return m_jumpTableBlock->llvm();
}
llvm::BasicBlock* Compiler::getBadJumpBlock()
{
if (!m_badJumpBlock)
{
m_badJumpBlock.reset(new BasicBlock("BadJump", m_mainFunc, m_builder));
InsertPointGuard g{m_builder};
m_builder.SetInsertPoint(m_badJumpBlock->llvm());
m_builder.CreateRet(Constant::get(ReturnCode::BadJumpDestination));
}
return m_badJumpBlock->llvm();
} }
std::unique_ptr<llvm::Module> Compiler::compile(bytes const& _bytecode, std::string const& _id) std::unique_ptr<llvm::Module> Compiler::compile(bytes const& _bytecode, std::string const& _id)
@ -158,9 +169,6 @@ std::unique_ptr<llvm::Module> Compiler::compile(bytes const& _bytecode, std::str
m_builder.SetInsertPoint(m_stopBB); m_builder.SetInsertPoint(m_stopBB);
m_builder.CreateRet(Constant::get(ReturnCode::Stop)); m_builder.CreateRet(Constant::get(ReturnCode::Stop));
m_builder.SetInsertPoint(m_badJumpBlock->llvm());
m_builder.CreateRet(Constant::get(ReturnCode::BadJumpDestination));
removeDeadBlocks(); removeDeadBlocks();
dumpCFGifRequired("blocks-init.dot"); dumpCFGifRequired("blocks-init.dot");
@ -560,7 +568,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode
} }
if (!targetBlock) if (!targetBlock)
targetBlock = m_badJumpBlock->llvm(); targetBlock = getBadJumpBlock();
} }
if (inst == Instruction::JUMP) if (inst == Instruction::JUMP)
@ -574,7 +582,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode
else else
{ {
stack.push(target); stack.push(target);
m_builder.CreateBr(getJumpTableBlock().llvm()); m_builder.CreateBr(getJumpTableBlock());
} }
} }
else // JUMPI else // JUMPI
@ -591,7 +599,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode
{ {
UNTESTED; UNTESTED;
stack.push(target); stack.push(target);
m_builder.CreateCondBr(cond, m_jumpTableBlock->llvm(), _nextBasicBlock); m_builder.CreateCondBr(cond, getJumpTableBlock(), _nextBasicBlock);
} }
} }
break; break;

10
libevmjit/Compiler.h

@ -47,7 +47,9 @@ private:
void compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode, class RuntimeManager& _runtimeManager, class Arith256& _arith, class Memory& _memory, class Ext& _ext, class GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock); void compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode, class RuntimeManager& _runtimeManager, class Arith256& _arith, class Memory& _memory, class Ext& _ext, class GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock);
BasicBlock& getJumpTableBlock(); llvm::BasicBlock* getJumpTableBlock();
llvm::BasicBlock* getBadJumpBlock();
void removeDeadBlocks(); void removeDeadBlocks();
@ -73,10 +75,10 @@ private:
llvm::BasicBlock* m_stopBB = nullptr; llvm::BasicBlock* m_stopBB = nullptr;
/// Block with a jump table. /// Block with a jump table.
std::unique_ptr<BasicBlock> m_jumpTableBlock = nullptr; std::unique_ptr<BasicBlock> m_jumpTableBlock;
/// Default destination for indirect jumps. /// Destination for invalid jumps
std::unique_ptr<BasicBlock> m_badJumpBlock = nullptr; std::unique_ptr<BasicBlock> m_badJumpBlock;
/// Main program function /// Main program function
llvm::Function* m_mainFunc = nullptr; llvm::Function* m_mainFunc = nullptr;

Loading…
Cancel
Save