Browse Source

Report error if static-analysed stack is too small

cl-refactor
Paweł Bylica 10 years ago
parent
commit
b56a815d2c
  1. 26
      evmcc/Compiler.cpp
  2. 2
      evmcc/GasMeter.cpp
  3. 2
      evmcc/test/jump/loop1.evm
  4. 12
      evmcc/test/jump/loop1.lll
  5. 2
      evmcc/test/jump/loop2.evm
  6. 16
      evmcc/test/jump/loop2.lll

26
evmcc/Compiler.cpp

@ -882,17 +882,22 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
void Compiler::linkBasicBlocks()
{
/// Helper function that finds basic block given LLVM basic block pointer
auto findBasicBlock = [this](llvm::BasicBlock* _llbb) -> BasicBlock&
auto findBasicBlock = [this](llvm::BasicBlock* _llbb) -> BasicBlock*
{
// TODO: Fix for finding jumpTableBlock
if (_llbb == this->m_jumpTableBlock->llvm())
return *this->m_jumpTableBlock;
return this->m_jumpTableBlock.get();
for (auto&& bb : this->basicBlocks)
if (_llbb == bb.second.llvm())
return &bb.second;
return nullptr;
// Name is used to get basic block index (index of first instruction)
// TODO: If basicBlocs are still a map - multikey map can be used
auto&& idxStr = _llbb->getName().substr(sizeof(BasicBlock::NamePrefix) - 2);
auto idx = std::stoul(idxStr);
return basicBlocks.find(idx)->second;
//auto&& idxStr = _llbb->getName().substr(sizeof(BasicBlock::NamePrefix) - 2);
//auto idx = std::stoul(idxStr);
//return basicBlocks.find(idx)->second;
};
auto completePhiNodes = [findBasicBlock](llvm::BasicBlock* _llbb) -> void
@ -905,9 +910,14 @@ void Compiler::linkBasicBlocks()
for (auto predIt = llvm::pred_begin(_llbb); predIt != llvm::pred_end(_llbb); ++predIt)
{
// TODO: In case entry block is reached - report error
auto& predBB = findBasicBlock(*predIt);
auto value = predBB.getStack().get(valueIdx);
phi->addIncoming(value, predBB);
auto predBB = findBasicBlock(*predIt);
if (!predBB)
{
std::cerr << "Stack too small in " << _llbb->getName().str() << std::endl;
std::exit(1);
}
auto value = predBB->getStack().get(valueIdx);
phi->addIncoming(value, predBB->llvm());
}
}
};

2
evmcc/GasMeter.cpp

@ -45,7 +45,7 @@ uint64_t getStepCost(dev::eth::Instruction inst) // TODO: Add this function to F
return static_cast<uint64_t>(c_createGas);
default: // Assumes instruction code is valid
return static_cast<uint64_t>(c_stepGas);;
return static_cast<uint64_t>(c_stepGas);
}
}

2
evmcc/test/jump/loop1.evm

@ -1 +1 @@
600a600181038060025900
600a600181038060025960005460015460025400

12
evmcc/test/jump/loop1.lll

@ -12,12 +12,12 @@ DUP1
JUMPI
;; stack = 1 2 3 4 5 6 7 8 9 10
;;0
;;MSTORE
;;1
;;MSTORE
;;2
;;MSTORE
0
MSTORE
1
MSTORE
2
MSTORE
;;3
;;MSTORE

2
evmcc/test/jump/loop2.evm

@ -1 +1 @@
600a80600160800360a060025900
600a80600190038060025960005460015460025400

16
evmcc/test/jump/loop2.lll

@ -6,19 +6,19 @@
;; 2
DUP1
1
SWAP
SWAP1
SUB
DUP
DUP1
2
JUMPI
;; stack = 1 2 3 4 5 6 7 8 9 10
;;0
;;MSTORE
;;1
;;MSTORE
;;2
;;MSTORE
0
MSTORE
1
MSTORE
2
MSTORE
;;3
;;MSTORE

Loading…
Cancel
Save