Browse Source

Count gas for CALL instructions

[#79942174]
cl-refactor
Paweł Bylica 10 years ago
parent
commit
fb87a0b2ab
  1. 1
      evmcc/Compiler.cpp
  2. 23
      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 outOff = stack.pop();
auto outSize = stack.pop(); auto outSize = stack.pop();
gasMeter.commitCostBlock(gas);
auto ret = ext.call(gas, receiveAddress, value, inOff, inSize, outOff, outSize); auto ret = ext.call(gas, receiveAddress, value, inOff, inSize, outOff, outSize);
stack.push(ret); stack.push(ret);
break; break;

23
evmcc/GasMeter.cpp

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

5
evmcc/GasMeter.h

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

Loading…
Cancel
Save