logo       

Re: LibXSLT / XPathContext interaction: msg#00018

lang.perl.xml

Subject: Re: LibXSLT / XPathContext interaction

Robin Berjon <robin.berjon@xxxxxxxxx> writes:

> Matt Sergeant wrote:
>> On 3 Dec 2003, at 11:55, Robin Berjon wrote:
>>> I thought Python had a simple refcounted GC just like Perl's, and
>>> that libxslt works there, am I wrong? If not, the way they've done
>>> it could surely help us.
>> I'm pretty sure the Python API for libxslt (and libxml) is a
>> straight port of the C library, including having to free things
>> yourself. Looking back, that might have been a better fit to the
>> library, but it wouldn't have been a better fit to perl.
>
> I don't mind having to free things myself if it means they don't
> segfault ;)

I think these two things don't fit well. Manually freeing also means
you have to check what can be dereferenced to prevent segfaults. By
freeing a document you also free all its nodes and you should avoid
dereferencing them after that. The only clean solution leads you back
to reference counting, as ingeniously implemented by Christian and
Matt in LibXML.

Although LibXML's MM works generaly very for DOM operations (if anyone
knows of a bug, tell me), the situation with user-defined XPath
extension functions is more complex (this applies both to LibXSLT and
XPathContext).

If the extension function creates and returns new node(s), it goes as
follows

1) the node it is referenced by Perl and LibXML's own refcounting
machinery

2) a XS wrapper gets the nodes from the Perl callback and wants to
pass them to libxslt/xpath. But: unless some extra action is taken,
Perl will try to free the nodes as soon as wrapper ends because the
XS wrapper was the last one who holds a Perl reference to them
(unless the app itself holds an extra reference).

There are two approaches:

Matt's way in LibXSLT: create a (deep) copy of the node, pass it to
libxslt and let Perl/LibXML free the created node in the usual
way. Problem: the copy looses its parent node as well as all its
relation to other nodes within the nodeset, document, etc. It is
basically a very different node (although it looks quite the same).

My way in XPathContext: postpone Perl's/LibXML's freeing machinery
by storing a reference to the nodes in a special "pool". This way,
the refcounts are artificially increased for the time the XPath
expression is being evaluated. The pool is emptied when XPath
processing is done. This works very well for XPath. For XSLT
processing, you would probably have to keep the pool filled during
the whole transformation. A small puddle would grow to a lake, then
to a see, then to an ocean,...

Ok, suppose for a while this part is solved in some other way (without
having to make a copy of each node or storing a reference in a pool).

You pass new node objects to libxslt/xpath and you want it to free
them as soon as they're of no use. For example, if new-node() in
//body[@background=new-node()] creates a new node, it should be freed
after the equality test is done, because it is not of any use and you
don't want libxslt/xpath to leak.

Libxslt/xpath uses a boolean flag on a node-set for this purpose. BUT:
what if the node created by new-node() is still referenced somewhere
in the Perl APP? Ok, LibXSLT could examine the refcounts first, and
only set the flag if apropriate. But what if only some of the nodes
within the node-set are referenced on the Perl level?

Conclusion: The XPathContext's way of doing it is very well unless
there are too many nodes being created within evaluation of one
XPath. LibXSLT's approach is memory-considerate, but doesn't pass to
XSLT exactly the nodes that the extension function created.
There might be some other way out of this, but I don't see it.

But AFAIK, both approaches do prevent segfaults (except maybe for some
implementation bugs). Am I wrong here?

-- Petr
_______________________________________________
Perl-XML mailing list
Perl-XML@xxxxxxxxxxxxxxxxxxxxxxxx
To unsubscribe: http://listserv.ActiveState.com/mailman/mysubs



<Prev in Thread] Current Thread [Next in Thread>
Google Custom Search

News | FAQ | advertise