Browse Source

Move jmpbuf to Runtime [#81470252]

cl-refactor
Paweł Bylica 10 years ago
parent
commit
64e374890c
  1. 8
      libevmjit/ExecutionEngine.cpp
  2. 3
      libevmjit/GasMeter.cpp
  3. 10
      libevmjit/Runtime.cpp
  4. 8
      libevmjit/Runtime.h
  5. 8
      libevmjit/Stack.cpp

8
libevmjit/ExecutionEngine.cpp

@ -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());

3
libevmjit/GasMeter.cpp

@ -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);

10
libevmjit/Runtime.cpp

@ -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);

8
libevmjit/Runtime.h

@ -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:

8
libevmjit/Stack.cpp

@ -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…
Cancel
Save