MCPcopy Create free account
hub / github.com/argotorg/solidity / handleQueueItem

Method handleQueueItem

libevmasm/PathGasMeter.cpp:65–139  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

63}
64
65GasMeter::GasConsumption PathGasMeter::handleQueueItem()
66{
67 assertThrow(!m_queue.empty(), OptimizerException, "");
68
69 std::unique_ptr<GasPath> path = std::move(m_queue.rbegin()->second);
70 m_queue.erase(--m_queue.end());
71
72 std::shared_ptr<KnownState> state = path->state;
73 GasMeter meter(state, m_evmVersion, path->largestMemoryAccess);
74 ExpressionClasses& classes = state->expressionClasses();
75 GasMeter::GasConsumption gas = path->gas;
76 size_t index = path->index;
77
78 if (index >= m_items.size() || (index > 0 && m_items.at(index).type() != Tag))
79 // Invalid jump usually provokes an out-of-gas exception, but we want to give an upper
80 // bound on the gas that is needed without changing the behaviour, so it is fine to
81 // return the current gas value.
82 return gas;
83
84 std::set<u256> jumpTags;
85 for (; index < m_items.size() && !gas.isInfinite; ++index)
86 {
87 bool branchStops = false;
88 jumpTags.clear();
89 AssemblyItem const& item = m_items.at(index);
90 if (item.type() == Tag || item == AssemblyItem(Instruction::JUMPDEST))
91 {
92 // Do not allow any backwards jump. This is quite restrictive but should work for
93 // the simplest things.
94 if (path->visitedJumpdests.count(index))
95 return GasMeter::GasConsumption::infinite();
96 path->visitedJumpdests.insert(index);
97 }
98 else if (item == AssemblyItem(Instruction::JUMP))
99 {
100 branchStops = true;
101 jumpTags = state->tagsInExpression(state->relativeStackElement(0));
102 if (jumpTags.empty()) // unknown jump destination
103 return GasMeter::GasConsumption::infinite();
104 }
105 else if (item == AssemblyItem(Instruction::JUMPI))
106 {
107 ExpressionClasses::Id condition = state->relativeStackElement(-1);
108 if (classes.knownNonZero(condition) || !classes.knownZero(condition))
109 {
110 jumpTags = state->tagsInExpression(state->relativeStackElement(0));
111 if (jumpTags.empty()) // unknown jump destination
112 return GasMeter::GasConsumption::infinite();
113 }
114 branchStops = classes.knownNonZero(condition);
115 }
116 else if (SemanticInformation::altersControlFlow(item))
117 branchStops = true;
118
119 gas += meter.estimateMax(item);
120
121 for (u256 const& tag: jumpTags)
122 {

Callers

nothing calls this directly

Calls 15

eraseMethod · 0.80
atMethod · 0.80
insertMethod · 0.80
tagsInExpressionMethod · 0.80
relativeStackElementMethod · 0.80
knownNonZeroMethod · 0.80
knownZeroMethod · 0.80
AssemblyItemClass · 0.70
emptyMethod · 0.45
endMethod · 0.45
sizeMethod · 0.45
typeMethod · 0.45

Tested by

no test coverage detected