Merge pull request #2103 from chriseth/sol_fix_sequenceError

Invalid sequence access.
This commit is contained in:
Gav Wood 2015-06-07 14:19:51 +09:00
commit dc462dcb6e
3 changed files with 13 additions and 0 deletions

View File

@ -46,6 +46,7 @@ vector<AssemblyItem> CommonSubexpressionEliminator::getOptimizedItems()
targetStackContents[height] = m_state.stackElement(height, SourceLocation()); targetStackContents[height] = m_state.stackElement(height, SourceLocation());
AssemblyItems items = CSECodeGenerator(m_state.expressionClasses(), m_storeOperations).generateCode( AssemblyItems items = CSECodeGenerator(m_state.expressionClasses(), m_storeOperations).generateCode(
m_initialState.sequenceNumber(),
m_initialState.stackHeight(), m_initialState.stackHeight(),
initialStackContents, initialStackContents,
targetStackContents targetStackContents
@ -112,6 +113,7 @@ CSECodeGenerator::CSECodeGenerator(
} }
AssemblyItems CSECodeGenerator::generateCode( AssemblyItems CSECodeGenerator::generateCode(
unsigned _initialSequenceNumber,
int _initialStackHeight, int _initialStackHeight,
map<int, Id> const& _initialStack, map<int, Id> const& _initialStack,
map<int, Id> const& _targetStackContents map<int, Id> const& _targetStackContents
@ -137,7 +139,14 @@ AssemblyItems CSECodeGenerator::generateCode(
for (auto const& p: m_neededBy) for (auto const& p: m_neededBy)
for (auto id: {p.first, p.second}) for (auto id: {p.first, p.second})
if (unsigned seqNr = m_expressionClasses.representative(id).sequenceNumber) if (unsigned seqNr = m_expressionClasses.representative(id).sequenceNumber)
{
if (seqNr < _initialSequenceNumber)
// Invalid sequenced operation.
// @todo quick fix for now. Proper fix needs to choose representative with higher
// sequence number during dependency analyis.
BOOST_THROW_EXCEPTION(StackTooDeepException());
sequencedExpressions.insert(make_pair(seqNr, id)); sequencedExpressions.insert(make_pair(seqNr, id));
}
// Perform all operations on storage and memory in order, if they are needed. // Perform all operations on storage and memory in order, if they are needed.
for (auto const& seqAndId: sequencedExpressions) for (auto const& seqAndId: sequencedExpressions)

View File

@ -105,10 +105,13 @@ public:
CSECodeGenerator(ExpressionClasses& _expressionClasses, StoreOperations const& _storeOperations); CSECodeGenerator(ExpressionClasses& _expressionClasses, StoreOperations const& _storeOperations);
/// @returns the assembly items generated from the given requirements /// @returns the assembly items generated from the given requirements
/// @param _initialSequenceNumber starting sequence number, do not generate sequenced operations
/// before this number.
/// @param _initialStack current contents of the stack (up to stack height of zero) /// @param _initialStack current contents of the stack (up to stack height of zero)
/// @param _targetStackContents final contents of the stack, by stack height relative to initial /// @param _targetStackContents final contents of the stack, by stack height relative to initial
/// @note should only be called once on each object. /// @note should only be called once on each object.
AssemblyItems generateCode( AssemblyItems generateCode(
unsigned _initialSequenceNumber,
int _initialStackHeight, int _initialStackHeight,
std::map<int, Id> const& _initialStack, std::map<int, Id> const& _initialStack,
std::map<int, Id> const& _targetStackContents std::map<int, Id> const& _targetStackContents

View File

@ -94,6 +94,7 @@ public:
/// Resets any knowledge. /// Resets any knowledge.
void reset() { resetStorage(); resetMemory(); resetStack(); } void reset() { resetStorage(); resetMemory(); resetStack(); }
unsigned sequenceNumber() const { return m_sequenceNumber; }
/// Manually increments the storage and memory sequence number. /// Manually increments the storage and memory sequence number.
void incrementSequenceNumber() { m_sequenceNumber += 2; } void incrementSequenceNumber() { m_sequenceNumber += 2; }