Use a heap-memory traversal to free compiler resources.
The stack-memory traversal is prone to stack overflow. See the
WebGL conformance test long-expressions-should-not-crash.
BUG=angle:584
Change-Id: I02d72bc2e4101b7141d609c50303403ea8298e60
Reviewed-on: https://chromium-review.googlesource.com/191930
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Nicolas Capens <nicolascapens@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/Intermediate.cpp b/src/compiler/translator/Intermediate.cpp
index 74b9a6e..9df2afc 100644
--- a/src/compiler/translator/Intermediate.cpp
+++ b/src/compiler/translator/Intermediate.cpp
@@ -786,6 +786,26 @@
return false;
}
+void TIntermLoop::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const
+{
+ if (init)
+ {
+ nodeQueue->push(init);
+ }
+ if (cond)
+ {
+ nodeQueue->push(cond);
+ }
+ if (expr)
+ {
+ nodeQueue->push(expr);
+ }
+ if (body)
+ {
+ nodeQueue->push(body);
+ }
+}
+
bool TIntermBranch::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
@@ -793,6 +813,14 @@
return false;
}
+void TIntermBranch::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const
+{
+ if (expression)
+ {
+ nodeQueue->push(expression);
+ }
+}
+
bool TIntermBinary::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
@@ -801,6 +829,18 @@
return false;
}
+void TIntermBinary::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const
+{
+ if (left)
+ {
+ nodeQueue->push(left);
+ }
+ if (right)
+ {
+ nodeQueue->push(right);
+ }
+}
+
bool TIntermUnary::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
@@ -808,6 +848,14 @@
return false;
}
+void TIntermUnary::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const
+{
+ if (operand)
+ {
+ nodeQueue->push(operand);
+ }
+}
+
bool TIntermAggregate::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
@@ -818,6 +866,14 @@
return false;
}
+void TIntermAggregate::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const
+{
+ for (size_t childIndex = 0; childIndex < sequence.size(); childIndex++)
+ {
+ nodeQueue->push(sequence[childIndex]);
+ }
+}
+
bool TIntermSelection::replaceChildNode(
TIntermNode *original, TIntermNode *replacement)
{
@@ -827,6 +883,22 @@
return false;
}
+void TIntermSelection::enqueueChildren(std::queue<TIntermNode*> *nodeQueue) const
+{
+ if (condition)
+ {
+ nodeQueue->push(condition);
+ }
+ if (trueBlock)
+ {
+ nodeQueue->push(trueBlock);
+ }
+ if (falseBlock)
+ {
+ nodeQueue->push(falseBlock);
+ }
+}
+
//
// Say whether or not an operation node changes the value of a variable.
//