mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-20 11:46:44 +00:00
Merge branch 'develop-evmcc' of https://github.com/imapp-pl/ethereum into develop-evmcc
This commit is contained in:
commit
293f0de7a9
15 changed files with 126 additions and 64 deletions
|
|
@ -139,7 +139,16 @@ void Compiler::createBasicBlocks(const dev::bytes& bytecode)
|
|||
}
|
||||
}
|
||||
|
||||
for (auto it = splitPoints.cbegin(); it != splitPoints.cend() && *it < bytecode.size();)
|
||||
// Remove split points generated from jumps out of code or into data.
|
||||
for (auto it = splitPoints.cbegin(); it != splitPoints.cend(); )
|
||||
{
|
||||
if (*it > bytecode.size() || !validJumpTargets[*it])
|
||||
it = splitPoints.erase(it);
|
||||
else
|
||||
++it;
|
||||
}
|
||||
|
||||
for (auto it = splitPoints.cbegin(); it != splitPoints.cend(); )
|
||||
{
|
||||
auto beginInstIdx = *it;
|
||||
++it;
|
||||
|
|
@ -153,28 +162,22 @@ void Compiler::createBasicBlocks(const dev::bytes& bytecode)
|
|||
|
||||
for (auto it = directJumpTargets.cbegin(); it != directJumpTargets.cend(); ++it)
|
||||
{
|
||||
if (it->second >= bytecode.size()) // Jump out of code
|
||||
auto blockIter = basicBlocks.find(it->second);
|
||||
if (blockIter != basicBlocks.end())
|
||||
{
|
||||
m_directJumpTargets[it->first] = m_finalBlock.get();
|
||||
m_directJumpTargets[it->first] = &(blockIter->second);
|
||||
}
|
||||
else if (!validJumpTargets[it->second]) // Jump into data
|
||||
else
|
||||
{
|
||||
std::cerr << "Bad JUMP at PC " << it->first
|
||||
<< ": " << it->second << " is not a valid PC\n";
|
||||
m_directJumpTargets[it->first] = m_badJumpBlock.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_directJumpTargets[it->first] = &basicBlocks.find(it->second)->second;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto it = indirectJumpTargets.cbegin(); it != indirectJumpTargets.cend(); ++it)
|
||||
{
|
||||
if (*it >= bytecode.size())
|
||||
m_indirectJumpTargets.push_back(m_finalBlock.get());
|
||||
else
|
||||
m_indirectJumpTargets.push_back(&basicBlocks.find(*it)->second);
|
||||
m_indirectJumpTargets.push_back(&basicBlocks.find(*it)->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -589,58 +592,56 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
// 1. this is not the first instruction in the block
|
||||
// 2. m_directJumpTargets[currentPC] is defined (meaning that the previous instruction is a PUSH)
|
||||
// Otherwise generate a indirect jump (a switch).
|
||||
BasicBlock* targetBlock = nullptr;
|
||||
if (currentPC != basicBlock.begin())
|
||||
{
|
||||
auto pairIter = m_directJumpTargets.find(currentPC);
|
||||
if (pairIter != m_directJumpTargets.end())
|
||||
{
|
||||
auto targetBlock = pairIter->second;
|
||||
|
||||
// The target address is computed at compile time,
|
||||
// just pop it without looking...
|
||||
stack.pop();
|
||||
|
||||
if (inst == Instruction::JUMP)
|
||||
{
|
||||
builder.CreateBr(targetBlock->llvm());
|
||||
}
|
||||
else // JUMPI
|
||||
{
|
||||
auto top = stack.pop();
|
||||
auto zero = ConstantInt::get(Type::i256, 0);
|
||||
auto cond = builder.CreateICmpNE(top, zero, "nonzero");
|
||||
|
||||
// Assume the basic blocks are properly ordered:
|
||||
auto nextBBIter = basicBlockPairIt;
|
||||
++nextBBIter;
|
||||
assert (nextBBIter != basicBlocks.end());
|
||||
auto& followBlock = nextBBIter->second;
|
||||
builder.CreateCondBr(cond, targetBlock->llvm(), followBlock.llvm());
|
||||
}
|
||||
break;
|
||||
targetBlock = pairIter->second;
|
||||
}
|
||||
}
|
||||
|
||||
if (inst == Instruction::JUMPI)
|
||||
if (inst == Instruction::JUMP)
|
||||
{
|
||||
std::cerr << "Indirect JUMPI is not supported yet (at PC "
|
||||
<< currentPC << ")\n";
|
||||
std::exit(1);
|
||||
if (targetBlock)
|
||||
{
|
||||
// The target address is computed at compile time,
|
||||
// just pop it without looking...
|
||||
stack.pop();
|
||||
builder.CreateBr(targetBlock->llvm());
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: this get(0) is a temporary workaround to get some of the jump tests running.
|
||||
stack.get(0);
|
||||
builder.CreateBr(m_jumpTableBlock->llvm());
|
||||
}
|
||||
}
|
||||
else // JUMPI
|
||||
{
|
||||
stack.swap(1);
|
||||
auto val = stack.pop();
|
||||
auto zero = ConstantInt::get(Type::i256, 0);
|
||||
auto cond = builder.CreateICmpNE(val, zero, "nonzero");
|
||||
|
||||
// Assume the basic blocks are properly ordered:
|
||||
auto nextBBIter = basicBlockPairIt;
|
||||
++nextBBIter;
|
||||
assert (nextBBIter != basicBlocks.end());
|
||||
auto& followBlock = nextBBIter->second;
|
||||
|
||||
if (targetBlock)
|
||||
{
|
||||
stack.pop();
|
||||
builder.CreateCondBr(cond, targetBlock->llvm(), followBlock.llvm());
|
||||
}
|
||||
else
|
||||
{
|
||||
builder.CreateCondBr(cond, m_jumpTableBlock->llvm(), followBlock.llvm());
|
||||
}
|
||||
}
|
||||
|
||||
builder.CreateBr(m_jumpTableBlock->llvm());
|
||||
/*
|
||||
// Generate switch for indirect jump.
|
||||
auto dest = stack.pop();
|
||||
auto switchInstr = builder.CreateSwitch(dest, m_badJumpBlock->llvm(),
|
||||
m_indirectJumpTargets.size());
|
||||
for (auto it = m_indirectJumpTargets.cbegin(); it != m_indirectJumpTargets.cend(); ++it)
|
||||
{
|
||||
auto& bb = *it;
|
||||
auto dest = ConstantInt::get(Type::i256, bb->begin());
|
||||
switchInstr->addCase(dest, bb->llvm());
|
||||
}
|
||||
*/
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -869,7 +870,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
|||
}
|
||||
else
|
||||
{
|
||||
builder.CreateRet(builder.getInt64(0));
|
||||
builder.CreateBr(m_badJumpBlock->llvm());
|
||||
}
|
||||
|
||||
linkBasicBlocks();
|
||||
|
|
|
|||
|
|
@ -30,9 +30,9 @@ private:
|
|||
/// @TODO Handle overflow
|
||||
uint64_t m_blockCost = 0;
|
||||
llvm::IRBuilder<>& m_builder;
|
||||
llvm::CallInst* m_checkCall;
|
||||
llvm::CallInst* m_checkCall = nullptr;
|
||||
llvm::GlobalVariable* m_gas;
|
||||
llvm::Function* m_gasCheckFunc;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
1
evmcc/test/jump/badindirect1.evm
Normal file
1
evmcc/test/jump/badindirect1.evm
Normal file
|
|
@ -0,0 +1 @@
|
|||
601b602502585d
|
||||
9
evmcc/test/jump/badindirect1.lll
Normal file
9
evmcc/test/jump/badindirect1.lll
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
;; Indirect jump out of code
|
||||
|
||||
(asm
|
||||
27
|
||||
37
|
||||
MUL
|
||||
JUMP
|
||||
JUMPDEST
|
||||
)
|
||||
1
evmcc/test/jump/badindirect2.evm
Normal file
1
evmcc/test/jump/badindirect2.evm
Normal file
|
|
@ -0,0 +1 @@
|
|||
60016003600302596000600058
|
||||
12
evmcc/test/jump/badindirect2.lll
Normal file
12
evmcc/test/jump/badindirect2.lll
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
;; Indirect jump into data
|
||||
|
||||
(asm
|
||||
1 ;; 0
|
||||
3
|
||||
3
|
||||
MUL ;; 6
|
||||
JUMPI ;; 7
|
||||
0 ;; 8
|
||||
0
|
||||
JUMP
|
||||
)
|
||||
|
|
@ -1 +1 @@
|
|||
601b602502585d
|
||||
6103e758
|
||||
|
|
|
|||
|
|
@ -1,9 +1,6 @@
|
|||
;; Bad indirect jump. Should go to BadJumpBlock.
|
||||
;; Direct jump out of code.
|
||||
|
||||
(asm
|
||||
27
|
||||
37
|
||||
MUL
|
||||
999
|
||||
JUMP
|
||||
JUMPDEST
|
||||
)
|
||||
1
evmcc/test/jump/badjump2.evm
Normal file
1
evmcc/test/jump/badjump2.evm
Normal file
|
|
@ -0,0 +1 @@
|
|||
6004586000600058
|
||||
9
evmcc/test/jump/badjump2.lll
Normal file
9
evmcc/test/jump/badjump2.lll
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
;; Direct jump into data
|
||||
|
||||
(asm
|
||||
4 ;; 0 0-3
|
||||
JUMP ;; 2
|
||||
0 ;; 3 3-4
|
||||
0 ;; 5 4-7
|
||||
JUMP ;; 6
|
||||
)
|
||||
|
|
@ -4,14 +4,14 @@
|
|||
8 ;; 0
|
||||
6 ;; 2
|
||||
ADD ;; 4
|
||||
JUMP ;; 5
|
||||
JUMP ;; 5 --> 14
|
||||
STOP ;; 6
|
||||
JUMPDEST ;; 7
|
||||
1 ;; 8
|
||||
0 ;; 10
|
||||
MSTORE ;; 12
|
||||
STOP ;; 13
|
||||
JUMPDEST ;; 14
|
||||
JUMPDEST ;; 14
|
||||
2
|
||||
0
|
||||
MSTORE
|
||||
|
|
|
|||
1
evmcc/test/jump/indirect3.evm
Normal file
1
evmcc/test/jump/indirect3.evm
Normal file
|
|
@ -0,0 +1 @@
|
|||
6001600460050159005d6001600054
|
||||
14
evmcc/test/jump/indirect3.lll
Normal file
14
evmcc/test/jump/indirect3.lll
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
;; Indirect JUMP
|
||||
|
||||
(asm
|
||||
1 ;; 0
|
||||
4 ;; 2
|
||||
5 ;; 4
|
||||
ADD ;; 6
|
||||
JUMPI ;; 7
|
||||
STOP ;; 8
|
||||
JUMPDEST ;; 9
|
||||
1
|
||||
0
|
||||
MSTORE
|
||||
)
|
||||
1
evmcc/test/jump/indirect4.evm
Normal file
1
evmcc/test/jump/indirect4.evm
Normal file
|
|
@ -0,0 +1 @@
|
|||
60006007600501596001600054005d00
|
||||
15
evmcc/test/jump/indirect4.lll
Normal file
15
evmcc/test/jump/indirect4.lll
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
;; Indirect JUMP
|
||||
|
||||
(asm
|
||||
0 ;; 0
|
||||
7 ;; 2
|
||||
5 ;; 4
|
||||
ADD ;; 6
|
||||
JUMPI ;; 7
|
||||
1 ;; 8
|
||||
0 ;; 9
|
||||
MSTORE ;; 10
|
||||
STOP ;; 11
|
||||
JUMPDEST ;; 12
|
||||
STOP
|
||||
)
|
||||
Loading…
Reference in a new issue