diff --git a/libevmjit/Compiler.cpp b/libevmjit/Compiler.cpp index 5061dabb0..26d5c6f19 100644 --- a/libevmjit/Compiler.cpp +++ b/libevmjit/Compiler.cpp @@ -180,7 +180,7 @@ std::unique_ptr Compiler::compile(bytesConstRef bytecode) RuntimeManager runtimeManager(m_builder); GasMeter gasMeter(m_builder, runtimeManager); Memory memory(m_builder, gasMeter, runtimeManager); - Ext ext(m_builder); + Ext ext(runtimeManager); Stack stack(m_builder, runtimeManager); m_builder.CreateBr(basicBlocks.begin()->second); @@ -686,7 +686,7 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode, case Instruction::ADDRESS: { - auto value = ext.address(); + auto value = _runtimeManager.get(RuntimeData::Address); stack.push(value); break; } @@ -873,7 +873,7 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode, auto receiveAddress = codeAddress; if (inst == Instruction::CALLCODE) - receiveAddress = ext.address(); + receiveAddress = _runtimeManager.get(RuntimeData::Address); auto ret = ext.call(gas, receiveAddress, value, inOff, inSize, outOff, outSize, codeAddress); gasMeter.giveBack(gas); diff --git a/libevmjit/Ext.cpp b/libevmjit/Ext.cpp index 07023c674..2e38aef27 100644 --- a/libevmjit/Ext.cpp +++ b/libevmjit/Ext.cpp @@ -44,10 +44,10 @@ struct ExtData const byte* code; }; -Ext::Ext(llvm::IRBuilder<>& _builder): - CompilerHelper(_builder) +Ext::Ext(RuntimeManager& _runtimeManager): + RuntimeHelper(_runtimeManager) { - auto&& ctx = _builder.getContext(); + auto&& ctx = m_builder.getContext(); auto module = getModule(); auto i256Ty = m_builder.getIntNTy(256); @@ -126,7 +126,6 @@ Value* Ext::getDataElem(unsigned _index, const Twine& _name) return m_builder.CreateLoad(valuePtr); } -Value* Ext::address() { return getDataElem(0, "address"); } Value* Ext::caller() { return getDataElem(1, "caller"); } Value* Ext::origin() { return getDataElem(2, "origin"); } Value* Ext::callvalue() { return getDataElem(3, "callvalue"); } @@ -243,7 +242,6 @@ using namespace dev::eth::jit; EXPORT void ext_init(ExtData* _extData) { 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); diff --git a/libevmjit/Ext.h b/libevmjit/Ext.h index 361b6e47e..6d8501d29 100644 --- a/libevmjit/Ext.h +++ b/libevmjit/Ext.h @@ -12,15 +12,14 @@ namespace eth namespace jit { -class Ext : public CompilerHelper +class Ext : public RuntimeHelper { public: - Ext(llvm::IRBuilder<>& _builder); + Ext(RuntimeManager& _runtimeManager); llvm::Value* store(llvm::Value* _index); void setStore(llvm::Value* _index, llvm::Value* _value); - llvm::Value* address(); llvm::Value* caller(); llvm::Value* origin(); llvm::Value* callvalue(); diff --git a/libevmjit/Runtime.cpp b/libevmjit/Runtime.cpp index e09db52c9..bf231cc10 100644 --- a/libevmjit/Runtime.cpp +++ b/libevmjit/Runtime.cpp @@ -22,7 +22,7 @@ llvm::StructType* RuntimeData::getType() { llvm::Type* elems[] = { - Type::i256, + llvm::ArrayType::get(Type::i256, _size) }; type = llvm::StructType::create(elems, "RuntimeData"); } @@ -36,7 +36,8 @@ Runtime::Runtime(u256 _gas, ExtVMFace& _ext): { assert(!g_runtime); g_runtime = this; - m_data.gas = eth2llvm(_gas); + set(RuntimeData::Gas, _gas); + set(RuntimeData::Address, fromAddress(_ext.myAddress)); } Runtime::~Runtime() @@ -44,15 +45,20 @@ Runtime::~Runtime() g_runtime = nullptr; } +void Runtime::set(RuntimeData::Index _index, u256 _value) +{ + m_data.elems[_index] = eth2llvm(_value); +} + ExtVMFace& Runtime::getExt() { return g_runtime->m_ext; } -u256 Runtime::getGas() +u256 Runtime::getGas() const { - return llvm2eth(m_data.gas); + return llvm2eth(m_data.elems[RuntimeData::Gas]); } extern "C" { @@ -60,12 +66,12 @@ extern "C" { EXPORT i256 mem_returnDataSize; } -bytesConstRef Runtime::getReturnData() +bytesConstRef Runtime::getReturnData() const { // TODO: Handle large indexes auto offset = static_cast(llvm2eth(mem_returnDataOffset)); auto size = static_cast(llvm2eth(mem_returnDataSize)); - return{getMemory().data() + offset, size}; + return {m_memory.data() + offset, size}; } @@ -85,16 +91,23 @@ llvm::Value* RuntimeManager::getRuntimePtr() return m_builder.CreateLoad(m_dataPtr); } +llvm::Value* RuntimeManager::get(RuntimeData::Index _index) +{ + llvm::Value* idxList[] = {m_builder.getInt32(0), m_builder.getInt32(0), m_builder.getInt32(_index)}; + auto ptr = m_builder.CreateInBoundsGEP(getRuntimePtr(), idxList, "dataElemPtr"); + return m_builder.CreateLoad(ptr); +} + llvm::Value* RuntimeManager::getGas() { - auto gasPtr = m_builder.CreateStructGEP(getRuntimePtr(), 0); - return m_builder.CreateLoad(gasPtr, "gas"); + return get(RuntimeData::Gas); } void RuntimeManager::setGas(llvm::Value* _gas) { - auto gasPtr = m_builder.CreateStructGEP(getRuntimePtr(), 0); - m_builder.CreateStore(_gas, gasPtr); + llvm::Value* idxList[] = {m_builder.getInt32(0), m_builder.getInt32(0), m_builder.getInt32(RuntimeData::Gas)}; + auto ptr = m_builder.CreateInBoundsGEP(getRuntimePtr(), idxList, "gasPtr"); + m_builder.CreateStore(_gas, ptr); } } diff --git a/libevmjit/Runtime.h b/libevmjit/Runtime.h index dc617b777..8b2efe8ed 100644 --- a/libevmjit/Runtime.h +++ b/libevmjit/Runtime.h @@ -24,9 +24,17 @@ namespace jit struct RuntimeData { - static llvm::StructType* getType(); + enum Index: unsigned + { + Gas, + Address, + + _size + }; + + i256 elems[_size]; - i256 gas; + static llvm::StructType* getType(); }; using StackImpl = std::vector; @@ -46,10 +54,12 @@ public: StackImpl& getStack() { return m_stack; } MemoryImpl& getMemory() { return m_memory; } static ExtVMFace& getExt(); - u256 getGas(); - bytesConstRef getReturnData(); + + u256 getGas() const; + bytesConstRef getReturnData() const; private: + void set(RuntimeData::Index _index, u256 _value); /// @internal Must be the first element to asure Runtime* === RuntimeData* RuntimeData m_data; @@ -65,6 +75,7 @@ public: llvm::Value* getRuntimePtr(); + llvm::Value* get(RuntimeData::Index _index); llvm::Value* getGas(); void setGas(llvm::Value* _gas);