diff --git a/libevmjit/Compiler.cpp b/libevmjit/Compiler.cpp index ddfe2497e..c3c09384b 100644 --- a/libevmjit/Compiler.cpp +++ b/libevmjit/Compiler.cpp @@ -179,7 +179,7 @@ std::unique_ptr 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); diff --git a/libevmjit/ExecutionEngine.cpp b/libevmjit/ExecutionEngine.cpp index 5d5af553e..f7f30614c 100644 --- a/libevmjit/ExecutionEngine.cpp +++ b/libevmjit/ExecutionEngine.cpp @@ -121,7 +121,7 @@ int ExecutionEngine::run(std::unique_ptr _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) diff --git a/libevmjit/Ext.cpp b/libevmjit/Ext.cpp index 045d25b62..07023c674 100644 --- a/libevmjit/Ext.cpp +++ b/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(llvm2eth(*_initOff)); auto initSize = static_cast(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(llvm2eth(*_inSize)); auto outOff = static_cast(llvm2eth(*_outOff)); auto outSize = static_cast(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(llvm2eth(*_inOff)); auto inSize = static_cast(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(&hash); } diff --git a/libevmjit/Memory.cpp b/libevmjit/Memory.cpp index 23d027ba4..8d7674885 100644 --- a/libevmjit/Memory.cpp +++ b/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(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(b) << ' '; + //} + //std::cerr << std::endl; } } // extern "C" - -dev::bytesConstRef dev::eth::jit::Memory::getReturnData() -{ - // TODO: Handle large indexes - auto offset = static_cast(llvm2eth(mem_returnDataOffset)); - auto size = static_cast(llvm2eth(mem_returnDataSize)); - auto& memory = Runtime::getMemory(); - return {memory.data() + offset, size}; -} diff --git a/libevmjit/Memory.h b/libevmjit/Memory.h index 2ab09c127..d92538247 100644 --- a/libevmjit/Memory.h +++ b/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; diff --git a/libevmjit/Runtime.cpp b/libevmjit/Runtime.cpp index e37729e5b..37e414b17 100644 --- a/libevmjit/Runtime.cpp +++ b/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(llvm2eth(mem_returnDataOffset)); + auto size = static_cast(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); } diff --git a/libevmjit/Runtime.h b/libevmjit/Runtime.h index 418555c04..87f43f786 100644 --- a/libevmjit/Runtime.h +++ b/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);