|
|
@ -47,12 +47,14 @@ Stack::Stack(llvm::IRBuilder<>& _builder, llvm::Module* _module) |
|
|
|
m_stackPush = llvm::Function::Create(funcType, |
|
|
|
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_push", _module); |
|
|
|
|
|
|
|
m_stackTop = llvm::Function::Create(funcType, |
|
|
|
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_top", _module); |
|
|
|
|
|
|
|
m_stackPop = llvm::Function::Create(funcType, |
|
|
|
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_pop", _module); |
|
|
|
|
|
|
|
llvm::Type* getArgsTypes[] = {stackPtrTy, m_builder.getInt32Ty(), i256PtrTy}; |
|
|
|
auto getFuncType = llvm::FunctionType::get(voidTy, getArgsTypes); |
|
|
|
m_stackGet = llvm::Function::Create(getFuncType, |
|
|
|
llvm::GlobalValue::LinkageTypes::ExternalLinkage, "evmccrt_stack_get", _module); |
|
|
|
|
|
|
|
m_args[0] = m_builder.CreateCall(stackCreate, "stack.ptr"); |
|
|
|
m_args[1] = m_builder.CreateAlloca(i256Ty, nullptr, "stack.val"); |
|
|
|
} |
|
|
@ -65,20 +67,27 @@ void Stack::push(llvm::Value* _value) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
llvm::Value* Stack::top() |
|
|
|
llvm::Value* Stack::pop() |
|
|
|
{ |
|
|
|
m_builder.CreateCall(m_stackTop, m_args); |
|
|
|
m_builder.CreateCall(m_stackPop, m_args); |
|
|
|
return m_builder.CreateLoad(m_args[1]); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
llvm::Value* Stack::pop() |
|
|
|
llvm::Value* Stack::get(uint32_t _index) |
|
|
|
{ |
|
|
|
m_builder.CreateCall(m_stackPop, m_args); |
|
|
|
llvm::Value* args[] = {m_args[0], m_builder.getInt32(_index), m_args[1]}; |
|
|
|
m_builder.CreateCall(m_stackGet, args); |
|
|
|
return m_builder.CreateLoad(m_args[1]); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
llvm::Value* Stack::top() |
|
|
|
{ |
|
|
|
return get(0); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void debugStack(const char* op, const i256& word) |
|
|
|
{ |
|
|
|
std::cerr << "STACK " << std::setw(4) << std::setfill(' ') << op << ": " |
|
|
@ -114,24 +123,24 @@ EXPORT void evmccrt_stack_push(void* _stack, void* _pWord) |
|
|
|
stack->push_back(*word); |
|
|
|
} |
|
|
|
|
|
|
|
EXPORT void evmccrt_stack_top(void* _stack, void* _pWord) |
|
|
|
EXPORT void evmccrt_stack_pop(void* _stack, void* _pWord) |
|
|
|
{ |
|
|
|
auto stack = static_cast<StackImpl*>(_stack); |
|
|
|
assert(!stack->empty()); |
|
|
|
auto word = &stack->back(); |
|
|
|
debugStack("top", *word); |
|
|
|
debugStack("pop", *word); |
|
|
|
auto outWord = static_cast<i256*>(_pWord); |
|
|
|
stack->pop_back(); |
|
|
|
*outWord = *word; |
|
|
|
} |
|
|
|
|
|
|
|
EXPORT void evmccrt_stack_pop(void* _stack, void* _pWord) |
|
|
|
EXPORT void evmccrt_stack_get(void* _stack, uint32_t _index, void* _pWord) |
|
|
|
{ |
|
|
|
auto stack = static_cast<StackImpl*>(_stack); |
|
|
|
assert(!stack->empty()); |
|
|
|
auto word = &stack->back(); |
|
|
|
debugStack("pop", *word); |
|
|
|
assert(_index < stack->size()); |
|
|
|
auto word = &(*stack)[stack->size() - _index - 1]; |
|
|
|
debugStack("get", *word); |
|
|
|
auto outWord = static_cast<i256*>(_pWord); |
|
|
|
stack->pop_back(); |
|
|
|
*outWord = *word; |
|
|
|
} |
|
|
|
|
|
|
|