Browse Source

Runtime class that inits and keeps stack, memory and ExtVM interface

cl-refactor
Paweł Bylica 10 years ago
parent
commit
24a99ef798
  1. 6
      evmcc/Compiler.cpp
  2. 12
      evmcc/ExecutionEngine.cpp
  3. 44
      evmcc/Ext.cpp
  4. 31
      evmcc/Memory.cpp
  5. 2
      evmcc/Memory.h
  6. 36
      evmcc/Runtime.cpp
  7. 35
      evmcc/Runtime.h
  8. 14
      evmcc/Stack.cpp
  9. 2
      windows/evmcc.vcxproj
  10. 2
      windows/evmcc.vcxproj.filters

6
evmcc/Compiler.cpp

@ -351,9 +351,9 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
/*
if (byteNum < 32) - use select
{
value <<= byteNum*8
value >>= 31*8
push value
value <<= byteNum*8
value >>= 31*8
push value
}
else push 0
*/

12
evmcc/ExecutionEngine.cpp

@ -13,8 +13,7 @@
#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/Host.h>
#include "Ext.h"
#include "Memory.h"
#include "Runtime.h"
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
exec->finalizeObject();
auto&& memory = Memory::init();
// Create fake ExtVM interface
auto ext = std::make_unique<dev::eth::ExtVMFace>();
ext->myAddress = dev::Address(1122334455667788);
ext->caller = dev::Address(0xfacefacefaceface);
@ -85,7 +83,9 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
ext->currentBlock.gasLimit = 1008;
std::string calldata = "Hello the Beautiful World of Ethereum!";
ext->data = calldata;
Ext::init(std::move(ext));
// Init runtime
Runtime runtime(std::move(ext));
auto entryFunc = module->getFunction("main");
if (!entryFunc)
@ -101,7 +101,7 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
auto size = 0xFFFFFFFF & intResult;
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 << "]";

44
evmcc/Ext.cpp

