Browse Source

VM execution wrapper with similar interface as libevm/VM

cl-refactor
Paweł Bylica 10 years ago
parent
commit
9552394cd1
  1. 4
      evmcc/evmcc.cpp
  2. 16
      libevmjit/Compiler.cpp
  3. 6
      libevmjit/Compiler.h
  4. 2
      libevmjit/ExecutionEngine.cpp
  5. 2
      libevmjit/ExecutionEngine.h
  6. 37
      libevmjit/VM.cpp
  7. 32
      libevmjit/VM.h
  8. 2
      windows/LibEvmJit.vcxproj
  9. 6
      windows/LibEvmJit.vcxproj.filters

4
evmcc/evmcc.cpp

@ -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;

16
libevmjit/Compiler.cpp

@ -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());

6
libevmjit/Compiler.h

@ -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();

2
libevmjit/ExecutionEngine.cpp

@ -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)

2
libevmjit/ExecutionEngine.h

@ -18,6 +18,8 @@ public:
ExecutionEngine();
int run(std::unique_ptr<llvm::Module> module);
bytes returnData;
};
}

37
libevmjit/VM.cpp

@ -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

@ -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;
};
}
}
}

2
windows/LibEvmJit.vcxproj

@ -133,6 +133,7 @@
<ClCompile Include="..\libevmjit\Runtime.cpp" />
<ClCompile Include="..\libevmjit\Type.cpp" />
<ClCompile Include="..\libevmjit\Utils.cpp" />
<ClCompile Include="..\libevmjit\VM.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\libevmjit\BasicBlock.h" />
@ -145,6 +146,7 @@
<ClInclude Include="..\libevmjit\Runtime.h" />
<ClInclude Include="..\libevmjit\Type.h" />
<ClInclude Include="..\libevmjit\Utils.h" />
<ClInclude Include="..\libevmjit\VM.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

6
windows/LibEvmJit.vcxproj.filters

@ -36,6 +36,9 @@
<ClCompile Include="..\libevmjit\Utils.cpp">
<Filter>libevmjit</Filter>
</ClCompile>
<ClCompile Include="..\libevmjit\VM.cpp">
<Filter>libevmjit</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\libevmjit\BasicBlock.h">
@ -68,5 +71,8 @@
<ClInclude Include="..\libevmjit\Utils.h">
<Filter>libevmjit</Filter>
</ClInclude>
<ClInclude Include="..\libevmjit\VM.h">
<Filter>libevmjit</Filter>
</ClInclude>
</ItemGroup>
</Project>
Loading…
Cancel
Save