private UserFunction establishTargetFunction(TailCallInfo tail, XPathContextMajor cm) { if (tail instanceof TailCallFunction) { return ((TailCallFunction) tail).function; } else if (tail instanceof TailCallComponent) { Component targetComponent = ((TailCallComponent) tail).component; cm.setCurrentComponent(targetComponent); return (UserFunction) targetComponent.getActor(); } else { throw new AssertionError(); } }
private UserFunction establishTargetFunction(TailCallInfo tail, XPathContextMajor cm) { if (tail instanceof TailCallFunction) { return ((TailCallFunction) tail).function; } else if (tail instanceof TailCallComponent) { Component targetComponent = ((TailCallComponent) tail).component; cm.setCurrentComponent(targetComponent); return (UserFunction) targetComponent.getActor(); } else { throw new AssertionError(); } }
/** * Invoke the function * * @param context the XPath dynamic evaluation context * @param args the actual arguments to be supplied * @return the result of invoking the function * @throws XPathException if a dynamic error occurs within the function */ public Sequence<?> call(XPathContext context, Sequence[] args) throws XPathException { XPathContextMajor c2 = userFunction.makeNewContext(context, this); c2.setCurrentComponent(component); return userFunction.call(c2, args); }
/** * Invoke the function * * @param context the XPath dynamic evaluation context * @param args the actual arguments to be supplied * @return the result of invoking the function * @throws XPathException if a dynamic error occurs within the function */ public Sequence<?> call(XPathContext context, Sequence[] args) throws XPathException { XPathContextMajor c2 = userFunction.makeNewContext(context); c2.setCurrentComponent(component); return userFunction.call(c2, args); }
public TailCall processLeavingTail() throws XPathException { evaluationContext.trackFocus(selectedItems.iterate()); evaluationContext.setCurrentMode(targetMode); evaluationContext.setCurrentComponent(targetMode); return targetMode.getActor().applyTemplates(params, tunnelParams, evaluationContext, locationId); } }
public TailCall processLeavingTail() throws XPathException { evaluationContext.trackFocus(selectedItems.iterate()); evaluationContext.setCurrentMode(targetMode); evaluationContext.setCurrentComponent(targetMode); return targetMode.getActor().applyTemplates(params, tunnelParams, evaluationContext, locationId); } }
/** * Create a context for evaluating this function * * @param oldContext the existing context of the caller * @return a new context which should be supplied to the call() method. */ public XPathContextMajor makeNewContext(XPathContext oldContext) { XPathContextMajor c2 = oldContext.newCleanContext(); c2.setOrigin(this); c2.setReceiver(oldContext.getReceiver()); c2.setTemporaryOutputState(StandardNames.XSL_FUNCTION); c2.setCurrentOutputUri(null); c2.setCurrentComponent(getDeclaringComponent()); // default value for the caller to override if necessary return c2; }
/** * Create a context for evaluating this function * * @param oldContext the existing context of the caller * @param originator * @return a new context which should be supplied to the call() method. */ public XPathContextMajor makeNewContext(XPathContext oldContext, ContextOriginator originator) { XPathContextMajor c2 = oldContext.newCleanContext(); c2.setReceiver(oldContext.getReceiver()); c2.setTemporaryOutputState(StandardNames.XSL_FUNCTION); c2.setCurrentOutputUri(null); c2.setCurrentComponent(getDeclaringComponent()); // default value for the caller to override if necessary c2.setOrigin(originator); return c2; }
/** * Make a new XPath context for evaluating patterns if there is any possibility that the * pattern uses local variables * * @param context The existing XPath context * @return a new XPath context */ public XPathContext makeNewContext(XPathContext context) { XPathContextMajor c2 = context.newContext(); c2.setOrigin(context.getController()); // WHY? c2.openStackFrame(getStackFrameSlotsNeeded()); if (!(context.getCurrentComponent().getActor() instanceof Accumulator)) { c2.setCurrentComponent(context.getCurrentMode()); // bug 3706 } return c2; }
/** * Make a new XPath context for evaluating patterns if there is any possibility that the * pattern uses local variables * * @param context The existing XPath context * @return a new XPath context */ public XPathContext makeNewContext(XPathContext context) { XPathContextMajor c2 = context.newContext(); c2.setOrigin(context.getController()); // WHY? c2.openStackFrame(getStackFrameSlotsNeeded()); if (!(context.getCurrentComponent().getActor() instanceof Accumulator)) { c2.setCurrentComponent(context.getCurrentMode()); // bug 3706 } return c2; }
/** * Process the template call encapsulated by this package. * * @return another TailCall. This will never be the original call, but it may be the next * recursive call. For example, if A calls B which calls C which calls D, then B may return * a TailCall to A representing the call from B to C; when this is processed, the result may be * a TailCall representing the call from C to D. * @throws XPathException if a dynamic error occurs */ public TailCall processLeavingTail() throws XPathException { // TODO: the idea of tail call optimization is to reuse the caller's stack frame rather than // creating a new one. We're doing this for the Java stack, but not for the context stack where // local variables are held. It should be possible to avoid creating a new context, and instead // to update the existing one in situ. NamedTemplate template = (NamedTemplate)targetComponent.getActor(); XPathContextMajor c2 = evaluationContext.newContext(); c2.setCurrentComponent(targetComponent); c2.setOrigin(instruction); c2.setLocalParameters(params); c2.setTunnelParameters(tunnelParams); c2.openStackFrame(template.getStackFrameMap()); // System.err.println("Tail call on template"); return template.expand(c2); } }
/** * Process the template call encapsulated by this package. * * @return another TailCall. This will never be the original call, but it may be the next * recursive call. For example, if A calls B which calls C which calls D, then B may return * a TailCall to A representing the call from B to C; when this is processed, the result may be * a TailCall representing the call from C to D. * @throws XPathException if a dynamic error occurs */ public TailCall processLeavingTail() throws XPathException { // TODO: the idea of tail call optimization is to reuse the caller's stack frame rather than // creating a new one. We're doing this for the Java stack, but not for the context stack where // local variables are held. It should be possible to avoid creating a new context, and instead // to update the existing one in situ. NamedTemplate template = (NamedTemplate)targetComponent.getActor(); XPathContextMajor c2 = evaluationContext.newContext(); c2.setCurrentComponent(targetComponent); c2.setOrigin(instruction); c2.setLocalParameters(params); c2.setTunnelParameters(tunnelParams); c2.openStackFrame(template.getStackFrameMap()); // System.err.println("Tail call on template"); return template.expand(c2); } }
/** * Perform the built-in template action for a given item. * @param item the item to be processed * @param parameters the parameters supplied to apply-templates * @param tunnelParams the tunnel parameters to be passed through * @param context the dynamic evaluation context * @param locationId location of the instruction (apply-templates, apply-imports etc) that caused * the built-in template to be invoked @throws net.sf.saxon.trans.XPathException */ public void process(Item item, ParameterSet parameters, ParameterSet tunnelParams, XPathContext context, Location locationId) throws XPathException { if (item instanceof NodeInfo && ((NodeInfo) item).getNodeKind() == Type.DOCUMENT) { XPathContextMajor c2 = context.newContext(); c2.setOrigin(this); c2.trackFocus(((NodeInfo) item).iterateAxis(AxisInfo.CHILD)); c2.setCurrentComponent(c2.getCurrentMode()); TailCall tc = c2.getCurrentMode().getActor().applyTemplates(parameters, tunnelParams, c2, locationId); while (tc != null) { tc = tc.processLeavingTail(); } } // otherwise, do nothing }
/** * Perform the built-in template action for a given item. * @param item the item to be processed * @param parameters the parameters supplied to apply-templates * @param tunnelParams the tunnel parameters to be passed through * @param context the dynamic evaluation context * @param locationId location of the instruction (apply-templates, apply-imports etc) that caused * the built-in template to be invoked @throws net.sf.saxon.trans.XPathException */ public void process(Item item, ParameterSet parameters, ParameterSet tunnelParams, XPathContext context, Location locationId) throws XPathException { if (item instanceof NodeInfo && ((NodeInfo) item).getNodeKind() == Type.DOCUMENT) { XPathContextMajor c2 = context.newContext(); c2.setOrigin(this); c2.trackFocus(((NodeInfo) item).iterateAxis(AxisInfo.CHILD)); c2.setCurrentComponent(c2.getCurrentMode()); TailCall tc = c2.getCurrentMode().getActor().applyTemplates(parameters, tunnelParams, c2, locationId); while (tc != null) { tc = tc.processLeavingTail(); } } // otherwise, do nothing }
/** * Process one key definition to add entries to the index * * * @param doc the document to be indexed * @param keydef the key definition used to build the index * @param context the XPath dynamic evaluation context * @param isFirst true if this is the first index to be built for this key * @throws XPathException if a dynamic error is encountered */ private void constructIndex(TreeInfo doc, KeyDefinition keydef, XPathContext context, boolean isFirst) throws XPathException { //System.err.println("build index for doc " + doc.getDocumentNumber()); Pattern match = keydef.getMatch(); //NodeInfo curr; XPathContextMajor xc = context.newContext(); xc.setOrigin(keydef); xc.setCurrentComponent(keydef.getDeclaringComponent()); xc.setTemporaryOutputState(StandardNames.XSL_KEY); // The use expression (or sequence constructor) may contain local variables. SlotManager map = keydef.getStackFrameMap(); if (map != null) { xc.openStackFrame(map); } match.selectNodes(doc, xc).forEachOrFail(node -> processNode(node, keydef, xc, isFirst)); }
/** * Apply an accumulator rule * * @param rule the rule to apply * @param node the node that was matched * @param isPostDescent false for the pre-descent visit to a node, true for the post-descent visit * @param value the value of the accumulator before applying the rule * @param context the dynamic evaluation context * @return the value of the accumulator after applying the rule * @throws XPathException if a dynamic error occurs during the evaluation */ private Sequence<?> processRule(Rule rule, NodeInfo node, boolean isPostDescent, Sequence<?> value, XPathContext context) throws XPathException { AccumulatorRule target = (AccumulatorRule) rule.getAction(); Expression delta = target.getNewValueExpression(); XPathContextMajor c2 = context.newCleanContext(); final Controller controller = c2.getController(); assert controller != null; ManualIterator<NodeInfo> initialNode = new ManualIterator<>(node); c2.setCurrentIterator(initialNode); c2.openStackFrame(target.getStackFrameMap()); c2.setLocalVariable(0, value); c2.setCurrentComponent(accumulator.getDeclaringComponent()); c2.setTemporaryOutputState(StandardNames.XSL_ACCUMULATOR_RULE); value = Evaluator.EAGER_SEQUENCE.evaluate(delta, c2); //System.err.println("Node " + ((TinyNodeImpl) node).getNodeNumber() + " : " + value); values.add(new DataPoint(new Visit(node, isPostDescent), value)); return value; }
/** * Process the template call encapsulated by this package. * * @return another TailCall. This will never be the original call, but it may be the next * recursive call. For example, if A calls B which calls C which calls D, then B may return * a TailCall to A representing the call from B to C; when this is processed, the result may be * a TailCall representing the call from C to D. * @throws XPathException if a dynamic error occurs */ public TailCall processLeavingTail() throws XPathException { TemplateRule nh = (TemplateRule) rule.getAction(); nh.initialize(); XPathContextMajor c2 = evaluationContext.newContext(); c2.setOrigin(NextMatch.this); //c2.setOriginatingConstructType(LocationKind.TEMPLATE); c2.setLocalParameters(params); c2.setTunnelParameters(tunnelParams); c2.openStackFrame(nh.getStackFrameMap()); c2.setCurrentTemplateRule(rule); c2.setCurrentComponent(evaluationContext.getCurrentComponent()); // System.err.println("Tail call on template"); return nh.applyLeavingTail(c2); } }
/** * Process the template call encapsulated by this package. * * @return another TailCall. This will never be the original call, but it may be the next * recursive call. For example, if A calls B which calls C which calls D, then B may return * a TailCall to A representing the call from B to C; when this is processed, the result may be * a TailCall representing the call from C to D. * @throws XPathException if a dynamic error occurs */ public TailCall processLeavingTail() throws XPathException { TemplateRule nh = (TemplateRule) rule.getAction(); nh.initialize(); XPathContextMajor c2 = evaluationContext.newContext(); c2.setOrigin(NextMatch.this); //c2.setOriginatingConstructType(LocationKind.TEMPLATE); c2.setLocalParameters(params); c2.setTunnelParameters(tunnelParams); c2.openStackFrame(nh.getStackFrameMap()); c2.setCurrentTemplateRule(rule); c2.setCurrentComponent(evaluationContext.getCurrentComponent()); // System.err.println("Tail call on template"); return nh.applyLeavingTail(c2); } }
/** * Process the function call in push mode * * @param context the XPath dynamic context * @throws XPathException if a dynamic error occurs */ public void process(XPathContext context) throws XPathException { Sequence<?>[] actualArgs = evaluateArguments(context); if (isTailCall()) { requestTailCall(context, actualArgs); return; } if (bindingSlot >= 0) { Component target = getTargetComponent(context); UserFunction targetFunction = (UserFunction) target.getActor(); if (target.getVisibility() == Visibility.ABSTRACT) { throw new XPathException("Cannot call a function defined with visibility=abstract", "XTDE3052"); } XPathContextMajor c2 = targetFunction.makeNewContext(context, this); c2.setCurrentComponent(target); c2.setOrigin(this); targetFunction.process(actualArgs, c2); } else { XPathContextMajor c2 = function.makeNewContext(context, this); c2.setOrigin(this); function.process(actualArgs, c2); } }
/** * Process the function call in push mode * * @param context the XPath dynamic context * @throws XPathException if a dynamic error occurs */ public void process(XPathContext context) throws XPathException { Sequence<?>[] actualArgs = evaluateArguments(context); if (isTailCall()) { requestTailCall(context, actualArgs); return; } if (bindingSlot >= 0) { Component target = getTargetComponent(context); UserFunction targetFunction = (UserFunction) target.getActor(); if (target.getVisibility() == Visibility.ABSTRACT) { throw new XPathException("Cannot call a function defined with visibility=abstract", "XTDE3052"); } XPathContextMajor c2 = targetFunction.makeNewContext(context); c2.setCurrentComponent(target); c2.setOrigin(this); targetFunction.process(actualArgs, c2); } else { XPathContextMajor c2 = function.makeNewContext(context); c2.setOrigin(this); function.process(actualArgs, c2); } }