il.append(DUP);
iteratorTemp.setEnd(
il.append(new ALOAD(iteratorTemp.getIndex())));
predicateValueTemp.setEnd(
il.append(new ILOAD(predicateValueTemp.getIndex())));
il.append(new INVOKESPECIAL(nthIteratorIdx));
} else {
// Translate predicates from right to left
final int initCNLI = cpg.addMethodref(CURRENT_NODE_LIST_ITERATOR,
"<init>",
"("+NODE_ITERATOR_SIG+"Z"+
CURRENT_NODE_LIST_FILTER_SIG +
NODE_SIG+TRANSLET_SIG+")V");
// Backwards branches are prohibited if an uninitialized object is
// on the stack by section 4.9.4 of the JVM Specification, 2nd Ed.
// We don't know whether this code might contain backwards branches,
// so we mustn't create the new object until after we've created
// the suspect arguments to its constructor. Instead we calculate
// the values of the arguments to the constructor first, store them
// in temporary variables, create the object and reload the
// arguments from the temporaries to avoid the problem.
LocalVariableGen nodeIteratorTemp =
methodGen.addLocalVariable("filter_expr_tmp1",
Util.getJCRefType(NODE_ITERATOR_SIG),
null, null);
nodeIteratorTemp.setStart(
il.append(new ASTORE(nodeIteratorTemp.getIndex())));
predicate.translate(classGen, methodGen);
LocalVariableGen filterTemp =
methodGen.addLocalVariable("filter_expr_tmp2",
Util.getJCRefType(CURRENT_NODE_LIST_FILTER_SIG),
null, null);
filterTemp.setStart(il.append(new ASTORE(filterTemp.getIndex())));
// Create a CurrentNodeListIterator
il.append(new NEW(cpg.addClass(CURRENT_NODE_LIST_ITERATOR)));
il.append(DUP);
// Initialize CurrentNodeListIterator
nodeIteratorTemp.setEnd(
il.append(new ALOAD(nodeIteratorTemp.getIndex())));
il.append(ICONST_1);
filterTemp.setEnd(il.append(new ALOAD(filterTemp.getIndex())));
il.append(methodGen.loadCurrentNode());
il.append(classGen.loadTranslet());
il.append(new INVOKESPECIAL(initCNLI));
}
}
}