Browse Source

Merge branch 'develop-evmcc' of github.com:imapp-pl/ethereum into develop-evmcc

cl-refactor
artur-zawlocki 10 years ago
parent
commit
7115536c99
  1. 12
      evmcc/ExecutionEngine.cpp
  2. 44
      evmcc/Ext.cpp
  3. 31
      evmcc/Memory.cpp
  4. 2
      evmcc/Memory.h
  5. 36
      evmcc/Runtime.cpp
  6. 35
      evmcc/Runtime.h
  7. 71
      evmcc/Stack.cpp
  8. 2
      evmcc/Stack.h
  9. 2
      windows/evmcc.vcxproj
  10. 2
      windows/evmcc.vcxproj.filters

12
evmcc/ExecutionEngine.cpp

@ -13,8 +13,7 @@
#include <llvm/Support/PrettyStackTrace.h> #include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/Host.h> #include <llvm/Support/Host.h>
#include "Ext.h" #include "Runtime.h"
#include "Memory.h"
namespace evmcc namespace evmcc
{ {
@ -69,8 +68,7 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
_module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module _module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module
exec->finalizeObject(); exec->finalizeObject();
auto&& memory = Memory::init(); // Create fake ExtVM interface
auto ext = std::make_unique<dev::eth::ExtVMFace>(); auto ext = std::make_unique<dev::eth::ExtVMFace>();
ext->myAddress = dev::Address(1122334455667788); ext->myAddress = dev::Address(1122334455667788);
ext->caller = dev::Address(0xfacefacefaceface); ext->caller = dev::Address(0xfacefacefaceface);
@ -85,7 +83,9 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
ext->currentBlock.gasLimit = 1008; ext->currentBlock.gasLimit = 1008;
std::string calldata = "Hello the Beautiful World of Ethereum!"; std::string calldata = "Hello the Beautiful World of Ethereum!";
ext->data = calldata; ext->data = calldata;
Ext::init(std::move(ext));
// Init runtime
Runtime runtime(std::move(ext));
auto entryFunc = module->getFunction("main"); auto entryFunc = module->getFunction("main");
if (!entryFunc) if (!entryFunc)
@ -101,7 +101,7 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
auto size = 0xFFFFFFFF & intResult; auto size = 0xFFFFFFFF & intResult;
std::cout << "RETURN [ "; std::cout << "RETURN [ ";
for (dev::bytes::const_iterator it = memory.cbegin() + index, end = it + size; it != end; ++it) for (dev::bytes::const_iterator it = Runtime::getMemory().cbegin() + index, end = it + size; it != end; ++it)
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)*it << " "; std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)*it << " ";
std::cout << "]"; std::cout << "]";

44
evmcc/Ext.cpp

@ -5,7 +5,7 @@
#include <llvm/IR/TypeBuilder.h> #include <llvm/IR/TypeBuilder.h>
#include <llvm/IR/IntrinsicInst.h> #include <llvm/IR/IntrinsicInst.h>
#include "Utils.h" #include "Runtime.h"
#ifdef _MSC_VER #ifdef _MSC_VER
#define EXPORT __declspec(dllexport) #define EXPORT __declspec(dllexport)
@ -27,13 +27,6 @@ inline dev::u256 fromAddress(dev::Address _a)
return (dev::u160)_a; return (dev::u160)_a;
} }
std::unique_ptr<dev::eth::ExtVMFace> g_ext;
void Ext::init(std::unique_ptr<dev::eth::ExtVMFace> _ext)
{
g_ext = std::move(_ext);
}
struct ExtData struct ExtData
{ {
i256 address; i256 address;
@ -147,25 +140,26 @@ extern "C"
EXPORT void ext_init(ExtData* _extData) EXPORT void ext_init(ExtData* _extData)
{ {
_extData->address = eth2llvm(fromAddress(g_ext->myAddress)); auto&& ext = Runtime::getExt();
_extData->caller = eth2llvm(fromAddress(g_ext->caller)); _extData->address = eth2llvm(fromAddress(ext.myAddress));
_extData->origin = eth2llvm(fromAddress(g_ext->origin)); _extData->caller = eth2llvm(fromAddress(ext.caller));
_extData->callvalue = eth2llvm(g_ext->value); _extData->origin = eth2llvm(fromAddress(ext.origin));
_extData->gasprice = eth2llvm(g_ext->gasPrice); _extData->callvalue = eth2llvm(ext.value);
_extData->calldatasize = eth2llvm(g_ext->data.size()); _extData->gasprice = eth2llvm(ext.gasPrice);
_extData->prevhash = eth2llvm(g_ext->previousBlock.hash); _extData->calldatasize = eth2llvm(ext.data.size());
_extData->coinbase = eth2llvm(fromAddress(g_ext->currentBlock.coinbaseAddress)); _extData->prevhash = eth2llvm(ext.previousBlock.hash);
_extData->timestamp = eth2llvm(g_ext->currentBlock.timestamp); _extData->coinbase = eth2llvm(fromAddress(ext.currentBlock.coinbaseAddress));
_extData->number = eth2llvm(g_ext->currentBlock.number); _extData->timestamp = eth2llvm(ext.currentBlock.timestamp);
_extData->difficulty = eth2llvm(g_ext->currentBlock.difficulty); _extData->number = eth2llvm(ext.currentBlock.number);
_extData->gaslimit = eth2llvm(g_ext->currentBlock.gasLimit); _extData->difficulty = eth2llvm(ext.currentBlock.difficulty);
//_extData->calldata = g_ext->data.data(); _extData->gaslimit = eth2llvm(ext.currentBlock.gasLimit);
//_extData->calldata = ext.data.data();
} }
EXPORT void ext_store(i256* _index, i256* _value) EXPORT void ext_store(i256* _index, i256* _value)
{ {
auto index = llvm2eth(*_index); auto index = llvm2eth(*_index);
auto value = g_ext->store(index); auto value = Runtime::getExt().store(index);
*_value = eth2llvm(value); *_value = eth2llvm(value);
} }
@ -173,7 +167,7 @@ EXPORT void ext_setStore(i256* _index, i256* _value)
{ {
auto index = llvm2eth(*_index); auto index = llvm2eth(*_index);
auto value = llvm2eth(*_value); auto value = llvm2eth(*_value);
g_ext->setStore(index, value); Runtime::getExt().setStore(index, value);
} }
EXPORT void ext_calldataload(i256* _index, i256* _value) EXPORT void ext_calldataload(i256* _index, i256* _value)
@ -182,13 +176,13 @@ EXPORT void ext_calldataload(i256* _index, i256* _value)
assert(index + 31 > index); // TODO: Handle large index assert(index + 31 > index); // TODO: Handle large index
auto b = reinterpret_cast<byte*>(_value); auto b = reinterpret_cast<byte*>(_value);
for (size_t i = index, j = 31; i <= index + 31; ++i, --j) for (size_t i = index, j = 31; i <= index + 31; ++i, --j)
b[j] = i < g_ext->data.size() ? g_ext->data[i] : 0; b[j] = i < Runtime::getExt().data.size() ? Runtime::getExt().data[i] : 0;
// TODO: It all can be done by adding padding to data or by using min() algorithm without branch // TODO: It all can be done by adding padding to data or by using min() algorithm without branch
} }
EXPORT void ext_balance(h256* _address, i256* _value) EXPORT void ext_balance(h256* _address, i256* _value)
{ {
auto u = g_ext->balance(dev::right160(*_address)); auto u = Runtime::getExt().balance(dev::right160(*_address));
*_value = eth2llvm(u); *_value = eth2llvm(u);
} }

31
evmcc/Memory.cpp

