Browse Source

Add code hash to RuntimeData. JIT is using it as an code identifier (do not need to invent any internal hashing)

cl-refactor
Paweł Bylica 10 years ago
parent
commit
b999cc28c4
  1. 2
      evmjit/libevmjit-cpp/JitVM.cpp
  2. 27
      evmjit/libevmjit/ExecutionEngine.cpp
  3. 1
      evmjit/libevmjit/RuntimeData.h

2
evmjit/libevmjit-cpp/JitVM.cpp

@ -2,6 +2,7 @@
#include "JitVM.h"
#include <libevm/VM.h>
#include <libevm/VMFactory.h>
#include <libdevcrypto/SHA3.h>
#include <evmjit/libevmjit/ExecutionEngine.h>
#include "Utils.h"
@ -45,6 +46,7 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _step)
m_data.timestamp = static_cast<decltype(m_data.timestamp)>(_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<Env*>(&_ext);
auto exitCode = m_engine.run(&m_data, env);

27
evmjit/libevmjit/ExecutionEngine.cpp

@ -20,6 +20,8 @@
#include "Compiler.h"
#include "Cache.h"
#include <iostream>
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<byte, size>*)&_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

1
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

Loading…
Cancel
Save