6 #include <llvm/IR/CFG.h> 7 #include <llvm/IR/Module.h> 8 #include <llvm/IR/Function.h> 9 #include <llvm/IR/Instructions.h> 10 #include <llvm/IR/IntrinsicInst.h> 11 #include <llvm/IR/IRBuilder.h> 12 #include <llvm/Support/raw_os_ostream.h> 27 m_firstInstrIdx{_firstInstrIdx},
30 m_llvmBB(llvm::BasicBlock::Create(_mainFunc->getContext(), {
".", std::to_string(_firstInstrIdx)}, _mainFunc))
37 auto undef = llvm::UndefValue::get(
Type::Size);
40 {
"sp",
m_builder.GetInsertBlock()->getName()});
67 auto val =
get(_index);
75 auto val =
get(_index);
84 return *(
m_local.rbegin() + _index);
94 ssize_t globalIdx = -
static_cast<ssize_t
>(idx) - 1;
96 item =
m_builder.CreateAlignedLoad(slot, 16);
107 *(
m_local.rbegin() + _index) = _word;
123 if (
auto term =
m_builder.GetInsertBlock()->getTerminator())
126 auto inputIt =
m_input.rbegin();
127 auto localIt =
m_local.begin();
128 for (
auto globalIdx = -static_cast<ssize_t>(
m_input.size()); globalIdx <
size(); ++globalIdx)
141 m_builder.CreateAlignedStore(item, slot, 16);
148 static const auto c_funcName =
"stack.prepare";
149 if (
auto func =
getModule()->getFunction(c_funcName))
153 auto func = llvm::Function::Create(llvm::FunctionType::get(
Type::WordPtr, argsTys,
false), llvm::Function::PrivateLinkage, c_funcName,
getModule());
154 func->setDoesNotThrow();
155 func->setDoesNotAccessMemory(1);
156 func->setDoesNotAlias(2);
157 func->setDoesNotCapture(2);
159 auto checkBB = llvm::BasicBlock::Create(func->getContext(),
"Check", func);
160 auto updateBB = llvm::BasicBlock::Create(func->getContext(),
"Update", func);
161 auto outOfStackBB = llvm::BasicBlock::Create(func->getContext(),
"OutOfStack", func);
163 auto iter = func->arg_begin();
164 llvm::Argument* base = &(*iter++);
165 base->setName(
"base");
166 llvm::Argument* sizePtr = &(*iter++);
167 sizePtr->setName(
"size.ptr");
168 llvm::Argument*
min = &(*iter++);
170 llvm::Argument*
max = &(*iter++);
172 llvm::Argument*
diff = &(*iter++);
173 diff->setName(
"diff");
174 llvm::Argument* jmpBuf = &(*iter);
175 jmpBuf->setName(
"jmpBuf");
180 auto size =
m_builder.CreateAlignedLoad(sizePtr, sizeAlignment,
"size");
185 auto ok =
m_builder.CreateAnd(minOk, maxOk,
"ok");
189 auto newSize =
m_builder.CreateNSWAdd(
size, diff,
"size.next");
190 m_builder.CreateAlignedStore(newSize, sizePtr, sizeAlignment);
195 auto longjmp = llvm::Intrinsic::getDeclaration(
getModule(), llvm::Intrinsic::eh_sjlj_longjmp);
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
void dup(size_t _index)
Duplicates _index'th value on stack.
void finalize()
Finalize local stack: check the requirements and update of the global stack.
llvm::BasicBlock *const m_llvmBB
Reference to the LLVM BasicBlock.
llvm::Module * getModule()
Reference to the IR module being compiled.
llvm::Value * pop()
Pops and returns top value.
ssize_t m_minSize
Minimum reached local stack size. Can be negative.
assert(len-trim+(2 *lenIndices)<=WIDTH)
llvm::Value * getStackSize() const
static llvm::PointerType * WordPtr
byte const * code_iterator
Base class for compiler helpers like Memory, GasMeter, etc.
void set(size_t _index, llvm::Value *_value)
Sets _index'th value from top (counting from 0)
static llvm::PointerType * BytePtr
code_iterator const m_begin
Iterator pointing code beginning of the block.
code_iterator const m_end
Iterator pointing code end of the block.
LocalStack(IRBuilder &_builder, RuntimeManager &_runtimeManager)
static llvm::IntegerType * Word
ssize_t m_globalPops
Number of items poped from global stack. In other words: global - local stack overlap.
void swap(size_t _index)
Swaps _index'th value on stack with a value on stack top.
llvm::CallInst * m_sp
Call to stack.prepare function which returns stack pointer for current basic block.
void push(llvm::Value *_value)
Pushes value on stack.
ssize_t m_maxSize
Maximum reached local stack size.
static const size_t stackSizeLimit
std::vector< llvm::Value * > m_local
Local stack items that has not been pushed to global stack. First item is just above global stack...
llvm::Value * get(size_t _index)
Gets _index'th value from top (counting from 0)
N diff(N const &_a, N const &_b)
BasicBlock(instr_idx _firstInstrIdx, code_iterator _begin, code_iterator _end, llvm::Function *_mainFunc)
static llvm::IntegerType * Size
IRBuilder & m_builder
Reference to parent compiler IR builder.
dev::WithExisting max(dev::WithExisting _a, dev::WithExisting _b)
llvm::IRBuilder<> IRBuilder
static llvm::MDNode * expectTrue
llvm::Value * getStackBase() const
std::vector< llvm::Value * > m_input
Items fetched from global stack.
llvm::Value * getJmpBuf()
llvm::Function * getStackPrepareFunc()