while (tc != null) {
tc = tc.processLeavingTail();
}
// find the template rule for this node
Rule rule = mode.getRule(node, context);
if (rule==null) { // Use the default action for the node
// No need to open a new stack frame!
defaultAction(node, parameters, tunnelParameters, context, locationId);
} else {
Template template = (Template)rule.getAction();
TraceListener traceListener = controller.getTraceListener();
context.setLocalParameters(parameters);
context.setTunnelParameters(tunnelParameters);
context.openStackFrame(template.getStackFrameMap());
context.setOriginatingConstructType(Location.TEMPLATE);
context.setCurrentTemplateRule(rule);
traceListener.startCurrentItem(node);
tc = template.applyLeavingTail(context);
traceListener.endCurrentItem(node);
}
}
} else { // not tracing
context.setCurrentIterator(iterator);
context.setCurrentMode(mode);
context.setOriginatingConstructType(Location.TEMPLATE);
boolean lookahead = (iterator.getProperties() & SequenceIterator.LOOKAHEAD) != 0;
Template previousTemplate = null;
while(true) {
// process any tail calls returned from previous nodes. We need to do this before changing
// the context. If we have a LookaheadIterator, we can tell whether we're positioned at the
// end without changing the current position, and we can then return the last tail call to
// the caller and execute it further down the stack, reducing the risk of running out of stack
// space. In other cases, we need to execute the outstanding tail calls before moving the iterator
if (tc != null) {
if (lookahead && !((LookaheadIterator)iterator).hasNext()) {
break;
}
do {
tc = tc.processLeavingTail();
} while (tc != null);
}
NodeInfo node = (NodeInfo)iterator.next();
// We can assume it's a node - we did static type checking
if (node == null) {
break;
}
// find the template rule for this node
Rule rule = mode.getRule(node, context);
if (rule==null) { // Use the default action for the node
// No need to open a new stack frame!
defaultAction(node, parameters, tunnelParameters, context, locationId);
} else {
Template template = (Template)rule.getAction();
if (template != previousTemplate) {
// Reuse the previous stackframe unless it's a different template rule
previousTemplate = template;
context.openStackFrame(template.getStackFrameMap());
context.setLocalParameters(parameters);