Browse Source

Reorder JIT runtime data fields

cl-refactor
Paweł Bylica 10 years ago
parent
commit
8b45198bc5
  1. 26
      evmjit/libevmjit-cpp/JitVM.cpp
  2. 14
      evmjit/libevmjit/Compiler.cpp
  3. 38
      evmjit/libevmjit/RuntimeData.h
  4. 40
      evmjit/libevmjit/RuntimeManager.cpp
  5. 2
      evmjit/libevmjit/RuntimeManager.h

26
evmjit/libevmjit-cpp/JitVM.cpp

@ -14,29 +14,33 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const&, uint64_t)
using namespace jit; using namespace jit;
if (m_gas > std::numeric_limits<decltype(m_data.gas)>::max()) if (m_gas > std::numeric_limits<decltype(m_data.gas)>::max())
BOOST_THROW_EXCEPTION(OutOfGas()); // Do not accept requests with gas > 2^63 (int64 max) BOOST_THROW_EXCEPTION(OutOfGas()); // Do not accept requests with gas > 2^63 (int64 max) // TODO: Return "not accepted" exception to allow interpreted handle that
if (_ext.currentBlock.number > std::numeric_limits<decltype(m_data.blockNumber)>::max()) if (_ext.gasPrice > std::numeric_limits<decltype(m_data.gasPrice)>::max())
BOOST_THROW_EXCEPTION(OutOfGas()); BOOST_THROW_EXCEPTION(OutOfGas());
if (_ext.currentBlock.timestamp > std::numeric_limits<decltype(m_data.blockTimestamp)>::max()) if (_ext.currentBlock.number > std::numeric_limits<decltype(m_data.number)>::max())
BOOST_THROW_EXCEPTION(OutOfGas()); BOOST_THROW_EXCEPTION(OutOfGas());
if (_ext.currentBlock.timestamp > std::numeric_limits<decltype(m_data.timestamp)>::max())
BOOST_THROW_EXCEPTION(OutOfGas());
m_data.gas = static_cast<decltype(m_data.gas)>(m_gas);
m_data.gasPrice = static_cast<decltype(m_data.gasPrice)>(_ext.gasPrice);
m_data.callData = _ext.data.data();
m_data.callDataSize = _ext.data.size();
m_data.address = eth2llvm(fromAddress(_ext.myAddress)); m_data.address = eth2llvm(fromAddress(_ext.myAddress));
m_data.caller = eth2llvm(fromAddress(_ext.caller)); m_data.caller = eth2llvm(fromAddress(_ext.caller));
m_data.origin = eth2llvm(fromAddress(_ext.origin)); m_data.origin = eth2llvm(fromAddress(_ext.origin));
m_data.callValue = eth2llvm(_ext.value); m_data.callValue = eth2llvm(_ext.value);
m_data.gasPrice = eth2llvm(_ext.gasPrice);
m_data.coinBase = eth2llvm(fromAddress(_ext.currentBlock.coinbaseAddress)); m_data.coinBase = eth2llvm(fromAddress(_ext.currentBlock.coinbaseAddress));
m_data.difficulty = eth2llvm(_ext.currentBlock.difficulty); m_data.difficulty = eth2llvm(_ext.currentBlock.difficulty);
m_data.gasLimit = eth2llvm(_ext.currentBlock.gasLimit); m_data.gasLimit = eth2llvm(_ext.currentBlock.gasLimit);
m_data.callData = _ext.data.data(); m_data.number = static_cast<decltype(m_data.number)>(_ext.currentBlock.number);
m_data.code = _ext.code.data(); m_data.timestamp = static_cast<decltype(m_data.timestamp)>(_ext.currentBlock.timestamp);
m_data.codeSize = _ext.code.size(); m_data.code = _ext.code.data();
m_data.callDataSize = _ext.data.size(); m_data.codeSize = _ext.code.size();
m_data.gas = static_cast<decltype(m_data.gas)>(m_gas);
m_data.blockNumber = static_cast<decltype(m_data.blockNumber)>(_ext.currentBlock.number);
m_data.blockTimestamp = static_cast<decltype(m_data.blockTimestamp)>(_ext.currentBlock.timestamp);
auto env = reinterpret_cast<Env*>(&_ext); auto env = reinterpret_cast<Env*>(&_ext);
auto exitCode = m_engine.run(_ext.code, &m_data, env); auto exitCode = m_engine.run(_ext.code, &m_data, env);

