|
|
@ -1,6 +1,18 @@ |
|
|
|
|
|
|
|
#include "ExecutionEngine.h" |
|
|
|
|
|
|
|
#include <llvm/IR/LLVMContext.h> |
|
|
|
#include <llvm/IR/Module.h> |
|
|
|
#include <llvm/ADT/Triple.h> |
|
|
|
#include <llvm/ExecutionEngine/ExecutionEngine.h> |
|
|
|
#include <llvm/ExecutionEngine/SectionMemoryManager.h> |
|
|
|
#include <llvm/ExecutionEngine/GenericValue.h> |
|
|
|
#include <llvm/ExecutionEngine/MCJIT.h> |
|
|
|
#include <llvm/Support/TargetSelect.h> |
|
|
|
#include <llvm/Support/Signals.h> |
|
|
|
#include <llvm/Support/PrettyStackTrace.h> |
|
|
|
#include <llvm/Support/Host.h> |
|
|
|
|
|
|
|
namespace evmcc |
|
|
|
{ |
|
|
|
|
|
|
@ -10,9 +22,60 @@ ExecutionEngine::ExecutionEngine() |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
int ExecutionEngine::run(const dev::bytes& bytecode) |
|
|
|
int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module) |
|
|
|
{ |
|
|
|
return 0; |
|
|
|
auto module = _module.get(); // Keep ownership of the module in _module
|
|
|
|
|
|
|
|
llvm::sys::PrintStackTraceOnErrorSignal(); |
|
|
|
static const auto program = "evmcc"; |
|
|
|
llvm::PrettyStackTraceProgram X(1, &program); |
|
|
|
|
|
|
|
auto&& context = llvm::getGlobalContext(); |
|
|
|
|
|
|
|
llvm::InitializeNativeTarget(); |
|
|
|
llvm::InitializeNativeTargetAsmPrinter(); |
|
|
|
llvm::InitializeNativeTargetAsmParser(); |
|
|
|
|
|
|
|
std::string errorMsg; |
|
|
|
llvm::EngineBuilder builder(module); |
|
|
|
//builder.setMArch(MArch);
|
|
|
|
//builder.setMCPU(MCPU);
|
|
|
|
//builder.setMAttrs(MAttrs);
|
|
|
|
//builder.setRelocationModel(RelocModel);
|
|
|
|
//builder.setCodeModel(CMModel);
|
|
|
|
builder.setErrorStr(&errorMsg); |
|
|
|
builder.setEngineKind(llvm::EngineKind::JIT); |
|
|
|
builder.setUseMCJIT(true); |
|
|
|
builder.setMCJITMemoryManager(new llvm::SectionMemoryManager()); |
|
|
|
builder.setOptLevel(llvm::CodeGenOpt::None); |
|
|
|
|
|
|
|
auto triple = llvm::Triple(llvm::sys::getProcessTriple()); |
|
|
|
if (triple.getOS() == llvm::Triple::OSType::Win32) |
|
|
|
triple.setObjectFormat(llvm::Triple::ObjectFormatType::ELF); // MCJIT does not support COFF format
|
|
|
|
module->setTargetTriple(triple.str()); |
|
|
|
|
|
|
|
auto exec = std::unique_ptr<llvm::ExecutionEngine>(builder.create()); |
|
|
|
if (!exec) |
|
|
|
{ |
|
|
|
if (!errorMsg.empty()) |
|
|
|
std::cerr << "error creating EE: " << errorMsg << std::endl; |
|
|
|
else |
|
|
|
std::cerr << "unknown error creating llvm::ExecutionEngine" << std::endl; |
|
|
|
exit(1); |
|
|
|
} |
|
|
|
_module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module
|
|
|
|
exec->finalizeObject(); |
|
|
|
|
|
|
|
auto entryFunc = module->getFunction("main"); |
|
|
|
if (!entryFunc) |
|
|
|
{ |
|
|
|
std::cerr << "main function not found\n"; |
|
|
|
exit(1); |
|
|
|
} |
|
|
|
|
|
|
|
auto result = exec->runFunction(entryFunc, {}); |
|
|
|
auto intResult = result.IntVal.getZExtValue(); |
|
|
|
return intResult; |
|
|
|
} |
|
|
|
|
|
|
|
} |