Browse Source

Access memory structure through runtime structure [#81470252]

cl-refactor
Paweł Bylica 10 years ago
parent
commit
c388a81cff
  1. 2
      libevmjit/Compiler.cpp
  2. 2
      libevmjit/ExecutionEngine.cpp
  3. 9
      libevmjit/Ext.cpp
  4. 68
      libevmjit/Memory.cpp
  5. 7
      libevmjit/Memory.h
  6. 34
      libevmjit/Runtime.cpp
  7. 5
      libevmjit/Runtime.h

2
libevmjit/Compiler.cpp

@ -179,7 +179,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(bytesConstRef bytecode)
// Init runtime structures. // Init runtime structures.
RuntimeManager runtimeManager(m_builder); RuntimeManager runtimeManager(m_builder);
GasMeter gasMeter(m_builder, runtimeManager); GasMeter gasMeter(m_builder, runtimeManager);
Memory memory(m_builder, gasMeter); Memory memory(m_builder, gasMeter, runtimeManager);
Ext ext(m_builder); Ext ext(m_builder);
Stack stack(m_builder); Stack stack(m_builder);

2
libevmjit/ExecutionEngine.cpp

@ -121,7 +121,7 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, u256& _gas, ExtV
if (returnCode == ReturnCode::Return) if (returnCode == ReturnCode::Return)
{ {
returnData = Memory::getReturnData().toVector(); // TODO: It might be better to place is in Runtime interface returnData = runtime.getReturnData().toVector(); // TODO: It might be better to place is in Runtime interface
std::cout << "RETURN [ "; std::cout << "RETURN [ ";
for (auto it = returnData.begin(), end = returnData.end(); it != end; ++it) for (auto it = returnData.begin(), end = returnData.end(); it != end; ++it)

9
libevmjit/Ext.cpp

@ -306,7 +306,8 @@ EXPORT void ext_create(i256* _endowment, i256* _initOff, i256* _initSize, h256*
u256 gas; // TODO: Handle gas u256 gas; // TODO: Handle gas
auto initOff = static_cast<size_t>(llvm2eth(*_initOff)); auto initOff = static_cast<size_t>(llvm2eth(*_initOff));
auto initSize = static_cast<size_t>(llvm2eth(*_initSize)); auto initSize = static_cast<size_t>(llvm2eth(*_initSize));
auto&& initRef = bytesConstRef(Runtime::getMemory().data() + initOff, initSize); //auto&& initRef = bytesConstRef(Runtime::getMemory().data() + initOff, initSize);
bytesConstRef initRef;
OnOpFunc onOp{}; // TODO: Handle that thing OnOpFunc onOp{}; // TODO: Handle that thing
h256 address = ext.create(endowment, &gas, initRef, onOp); h256 address = ext.create(endowment, &gas, initRef, onOp);
*_address = address; *_address = address;
@ -332,8 +333,8 @@ EXPORT void ext_call(i256* _gas, h256* _receiveAddress, i256* _value, i256* _inO
auto inSize = static_cast<size_t>(llvm2eth(*_inSize)); auto inSize = static_cast<size_t>(llvm2eth(*_inSize));
auto outOff = static_cast<size_t>(llvm2eth(*_outOff)); auto outOff = static_cast<size_t>(llvm2eth(*_outOff));
auto outSize = static_cast<size_t>(llvm2eth(*_outSize)); auto outSize = static_cast<size_t>(llvm2eth(*_outSize));
auto&& inRef = bytesConstRef(Runtime::getMemory().data() + inOff, inSize); auto&& inRef = bytesConstRef(); //Runtime::getMemory().data() + inOff, inSize);
auto&& outRef = bytesConstRef(Runtime::getMemory().data() + outOff, outSize); auto&& outRef = bytesConstRef(); // Runtime::getMemory().data() + outOff, outSize);
OnOpFunc onOp{}; // TODO: Handle that thing OnOpFunc onOp{}; // TODO: Handle that thing
auto codeAddress = right160(*_codeAddress); auto codeAddress = right160(*_codeAddress);
ret = ext.call(receiveAddress, value, inRef, &gas, outRef, onOp, {}, codeAddress); ret = ext.call(receiveAddress, value, inRef, &gas, outRef, onOp, {}, codeAddress);
@ -347,7 +348,7 @@ EXPORT void ext_sha3(i256* _inOff, i256* _inSize, i256* _ret)
{ {
auto inOff = static_cast<size_t>(llvm2eth(*_inOff)); auto inOff = static_cast<size_t>(llvm2eth(*_inOff));
auto inSize = static_cast<size_t>(llvm2eth(*_inSize)); auto inSize = static_cast<size_t>(llvm2eth(*_inSize));
auto dataRef = bytesConstRef(Runtime::getMemory().data() + inOff, inSize); auto dataRef = bytesConstRef(); // Runtime::getMemory().data() + inOff, inSize);
auto hash = sha3(dataRef); auto hash = sha3(dataRef);
*_ret = *reinterpret_cast<i256*>(&hash); *_ret = *reinterpret_cast<i256*>(&hash);
} }

68
libevmjit/Memory.cpp

@ -15,6 +15,7 @@
#include "Runtime.h" #include "Runtime.h"
#include "GasMeter.h" #include "GasMeter.h"
#include "Endianness.h" #include "Endianness.h"
#include "Runtime.h"
namespace dev namespace dev
{ {
@ -23,7 +24,7 @@ namespace eth
namespace jit namespace jit
{ {
Memory::Memory(llvm::IRBuilder<>& _builder, GasMeter& _gasMeter): Memory::Memory(llvm::IRBuilder<>& _builder, GasMeter& _gasMeter, RuntimeManager& _runtimeManager):
CompilerHelper(_builder) CompilerHelper(_builder)
{ {
auto module = getModule(); auto module = getModule();
@ -45,18 +46,19 @@ Memory::Memory(llvm::IRBuilder<>& _builder, GasMeter& _gasMeter):
m_returnDataSize = new llvm::GlobalVariable(*module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "mem_returnDataSize"); m_returnDataSize = new llvm::GlobalVariable(*module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "mem_returnDataSize");
m_returnDataSize->setUnnamedAddr(true); // Address is not important m_returnDataSize->setUnnamedAddr(true); // Address is not important
m_resize = llvm::Function::Create(llvm::FunctionType::get(Type::BytePtr, Type::WordPtr, false), llvm::Function::ExternalLinkage, "mem_resize", module); llvm::Type* resizeArgs[] = {RuntimeData::getType()->getPointerTo(), Type::WordPtr};
m_resize = llvm::Function::Create(llvm::FunctionType::get(Type::BytePtr, resizeArgs, false), llvm::Function::ExternalLinkage, "mem_resize", module);
llvm::AttrBuilder attrBuilder; llvm::AttrBuilder attrBuilder;
attrBuilder.addAttribute(llvm::Attribute::NoAlias).addAttribute(llvm::Attribute::NoCapture).addAttribute(llvm::Attribute::NonNull).addAttribute(llvm::Attribute::ReadOnly); attrBuilder.addAttribute(llvm::Attribute::NoAlias).addAttribute(llvm::Attribute::NoCapture).addAttribute(llvm::Attribute::NonNull).addAttribute(llvm::Attribute::ReadOnly);
m_resize->setAttributes(llvm::AttributeSet::get(m_resize->getContext(), 1, attrBuilder)); m_resize->setAttributes(llvm::AttributeSet::get(m_resize->getContext(), 1, attrBuilder));
m_require = createRequireFunc(_gasMeter); m_require = createRequireFunc(_gasMeter, _runtimeManager);
m_loadWord = createFunc(false, Type::i256, _gasMeter); m_loadWord = createFunc(false, Type::i256, _gasMeter);
m_storeWord = createFunc(true, Type::i256, _gasMeter); m_storeWord = createFunc(true, Type::i256, _gasMeter);
m_storeByte = createFunc(true, Type::Byte, _gasMeter); m_storeByte = createFunc(true, Type::Byte, _gasMeter);
} }
llvm::Function* Memory::createRequireFunc(GasMeter& _gasMeter) llvm::Function* Memory::createRequireFunc(GasMeter& _gasMeter, RuntimeManager& _runtimeManager)
{ {
auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "mem.require", getModule()); auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::i256, false), llvm::Function::PrivateLinkage, "mem.require", getModule());
@ -83,7 +85,7 @@ llvm::Function* Memory::createRequireFunc(GasMeter& _gasMeter)
_gasMeter.checkMemory(newWords, m_builder); _gasMeter.checkMemory(newWords, m_builder);
// Resize // Resize
m_builder.CreateStore(sizeRequired, m_size); m_builder.CreateStore(sizeRequired, m_size);
auto newData = m_builder.CreateCall(m_resize, m_size, "newData"); auto newData = m_builder.CreateCall2(m_resize, _runtimeManager.getRuntimePtr(), m_size, "newData");
m_builder.CreateStore(newData, m_data); m_builder.CreateStore(newData, m_data);
m_builder.CreateBr(returnBB); m_builder.CreateBr(returnBB);
@ -232,48 +234,36 @@ extern "C"
using namespace dev::eth::jit; using namespace dev::eth::jit;
EXPORT i256 mem_returnDataOffset; EXPORT uint8_t* mem_resize(Runtime* _rt, i256* _size)
EXPORT i256 mem_returnDataSize;
EXPORT uint8_t* mem_resize(i256* _size)
{ {
auto size = _size->a; // Trunc to 64-bit auto size = _size->a; // Trunc to 64-bit
auto& memory = Runtime::getMemory(); auto& memory = _rt->getMemory();
memory.resize(size); memory.resize(size);
return memory.data(); return memory.data();
} }
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 = Runtime::getMemory().size(); // _end = Runtime::getMemory().size();
std::cerr << "MEMORY: active size: " << std::dec //std::cerr << "MEMORY: active size: " << std::dec
<< Runtime::getMemory().size() / 32 << " words\n"; // << Runtime::getMemory().size() / 32 << " words\n";
std::cerr << "MEMORY: dump from " << std::dec //std::cerr << "MEMORY: dump from " << std::dec
<< _begin << " to " << _end << ":"; // << _begin << " to " << _end << ":";
if (_end <= _begin) //if (_end <= _begin)
return; // return;
_begin = _begin / 16 * 16; //_begin = _begin / 16 * 16;
for (size_t i = _begin; i < _end; i++) //for (size_t i = _begin; i < _end; i++)
{ //{
if ((i - _begin) % 16 == 0) // if ((i - _begin) % 16 == 0)
std::cerr << '\n' << std::dec << i << ": "; // std::cerr << '\n' << std::dec << i << ": ";
auto b = Runtime::getMemory()[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;
} }
} // extern "C" } // extern "C"
dev::bytesConstRef dev::eth::jit::Memory::getReturnData()
{
// TODO: Handle large indexes
auto offset = static_cast<size_t>(llvm2eth(mem_returnDataOffset));
auto size = static_cast<size_t>(llvm2eth(mem_returnDataSize));
auto& memory = Runtime::getMemory();
return {memory.data() + offset, size};
}

7
libevmjit/Memory.h

@ -10,11 +10,12 @@ namespace eth
{ {
namespace jit namespace jit
{ {
class RuntimeManager;
class Memory : public CompilerHelper class Memory : public CompilerHelper
{ {
public: public:
Memory(llvm::IRBuilder<>& _builder, class GasMeter& _gasMeter); Memory(llvm::IRBuilder<>& _builder, class GasMeter& _gasMeter, RuntimeManager& _runtimeManager);
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);
@ -31,13 +32,13 @@ public:
void require(llvm::Value* _offset, llvm::Value* _size); void require(llvm::Value* _offset, llvm::Value* _size);
void registerReturnData(llvm::Value* _index, llvm::Value* _size); void registerReturnData(llvm::Value* _index, llvm::Value* _size);
static bytesConstRef getReturnData(); bytesConstRef getReturnData();
void dump(uint64_t _begin, uint64_t _end = 0); void dump(uint64_t _begin, uint64_t _end = 0);
private: private:
llvm::Function* createFunc(bool _isStore, llvm::Type* _type, GasMeter& _gasMeter); llvm::Function* createFunc(bool _isStore, llvm::Type* _type, GasMeter& _gasMeter);
llvm::Function* createRequireFunc(GasMeter& _gasMeter); llvm::Function* createRequireFunc(GasMeter& _gasMeter, RuntimeManager& _runtimeManager);
private: private:
llvm::GlobalVariable* m_data; llvm::GlobalVariable* m_data;

34
libevmjit/Runtime.cpp

@ -29,7 +29,7 @@ llvm::StructType* RuntimeData::getType()
return type; return type;
} }
static Runtime* g_runtime; static Runtime* g_runtime; // FIXME: Remove
Runtime::Runtime(u256 _gas, ExtVMFace& _ext): Runtime::Runtime(u256 _gas, ExtVMFace& _ext):
m_ext(_ext) m_ext(_ext)
@ -49,11 +49,6 @@ StackImpl& Runtime::getStack()
return g_runtime->m_stack; return g_runtime->m_stack;
} }
MemoryImpl& Runtime::getMemory()
{
return g_runtime->m_memory;
}
ExtVMFace& Runtime::getExt() ExtVMFace& Runtime::getExt()
{ {
return g_runtime->m_ext; return g_runtime->m_ext;
@ -64,6 +59,19 @@ u256 Runtime::getGas()
return llvm2eth(m_data.gas); return llvm2eth(m_data.gas);
} }
extern "C" {
EXPORT i256 mem_returnDataOffset; // FIXME: Dis-globalize
EXPORT i256 mem_returnDataSize;
}
bytesConstRef Runtime::getReturnData()
{
// TODO: Handle large indexes
auto offset = static_cast<size_t>(llvm2eth(mem_returnDataOffset));
auto size = static_cast<size_t>(llvm2eth(mem_returnDataSize));
return{getMemory().data() + offset, size};
}
RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder): CompilerHelper(_builder) RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder): CompilerHelper(_builder)
{ {
@ -76,19 +84,21 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder): CompilerHelper(_bui
m_builder.CreateStore(dataPtr, m_dataPtr); m_builder.CreateStore(dataPtr, m_dataPtr);
} }
llvm::Value* RuntimeManager::getRuntimePtr()
{
// TODO: If in main function - get it from param
return m_builder.CreateLoad(m_dataPtr);
}
llvm::Value* RuntimeManager::getGas() llvm::Value* RuntimeManager::getGas()
{ {
//auto gasPtr = m_builder.CreateConstGEP2_64(m_dataPtr, 0, 0); auto gasPtr = m_builder.CreateStructGEP(getRuntimePtr(), 0);
auto rt = m_builder.CreateLoad(m_dataPtr);
auto gasPtr = m_builder.CreateStructGEP(rt, 0);
return m_builder.CreateLoad(gasPtr, "gas"); return m_builder.CreateLoad(gasPtr, "gas");
} }
void RuntimeManager::setGas(llvm::Value* _gas) void RuntimeManager::setGas(llvm::Value* _gas)
{ {
//auto gasPtr = m_builder.CreateStructGEP(m_dataPtr, 0); auto gasPtr = m_builder.CreateStructGEP(getRuntimePtr(), 0);
auto rt = m_builder.CreateLoad(m_dataPtr);
auto gasPtr = m_builder.CreateStructGEP(rt, 0);
m_builder.CreateStore(_gas, gasPtr); m_builder.CreateStore(_gas, gasPtr);
} }

5
libevmjit/Runtime.h

@ -44,9 +44,10 @@ public:
RuntimeData* getDataPtr() { return &m_data; } RuntimeData* getDataPtr() { return &m_data; }
static StackImpl& getStack(); static StackImpl& getStack();
static MemoryImpl& getMemory(); MemoryImpl& getMemory() { return m_memory; }
static ExtVMFace& getExt(); static ExtVMFace& getExt();
u256 getGas(); u256 getGas();
bytesConstRef getReturnData();
private: private:
@ -62,6 +63,8 @@ class RuntimeManager: public CompilerHelper
public: public:
RuntimeManager(llvm::IRBuilder<>& _builder); RuntimeManager(llvm::IRBuilder<>& _builder);
llvm::Value* getRuntimePtr();
llvm::Value* getGas(); llvm::Value* getGas();
void setGas(llvm::Value* _gas); void setGas(llvm::Value* _gas);

Loading…
Cancel
Save