mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-22 04:36:42 +00:00
Remove global privite pointers to runtime instance and runtime data
This commit is contained in:
parent
6643af5224
commit
f8ffdfa30c
6 changed files with 60 additions and 58 deletions
|
|
@ -69,7 +69,7 @@ Ext::Ext(RuntimeManager& _runtimeManager, Memory& _memoryMan):
|
||||||
llvm::Value* Ext::sload(llvm::Value* _index)
|
llvm::Value* Ext::sload(llvm::Value* _index)
|
||||||
{
|
{
|
||||||
m_builder.CreateStore(_index, m_args[0]);
|
m_builder.CreateStore(_index, m_args[0]);
|
||||||
m_builder.CreateCall3(m_sload, getRuntimeManager().getEnv(), m_args[0], m_args[1]); // Uses native endianness
|
m_builder.CreateCall3(m_sload, getRuntimeManager().getEnvPtr(), m_args[0], m_args[1]); // Uses native endianness
|
||||||
return m_builder.CreateLoad(m_args[1]);
|
return m_builder.CreateLoad(m_args[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,7 +77,7 @@ void Ext::sstore(llvm::Value* _index, llvm::Value* _value)
|
||||||
{
|
{
|
||||||
m_builder.CreateStore(_index, m_args[0]);
|
m_builder.CreateStore(_index, m_args[0]);
|
||||||
m_builder.CreateStore(_value, m_args[1]);
|
m_builder.CreateStore(_value, m_args[1]);
|
||||||
m_builder.CreateCall3(m_sstore, getRuntimeManager().getEnv(), m_args[0], m_args[1]); // Uses native endianness
|
m_builder.CreateCall3(m_sstore, getRuntimeManager().getEnvPtr(), m_args[0], m_args[1]); // Uses native endianness
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value* Ext::calldataload(llvm::Value* _index)
|
llvm::Value* Ext::calldataload(llvm::Value* _index)
|
||||||
|
|
@ -92,7 +92,7 @@ llvm::Value* Ext::balance(llvm::Value* _address)
|
||||||
{
|
{
|
||||||
auto address = Endianness::toBE(m_builder, _address);
|
auto address = Endianness::toBE(m_builder, _address);
|
||||||
m_builder.CreateStore(address, m_args[0]);
|
m_builder.CreateStore(address, m_args[0]);
|
||||||
m_builder.CreateCall3(m_balance, getRuntimeManager().getEnv(), m_args[0], m_args[1]);
|
m_builder.CreateCall3(m_balance, getRuntimeManager().getEnvPtr(), m_args[0], m_args[1]);
|
||||||
return m_builder.CreateLoad(m_args[1]);
|
return m_builder.CreateLoad(m_args[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,7 +100,7 @@ void Ext::suicide(llvm::Value* _address)
|
||||||
{
|
{
|
||||||
auto address = Endianness::toBE(m_builder, _address);
|
auto address = Endianness::toBE(m_builder, _address);
|
||||||
m_builder.CreateStore(address, m_args[0]);
|
m_builder.CreateStore(address, m_args[0]);
|
||||||
m_builder.CreateCall2(m_suicide, getRuntimeManager().getEnv(), m_args[0]);
|
m_builder.CreateCall2(m_suicide, getRuntimeManager().getEnvPtr(), m_args[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value* Ext::create(llvm::Value*& _gas, llvm::Value* _endowment, llvm::Value* _initOff, llvm::Value* _initSize)
|
llvm::Value* Ext::create(llvm::Value*& _gas, llvm::Value* _endowment, llvm::Value* _initOff, llvm::Value* _initSize)
|
||||||
|
|
@ -109,7 +109,7 @@ llvm::Value* Ext::create(llvm::Value*& _gas, llvm::Value* _endowment, llvm::Valu
|
||||||
m_builder.CreateStore(_endowment, m_arg2);
|
m_builder.CreateStore(_endowment, m_arg2);
|
||||||
auto begin = m_memoryMan.getBytePtr(_initOff);
|
auto begin = m_memoryMan.getBytePtr(_initOff);
|
||||||
auto size = m_builder.CreateTrunc(_initSize, Type::Size, "size");
|
auto size = m_builder.CreateTrunc(_initSize, Type::Size, "size");
|
||||||
createCall(m_create, getRuntimeManager().getEnv(), m_args[0], m_arg2, begin, size, m_args[1]);
|
createCall(m_create, getRuntimeManager().getEnvPtr(), m_args[0], m_arg2, begin, size, m_args[1]);
|
||||||
_gas = m_builder.CreateLoad(m_args[0]); // Return gas
|
_gas = m_builder.CreateLoad(m_args[0]); // Return gas
|
||||||
llvm::Value* address = m_builder.CreateLoad(m_args[1]);
|
llvm::Value* address = m_builder.CreateLoad(m_args[1]);
|
||||||
address = Endianness::toNative(m_builder, address);
|
address = Endianness::toNative(m_builder, address);
|
||||||
|
|
@ -128,7 +128,7 @@ llvm::Value* Ext::call(llvm::Value*& _gas, llvm::Value* _receiveAddress, llvm::V
|
||||||
auto outSize = m_builder.CreateTrunc(_outSize, Type::Size, "out.size");
|
auto outSize = m_builder.CreateTrunc(_outSize, Type::Size, "out.size");
|
||||||
auto codeAddress = Endianness::toBE(m_builder, _codeAddress);
|
auto codeAddress = Endianness::toBE(m_builder, _codeAddress);
|
||||||
m_builder.CreateStore(codeAddress, m_arg8);
|
m_builder.CreateStore(codeAddress, m_arg8);
|
||||||
auto ret = createCall(m_call, getRuntimeManager().getEnv(), m_args[0], m_arg2, m_arg3, inBeg, inSize, outBeg, outSize, m_arg8);
|
auto ret = createCall(m_call, getRuntimeManager().getEnvPtr(), m_args[0], m_arg2, m_arg3, inBeg, inSize, outBeg, outSize, m_arg8);
|
||||||
_gas = m_builder.CreateLoad(m_args[0]); // Return gas
|
_gas = m_builder.CreateLoad(m_args[0]); // Return gas
|
||||||
return m_builder.CreateZExt(ret, Type::Word, "ret");
|
return m_builder.CreateZExt(ret, Type::Word, "ret");
|
||||||
}
|
}
|
||||||
|
|
@ -147,7 +147,7 @@ MemoryRef Ext::getExtCode(llvm::Value* _addr)
|
||||||
{
|
{
|
||||||
auto addr = Endianness::toBE(m_builder, _addr);
|
auto addr = Endianness::toBE(m_builder, _addr);
|
||||||
m_builder.CreateStore(addr, m_args[0]);
|
m_builder.CreateStore(addr, m_args[0]);
|
||||||
auto code = createCall(m_getExtCode, getRuntimeManager().getEnv(), m_args[0], m_size);
|
auto code = createCall(m_getExtCode, getRuntimeManager().getEnvPtr(), m_args[0], m_size);
|
||||||
auto codeSize = m_builder.CreateLoad(m_size);
|
auto codeSize = m_builder.CreateLoad(m_size);
|
||||||
auto codeSize256 = m_builder.CreateZExt(codeSize, Type::Word);
|
auto codeSize256 = m_builder.CreateZExt(codeSize, Type::Word);
|
||||||
return {code, codeSize256};
|
return {code, codeSize256};
|
||||||
|
|
@ -157,7 +157,7 @@ void Ext::log(llvm::Value* _memIdx, llvm::Value* _numBytes, std::array<llvm::Val
|
||||||
{
|
{
|
||||||
auto begin = m_memoryMan.getBytePtr(_memIdx);
|
auto begin = m_memoryMan.getBytePtr(_memIdx);
|
||||||
auto size = m_builder.CreateTrunc(_numBytes, Type::Size, "size");
|
auto size = m_builder.CreateTrunc(_numBytes, Type::Size, "size");
|
||||||
llvm::Value* args[] = {getRuntimeManager().getEnv(), begin, size, m_arg2, m_arg3, m_arg4, m_arg5};
|
llvm::Value* args[] = {getRuntimeManager().getEnvPtr(), begin, size, m_arg2, m_arg3, m_arg4, m_arg5};
|
||||||
|
|
||||||
auto topicArgPtr = &args[3];
|
auto topicArgPtr = &args[3];
|
||||||
for (auto&& topic : _topics)
|
for (auto&& topic : _topics)
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,8 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder, RuntimeManager& _runtimeManager)
|
||||||
{
|
{
|
||||||
auto module = getModule();
|
auto module = getModule();
|
||||||
|
|
||||||
m_gasCheckFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, Type::Word, false), llvm::Function::PrivateLinkage, "gas.check", module);
|
llvm::Type* gasCheckArgs[] = {Type::RuntimePtr, Type::Word};
|
||||||
|
m_gasCheckFunc = llvm::Function::Create(llvm::FunctionType::get(Type::Void, gasCheckArgs, false), llvm::Function::PrivateLinkage, "gas.check", module);
|
||||||
InsertPointGuard guard(m_builder);
|
InsertPointGuard guard(m_builder);
|
||||||
|
|
||||||
auto checkBB = llvm::BasicBlock::Create(_builder.getContext(), "Check", m_gasCheckFunc);
|
auto checkBB = llvm::BasicBlock::Create(_builder.getContext(), "Check", m_gasCheckFunc);
|
||||||
|
|
@ -94,14 +95,17 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder, RuntimeManager& _runtimeManager)
|
||||||
auto updateBB = llvm::BasicBlock::Create(_builder.getContext(), "Update", m_gasCheckFunc);
|
auto updateBB = llvm::BasicBlock::Create(_builder.getContext(), "Update", m_gasCheckFunc);
|
||||||
|
|
||||||
m_builder.SetInsertPoint(checkBB);
|
m_builder.SetInsertPoint(checkBB);
|
||||||
llvm::Value* cost = m_gasCheckFunc->arg_begin();
|
auto arg = m_gasCheckFunc->arg_begin();
|
||||||
cost->setName("cost");
|
arg->setName("rt");
|
||||||
|
++arg;
|
||||||
|
arg->setName("cost");
|
||||||
|
auto cost = arg;
|
||||||
auto gas = m_runtimeManager.getGas();
|
auto gas = m_runtimeManager.getGas();
|
||||||
auto isOutOfGas = m_builder.CreateICmpUGT(cost, gas, "isOutOfGas");
|
auto isOutOfGas = m_builder.CreateICmpUGT(cost, gas, "isOutOfGas");
|
||||||
m_builder.CreateCondBr(isOutOfGas, outOfGasBB, updateBB);
|
m_builder.CreateCondBr(isOutOfGas, outOfGasBB, updateBB);
|
||||||
|
|
||||||
m_builder.SetInsertPoint(outOfGasBB);
|
m_builder.SetInsertPoint(outOfGasBB);
|
||||||
_runtimeManager.raiseException(ReturnCode::OutOfGas);
|
m_runtimeManager.raiseException(ReturnCode::OutOfGas);
|
||||||
m_builder.CreateUnreachable();
|
m_builder.CreateUnreachable();
|
||||||
|
|
||||||
m_builder.SetInsertPoint(updateBB);
|
m_builder.SetInsertPoint(updateBB);
|
||||||
|
|
@ -115,7 +119,7 @@ void GasMeter::count(Instruction _inst)
|
||||||
if (!m_checkCall)
|
if (!m_checkCall)
|
||||||
{
|
{
|
||||||
// Create gas check call with mocked block cost at begining of current cost-block
|
// Create gas check call with mocked block cost at begining of current cost-block
|
||||||
m_checkCall = m_builder.CreateCall(m_gasCheckFunc, llvm::UndefValue::get(Type::Word));
|
m_checkCall = createCall(m_gasCheckFunc, m_runtimeManager.getRuntimePtr(), llvm::UndefValue::get(Type::Word));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_blockCost += getStepCost(_inst);
|
m_blockCost += getStepCost(_inst);
|
||||||
|
|
@ -123,7 +127,7 @@ void GasMeter::count(Instruction _inst)
|
||||||
|
|
||||||
void GasMeter::count(llvm::Value* _cost)
|
void GasMeter::count(llvm::Value* _cost)
|
||||||
{
|
{
|
||||||
createCall(m_gasCheckFunc, _cost);
|
createCall(m_gasCheckFunc, m_runtimeManager.getRuntimePtr(), _cost);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GasMeter::countExp(llvm::Value* _exponent)
|
void GasMeter::countExp(llvm::Value* _exponent)
|
||||||
|
|
@ -193,7 +197,7 @@ void GasMeter::commitCostBlock()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_checkCall->setArgOperand(0, Constant::get(m_blockCost)); // Update block cost in gas check call
|
m_checkCall->setArgOperand(1, Constant::get(m_blockCost)); // Update block cost in gas check call
|
||||||
m_checkCall = nullptr; // End cost-block
|
m_checkCall = nullptr; // End cost-block
|
||||||
m_blockCost = 0;
|
m_blockCost = 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ namespace jit
|
||||||
{
|
{
|
||||||
|
|
||||||
Memory::Memory(RuntimeManager& _runtimeManager, GasMeter& _gasMeter):
|
Memory::Memory(RuntimeManager& _runtimeManager, GasMeter& _gasMeter):
|
||||||
RuntimeHelper(_runtimeManager),
|
RuntimeHelper(_runtimeManager), // TODO: RuntimeHelper not needed
|
||||||
m_gasMeter(_gasMeter)
|
m_gasMeter(_gasMeter)
|
||||||
{
|
{
|
||||||
auto module = getModule();
|
auto module = getModule();
|
||||||
|
|
@ -45,17 +45,19 @@ Memory::Memory(RuntimeManager& _runtimeManager, GasMeter& _gasMeter):
|
||||||
attrBuilder.addAttribute(llvm::Attribute::NoAlias).addAttribute(llvm::Attribute::NoCapture).addAttribute(llvm::Attribute::NonNull).addAttribute(llvm::Attribute::ReadOnly);
|
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_resize->setAttributes(llvm::AttributeSet::get(m_resize->getContext(), 1, attrBuilder));
|
||||||
|
|
||||||
m_require = createRequireFunc(_gasMeter, _runtimeManager);
|
m_require = createRequireFunc(_gasMeter);
|
||||||
m_loadWord = createFunc(false, Type::Word, _gasMeter);
|
m_loadWord = createFunc(false, Type::Word, _gasMeter);
|
||||||
m_storeWord = createFunc(true, Type::Word, _gasMeter);
|
m_storeWord = createFunc(true, Type::Word, _gasMeter);
|
||||||
m_storeByte = createFunc(true, Type::Byte, _gasMeter);
|
m_storeByte = createFunc(true, Type::Byte, _gasMeter);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Function* Memory::createRequireFunc(GasMeter& _gasMeter, RuntimeManager& _runtimeManager)
|
llvm::Function* Memory::createRequireFunc(GasMeter& _gasMeter)
|
||||||
{
|
{
|
||||||
llvm::Type* argTypes[] = {Type::Word, Type::Word};
|
llvm::Type* argTypes[] = {Type::RuntimePtr, Type::Word, Type::Word};
|
||||||
auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::PrivateLinkage, "mem.require", getModule());
|
auto func = llvm::Function::Create(llvm::FunctionType::get(Type::Void, argTypes, false), llvm::Function::PrivateLinkage, "mem.require", getModule());
|
||||||
auto offset = func->arg_begin();
|
auto rt = func->arg_begin();
|
||||||
|
rt->setName("rt");
|
||||||
|
auto offset = rt->getNextNode();
|
||||||
offset->setName("offset");
|
offset->setName("offset");
|
||||||
auto size = offset->getNextNode();
|
auto size = offset->getNextNode();
|
||||||
size->setName("size");
|
size->setName("size");
|
||||||
|
|
@ -98,7 +100,7 @@ llvm::Function* Memory::createRequireFunc(GasMeter& _gasMeter, RuntimeManager& _
|
||||||
_gasMeter.countMemory(newWords);
|
_gasMeter.countMemory(newWords);
|
||||||
// Resize
|
// Resize
|
||||||
m_builder.CreateStore(sizeRequired, m_size);
|
m_builder.CreateStore(sizeRequired, m_size);
|
||||||
auto newData = m_builder.CreateCall2(m_resize, _runtimeManager.getRuntimePtr(), m_size, "newData");
|
auto newData = m_builder.CreateCall2(m_resize, rt, m_size, "newData");
|
||||||
m_builder.CreateStore(newData, m_data);
|
m_builder.CreateStore(newData, m_data);
|
||||||
m_builder.CreateBr(returnBB);
|
m_builder.CreateBr(returnBB);
|
||||||
|
|
||||||
|
|
@ -112,15 +114,18 @@ llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType, GasMet
|
||||||
{
|
{
|
||||||
auto isWord = _valueType == Type::Word;
|
auto isWord = _valueType == Type::Word;
|
||||||
|
|
||||||
llvm::Type* storeArgs[] = {Type::Word, _valueType};
|
llvm::Type* storeArgs[] = {Type::RuntimePtr, Type::Word, _valueType};
|
||||||
|
llvm::Type* loadArgs[] = {Type::RuntimePtr, Type::Word};
|
||||||
auto name = _isStore ? isWord ? "mstore" : "mstore8" : "mload";
|
auto name = _isStore ? isWord ? "mstore" : "mstore8" : "mload";
|
||||||
auto funcType = _isStore ? llvm::FunctionType::get(Type::Void, storeArgs, false) : llvm::FunctionType::get(Type::Word, Type::Word, false);
|
auto funcType = _isStore ? llvm::FunctionType::get(Type::Void, storeArgs, false) : llvm::FunctionType::get(Type::Word, loadArgs, false);
|
||||||
auto func = llvm::Function::Create(funcType, llvm::Function::PrivateLinkage, name, getModule());
|
auto func = llvm::Function::Create(funcType, llvm::Function::PrivateLinkage, name, getModule());
|
||||||
|
|
||||||
InsertPointGuard guard(m_builder); // Restores insert point at function exit
|
InsertPointGuard guard(m_builder); // Restores insert point at function exit
|
||||||
|
|
||||||
m_builder.SetInsertPoint(llvm::BasicBlock::Create(func->getContext(), {}, func));
|
m_builder.SetInsertPoint(llvm::BasicBlock::Create(func->getContext(), {}, func));
|
||||||
llvm::Value* index = func->arg_begin();
|
auto rt = func->arg_begin();
|
||||||
|
rt->setName("rt");
|
||||||
|
auto index = rt->getNextNode();
|
||||||
index->setName("index");
|
index->setName("index");
|
||||||
|
|
||||||
auto valueSize = _valueType->getPrimitiveSizeInBits() / 8;
|
auto valueSize = _valueType->getPrimitiveSizeInBits() / 8;
|
||||||
|
|
@ -130,7 +135,7 @@ llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType, GasMet
|
||||||
ptr = m_builder.CreateBitCast(ptr, Type::WordPtr, "wordPtr");
|
ptr = m_builder.CreateBitCast(ptr, Type::WordPtr, "wordPtr");
|
||||||
if (_isStore)
|
if (_isStore)
|
||||||
{
|
{
|
||||||
llvm::Value* value = ++func->arg_begin();
|
llvm::Value* value = index->getNextNode();
|
||||||
value->setName("value");
|
value->setName("value");
|
||||||
if (isWord)
|
if (isWord)
|
||||||
value = Endianness::toBE(m_builder, value);
|
value = Endianness::toBE(m_builder, value);
|
||||||
|
|
@ -150,19 +155,18 @@ llvm::Function* Memory::createFunc(bool _isStore, llvm::Type* _valueType, GasMet
|
||||||
|
|
||||||
llvm::Value* Memory::loadWord(llvm::Value* _addr)
|
llvm::Value* Memory::loadWord(llvm::Value* _addr)
|
||||||
{
|
{
|
||||||
auto value = m_builder.CreateCall(m_loadWord, _addr);
|
return createCall(m_loadWord, getRuntimeManager().getRuntimePtr(), _addr);
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::storeWord(llvm::Value* _addr, llvm::Value* _word)
|
void Memory::storeWord(llvm::Value* _addr, llvm::Value* _word)
|
||||||
{
|
{
|
||||||
m_builder.CreateCall2(m_storeWord, _addr, _word);
|
createCall(m_storeWord, getRuntimeManager().getRuntimePtr(), _addr, _word);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::storeByte(llvm::Value* _addr, llvm::Value* _word)
|
void Memory::storeByte(llvm::Value* _addr, llvm::Value* _word)
|
||||||
{
|
{
|
||||||
auto byte = m_builder.CreateTrunc(_word, Type::Byte, "byte");
|
auto byte = m_builder.CreateTrunc(_word, Type::Byte, "byte");
|
||||||
m_builder.CreateCall2(m_storeByte, _addr, byte);
|
createCall(m_storeByte, getRuntimeManager().getRuntimePtr(), _addr, byte);
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value* Memory::getData()
|
llvm::Value* Memory::getData()
|
||||||
|
|
@ -183,7 +187,7 @@ llvm::Value* Memory::getBytePtr(llvm::Value* _index)
|
||||||
|
|
||||||
void Memory::require(llvm::Value* _offset, llvm::Value* _size)
|
void Memory::require(llvm::Value* _offset, llvm::Value* _size)
|
||||||
{
|
{
|
||||||
m_builder.CreateCall2(m_require, _offset, _size);
|
createCall(m_require, getRuntimeManager().getRuntimePtr(), _offset, _size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Memory::copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value* _srcIdx,
|
void Memory::copyBytes(llvm::Value* _srcPtr, llvm::Value* _srcSize, llvm::Value* _srcIdx,
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ private:
|
||||||
GasMeter& m_gasMeter;
|
GasMeter& m_gasMeter;
|
||||||
|
|
||||||
llvm::Function* createFunc(bool _isStore, llvm::Type* _type, GasMeter& _gasMeter);
|
llvm::Function* createFunc(bool _isStore, llvm::Type* _type, GasMeter& _gasMeter);
|
||||||
llvm::Function* createRequireFunc(GasMeter& _gasMeter, RuntimeManager& _runtimeManager);
|
llvm::Function* createRequireFunc(GasMeter& _gasMeter);
|
||||||
|
|
||||||
llvm::GlobalVariable* m_data;
|
llvm::GlobalVariable* m_data;
|
||||||
llvm::GlobalVariable* m_size;
|
llvm::GlobalVariable* m_size;
|
||||||
|
|
|
||||||
|
|
@ -74,43 +74,38 @@ llvm::Twine getName(RuntimeData::Index _index)
|
||||||
|
|
||||||
RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder): CompilerHelper(_builder)
|
RuntimeManager::RuntimeManager(llvm::IRBuilder<>& _builder): CompilerHelper(_builder)
|
||||||
{
|
{
|
||||||
m_rtPtr = new llvm::GlobalVariable(*getModule(), Type::RuntimePtr, false, llvm::GlobalVariable::PrivateLinkage, llvm::UndefValue::get(Type::RuntimePtr), "rt");
|
|
||||||
m_dataPtr = new llvm::GlobalVariable(*getModule(), Type::RuntimeDataPtr, false, llvm::GlobalVariable::PrivateLinkage, llvm::UndefValue::get(Type::RuntimeDataPtr), "data");
|
|
||||||
m_longjmp = llvm::Intrinsic::getDeclaration(getModule(), llvm::Intrinsic::longjmp);
|
m_longjmp = llvm::Intrinsic::getDeclaration(getModule(), llvm::Intrinsic::longjmp);
|
||||||
|
|
||||||
// Export data
|
// Unpack data
|
||||||
auto mainFunc = getMainFunction();
|
auto rtPtr = getRuntimePtr();
|
||||||
llvm::Value* rtPtr = &mainFunc->getArgumentList().front();
|
m_dataPtr = m_builder.CreateLoad(m_builder.CreateStructGEP(rtPtr, 0), "data");
|
||||||
m_builder.CreateStore(rtPtr, m_rtPtr);
|
assert(m_dataPtr->getType() == Type::RuntimeDataPtr);
|
||||||
auto dataPtr = m_builder.CreateStructGEP(rtPtr, 0, "dataPtr");
|
m_envPtr = m_builder.CreateLoad(m_builder.CreateStructGEP(rtPtr, 1), "env");
|
||||||
auto data = m_builder.CreateLoad(dataPtr, "data");
|
assert(m_envPtr->getType() == Type::EnvPtr);
|
||||||
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()
|
llvm::Value* RuntimeManager::getRuntimePtr()
|
||||||
{
|
{
|
||||||
// FIXME: Data ptr
|
// Expect first argument of a function to be a pointer to Runtime
|
||||||
//if (auto mainFunc = getMainFunction())
|
auto func = m_builder.GetInsertBlock()->getParent();
|
||||||
// return mainFunc->arg_begin(); // Runtime is the parameter of main function
|
auto rtPtr = &func->getArgumentList().front();
|
||||||
return m_builder.CreateLoad(m_rtPtr, "rt");
|
assert(rtPtr->getType() == Type::RuntimePtr);
|
||||||
|
return rtPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value* RuntimeManager::getDataPtr()
|
llvm::Value* RuntimeManager::getDataPtr()
|
||||||
{
|
{
|
||||||
// FIXME: Data ptr
|
if (getMainFunction())
|
||||||
//if (auto mainFunc = getMainFunction())
|
return m_dataPtr;
|
||||||
// return mainFunc->arg_begin(); // Runtime is the parameter of main function
|
|
||||||
return m_builder.CreateLoad(m_dataPtr, "data");
|
auto rtPtr = getRuntimePtr();
|
||||||
|
return m_builder.CreateLoad(m_builder.CreateStructGEP(rtPtr, 0), "data");
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value* RuntimeManager::getEnv()
|
llvm::Value* RuntimeManager::getEnvPtr()
|
||||||
{
|
{
|
||||||
assert(getMainFunction()); // Available only in main function
|
assert(getMainFunction()); // Available only in main function
|
||||||
return m_env;
|
return m_envPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Value* RuntimeManager::getPtr(RuntimeData::Index _index)
|
llvm::Value* RuntimeManager::getPtr(RuntimeData::Index _index)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ public:
|
||||||
|
|
||||||
llvm::Value* getRuntimePtr();
|
llvm::Value* getRuntimePtr();
|
||||||
llvm::Value* getDataPtr();
|
llvm::Value* getDataPtr();
|
||||||
llvm::Value* getEnv();
|
llvm::Value* getEnvPtr(); // TODO: Can we make it const?
|
||||||
|
|
||||||
llvm::Value* get(RuntimeData::Index _index);
|
llvm::Value* get(RuntimeData::Index _index);
|
||||||
llvm::Value* get(Instruction _inst);
|
llvm::Value* get(Instruction _inst);
|
||||||
|
|
@ -40,10 +40,9 @@ private:
|
||||||
void set(RuntimeData::Index _index, llvm::Value* _value);
|
void set(RuntimeData::Index _index, llvm::Value* _value);
|
||||||
llvm::Value* getJmpBuf();
|
llvm::Value* getJmpBuf();
|
||||||
|
|
||||||
llvm::GlobalVariable* m_rtPtr = nullptr;
|
|
||||||
llvm::GlobalVariable* m_dataPtr = nullptr;
|
|
||||||
llvm::Function* m_longjmp = nullptr;
|
llvm::Function* m_longjmp = nullptr;
|
||||||
llvm::Value* m_env = nullptr;
|
llvm::Value* m_dataPtr = nullptr;
|
||||||
|
llvm::Value* m_envPtr = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue