// 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 iteratorTemp
= methodGen.addLocalVariable("filter_expr_tmp1",
Util.getJCRefType(NODE_ITERATOR_SIG),
null, null);
iteratorTemp.setStart(
il.append(new ASTORE(iteratorTemp.getIndex())));
predicate.translate(classGen, methodGen);
LocalVariableGen predicateValueTemp
= methodGen.addLocalVariable("filter_expr_tmp2",
Util.getJCRefType("I"),
null, null);
predicateValueTemp.setStart(
il.append(new ISTORE(predicateValueTemp.getIndex())));
il.append(new NEW(cpg.addClass(NTH_ITERATOR_CLASS)));
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));
}
}