@ -5,7 +5,7 @@
#include <llvm/IR/TypeBuilder.h>
#include <llvm/IR/IntrinsicInst.h>
#include "Utils.h"
#include "Runtime.h"
#ifdef _MSC_VER
#define EXPORT __declspec(dllexport)
@ -27,13 +27,6 @@ inline dev::u256 fromAddress(dev::Address _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
{
i256 address;
@ -147,25 +140,26 @@ extern "C"
EXPORT void ext_init(ExtData* _extData)
{
_extData->address = eth2llvm(fromAddress(g_ext->myAddress));
_extData->caller = eth2llvm(fromAddress(g_ext->caller));
_extData->origin = eth2llvm(fromAddress(g_ext->origin));
_extData->callvalue = eth2llvm(g_ext->value);
_extData->gasprice = eth2llvm(g_ext->gasPrice);
_extData->calldatasize = eth2llvm(g_ext->data.size());
_extData->prevhash = eth2llvm(g_ext->previousBlock.hash);
_extData->coinbase = eth2llvm(fromAddress(g_ext->currentBlock.coinbaseAddress));
_extData->timestamp = eth2llvm(g_ext->currentBlock.timestamp);
_extData->number = eth2llvm(g_ext->currentBlock.number);
_extData->difficulty = eth2llvm(g_ext->currentBlock.difficulty);
_extData->gaslimit = eth2llvm(g_ext->currentBlock.gasLimit);
//_extData->calldata = g_ext->data.data();
auto&& ext = Runtime::getExt();
_extData->address = eth2llvm(fromAddress(ext.myAddress));
_extData->caller = eth2llvm(fromAddress(ext.caller));
_extData->origin = eth2llvm(fromAddress(ext.origin));
_extData->callvalue = eth2llvm(ext.value);
_extData->gasprice = eth2llvm(ext.gasPrice);
_extData->calldatasize = eth2llvm(ext.data.size());
_extData->prevhash = eth2llvm(ext.previousBlock.hash);
_extData->coinbase = eth2llvm(fromAddress(ext.currentBlock.coinbaseAddress));
_extData->timestamp = eth2llvm(ext.currentBlock.timestamp);
_extData->number = eth2llvm(ext.currentBlock.number);
_extData->difficulty = eth2llvm(ext.currentBlock.difficulty);
_extData->gaslimit = eth2llvm(ext.currentBlock.gasLimit);
//_extData->calldata = ext.data.data();
}
EXPORT void ext_store(i256* _index, i256* _value)
{
auto index = llvm2eth(*_index);
auto value = g_ext->store(index);
auto value = Runtime::getExt().store(index);
*_value = eth2llvm(value);
}
@ -173,7 +167,7 @@ EXPORT void ext_setStore(i256* _index, i256* _value)
{
auto index = llvm2eth(*_index);
auto value = llvm2eth(*_value);
g_ext->setStore(index, value);
Runtime::getExt().setStore(index, 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
auto b = reinterpret_cast<byte*>(_value);
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
}
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);
}

31
evmcc/Memory.cpp

@ -10,7 +10,7 @@
#include <libdevcore/Common.h>
#include "Utils.h"
#include "Runtime.h"
#ifdef _MSC_VER
#define EXPORT __declspec(dllexport)
@ -21,11 +21,6 @@
namespace evmcc
{
using MemoryImpl = dev::bytes;
static MemoryImpl* evmccrt_memory;
Memory::Memory(llvm::IRBuilder<>& _builder, llvm::Module* module)
: m_builder(_builder)
{
@ -48,15 +43,6 @@ Memory::Memory(llvm::IRBuilder<>& _builder, llvm::Module* 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)
{
@ -132,29 +118,30 @@ extern "C"
EXPORT uint8_t* evmccrt_memory_require(uint64_t _index)
{
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
<< evmccrt_memory->size() << " bytes, required size: "
<< memory.size() << " bytes, required size: "
<< requiredSize << " bytes"
<< std::endl;
evmccrt_memory->resize(requiredSize);
memory.resize(requiredSize);
}
return evmccrt_memory->data();
return memory.data();
}
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)
{
if (_end == 0)
_end = evmccrt_memory->size();
_end = Runtime::getMemory().size();
std::cerr << "MEMORY: active size: " << std::dec
<< 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)
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::endl;

2
evmcc/Memory.h

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

14
evmcc/Stack.cpp

@ -9,7 +9,7 @@
#include <llvm/IR/Function.h>
#include "Utils.h"
#include "Runtime.h"
#ifdef _MSC_VER
#define EXPORT __declspec(dllexport)
@ -20,9 +20,6 @@
namespace evmcc
{
using StackImpl = std::vector<i256>;
Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module)
: m_builder(_builder)
{
@ -115,7 +112,8 @@ extern "C"
EXPORT void* evmccrt_stack_create()
{
auto stack = new StackImpl;
// TODO: Simplify stack pointer passing
auto stack = &Runtime::getStack();
std::cerr << "STACK create\n";
return stack;
}
@ -130,7 +128,7 @@ EXPORT void evmccrt_stack_pop(StackImpl* _stack, i256* _outWord)
{
assert(!_stack->empty());
auto word = &_stack->back();
debugStack("pop", *word);
//debugStack("pop", *word);
_stack->pop_back();
*_outWord = *word;
}
@ -139,7 +137,7 @@ EXPORT void evmccrt_stack_get(StackImpl* _stack, uint32_t _index, i256* _outWord
{
assert(_index < _stack->size());
auto word = _stack->rbegin() + _index;
debugStack("get", *word, _index);
//debugStack("get", *word, _index);
*_outWord = *word;
}
@ -147,7 +145,7 @@ EXPORT void evmccrt_stack_set(StackImpl* _stack, uint32_t _index, i256* _word)
{
assert(_index < _stack->size());
*(_stack->rbegin() + _index) = *_word;
debugStack("set", *_word, _index);
//debugStack("set", *_word, _index);
}
} // extern "C"

2
windows/evmcc.vcxproj

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

2
windows/evmcc.vcxproj.filters

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