mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-20 19:56:44 +00:00
parent
9007b74118
commit
ec2013d5c9
4 changed files with 19 additions and 22 deletions
|
|
@ -199,22 +199,12 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
|
|
||||||
createBasicBlocks(bytecode);
|
createBasicBlocks(bytecode);
|
||||||
|
|
||||||
// Prepare jump buffer
|
|
||||||
auto jmpBufStorageTy = llvm::ArrayType::get(Type::Byte, 2048);
|
|
||||||
auto jmpBufStorage = new llvm::GlobalVariable(*module, jmpBufStorageTy, false, llvm::GlobalVariable::PrivateLinkage, llvm::ConstantAggregateZero::get(jmpBufStorageTy), "jmpBuf");
|
|
||||||
jmpBufStorage->setAlignment(16);
|
|
||||||
auto jmpBuf = builder.CreateConstInBoundsGEP2_32(jmpBufStorage, 0, 0);
|
|
||||||
|
|
||||||
// Init runtime structures.
|
// Init runtime structures.
|
||||||
GasMeter gasMeter(builder, module.get(), jmpBuf);
|
GasMeter gasMeter(builder, module.get());
|
||||||
Memory memory(builder, module.get(), gasMeter);
|
Memory memory(builder, module.get(), gasMeter);
|
||||||
Ext ext(builder, module.get());
|
Ext ext(builder, module.get());
|
||||||
|
|
||||||
// Create exception landing with setjmp and jump to first instruction
|
builder.CreateBr(basicBlocks.begin()->second);
|
||||||
auto setjmpFunc = llvm::Intrinsic::getDeclaration(module.get(), llvm::Intrinsic::eh_sjlj_setjmp);
|
|
||||||
auto setjmpRet = builder.CreateCall(setjmpFunc, jmpBuf);
|
|
||||||
auto isNormalFlow = builder.CreateICmpEQ(setjmpRet, builder.getInt32(0));
|
|
||||||
builder.CreateCondBr(isNormalFlow, basicBlocks.begin()->second, m_outOfGasBlock->llvm());
|
|
||||||
|
|
||||||
for (auto basicBlockPairIt = basicBlocks.begin(); basicBlockPairIt != basicBlocks.end(); ++basicBlockPairIt)
|
for (auto basicBlockPairIt = basicBlocks.begin(); basicBlockPairIt != basicBlocks.end(); ++basicBlockPairIt)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
|
||||||
#include "ExecutionEngine.h"
|
#include "ExecutionEngine.h"
|
||||||
|
|
||||||
|
#include <csetjmp>
|
||||||
|
|
||||||
#include <llvm/IR/LLVMContext.h>
|
#include <llvm/IR/LLVMContext.h>
|
||||||
#include <llvm/IR/Module.h>
|
#include <llvm/IR/Module.h>
|
||||||
#include <llvm/ADT/Triple.h>
|
#include <llvm/ADT/Triple.h>
|
||||||
|
|
@ -27,6 +29,8 @@ ExecutionEngine::ExecutionEngine()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" { EXPORT std::jmp_buf* rt_jmpBuf; }
|
||||||
|
|
||||||
|
|
||||||
int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
|
int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
|
||||||
{
|
{
|
||||||
|
|
@ -101,17 +105,17 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ReturnCode returnCode;
|
ReturnCode returnCode;
|
||||||
try
|
std::jmp_buf buf;
|
||||||
|
auto r = setjmp(buf);
|
||||||
|
if (r == 0)
|
||||||
{
|
{
|
||||||
|
rt_jmpBuf = &buf;
|
||||||
auto result = exec->runFunction(entryFunc, {});
|
auto result = exec->runFunction(entryFunc, {});
|
||||||
returnCode = static_cast<ReturnCode>(result.IntVal.getZExtValue());
|
returnCode = static_cast<ReturnCode>(result.IntVal.getZExtValue());
|
||||||
}
|
}
|
||||||
catch (const dev::eth::OutOfGas&)
|
else
|
||||||
{
|
returnCode = static_cast<ReturnCode>(r);
|
||||||
returnCode = ReturnCode::OutOfGas;
|
|
||||||
}
|
|
||||||
|
|
||||||
gas = static_cast<decltype(gas)>(Runtime::getGas());
|
gas = static_cast<decltype(gas)>(Runtime::getGas());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ bool isCostBlockEnd(Instruction _inst)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module, llvm::Value* _jmpBuf) :
|
GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module) :
|
||||||
m_builder(_builder)
|
m_builder(_builder)
|
||||||
{
|
{
|
||||||
m_gas = new llvm::GlobalVariable(*_module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "gas");
|
m_gas = new llvm::GlobalVariable(*_module, Type::i256, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "gas");
|
||||||
|
|
@ -102,8 +102,11 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module, llvm::Val
|
||||||
|
|
||||||
m_builder.SetInsertPoint(outOfGasBB);
|
m_builder.SetInsertPoint(outOfGasBB);
|
||||||
|
|
||||||
auto longjmpFunc = llvm::Intrinsic::getDeclaration(_module, llvm::Intrinsic::eh_sjlj_longjmp);
|
//auto longjmpFunc = llvm::Intrinsic::getDeclaration(_module, llvm::Intrinsic::eh_sjlj_longjmp);
|
||||||
m_builder.CreateCall(longjmpFunc, _jmpBuf);
|
auto extJmpBuf = new llvm::GlobalVariable(*_module, Type::BytePtr, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "rt_jmpBuf");
|
||||||
|
llvm::Type* args[] = {Type::BytePtr, m_builder.getInt32Ty()};
|
||||||
|
auto longjmpNative = llvm::Function::Create(llvm::FunctionType::get(Type::Void, args, false), llvm::Function::ExternalLinkage, "longjmp", _module);
|
||||||
|
m_builder.CreateCall2(longjmpNative, m_builder.CreateLoad(extJmpBuf), Constant::get(ReturnCode::OutOfGas));
|
||||||
m_builder.CreateUnreachable();
|
m_builder.CreateUnreachable();
|
||||||
|
|
||||||
m_builder.SetInsertPoint(updateBB);
|
m_builder.SetInsertPoint(updateBB);
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace evmcc
|
||||||
class GasMeter
|
class GasMeter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module, llvm::Value* _jmpBuf);
|
GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module);
|
||||||
|
|
||||||
GasMeter(const GasMeter&) = delete;
|
GasMeter(const GasMeter&) = delete;
|
||||||
void operator=(GasMeter) = delete;
|
void operator=(GasMeter) = delete;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue