Commit 0ea959f4 by Olli Etuaho

Unfold sequence operator when operations inside need unfolding

Unfolding the sequence operator ensures correct evaluation order when parts of the expression need to get hoisted out of the expression to the surrounding scope. BUG=angleproject:1001 TEST=WebGL conformance tests Change-Id: Ifd3093c9fb63d3e9842ebb4b9531b2f46875ad8a Reviewed-on: https://chromium-review.googlesource.com/270660Tested-by: 's avatarOlli Etuaho <oetuaho@nvidia.com> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent d81ed841
...@@ -208,6 +208,9 @@ bool UnfoldShortCircuitTraverser::visitSelection(Visit visit, TIntermSelection * ...@@ -208,6 +208,9 @@ bool UnfoldShortCircuitTraverser::visitSelection(Visit visit, TIntermSelection *
bool UnfoldShortCircuitTraverser::visitAggregate(Visit visit, TIntermAggregate *node) bool UnfoldShortCircuitTraverser::visitAggregate(Visit visit, TIntermAggregate *node)
{ {
if (visit == PreVisit && mFoundShortCircuit)
return false; // No need to traverse further
if (node->getOp() == EOpSequence) if (node->getOp() == EOpSequence)
{ {
if (visit == PreVisit) if (visit == PreVisit)
...@@ -224,6 +227,40 @@ bool UnfoldShortCircuitTraverser::visitAggregate(Visit visit, TIntermAggregate * ...@@ -224,6 +227,40 @@ bool UnfoldShortCircuitTraverser::visitAggregate(Visit visit, TIntermAggregate *
mParentBlockStack.pop_back(); mParentBlockStack.pop_back();
} }
} }
else if (node->getOp() == EOpComma)
{
ASSERT(visit != PreVisit || !mFoundShortCircuit);
if (visit == PostVisit && mFoundShortCircuit)
{
// We can be sure that we arrived here because there was a short-circuiting operator
// inside the sequence operator since we only start traversing the sequence operator in
// case a short-circuiting operator has not been found so far.
// We need to unfold the sequence (comma) operator, otherwise the evaluation order of
// statements would be messed up by unfolded operations inside.
// Don't do any other unfolding on this round of traversal.
mReplacements.clear();
mMultiReplacements.clear();
mInsertions.clear();
TIntermSequence insertions;
TIntermSequence *seq = node->getSequence();
TIntermSequence::size_type i = 0;
ASSERT(!seq->empty());
while (i < seq->size() - 1)
{
TIntermTyped *child = (*seq)[i]->getAsTyped();
insertions.push_back(child);
++i;
}
NodeInsertMultipleEntry insert(mParentBlockStack.back().node, mParentBlockStack.back().pos, insertions);
mInsertions.push_back(insert);
NodeUpdateEntry replaceVariable(getParentNode(), node, (*seq)[i], false);
mReplacements.push_back(replaceVariable);
}
}
return true; return true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment