mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
Add support for direct jump outside the code - terminates with STOP
This commit is contained in:
parent
6c3af96a40
commit
52ba848c18
2 changed files with 14 additions and 9 deletions
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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…
Reference in a new issue