Project

Profile

Help

Bug #4259

closed

Interaction of try/catch and tail recursion

Added by Michael Kay almost 5 years ago. Updated over 4 years ago.

Status:
Closed
Priority:
Low
Assignee:
Category:
-
Sprint/Milestone:
-
Start date:
2019-07-19
Due date:
% Done:

0%

Estimated time:
Legacy ID:
Applies to branch:
Fix Committed on Branch:
Fixed in Maintenance Release:
Platforms:

Description

In private email to support, a question is raised about the interaction between try/catch and tail recursion. Example code:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:ixsl="http://saxonica.com/ns/interactiveXSLT"
  exclude-result-prefixes="xs"
  version="3.0">
  
  <xsl:template match="/">
    <xsl:call-template name="computation"/>
  </xsl:template>
  
  <xsl:template name="computation">
    <xsl:param name="index" as="xs:integer" select="1"/>
    <xsl:param name="someparam" as="element()" select="/*"/>    
    <xsl:value-of select="'&#10;' || $index"/>
    <xsl:choose>
      <xsl:when test="$index ge 10">
        <xsl:text>&#10;Done.</xsl:text>
      </xsl:when>
      <xsl:otherwise>
        <xsl:try>
          <xsl:message>&#10;Reached try block for index <xsl:value-of select="$index"/></xsl:message>
          <xsl:text>&#10;Reached try block for index </xsl:text><xsl:value-of select="$index"/>
          
          <!-- Error A: $someparam is empty, which does not match the required data type. -->
          <xsl:call-template name="computation">
            <xsl:with-param name="index" select="$index + 1"/>
            <xsl:with-param name="someparam" select="/nonexistent"/>
          </xsl:call-template>
          <!-- Error B: ixsl:schedule-action raises an error in Saxon-EE.
          <ixsl:schedule-action wait="10">
            <xsl:call-template name="computation">
              <xsl:with-param name="index" select="$index + 1"/>
            </xsl:call-template>
          </ixsl:schedule-action>-->
          <xsl:catch>
            <xsl:message>&#10;Reached catch block for index <xsl:value-of select="$index"/></xsl:message>
            <xsl:text>&#10;Reached catch block for index </xsl:text><xsl:value-of select="$index"/>
            <xsl:call-template name="computation">
              <xsl:with-param name="index" select="$index + 1"/>
            </xsl:call-template>
          </xsl:catch>          
        </xsl:try>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

We need to test whether we are getting this right. If we treat the tail call in the xsl:try in the normal way by doing the recursive call after unwinding the stack frame, then it seems likely that we'll lose the ability to catch any errors.

Need to construct a test case for this.

Actions #1

Updated by Michael Kay over 4 years ago

  • Status changed from New to Closed

After studying the code, I have persuaded myself there is no issue here. A tail call on xsl:call-template or xsl:apply-templates is recognized only if it is the last instruction in a template, or if it appears in a few very well-defined contexts such as xsl:if and xsl:choose. It won't be recognized as a tail call with xsl:try.

Please register to edit this issue

Also available in: Atom PDF