|
|
@ -49,7 +49,10 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode) |
|
|
|
IRBuilder<> builder(context); |
|
|
|
|
|
|
|
// Create main function
|
|
|
|
auto mainFuncType = FunctionType::get(llvm::Type::getInt32Ty(context), false); |
|
|
|
const auto i32Ty = builder.getInt32Ty(); |
|
|
|
Type* retTypeElems[] = {i32Ty, i32Ty}; |
|
|
|
auto retType = StructType::create(retTypeElems, "MemRef", true); |
|
|
|
auto mainFuncType = FunctionType::get(builder.getInt64Ty(), false); |
|
|
|
auto mainFunc = Function::Create(mainFuncType, Function::ExternalLinkage, "main", module.get()); |
|
|
|
|
|
|
|
auto entryBlock = BasicBlock::Create(context, "entry", mainFunc); |
|
|
@ -61,7 +64,9 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode) |
|
|
|
|
|
|
|
auto ext = Ext(builder); |
|
|
|
|
|
|
|
for (auto pc = bytecode.cbegin(); pc != bytecode.cend(); ++pc) |
|
|
|
auto userRet = false; |
|
|
|
auto finished = false; |
|
|
|
for (auto pc = bytecode.cbegin(); pc != bytecode.cend() && !finished; ++pc) |
|
|
|
{ |
|
|
|
using dev::eth::Instruction; |
|
|
|
|
|
|
@ -313,10 +318,47 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode) |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
case Instruction::CODESIZE: |
|
|
|
{ |
|
|
|
auto value = builder.getIntN(256, bytecode.size()); |
|
|
|
stack.push(value); |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
case Instruction::RETURN: |
|
|
|
{ |
|
|
|
auto index = stack.pop(); |
|
|
|
auto size = stack.pop(); |
|
|
|
|
|
|
|
// MCJIT does not support returning structs
|
|
|
|
//auto index32 = builder.CreateTrunc(index, i32Ty, "index32");
|
|
|
|
//auto size32 = builder.CreateTrunc(size, i32Ty, "size32");
|
|
|
|
//auto ret = builder.CreateInsertValue(UndefValue::get(retType), index32, 0, "ret");
|
|
|
|
//ret = builder.CreateInsertValue(ret, size32, 1, "ret");
|
|
|
|
|
|
|
|
auto ret = builder.CreateTrunc(index, builder.getInt64Ty()); |
|
|
|
ret = builder.CreateShl(ret, 32); |
|
|
|
size = builder.CreateTrunc(size, i32Ty); |
|
|
|
size = builder.CreateZExt(size, builder.getInt64Ty()); |
|
|
|
ret = builder.CreateOr(ret, size); |
|
|
|
|
|
|
|
builder.CreateRet(ret); |
|
|
|
finished = true; |
|
|
|
userRet = true; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
case Instruction::STOP: |
|
|
|
{ |
|
|
|
finished = true; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
builder.CreateRet(ConstantInt::get(Type::getInt32Ty(context), 0)); |
|
|
|
if (!userRet) |
|
|
|
builder.CreateRet(builder.getInt64(0)); |
|
|
|
|
|
|
|
return module; |
|
|
|
} |
|
|
|