14
evmjit/libevmjit/Compiler.cpp

@ -641,9 +641,13 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode
case Instruction::COINBASE: case Instruction::COINBASE:
case Instruction::DIFFICULTY: case Instruction::DIFFICULTY:
case Instruction::GASLIMIT: case Instruction::GASLIMIT:
case Instruction::NUMBER:
case Instruction::TIMESTAMP:
{ {
// Pushes an element of runtime data on stack // Pushes an element of runtime data on stack
stack.push(_runtimeManager.get(inst)); auto value = _runtimeManager.get(inst);
value = m_builder.CreateZExt(value, Type::Word);
stack.push(value);
break; break;
} }
@ -656,14 +660,6 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode
stack.push(_runtimeManager.getCallDataSize()); stack.push(_runtimeManager.getCallDataSize());
break; break;
case Instruction::NUMBER:
stack.push(_runtimeManager.getBlockNumber());
break;
case Instruction::TIMESTAMP:
stack.push(_runtimeManager.getBlockTimestamp());
break;
case Instruction::BLOCKHASH: case Instruction::BLOCKHASH:
{ {
auto number = stack.pop(); auto number = stack.pop();

38
evmjit/libevmjit/RuntimeData.h

@ -14,42 +14,42 @@ struct RuntimeData
{ {
enum Index enum Index
{ {
Gas,
GasPrice,
CallData,
CallDataSize,
Address, Address,
Caller, Caller,
Origin, Origin,
CallValue, CallValue,
GasPrice,
CoinBase, CoinBase,
Difficulty, Difficulty,
GasLimit, GasLimit,
CallData, Number,
Timestamp,
Code, Code,
CodeSize, CodeSize,
CallDataSize,
Gas,
BlockNumber,
BlockTimestamp,
SuicideDestAddress = Address, ///< Suicide balance destination address SuicideDestAddress = Address, ///< Suicide balance destination address
ReturnData = CallData, ///< Return data pointer (set only in case of RETURN) ReturnData = CallData, ///< Return data pointer (set only in case of RETURN)
ReturnDataSize = CallDataSize, ///< Return data size (set only in case of RETURN) ReturnDataSize = CallDataSize, ///< Return data size (set only in case of RETURN)
}; };
i256 address; int64_t gas = 0;
i256 caller; int64_t gasPrice = 0;
i256 origin;
i256 callValue;
i256 gasPrice;
i256 coinBase;
i256 difficulty;
i256 gasLimit;
byte const* callData = nullptr; byte const* callData = nullptr;
uint64_t callDataSize = 0;
i256 address;
i256 caller;
i256 origin;
i256 callValue;
i256 coinBase;
i256 difficulty;
i256 gasLimit;
uint64_t number = 0;
uint64_t timestamp = 0;
byte const* code = nullptr; byte const* code = nullptr;
uint64_t codeSize = 0; uint64_t codeSize = 0;
uint64_t callDataSize = 0;
int64_t gas = 0;
uint64_t blockNumber = 0;
uint64_t blockTimestamp = 0;
}; };
/// VM Environment (ExtVM) opaque type /// VM Environment (ExtVM) opaque type

40
evmjit/libevmjit/RuntimeManager.cpp

@ -22,21 +22,21 @@ llvm::StructType* RuntimeManager::getRuntimeDataType()
{ {
llvm::Type* elems[] = llvm::Type* elems[] =
{ {
Type::Size, // gas
Type::Size, // gasPrice
Type::BytePtr, // callData
Type::Size, // callDataSize
Type::Word, // address Type::Word, // address
Type::Word, // caller Type::Word, // caller
Type::Word, // origin Type::Word, // origin
Type::Word, // address Type::Word, // callValue
Type::Word, // address Type::Word, // coinBase
Type::Word, // address Type::Word, // difficulty
Type::Word, // address Type::Word, // gasLimit
Type::Word, // address
Type::BytePtr, // callData
Type::BytePtr, // code
Type::Size, // codeSize
Type::Size, // callDataSize
Type::Size, // gas
Type::Size, // blockNumber Type::Size, // blockNumber
Type::Size, // blockTimestamp Type::Size, // blockTimestamp
Type::BytePtr, // code
Type::Size, // codeSize
}; };
type = llvm::StructType::create(elems, "RuntimeData"); type = llvm::StructType::create(elems, "RuntimeData");
} }
@ -81,8 +81,8 @@ llvm::Twine getName(RuntimeData::Index _index)
case RuntimeData::CodeSize: return "code"; case RuntimeData::CodeSize: return "code";
case RuntimeData::CallDataSize: return "callDataSize"; case RuntimeData::CallDataSize: return "callDataSize";
case RuntimeData::Gas: return "gas"; case RuntimeData::Gas: return "gas";
case RuntimeData::BlockNumber: return "number"; case RuntimeData::Number: return "number";
case RuntimeData::BlockTimestamp: return "timestamp"; case RuntimeData::Timestamp: return "timestamp";
} }
} }
} }
@ -178,6 +178,8 @@ llvm::Value* RuntimeManager::get(Instruction _inst)
case Instruction::COINBASE: return get(RuntimeData::CoinBase); case Instruction::COINBASE: return get(RuntimeData::CoinBase);
case Instruction::DIFFICULTY: return get(RuntimeData::Difficulty); case Instruction::DIFFICULTY: return get(RuntimeData::Difficulty);
case Instruction::GASLIMIT: return get(RuntimeData::GasLimit); case Instruction::GASLIMIT: return get(RuntimeData::GasLimit);
case Instruction::NUMBER: return get(RuntimeData::Number);
case Instruction::TIMESTAMP: return get(RuntimeData::Timestamp);
} }
} }
@ -205,20 +207,6 @@ llvm::Value* RuntimeManager::getCallDataSize()
return getBuilder().CreateZExt(value, Type::Word); return getBuilder().CreateZExt(value, Type::Word);
} }
llvm::Value* RuntimeManager::getBlockNumber()
{
auto value = get(RuntimeData::BlockNumber);
assert(value->getType() == Type::Size);
return getBuilder().CreateZExt(value, Type::Word);
}
llvm::Value* RuntimeManager::getBlockTimestamp()
{
auto value = get(RuntimeData::BlockTimestamp);
assert(value->getType() == Type::Size);
return getBuilder().CreateZExt(value, Type::Word);
}
llvm::Value* RuntimeManager::getJmpBuf() llvm::Value* RuntimeManager::getJmpBuf()
{ {
auto ptr = getBuilder().CreateStructGEP(getRuntimePtr(), 2, "jmpbufPtr"); auto ptr = getBuilder().CreateStructGEP(getRuntimePtr(), 2, "jmpbufPtr");

2
evmjit/libevmjit/RuntimeManager.h

@ -28,8 +28,6 @@ public:
llvm::Value* getCode(); llvm::Value* getCode();
llvm::Value* getCodeSize(); llvm::Value* getCodeSize();
llvm::Value* getCallDataSize(); llvm::Value* getCallDataSize();
llvm::Value* getBlockNumber();
llvm::Value* getBlockTimestamp();
void setGas(llvm::Value* _gas); void setGas(llvm::Value* _gas);
void registerReturnData(llvm::Value* _index, llvm::Value* _size); void registerReturnData(llvm::Value* _index, llvm::Value* _size);

Loading…
Cancel
Save