aboutsummaryrefslogtreecommitdiffstats
path: root/libevmasm/GasMeter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libevmasm/GasMeter.cpp')
-rw-r--r--libevmasm/GasMeter.cpp38
1 files changed, 25 insertions, 13 deletions
diff --git a/libevmasm/GasMeter.cpp b/libevmasm/GasMeter.cpp
index 21db3565..c96c6ca5 100644
--- a/libevmasm/GasMeter.cpp
+++ b/libevmasm/GasMeter.cpp
@@ -80,6 +80,7 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _
gas += GasCosts::sloadGas;
break;
case Instruction::RETURN:
+ case Instruction::REVERT:
gas += memoryGas(0, -1);
break;
case Instruction::MLOAD:
@@ -95,13 +96,14 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _
classes.find(AssemblyItem(1))
}));
break;
- case Instruction::SHA3:
- gas = GasCosts::sha3Gas;
- gas += wordGas(GasCosts::sha3WordGas, m_state->relativeStackElement(-1));
+ case Instruction::KECCAK256:
+ gas = GasCosts::keccak256Gas;
+ gas += wordGas(GasCosts::keccak256WordGas, m_state->relativeStackElement(-1));
gas += memoryGas(0, -1);
break;
case Instruction::CALLDATACOPY:
case Instruction::CODECOPY:
+ case Instruction::RETURNDATACOPY:
gas += memoryGas(0, -2);
gas += wordGas(GasCosts::copyGas, m_state->relativeStackElement(-2));
break;
@@ -127,6 +129,7 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _
case Instruction::CALL:
case Instruction::CALLCODE:
case Instruction::DELEGATECALL:
+ case Instruction::STATICCALL:
{
if (_includeExternalCosts)
// We assume that we do not know the target contract and thus, the consumption is infinite.
@@ -140,15 +143,22 @@ GasMeter::GasConsumption GasMeter::estimateMax(AssemblyItem const& _item, bool _
gas = GasConsumption::infinite();
if (_item.instruction() == Instruction::CALL)
gas += GasCosts::callNewAccountGas; // We very rarely know whether the address exists.
- int valueSize = _item.instruction() == Instruction::DELEGATECALL ? 0 : 1;
- if (!classes.knownZero(m_state->relativeStackElement(-1 - valueSize)))
+ int valueSize = 1;
+ if (_item.instruction() == Instruction::DELEGATECALL || _item.instruction() == Instruction::STATICCALL)
+ valueSize = 0;
+ else if (!classes.knownZero(m_state->relativeStackElement(-1 - valueSize)))
gas += GasCosts::callValueTransferGas;
gas += memoryGas(-2 - valueSize, -3 - valueSize);
gas += memoryGas(-4 - valueSize, -5 - valueSize);
}
break;
}
+ case Instruction::SELFDESTRUCT:
+ gas = GasCosts::selfdestructGas;
+ gas += GasCosts::callNewAccountGas; // We very rarely know whether the address exists.
+ break;
case Instruction::CREATE:
+ case Instruction::CREATE2:
if (_includeExternalCosts)
// We assume that we do not know the target contract and thus, the consumption is infinite.
gas = GasConsumption::infinite();
@@ -223,14 +233,16 @@ unsigned GasMeter::runGas(Instruction _instruction)
switch (instructionInfo(_instruction).gasPriceTier)
{
- case 0: return GasCosts::tier0Gas;
- case 1: return GasCosts::tier1Gas;
- case 2: return GasCosts::tier2Gas;
- case 3: return GasCosts::tier3Gas;
- case 4: return GasCosts::tier4Gas;
- case 5: return GasCosts::tier5Gas;
- case 6: return GasCosts::tier6Gas;
- case 7: return GasCosts::tier7Gas;
+ case Tier::Zero: return GasCosts::tier0Gas;
+ case Tier::Base: return GasCosts::tier1Gas;
+ case Tier::VeryLow: return GasCosts::tier2Gas;
+ case Tier::Low: return GasCosts::tier3Gas;
+ case Tier::Mid: return GasCosts::tier4Gas;
+ case Tier::High: return GasCosts::tier5Gas;
+ case Tier::Ext: return GasCosts::tier6Gas;
+ case Tier::Special: return GasCosts::tier7Gas;
+ case Tier::ExtCode: return GasCosts::extCodeGas;
+ case Tier::Balance: return GasCosts::balanceGas;
default: break;
}
assertThrow(false, OptimizerException, "Invalid gas tier.");