diff --git a/evmcc/Compiler.cpp b/evmcc/Compiler.cpp index 9a46313b6..0e695df06 100644 --- a/evmcc/Compiler.cpp +++ b/evmcc/Compiler.cpp @@ -178,8 +178,7 @@ std::unique_ptr Compiler::compile(const dev::bytes& bytecode) { auto inst = static_cast(bytecode[currentPC]); - // Disable for now - //gasMeter.check(inst); + gasMeter.check(inst); switch (inst) { diff --git a/evmcc/GasMeter.cpp b/evmcc/GasMeter.cpp index 2006f319f..a40b8cb5c 100644 --- a/evmcc/GasMeter.cpp +++ b/evmcc/GasMeter.cpp @@ -49,6 +49,33 @@ uint64_t getStepCost(dev::eth::Instruction inst) // TODO: Add this function to F } } +bool isCommitTrigger(Instruction _inst) +{ + switch (_inst) + { + case Instruction::STOP: + case Instruction::CALLDATACOPY: + case Instruction::CODECOPY: + case Instruction::MLOAD: + case Instruction::MSTORE: + case Instruction::MSTORE8: + case Instruction::SSTORE: + case Instruction::JUMP: + case Instruction::JUMPI: + case Instruction::JUMPDEST: + case Instruction::GAS: + case Instruction::CREATE: + case Instruction::CALL: + case Instruction::CALLCODE: + case Instruction::RETURN: + case Instruction::SUICIDE: + return true; + + default: + return false; + } +} + } GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module): @@ -72,8 +99,20 @@ GasMeter::GasMeter(llvm::IRBuilder<>& _builder, llvm::Module* _module): void GasMeter::check(Instruction _inst) { + if (!m_checkCall) + { + m_checkCall = m_builder.CreateCall(m_gasCheckFunc, m_builder.getIntN(256, 0)); + } + auto stepCost = getStepCost(_inst); - m_builder.CreateCall(m_gasCheckFunc, m_builder.getIntN(256, stepCost)); + m_blockCost += stepCost; + + auto isTrigger = isCommitTrigger(_inst); + if (isTrigger) + { + m_checkCall->setArgOperand(0, m_builder.getIntN(256, m_blockCost)); + m_checkCall = nullptr; + } } } \ No newline at end of file diff --git a/evmcc/GasMeter.h b/evmcc/GasMeter.h index e2ee26a71..057391102 100644 --- a/evmcc/GasMeter.h +++ b/evmcc/GasMeter.h @@ -19,7 +19,11 @@ public: void check(dev::eth::Instruction _inst); private: + /// Cumulative gas cost of a block of instructions + /// @TODO Handle overflow + uint64_t m_blockCost = 0; llvm::IRBuilder<>& m_builder; + llvm::CallInst* m_checkCall; llvm::GlobalVariable* m_gas; llvm::Function* m_gasCheckFunc; };