[saxon] Doc about dynamic XPathContext structure?

Michael,
Is there any documentation about the "stack" structure
represented by an XPathContext and its origin and caller?
What its origin and caller should be regarding a specific
stylesheet (and a specific point during the evaluation of
this stylesheet)? How optimization could modify those
links? How those links would evolve during the evaluation
of the stylesheet?
PS: I am interested by Saxon 9.
Thank you for any pointer. Regards,
--drkm
_____________________________________________________________________________
Ne gardez plus qu'une seule adresse mail ! Copiez vos mails vers Yahoo! Mail

Thread view

Michael,
Is there any documentation about the "stack" structure
represented by an XPathContext and its origin and caller?
What its origin and caller should be regarding a specific
stylesheet (and a specific point during the evaluation of
this stylesheet)? How optimization could modify those
links? How those links would evolve during the evaluation
of the stylesheet?
PS: I am interested by Saxon 9.
Thank you for any pointer. Regards,
--drkm
_____________________________________________________________________________
Ne gardez plus qu'une seule adresse mail ! Copiez vos mails vers Yahoo! Mail

No, there's no documentation on this beyond what is in the source code.
Generally, a new XPathContextMajor is created when you need a new stackframe
for holding variables - that is, for evaluating a function or template (also
for evaluating match patterns if they use variables). A new
XPathContextMinor is created when there is a change in the focus.
The "caller" information links to the next context object down the stack,
and is used for two purposes (a) to get from the XPathContextMinor to the
underlying ..Major when evaluating variables, and (b) to produce a
termination stacktrace on fatal errors (Saxon-SA only). It isn't used to
unwind the stack - that happens automatically when the Java stack unwinds,
because references to the current XPathContext object are always held in
Java variables. Actually of course the context objects do not form a pure
stack, because they can be retained in Closures for lazy evaluation.
The "origin" information is used only for diagnostics, it links the context
object to the instruction/expression that caused it to be created. This is
used in the Saxon-SA stack trace on fatal errors, and I believe it is also
used by third-party Saxon debuggers.
I've been considering various design changes to this for some time: the
costs of allocating context objects show up fairly significantly especially
when running very trivial stylesheets (such as the identity stylesheet). One
option is to get rid of the dynamic allocation of XPathContextMinor objects
and instead treat focus changes like declarations of local variables -
analyze them statically and allocate fixed slots on the stackframe for each
focus that can exist during the execution of a function or template. An even
more radical redesign would be to maintain the various parts of the focus
only where it is actually required, which in most cases can be decided by
static analysis (the exception of course is apply-templates).
Michael Kay
http://www.saxonica.com/
> -----Original Message-----
> From: saxon-help-bounces@...
> [mailto:saxon-help-bounces@...] On Behalf
> Of Florent Georges
> Sent: 06 November 2007 01:38
> To: Saxon Help SF list
> Subject: [saxon] Doc about dynamic XPathContext structure?
>
> Michael,
>
> Is there any documentation about the "stack" structure
> represented by an XPathContext and its origin and caller?
> What its origin and caller should be regarding a specific
> stylesheet (and a specific point during the evaluation of
> this stylesheet)? How optimization could modify those links?
> How those links would evolve during the evaluation of the stylesheet?
>
> PS: I am interested by Saxon 9.
>
> Thank you for any pointer. Regards,
>
> --drkm
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> ______________________________________________________________
> _______________
> Ne gardez plus qu'une seule adresse mail ! Copiez vos mails
> vers Yahoo! Mail
>
>
> --------------------------------------------------------------
> -----------
> This SF.net email is sponsored by: Splunk Inc.
> Still grepping through log files to find problems? Stop.
> Now Search log events and configuration files using AJAX and
> a browser.
> Download your FREE copy of Splunk now >> http://get.splunk.com/
> _______________________________________________
> saxon-help mailing list
> saxon-help@...
> https://lists.sourceforge.net/lists/listinfo/saxon-help

