|
@ -14,6 +14,8 @@ |
|
|
#include "Compiler.h" |
|
|
#include "Compiler.h" |
|
|
#include "Cache.h" |
|
|
#include "Cache.h" |
|
|
|
|
|
|
|
|
|
|
|
extern "C" void env_sha3(dev::eth::jit::byte const* _begin, uint64_t _size, std::array<dev::eth::jit::byte, 32>* o_hash); |
|
|
|
|
|
|
|
|
namespace dev |
|
|
namespace dev |
|
|
{ |
|
|
{ |
|
|
namespace eth |
|
|
namespace eth |
|
@ -39,18 +41,26 @@ ReturnCode runEntryFunc(EntryFuncPtr _mainFunc, Runtime* _runtime) |
|
|
|
|
|
|
|
|
return returnCode; |
|
|
return returnCode; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::string codeHash(bytes const& _code) |
|
|
|
|
|
{ |
|
|
|
|
|
std::array<dev::eth::jit::byte, 32> binHash; |
|
|
|
|
|
env_sha3(_code.data(), _code.size(), &binHash); |
|
|
|
|
|
|
|
|
|
|
|
std::ostringstream os; |
|
|
|
|
|
for (auto i: binHash) |
|
|
|
|
|
os << std::hex << std::setfill('0') << std::setw(2) << (int)(std::make_unsigned<decltype(i)>::type)i; |
|
|
|
|
|
|
|
|
|
|
|
return os.str(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env) |
|
|
ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _env) |
|
|
{ |
|
|
{ |
|
|
static std::unique_ptr<llvm::ExecutionEngine> ee; // TODO: Use Managed Objects from LLVM?
|
|
|
static std::unique_ptr<llvm::ExecutionEngine> ee; // TODO: Use Managed Objects from LLVM?
|
|
|
|
|
|
|
|
|
|
|
|
auto mainFuncName = codeHash(_code); |
|
|
// TODO: Better hash of code needed, probably SHA3
|
|
|
|
|
|
std::string code{reinterpret_cast<char const*>(_code.data()), _code.size()}; |
|
|
|
|
|
auto hash = std::hash<std::string>{}(code); |
|
|
|
|
|
auto mainFuncName = std::to_string(hash); |
|
|
|
|
|
|
|
|
|
|
|
EntryFuncPtr entryFuncPtr{}; |
|
|
EntryFuncPtr entryFuncPtr{}; |
|
|
Runtime runtime(_data, _env); // TODO: I don't know why but it must be created before getFunctionAddress() calls
|
|
|
Runtime runtime(_data, _env); // TODO: I don't know why but it must be created before getFunctionAddress() calls
|
|
|
|
|
|
|
|
@ -60,6 +70,7 @@ ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _en |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
auto module = Compiler({}).compile(_code, mainFuncName); |
|
|
auto module = Compiler({}).compile(_code, mainFuncName); |
|
|
|
|
|
//module->dump();
|
|
|
if (!ee) |
|
|
if (!ee) |
|
|
{ |
|
|
{ |
|
|
llvm::InitializeNativeTarget(); |
|
|
llvm::InitializeNativeTarget(); |
|
@ -70,7 +81,7 @@ ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _en |
|
|
builder.setUseMCJIT(true); |
|
|
builder.setUseMCJIT(true); |
|
|
std::unique_ptr<llvm::SectionMemoryManager> memoryManager(new llvm::SectionMemoryManager); |
|
|
std::unique_ptr<llvm::SectionMemoryManager> memoryManager(new llvm::SectionMemoryManager); |
|
|
builder.setMCJITMemoryManager(memoryManager.get()); |
|
|
builder.setMCJITMemoryManager(memoryManager.get()); |
|
|
builder.setOptLevel(llvm::CodeGenOpt::None); |
|
|
builder.setOptLevel(llvm::CodeGenOpt::Default); |
|
|
|
|
|
|
|
|
auto triple = llvm::Triple(llvm::sys::getProcessTriple()); |
|
|
auto triple = llvm::Triple(llvm::sys::getProcessTriple()); |
|
|
if (triple.getOS() == llvm::Triple::OSType::Win32) |
|
|
if (triple.getOS() == llvm::Triple::OSType::Win32) |
|
@ -84,7 +95,7 @@ ReturnCode ExecutionEngine::run(bytes const& _code, RuntimeData* _data, Env* _en |
|
|
module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module
|
|
|
module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module
|
|
|
memoryManager.release(); // and memory manager
|
|
|
memoryManager.release(); // and memory manager
|
|
|
|
|
|
|
|
|
//ee->setObjectCache(Cache::getObjectCache());
|
|
|
ee->setObjectCache(Cache::getObjectCache()); |
|
|
entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName); |
|
|
entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName); |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|