| Index: third_party/libxml/src/xpath.c
|
| diff --git a/third_party/libxml/src/xpath.c b/third_party/libxml/src/xpath.c
|
| index dc41ce6b327774adad749c3c58401f485b5a5f0c..533c7b7cd3e796ea7a226c9899357fd77075c6ae 100644
|
| --- a/third_party/libxml/src/xpath.c
|
| +++ b/third_party/libxml/src/xpath.c
|
| @@ -1132,6 +1132,7 @@ xmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2,
|
| comp->steps[comp->nbStep].value5 = value5;
|
| }
|
| comp->steps[comp->nbStep].cache = NULL;
|
| + comp->steps[comp->nbStep].cacheURI = NULL;
|
| return(comp->nbStep++);
|
| }
|
|
|
| @@ -14732,8 +14733,12 @@ xmlXPathTryStreamCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
|
| #endif /* XPATH_STREAMING */
|
|
|
| static void
|
| -xmlXPathOptimizeExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op)
|
| +xmlXPathOptimizeExpressionInternal(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op)
|
| {
|
| + /* Already optimized? */
|
| + if (op->cacheURI != NULL)
|
| + return;
|
| +
|
| /*
|
| * Try to rewrite "descendant-or-self::node()/foo" to an optimized
|
| * internal representation.
|
| @@ -14784,11 +14789,28 @@ xmlXPathOptimizeExpression(xmlXPathCompExprPtr comp, xmlXPathStepOpPtr op)
|
| }
|
| }
|
|
|
| + /* Mark the node. */
|
| + op->cacheURI = (void*)(~0);
|
| +
|
| /* Recurse */
|
| if (op->ch1 != -1)
|
| - xmlXPathOptimizeExpression(comp, &comp->steps[op->ch1]);
|
| + xmlXPathOptimizeExpressionInternal(comp, &comp->steps[op->ch1]);
|
| if (op->ch2 != -1)
|
| - xmlXPathOptimizeExpression(comp, &comp->steps[op->ch2]);
|
| + xmlXPathOptimizeExpressionInternal(comp, &comp->steps[op->ch2]);
|
| +}
|
| +
|
| +static void
|
| +xmlXPathOptimizeExpression(xmlXPathCompExprPtr comp, int root)
|
| +{
|
| + int i;
|
| + /* The expression tree/graph traversal is linear, visiting
|
| + * each node at most once. Mark each xmlXPathStepOp node
|
| + * upon visiting, taking care of clearing out the marks
|
| + * afterwards.
|
| + */
|
| + xmlXPathOptimizeExpressionInternal(comp, &comp->steps[root]);
|
| + for (i = 0; i <= root; ++i)
|
| + comp->steps[i].cacheURI = NULL;
|
| }
|
|
|
| /**
|
| @@ -14847,7 +14869,7 @@ xmlXPathCtxtCompile(xmlXPathContextPtr ctxt, const xmlChar *str) {
|
| comp->nb = 0;
|
| #endif
|
| if ((comp->nbStep > 1) && (comp->last >= 0)) {
|
| - xmlXPathOptimizeExpression(comp, &comp->steps[comp->last]);
|
| + xmlXPathOptimizeExpression(comp, comp->last);
|
| }
|
| }
|
| return(comp);
|
| @@ -15029,8 +15051,7 @@ xmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
|
| (ctxt->comp->nbStep > 1) &&
|
| (ctxt->comp->last >= 0))
|
| {
|
| - xmlXPathOptimizeExpression(ctxt->comp,
|
| - &ctxt->comp->steps[ctxt->comp->last]);
|
| + xmlXPathOptimizeExpression(ctxt->comp, ctxt->comp->last);
|
| }
|
| }
|
| CHECK_ERROR;
|
|
|