mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
Move return data reference to Runtime [#81470252]
This commit is contained in:
parent
6d428d8602
commit
fd7b6da606
5 changed files with 35 additions and 38 deletions
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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…
Reference in a new issue