diff --git a/evmcc/evmcc.cpp b/evmcc/evmcc.cpp index 8a7ac5384..600980d44 100644 --- a/evmcc/evmcc.cpp +++ b/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; diff --git a/libevmjit/Compiler.cpp b/libevmjit/Compiler.cpp index 035abf287..cbb6118f4 100644 --- a/libevmjit/Compiler.cpp +++ b/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 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 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(*curr); @@ -51,7 +51,7 @@ void Compiler::createBasicBlocks(const bytes& bytecode) { auto numBytes = static_cast(inst) - static_cast(Instruction::PUSH1) + 1; auto next = curr + numBytes + 1; - if (next >= bytecode.cend()) + if (next >= bytecode.end()) break; auto nextInst = static_cast(*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 Compiler::compile(const bytes& bytecode) +std::unique_ptr Compiler::compile(bytesConstRef bytecode) { auto module = std::make_unique("main", m_builder.getContext()); @@ -214,7 +214,7 @@ std::unique_ptr 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()); diff --git a/libevmjit/Compiler.h b/libevmjit/Compiler.h index bda154689..f708898d6 100644 --- a/libevmjit/Compiler.h +++ b/libevmjit/Compiler.h @@ -22,16 +22,16 @@ public: Compiler(); - std::unique_ptr compile(const bytes& bytecode); + std::unique_ptr 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(); diff --git a/libevmjit/ExecutionEngine.cpp b/libevmjit/ExecutionEngine.cpp index 6a494f42a..bac15a478 100644 --- a/libevmjit/ExecutionEngine.cpp +++ b/libevmjit/ExecutionEngine.cpp @@ -125,7 +125,7 @@ int ExecutionEngine::run(std::unique_ptr _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) diff --git a/libevmjit/ExecutionEngine.h b/libevmjit/ExecutionEngine.h index 158df0283..f6fb49276 100644 --- a/libevmjit/ExecutionEngine.h +++ b/libevmjit/ExecutionEngine.h @@ -18,6 +18,8 @@ public: ExecutionEngine(); int run(std::unique_ptr module); + + bytes returnData; }; } diff --git a/libevmjit/VM.cpp b/libevmjit/VM.cpp new file mode 100644 index 000000000..51cd7c5a3 --- /dev/null +++ b/libevmjit/VM.cpp @@ -0,0 +1,37 @@ + +#include "VM.h" + +#include + +#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); +} + +} +} +} diff --git a/libevmjit/VM.h b/libevmjit/VM.h new file mode 100644 index 000000000..3e7884b10 --- /dev/null +++ b/libevmjit/VM.h @@ -0,0 +1,32 @@ + +#pragma once + +#include +#include + +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; +}; + +} +} +} diff --git a/windows/LibEvmJit.vcxproj b/windows/LibEvmJit.vcxproj index 17832d871..1c71bb082 100644 --- a/windows/LibEvmJit.vcxproj +++ b/windows/LibEvmJit.vcxproj @@ -133,6 +133,7 @@ + @@ -145,6 +146,7 @@ + diff --git a/windows/LibEvmJit.vcxproj.filters b/windows/LibEvmJit.vcxproj.filters index e24e4379e..a2008f971 100644 --- a/windows/LibEvmJit.vcxproj.filters +++ b/windows/LibEvmJit.vcxproj.filters @@ -36,6 +36,9 @@ libevmjit + + libevmjit + @@ -68,5 +71,8 @@ libevmjit + + libevmjit + \ No newline at end of file