|
|
@ -14,8 +14,9 @@ namespace eth |
|
|
|
namespace jit |
|
|
|
{ |
|
|
|
|
|
|
|
Stack::Stack(llvm::IRBuilder<>& _builder) |
|
|
|
: CompilerHelper(_builder) |
|
|
|
Stack::Stack(llvm::IRBuilder<>& _builder, RuntimeManager& _runtimeManager) |
|
|
|
: CompilerHelper(_builder), |
|
|
|
m_runtimeManager(_runtimeManager) |
|
|
|
{ |
|
|
|
m_arg = m_builder.CreateAlloca(Type::i256, nullptr, "stack.arg"); |
|
|
|
|
|
|
@ -23,11 +24,16 @@ Stack::Stack(llvm::IRBuilder<>& _builder) |
|
|
|
using Linkage = GlobalValue::LinkageTypes; |
|
|
|
|
|
|
|
auto module = getModule(); |
|
|
|
m_push = Function::Create(FunctionType::get(m_builder.getVoidTy(), Type::WordPtr, false), Linkage::ExternalLinkage, "stack_push", module); |
|
|
|
m_pop = Function::Create(FunctionType::get(m_builder.getVoidTy(), Type::Size, false), Linkage::ExternalLinkage, "stack_pop", module); |
|
|
|
llvm::Type* getSetArgTypes[] = {Type::Size, Type::WordPtr}; |
|
|
|
m_get = Function::Create(FunctionType::get(m_builder.getVoidTy(), ArrayRef<llvm::Type*>(getSetArgTypes), false), Linkage::ExternalLinkage, "stack_get", module); |
|
|
|
m_set = Function::Create(FunctionType::get(m_builder.getVoidTy(), ArrayRef<llvm::Type*>(getSetArgTypes), false), Linkage::ExternalLinkage, "stack_set", module); |
|
|
|
|
|
|
|
llvm::Type* pushArgTypes[] = {Type::RuntimePtr, Type::WordPtr}; |
|
|
|
m_push = Function::Create(FunctionType::get(Type::Void, pushArgTypes, false), Linkage::ExternalLinkage, "stack_push", module); |
|
|
|
|
|
|
|
llvm::Type* popArgTypes[] = {Type::RuntimePtr, Type::Size}; |
|
|
|
m_pop = Function::Create(FunctionType::get(Type::Void, popArgTypes, false), Linkage::ExternalLinkage, "stack_pop", module); |
|
|
|
|
|
|
|
llvm::Type* getSetArgTypes[] = {Type::RuntimePtr, Type::Size, Type::WordPtr}; |
|
|
|
m_get = Function::Create(FunctionType::get(Type::Void, getSetArgTypes, false), Linkage::ExternalLinkage, "stack_get", module); |
|
|
|
m_set = Function::Create(FunctionType::get(Type::Void, getSetArgTypes, false), Linkage::ExternalLinkage, "stack_set", module); |
|
|
|
} |
|
|
|
|
|
|
|
Stack::~Stack() |
|
|
@ -35,25 +41,25 @@ Stack::~Stack() |
|
|
|
|
|
|
|
llvm::Value* Stack::get(size_t _index) |
|
|
|
{ |
|
|
|
m_builder.CreateCall2(m_get, llvm::ConstantInt::get(Type::Size, _index, false), m_arg); |
|
|
|
m_builder.CreateCall3(m_get, m_runtimeManager.getRuntimePtr(), llvm::ConstantInt::get(Type::Size, _index, false), m_arg); |
|
|
|
return m_builder.CreateLoad(m_arg); |
|
|
|
} |
|
|
|
|
|
|
|
void Stack::set(size_t _index, llvm::Value* _value) |
|
|
|
{ |
|
|
|
m_builder.CreateStore(_value, m_arg); |
|
|
|
m_builder.CreateCall2(m_set, llvm::ConstantInt::get(Type::Size, _index, false), m_arg); |
|
|
|
m_builder.CreateCall3(m_set, m_runtimeManager.getRuntimePtr(), llvm::ConstantInt::get(Type::Size, _index, false), m_arg); |
|
|
|
} |
|
|
|
|
|
|
|
void Stack::pop(size_t _count) |
|
|
|
{ |
|
|
|
m_builder.CreateCall(m_pop, llvm::ConstantInt::get(Type::Size, _count, false)); |
|
|
|
m_builder.CreateCall2(m_pop, m_runtimeManager.getRuntimePtr(), llvm::ConstantInt::get(Type::Size, _count, false)); |
|
|
|
} |
|
|
|
|
|
|
|
void Stack::push(llvm::Value* _value) |
|
|
|
{ |
|
|
|
m_builder.CreateStore(_value, m_arg); |
|
|
|
m_builder.CreateCall(m_push, m_arg); |
|
|
|
m_builder.CreateCall2(m_push, m_runtimeManager.getRuntimePtr(), m_arg); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -70,27 +76,27 @@ using namespace dev::eth::jit; |
|
|
|
|
|
|
|
extern std::jmp_buf* rt_jmpBuf; |
|
|
|
|
|
|
|
EXPORT void stack_pop(uint64_t _count) |
|
|
|
EXPORT void stack_pop(Runtime* _rt, uint64_t _count) |
|
|
|
{ |
|
|
|
auto& stack = Runtime::getStack(); |
|
|
|
auto& stack = _rt->getStack(); |
|
|
|
if (stack.size() < _count) |
|
|
|
longjmp(*rt_jmpBuf, static_cast<uint64_t>(ReturnCode::StackTooSmall)); |
|
|
|
|
|
|
|
stack.erase(stack.end() - _count, stack.end()); |
|
|
|
} |
|
|
|
|
|
|
|
EXPORT void stack_push(i256* _word) |
|
|
|
EXPORT void stack_push(Runtime* _rt, i256* _word) |
|
|
|
{ |
|
|
|
auto& stack = Runtime::getStack(); |
|
|
|
auto& stack = _rt->getStack(); |
|
|
|
stack.push_back(*_word); |
|
|
|
|
|
|
|
if (stack.size() > Stack::maxStackSize) |
|
|
|
Stack::maxStackSize = stack.size(); |
|
|
|
} |
|
|
|
|
|
|
|
EXPORT void stack_get(uint64_t _index, i256* _ret) |
|
|
|
EXPORT void stack_get(Runtime* _rt, uint64_t _index, i256* _ret) |
|
|
|
{ |
|
|
|
auto& stack = Runtime::getStack(); |
|
|
|
auto& stack = _rt->getStack(); |
|
|
|
// TODO: encode _index and stack size in the return code
|
|
|
|
if (stack.size() <= _index) |
|
|
|
longjmp(*rt_jmpBuf, static_cast<uint64_t>(ReturnCode::StackTooSmall)); |
|
|
@ -98,9 +104,9 @@ EXPORT void stack_get(uint64_t _index, i256* _ret) |
|
|
|
*_ret = *(stack.rbegin() + _index); |
|
|
|
} |
|
|
|
|
|
|
|
EXPORT void stack_set(uint64_t _index, i256* _word) |
|
|
|
EXPORT void stack_set(Runtime* _rt, uint64_t _index, i256* _word) |
|
|
|
{ |
|
|
|
auto& stack = Runtime::getStack(); |
|
|
|
auto& stack = _rt->getStack(); |
|
|
|
// TODO: encode _index and stack size in the return code
|
|
|
|
if (stack.size() <= _index) |
|
|
|
longjmp(*rt_jmpBuf, static_cast<uint64_t>(ReturnCode::StackTooSmall)); |
|
|
|