Project

Profile

Help

Bug #3467

closed

Difference in evaluation between PE and EE (Saxon 9.7.0.20)

Added by Radu Coravu over 6 years ago. Updated over 6 years ago.

Status:
Closed
Priority:
Normal
Assignee:
Category:
Internals
Sprint/Milestone:
-
Start date:
2017-10-03
Due date:
% Done:

100%

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

Description

One of our users posted an example here:

https://www.oxygenxml.com/forum/post44286.html#p44283

So the test.xml is:

<root filePath="../../../grammars/efl/infoCommentaire/xf_infoCommentaire.srng"/>

and the test.xsl is:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:els="http://www.lefebvre-sarrut.eu/ns/els"
    xmlns:functx="http://www.functx.com"
    exclude-result-prefixes="#all"
    version="2.0">
    
    <!--<xsl:include href="functx.xsl"/>-->
    
    <!--==========================================-->
    <!--MAIN-->
    <!--==========================================-->
    
    <xsl:template match="/*">
        <xsl:value-of select="els:getFileName(@filePath)"/>
    </xsl:template>
    
    <!--==========================================-->
    <!--FUNCTIONS-->
    <!--==========================================-->
    
    <xsl:function name="els:getFileName" as="xs:string">
        <xsl:param name="filePath" as="xs:string?"/>
        <xsl:param name="withExt" as="xs:boolean"/>
        <xsl:variable name="fileNameWithExt" select="functx:substring-after-last-match($filePath,'/')"/>
        <xsl:variable name="fileNameNoExt" select="functx:substring-before-last-match($fileNameWithExt,'\.')"/>
        <!--DEBUG-->
        <xsl:message>filePath = <xsl:value-of select="$filePath"/></xsl:message>
        <xsl:variable name="localString" select="'../../../grammars/efl/infoCommentaire/xf_infoCommentaire.srng'" as="xs:string"/>
        <xsl:message>$localString = $filePath  is <xsl:value-of select="$localString = $filePath"/></xsl:message>
        <xsl:message>test1 (with $filePath) = <xsl:value-of select="functx:substring-after-last-match($filePath,'/')"/></xsl:message>
        <xsl:message>test2 (with $localString) = <xsl:value-of select="functx:substring-after-last-match($localString,'/')"/></xsl:message>
        <!--/DEBUG-->
        <xsl:variable name="ext" select="els:getFileExt($fileNameWithExt)"/>
        <xsl:sequence select="concat('', $fileNameNoExt, if ($withExt) then (concat('.',$ext)) else (''))"/>
    </xsl:function>
    
    <!--1 arg signature-->
    <xsl:function name="els:getFileName" as="xs:string">
        <xsl:param name="filePath" as="xs:string?"/>
        <xsl:sequence select="els:getFileName($filePath,true())"/>
    </xsl:function>
    
    <xsl:function name="els:getFileExt" as="xs:string">
        <xsl:param name="filePath" as="xs:string?"/>
        <xsl:sequence select="concat('',functx:substring-after-last-match($filePath,'\.'))"/>
    </xsl:function>
    
    <!--==========================================-->
    <!--FUNCTX (copy of used functions)-->
    <!--==========================================-->
    <xsl:function xmlns:functx="http://www.functx.com" name="functx:substring-after-last-match" as="xs:string">
        <xsl:param name="arg" as="xs:string?"/>
        <xsl:param name="regex" as="xs:string"/>
        <xsl:sequence select=" replace($arg,concat('^.*',$regex),'') "/>
    </xsl:function>
    
    <xsl:function xmlns:functx="http://www.functx.com" name="functx:substring-before-last-match" as="xs:string?">
        <xsl:param name="arg" as="xs:string?"/>
        <xsl:param name="regex" as="xs:string"/>
        <xsl:sequence select=" replace($arg,concat('^(.*)',$regex,'.*'),'$1') "/>
    </xsl:function>
    
</xsl:stylesheet>

Running Saxon EE from the command line you obtain:

<?xml version="1.0" encoding="UTF-8"?>srng.srng

but running Saxon PE you obtain:

<?xml version="1.0" encoding="UTF-8"?>xf_infoCommentaire.srng
Actions #1

Updated by Michael Kay over 6 years ago

  • Subject changed from Difference in evaluation betwee PE and HE (Saxon 9.7.0.20) to Difference in evaluation betwee PE and EE (Saxon 9.7.0.20)
Actions #2

Updated by Michael Kay over 6 years ago

More strange results:

9.8.0.4 EE

<?xml version="1.0" encoding="UTF-8"?>xf_infoCommentaire.xf_infoCommentaire.srng

9.8.0.4 EE with -opt:0

<?xml version="1.0" encoding="UTF-8"?>xf_infoCommentaire.srng

9.8.0.4 with --generateByteCode:off

<?xml version="1.0" encoding="UTF-8"?>xf_infoCommentaire.xf_infoCommentaire.srng

9.8.0.4 PE

<?xml version="1.0" encoding="UTF-8"?>xf_infoCommentaire.srng

9.7.0.20 EE

<?xml version="1.0" encoding="UTF-8"?>srng.srng

9.7.0.20 EE with -opt:0

<?xml version="1.0" encoding="UTF-8"?>xf_infoCommentaire.srng

9.7.0.20 EE with --generateByteCode:off

<?xml version="1.0" encoding="UTF-8"?>srng.srng

9.7.0.20 PE

<?xml version="1.0" encoding="UTF-8"?>xf_infoCommentaire.srng

So it looks like the EE optimizer is causing the trouble, and it's causing different trouble on the 9.7 and 9.8 branches.

Actions #3

Updated by Michael Kay over 6 years ago

The problem appears to be connected to incorrect inlining of the function functx:substring-after-last-match(). This is called from two different places, and in each case it is inlined. In each case the inlining has the beneficial effect that the regular expression passed to replace() is known statically, so it can be precompiled. However, it seems that the call from els:getFileExt() is using the wrong regular expression -- specifically, the one associated with the call substring-after-last-match(xx, '/').

The issue (in 9.8 terms) is that there is a SystemFunctionCall object and a SystemFunction object: the latter being in this case a Replace function, and when we do function inlining we copy the SystemFunctionCall (because it's a node on the expression tree), but we don't copy the SystemFunction. However, when we find that the regular expression is statically known, we modify the Replace object to hold the compiled regular expression. But the regular expression is different for the two callers.

There are some other classes of function that may suffer the same problem, for example CollatingFunctionFixed holds a collation name.

Actions #4

Updated by Michael Kay over 6 years ago

  • Category set to Internals
  • Status changed from New to In Progress
  • Assignee set to Michael Kay
  • Priority changed from High to Normal

For 9.8 I have implemented a solution where the relevant system functions (I have so far identified RegexFunction, CollatingFunctionFixed, and Translate) clone themselves when the calling SystemFunctionCall is cloned. XSLT3 and QT3 regression tests pass.

The design in 9.7 is essentially the same so I will retrofit the same fix.

I have a slight unease that the caller-specific information really belongs with the SystemFunctionCall rather than with the SystemFunction. However, doing that makes it harder for static and dynamic function calls to work in the same way, which is why we did the design like this in the first place.

Actions #5

Updated by Michael Kay over 6 years ago

  • Applies to branch 9.7, 9.8, trunk added
  • Fix Committed on Branch 9.7, 9.8, trunk added

Fix committed on 9.7, 9.8, and development branches.

Actions #6

Updated by Radu Coravu over 6 years ago

Thanks Michael, I tested your 9.7 changes and they seem to work, I will add them to the next Oxygen 19.1 minor bug fix release.

If our XSLT-related automated tests catch anything I will add a comment on the issue.

Actions #7

Updated by Michael Kay over 6 years ago

  • Subject changed from Difference in evaluation betwee PE and EE (Saxon 9.7.0.20) to Difference in evaluation between PE and EE (Saxon 9.7.0.20)
Actions #8

Updated by Michael Kay over 6 years ago

  • Status changed from In Progress to Resolved
Actions #9

Updated by O'Neil Delpratt over 6 years ago

  • Fixed in Maintenance Release 9.8.0.5 added

Bug fix applied in the Saxon 9.8.0.5 maintenance release. Leave open until the bug fix is applied in 9.7 branch.

Actions #10

Updated by O'Neil Delpratt over 6 years ago

  • Status changed from Resolved to Closed
  • % Done changed from 0 to 100

Bug fix applied in the Saxon 9.8.0.5 maintenance release. Leave open until fix applied in the 9.7 release

Actions #11

Updated by O'Neil Delpratt over 6 years ago

  • Status changed from Closed to Resolved

Bug fix applied in the Saxon 9.8.0.5 maintenance release. Leave open until fix applied in the 9.7 release

Actions #12

Updated by O'Neil Delpratt over 6 years ago

  • Status changed from Resolved to Closed
  • Fixed in Maintenance Release 9.7.0.21 added

Bug fix applied in the Saxon 9.7.0.21 maintenance release.

Please register to edit this issue

Also available in: Atom PDF