http://nagoya.apache.org/bugzilla/show_bug.cgi?id=2468 If you can stomach it, here is my latest summary of this bug. Any help would be appreciated. In it I've set out to examine the set of iterators in xsltc that implement setStartNode(int): AbsoluteIterator, CurrentNodeListIterator, FilteredStepIterator, FilterIterator MatchingIterator, NthIterator, ReverseIterator, SingletonIterator SortingIterator, StepIterator, UnionIterator AbsoluteIterator implements this method as follows: public NodeIterator setStartNode(int node) { if (_isRestartable) { resetPosition(); NodeIterator iter = _source.setStartNode(_startNode = DOM.ROOTNODE); return iter; } return reset(); } There are some things I find curius about this code. Presently unfamiliar with AbsoluteIterator, I can't clearly determine if the things I find curius about this code are in-fact bugs. Firstly, most of the above mentioned iterators return from their implementation of setStartNode(int) using either "return this;" or "return resetPosition();". Whats different here is that (depending upon the codepath) the _source iterator could be returned to the caller. I consider this behaviour suspicious. Additionally suspicious about this iterator is that when _isRestartable == false the iterator will call reset() - with no ultimate effect since the next() method is implemented as: public int next() { // Should never be called return returnNode(NodeIterator.END); } How can AbsoluteIterator usefully be used with next() implemented this way? Perhaps it doesn't matter. Let's look at some example xsl (my patched version of mk031.xsl): <xsl:for-each select="/programme/composer/fullname"> <xsl:call-template name="make-list"> <xsl:with-param name="names" select="/programme/composer/fullname"/> </xsl:call-template> </xsl:for-each> This results in the parameter initialization of the xpath to be (shown here from the decompiled translet): this.addParameter( "names", new AbsoluteIterator( new StepIterator( (new StepIterator( domadapter.getTypedAxisIterator(3, 7), domadapter.getTypedAxisIterator(3, 8) )), domadapter.getTypedAxisIterator(3, 9) ) ).setStartNode(i), false ); make_list(domadapter, nodeiterator, transletoutputhandler, i); Notice that this code calls AbsoluteIterator::setStartNode(int) and initialized to state i. This i is also passed into the template (important in the next step). Since setStartNode(int) follows the "if (_isRestartable)" codepath, the "return iter;" will return the outer StepIterator instance which will be pushed onto the parameter stack. When the parameter is retrieved from the stack StepIterator::setStartNode(int) will be called, using the same variable i: Object object = this.addParameter("names", "", true); nodeiterator = BasisLibrary.referenceToNodeSet(object).reset().setStartNode(i); thus reinitializing the iterator into a different state. So, where's the bug? Is it: 1. in AbsoluteIterator::setStartNode(int): perhaps it shouldn't return the _source iterator but should instead allow itself to be pushed onto the stack? If so, AbsoluteIterator::next() certainly is also broken (if the comment is any indication). 2. somewhere in the code generation of the local iterator: inparticular, the call to StepIterator::setStartNode(int) resets the iterator to an incorrect state - in the case of an xpath constructed on the stack perhaps this call should not be made? Would the resolution then be inside Expression::startResetIterator(...)? 3. because the template call is enclosed in a for-each and the current node (i which is passed as an argument) changes each loop the problem is that the iterator's reinitialization (inside make$list) is using the wrong i. Should it be DOM.ROOTNODE? 4. somewhere else? Anyone have any thoughts on the matter? dazed but not yet (completely) confused, john
