Bug #6380
closedInternal error when match pattern invoked by xsl:next-match refers to global variable
100%
Description
Email on saxonica support
Updated by Michael Kay 9 months ago
Root cause: class net.sf.saxon.expr.instruct.UserFunction cannot be cast to class net.sf.saxon.expr.instruct.GlobalVariable (net.sf.saxon.expr.instruct.UserFunction
Caused by: java.lang.ClassCastException: class net.sf.saxon.expr.instruct.UserFunction cannot be cast to class net.sf.saxon.expr.instruct.GlobalVariable (net.sf.saxon.expr.instruct.UserFunction and net.sf.saxon.expr.instruct.GlobalVariable are in unnamed module of loader 'app')
at net.sf.saxon.expr.GlobalVariableReference.evaluateVariable(GlobalVariableReference.java:126)
at net.sf.saxon.expr.GlobalVariableReference$GlobalVariableReferenceElaborator.lambda$elaborateForItem$2(GlobalVariableReference.java:228)
at net.sf.saxon.expr.ValueComparison$ValueComparisonElaborator.lambda$elaborateForBoolean$4(ValueComparison.java:609)
at net.sf.saxon.expr.AndExpression$AndElaborator.lambda$elaborateForBoolean$0(AndExpression.java:212)
at net.sf.saxon.expr.FilterExpression$FilterExprElaborator$SimpleFilteredIterator.next(FilterExpression.java:1472)
at net.sf.saxon.expr.parser.ExpressionTool.effectiveBooleanValue(ExpressionTool.java:664)
at net.sf.saxon.expr.elab.PullElaborator.lambda$elaborateForBoolean$2(PullElaborator.java:65)
at net.sf.saxon.pattern.BasePatternWithPredicate.matchesPredicate(BasePatternWithPredicate.java:141)
at net.sf.saxon.pattern.BasePatternWithPredicate.matches(BasePatternWithPredicate.java:129)
at net.sf.saxon.pattern.Pattern.matchesItem(Pattern.java:268)
at net.sf.saxon.trans.rules.Rule.matches(Rule.java:240)
at com.saxonica.ee.trans.ModeEE.ruleMatches(ModeEE.java:142)
at net.sf.saxon.trans.SimpleMode.searchRuleChain(SimpleMode.java:896)
at net.sf.saxon.trans.SimpleMode.getRule(SimpleMode.java:786)
at net.sf.saxon.trans.Mode.getNextMatchRule(Mode.java:378)
at net.sf.saxon.expr.instruct.NextMatch$NextMatchElaborator.lambda$elaborateForPush$0(NextMatch.java:221)
at net.sf.saxon.expr.instruct.Choose$ChooseExprElaborator.lambda$elaborateForPush$10(Choose.java:1177)
at net.sf.saxon.expr.instruct.Choose$ChooseExprElaborator.lambda$elaborateForPush$12(Choose.java:1188)
at net.sf.saxon.expr.instruct.NamedTemplate.expand(NamedTemplate.java:247)
at net.sf.saxon.expr.instruct.CallTemplate$CallTemplatePackage.processLeavingTail(CallTemplate.java:515)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:476)
Updated by Michael Kay 9 months ago
It seems that the currentComponent in the context is wrong, so it's attempting to reference a global variable using the wrong binding slot number, and the slot that it's using is a reference to a user function rather than a global variable.
The variable it's trying to access is $logic.master in the match pattern predicate match="tr[td[1][choice and (count(child::*) eq 1) and $logic.master = false()]]
(line 158 of eoc_preprocess.xsl
). The current component is a named template, which I think is wrong: for evaluating match patterns I think the current component should be the mode.
Updated by Michael Kay 9 months ago
The Mode object has stackFrameSlotsNeeded
=0, which means it's not going to create a new context for evaluating the match patterns, which means that the current component isn't going to be set (see Mode.makeNewContext()
). Note there's a comment here pointing to bug #3706.
The theory is that stackFrameSlotsNeeded should be non-zero if there are any match patterns in the Mode that contain local variables. But in this case the reference is to a global variable.
If I artificially introduce a local variable in the match pattern, making it
<xsl:template match="tr[td[1][let $c := child::* return choice and (count($c) eq 1) and $logic.master = false()]]">
then the problem goes away.
Updated by Michael Kay 9 months ago
- Subject changed from Internal error evaluating template rule at line 320 to Internal error evaluating template rule at line 320 (match pattern refers to global variable)
- Category set to Internals
- Status changed from New to In Progress
Updated by Michael Kay 9 months ago
BasePatternWithPredicate.matchesPredicate
creates a new XPathContext object, but it doesn't change the current component to be the Mode.
In fact, it doesn't know the Mode.
I think it's relevant that we're in xsl:next-match
rather than xsl:apply-templates
. ApplyTemplates line 643 appears to create a new context unconditionally, and to set the current component at that point. This logic is missing from NextMatch.
Updated by Michael Kay 9 months ago
- Subject changed from Internal error evaluating template rule at line 320 (match pattern refers to global variable) to Internal error when match pattern invoked by xsl:next-match refers to global variable
Updated by Michael Kay 9 months ago
- Status changed from In Progress to Resolved
- Applies to branch 12, trunk added
- Fix Committed on Branch 12, trunk added
- Platforms .NET, Java added
Patch regression tested, will go out in next maintenance release.
Updated by O'Neil Delpratt 6 months ago
- Status changed from Resolved to Closed
- % Done changed from 0 to 100
- Fixed in Maintenance Release 12.5 added
Bug fix applied in the Saxon 12.5 Maintenance release.
Please register to edit this issue