From 6332bff81d806b60131dbf87eddba75c88e9d42a Mon Sep 17 00:00:00 2001 From: chriseth Date: Tue, 26 May 2015 11:27:59 +0200 Subject: Gas estimation for internal functions. --- GasEstimator.cpp | 44 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 35 insertions(+), 9 deletions(-) (limited to 'GasEstimator.cpp') diff --git a/GasEstimator.cpp b/GasEstimator.cpp index 18e3a5ca..01219a65 100644 --- a/GasEstimator.cpp +++ b/GasEstimator.cpp @@ -30,6 +30,7 @@ #include #include #include +#include using namespace std; using namespace dev; @@ -130,20 +131,45 @@ GasEstimator::GasConsumption GasEstimator::functionalEstimation( { auto state = make_shared(); - ExpressionClasses& classes = state->expressionClasses(); - using Id = ExpressionClasses::Id; - using Ids = vector; - Id hashValue = classes.find(u256(FixedHash<4>::Arith(FixedHash<4>(dev::sha3(_signature))))); - Id calldata = classes.find(eth::Instruction::CALLDATALOAD, Ids{classes.find(u256(0))}); - classes.forceEqual(hashValue, eth::Instruction::DIV, Ids{ - calldata, - classes.find(u256(1) << (8 * 28)) - }); + if (!_signature.empty()) + { + ExpressionClasses& classes = state->expressionClasses(); + using Id = ExpressionClasses::Id; + using Ids = vector; + Id hashValue = classes.find(u256(FixedHash<4>::Arith(FixedHash<4>(dev::sha3(_signature))))); + Id calldata = classes.find(eth::Instruction::CALLDATALOAD, Ids{classes.find(u256(0))}); + classes.forceEqual(hashValue, eth::Instruction::DIV, Ids{ + calldata, + classes.find(u256(1) << (8 * 28)) + }); + } PathGasMeter meter(_items); return meter.estimateMax(0, state); } +GasEstimator::GasConsumption GasEstimator::functionalEstimation( + AssemblyItems const& _items, + size_t const& _offset, + FunctionDefinition const& _function +) +{ + auto state = make_shared(); + + unsigned parametersSize = CompilerUtils::getSizeOnStack(_function.getParameters()); + if (parametersSize > 16) + return GasConsumption::infinite(); + + // Store an invalid return value on the stack, so that the path estimator breaks upon reaching + // the return jump. + AssemblyItem invalidTag(PushTag, u256(-0x10)); + state->feedItem(invalidTag, true); + if (parametersSize > 0) + state->feedItem(eth::swapInstruction(parametersSize)); + + return PathGasMeter(_items).estimateMax(_offset, state); +} + set GasEstimator::finestNodesAtLocation( vector const& _roots ) -- cgit v1.2.3