|
|
@ -39,10 +39,10 @@ Compiler::Compiler(Options const& _options): |
|
|
|
Type::init(m_builder.getContext()); |
|
|
|
} |
|
|
|
|
|
|
|
void Compiler::createBasicBlocks(bytes const& _bytecode) |
|
|
|
void Compiler::createBasicBlocks(code_iterator _codeBegin, code_iterator _codeEnd) |
|
|
|
{ |
|
|
|
/// Helper function that skips push data and finds next iterator (can be the end)
|
|
|
|
auto skipPushDataAndGetNext = [](bytes::const_iterator _curr, bytes::const_iterator _end) |
|
|
|
auto skipPushDataAndGetNext = [](code_iterator _curr, code_iterator _end) |
|
|
|
{ |
|
|
|
static const auto push1 = static_cast<size_t>(Instruction::PUSH1); |
|
|
|
static const auto push32 = static_cast<size_t>(Instruction::PUSH32); |
|
|
@ -52,11 +52,11 @@ void Compiler::createBasicBlocks(bytes const& _bytecode) |
|
|
|
return _curr + offset; |
|
|
|
}; |
|
|
|
|
|
|
|
auto begin = _bytecode.begin(); |
|
|
|
auto begin = _codeBegin; // begin of current block
|
|
|
|
bool nextJumpDest = false; |
|
|
|
for (auto curr = begin, next = begin; curr != _bytecode.end(); curr = next) |
|
|
|
for (auto curr = begin, next = begin; curr != _codeEnd; curr = next) |
|
|
|
{ |
|
|
|
next = skipPushDataAndGetNext(curr, _bytecode.end()); |
|
|
|
next = skipPushDataAndGetNext(curr, _codeEnd); |
|
|
|
|
|
|
|
bool isEnd = false; |
|
|
|
switch (Instruction(*curr)) |
|
|
@ -77,13 +77,13 @@ void Compiler::createBasicBlocks(bytes const& _bytecode) |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
assert(next <= _bytecode.end()); |
|
|
|
if (next == _bytecode.end() || Instruction(*next) == Instruction::JUMPDEST) |
|
|
|
assert(next <= _codeEnd); |
|
|
|
if (next == _codeEnd || Instruction(*next) == Instruction::JUMPDEST) |
|
|
|
isEnd = true; |
|
|
|
|
|
|
|
if (isEnd) |
|
|
|
{ |
|
|
|
auto beginIdx = begin - _bytecode.begin(); |
|
|
|
auto beginIdx = begin - _codeBegin; |
|
|
|
m_basicBlocks.emplace(std::piecewise_construct, std::forward_as_tuple(beginIdx), |
|
|
|
std::forward_as_tuple(begin, next, m_mainFunc, m_builder, nextJumpDest)); |
|
|
|
nextJumpDest = false; |
|
|
@ -124,7 +124,7 @@ llvm::BasicBlock* Compiler::getBadJumpBlock() |
|
|
|
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(code_iterator _begin, code_iterator _end, std::string const& _id) |
|
|
|
{ |
|
|
|
auto compilationStartTime = std::chrono::high_resolution_clock::now(); |
|
|
|
auto module = std::unique_ptr<llvm::Module>(new llvm::Module(_id, m_builder.getContext())); |
|
|
@ -138,7 +138,8 @@ std::unique_ptr<llvm::Module> Compiler::compile(bytes const& _bytecode, std::str |
|
|
|
auto entryBlock = llvm::BasicBlock::Create(m_builder.getContext(), "entry", m_mainFunc); |
|
|
|
m_builder.SetInsertPoint(entryBlock); |
|
|
|
|
|
|
|
createBasicBlocks(_bytecode); |
|
|
|
m_codeBegin = _begin; |
|
|
|
createBasicBlocks(_begin, _end); |
|
|
|
|
|
|
|
// Init runtime structures.
|
|
|
|
RuntimeManager runtimeManager(m_builder); |
|
|
@ -156,7 +157,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(bytes const& _bytecode, std::str |
|
|
|
auto iterCopy = basicBlockPairIt; |
|
|
|
++iterCopy; |
|
|
|
auto nextBasicBlock = (iterCopy != m_basicBlocks.end()) ? iterCopy->second.llvm() : nullptr; |
|
|
|
compileBasicBlock(basicBlock, _bytecode, runtimeManager, arith, memory, ext, gasMeter, nextBasicBlock); |
|
|
|
compileBasicBlock(basicBlock, runtimeManager, arith, memory, ext, gasMeter, nextBasicBlock); |
|
|
|
} |
|
|
|
|
|
|
|
// Code for special blocks:
|
|
|
@ -223,7 +224,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(bytes const& _bytecode, std::str |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode, RuntimeManager& _runtimeManager, |
|
|
|
void Compiler::compileBasicBlock(BasicBlock& _basicBlock, RuntimeManager& _runtimeManager, |
|
|
|
Arith256& _arith, Memory& _memory, Ext& _ext, GasMeter& _gasMeter, llvm::BasicBlock* _nextBasicBlock) |
|
|
|
{ |
|
|
|
if (!_nextBasicBlock) // this is the last block in the code
|
|
|
@ -622,7 +623,7 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode |
|
|
|
|
|
|
|
case Instruction::PC: |
|
|
|
{ |
|
|
|
auto value = Constant::get(it - _bytecode.begin()); |
|
|
|
auto value = Constant::get(it - m_codeBegin); |
|
|
|
stack.push(value); |
|
|
|
break; |
|
|
|
} |
|
|
|