Browse Source

Move return data reference to Runtime [#81470252]

cl-refactor
Paweł Bylica 10 years ago
parent
commit
33246126f2
  1. 5
      libevmjit/Compiler.cpp
  2. 18
      libevmjit/Memory.cpp
  3. 12
      libevmjit/Memory.h
  4. 33
      libevmjit/Runtime.cpp
  5. 5
      libevmjit/Runtime.h

5
libevmjit/Compiler.cpp

@ -182,7 +182,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, runtimeManager); Memory memory(runtimeManager, gasMeter);
Ext ext(runtimeManager); Ext ext(runtimeManager);
Stack stack(m_builder, runtimeManager); Stack stack(m_builder, runtimeManager);
@ -817,7 +817,8 @@ void Compiler::compileBasicBlock(BasicBlock& basicBlock, bytesConstRef bytecode,
auto index = stack.pop(); auto index = stack.pop();
auto size = stack.pop(); auto size = stack.pop();
memory.registerReturnData(index, size); memory.require(index, size);
_runtimeManager.registerReturnData(index, size);
m_builder.CreateRet(Constant::get(ReturnCode::Return)); m_builder.CreateRet(Constant::get(ReturnCode::Return));
break; break;

18
libevmjit/Memory.cpp

@ -24,8 +24,8 @@ namespace eth
namespace jit namespace jit
{ {
Memory::Memory(llvm::IRBuilder<>& _builder, GasMeter& _gasMeter, RuntimeManager& _runtimeManager): Memory::Memory(RuntimeManager& _runtimeManager, GasMeter& _gasMeter):
CompilerHelper(_builder) RuntimeHelper(_runtimeManager)
{ {
auto module = getModule(); auto module = getModule();
auto i64Ty = m_builder.getInt64Ty(); auto i64Ty = m_builder.getInt64Ty();
@ -40,12 +40,6 @@ Memory::Memory(llvm::IRBuilder<>& _builder, GasMeter& _gasMeter, RuntimeManager&
m_size = new llvm::GlobalVariable(*module, Type::i256, false, llvm::GlobalVariable::PrivateLinkage, Constant::get(0), "mem.size"); m_size = new llvm::GlobalVariable(*module, Type::i256, false, llvm::GlobalVariable::PrivateLinkage, Constant::get(0), "mem.size");
m_size->setUnnamedAddr(true); // Address is not important m_size->setUnnamedAddr(true); // Address is not important
m_returnDataOffset = new llvm::GlobalVariable(*module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "mem_returnDataOffset");
m_returnDataOffset->setUnnamedAddr(true); // Address is not important
m_returnDataSize = new llvm::GlobalVariable(*module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "mem_returnDataSize");
m_returnDataSize->setUnnamedAddr(true); // Address is not important
llvm::Type* resizeArgs[] = {Type::RuntimePtr, Type::WordPtr}; llvm::Type* resizeArgs[] = {Type::RuntimePtr, Type::WordPtr};
m_resize = llvm::Function::Create(llvm::FunctionType::get(Type::BytePtr, resizeArgs, false), llvm::Function::ExternalLinkage, "mem_resize", module); m_resize = llvm::Function::Create(llvm::FunctionType::get(Type::BytePtr, resizeArgs, false), llvm::Function::ExternalLinkage, "mem_resize", module);
llvm::AttrBuilder attrBuilder; llvm::AttrBuilder attrBuilder;
@ -180,14 +174,6 @@ void Memory::require(llvm::Value* _offset, llvm::Value* _size)
require(sizeRequired); require(sizeRequired);
} }
void Memory::registerReturnData(llvm::Value* _index, llvm::Value* _size)
{
require(_index, _size); // Make sure that memory is allocated and count gas
m_builder.CreateStore(_index, m_returnDataOffset);
m_builder.CreateStore(_size, m_returnDataSize);
}
void Memory::copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value* _srcIdx, void Memory::copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value* _srcIdx,
llvm::Value* _destMemIdx, llvm::Value* _reqBytes) llvm::Value* _destMemIdx, llvm::Value* _reqBytes)
{ {

12
libevmjit/Memory.h

@ -10,12 +10,11 @@ namespace eth
{ {
namespace jit namespace jit
{ {
class RuntimeManager;
class Memory : public CompilerHelper class Memory : public RuntimeHelper
{ {
public: public:
Memory(llvm::IRBuilder<>& _builder, class GasMeter& _gasMeter, RuntimeManager& _runtimeManager); Memory(RuntimeManager& _runtimeManager, class GasMeter& _gasMeter);
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,9 +30,6 @@ public:
/// Requires the amount of memory to for data defined by offset and size. And counts gas fee for that memory. /// Requires the amount of memory to for data defined by offset and size. And counts gas fee for that memory.
void require(llvm::Value* _offset, llvm::Value* _size); void require(llvm::Value* _offset, llvm::Value* _size);
void registerReturnData(llvm::Value* _index, llvm::Value* _size);
bytesConstRef getReturnData();
void dump(uint64_t _begin, uint64_t _end = 0); void dump(uint64_t _begin, uint64_t _end = 0);
private: private:
@ -44,10 +40,6 @@ private:
llvm::GlobalVariable* m_data; llvm::GlobalVariable* m_data;
llvm::GlobalVariable* m_size; llvm::GlobalVariable* m_size;
/// @TODO: m_data and m_size could be used
llvm::GlobalVariable* m_returnDataOffset;
llvm::GlobalVariable* m_returnDataSize;
llvm::Function* m_resize; llvm::Function* m_resize;
llvm::Function* m_require; llvm::Function* m_require;
llvm::Function* m_loadWord; llvm::Function* m_loadWord;

33
libevmjit/Runtime.cpp

@ -98,16 +98,14 @@ u256 Runtime::getGas() const
return llvm2eth(m_data.elems[RuntimeData::Gas]); return llvm2eth(m_data.elems[RuntimeData::Gas]);
} }
extern "C" {
EXPORT i256 mem_returnDataOffset; // FIXME: Dis-globalize
EXPORT i256 mem_returnDataSize;
}
bytesConstRef Runtime::getReturnData() const bytesConstRef Runtime::getReturnData() const
{ {
// TODO: Handle large indexes // TODO: Handle large indexes
auto offset = static_cast<size_t>(llvm2eth(mem_returnDataOffset)); auto offset = static_cast<size_t>(llvm2eth(m_data.elems[RuntimeData::ReturnDataOffset]));
auto size = static_cast<size_t>(llvm2eth(mem_returnDataSize)); auto size = static_cast<size_t>(llvm2eth(m_data.elems[RuntimeData::ReturnDataSize]));
assert(offset + size <= m_memory.size());
// TODO: Handle invalid data access by returning empty ref
return {m_memory.data() + offset, size}; return {m_memory.data() + offset, size};
} }
@ -128,11 +126,26 @@ llvm::Value* RuntimeManager::getRuntimePtr()
return m_builder.CreateLoad(m_dataPtr); return m_builder.CreateLoad(m_dataPtr);
} }
llvm::Value* RuntimeManager::get(RuntimeData::Index _index) llvm::Value* RuntimeManager::getPtr(RuntimeData::Index _index)
{ {
llvm::Value* idxList[] = {m_builder.getInt32(0), m_builder.getInt32(0), m_builder.getInt32(_index)}; llvm::Value* idxList[] = {m_builder.getInt32(0), m_builder.getInt32(0), m_builder.getInt32(_index)};
auto ptr = m_builder.CreateInBoundsGEP(getRuntimePtr(), idxList, getName(_index) + "Ptr"); return m_builder.CreateInBoundsGEP(getRuntimePtr(), idxList, getName(_index) + "Ptr");
return m_builder.CreateLoad(ptr, getName(_index)); }
llvm::Value* RuntimeManager::get(RuntimeData::Index _index)
{
return m_builder.CreateLoad(getPtr(_index), getName(_index));
}
void RuntimeManager::set(RuntimeData::Index _index, llvm::Value* _value)
{
m_builder.CreateStore(_value, getPtr(_index));
}
void RuntimeManager::registerReturnData(llvm::Value* _offset, llvm::Value* _size)
{
set(RuntimeData::ReturnDataOffset, _offset);
set(RuntimeData::ReturnDataSize, _size);
} }
llvm::Value* RuntimeManager::get(Instruction _inst) llvm::Value* RuntimeManager::get(Instruction _inst)

5
libevmjit/Runtime.h

@ -102,7 +102,12 @@ public:
llvm::Value* getJmpBuf(); llvm::Value* getJmpBuf();
void setGas(llvm::Value* _gas); void setGas(llvm::Value* _gas);
void registerReturnData(llvm::Value* _index, llvm::Value* _size);
private: private:
llvm::Value* getPtr(RuntimeData::Index _index);
void set(RuntimeData::Index _index, llvm::Value* _value);
llvm::GlobalVariable* m_dataPtr; llvm::GlobalVariable* m_dataPtr;
}; };

Loading…
Cancel
Save