package client.net.sf.saxon.ce.expr; import client.net.sf.saxon.ce.om.ValueRepresentation; import client.net.sf.saxon.ce.trans.XPathException; /** * Variable reference: a reference to a local variable. This subclass of VariableReference * bypasses the Binding object to get the value directly from the relevant slot in the local * stackframe. */ public class LocalVariableReference extends VariableReference { int slotNumber = -999; /** * Create a local variable reference. The binding and slot number will be supplied later */ public LocalVariableReference() { } /** * Create a LocalVariableReference bound to a given Binding * @param binding the binding (that is, the declaration of this local variable) */ public LocalVariableReference(Binding binding) { super(binding); } /** * Create a clone copy of this VariableReference * @return the cloned copy */ private Expression copy() { if (binding == null) { throw new UnsupportedOperationException("Cannot copy a variable reference whose binding is unknown"); } LocalVariableReference ref = new LocalVariableReference(); ref.binding = binding; ref.staticType = staticType; ref.slotNumber = slotNumber; ref.constantValue = constantValue; ref.displayName = displayName; ExpressionTool.copyLocationInfo(this, ref); return ref; } /** * Set the slot number for this local variable, that is, its position in the local stack frame * @param slotNumber the slot number to be used */ public void setSlotNumber(int slotNumber) { this.slotNumber = slotNumber; } /** * Get the slot number allocated to this local variable * @return the slot number */ public int getSlotNumber() { return slotNumber; } /** * Return the value of the variable * @param c the XPath dynamic context * @return the value of the variable * @throws XPathException if any dynamic error occurs while evaluating the variable */ public ValueRepresentation evaluateVariable(XPathContext c) throws XPathException { try { return c.getStackFrame().slots[slotNumber]; } catch (ArrayIndexOutOfBoundsException err) { if (slotNumber == -999) { throw new ArrayIndexOutOfBoundsException("Local variable has not been allocated a stack frame slot"); } throw err; } } /** * Replace this VariableReference where appropriate by a more efficient implementation. This * can only be done after all slot numbers are allocated. The efficiency is gained by binding the * VariableReference directly to a local or global slot, rather than going via the Binding object * * @param parent the parent expression of this variable reference */ // public void refineVariableReference(Expression parent) { // // no-op // } } // This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. // If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. // This Source Code Form is “Incompatible With Secondary Licenses”, as defined by the Mozilla Public License, v. 2.0.