diff --git a/evmjit/libevmjit-cpp/JitVM.cpp b/evmjit/libevmjit-cpp/JitVM.cpp index f92b114df..08113122b 100644 --- a/evmjit/libevmjit-cpp/JitVM.cpp +++ b/evmjit/libevmjit-cpp/JitVM.cpp @@ -2,6 +2,7 @@ #include "JitVM.h" #include #include +#include #include #include "Utils.h" @@ -45,6 +46,7 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _step) m_data.timestamp = static_cast(_ext.currentBlock.timestamp); m_data.code = _ext.code.data(); m_data.codeSize = _ext.code.size(); + m_data.codeHash = eth2llvm(sha3(_ext.code)); auto env = reinterpret_cast(&_ext); auto exitCode = m_engine.run(&m_data, env); diff --git a/evmjit/libevmjit/ExecutionEngine.cpp b/evmjit/libevmjit/ExecutionEngine.cpp index 653e0d9d0..69cf28afd 100644 --- a/evmjit/libevmjit/ExecutionEngine.cpp +++ b/evmjit/libevmjit/ExecutionEngine.cpp @@ -20,6 +20,8 @@ #include "Compiler.h" #include "Cache.h" +#include + namespace dev { namespace eth @@ -46,19 +48,20 @@ ReturnCode runEntryFunc(EntryFuncPtr _mainFunc, Runtime* _runtime) return returnCode; } -std::string codeHash(code_iterator _begin, code_iterator _end) +std::string codeHash(i256 const& _hash) { - uint32_t hash = 0; - std::for_each(_begin, _end, [&hash](decltype(*_begin) b) + static const auto size = sizeof(_hash); + static const auto hexChars = "0123456789abcdef"; + std::string str; + str.resize(size * 2); + auto outIt = str.rbegin(); // reverse for BE + auto& arr = *(std::array*)&_hash; + for (auto b : arr) { - hash += b; - hash += (hash << 10); - hash ^= (hash >> 6); - }); - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - return std::to_string(hash); + *(outIt++) = hexChars[b & 0xf]; + *(outIt++) = hexChars[b >> 4]; + } + return str; } bool getEnvOption(char const* _name, bool _default) @@ -80,7 +83,7 @@ ReturnCode ExecutionEngine::run(RuntimeData* _data, Env* _env) auto codeBegin = _data->code; auto codeEnd = codeBegin + _data->codeSize; assert(codeBegin || !codeEnd); //TODO: Is it good idea to execute empty code? - auto mainFuncName = codeHash(codeBegin, codeEnd); + auto mainFuncName = codeHash(_data->codeHash); EntryFuncPtr entryFuncPtr{}; Runtime runtime(_data, _env); // TODO: I don't know why but it must be created before getFunctionAddress() calls diff --git a/evmjit/libevmjit/RuntimeData.h b/evmjit/libevmjit/RuntimeData.h index 58d68db8a..ff6e82fe8 100644 --- a/evmjit/libevmjit/RuntimeData.h +++ b/evmjit/libevmjit/RuntimeData.h @@ -50,6 +50,7 @@ struct RuntimeData int64_t timestamp = 0; byte const* code = nullptr; uint64_t codeSize = 0; + i256 codeHash; }; /// VM Environment (ExtVM) opaque type