Project

Profile

Help

Bug #5845

closed

Migrating TEI stylesheets to 12.0 produces XPDY0002 (context item is absent)

Added by Michael Kay about 1 year ago. Updated about 1 year ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Internals
Sprint/Milestone:
-
Start date:
2023-01-22
Due date:
% Done:

100%

Estimated time:
Legacy ID:
Applies to branch:
12, trunk
Fix Committed on Branch:
12, trunk
Fixed in Maintenance Release:
Platforms:
.NET, Java

Description

Actions #1

Updated by Michael Kay about 1 year ago

I've managed to breakpoint at the point of failure.

It's failed during the deferred (lazy) evaluation of the parameter on line 708 of verbatim.xsl

<xsl:with-param name="content" select="string(@name)"/>

because the saved context for lazy evaluation has no context item.

Looking backwards, it appears that the template verbatim-nextAttribute was called with no context item. The call was from line 670 of the same module, and the puzzling thing is that it is a tail call; the xsl:call-template instruction is within an xsl:for-each loop so this feels wrong. It's still within the xsl:for-each at run-time so it doesn't look like an incorrect expression rewrite.

Actions #2

Updated by Michael Kay about 1 year ago

The logic in XSLForEach.markTailCalls() is prepared to treat the last instruction in the for-each body as a tail call if the select attribute is known to return a single item, which is the case here (in $Atts/*[1], $Atts is a single document node, so *[1] selects zero or one elements).

Actions #3

Updated by Michael Kay about 1 year ago

Observed that at the time we create the CallTemplatePackage for the tail call, it is saved with an evaluation context whose current item is the element selected by the xsl:for-each; but when we come to evaluate the CallTemplatePackage, the current item is null. I'm slightly surprised that we aren't saving a snapshot of the context as it is a mutable object, but this seems to be unchanged from 11.x.

So it's clear what's going wrong: within the ForEach, we create a CallTemplatePackage with a reference to a context containing a current iterator which is the select iterator of the ForEach; the ForEach then resumes and does iterator.next() on this iterator, setting the context item to null, and this is the state in which it is found when the CallTemplatePackage then gets executed.

What's not clear is why Saxon 11 didn't fail in exactly the same way.

Actions #4

Updated by Michael Kay about 1 year ago

It seems that in Saxon 11 ForEach there is a special path for a ForEach instruction that contains a tail call; this has not been replicated in the new elaboration code. The special path ensures that after processing the single item in the select expression, the focus iterator is not advanced any further.

Added the corresponding path to the elaboration code, and fixed the fact that ForEach.containsTailCall was no longer being set.

The test case now appears to be working; regression testing needed.

Looking at the elaboration code, I'm not convinced its making all the right calls to the TraceListener when tracing is enabled.

Actions #5

Updated by Michael Kay about 1 year ago

Also noted, the property ForEach.containsTailCall does not survive exporting to a SEF file. This is equally true in 11.x.

Actions #6

Updated by Michael Kay about 1 year ago

  • Status changed from In Progress to Resolved
  • Fix Committed on Branch 12, trunk added
  • Platforms .NET, Java added

Added test case call-template-1003

Actions #7

Updated by O'Neil Delpratt about 1 year ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100
  • Fixed in Maintenance Release 12.1 added

Bug fix applied in the Saxon 12.1 maintenance release.

Please register to edit this issue

Also available in: Atom PDF