mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-21 04:06:44 +00:00
Pop entry state of basic block from external stack, push exit state to external stack.
[Delivers #80113346]
This commit is contained in:
parent
33e36ce6cc
commit
cc51bfded6
5 changed files with 50 additions and 5 deletions
|
|
@ -188,12 +188,12 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
createBasicBlocks(bytecode);
|
createBasicBlocks(bytecode);
|
||||||
|
|
||||||
// Init runtime structures.
|
// Init runtime structures.
|
||||||
auto globalStack = Stack(builder, module.get());
|
auto extStack = Stack(builder, module.get());
|
||||||
auto memory = Memory(builder, module.get());
|
auto memory = Memory(builder, module.get());
|
||||||
auto ext = Ext(builder, module.get());
|
auto ext = Ext(builder, module.get());
|
||||||
|
|
||||||
BasicBlock* currentBlock = entryBlock;
|
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)
|
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);
|
mainFunc->getBasicBlockList().push_back(nextBlock);
|
||||||
builder.SetInsertPoint(nextBlock);
|
builder.SetInsertPoint(nextBlock);
|
||||||
currentBlock = nextBlock;
|
currentBlock = nextBlock;
|
||||||
stack = BBStack(); // Reset stack
|
assert(stack.empty()); // Stack should be empty
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(currentBlock != nullptr);
|
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,
|
// The target address is computed at compile time,
|
||||||
// just pop it without looking...
|
// just pop it without looking...
|
||||||
stack.pop();
|
stack.pop();
|
||||||
|
stack.reset();
|
||||||
|
|
||||||
auto targetBlock = jumpTargets[currentPC];
|
auto targetBlock = jumpTargets[currentPC];
|
||||||
builder.CreateBr(targetBlock);
|
builder.CreateBr(targetBlock);
|
||||||
|
|
@ -598,6 +599,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
auto top = stack.pop();
|
auto top = stack.pop();
|
||||||
auto zero = ConstantInt::get(Types.word256, 0);
|
auto zero = ConstantInt::get(Types.word256, 0);
|
||||||
auto cond = builder.CreateICmpNE(top, zero, "nonzero");
|
auto cond = builder.CreateICmpNE(top, zero, "nonzero");
|
||||||
|
stack.reset();
|
||||||
auto targetBlock = jumpTargets[currentPC];
|
auto targetBlock = jumpTargets[currentPC];
|
||||||
auto followBlock = basicBlocks[currentPC + 1];
|
auto followBlock = basicBlocks[currentPC + 1];
|
||||||
builder.CreateCondBr(cond, targetBlock, followBlock);
|
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);
|
ret = builder.CreateOr(ret, size);
|
||||||
|
|
||||||
builder.CreateRet(ret);
|
builder.CreateRet(ret);
|
||||||
|
stack.clear();
|
||||||
currentBlock = nullptr;
|
currentBlock = nullptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -777,6 +780,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
|
||||||
case Instruction::STOP:
|
case Instruction::STOP:
|
||||||
{
|
{
|
||||||
builder.CreateRet(builder.getInt64(0));
|
builder.CreateRet(builder.getInt64(0));
|
||||||
|
stack.clear();
|
||||||
currentBlock = nullptr;
|
currentBlock = nullptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ int ExecutionEngine::run(std::unique_ptr<llvm::Module> _module)
|
||||||
std::cout << "RETURN [ ";
|
std::cout << "RETURN [ ";
|
||||||
for (dev::bytes::const_iterator it = Runtime::getMemory().cbegin() + index, end = it + size; it != end; ++it)
|
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::hex << std::setw(2) << std::setfill('0') << (int)*it << " ";
|
||||||
std::cout << "]";
|
std::cout << "]\n";
|
||||||
|
|
||||||
return 10;
|
return 10;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@
|
||||||
namespace evmcc
|
namespace evmcc
|
||||||
{
|
{
|
||||||
|
|
||||||
|
BBStack::BBStack(Stack& _extStack)
|
||||||
|
: m_extStack(_extStack)
|
||||||
|
{}
|
||||||
|
|
||||||
void BBStack::push(llvm::Value* _value)
|
void BBStack::push(llvm::Value* _value)
|
||||||
{
|
{
|
||||||
m_state.push_back(_value);
|
m_state.push_back(_value);
|
||||||
|
|
@ -27,11 +31,31 @@ void BBStack::push(llvm::Value* _value)
|
||||||
|
|
||||||
llvm::Value* BBStack::pop()
|
llvm::Value* BBStack::pop()
|
||||||
{
|
{
|
||||||
|
if (m_state.empty())
|
||||||
|
return m_extStack.pop();
|
||||||
|
|
||||||
auto top = m_state.back();
|
auto top = m_state.back();
|
||||||
m_state.pop_back();
|
m_state.pop_back();
|
||||||
return top;
|
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)
|
void BBStack::dup(size_t _index)
|
||||||
{
|
{
|
||||||
auto value = *(m_state.rbegin() + _index);
|
auto value = *(m_state.rbegin() + _index);
|
||||||
|
|
|
||||||
|
|
@ -36,15 +36,31 @@ private:
|
||||||
class BBStack
|
class BBStack
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
//BBStack(llvm::IRBuilder<>& _builder, llvm::Module* _module);
|
BBStack(Stack& _extStack);
|
||||||
|
|
||||||
void push(llvm::Value* _value);
|
void push(llvm::Value* _value);
|
||||||
llvm::Value* pop();
|
llvm::Value* pop();
|
||||||
void dup(size_t _index);
|
void dup(size_t _index);
|
||||||
void swap(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:
|
private:
|
||||||
std::vector<llvm::Value*> m_state; ///< Basic black state vector - current values and their positions
|
std::vector<llvm::Value*> m_state; ///< Basic black state vector - current values and their positions
|
||||||
|
Stack& m_extStack; ///< External (global) stack
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
1
evmcc/bytecode/stackjump.evm
Normal file
1
evmcc/bytecode/stackjump.evm
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
600460066009601358600a036000545b6000f260005401600958
|
||||||
Loading…
Reference in a new issue