mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-20 11:46: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);
|
||||
|
||||
// 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.
|
||||
GasMeter gasMeter(builder, module.get(), jmpBuf);
|
||||
GasMeter gasMeter(builder, module.get());
|
||||
Memory memory(builder, module.get(), gasMeter);
|
||||
Ext ext(builder, module.get());
|
||||
|
||||
// Create exception landing with setjmp and jump to first instruction
|
||||
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());
|
||||
builder.CreateBr(basicBlocks.begin()->second);
|
||||
|
||||
for (auto basicBlockPairIt = basicBlocks.begin(); basicBlockPairIt != basicBlocks.end(); ++basicBlockPairIt)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
|
||||
#include "ExecutionEngine.h"
|
||||
|
||||
#include <csetjmp>
|
||||
|
||||
#include <llvm/IR/LLVMContext.h>
|
||||
#include <llvm/IR/Module.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)
|
||||
{
|
||||
|
|
@ -101,17 +105,17 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
ReturnCode returnCode;
|
||||
try
|
||||
std::jmp_buf buf;
|
||||
auto r = setjmp(buf);
|
||||
if (r == 0)
|
||||
{
|
||||
rt_jmpBuf = &buf;
|
||||
auto result = exec->runFunction(entryFunc, {});
|
||||
returnCode = static_cast<ReturnCode>(result.IntVal.getZExtValue());
|
||||
}
|
||||
catch (const dev::eth::OutOfGas&)
|
||||
{
|
||||
returnCode = ReturnCode::OutOfGas;
|
||||
}
|
||||
else
|
||||
returnCode = static_cast<ReturnCode>(r);
|
||||
|
||||
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_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);
|
||||
|
||||
auto longjmpFunc = llvm::Intrinsic::getDeclaration(_module, llvm::Intrinsic::eh_sjlj_longjmp);
|
||||
m_builder.CreateCall(longjmpFunc, _jmpBuf);
|
||||
//auto longjmpFunc = llvm::Intrinsic::getDeclaration(_module, llvm::Intrinsic::eh_sjlj_longjmp);
|
||||
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.SetInsertPoint(updateBB);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ namespace evmcc
|
|||
class GasMeter
|
||||
{
|
||||
public:
|
||||
GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module, llvm::Value* _jmpBuf);
|
||||
GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module);
|
||||
|
||||
GasMeter(const GasMeter&) = delete;
|
||||
void operator=(GasMeter) = delete;
|
||||
|
|
|
|||
Loading…
Reference in a new issue