Michael Kay wrote:
Thank you for your valuable comments.
> Generally, a new XPathContextMajor is created when you
> need a new stackframe for holding variables - that is, for
> evaluating a function or template (also for evaluating
> match patterns if they use variables). A new
> XPathContextMinor is created when there is a change in the
> focus.
Ok.
> The "caller" information links to the next context object
> down the stack, and is used for two purposes (a) to get
> from the XPathContextMinor to the underlying ..Major when
> evaluating variables, and (b) to produce a termination
> stacktrace on fatal errors (Saxon-SA only).
Ok. This is actually my goal too. See the last post on
http://fgeorges.blogspot.com/.
I found something strange in the XPath context. I printed
the bottom of the "stack" like this:
XPathContext ctxt = ...;
for ( /* */; ctxt != null; ctxt = ctxt.getCaller() ) {
int type =
ctxt.getOrigin().getInstructionInfo()
.getConstructType();
System.err.println("type: "
+ Functions.resolveConstructType(type));
}
and I got:
...
type: FUNCTION_CALL
type: xsl:call-template
type: xsl:for-each
type: xsl:template
type: CONTROLLER
The relevant part of the stylesheet, simplified, is like:
<xsl:template match="/">
<xsl:for-each select="*">
<xsl:call-template name="t"/>
</xsl:for-each>
</xsl:template>
<xsl:template match="*" name="t" mode="m">
<xsl:sequence select="fg:f(*)"/>
</xsl:template>
<xsl:function name="fg:f">
<xsl:param name="n" as="node()*"/>
<xsl:sequence select="
error(xs:QName('yoy:ERR007'), 'Error message')"/>
</xsl:function>
What I find strange is that we have a function call
following a call template, without template in between. The
real template 't', even if a little bit complex than showed,
is really simple, so I guess it is because of some
optimization. Is it possible? Is it possible to have
"wholes" in the stack because of optimization?
The problem is that my resulting stack XSLT representation
is (the goal is to print the XSLT stack on the console):
...
applied in function fg:f #1 (at style.xsl:40)
called in template matching "/" (at style.xsl:12)
`-> /
applied from external application
instead of:
...
applied in function fg:f #1 (at style.xsl:40)
called in template t #m matching "*" (at style.xsl:21)
`-> /xsl:stylesheet[1]
called in template matching "/" (at style.xsl:12)
`-> /
applied from external application
Thank you for your help,
--drkm
_____________________________________________________________________________
Ne gardez plus qu'une seule adresse mail ! Copiez vos mails vers Yahoo! Mail

> and I got:
This looks straightforward enough:
>
> ...
> type: FUNCTION_CALL fg:f()
> type: xsl:call-template call-template name="t"
> type: xsl:for-each for-each select="*"
> type: xsl:template match="/"
> type: CONTROLLER
>
> The relevant part of the stylesheet, simplified, is like:
>
> <xsl:template match="/">
> <xsl:for-each select="*">
> <xsl:call-template name="t"/>
> </xsl:for-each>
> </xsl:template>
>
> <xsl:template match="*" name="t" mode="m">
> <xsl:sequence select="fg:f(*)"/>
> </xsl:template>
>
> <xsl:function name="fg:f">
> <xsl:param name="n" as="node()*"/>
> <xsl:sequence select="
> error(xs:QName('yoy:ERR007'), 'Error message')"/>
> </xsl:function>
>
> What I find strange is that we have a function call
> following a call template, without template in between. The
> real template 't', even if a little bit complex than showed,
> is really simple, so I guess it is because of some
> optimization. Is it possible? Is it possible to have
> "wholes" in the stack because of optimization?
Yes, it's certainly possible, though I don't see it here. Saxon-SA 9.0 does
function inlining where it considers it appropriate - that is, a function
call is statically replaced by the body of the function being called. All
such optimizations make it increasingly hard to relate run-time events to
things the user understands.
What you are seeing here is simply that the new stackframe/context that's
created when call-template is executed is ascribed to the call-template
instruction rather than to the template itself. You clearly don't need two
new stackframes one for the call and one for the callee.
But yes, it means you have to do more grovelling around to produce nice
output. That's how Stylus Studio and oXygen earn their money!
Michael Kay
http://www.saxonica.com/