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.
RuntimeManager runtimeManager(m_builder);
GasMeter gasMeter(m_builder, runtimeManager);
Memory memory(m_builder, gasMeter);
Memory memory(m_builder, gasMeter, runtimeManager);
Ext ext(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)
{
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 [ ";
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
auto initOff = static_cast<size_t>(llvm2eth(*_initOff));
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
h256 address = ext.create(endowment, &gas, initRef, onOp);
*_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 outOff = static_cast<size_t>(llvm2eth(*_outOff));
auto outSize = static_cast<size_t>(llvm2eth(*_outSize));
auto&& inRef = bytesConstRef(Runtime::getMemory().data() + inOff, inSize);
auto&& outRef = bytesConstRef(Runtime::getMemory().data() + outOff, outSize);
auto&& inRef = bytesConstRef(); //Runtime::getMemory().data() + inOff, inSize);
auto&& outRef = bytesConstRef(); // Runtime::getMemory().data() + outOff, outSize);
OnOpFunc onOp{}; // TODO: Handle that thing
auto codeAddress = right160(*_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 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);
*_ret = *reinterpret_cast<i256*>(&hash);
}

68
libevmjit/Memory.cpp

@ -15,6 +15,7 @@
#include "Runtime.h"
#include "GasMeter.h"
#include "Endianness.h"
#include "Runtime.h"
namespace dev
{
@ -23,7 +24,7 @@ namespace eth
namespace jit
{
Memory::Memory(llvm::IRBuilder<>& _builder, GasMeter& _gasMeter):
Memory::Memory(llvm::IRBuilder<>& _builder, GasMeter& _gasMeter, RuntimeManager& _runtimeManager):
CompilerHelper(_builder)
{
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->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;
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_require = createRequireFunc(_gasMeter);
m_require = createRequireFunc(_gasMeter, _runtimeManager);
m_loadWord = createFunc(false, Type::i256, _gasMeter);
m_storeWord = createFunc(true, Type::i256, _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());
@ -83,7 +85,7 @@ llvm::Function* Memory::createRequireFunc(GasMeter& _gasMeter)
_gasMeter.checkMemory(newWords, m_builder);
// Resize
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.CreateBr(returnBB);
@ -232,48 +234,36 @@ extern "C"
using namespace dev::eth::jit;
EXPORT i256 mem_returnDataOffset;
EXPORT i256 mem_returnDataSize;
EXPORT uint8_t* mem_resize(i256* _size)
EXPORT uint8_t* mem_resize(Runtime* _rt, i256* _size)
{
auto size = _size->a; // Trunc to 64-bit
auto& memory = Runtime::getMemory();
auto& memory = _rt->getMemory();
memory.resize(size);
return memory.data();
}
EXPORT void evmccrt_memory_dump(uint64_t _begin, uint64_t _end)
{
if (_end == 0)
_end = Runtime::getMemory().size();
std::cerr << "MEMORY: active size: " << std::dec
<< Runtime::getMemory().size() / 32 << " words\n";
std::cerr << "MEMORY: dump from " << std::dec
<< _begin << " to " << _end << ":";
if (_end <= _begin)
return;
_begin = _begin / 16 * 16;
for (size_t i = _begin; i < _end; i++)
{
if ((i - _begin) % 16 == 0)
std::cerr << '\n' << std::dec << i << ": ";
auto b = Runtime::getMemory()[i];
std::cerr << std::hex << std::setw(2) << static_cast<int>(b) << ' ';
}
std::cerr << std::endl;
//if (_end == 0)
// _end = Runtime::getMemory().size();
//std::cerr << "MEMORY: active size: " << std::dec
// << Runtime::getMemory().size() / 32 << " words\n";
//std::cerr << "MEMORY: dump from " << std::dec
// << _begin << " to " << _end << ":";
//if (_end <= _begin)
// return;
//_begin = _begin / 16 * 16;
//for (size_t i = _begin; i < _end; i++)
//{
// if ((i - _begin) % 16 == 0)
// std::cerr << '\n' << std::dec << i << ": ";
// auto b = Runtime::getMemory()[i];
// std::cerr << std::hex << std::setw(2) << static_cast<int>(b) << ' ';
//}
//std::cerr << std::endl;
}
} // 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
{
class RuntimeManager;
class Memory : public CompilerHelper
{
public:
Memory(llvm::IRBuilder<>& _builder, class GasMeter& _gasMeter);
Memory(llvm::IRBuilder<>& _builder, class GasMeter& _gasMeter, RuntimeManager& _runtimeManager);
llvm::Value* loadWord(llvm::Value* _addr);
void storeWord(llvm::Value* _addr, llvm::Value* _word);
@ -31,13 +32,13 @@ public:
void require(llvm::Value* _offset, 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);
private:
llvm::Function* createFunc(bool _isStore, llvm::Type* _type, GasMeter& _gasMeter);
llvm::Function* createRequireFunc(GasMeter& _gasMeter);
llvm::Function* createRequireFunc(GasMeter& _gasMeter, RuntimeManager& _runtimeManager);
private:
llvm::GlobalVariable* m_data;

34
libevmjit/Runtime.cpp

@ -29,7 +29,7 @@ llvm::StructType* RuntimeData::getType()
return type;
}
static Runtime* g_runtime;
static Runtime* g_runtime; // FIXME: Remove
Runtime::Runtime(u256 _gas, ExtVMFace& _ext):
m_ext(_ext)
@ -49,11 +49,6 @@ StackImpl& Runtime::getStack()
return g_runtime->m_stack;
}
MemoryImpl& Runtime::getMemory()
{
return g_runtime->m_memory;
}
ExtVMFace& Runtime::getExt()
{
return g_runtime->m_ext;
@ -64,6 +59,19 @@ u256 Runtime::getGas()
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)
{
@ -76,19 +84,21 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder): CompilerHelper(_bui
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()
{
//auto gasPtr = m_builder.CreateConstGEP2_64(m_dataPtr, 0, 0);
auto rt = m_builder.CreateLoad(m_dataPtr);
auto gasPtr = m_builder.CreateStructGEP(rt, 0);
auto gasPtr = m_builder.CreateStructGEP(getRuntimePtr(), 0);
return m_builder.CreateLoad(gasPtr, "gas");
}
void RuntimeManager::setGas(llvm::Value* _gas)
{
//auto gasPtr = m_builder.CreateStructGEP(m_dataPtr, 0);
auto rt = m_builder.CreateLoad(m_dataPtr);
auto gasPtr = m_builder.CreateStructGEP(rt, 0);
auto gasPtr = m_builder.CreateStructGEP(getRuntimePtr(), 0);
m_builder.CreateStore(_gas, gasPtr);
}

5
libevmjit/Runtime.h

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

Loading…
Cancel
Save