Pop entry state of basic block from external stack, push exit state to external stack.

[Delivers #80113346]
This commit is contained in:
Paweł Bylica 2014-10-07 09:24:55 +02:00
parent 33e36ce6cc
commit cc51bfded6
5 changed files with 50 additions and 5 deletions

View file

@ -188,12 +188,12 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
createBasicBlocks(bytecode);
// Init runtime structures.
auto globalStack = Stack(builder, module.get());
auto extStack = Stack(builder, module.get());
auto memory = Memory(builder, module.get());
auto ext = Ext(builder, module.get());
BasicBlock* currentBlock = entryBlock;
BBStack stack; // Stack for current block
BBStack stack(extStack); // Stack for current block
for (auto pc = bytecode.cbegin(); pc != bytecode.cend(); ++pc)
{
@ -212,7 +212,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
mainFunc->getBasicBlockList().push_back(nextBlock);
builder.SetInsertPoint(nextBlock);
currentBlock = nextBlock;
stack = BBStack(); // Reset stack
assert(stack.empty()); // Stack should be empty
}
assert(currentBlock != nullptr);
@ -579,6 +579,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
// The target address is computed at compile time,
// just pop it without looking...
stack.pop();
stack.reset();
auto targetBlock = jumpTargets[currentPC];
builder.CreateBr(targetBlock);
@ -598,6 +599,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
auto top = stack.pop();
auto zero = ConstantInt::get(Types.word256, 0);
auto cond = builder.CreateICmpNE(top, zero, "nonzero");
stack.reset();
auto targetBlock = jumpTargets[currentPC];
auto followBlock = basicBlocks[currentPC + 1];
builder.CreateCondBr(cond, targetBlock, followBlock);
@ -764,6 +766,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
ret = builder.CreateOr(ret, size);
builder.CreateRet(ret);
stack.clear();
currentBlock = nullptr;
break;
}
@ -777,6 +780,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
case Instruction::STOP:
{
builder.CreateRet(builder.getInt64(0));
stack.clear();
currentBlock = nullptr;
break;
}

View file

@ -103,7 +103,7 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
std::cout << "RETURN [ ";
for (dev::bytes::const_iterator it = Runtime::getMemory().cbegin() + index, end = it + size; it != end; ++it)
std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)*it << " ";
std::cout << "]";
std::cout << "]\n";
return 10;
}

View file

@ -20,6 +20,10 @@
namespace evmcc
{
BBStack::BBStack(Stack& _extStack)
: m_extStack(_extStack)
{}
void BBStack::push(llvm::Value* _value)
{
m_state.push_back(_value);
@ -27,11 +31,31 @@ void BBStack::push(llvm::Value* _value)
llvm::Value* BBStack::pop()
{
if (m_state.empty())
return m_extStack.pop();
auto top = m_state.back();
m_state.pop_back();
return top;
}
void BBStack::reset()
{
for (auto&& value : m_state)
m_extStack.push(value);
m_state.clear();
}
void BBStack::clear()
{
m_state.clear();
}
bool BBStack::empty() const
{
return m_state.empty();
}
void BBStack::dup(size_t _index)
{
auto value = *(m_state.rbegin() + _index);

View file

@ -36,15 +36,31 @@ private:
class BBStack
{
public:
//BBStack(llvm::IRBuilder<>& _builder, llvm::Module* _module);
BBStack(Stack& _extStack);
void push(llvm::Value* _value);
llvm::Value* pop();
void dup(size_t _index);
void swap(size_t _index);
/**
Resets stack on basic block change.
Values left on local stack are pushed on external stack.
Local stack is empty after this operation and compilation of new basic block can be started.
*/
void reset();
/**
Dumps values on stack.
*/
void clear();
/// Debug only
bool empty() const;
private:
std::vector<llvm::Value*> m_state; ///< Basic black state vector - current values and their positions
Stack& m_extStack; ///< External (global) stack
};

View file

@ -0,0 +1 @@
600460066009601358600a036000545b6000f260005401600958