19f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* 29f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Licensed to the Apache Software Foundation (ASF) under one 39f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * or more contributor license agreements. See the NOTICE file 49f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed with this work for additional information 59f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * regarding copyright ownership. The ASF licenses this file 69f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * to you under the Apache License, Version 2.0 (the "License"); 79f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * you may not use this file except in compliance with the License. 89f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * You may obtain a copy of the License at 99f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * http://www.apache.org/licenses/LICENSE-2.0 119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Unless required by applicable law or agreed to in writing, software 139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * distributed under the License is distributed on an "AS IS" BASIS, 149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * See the License for the specific language governing permissions and 169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitations under the License. 179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/* 199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * $Id: VariableStack.java 524812 2007-04-02 15:52:03Z zongaro $ 209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpackage org.apache.xpath; 229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport javax.xml.transform.TransformerException; 249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xalan.res.XSLMessages; 269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.objects.XObject; 279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonimport org.apache.xpath.res.XPATHErrorResources; 289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson/** 309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Defines a class to keep track of a stack for 319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * template arguments and variables. 329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>This has been changed from the previous incarnations of this 349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * class to be fairly low level.</p> 359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @xsl.usage internal 369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilsonpublic class VariableStack implements Cloneable 389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson{ 399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * limitation for 1K 419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public static final int CLEARLIMITATION= 1024; 439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Constructor for a variable stack. 469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public VariableStack() 489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson reset(); 509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Constructor for a variable stack. 549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param initStackSize The initial stack size. Must be at least one. The 559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * stack can grow if needed. 569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public VariableStack(int initStackSize) 589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Allow for twice as many variables as stack link entries 609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson reset(initStackSize, initStackSize*2); 619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Returns a clone of this variable stack. 659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return a clone of this variable stack. 679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws CloneNotSupportedException 699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public synchronized Object clone() throws CloneNotSupportedException 719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson VariableStack vs = (VariableStack) super.clone(); 749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // I *think* I can get away with a shallow clone here? 769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson vs._stackFrames = (XObject[]) _stackFrames.clone(); 779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson vs._links = (int[]) _links.clone(); 789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return vs; 809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * The stack frame where all variables and params will be kept. 849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @serial 859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XObject[] _stackFrames; 879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * The top of the stack frame (<code>_stackFrames</code>). 909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @serial 919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int _frameTop; 939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * The bottom index of the current frame (relative to <code>_stackFrames</code>). 969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @serial 979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private int _currentFrameBottom; 999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * The stack of frame positions. I call 'em links because of distant 1029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <a href="http://math.millikin.edu/mprogers/Courses/currentCourses/CS481-ComputerArchitecture/cs481.Motorola68000.html"> 1039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Motorola 68000 assembler</a> memories. :-) 1049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @serial 1059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int[] _links; 1079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * The top of the links stack. 1109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int _linksTop; 1129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Get the element at the given index, regardless of stackframe. 1159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param i index from zero. 1179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The item at the given index. 1199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public XObject elementAt(final int i) 1219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return _stackFrames[i]; 1239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Get size of the stack. 1279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return the total size of the execution stack. 1299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public int size() 1319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return _frameTop; 1339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Reset the stack to a start position. 1379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void reset() 1399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // If the stack was previously allocated, assume that about the same 1419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // amount of stack space will be needed again; otherwise, use a very 1429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // large stack size. 1439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int linksSize = (_links == null) ? XPathContext.RECURSIONLIMIT 1449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson : _links.length; 1459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int varArraySize = (_stackFrames == null) ? XPathContext.RECURSIONLIMIT * 2 1469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson : _stackFrames.length; 1479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson reset(linksSize, varArraySize); 1489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Reset the stack to a start position. 1529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param linksSize Initial stack size to use 1539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param varArraySize Initial variable array size to use 1549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson protected void reset(int linksSize, int varArraySize) { 1569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _frameTop = 0; 1579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _linksTop = 0; 1589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Don't bother reallocating _links array if it exists already 1609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (_links == null) { 1619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _links = new int[linksSize]; 1629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Adding one here to the stack of frame positions will allow us always 1659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // to look one under without having to check if we're at zero. 1669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // (As long as the caller doesn't screw up link/unlink.) 1679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _links[_linksTop++] = 0; 1689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Get a clean _stackFrames array and discard the old one. 1709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _stackFrames = new XObject[varArraySize]; 1719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Set the current stack frame. 1759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param sf The new stack frame position. 1779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setStackFrame(int sf) 1799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _currentFrameBottom = sf; 1819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Get the position from where the search should start, 1859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * which is either the searchStart property, or the top 1869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * of the stack if that value is -1. 1879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The current stack frame position. 1899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 1909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public int getStackFrame() 1919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 1929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return _currentFrameBottom; 1939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 1949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 1959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 1969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Allocates memory (called a stackframe) on the stack; used to store 1979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * local variables and parameter arguments. 1989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 1999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <p>I use the link/unlink concept because of distant 2009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * <a href="http://math.millikin.edu/mprogers/Courses/currentCourses/CS481-ComputerArchitecture/cs481.Motorola68000.html"> 2019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Motorola 68000 assembler</a> memories.</p> 2029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param size The size of the stack frame allocation. This ammount should 2049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * normally be the maximum number of variables that you can have allocated 2059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * at one time in the new stack frame. 2069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The bottom of the stack frame, from where local variable addressing 2089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * should start from. 2099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 2109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public int link(final int size) 2119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _currentFrameBottom = _frameTop; 2149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _frameTop += size; 2159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (_frameTop >= _stackFrames.length) 2179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XObject newsf[] = new XObject[_stackFrames.length + XPathContext.RECURSIONLIMIT + size]; 2199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.arraycopy(_stackFrames, 0, newsf, 0, _stackFrames.length); 2219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _stackFrames = newsf; 2239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (_linksTop + 1 >= _links.length) 2269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson int newlinks[] = new int[_links.length + (CLEARLIMITATION * 2)]; 2289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.arraycopy(_links, 0, newlinks, 0, _links.length); 2309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _links = newlinks; 2329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _links[_linksTop++] = _currentFrameBottom; 2359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return _currentFrameBottom; 2379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 2409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Free up the stack frame that was last allocated with 2419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * {@link #link(int size)}. 2429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 2439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void unlink() 2449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _frameTop = _links[--_linksTop]; 2469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _currentFrameBottom = _links[_linksTop - 1]; 2479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 2509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Free up the stack frame that was last allocated with 2519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * {@link #link(int size)}. 2529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param currentFrame The current frame to set to 2539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * after the unlink. 2549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 2559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void unlink(int currentFrame) 2569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _frameTop = _links[--_linksTop]; 2589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _currentFrameBottom = currentFrame; 2599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 2629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Set a local variable or parameter in the current stack frame. 2639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param index Local variable index relative to the current stack 2669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * frame bottom. 2679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param val The value of the variable that is being set. 2699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 2709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setLocalVariable(int index, XObject val) 2719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _stackFrames[index + _currentFrameBottom] = val; 2739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 2769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Set a local variable or parameter in the specified stack frame. 2779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param index Local variable index relative to the current stack 2809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * frame bottom. 2819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * NEEDSDOC @param stackFrame 2829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param val The value of the variable that is being set. 2849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 2859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setLocalVariable(int index, XObject val, int stackFrame) 2869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 2879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _stackFrames[index + stackFrame] = val; 2889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 2899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 2909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 2919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Get a local variable or parameter in the current stack frame. 2929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param xctxt The XPath context, which must be passed in order to 2959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * lazy evaluate variables. 2969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 2979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param index Local variable index relative to the current stack 2989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * frame bottom. 2999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The value of the variable. 3019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws TransformerException 3039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 3049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public XObject getLocalVariable(XPathContext xctxt, int index) 3059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws TransformerException 3069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson index += _currentFrameBottom; 3099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XObject val = _stackFrames[index]; 3119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null == val) 3139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new TransformerException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_VARIABLE_ACCESSED_BEFORE_BIND, null), 3149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson xctxt.getSAXLocator()); 3159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // "Variable accessed before it is bound!", xctxt.getSAXLocator()); 3169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Lazy execution of variables. 3189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (val.getType() == XObject.CLASS_UNRESOLVEDVARIABLE) 3199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return (_stackFrames[index] = val.execute(xctxt)); 3209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return val; 3229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 3259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Get a local variable or parameter in the current stack frame. 3269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param index Local variable index relative to the given 3299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * frame bottom. 3309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * NEEDSDOC @param frame 3319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The value of the variable. 3339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws TransformerException 3359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 3369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public XObject getLocalVariable(int index, int frame) 3379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws TransformerException 3389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson index += frame; 3419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XObject val = _stackFrames[index]; 3439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return val; 3459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 3489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Get a local variable or parameter in the current stack frame. 3499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param xctxt The XPath context, which must be passed in order to 3529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * lazy evaluate variables. 3539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param index Local variable index relative to the current stack 3559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * frame bottom. 3569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The value of the variable. 3589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws TransformerException 3609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 3619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public XObject getLocalVariable(XPathContext xctxt, int index, boolean destructiveOK) 3629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws TransformerException 3639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson index += _currentFrameBottom; 3669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XObject val = _stackFrames[index]; 3689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if(null == val) 3709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new TransformerException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_VARIABLE_ACCESSED_BEFORE_BIND, null), 3719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson xctxt.getSAXLocator()); 3729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // "Variable accessed before it is bound!", xctxt.getSAXLocator()); 3739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Lazy execution of variables. 3759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (val.getType() == XObject.CLASS_UNRESOLVEDVARIABLE) 3769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return (_stackFrames[index] = val.execute(xctxt)); 3779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return destructiveOK ? val : val.getFresh(); 3799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 3829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Tell if a local variable has been set or not. 3839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param index Local variable index relative to the current stack 3859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * frame bottom. 3869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return true if the value at the index is not null. 3889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 3899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws TransformerException 3909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 3919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public boolean isLocalSet(int index) throws TransformerException 3929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 3939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return (_stackFrames[index + _currentFrameBottom] != null); 3949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 3959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** NEEDSDOC Field m_nulls */ 3979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson private static XObject[] m_nulls = new XObject[CLEARLIMITATION]; 3989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 3999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 4009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Use this to clear the variables in a section of the stack. This is 4019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * used to clear the parameter section of the stack, so that default param 4029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * values can tell if they've already been set. It is important to note that 4039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * this function has a 1K limitation. 4049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param start The start position, relative to the current local stack frame. 4069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param len The number of slots to be cleared. 4079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 4089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void clearLocalSlots(int start, int len) 4099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson start += _currentFrameBottom; 4129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson System.arraycopy(m_nulls, 0, _stackFrames, start, len); 4149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 4179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Set a global variable or parameter in the global stack frame. 4189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param index Local variable index relative to the global stack frame 4219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * bottom. 4229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param val The value of the variable that is being set. 4249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 4259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public void setGlobalVariable(final int index, final XObject val) 4269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson _stackFrames[index] = val; 4289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 4319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Get a global variable or parameter from the global stack frame. 4329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param xctxt The XPath context, which must be passed in order to 4359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * lazy evaluate variables. 4369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param index Global variable index relative to the global stack 4389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * frame bottom. 4399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The value of the variable. 4419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws TransformerException 4439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 4449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public XObject getGlobalVariable(XPathContext xctxt, final int index) 4459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws TransformerException 4469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4489f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XObject val = _stackFrames[index]; 4499f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4509f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Lazy execution of variables. 4519f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (val.getType() == XObject.CLASS_UNRESOLVEDVARIABLE) 4529f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return (_stackFrames[index] = val.execute(xctxt)); 4539f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4549f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return val; 4559f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4569f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4579f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 4589f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Get a global variable or parameter from the global stack frame. 4599f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4609f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4619f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param xctxt The XPath context, which must be passed in order to 4629f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * lazy evaluate variables. 4639f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4649f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param index Global variable index relative to the global stack 4659f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * frame bottom. 4669f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4679f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The value of the variable. 4689f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4699f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws TransformerException 4709f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 4719f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public XObject getGlobalVariable(XPathContext xctxt, final int index, boolean destructiveOK) 4729f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws TransformerException 4739f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 4749f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4759f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XObject val = _stackFrames[index]; 4769f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4779f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Lazy execution of variables. 4789f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (val.getType() == XObject.CLASS_UNRESOLVEDVARIABLE) 4799f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return (_stackFrames[index] = val.execute(xctxt)); 4809f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4819f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return destructiveOK ? val : val.getFresh(); 4829f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 4839f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 4849f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson /** 4859f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * Get a variable based on it's qualified name. 4869f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * This is for external use only. 4879f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4889f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param xctxt The XPath context, which must be passed in order to 4899f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * lazy evaluate variables. 4909f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4919f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @param qname The qualified name of the variable. 4929f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4939f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @return The evaluated value of the variable. 4949f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * 4959f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson * @throws javax.xml.transform.TransformerException 4969f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson */ 4979f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson public XObject getVariableOrParam( 4989f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson XPathContext xctxt, org.apache.xml.utils.QName qname) 4999f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throws javax.xml.transform.TransformerException 5009f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5019f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5029f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson org.apache.xml.utils.PrefixResolver prefixResolver = 5039f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson xctxt.getNamespaceContext(); 5049f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5059f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // Get the current ElemTemplateElement, which must be pushed in as the 5069f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // prefix resolver, and then walk backwards in document order, searching 5079f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // for an xsl:param element or xsl:variable element that matches our 5089f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // qname. If we reach the top level, use the StylesheetRoot's composed 5099f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson // list of top level variables and parameters. 5109f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5119f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (prefixResolver instanceof org.apache.xalan.templates.ElemTemplateElement) 5129f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5139f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5149f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson org.apache.xalan.templates.ElemVariable vvar; 5159f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5169f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson org.apache.xalan.templates.ElemTemplateElement prev = 5179f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson (org.apache.xalan.templates.ElemTemplateElement) prefixResolver; 5189f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5199f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (!(prev instanceof org.apache.xalan.templates.Stylesheet)) 5209f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5219f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while ( !(prev.getParentNode() instanceof org.apache.xalan.templates.Stylesheet) ) 5229f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5239f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson org.apache.xalan.templates.ElemTemplateElement savedprev = prev; 5249f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5259f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson while (null != (prev = prev.getPreviousSiblingElem())) 5269f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5279f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (prev instanceof org.apache.xalan.templates.ElemVariable) 5289f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson { 5299f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson vvar = (org.apache.xalan.templates.ElemVariable) prev; 5309f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5319f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (vvar.getName().equals(qname)) 5329f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return getLocalVariable(xctxt, vvar.getIndex()); 5339f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5349f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5359f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson prev = savedprev.getParentElem(); 5369f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5379f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5389f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5399f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson vvar = prev.getStylesheetRoot().getVariableOrParamComposed(qname); 5409f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson if (null != vvar) 5419f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson return getGlobalVariable(xctxt, vvar.getIndex()); 5429f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5439f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 5449f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson throw new javax.xml.transform.TransformerException(XSLMessages.createXPATHMessage(XPATHErrorResources.ER_VAR_NOT_RESOLVABLE, new Object[]{qname.toString()})); //"Variable not resolvable: " + qname); 5459f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson } 5469f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson} // end VariableStack 5479f8118474e9513f7a5b7d2a05e4a0fb15d1a6569Jesse Wilson 548