diff --git a/libevmjit/Ext.cpp b/libevmjit/Ext.cpp index ef7bba69c..4e681d5be 100644 --- a/libevmjit/Ext.cpp +++ b/libevmjit/Ext.cpp @@ -40,7 +40,7 @@ Ext::Ext(RuntimeManager& _runtimeManager): using Linkage = llvm::GlobalValue::LinkageTypes; - llvm::Type* argsTypes[] = {Type::RuntimePtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr}; + llvm::Type* argsTypes[] = {Type::EnvPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr}; m_store = llvm::Function::Create(llvm::FunctionType::get(Type::Void, {argsTypes, 3}, false), Linkage::ExternalLinkage, "ext_store", module); m_setStore = llvm::Function::Create(llvm::FunctionType::get(Type::Void, {argsTypes, 3}, false), Linkage::ExternalLinkage, "ext_setStore", module); @@ -63,7 +63,7 @@ Ext::Ext(RuntimeManager& _runtimeManager): llvm::Value* Ext::store(llvm::Value* _index) { m_builder.CreateStore(_index, m_args[0]); - m_builder.CreateCall3(m_store, getRuntimeManager().getRuntimePtr(), m_args[0], m_args[1]); // Uses native endianness + m_builder.CreateCall3(m_store, getRuntimeManager().getEnv(), m_args[0], m_args[1]); // Uses native endianness return m_builder.CreateLoad(m_args[1]); } @@ -71,13 +71,13 @@ void Ext::setStore(llvm::Value* _index, llvm::Value* _value) { m_builder.CreateStore(_index, m_args[0]); m_builder.CreateStore(_value, m_args[1]); - m_builder.CreateCall3(m_setStore, getRuntimeManager().getRuntimePtr(), m_args[0], m_args[1]); // Uses native endianness + m_builder.CreateCall3(m_setStore, getRuntimeManager().getEnv(), m_args[0], m_args[1]); // Uses native endianness } llvm::Value* Ext::calldataload(llvm::Value* _index) { m_builder.CreateStore(_index, m_args[0]); - m_builder.CreateCall3(m_calldataload, getRuntimeManager().getRuntimePtr(), m_args[0], m_args[1]); + m_builder.CreateCall3(m_calldataload, getRuntimeManager().getEnv(), m_args[0], m_args[1]); auto ret = m_builder.CreateLoad(m_args[1]); return Endianness::toNative(m_builder, ret); } @@ -86,7 +86,7 @@ llvm::Value* Ext::balance(llvm::Value* _address) { auto address = Endianness::toBE(m_builder, _address); m_builder.CreateStore(address, m_args[0]); - m_builder.CreateCall3(m_balance, getRuntimeManager().getRuntimePtr(), m_args[0], m_args[1]); + m_builder.CreateCall3(m_balance, getRuntimeManager().getEnv(), m_args[0], m_args[1]); return m_builder.CreateLoad(m_args[1]); } @@ -94,7 +94,7 @@ void Ext::suicide(llvm::Value* _address) { auto address = Endianness::toBE(m_builder, _address); m_builder.CreateStore(address, m_args[0]); - m_builder.CreateCall2(m_suicide, getRuntimeManager().getRuntimePtr(), m_args[0]); + m_builder.CreateCall2(m_suicide, getRuntimeManager().getEnv(), m_args[0]); } llvm::Value* Ext::create(llvm::Value* _endowment, llvm::Value* _initOff, llvm::Value* _initSize) @@ -120,7 +120,7 @@ llvm::Value* Ext::call(llvm::Value*& _gas, llvm::Value* _receiveAddress, llvm::V m_builder.CreateStore(_outSize, m_arg7); auto codeAddress = Endianness::toBE(m_builder, _codeAddress); m_builder.CreateStore(codeAddress, m_arg8); - createCall(m_call, getRuntimeManager().getRuntimePtr(), m_args[0], m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_args[1]); + createCall(m_call, getRuntimeManager().getEnv(), m_args[0], m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_args[1]); _gas = m_builder.CreateLoad(m_args[0]); // Return gas return m_builder.CreateLoad(m_args[1]); } @@ -129,7 +129,7 @@ llvm::Value* Ext::sha3(llvm::Value* _inOff, llvm::Value* _inSize) { m_builder.CreateStore(_inOff, m_args[0]); m_builder.CreateStore(_inSize, m_arg2); - createCall(m_sha3, getRuntimeManager().getRuntimePtr(), m_args[0], m_arg2, m_args[1]); + createCall(m_sha3, getRuntimeManager().getEnv(), m_args[0], m_arg2, m_args[1]); llvm::Value* hash = m_builder.CreateLoad(m_args[1]); hash = Endianness::toNative(m_builder, hash); return hash; @@ -139,14 +139,14 @@ llvm::Value* Ext::codeAt(llvm::Value* _addr) { auto addr = Endianness::toBE(m_builder, _addr); m_builder.CreateStore(addr, m_args[0]); - return m_builder.CreateCall2(m_codeAt, getRuntimeManager().getRuntimePtr(), m_args[0]); + return m_builder.CreateCall2(m_codeAt, getRuntimeManager().getEnv(), m_args[0]); } llvm::Value* Ext::codesizeAt(llvm::Value* _addr) { auto addr = Endianness::toBE(m_builder, _addr); m_builder.CreateStore(addr, m_args[0]); - createCall(m_codesizeAt, getRuntimeManager().getRuntimePtr(), m_args[0], m_args[1]); + createCall(m_codesizeAt, getRuntimeManager().getEnv(), m_args[0], m_args[1]); return m_builder.CreateLoad(m_args[1]); } @@ -155,7 +155,7 @@ void Ext::log(llvm::Value* _memIdx, llvm::Value* _numBytes, size_t _numTopics, s llvm::Value* args[] = {nullptr, m_args[0], m_args[1], m_arg2, m_arg3, m_arg4, m_arg5}; llvm::Value* funcs[] = {m_log0, m_log1, m_log2, m_log3, m_log4}; - args[0] = getRuntimeManager().getRuntimePtr(); + args[0] = getRuntimeManager().getEnv(); m_builder.CreateStore(_memIdx, m_args[0]); m_builder.CreateStore(_numBytes, m_args[1]); diff --git a/libevmjit/RuntimeManager.cpp b/libevmjit/RuntimeManager.cpp index 2d80ad131..56efa0c64 100644 --- a/libevmjit/RuntimeManager.cpp +++ b/libevmjit/RuntimeManager.cpp @@ -39,7 +39,7 @@ llvm::StructType* RuntimeManager::getRuntimeType() llvm::Type* elems[] = { Type::RuntimeDataPtr, // data - Type::BytePtr, // Env* + Type::EnvPtr, // Env* Type::BytePtr // jmpbuf }; type = llvm::StructType::create(elems, "Runtime"); @@ -85,6 +85,10 @@ RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder): CompilerHelper(_bui auto dataPtr = m_builder.CreateStructGEP(rtPtr, 0, "dataPtr"); auto data = m_builder.CreateLoad(dataPtr, "data"); m_builder.CreateStore(data, m_dataPtr); + + auto envPtr = m_builder.CreateStructGEP(rtPtr, 1, "envPtr"); + m_env = m_builder.CreateLoad(envPtr, "env"); + assert(m_env->getType() == Type::EnvPtr); } llvm::Value* RuntimeManager::getRuntimePtr() @@ -103,6 +107,12 @@ llvm::Value* RuntimeManager::getDataPtr() return m_builder.CreateLoad(m_dataPtr, "data"); } +llvm::Value* RuntimeManager::getEnv() +{ + assert(getMainFunction()); // Available only in main function + return m_env; +} + llvm::Value* RuntimeManager::getPtr(RuntimeData::Index _index) { llvm::Value* idxList[] = {m_builder.getInt32(0), m_builder.getInt32(0), m_builder.getInt32(_index)}; diff --git a/libevmjit/RuntimeManager.h b/libevmjit/RuntimeManager.h index 32f7786d7..c10c8cd25 100644 --- a/libevmjit/RuntimeManager.h +++ b/libevmjit/RuntimeManager.h @@ -19,6 +19,7 @@ public: llvm::Value* getRuntimePtr(); llvm::Value* getDataPtr(); + llvm::Value* getEnv(); llvm::Value* get(RuntimeData::Index _index); llvm::Value* get(Instruction _inst); @@ -42,6 +43,7 @@ private: llvm::GlobalVariable* m_rtPtr = nullptr; llvm::GlobalVariable* m_dataPtr = nullptr; llvm::Function* m_longjmp = nullptr; + llvm::Value* m_env = nullptr; }; } diff --git a/libevmjit/Type.cpp b/libevmjit/Type.cpp index 405302860..62b819dc8 100644 --- a/libevmjit/Type.cpp +++ b/libevmjit/Type.cpp @@ -20,22 +20,28 @@ llvm::IntegerType* Type::Byte; llvm::PointerType* Type::BytePtr; llvm::Type* Type::Void; llvm::IntegerType* Type::MainReturn; +llvm::PointerType* Type::EnvPtr; llvm::PointerType* Type::RuntimeDataPtr; llvm::PointerType* Type::RuntimePtr; void Type::init(llvm::LLVMContext& _context) { - Word = llvm::Type::getIntNTy(_context, 256); - WordPtr = Word->getPointerTo(); - lowPrecision = llvm::Type::getInt64Ty(_context); - // TODO: Size should be architecture-dependent - Size = llvm::Type::getInt64Ty(_context); - Byte = llvm::Type::getInt8Ty(_context); - BytePtr = Byte->getPointerTo(); - Void = llvm::Type::getVoidTy(_context); - MainReturn = llvm::Type::getInt32Ty(_context); - RuntimeDataPtr = RuntimeManager::getRuntimeDataType()->getPointerTo(); - RuntimePtr = RuntimeManager::getRuntimeType()->getPointerTo(); + if (!Word) // Do init only once + { + Word = llvm::Type::getIntNTy(_context, 256); + WordPtr = Word->getPointerTo(); + lowPrecision = llvm::Type::getInt64Ty(_context); + // TODO: Size should be architecture-dependent + Size = llvm::Type::getInt64Ty(_context); + Byte = llvm::Type::getInt8Ty(_context); + BytePtr = Byte->getPointerTo(); + Void = llvm::Type::getVoidTy(_context); + MainReturn = llvm::Type::getInt32Ty(_context); + + EnvPtr = llvm::StructType::create(_context, "Env")->getPointerTo(); + RuntimeDataPtr = RuntimeManager::getRuntimeDataType()->getPointerTo(); + RuntimePtr = RuntimeManager::getRuntimeType()->getPointerTo(); + } } llvm::ConstantInt* Constant::get(int64_t _n) diff --git a/libevmjit/Type.h b/libevmjit/Type.h index 393b72c5c..b0e3fa237 100644 --- a/libevmjit/Type.h +++ b/libevmjit/Type.h @@ -31,6 +31,7 @@ struct Type /// Main function return type static llvm::IntegerType* MainReturn; + static llvm::PointerType* EnvPtr; static llvm::PointerType* RuntimeDataPtr; static llvm::PointerType* RuntimePtr;