From 7b9d4956a52c2e8794ac44d44bb44c9b561652af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Thu, 8 Jan 2015 11:10:10 +0100 Subject: [PATCH] BLOCKHASH instruction --- libevmjit-cpp/Env.cpp | 5 +++++ libevmjit/Compiler.cpp | 8 ++++++++ libevmjit/Ext.cpp | 9 +++++++++ libevmjit/Ext.h | 2 ++ 4 files changed, 24 insertions(+) diff --git a/libevmjit-cpp/Env.cpp b/libevmjit-cpp/Env.cpp index 4112774eed..9fa15735ef 100644 --- a/libevmjit-cpp/Env.cpp +++ b/libevmjit-cpp/Env.cpp @@ -42,6 +42,11 @@ extern "C" *o_value = eth2llvm(u); } + EXPORT void env_blockhash(ExtVMFace* _env, i256* _number, h256* o_hash) + { + *o_hash = _env->prevhash(llvm2eth(*_number)); + } + EXPORT void env_create(ExtVMFace* _env, i256* io_gas, i256* _endowment, byte* _initBeg, uint64_t _initSize, h256* o_address) { auto endowment = llvm2eth(*_endowment); diff --git a/libevmjit/Compiler.cpp b/libevmjit/Compiler.cpp index 6f256a5712..7733321aaa 100644 --- a/libevmjit/Compiler.cpp +++ b/libevmjit/Compiler.cpp @@ -645,6 +645,14 @@ void Compiler::compileBasicBlock(BasicBlock& _basicBlock, bytes const& _bytecode break; } + case Instruction::BLOCKHASH: + { + auto number = stack.pop(); + auto hash = _ext.blockhash(number); + stack.push(hash); + break; + } + case Instruction::BALANCE: { auto address = stack.pop(); diff --git a/libevmjit/Ext.cpp b/libevmjit/Ext.cpp index f2db32137c..c30b0a1e38 100644 --- a/libevmjit/Ext.cpp +++ b/libevmjit/Ext.cpp @@ -45,6 +45,7 @@ std::array::value> const& getEnvFuncDescs() FuncDesc{"env_create", getFunctionType(Type::Void, {Type::EnvPtr, Type::WordPtr, Type::WordPtr, Type::BytePtr, Type::Size, Type::WordPtr})}, FuncDesc{"env_call", getFunctionType(Type::Bool, {Type::EnvPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::BytePtr, Type::Size, Type::BytePtr, Type::Size, Type::WordPtr})}, FuncDesc{"env_log", getFunctionType(Type::Void, {Type::EnvPtr, Type::BytePtr, Type::Size, Type::WordPtr, Type::WordPtr, Type::WordPtr, Type::WordPtr})}, + FuncDesc{"env_blockhash", getFunctionType(Type::Void, {Type::EnvPtr, Type::WordPtr, Type::WordPtr})}, FuncDesc{"env_getExtCode", getFunctionType(Type::BytePtr, {Type::EnvPtr, Type::WordPtr, Type::Size->getPointerTo()})}, FuncDesc{"ext_calldataload", getFunctionType(Type::Void, {Type::RuntimeDataPtr, Type::WordPtr, Type::WordPtr})}, }}; @@ -117,6 +118,14 @@ llvm::Value* Ext::balance(llvm::Value* _address) return m_builder.CreateLoad(ret); } +llvm::Value* Ext::blockhash(llvm::Value* _number) +{ + auto hash = getArgAlloca(); + createCall(EnvFunc::blockhash, {getRuntimeManager().getEnvPtr(), byPtr(_number), hash}); + hash = m_builder.CreateLoad(hash); + return Endianness::toNative(getBuilder(), hash); +} + llvm::Value* Ext::create(llvm::Value*& _gas, llvm::Value* _endowment, llvm::Value* _initOff, llvm::Value* _initSize) { auto gas = byPtr(_gas); diff --git a/libevmjit/Ext.h b/libevmjit/Ext.h index 9a9b3548ac..2850be072b 100644 --- a/libevmjit/Ext.h +++ b/libevmjit/Ext.h @@ -33,6 +33,7 @@ enum class EnvFunc create, call, log, + blockhash, getExtCode, calldataload, // Helper function, not client Env interface @@ -51,6 +52,7 @@ public: llvm::Value* calldataload(llvm::Value* _index); llvm::Value* create(llvm::Value*& _gas, llvm::Value* _endowment, llvm::Value* _initOff, llvm::Value* _initSize); llvm::Value* call(llvm::Value*& _gas, llvm::Value* _receiveAddress, llvm::Value* _value, llvm::Value* _inOff, llvm::Value* _inSize, llvm::Value* _outOff, llvm::Value* _outSize, llvm::Value* _codeAddress); + llvm::Value* blockhash(llvm::Value* _number); llvm::Value* sha3(llvm::Value* _inOff, llvm::Value* _inSize); MemoryRef getExtCode(llvm::Value* _addr);