Browse Source

Add support for direct jump outside the code - terminates with STOP

cl-refactor
Paweł Bylica 10 years ago
parent
commit
52ba848c18
  1. 21
      libevmjit/Compiler.cpp
  2. 2
      libevmjit/Compiler.h

21
libevmjit/Compiler.cpp

@ -67,9 +67,7 @@ void Compiler::createBasicBlocks(bytesConstRef bytecode)
} }
// Create a block for the JUMP target. // Create a block for the JUMP target.
ProgramCounter targetPC = val.convert_to<ProgramCounter>(); ProgramCounter targetPC = val < bytecode.size() ? val.convert_to<ProgramCounter>() : bytecode.size();
if (targetPC > bytecode.size())
targetPC = bytecode.size();
splitPoints.insert(targetPC); splitPoints.insert(targetPC);
ProgramCounter jumpPC = (next - bytecode.begin()); ProgramCounter jumpPC = (next - bytecode.begin());
@ -130,16 +128,23 @@ void Compiler::createBasicBlocks(bytesConstRef bytecode)
for (auto it = directJumpTargets.cbegin(); it != directJumpTargets.cend(); ++it) for (auto it = directJumpTargets.cbegin(); it != directJumpTargets.cend(); ++it)
{ {
if (it->second >= bytecode.size())
{
// Jumping out of code means STOP
m_directJumpTargets[it->first] = m_stopBB;
continue;
}
auto blockIter = basicBlocks.find(it->second); auto blockIter = basicBlocks.find(it->second);
if (blockIter != basicBlocks.end()) if (blockIter != basicBlocks.end())
{ {
m_directJumpTargets[it->first] = &(blockIter->second); m_directJumpTargets[it->first] = blockIter->second.llvm();
} }
else else
{ {
std::cerr << "Bad JUMP at PC " << it->first std::cerr << "Bad JUMP at PC " << it->first
<< ": " << it->second << " is not a valid PC\n"; << ": " << it->second << " is not a valid PC\n";
m_directJumpTargets[it->first] = m_badJumpBlock.get(); m_directJumpTargets[it->first] = m_badJumpBlock->llvm();
} }
} }
@ -567,7 +572,7 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode,
// 1. this is not the first instruction in the block // 1. this is not the first instruction in the block
// 2. m_directJumpTargets[currentPC] is defined (meaning that the previous instruction is a PUSH) // 2. m_directJumpTargets[currentPC] is defined (meaning that the previous instruction is a PUSH)
// Otherwise generate a indirect jump (a switch). // Otherwise generate a indirect jump (a switch).
BasicBlock* targetBlock = nullptr; llvm::BasicBlock* targetBlock = nullptr;
if (currentPC != basicBlock.begin()) if (currentPC != basicBlock.begin())
{ {
auto pairIter = m_directJumpTargets.find(currentPC); auto pairIter = m_directJumpTargets.find(currentPC);
@ -584,7 +589,7 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode,
// The target address is computed at compile time, // The target address is computed at compile time,
// just pop it without looking... // just pop it without looking...
stack.pop(); stack.pop();
m_builder.CreateBr(targetBlock->llvm()); m_builder.CreateBr(targetBlock);
} }
else else
{ {
@ -606,7 +611,7 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode,
if (targetBlock) if (targetBlock)
{ {
stack.pop(); stack.pop();
m_builder.CreateCondBr(cond, targetBlock->llvm(), nextBasicBlock); m_builder.CreateCondBr(cond, targetBlock, nextBasicBlock);
} }
else else
{ {

2
libevmjit/Compiler.h

@ -46,7 +46,7 @@ private:
/** /**
* Maps a pc at which there is a JUMP or JUMPI to the target block of the jump. * Maps a pc at which there is a JUMP or JUMPI to the target block of the jump.
*/ */
std::map<ProgramCounter, BasicBlock*> m_directJumpTargets; std::map<ProgramCounter, llvm::BasicBlock*> m_directJumpTargets;
/** /**
* A list of possible blocks to which there may be indirect jumps. * A list of possible blocks to which there may be indirect jumps.

Loading…
Cancel
Save