mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 20:26:41 +00:00
Move jmpbuf to Runtime [#81470252]
This commit is contained in:
parent
68ca6962cf
commit
64e374890c
5 changed files with 22 additions and 15 deletions
|
|
@ -35,8 +35,6 @@ ExecutionEngine::ExecutionEngine()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" { EXPORT std::jmp_buf* rt_jmpBuf; }
|
|
||||||
|
|
||||||
int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, u256& _gas, ExtVMFace* _ext)
|
int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, u256& _gas, ExtVMFace* _ext)
|
||||||
{
|
{
|
||||||
auto module = _module.get(); // Keep ownership of the module in _module
|
auto module = _module.get(); // Keep ownership of the module in _module
|
||||||
|
|
@ -102,21 +100,19 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module, u256& _gas, ExtV
|
||||||
_ext->code = decltype(_ext->code)(fakecode, 8);
|
_ext->code = decltype(_ext->code)(fakecode, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init runtime
|
|
||||||
Runtime runtime(_gas, *_ext);
|
|
||||||
|
|
||||||
auto entryFunc = module->getFunction("main");
|
auto entryFunc = module->getFunction("main");
|
||||||
if (!entryFunc)
|
if (!entryFunc)
|
||||||
BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("main function not found"));
|
BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("main function not found"));
|
||||||
|
|
||||||
ReturnCode returnCode;
|
ReturnCode returnCode;
|
||||||
std::jmp_buf buf;
|
std::jmp_buf buf;
|
||||||
|
Runtime runtime(_gas, *_ext, buf);
|
||||||
auto r = setjmp(buf);
|
auto r = setjmp(buf);
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
auto executionStartTime = std::chrono::high_resolution_clock::now();
|
auto executionStartTime = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
rt_jmpBuf = &buf;
|
|
||||||
auto result = exec->runFunction(entryFunc, {{}, llvm::GenericValue(runtime.getDataPtr())});
|
auto result = exec->runFunction(entryFunc, {{}, llvm::GenericValue(runtime.getDataPtr())});
|
||||||
returnCode = static_cast<ReturnCode>(result.IntVal.getZExtValue());
|
returnCode = static_cast<ReturnCode>(result.IntVal.getZExtValue());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -103,10 +103,9 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder, RuntimeManager& _runtimeManager)
|
||||||
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);
|
||||||
auto extJmpBuf = new llvm::GlobalVariable(*module, Type::BytePtr, false, llvm::GlobalVariable::ExternalLinkage, nullptr, "rt_jmpBuf");
|
|
||||||
llvm::Type* args[] = {Type::BytePtr, m_builder.getInt32Ty()};
|
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);
|
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.CreateCall2(longjmpNative, m_runtimeManager.getJmpBuf(), Constant::get(ReturnCode::OutOfGas));
|
||||||
m_builder.CreateUnreachable();
|
m_builder.CreateUnreachable();
|
||||||
|
|
||||||
m_builder.SetInsertPoint(updateBB);
|
m_builder.SetInsertPoint(updateBB);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ llvm::StructType* RuntimeData::getType()
|
||||||
{
|
{
|
||||||
llvm::ArrayType::get(Type::i256, _size),
|
llvm::ArrayType::get(Type::i256, _size),
|
||||||
Type::BytePtr,
|
Type::BytePtr,
|
||||||
|
Type::BytePtr,
|
||||||
Type::BytePtr
|
Type::BytePtr
|
||||||
};
|
};
|
||||||
type = llvm::StructType::create(elems, "RuntimeData");
|
type = llvm::StructType::create(elems, "RuntimeData");
|
||||||
|
|
@ -58,7 +59,7 @@ llvm::Twine getName(RuntimeData::Index _index)
|
||||||
|
|
||||||
static Runtime* g_runtime; // FIXME: Remove
|
static Runtime* g_runtime; // FIXME: Remove
|
||||||
|
|
||||||
Runtime::Runtime(u256 _gas, ExtVMFace& _ext):
|
Runtime::Runtime(u256 _gas, ExtVMFace& _ext, jmp_buf _jmpBuf):
|
||||||
m_ext(_ext)
|
m_ext(_ext)
|
||||||
{
|
{
|
||||||
assert(!g_runtime);
|
assert(!g_runtime);
|
||||||
|
|
@ -79,6 +80,7 @@ Runtime::Runtime(u256 _gas, ExtVMFace& _ext):
|
||||||
set(RuntimeData::CodeSize, _ext.code.size()); // TODO: Use constant
|
set(RuntimeData::CodeSize, _ext.code.size()); // TODO: Use constant
|
||||||
m_data.callData = _ext.data.data();
|
m_data.callData = _ext.data.data();
|
||||||
m_data.code = _ext.code.data();
|
m_data.code = _ext.code.data();
|
||||||
|
m_data.jmpBuf = _jmpBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
Runtime::~Runtime()
|
Runtime::~Runtime()
|
||||||
|
|
@ -167,6 +169,12 @@ llvm::Value* RuntimeManager::getCode()
|
||||||
return getBuilder().CreateLoad(ptr, "code");
|
return getBuilder().CreateLoad(ptr, "code");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
llvm::Value* RuntimeManager::getJmpBuf()
|
||||||
|
{
|
||||||
|
auto ptr = getBuilder().CreateStructGEP(getRuntimePtr(), 3, "jmpbufPtr");
|
||||||
|
return getBuilder().CreateLoad(ptr, "jmpbuf");
|
||||||
|
}
|
||||||
|
|
||||||
llvm::Value* RuntimeManager::getGas()
|
llvm::Value* RuntimeManager::getGas()
|
||||||
{
|
{
|
||||||
return get(RuntimeData::Gas);
|
return get(RuntimeData::Gas);
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,16 @@ struct RuntimeData
|
||||||
GasLimit,
|
GasLimit,
|
||||||
CodeSize,
|
CodeSize,
|
||||||
|
|
||||||
|
ReturnDataOffset = CallValue, // Reuse 2 fields for return data reference
|
||||||
|
ReturnDataSize = CallDataSize,
|
||||||
|
|
||||||
_size
|
_size
|
||||||
};
|
};
|
||||||
|
|
||||||
i256 elems[_size];
|
i256 elems[_size];
|
||||||
byte const* callData;
|
byte const* callData;
|
||||||
byte const* code;
|
byte const* code;
|
||||||
|
decltype(&jmp_buf{}[0]) jmpBuf;
|
||||||
|
|
||||||
static llvm::StructType* getType();
|
static llvm::StructType* getType();
|
||||||
};
|
};
|
||||||
|
|
@ -57,7 +61,7 @@ using MemoryImpl = bytes;
|
||||||
class Runtime
|
class Runtime
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Runtime(u256 _gas, ExtVMFace& _ext);
|
Runtime(u256 _gas, ExtVMFace& _ext, jmp_buf _jmpBuf);
|
||||||
~Runtime();
|
~Runtime();
|
||||||
|
|
||||||
Runtime(const Runtime&) = delete;
|
Runtime(const Runtime&) = delete;
|
||||||
|
|
@ -71,6 +75,7 @@ public:
|
||||||
|
|
||||||
u256 getGas() const;
|
u256 getGas() const;
|
||||||
bytesConstRef getReturnData() const;
|
bytesConstRef getReturnData() const;
|
||||||
|
decltype(&jmp_buf{}[0]) getJmpBuf() { return m_data.jmpBuf; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void set(RuntimeData::Index _index, u256 _value);
|
void set(RuntimeData::Index _index, u256 _value);
|
||||||
|
|
@ -94,6 +99,7 @@ public:
|
||||||
llvm::Value* getGas(); // TODO: Remove
|
llvm::Value* getGas(); // TODO: Remove
|
||||||
llvm::Value* getCallData();
|
llvm::Value* getCallData();
|
||||||
llvm::Value* getCode();
|
llvm::Value* getCode();
|
||||||
|
llvm::Value* getJmpBuf();
|
||||||
void setGas(llvm::Value* _gas);
|
void setGas(llvm::Value* _gas);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
||||||
|
|
@ -74,13 +74,11 @@ extern "C"
|
||||||
|
|
||||||
using namespace dev::eth::jit;
|
using namespace dev::eth::jit;
|
||||||
|
|
||||||
extern std::jmp_buf* rt_jmpBuf;
|
|
||||||
|
|
||||||
EXPORT void stack_pop(Runtime* _rt, uint64_t _count)
|
EXPORT void stack_pop(Runtime* _rt, uint64_t _count)
|
||||||
{
|
{
|
||||||
auto& stack = _rt->getStack();
|
auto& stack = _rt->getStack();
|
||||||
if (stack.size() < _count)
|
if (stack.size() < _count)
|
||||||
longjmp(*rt_jmpBuf, static_cast<uint64_t>(ReturnCode::StackTooSmall));
|
longjmp(_rt->getJmpBuf(), static_cast<uint64_t>(ReturnCode::StackTooSmall));
|
||||||
|
|
||||||
stack.erase(stack.end() - _count, stack.end());
|
stack.erase(stack.end() - _count, stack.end());
|
||||||
}
|
}
|
||||||
|
|
@ -99,7 +97,7 @@ EXPORT void stack_get(Runtime* _rt, uint64_t _index, i256* _ret)
|
||||||
auto& stack = _rt->getStack();
|
auto& stack = _rt->getStack();
|
||||||
// TODO: encode _index and stack size in the return code
|
// TODO: encode _index and stack size in the return code
|
||||||
if (stack.size() <= _index)
|
if (stack.size() <= _index)
|
||||||
longjmp(*rt_jmpBuf, static_cast<uint64_t>(ReturnCode::StackTooSmall));
|
longjmp(_rt->getJmpBuf(), static_cast<uint64_t>(ReturnCode::StackTooSmall));
|
||||||
|
|
||||||
*_ret = *(stack.rbegin() + _index);
|
*_ret = *(stack.rbegin() + _index);
|
||||||
}
|
}
|
||||||
|
|
@ -109,7 +107,7 @@ EXPORT void stack_set(Runtime* _rt, uint64_t _index, i256* _word)
|
||||||
auto& stack = _rt->getStack();
|
auto& stack = _rt->getStack();
|
||||||
// TODO: encode _index and stack size in the return code
|
// TODO: encode _index and stack size in the return code
|
||||||
if (stack.size() <= _index)
|
if (stack.size() <= _index)
|
||||||
longjmp(*rt_jmpBuf, static_cast<uint64_t>(ReturnCode::StackTooSmall));
|
longjmp(_rt->getJmpBuf(), static_cast<uint64_t>(ReturnCode::StackTooSmall));
|
||||||
|
|
||||||
*(stack.rbegin() + _index) = *_word;
|
*(stack.rbegin() + _index) = *_word;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue