mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-20 03:36:44 +00:00
VM execution wrapper with similar interface as libevm/VM
This commit is contained in:
parent
9105fb1771
commit
0f4c8eb63f
7 changed files with 85 additions and 14 deletions
|
|
@ -94,7 +94,7 @@ int main(int argc, char** argv)
|
|||
if (opt_compile)
|
||||
{
|
||||
auto compiler = eth::jit::Compiler();
|
||||
auto module = compiler.compile(bytecode);
|
||||
auto module = compiler.compile({bytecode.data(), bytecode.size()});
|
||||
llvm::raw_os_ostream out(std::cout);
|
||||
module->print(out, nullptr);
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ int main(int argc, char** argv)
|
|||
if (opt_interpret)
|
||||
{
|
||||
auto engine = eth::jit::ExecutionEngine();
|
||||
auto module = eth::jit::Compiler().compile(bytecode);
|
||||
auto module = eth::jit::Compiler().compile({bytecode.data(), bytecode.size()});
|
||||
module->dump();
|
||||
auto result = engine.run(std::move(module));
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ Compiler::Compiler():
|
|||
Type::init(m_builder.getContext());
|
||||
}
|
||||
|
||||
void Compiler::createBasicBlocks(const bytes& bytecode)
|
||||
void Compiler::createBasicBlocks(bytesConstRef bytecode)
|
||||
{
|
||||
std::set<ProgramCounter> splitPoints; // Sorted collections of instruction indices where basic blocks start/end
|
||||
splitPoints.insert(0); // First basic block
|
||||
|
|
@ -38,9 +38,9 @@ void Compiler::createBasicBlocks(const bytes& bytecode)
|
|||
std::vector<ProgramCounter> indirectJumpTargets;
|
||||
boost::dynamic_bitset<> validJumpTargets(bytecode.size());
|
||||
|
||||
for (auto curr = bytecode.cbegin(); curr != bytecode.cend(); ++curr)
|
||||
for (auto curr = bytecode.begin(); curr != bytecode.end(); ++curr)
|
||||
{
|
||||
ProgramCounter currentPC = curr - bytecode.cbegin();
|
||||
ProgramCounter currentPC = curr - bytecode.begin();
|
||||
validJumpTargets[currentPC] = 1;
|
||||
|
||||
auto inst = static_cast<Instruction>(*curr);
|
||||
|
|
@ -51,7 +51,7 @@ void Compiler::createBasicBlocks(const bytes& bytecode)
|
|||
{
|
||||
auto numBytes = static_cast<size_t>(inst) - static_cast<size_t>(Instruction::PUSH1) + 1;
|
||||
auto next = curr + numBytes + 1;
|
||||
if (next >= bytecode.cend())
|
||||
if (next >= bytecode.end())
|
||||
break;
|
||||
|
||||
auto nextInst = static_cast<Instruction>(*next);
|
||||
|
|
@ -72,7 +72,7 @@ void Compiler::createBasicBlocks(const bytes& bytecode)
|
|||
targetPC = bytecode.size();
|
||||
splitPoints.insert(targetPC);
|
||||
|
||||
ProgramCounter jumpPC = (next - bytecode.cbegin());
|
||||
ProgramCounter jumpPC = (next - bytecode.begin());
|
||||
directJumpTargets[jumpPC] = targetPC;
|
||||
}
|
||||
|
||||
|
|
@ -95,7 +95,7 @@ void Compiler::createBasicBlocks(const bytes& bytecode)
|
|||
case Instruction::SUICIDE:
|
||||
{
|
||||
// Create a basic block starting at the following instruction.
|
||||
if (curr + 1 < bytecode.cend())
|
||||
if (curr + 1 < bytecode.end())
|
||||
{
|
||||
splitPoints.insert(currentPC + 1);
|
||||
}
|
||||
|
|
@ -149,7 +149,7 @@ void Compiler::createBasicBlocks(const bytes& bytecode)
|
|||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
||||
std::unique_ptr<llvm::Module> Compiler::compile(bytesConstRef bytecode)
|
||||
{
|
||||
auto module = std::make_unique<llvm::Module>("main", m_builder.getContext());
|
||||
|
||||
|
|
@ -214,7 +214,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const bytes& bytecode)
|
|||
}
|
||||
|
||||
|
||||
void Compiler::compileBasicBlock(BasicBlock& basicBlock, const bytes& bytecode, Memory& memory, Ext& ext, GasMeter& gasMeter, llvm::BasicBlock* nextBasicBlock)
|
||||
void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode, Memory& memory, Ext& ext, GasMeter& gasMeter, llvm::BasicBlock* nextBasicBlock)
|
||||
{
|
||||
auto& stack = basicBlock.getStack();
|
||||
m_builder.SetInsertPoint(basicBlock.llvm());
|
||||
|
|
|
|||
|
|
@ -22,16 +22,16 @@ public:
|
|||
|
||||
Compiler();
|
||||
|
||||
std::unique_ptr<llvm::Module> compile(const bytes& bytecode);
|
||||
std::unique_ptr<llvm::Module> compile(bytesConstRef bytecode);
|
||||
|
||||
void dumpBasicBlockGraph(std::ostream& out);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void createBasicBlocks(const bytes& bytecode);
|
||||
void createBasicBlocks(bytesConstRef bytecode);
|
||||
|
||||
void compileBasicBlock(BasicBlock& basicBlock, const bytes& bytecode, class Memory& memory, class Ext& ext, class GasMeter& gasMeter, llvm::BasicBlock* nextBasicBlock);
|
||||
void compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode, class Memory& memory, class Ext& ext, class GasMeter& gasMeter, llvm::BasicBlock* nextBasicBlock);
|
||||
|
||||
void linkBasicBlocks();
|
||||
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
|
|||
|
||||
if (returnCode == ReturnCode::Return)
|
||||
{
|
||||
auto&& returnData = Memory::getReturnData(); // TODO: It might be better to place is in Runtime interface
|
||||
returnData = Memory::getReturnData().toVector(); // TODO: It might be better to place is in Runtime interface
|
||||
|
||||
std::cout << "RETURN [ ";
|
||||
for (auto it = returnData.begin(), end = returnData.end(); it != end; ++it)
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ public:
|
|||
ExecutionEngine();
|
||||
|
||||
int run(std::unique_ptr<llvm::Module> module);
|
||||
|
||||
bytes returnData;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
37
libevmjit/VM.cpp
Normal file
37
libevmjit/VM.cpp
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
#include "VM.h"
|
||||
|
||||
#include <libevm/VM.h>
|
||||
|
||||
#include "ExecutionEngine.h"
|
||||
#include "Compiler.h"
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace eth
|
||||
{
|
||||
namespace jit
|
||||
{
|
||||
|
||||
bytes VM::go(ExtVMFace& _ext)
|
||||
{
|
||||
auto module = Compiler().compile(_ext.code);
|
||||
module->dump();
|
||||
|
||||
ExecutionEngine engine;
|
||||
auto exitCode = engine.run(std::move(module));
|
||||
|
||||
switch (exitCode)
|
||||
{
|
||||
case 101:
|
||||
BOOST_THROW_EXCEPTION(BadJumpDestination());
|
||||
case 102:
|
||||
BOOST_THROW_EXCEPTION(OutOfGas());
|
||||
}
|
||||
|
||||
return std::move(engine.returnData);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
32
libevmjit/VM.h
Normal file
32
libevmjit/VM.h
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <libdevcore/Common.h>
|
||||
#include <libevm/ExtVMFace.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace eth
|
||||
{
|
||||
namespace jit
|
||||
{
|
||||
|
||||
class VM
|
||||
{
|
||||
public:
|
||||
/// Construct VM object.
|
||||
explicit VM(u256 _gas = 0): m_gas(_gas) {}
|
||||
|
||||
void reset(u256 _gas = 0) { m_gas = _gas; }
|
||||
|
||||
bytes go(ExtVMFace& _ext);
|
||||
|
||||
u256 gas() const { return m_gas; }
|
||||
|
||||
private:
|
||||
u256 m_gas = 0;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue