[libxslt] Don't cache direct evaluation of patterns with variables
- From: Nick Wellnhofer <nwellnhof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libxslt] Don't cache direct evaluation of patterns with variables
- Date: Wed, 21 Nov 2018 16:41:32 +0000 (UTC)
commit a846514a159a2524266b57d8aae47b66572d0b0a
Author: Nick Wellnhofer <wellnhofer aevum de>
Date: Wed Nov 21 17:12:17 2018 +0100
Don't cache direct evaluation of patterns with variables
The slow pattern matching path in xsltTestCompMatchDirect caches the
result of evaluating the pattern. But this can't be done if the pattern
contains variables which could evaluate to different values.
Only enable the cache for patterns like template matches that don't
allow variable references. Don't use the cache for "count" and "from"
patterns in xsl:number.
A more fine-grained approach would be nice, but most effort should be
spent on eliminating the slow path completely.
Thanks to Martin Honnen for the report.
Fixes #6.
libxslt/pattern.c | 5 ++++-
tests/docs/bug-214.xml | 6 ++++++
tests/general/bug-214.out | 6 ++++++
tests/general/bug-214.xsl | 25 +++++++++++++++++++++++++
4 files changed, 41 insertions(+), 1 deletion(-)
---
diff --git a/libxslt/pattern.c b/libxslt/pattern.c
index 07f11f9b..7d660192 100644
--- a/libxslt/pattern.c
+++ b/libxslt/pattern.c
@@ -113,6 +113,7 @@ struct _xsltCompMatch {
xmlNsPtr *nsList; /* the namespaces in scope */
int nsNr; /* the number of namespaces in scope */
xsltStepOpPtr steps; /* ops for computation */
+ int novar; /* doesn't contain variables */
};
typedef struct _xsltParserContext xsltParserContext;
@@ -594,7 +595,8 @@ xsltTestCompMatchDirect(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
}
ix = 0;
- if ((parent == NULL) || (node->doc == NULL) || isRVT)
+ if ((parent == NULL) || (node->doc == NULL) || isRVT ||
+ (comp->novar == 0))
nocache = 1;
if (nocache == 0) {
@@ -1970,6 +1972,7 @@ xsltCompilePatternInternal(const xmlChar *pattern, xmlDocPtr doc,
j++;
}
element->nsNr = j;
+ element->novar = novar;
#ifdef WITH_XSLT_DEBUG_PATTERN
diff --git a/tests/docs/bug-214.xml b/tests/docs/bug-214.xml
new file mode 100644
index 00000000..196b8025
--- /dev/null
+++ b/tests/docs/bug-214.xml
@@ -0,0 +1,6 @@
+<root>
+ <element type="a"/>
+ <element type="b"/>
+ <element type="a"/>
+</root>
+
diff --git a/tests/general/bug-214.out b/tests/general/bug-214.out
new file mode 100644
index 00000000..e51e7097
--- /dev/null
+++ b/tests/general/bug-214.out
@@ -0,0 +1,6 @@
+<?xml version="1.0"?>
+<root>
+ <element type="a" pos="1"/>
+ <element type="b" pos="1"/>
+ <element type="a" pos="2"/>
+</root>
diff --git a/tests/general/bug-214.xsl b/tests/general/bug-214.xsl
new file mode 100644
index 00000000..52243113
--- /dev/null
+++ b/tests/general/bug-214.xsl
@@ -0,0 +1,25 @@
+<xsl:stylesheet
+ xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+ <xsl:template match="@* | node()">
+ <xsl:copy>
+ <xsl:apply-templates select="@* | node()"/>
+ </xsl:copy>
+ </xsl:template>
+
+ <xsl:template match="*[@type]">
+ <xsl:copy>
+ <xsl:variable name="type" select="@type"/>
+ <xsl:variable name="pos">
+ <xsl:number count="node()[@type = $type]"/>
+ </xsl:variable>
+ <xsl:apply-templates select="@*"/>
+ <xsl:attribute name="pos">
+ <xsl:value-of select="$pos"/>
+ </xsl:attribute>
+ <xsl:apply-templates/>
+ </xsl:copy>
+ </xsl:template>
+
+</xsl:stylesheet>
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]