Browse Source

Flatten JIT RuntimeData

cl-refactor
Paweł Bylica 10 years ago
parent
commit
3e8c30d2fb
  1. 18
      libevmjit-cpp/JitVM.cpp
  2. 24
      libevmjit/RuntimeData.h
  3. 77
      libevmjit/RuntimeManager.cpp

18
libevmjit-cpp/JitVM.cpp

@ -22,14 +22,14 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const&, uint64_t)
if (_ext.currentBlock.timestamp > std::numeric_limits<decltype(m_data.blockTimestamp)>::max()) if (_ext.currentBlock.timestamp > std::numeric_limits<decltype(m_data.blockTimestamp)>::max())
BOOST_THROW_EXCEPTION(OutOfGas()); BOOST_THROW_EXCEPTION(OutOfGas());
m_data.elems[RuntimeData::Address] = eth2llvm(fromAddress(_ext.myAddress)); m_data.address = eth2llvm(fromAddress(_ext.myAddress));
m_data.elems[RuntimeData::Caller] = eth2llvm(fromAddress(_ext.caller)); m_data.caller = eth2llvm(fromAddress(_ext.caller));
m_data.elems[RuntimeData::Origin] = eth2llvm(fromAddress(_ext.origin)); m_data.origin = eth2llvm(fromAddress(_ext.origin));
m_data.elems[RuntimeData::CallValue] = eth2llvm(_ext.value); m_data.callValue = eth2llvm(_ext.value);
m_data.elems[RuntimeData::GasPrice] = eth2llvm(_ext.gasPrice); m_data.gasPrice = eth2llvm(_ext.gasPrice);
m_data.elems[RuntimeData::CoinBase] = eth2llvm(fromAddress(_ext.currentBlock.coinbaseAddress)); m_data.coinBase = eth2llvm(fromAddress(_ext.currentBlock.coinbaseAddress));
m_data.elems[RuntimeData::Difficulty] = eth2llvm(_ext.currentBlock.difficulty); m_data.difficulty = eth2llvm(_ext.currentBlock.difficulty);
m_data.elems[RuntimeData::GasLimit] = eth2llvm(_ext.currentBlock.gasLimit); m_data.gasLimit = eth2llvm(_ext.currentBlock.gasLimit);
m_data.callData = _ext.data.data(); m_data.callData = _ext.data.data();
m_data.code = _ext.code.data(); m_data.code = _ext.code.data();
m_data.codeSize = _ext.code.size(); m_data.codeSize = _ext.code.size();
@ -43,7 +43,7 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const&, uint64_t)
switch (exitCode) switch (exitCode)
{ {
case ReturnCode::Suicide: case ReturnCode::Suicide:
_ext.suicide(right160(llvm2eth(m_data.elems[RuntimeData::SuicideDestAddress]))); _ext.suicide(right160(llvm2eth(m_data.address)));
break; break;
case ReturnCode::BadJumpDestination: case ReturnCode::BadJumpDestination:

24
libevmjit/RuntimeData.h

@ -22,13 +22,27 @@ struct RuntimeData
CoinBase, CoinBase,
Difficulty, Difficulty,
GasLimit, GasLimit,
CallData,
_size, Code,
CodeSize,
SuicideDestAddress = Address, ///< Suicide balance destination address CallDataSize,
Gas,
BlockNumber,
BlockTimestamp,
SuicideDestAddress = Address, ///< Suicide balance destination address
ReturnData = CallData, ///< Return data pointer (set only in case of RETURN)
ReturnDataSize = CallDataSize, ///< Return data size (set only in case of RETURN)
}; };
i256 elems[_size] = {}; i256 address;
i256 caller;
i256 origin;
i256 callValue;
i256 gasPrice;
i256 coinBase;
i256 difficulty;
i256 gasLimit;
byte const* callData = nullptr; byte const* callData = nullptr;
byte const* code = nullptr; byte const* code = nullptr;
uint64_t codeSize = 0; uint64_t codeSize = 0;

77
libevmjit/RuntimeManager.cpp

@ -22,14 +22,21 @@ llvm::StructType* RuntimeManager::getRuntimeDataType()
{ {
llvm::Type* elems[] = llvm::Type* elems[] =
{ {
llvm::ArrayType::get(Type::Word, RuntimeData::_size), // i256[] Type::Word, // address
Type::BytePtr, // callData Type::Word, // caller
Type::BytePtr, // code Type::Word, // origin
Type::Size, // codeSize Type::Word, // address
Type::Size, // callDataSize Type::Word, // address
Type::Size, // gas Type::Word, // address
Type::Size, // blockNumber Type::Word, // address
Type::Size, // blockTimestamp Type::Word, // address
Type::BytePtr, // callData
Type::BytePtr, // code
Type::Size, // codeSize
Type::Size, // callDataSize
Type::Size, // gas
Type::Size, // blockNumber
Type::Size, // blockTimestamp
}; };
type = llvm::StructType::create(elems, "RuntimeData"); type = llvm::StructType::create(elems, "RuntimeData");
} }
@ -69,6 +76,13 @@ llvm::Twine getName(RuntimeData::Index _index)
case RuntimeData::CoinBase: return "coinbase"; case RuntimeData::CoinBase: return "coinbase";
case RuntimeData::Difficulty: return "difficulty"; case RuntimeData::Difficulty: return "difficulty";
case RuntimeData::GasLimit: return "gaslimit"; case RuntimeData::GasLimit: return "gaslimit";
case RuntimeData::CallData: return "callData";
case RuntimeData::Code: return "code";
case RuntimeData::CodeSize: return "code";
case RuntimeData::CallDataSize: return "callDataSize";
case RuntimeData::Gas: return "gas";
case RuntimeData::BlockNumber: return "number";
case RuntimeData::BlockTimestamp: return "timestamp";
} }
} }
} }
@ -100,7 +114,9 @@ llvm::Value* RuntimeManager::getDataPtr()
return m_dataPtr; return m_dataPtr;
auto rtPtr = getRuntimePtr(); auto rtPtr = getRuntimePtr();
return m_builder.CreateLoad(m_builder.CreateStructGEP(rtPtr, 0), "data"); auto dataPtr = m_builder.CreateLoad(m_builder.CreateStructGEP(rtPtr, 0), "data");
assert(dataPtr->getType() == getRuntimeDataType()->getPointerTo());
return dataPtr;
} }
llvm::Value* RuntimeManager::getEnvPtr() llvm::Value* RuntimeManager::getEnvPtr()
@ -111,18 +127,21 @@ llvm::Value* RuntimeManager::getEnvPtr()
llvm::Value* RuntimeManager::getPtr(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)}; auto ptr = getBuilder().CreateStructGEP(getDataPtr(), _index);
return m_builder.CreateInBoundsGEP(getDataPtr(), idxList, getName(_index) + "Ptr"); assert(getRuntimeDataType()->getElementType(_index)->getPointerTo() == ptr->getType());
return ptr;
} }
llvm::Value* RuntimeManager::get(RuntimeData::Index _index) llvm::Value* RuntimeManager::get(RuntimeData::Index _index)
{ {
return m_builder.CreateLoad(getPtr(_index), getName(_index)); return getBuilder().CreateLoad(getPtr(_index), getName(_index));
} }
void RuntimeManager::set(RuntimeData::Index _index, llvm::Value* _value) void RuntimeManager::set(RuntimeData::Index _index, llvm::Value* _value)
{ {
m_builder.CreateStore(_value, getPtr(_index)); auto ptr = getPtr(_index);
assert(ptr->getType() == _value->getType()->getPointerTo());
getBuilder().CreateStore(_value, ptr);
} }
void RuntimeManager::registerReturnData(llvm::Value* _offset, llvm::Value* _size) void RuntimeManager::registerReturnData(llvm::Value* _offset, llvm::Value* _size)
@ -130,14 +149,10 @@ void RuntimeManager::registerReturnData(llvm::Value* _offset, llvm::Value* _size
auto memPtr = getBuilder().CreateStructGEP(getRuntimePtr(), 3); auto memPtr = getBuilder().CreateStructGEP(getRuntimePtr(), 3);
auto mem = getBuilder().CreateLoad(memPtr, "memory"); auto mem = getBuilder().CreateLoad(memPtr, "memory");
auto returnDataPtr = getBuilder().CreateGEP(mem, _offset); auto returnDataPtr = getBuilder().CreateGEP(mem, _offset);
auto callDataPtr = getBuilder().CreateStructGEP(getDataPtr(), 1); set(RuntimeData::ReturnData, returnDataPtr);
getBuilder().CreateStore(returnDataPtr, callDataPtr);
auto ptr = getBuilder().CreateStructGEP(getDataPtr(), 4);
assert(ptr->getType() == Type::Size->getPointerTo());
assert(_size->getType() == Type::Word);
auto size64 = getBuilder().CreateTrunc(_size, Type::Size); auto size64 = getBuilder().CreateTrunc(_size, Type::Size);
getBuilder().CreateStore(size64, ptr); set(RuntimeData::ReturnDataSize, size64);
} }
void RuntimeManager::registerSuicide(llvm::Value* _balanceAddress) void RuntimeManager::registerSuicide(llvm::Value* _balanceAddress)
@ -168,44 +183,38 @@ llvm::Value* RuntimeManager::get(Instruction _inst)
llvm::Value* RuntimeManager::getCallData() llvm::Value* RuntimeManager::getCallData()
{ {
auto ptr = getBuilder().CreateStructGEP(getDataPtr(), 1, "calldataPtr"); return get(RuntimeData::CallData);
return getBuilder().CreateLoad(ptr, "callData");
} }
llvm::Value* RuntimeManager::getCode() llvm::Value* RuntimeManager::getCode()
{ {
auto ptr = getBuilder().CreateStructGEP(getDataPtr(), 2, "codePtr"); return get(RuntimeData::Code);
return getBuilder().CreateLoad(ptr, "code");
} }
llvm::Value* RuntimeManager::getCodeSize() llvm::Value* RuntimeManager::getCodeSize()
{ {
auto ptr = getBuilder().CreateStructGEP(getDataPtr(), 3); auto value = get(RuntimeData::CodeSize);
auto value = getBuilder().CreateLoad(ptr, "codeSize");
assert(value->getType() == Type::Size); assert(value->getType() == Type::Size);
return getBuilder().CreateZExt(value, Type::Word); return getBuilder().CreateZExt(value, Type::Word);
} }
llvm::Value* RuntimeManager::getCallDataSize() llvm::Value* RuntimeManager::getCallDataSize()
{ {
auto ptr = getBuilder().CreateStructGEP(getDataPtr(), 4); auto value = get(RuntimeData::CallDataSize);
auto value = getBuilder().CreateLoad(ptr, "callDataSize");
assert(value->getType() == Type::Size); assert(value->getType() == Type::Size);
return getBuilder().CreateZExt(value, Type::Word); return getBuilder().CreateZExt(value, Type::Word);
} }
llvm::Value* RuntimeManager::getBlockNumber() llvm::Value* RuntimeManager::getBlockNumber()
{ {
auto ptr = getBuilder().CreateStructGEP(getDataPtr(), 6); auto value = get(RuntimeData::BlockNumber);
auto value = getBuilder().CreateLoad(ptr, "number");
assert(value->getType() == Type::Size); assert(value->getType() == Type::Size);
return getBuilder().CreateZExt(value, Type::Word); return getBuilder().CreateZExt(value, Type::Word);
} }
llvm::Value* RuntimeManager::getBlockTimestamp() llvm::Value* RuntimeManager::getBlockTimestamp()
{ {
auto ptr = getBuilder().CreateStructGEP(getDataPtr(), 7); auto value = get(RuntimeData::BlockTimestamp);
auto value = getBuilder().CreateLoad(ptr, "timestamp");
assert(value->getType() == Type::Size); assert(value->getType() == Type::Size);
return getBuilder().CreateZExt(value, Type::Word); return getBuilder().CreateZExt(value, Type::Word);
} }
@ -218,17 +227,15 @@ llvm::Value* RuntimeManager::getJmpBuf()
llvm::Value* RuntimeManager::getGas() llvm::Value* RuntimeManager::getGas()
{ {
auto ptr = getBuilder().CreateStructGEP(getDataPtr(), 5); auto value = get(RuntimeData::Gas);
auto value = getBuilder().CreateLoad(ptr, "gas");
assert(value->getType() == Type::Size); assert(value->getType() == Type::Size);
return getBuilder().CreateZExt(value, Type::Word); return getBuilder().CreateZExt(value, Type::Word);
} }
void RuntimeManager::setGas(llvm::Value* _gas) void RuntimeManager::setGas(llvm::Value* _gas)
{ {
auto ptr = getBuilder().CreateStructGEP(getDataPtr(), 5);
auto newGas = getBuilder().CreateTrunc(_gas, Type::Size); auto newGas = getBuilder().CreateTrunc(_gas, Type::Size);
getBuilder().CreateStore(newGas, ptr); set(RuntimeData::Gas, newGas);
} }
} }

Loading…
Cancel
Save