_value.startResetIterator(classGen, methodGen);
il.append(methodGen.storeIterator());
// Create the KeyIndex object (the iterator) we'll return
il.append(classGen.loadTranslet());
il.append(new INVOKEVIRTUAL(indexConstructor));
il.append(new ASTORE(returnIndex.getIndex()));
// Initialise the index specified in the first parameter of key()
il.append(classGen.loadTranslet());
if (_name == null) {
il.append(new PUSH(cpg,"##id"));
}
else if (_resolvedQName != null) {
il.append(new PUSH(cpg, _resolvedQName.toString()));
}
else {
_name.translate(classGen, methodGen);
}
il.append(new INVOKEVIRTUAL(getKeyIndex));
il.append(new ASTORE(searchIndex.getIndex()));
// LOOP STARTS HERE
// Now we're ready to start traversing the node-set given in
// the key() function's second argument....
final BranchHandle nextNode = il.append(new GOTO(null));
final InstructionHandle loop = il.append(NOP);
// Push returnIndex on stack to prepare for call to merge()
il.append(new ALOAD(returnIndex.getIndex()));
// Lookup index using the string value from the current node
il.append(new ALOAD(searchIndex.getIndex()));
il.append(DUP);
il.append(methodGen.loadDOM());
il.append(methodGen.loadCurrentNode());
il.append(new INVOKEINTERFACE(getNodeValue, 2));
if (_name == null) {
il.append(new INVOKEVIRTUAL(lookupId));
}
else {
il.append(new INVOKEVIRTUAL(lookupKey));
}
// Call to returnIndex.merge(searchIndex);
il.append(new INVOKEVIRTUAL(merge));
// Go on with next node in the 2nd parameter node-set
nextNode.setTarget(il.append(methodGen.loadIterator()));
il.append(methodGen.nextNode());
il.append(DUP);
il.append(methodGen.storeCurrentNode());
il.append(new IFNE(loop));
// LOOP ENDS HERE
// Restore current node and current iterator from the stack
il.append(methodGen.storeIterator());
il.append(methodGen.storeCurrentNode());
// Return with the an iterator for all resulting nodes
il.append(new ALOAD(returnIndex.getIndex()));
}
// If the second parameter is a single value we just lookup the named
// index and initialise the iterator to return nodes with this value.
else {
// Call getKeyIndex in AbstractTranslet with the name of the key
// to get the index for this key (which is also a node iterator).
il.append(classGen.loadTranslet());
if (_name == null) {
il.append(new PUSH(cpg,"##id"));
}
else if (_resolvedQName != null) {
il.append(new PUSH(cpg, _resolvedQName.toString()));
}
else {
_name.translate(classGen, methodGen);
}
il.append(new INVOKEVIRTUAL(getKeyIndex));
// Now use the value in the second argument to determine what nodes
// the iterator should return.
il.append(DUP);
_value.translate(classGen, methodGen);
if (_name == null) {
il.append(new INVOKEVIRTUAL(lookupId));
}
else {
il.append(new INVOKEVIRTUAL(lookupKey));
}
}
}