Browse Source

Count gas for CALL instructions

[#79942174]
cl-refactor
Paweł Bylica 10 years ago
parent
commit
fb87a0b2ab
  1. 1
      evmcc/Compiler.cpp
  2. 21
      evmcc/GasMeter.cpp
  3. 5
      evmcc/GasMeter.h

1
evmcc/Compiler.cpp

@ -784,6 +784,7 @@ std::unique_ptr<llvm::Module> Compiler::compile(const dev::bytes& bytecode)
auto outOff = stack.pop();
auto outSize = stack.pop();
gasMeter.commitCostBlock(gas);
auto ret = ext.call(gas, receiveAddress, value, inOff, inSize, outOff, outSize);
stack.push(ret);
break;

21
evmcc/GasMeter.cpp

@ -53,6 +53,9 @@ bool isCostBlockEnd(Instruction _inst)
{
// Basic block terminators like STOP are not needed on the list
// as cost will be commited at the end of basic block
// CALL & CALLCODE are commited manually
switch (_inst)
{
case Instruction::CALLDATACOPY:
@ -63,8 +66,6 @@ bool isCostBlockEnd(Instruction _inst)
case Instruction::SSTORE:
case Instruction::GAS:
case Instruction::CREATE:
case Instruction::CALL:
case Instruction::CALLCODE:
return true;
default:
@ -107,16 +108,24 @@ void GasMeter::count(Instruction _inst)
commitCostBlock();
}
void GasMeter::commitCostBlock()
void GasMeter::commitCostBlock(llvm::Value* _additionalCost)
{
assert(!_additionalCost || m_checkCall); // _additionalCost => m_checkCall; Must be inside cost-block
// If any uncommited block
if (m_checkCall)
{
if (m_blockCost > 0) // If any cost
m_checkCall->setArgOperand(0, Constant::get(m_blockCost)); // Update block cost in gas check call
else
if (m_blockCost == 0 && !_additionalCost) // Do not check 0
{
m_checkCall->eraseFromParent(); // Remove the gas check call
return;
}
llvm::Value* cost = Constant::get(m_blockCost);
if (_additionalCost)
cost = m_builder.CreateAdd(cost, _additionalCost);
m_checkCall->setArgOperand(0, cost); // Update block cost in gas check call
m_checkCall = nullptr; // End cost-block
m_blockCost = 0;
}

5
evmcc/GasMeter.h

@ -19,8 +19,9 @@ public:
/// Count step cost of instruction
void count(dev::eth::Instruction _inst);
/// Finalize cost block by checking gas needed for the block before the block
void commitCostBlock();
/// Finalize cost-block by checking gas needed for the block before the block
/// @param _additionalCost adds additional cost to cost-block before commit
void commitCostBlock(llvm::Value* _additionalCost = nullptr);
/// Generate code that checks the cost of additional memory used by program
void checkMemory(llvm::Value* _additionalMemoryInWords, llvm::IRBuilder<>& _builder);

Loading…
Cancel
Save