diff --git a/libevmjit-cpp/JitVM.cpp b/libevmjit-cpp/JitVM.cpp index c8ee74899..719e2120c 100644 --- a/libevmjit-cpp/JitVM.cpp +++ b/libevmjit-cpp/JitVM.cpp @@ -16,14 +16,18 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const&, uint64_t) if (m_gas > std::numeric_limits::max()) BOOST_THROW_EXCEPTION(OutOfGas()); // Do not accept requests with gas > 2^63 (int64 max) + if (_ext.currentBlock.number > std::numeric_limits::max()) + BOOST_THROW_EXCEPTION(OutOfGas()); + + if (_ext.currentBlock.timestamp > std::numeric_limits::max()) + BOOST_THROW_EXCEPTION(OutOfGas()); + m_data.elems[RuntimeData::Address] = eth2llvm(fromAddress(_ext.myAddress)); m_data.elems[RuntimeData::Caller] = eth2llvm(fromAddress(_ext.caller)); m_data.elems[RuntimeData::Origin] = eth2llvm(fromAddress(_ext.origin)); m_data.elems[RuntimeData::CallValue] = eth2llvm(_ext.value); m_data.elems[RuntimeData::GasPrice] = eth2llvm(_ext.gasPrice); m_data.elems[RuntimeData::CoinBase] = eth2llvm(fromAddress(_ext.currentBlock.coinbaseAddress)); - m_data.elems[RuntimeData::TimeStamp] = eth2llvm(_ext.currentBlock.timestamp); - m_data.elems[RuntimeData::Number] = eth2llvm(_ext.currentBlock.number); m_data.elems[RuntimeData::Difficulty] = eth2llvm(_ext.currentBlock.difficulty); m_data.elems[RuntimeData::GasLimit] = eth2llvm(_ext.currentBlock.gasLimit); m_data.callData = _ext.data.data(); @@ -31,6 +35,8 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const&, uint64_t) m_data.codeSize = _ext.code.size(); m_data.callDataSize = _ext.data.size(); m_data.gas = static_cast(m_gas); + m_data.blockNumber = static_cast(_ext.currentBlock.number); + m_data.blockTimestamp = static_cast(_ext.currentBlock.timestamp); auto env = reinterpret_cast(&_ext); auto exitCode = m_engine.run(_ext.code, &m_data, env); diff --git a/libevmjit/Compiler.cpp b/libevmjit/Compiler.cpp index beac37815..d109cadfc 100644 --- a/libevmjit/Compiler.cpp +++ b/libevmjit/Compiler.cpp @@ -639,8 +639,6 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode case Instruction::CALLVALUE: case Instruction::GASPRICE: case Instruction::COINBASE: - case Instruction::TIMESTAMP: - case Instruction::NUMBER: case Instruction::DIFFICULTY: case Instruction::GASLIMIT: { @@ -658,6 +656,14 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode stack.push(_runtimeManager.getCallDataSize()); break; + case Instruction::NUMBER: + stack.push(_runtimeManager.getBlockNumber()); + break; + + case Instruction::TIMESTAMP: + stack.push(_runtimeManager.getBlockTimestamp()); + break; + case Instruction::BLOCKHASH: { auto number = stack.pop(); diff --git a/libevmjit/RuntimeData.h b/libevmjit/RuntimeData.h index 7c33b1ec6..6b07fbe84 100644 --- a/libevmjit/RuntimeData.h +++ b/libevmjit/RuntimeData.h @@ -20,8 +20,6 @@ struct RuntimeData CallValue, GasPrice, CoinBase, - TimeStamp, - Number, Difficulty, GasLimit, @@ -36,6 +34,8 @@ struct RuntimeData 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 diff --git a/libevmjit/RuntimeManager.cpp b/libevmjit/RuntimeManager.cpp index c979c793e..24583440e 100644 --- a/libevmjit/RuntimeManager.cpp +++ b/libevmjit/RuntimeManager.cpp @@ -28,6 +28,8 @@ llvm::StructType* RuntimeManager::getRuntimeDataType() Type::Size, // codeSize Type::Size, // callDataSize Type::Size, // gas + Type::Size, // blockNumber + Type::Size, // blockTimestamp }; type = llvm::StructType::create(elems, "RuntimeData"); } @@ -65,8 +67,6 @@ llvm::Twine getName(RuntimeData::Index _index) case RuntimeData::CallValue: return "callvalue"; case RuntimeData::GasPrice: return "gasprice"; case RuntimeData::CoinBase: return "coinbase"; - case RuntimeData::TimeStamp: return "timestamp"; - case RuntimeData::Number: return "number"; case RuntimeData::Difficulty: return "difficulty"; case RuntimeData::GasLimit: return "gaslimit"; } @@ -161,8 +161,6 @@ llvm::Value* RuntimeManager::get(Instruction _inst) case Instruction::CALLVALUE: return get(RuntimeData::CallValue); case Instruction::GASPRICE: return get(RuntimeData::GasPrice); case Instruction::COINBASE: return get(RuntimeData::CoinBase); - case Instruction::TIMESTAMP: return get(RuntimeData::TimeStamp); - case Instruction::NUMBER: return get(RuntimeData::Number); case Instruction::DIFFICULTY: return get(RuntimeData::Difficulty); case Instruction::GASLIMIT: return get(RuntimeData::GasLimit); } @@ -196,6 +194,22 @@ llvm::Value* RuntimeManager::getCallDataSize() return getBuilder().CreateZExt(value, Type::Word); } +llvm::Value* RuntimeManager::getBlockNumber() +{ + auto ptr = getBuilder().CreateStructGEP(getDataPtr(), 6); + auto value = getBuilder().CreateLoad(ptr, "number"); + assert(value->getType() == Type::Size); + return getBuilder().CreateZExt(value, Type::Word); +} + +llvm::Value* RuntimeManager::getBlockTimestamp() +{ + auto ptr = getBuilder().CreateStructGEP(getDataPtr(), 7); + auto value = getBuilder().CreateLoad(ptr, "timestamp"); + assert(value->getType() == Type::Size); + return getBuilder().CreateZExt(value, Type::Word); +} + llvm::Value* RuntimeManager::getJmpBuf() { auto ptr = getBuilder().CreateStructGEP(getRuntimePtr(), 2, "jmpbufPtr"); diff --git a/libevmjit/RuntimeManager.h b/libevmjit/RuntimeManager.h index b5f3ca657..5e2eb7550 100644 --- a/libevmjit/RuntimeManager.h +++ b/libevmjit/RuntimeManager.h @@ -28,6 +28,8 @@ public: llvm::Value* getCode(); llvm::Value* getCodeSize(); llvm::Value* getCallDataSize(); + llvm::Value* getBlockNumber(); + llvm::Value* getBlockTimestamp(); void setGas(llvm::Value* _gas); void registerReturnData(llvm::Value* _index, llvm::Value* _size);