@ -10,7 +10,7 @@
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include "Utils.h" #include "Runtime.h"
#ifdef _MSC_VER #ifdef _MSC_VER
#define EXPORT __declspec(dllexport) #define EXPORT __declspec(dllexport)
@ -21,11 +21,6 @@
namespace evmcc namespace evmcc
{ {
using MemoryImpl = dev::bytes;
static MemoryImpl* evmccrt_memory;
Memory::Memory(llvm::IRBuilder<>& _builder, llvm::Module* module) Memory::Memory(llvm::IRBuilder<>& _builder, llvm::Module* module)
: m_builder(_builder) : m_builder(_builder)
{ {
@ -48,15 +43,6 @@ Memory::Memory(llvm::IRBuilder<>& _builder, llvm::Module* module)
"evmccrt_memory_dump", module); "evmccrt_memory_dump", module);
} }
const dev::bytes& Memory::init()
{
evmccrt_memory = new MemoryImpl();
std::cerr << "MEMORY: create(), initial size = " << evmccrt_memory->size()
<< std::endl;
return *evmccrt_memory;
}
llvm::Value* Memory::loadWord(llvm::Value* _addr) llvm::Value* Memory::loadWord(llvm::Value* _addr)
{ {
@ -132,29 +118,30 @@ extern "C"
EXPORT uint8_t* evmccrt_memory_require(uint64_t _index) EXPORT uint8_t* evmccrt_memory_require(uint64_t _index)
{ {
uint64_t requiredSize = (_index / 32 + 1) * 32; uint64_t requiredSize = (_index / 32 + 1) * 32;
auto&& memory = Runtime::getMemory();
if (evmccrt_memory->size() < requiredSize) if (memory.size() < requiredSize)
{ {
std::cerr << "MEMORY: current size: " << std::dec std::cerr << "MEMORY: current size: " << std::dec
<< evmccrt_memory->size() << " bytes, required size: " << memory.size() << " bytes, required size: "
<< requiredSize << " bytes" << requiredSize << " bytes"
<< std::endl; << std::endl;
evmccrt_memory->resize(requiredSize); memory.resize(requiredSize);
} }
return evmccrt_memory->data(); return memory.data();
} }
EXPORT uint64_t evmccrt_memory_size() EXPORT uint64_t evmccrt_memory_size()
{ {
return evmccrt_memory->size() / 32; return Runtime::getMemory().size() / 32;
} }
EXPORT void evmccrt_memory_dump(uint64_t _begin, uint64_t _end) EXPORT void evmccrt_memory_dump(uint64_t _begin, uint64_t _end)
{ {
if (_end == 0) if (_end == 0)
_end = evmccrt_memory->size(); _end = Runtime::getMemory().size();
std::cerr << "MEMORY: active size: " << std::dec std::cerr << "MEMORY: active size: " << std::dec
<< evmccrt_memory_size() << " words\n"; << evmccrt_memory_size() << " words\n";
@ -169,7 +156,7 @@ EXPORT void evmccrt_memory_dump(uint64_t _begin, uint64_t _end)
if ((i - _begin) % 16 == 0) if ((i - _begin) % 16 == 0)
std::cerr << '\n' << std::dec << i << ": "; std::cerr << '\n' << std::dec << i << ": ";
uint8_t b = (*evmccrt_memory)[i]; auto b = Runtime::getMemory()[i];
std::cerr << std::hex << std::setw(2) << static_cast<int>(b) << ' '; std::cerr << std::hex << std::setw(2) << static_cast<int>(b) << ' ';
} }
std::cerr << std::endl; std::cerr << std::endl;

2
evmcc/Memory.h

@ -12,8 +12,6 @@ class Memory
public: public:
Memory(llvm::IRBuilder<>& _builder, llvm::Module* module); Memory(llvm::IRBuilder<>& _builder, llvm::Module* module);
static const dev::bytes& init();
llvm::Value* loadWord(llvm::Value* _addr); llvm::Value* loadWord(llvm::Value* _addr);
void storeWord(llvm::Value* _addr, llvm::Value* _word); void storeWord(llvm::Value* _addr, llvm::Value* _word);
void storeByte(llvm::Value* _addr, llvm::Value* _byte); void storeByte(llvm::Value* _addr, llvm::Value* _byte);

36
evmcc/Runtime.cpp

@ -0,0 +1,36 @@
#include "Runtime.h"
namespace evmcc
{
static Runtime* g_runtime;
Runtime::Runtime(std::unique_ptr<dev::eth::ExtVMFace> _ext)
: m_ext(std::move(_ext))
{
assert(!g_runtime);
g_runtime = this;
}
Runtime::~Runtime()
{
g_runtime = nullptr;
}
StackImpl& Runtime::getStack()
{
return g_runtime->m_stack;
}
MemoryImpl& Runtime::getMemory()
{
return g_runtime->m_memory;
}
dev::eth::ExtVMFace& Runtime::getExt()
{
return *g_runtime->m_ext;
}
}

35
evmcc/Runtime.h

@ -0,0 +1,35 @@
#pragma once
#include <vector>
#include <libevm/ExtVMFace.h>
#include "Utils.h"
namespace evmcc
{
using StackImpl = std::vector<i256>;
using MemoryImpl = dev::bytes;
class Runtime
{
public:
Runtime(std::unique_ptr<dev::eth::ExtVMFace> _ext);
~Runtime();
Runtime(const Runtime&) = delete;
void operator=(const Runtime&) = delete;
static StackImpl& getStack();
static MemoryImpl& getMemory();
static dev::eth::ExtVMFace& getExt();
private:
StackImpl m_stack;
MemoryImpl m_memory;
std::unique_ptr<dev::eth::ExtVMFace> m_ext;
};
}

71
evmcc/Stack.cpp

@ -9,7 +9,7 @@
#include <llvm/IR/Function.h> #include <llvm/IR/Function.h>
#include "Utils.h" #include "Runtime.h"
#ifdef _MSC_VER #ifdef _MSC_VER
#define EXPORT __declspec(dllexport) #define EXPORT __declspec(dllexport)
@ -20,9 +20,6 @@
namespace evmcc namespace evmcc
{ {
using StackImpl = std::vector<i256>;
Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module) Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module)
: m_builder(_builder) : m_builder(_builder)
{ {
@ -32,18 +29,14 @@ Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module)
auto i256PtrTy = i256Ty->getPointerTo(); auto i256PtrTy = i256Ty->getPointerTo();
auto voidTy = m_builder.getVoidTy(); auto voidTy = m_builder.getVoidTy();
auto stackCreate = llvm::Function::Create(llvm::FunctionType::get(stackPtrTy, false), auto funcType = llvm::FunctionType::get(voidTy, i256PtrTy, false);
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_create", _module);
llvm::Type* argsTypes[] = {stackPtrTy, i256PtrTy};
auto funcType = llvm::FunctionType::get(voidTy, argsTypes, false);
m_stackPush = llvm::Function::Create(funcType, m_stackPush = llvm::Function::Create(funcType,
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_push", _module); llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_push", _module);
m_stackPop = llvm::Function::Create(funcType, m_stackPop = llvm::Function::Create(funcType,
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_pop", _module); llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_pop", _module);
llvm::Type* getArgsTypes[] = {stackPtrTy, m_builder.getInt32Ty(), i256PtrTy}; llvm::Type* getArgsTypes[] = {m_builder.getInt32Ty(), i256PtrTy};
auto getFuncType = llvm::FunctionType::get(voidTy, getArgsTypes, false); auto getFuncType = llvm::FunctionType::get(voidTy, getArgsTypes, false);
m_stackGet = llvm::Function::Create(getFuncType, m_stackGet = llvm::Function::Create(getFuncType,
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_get", _module); llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_get", _module);
@ -51,37 +44,36 @@ Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module)
m_stackSet = llvm::Function::Create(getFuncType, m_stackSet = llvm::Function::Create(getFuncType,
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_set", _module); llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_set", _module);
m_args[0] = m_builder.CreateCall(stackCreate, "stack.ptr"); m_stackVal = m_builder.CreateAlloca(i256Ty, nullptr, "stack.val");
m_args[1] = m_builder.CreateAlloca(i256Ty, nullptr, "stack.val");
} }
void Stack::push(llvm::Value* _value) void Stack::push(llvm::Value* _value)
{ {
m_builder.CreateStore(_value, m_args[1]); // copy value to memory m_builder.CreateStore(_value, m_stackVal); // copy value to memory
m_builder.CreateCall(m_stackPush, m_args); m_builder.CreateCall(m_stackPush, m_stackVal);
} }
llvm::Value* Stack::pop() llvm::Value* Stack::pop()
{ {
m_builder.CreateCall(m_stackPop, m_args); m_builder.CreateCall(m_stackPop, m_stackVal);
return m_builder.CreateLoad(m_args[1]); return m_builder.CreateLoad(m_stackVal);
} }
llvm::Value* Stack::get(uint32_t _index) llvm::Value* Stack::get(uint32_t _index)
{ {
llvm::Value* args[] = {m_args[0], m_builder.getInt32(_index), m_args[1]}; llvm::Value* args[] = {m_builder.getInt32(_index), m_stackVal};
m_builder.CreateCall(m_stackGet, args); m_builder.CreateCall(m_stackGet, args);
return m_builder.CreateLoad(m_args[1]); return m_builder.CreateLoad(m_stackVal);
} }
void Stack::set(uint32_t _index, llvm::Value* _value) void Stack::set(uint32_t _index, llvm::Value* _value)
{ {
m_builder.CreateStore(_value, m_args[1]); // copy value to memory m_builder.CreateStore(_value, m_stackVal); // copy value to memory
llvm::Value* args[] = {m_args[0], m_builder.getInt32(_index), m_args[1]}; llvm::Value* args[] = {m_builder.getInt32(_index), m_stackVal};
m_builder.CreateCall(m_stackSet, args); m_builder.CreateCall(m_stackSet, args);
} }
@ -113,41 +105,34 @@ extern "C"
{ {
using namespace evmcc; using namespace evmcc;
EXPORT void* evmccrt_stack_create() EXPORT void evmccrt_stack_push(i256* _word)
{
auto stack = new StackImpl;
std::cerr << "STACK create\n";
return stack;
}
EXPORT void evmccrt_stack_push(StackImpl* _stack, i256* _word)
{ {
debugStack("push", *_word); //debugStack("push", *_word);
_stack->push_back(*_word); Runtime::getStack().push_back(*_word);
} }
EXPORT void evmccrt_stack_pop(StackImpl* _stack, i256* _outWord) EXPORT void evmccrt_stack_pop(i256* _outWord)
{ {
assert(!_stack->empty()); assert(!Runtime::getStack().empty());
auto word = &_stack->back(); auto word = &Runtime::getStack().back();
debugStack("pop", *word); //debugStack("pop", *word);
_stack->pop_back(); Runtime::getStack().pop_back();
*_outWord = *word; *_outWord = *word;
} }
EXPORT void evmccrt_stack_get(StackImpl* _stack, uint32_t _index, i256* _outWord) EXPORT void evmccrt_stack_get(uint32_t _index, i256* _outWord)
{ {
assert(_index < _stack->size()); assert(_index < Runtime::getStack().size());
auto word = _stack->rbegin() + _index; auto word = Runtime::getStack().rbegin() + _index;
debugStack("get", *word, _index); //debugStack("get", *word, _index);
*_outWord = *word; *_outWord = *word;
} }
EXPORT void evmccrt_stack_set(StackImpl* _stack, uint32_t _index, i256* _word) EXPORT void evmccrt_stack_set(uint32_t _index, i256* _word)
{ {
assert(_index < _stack->size()); assert(_index < Runtime::getStack().size());
*(_stack->rbegin() + _index) = *_word; *(Runtime::getStack().rbegin() + _index) = *_word;
debugStack("set", *_word, _index); //debugStack("set", *_word, _index);
} }
} // extern "C" } // extern "C"

2
evmcc/Stack.h

@ -19,7 +19,7 @@ public:
private: private:
llvm::IRBuilder<>& m_builder; llvm::IRBuilder<>& m_builder;
llvm::Value* m_args[2]; llvm::Value* m_stackVal;
llvm::Function* m_stackPush; llvm::Function* m_stackPush;
llvm::Function* m_stackPop; llvm::Function* m_stackPop;
llvm::Function* m_stackGet; llvm::Function* m_stackGet;

2
windows/evmcc.vcxproj

@ -24,6 +24,7 @@
<ClCompile Include="..\evmcc\ExecutionEngine.cpp" /> <ClCompile Include="..\evmcc\ExecutionEngine.cpp" />
<ClCompile Include="..\evmcc\Ext.cpp" /> <ClCompile Include="..\evmcc\Ext.cpp" />
<ClCompile Include="..\evmcc\Memory.cpp" /> <ClCompile Include="..\evmcc\Memory.cpp" />
<ClCompile Include="..\evmcc\Runtime.cpp" />
<ClCompile Include="..\evmcc\Stack.cpp" /> <ClCompile Include="..\evmcc\Stack.cpp" />
<ClCompile Include="..\evmcc\Utils.cpp" /> <ClCompile Include="..\evmcc\Utils.cpp" />
</ItemGroup> </ItemGroup>
@ -32,6 +33,7 @@
<ClInclude Include="..\evmcc\ExecutionEngine.h" /> <ClInclude Include="..\evmcc\ExecutionEngine.h" />
<ClInclude Include="..\evmcc\Ext.h" /> <ClInclude Include="..\evmcc\Ext.h" />
<ClInclude Include="..\evmcc\Memory.h" /> <ClInclude Include="..\evmcc\Memory.h" />
<ClInclude Include="..\evmcc\Runtime.h" />
<ClInclude Include="..\evmcc\Stack.h" /> <ClInclude Include="..\evmcc\Stack.h" />
<ClInclude Include="..\evmcc\Utils.h" /> <ClInclude Include="..\evmcc\Utils.h" />
</ItemGroup> </ItemGroup>

2
windows/evmcc.vcxproj.filters

@ -8,6 +8,7 @@
<ClCompile Include="..\evmcc\Ext.cpp" /> <ClCompile Include="..\evmcc\Ext.cpp" />
<ClCompile Include="..\evmcc\Memory.cpp" /> <ClCompile Include="..\evmcc\Memory.cpp" />
<ClCompile Include="..\evmcc\Utils.cpp" /> <ClCompile Include="..\evmcc\Utils.cpp" />
<ClCompile Include="..\evmcc\Runtime.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="..\evmcc\Compiler.h" /> <ClInclude Include="..\evmcc\Compiler.h" />
@ -16,5 +17,6 @@
<ClInclude Include="..\evmcc\Ext.h" /> <ClInclude Include="..\evmcc\Ext.h" />
<ClInclude Include="..\evmcc\Memory.h" /> <ClInclude Include="..\evmcc\Memory.h" />
<ClInclude Include="..\evmcc\Utils.h" /> <ClInclude Include="..\evmcc\Utils.h" />
<ClInclude Include="..\evmcc\Runtime.h" />
</ItemGroup> </ItemGroup>
</Project> </Project>
Loading…
Cancel
Save