xalan-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From santiag...@apache.org
Subject cvs commit: xml-xalan/java/src/org/apache/xalan/xsltc/runtime AbstractTranslet.java
Date Mon, 26 Aug 2002 16:03:01 GMT
santiagopg    2002/08/26 09:03:01

  Modified:    java/src/org/apache/xalan/xsltc/cmdline Compile.java
               java/src/org/apache/xalan/xsltc/compiler Constants.java
                        Number.java ParameterRef.java Predicate.java
                        Sort.java SyntaxTreeNode.java Template.java
                        Variable.java VariableRef.java VariableRefBase.java
                        XSLTC.java
               java/src/org/apache/xalan/xsltc/runtime
                        AbstractTranslet.java
  Added:       java/src/org/apache/xalan/xsltc/compiler Closure.java
               java/src/org/apache/xalan/xsltc/compiler/util
                        NodeSortRecordFactGenerator.java
  Log:
  Fix for Bugzilla 11828. A new closure conversion algorithm has been
  designed and implemented. The old algorithm did not work in some edge
  cases (c.f. description of Bugzilla 11828). Closure variables in an
  inner class are now accessed locally instead of via the AbstractTranslet
  class. Also, we have set the new version to be "XSLTC 1.2".
  
  Revision  Changes    Path
  1.12      +2 -2      xml-xalan/java/src/org/apache/xalan/xsltc/cmdline/Compile.java
  
  Index: Compile.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/cmdline/Compile.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- Compile.java	9 Jul 2002 15:31:24 -0000	1.11
  +++ Compile.java	26 Aug 2002 16:03:00 -0000	1.12
  @@ -82,7 +82,7 @@
   
       // Versioning numbers  for the compiler -v option output
       private static int VERSION_MAJOR = 1;
  -    private static int VERSION_MINOR = 1;
  +    private static int VERSION_MINOR = 2;
       private static int VERSION_DELTA = 0;
    
   
  
  
  
  1.25      +3 -17     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Constants.java
  
  Index: Constants.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Constants.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- Constants.java	9 Jul 2002 17:40:17 -0000	1.24
  +++ Constants.java	26 Aug 2002 16:03:00 -0000	1.25
  @@ -312,6 +312,8 @@
   	= "iterator";
       public static final String DOCUMENT_PNAME     
   	= "document";
  +    public static final String TRANSLET_PNAME     
  +	= "translet";
   
       public static final String GET_NODE_NAME      
   	= "getNodeName";
  @@ -446,22 +448,6 @@
   	= "(" + STRING_SIG + ")" + OBJECT_SIG;
       public static final String ADD_PARAMETER_SIG
   	= "(" + STRING_SIG + OBJECT_SIG + "Z)" + OBJECT_SIG;
  -    public static final String PUSH_VAR_FRAME
  -	= "pushVarFrame";
  -    public static final String PUSH_VAR_FRAME_SIG
  -	= "(I)V";
  -    public static final String POP_VAR_FRAME
  -	= "popVarFrame";
  -    public static final String POP_VAR_FRAME_SIG
  -	= "()V";
  -    public static final String ADD_VARIABLE
  -	= "addVariable";
  -    public static final String ADD_VARIABLE_SIG
  -	= "(I" + OBJECT_SIG + ")V";
  -    public static final String GET_VARIABLE
  -	= "getVariable";
  -    public static final String GET_VARIABLE_SIG
  -	= "(I)" + OBJECT_SIG;
   
       public static final String STRIP_SPACE
   	= "stripSpace";
  
  
  
  1.10      +104 -33   xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Number.java
  
  Index: Number.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Number.java,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -r1.9 -r1.10
  --- Number.java	24 Apr 2002 17:03:15 -0000	1.9
  +++ Number.java	26 Aug 2002 16:03:00 -0000	1.10
  @@ -63,6 +63,8 @@
   
   package org.apache.xalan.xsltc.compiler;
   
  +import java.util.ArrayList;
  +
   import org.apache.xalan.xsltc.compiler.util.Type;
   import org.apache.xalan.xsltc.compiler.util.ReferenceType;
   import org.apache.bcel.classfile.JavaClass;
  @@ -71,11 +73,23 @@
   
   import org.apache.xalan.xsltc.compiler.util.*;
   
  -final class Number extends Instruction {
  +final class Number extends Instruction implements Closure {
       private static final int LEVEL_SINGLE   = 0;
       private static final int LEVEL_MULTIPLE = 1;
       private static final int LEVEL_ANY      = 2;
   
  +    static final private String[] ClassNames = { 
  +	"org.apache.xalan.xsltc.dom.SingleNodeCounter",	  // LEVEL_SINGLE
  +	"org.apache.xalan.xsltc.dom.MultipleNodeCounter", // LEVEL_MULTIPLE
  +	"org.apache.xalan.xsltc.dom.AnyNodeCounter"	  // LEVEL_ANY
  +    };
  +
  +    static final private String[] FieldNames = { 
  +	"___single_node_counter",		   // LEVEL_SINGLE
  +	"___multiple_node_counter",		   // LEVEL_MULTIPLE
  +	"___any_node_counter"			   // LEVEL_ANY
  +    };
  +
       private Pattern _from = null;
       private Pattern _count = null;
       private Expression _value = null;
  @@ -89,19 +103,51 @@
       private int _level = LEVEL_SINGLE;
       private boolean _formatNeeded = false;
   
  -    static final private String[] ClassNames = { 
  -	"org.apache.xalan.xsltc.dom.SingleNodeCounter",	  // LEVEL_SINGLE
  -	"org.apache.xalan.xsltc.dom.MultipleNodeCounter", // LEVEL_MULTIPLE
  -	"org.apache.xalan.xsltc.dom.AnyNodeCounter"	  // LEVEL_ANY
  -    };
  +    private String _className = null;
  +    private ArrayList _closureVars = null;
   
  -    static final private String[] FieldNames = { 
  -	"___single_node_counter",		   // LEVEL_SINGLE
  -	"___multiple_node_counter",		   // LEVEL_MULTIPLE
  -	"___any_node_counter"			   // LEVEL_ANY
  -    };
  +     // -- Begin Closure interface --------------------
  +
  +    /**
  +     * Returns true if this closure is compiled in an inner class (i.e.
  +     * if this is a real closure).
  +     */
  +    public boolean inInnerClass() {
  +	return (_className != null);
  +    }
   
  -    public void parseContents(Parser parser) {
  +    /**
  +     * Returns a reference to its parent closure or null if outermost.
  +     */
  +    public Closure getParentClosure() {
  +	return null;
  +    }
  +
  +    /**
  +     * Returns the name of the auxiliary class or null if this predicate 
  +     * is compiled inside the Translet.
  +     */
  +    public String getInnerClassName() {
  +	return _className;
  +    }
  +
  +    /**
  +     * Add new variable to the closure.
  +     */
  +    public void addVariable(VariableRefBase variableRef) {
  +	if (_closureVars == null) {
  +	    _closureVars = new ArrayList();
  +	}
  +
  +	// Only one reference per variable
  +	if (!_closureVars.contains(variableRef)) {
  +	    _closureVars.add(variableRef);
  +	}
  +    }
  +
  +    // -- End Closure interface ----------------------
  +
  +   public void parseContents(Parser parser) {
   	final int count = _attributes.getLength();
   
   	for (int i = 0; i < count; i++) {
  @@ -253,12 +299,11 @@
       }
   
       /**
  -     * Compiles a constructor for the class <tt>className</tt> that
  +     * Compiles a constructor for the class <tt>_className</tt> that
        * inherits from {Any,Single,Multiple}NodeCounter. This constructor
        * simply calls the same constructor in the super class.
        */
  -    private void compileConstructor(ClassGenerator classGen,
  -                                    String className) {
  +    private void compileConstructor(ClassGenerator classGen) {
   	MethodGenerator cons;
   	final InstructionList il = new InstructionList();
   	final ConstantPoolGen cpg = classGen.getConstantPool();
  @@ -275,7 +320,7 @@
   				       "translet",
   				       "iterator"
   				   },
  -				   "<init>", className, il, cpg);
  +				   "<init>", _className, il, cpg);
   
   	il.append(ALOAD_0);     // this
   	il.append(ALOAD_1);     // translet
  @@ -303,13 +348,11 @@
        */
       private void compileLocals(NodeCounterGenerator nodeCounterGen,
   			       MatchGenerator matchGen,
  -			       InstructionList il) {
  -
  -	ConstantPoolGen cpg = nodeCounterGen.getConstantPool();
  -	final String className = matchGen.getClassName();
  -
  -	LocalVariableGen local;
  +			       InstructionList il) 
  +    {
   	int field;
  +	LocalVariableGen local;
  +	ConstantPoolGen cpg = nodeCounterGen.getConstantPool();
   
   	// Get NodeCounter._iterator and store locally
   	local = matchGen.addLocalVariable("iterator", 
  @@ -338,7 +381,7 @@
   	local = matchGen.addLocalVariable("document", 
   					  Util.getJCRefType(DOM_INTF_SIG),
   					  null, null);
  -	field = cpg.addFieldref(className, "_document", DOM_INTF_SIG);
  +	field = cpg.addFieldref(_className, "_document", DOM_INTF_SIG);
   	il.append(ALOAD_0); // 'this' pointer on stack
   	il.append(new GETFIELD(field));
   	// Make sure we have the correct DOM type on the stack!!!
  @@ -347,16 +390,16 @@
       }
   
       private void compilePatterns(ClassGenerator classGen,
  -				 MethodGenerator methodGen) {
  -	//!!!  local variables?
  +				 MethodGenerator methodGen) 
  +    {
   	int current;
   	int field;
   	LocalVariableGen local;
   	MatchGenerator matchGen;
   	NodeCounterGenerator nodeCounterGen;
   
  -	final String className = getXSLTC().getHelperClassName();
  -	nodeCounterGen = new NodeCounterGenerator(className,
  +	_className = getXSLTC().getHelperClassName();
  +	nodeCounterGen = new NodeCounterGenerator(_className,
   						  ClassNames[_level],
   						  toString(), 
   						  ACC_PUBLIC | ACC_SUPER,
  @@ -365,8 +408,22 @@
   	InstructionList il = null;
   	ConstantPoolGen cpg = nodeCounterGen.getConstantPool();
   
  +	// Add a new instance variable for each var in closure
  +	final int closureLen = (_closureVars == null) ? 0 : 
  +	    _closureVars.size();
  +
  +	for (int i = 0; i < closureLen; i++) {
  +	    VariableBase var = 
  +		((VariableRefBase) _closureVars.get(i)).getVariable();
  +
  +	    nodeCounterGen.addField(new Field(ACC_PUBLIC, 
  +					cpg.addUtf8(var.getVariable()),
  +					cpg.addUtf8(var.getType().toSignature()),
  +					null, cpg.getConstantPool()));
  +	}
  +
   	// Add a single constructor to the class
  -	compileConstructor(nodeCounterGen, className);
  +	compileConstructor(nodeCounterGen);
   
   	/*
   	 * Compile method matchesFrom()
  @@ -382,7 +439,7 @@
   				   new String[] {
   				       "node",
   				   },
  -				   "matchesFrom", className, il, cpg);
  +				   "matchesFrom", _className, il, cpg);
   
   	    compileLocals(nodeCounterGen,matchGen,il);
   
  @@ -412,7 +469,7 @@
   					  new String[] {
   					      "node",
   					  },
  -					  "matchesCount", className, il, cpg);
  +					  "matchesCount", _className, il, cpg);
   
   	    compileLocals(nodeCounterGen,matchGen,il);
   	    
  @@ -436,17 +493,31 @@
   	cpg = classGen.getConstantPool();
   	il = methodGen.getInstructionList();
   
  -	final int index = cpg.addMethodref(className, "<init>", 
  +	final int index = cpg.addMethodref(_className, "<init>", 
   					   "(" + TRANSLET_INTF_SIG
   					   + DOM_INTF_SIG 
   					   + NODE_ITERATOR_SIG
   					   + ")V");
  -	il.append(new NEW(cpg.addClass(className)));
  +	il.append(new NEW(cpg.addClass(_className)));
   	il.append(DUP);
   	il.append(classGen.loadTranslet());
   	il.append(methodGen.loadDOM());
   	il.append(methodGen.loadIterator());
   	il.append(new INVOKESPECIAL(index));
  +
  +	// Initialize closure variables
  +	for (int i = 0; i < closureLen; i++) {
  +	    final VariableRefBase varRef = (VariableRefBase) _closureVars.get(i);
  +	    final VariableBase var = varRef.getVariable();
  +	    final Type varType = var.getType();
  +
  +	    // Store variable in new closure
  +	    il.append(DUP);
  +	    il.append(var.loadInstruction());
  +	    il.append(new PUTFIELD(
  +		    cpg.addFieldref(_className, var.getVariable(), 
  +			varType.toSignature())));
  +	}
       }
   
       public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  
  
  
  1.12      +24 -17    xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ParameterRef.java
  
  Index: ParameterRef.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/ParameterRef.java,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- ParameterRef.java	13 Aug 2002 19:12:32 -0000	1.11
  +++ ParameterRef.java	26 Aug 2002 16:03:00 -0000	1.12
  @@ -79,21 +79,31 @@
   	return "parameter-ref("+_variable.getName()+'/'+_variable.getType()+')';
       }
   
  -    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
  +   public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
   	final ConstantPoolGen cpg = classGen.getConstantPool();
   	final InstructionList il = methodGen.getInstructionList();
   
   	final String name = _variable.getVariable();
  +	final String signature = _type.toSignature();
   
   	if (_variable.isLocal()) {
   	    if (classGen.isExternal()) {
  -		il.append(classGen.loadTranslet());
  -		il.append(new PUSH(cpg, name));
  -		final int index = cpg.addMethodref(TRANSLET_CLASS, 
  -						   GET_PARAMETER,
  -						   GET_PARAMETER_SIG);
  -		il.append(new INVOKEVIRTUAL(index));
  -		_type.translateUnBox(classGen, methodGen);
  +		Closure variableClosure = _closure;
  +		while (variableClosure != null) {
  +		    if (variableClosure.inInnerClass()) break;
  +		    variableClosure = variableClosure.getParentClosure();
  +		}
  +	    
  +		if (variableClosure != null) {
  +		    il.append(ALOAD_0);
  +		    il.append(new GETFIELD(
  +			cpg.addFieldref(variableClosure.getInnerClassName(), 
  +			    name, signature)));
  +		}
  +		else {
  +		    il.append(_variable.loadInstruction());
  +		    _variable.removeReference(this);
  +		}
   	    }
   	    else {
   		il.append(_variable.loadInstruction());
  @@ -101,10 +111,8 @@
   	    }
   	}
   	else {
  -	    final String signature = _type.toSignature();
   	    final String className = classGen.getClassName();
   	    il.append(classGen.loadTranslet());
  -	    // If inside a predicate we must cast this ref down
   	    if (classGen.isExternal()) {
   		il.append(new CHECKCAST(cpg.addClass(className)));
   	    }
  @@ -113,12 +121,11 @@
   
   	if (_variable.getType() instanceof NodeSetType) {
   	    // The method cloneIterator() also does resetting
  -            final int clone = cpg.addInterfaceMethodref(NODE_ITERATOR,
  -                                                       "cloneIterator",
  -                                                       "()" +
  -                                                        NODE_ITERATOR_SIG);
  -            il.append(new INVOKEINTERFACE(clone, 1));
  +	    final int clone = cpg.addInterfaceMethodref(NODE_ITERATOR,
  +						       "cloneIterator",
  +						       "()" + 
  +							NODE_ITERATOR_SIG);
  +	    il.append(new INVOKEINTERFACE(clone, 1));
   	}
  -
       }
   }
  
  
  
  1.25      +120 -13   xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Predicate.java
  
  Index: Predicate.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Predicate.java,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- Predicate.java	18 Jul 2002 17:31:02 -0000	1.24
  +++ Predicate.java	26 Aug 2002 16:03:00 -0000	1.25
  @@ -65,22 +65,27 @@
   package org.apache.xalan.xsltc.compiler;
   
   import java.util.Vector;
  +import java.util.ArrayList;
   
   import org.apache.bcel.classfile.JavaClass;
   import org.apache.xalan.xsltc.compiler.util.Type;
   import org.apache.xalan.xsltc.compiler.util.ReferenceType;
   import org.apache.bcel.generic.*;
   import org.apache.xalan.xsltc.compiler.util.*;
  +import org.apache.bcel.classfile.Field;
   
  -final class Predicate extends Expression {
  +final class Predicate extends Expression implements Closure {
   
       private Expression _exp = null; // Expression to be compiled inside pred.
  -    private String  _className;     // Name of filter to generate
       private boolean _nthPositionFilter = false;
       private boolean _nthDescendant = false;
       private boolean _canOptimize = true;
       private int     _ptype = -1;
   
  +    private String _className = null;
  +    private ArrayList _closureVars = null;
  +    private Closure _parentClosure = null;
  +
       public Predicate(Expression exp) {
   	(_exp = exp).setParent(this);
       }
  @@ -102,10 +107,66 @@
   	_canOptimize = false;
       }
   
  -    protected final boolean isClosureBoundary() {
  -	return true;
  +    // -- Begin Closure interface --------------------
  +
  +    /**
  +     * Returns true if this closure is compiled in an inner class (i.e.
  +     * if this is a real closure).
  +     */
  +    public boolean inInnerClass() {
  +	return (_className != null);
  +    }
  +
  +    /**
  +     * Returns a reference to its parent closure or null if outermost.
  +     */
  +    public Closure getParentClosure() {
  +	if (_parentClosure == null) {
  +	    SyntaxTreeNode node = getParent();
  +	    do {
  +		if (node instanceof Closure) {
  +		    _parentClosure = (Closure) node;
  +		    break;
  +		}
  +		if (node instanceof TopLevelElement) {
  +		    break;	// way up in the tree
  +		}
  +		node = node.getParent();
  +	    } while (node != null);
  +	}
  +	return _parentClosure;
       }
  -    
  +
  +    /**
  +     * Returns the name of the auxiliary class or null if this predicate 
  +     * is compiled inside the Translet.
  +     */
  +    public String getInnerClassName() {
  +	return _className;
  +    }
  +
  +    /**
  +     * Add new variable to the closure.
  +     */
  +    public void addVariable(VariableRefBase variableRef) {
  +	if (_closureVars == null) {
  +	    _closureVars = new ArrayList();
  +	}
  +
  +	// Only one reference per variable
  +	if (!_closureVars.contains(variableRef)) {
  +	    _closureVars.add(variableRef);
  +
  +	    // Add variable to parent closure as well
  +	    Closure parentClosure = getParentClosure();
  +	    if (parentClosure != null) {
  +		parentClosure.addVariable(variableRef);
  +	    }
  +	}
  +    }
  +
  +    // -- End Closure interface ----------------------
  +
       public int getPosType() {
   	if (_ptype == -1) {
   	    SyntaxTreeNode parent = getParent();
  @@ -273,9 +334,20 @@
   					},
   					classGen.getStylesheet());	
   
  -	final InstructionList il = new InstructionList();
   	final ConstantPoolGen cpg = filterGen.getConstantPool();
  +	final int length = (_closureVars == null) ? 0 : _closureVars.size();
   
  +	// Add a new instance variable for each var in closure
  +	for (int i = 0; i < length; i++) {
  +	    VariableBase var = ((VariableRefBase) _closureVars.get(i)).getVariable();
  +
  +	    filterGen.addField(new Field(ACC_PUBLIC, 
  +					cpg.addUtf8(var.getVariable()),
  +					cpg.addUtf8(var.getType().toSignature()),
  +					null, cpg.getConstantPool()));
  +	}
  +
  +	final InstructionList il = new InstructionList();
   	testGen = new TestGenerator(ACC_PUBLIC | ACC_FINAL,
   				    org.apache.bcel.generic.Type.BOOLEAN, 
   				    new org.apache.bcel.generic.Type[] {
  @@ -339,10 +411,7 @@
        */
       public boolean isNodeValueTest() {
   	if (!_canOptimize) return false;
  -	if ((getStep() != null) && (getCompareValue() != null))
  -	    return true;
  -	else
  -	    return false;
  +	return (getStep() != null && getCompareValue() != null);
       }
   
       private Expression _value = null;
  @@ -439,15 +508,53 @@
        * filter object and a reference to the predicate's closure.
        */
       public void translateFilter(ClassGenerator classGen,
  -				MethodGenerator methodGen) {
  -
  +				MethodGenerator methodGen) 
  +    {
   	final ConstantPoolGen cpg = classGen.getConstantPool();
   	final InstructionList il = methodGen.getInstructionList();
   
  +	// Compile auxiliary class for filter
   	compileFilter(classGen, methodGen);
  +	
  +	// Create new instance of filter
   	il.append(new NEW(cpg.addClass(_className)));
   	il.append(DUP);
   	il.append(new INVOKESPECIAL(cpg.addMethodref(_className,
   						     "<init>", "()V")));
  +
  +	// Initialize closure variables
  +	final int length = (_closureVars == null) ? 0 : _closureVars.size();
  +
  +	for (int i = 0; i < length; i++) {
  +	    VariableRefBase varRef = (VariableRefBase) _closureVars.get(i);
  +	    VariableBase var = varRef.getVariable();
  +	    Type varType = var.getType();
  +
  +	    il.append(DUP);
  +
  +	    // Find nearest closure implemented as an inner class
  +	    Closure variableClosure = _parentClosure;
  +	    while (variableClosure != null) {
  +		if (variableClosure.inInnerClass()) break;
  +		variableClosure = variableClosure.getParentClosure();
  +	    }
  +
  +	    // Use getfield if in an inner class
  +	    if (variableClosure != null) {
  +		il.append(ALOAD_0);
  +		il.append(new GETFIELD(
  +		    cpg.addFieldref(variableClosure.getInnerClassName(), 
  +			var.getVariable(), varType.toSignature())));
  +	    }
  +	    else {
  +		// Use a load of instruction if in translet class
  +		il.append(var.loadInstruction());
  +	    }
  +
  +	    // Store variable in new closure
  +	    il.append(new PUTFIELD(
  +		    cpg.addFieldref(_className, var.getVariable(), 
  +			varType.toSignature())));
  +	}
       }
   }
  
  
  
  1.16      +276 -30   xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Sort.java
  
  Index: Sort.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Sort.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- Sort.java	9 Jul 2002 17:40:17 -0000	1.15
  +++ Sort.java	26 Aug 2002 16:03:00 -0000	1.16
  @@ -65,6 +65,7 @@
   package org.apache.xalan.xsltc.compiler;
   
   import java.util.Vector;
  +import java.util.ArrayList;
   import java.util.StringTokenizer;
   import java.util.NoSuchElementException;
   import java.text.Collator;
  @@ -82,7 +83,7 @@
   import org.apache.xalan.xsltc.compiler.util.*;
   
   
  -final class Sort extends Instruction {
  +final class Sort extends Instruction implements Closure {
   
       private Expression     _select;
       private AttributeValue _order;
  @@ -93,6 +94,56 @@
       public  String         _lang;
       public  String         _country;
   
  +    private String _className = null;
  +    private ArrayList _closureVars = null;
  +    private boolean _needsSortRecordFactory = false;
  +
  +    // -- Begin Closure interface --------------------
  +
  +    /**
  +     * Returns true if this closure is compiled in an inner class (i.e.
  +     * if this is a real closure).
  +     */
  +    public boolean inInnerClass() {
  +	return (_className != null);
  +    }
  +
  +    /**
  +     * Returns a reference to its parent closure or null if outermost.
  +     */
  +    public Closure getParentClosure() {
  +	return null;
  +    }
  +
  +    /**
  +     * Returns the name of the auxiliary class or null if this predicate 
  +     * is compiled inside the Translet.
  +     */
  +    public String getInnerClassName() {
  +	return _className;
  +    }
  +
  +    /**
  +     * Add new variable to the closure.
  +     */
  +    public void addVariable(VariableRefBase variableRef) {
  +	if (_closureVars == null) {
  +	    _closureVars = new ArrayList();
  +	}
  +
  +	// Only one reference per variable
  +	if (!_closureVars.contains(variableRef)) {
  +	    _closureVars.add(variableRef);
  +	    _needsSortRecordFactory = true;
  +	}
  +    }
  +
  +    // -- End Closure interface ----------------------
  +
  +    private void setInnerClassName(String className) {
  +	_className = className;
  +    }
  +
       /**
        * Parse the attributes of the xsl:sort element
        */
  @@ -202,9 +253,10 @@
        * and a node sort record producing objects as its parameters.
        */
       public static void translateSortIterator(ClassGenerator classGen,
  -					     MethodGenerator methodGen,
  -					     Expression nodeSet,
  -					     Vector sortObjects) {
  +				      MethodGenerator methodGen,
  +				      Expression nodeSet,
  +				      Vector sortObjects) 
  +    {
   	final ConstantPoolGen cpg = classGen.getConstantPool();
   	final InstructionList il = methodGen.getInstructionList();
   
  @@ -244,36 +296,38 @@
        * will produce NodeSortRecord objects of a specific type.
        */
       public static void compileSortRecordFactory(Vector sortObjects,
  -						ClassGenerator classGen,
  -						MethodGenerator methodGen) {
  +	ClassGenerator classGen, MethodGenerator methodGen) 
  +    {
  +	String sortRecordClass = 
  +	    compileSortRecord(sortObjects, classGen, methodGen);
  +
  +	boolean needsSortRecordFactory = false;
  +	final int nsorts = sortObjects.size();
  +	for (int i = 0; i < nsorts; i++) {
  +	    final Sort sort = (Sort) sortObjects.elementAt(i);
  +	    needsSortRecordFactory |= sort._needsSortRecordFactory;
  +	}
  +
  +	String sortRecordFactoryClass = NODE_SORT_FACTORY;
  +	if (needsSortRecordFactory) {
  +	    sortRecordFactoryClass = 
  +		compileSortRecordFactory(sortObjects, classGen, methodGen, 
  +		    sortRecordClass);
  +	}
  +
   	final ConstantPoolGen cpg = classGen.getConstantPool();
   	final InstructionList il = methodGen.getInstructionList();
   	
  -	// NodeSortRecordFactory.NodeSortRecordFactory(dom,class,levels,trlet);
  -	final String initParams =
  -	    "("+DOM_INTF_SIG+STRING_SIG+TRANSLET_INTF_SIG+
  -	    "["+STRING_SIG+"["+STRING_SIG+")V";
  -	final int init = cpg.addMethodref(NODE_SORT_FACTORY,
  -					  "<init>", initParams);
  -
  -	// Compile the object that will encapsulate each sort object (node).
  -	// NodeSortRecordFactory needs the name of the new class.
  -	String className = compileSortRecord(sortObjects, classGen, methodGen);
  -
  -	// The constructor for the NodeSortRecord generating class takes no
  -	// parameters so we must to pass initialization params to other methods
  -	il.append(new NEW(cpg.addClass(NODE_SORT_FACTORY)));
  +	il.append(new NEW(cpg.addClass(sortRecordFactoryClass)));
   	il.append(DUP);
   	il.append(methodGen.loadDOM());
  -	il.append(new PUSH(cpg, className));
  +	il.append(new PUSH(cpg, sortRecordClass));
   	il.append(classGen.loadTranslet());
   
  -	// Compile code that initializes the static _compareType array
  -	final int levels = sortObjects.size();
   	// Compile code that initializes the static _sortOrder
  -	il.append(new PUSH(cpg, levels));
  +	il.append(new PUSH(cpg, nsorts));
   	il.append(new ANEWARRAY(cpg.addClass(STRING)));
  -	for (int level = 0; level < levels; level++) {
  +	for (int level = 0; level < nsorts; level++) {
   	    final Sort sort = (Sort)sortObjects.elementAt(level);
   	    il.append(DUP);
   	    il.append(new PUSH(cpg, level));
  @@ -281,9 +335,9 @@
   	    il.append(AASTORE);
   	}
   
  -	il.append(new PUSH(cpg,levels));
  +	il.append(new PUSH(cpg, nsorts));
   	il.append(new ANEWARRAY(cpg.addClass(STRING)));
  -	for (int level = 0; level < levels; level++) {
  +	for (int level = 0; level < nsorts; level++) {
   	    final Sort sort = (Sort)sortObjects.elementAt(level);
   	    il.append(DUP);
   	    il.append(new PUSH(cpg, level));
  @@ -291,7 +345,172 @@
   	    il.append(AASTORE);
   	}
   
  -	il.append(new INVOKESPECIAL(init));
  +	il.append(new INVOKESPECIAL(
  +	    cpg.addMethodref(sortRecordFactoryClass, "<init>", 
  +		"(" + DOM_INTF_SIG 
  +		    + STRING_SIG
  +		    + TRANSLET_INTF_SIG
  +		    + "[" + STRING_SIG
  +		    + "[" + STRING_SIG + ")V")));
  +
  +	// Initialize closure variables in sortRecordFactory
  +	final ArrayList dups = new ArrayList();
  +
  +	for (int j = 0; j < nsorts; j++) {
  +	    final Sort sort = (Sort) sortObjects.get(j);
  +	    final int length = (sort._closureVars == null) ? 0 : 
  +		sort._closureVars.size();
  +
  +	    for (int i = 0; i < length; i++) {
  +		VariableRefBase varRef = (VariableRefBase) sort._closureVars.get(i);
  +
  +		// Discard duplicate variable references
  +		if (dups.contains(varRef)) continue;
  +
  +		final VariableBase var = varRef.getVariable();
  +
  +		// Store variable in new closure
  +		il.append(DUP);
  +		il.append(var.loadInstruction());
  +		il.append(new PUTFIELD(
  +			cpg.addFieldref(sortRecordFactoryClass, var.getVariable(), 
  +			    var.getType().toSignature())));
  +		dups.add(varRef);
  +	    }
  +	}
  +    }
  +
  +    public static String compileSortRecordFactory(Vector sortObjects,
  +	ClassGenerator classGen, MethodGenerator methodGen, 
  +	String sortRecordClass)
  +    {
  +	final XSLTC  xsltc = ((Sort)sortObjects.firstElement()).getXSLTC();
  +	final String className = xsltc.getHelperClassName();
  +
  +	final NodeSortRecordFactGenerator sortRecordFactory =
  +	    new NodeSortRecordFactGenerator(className,
  +					NODE_SORT_FACTORY,
  +					className + ".java",
  +					ACC_PUBLIC | ACC_SUPER | ACC_FINAL,
  +					new String[] {},
  +					classGen.getStylesheet());
  +
  +	ConstantPoolGen cpg = sortRecordFactory.getConstantPool();
  +
  +	// Add a new instance variable for each var in closure
  +	final int nsorts = sortObjects.size();
  +	final ArrayList dups = new ArrayList();
  +
  +	for (int j = 0; j < nsorts; j++) {
  +	    final Sort sort = (Sort) sortObjects.get(j);
  +	    final int length = (sort._closureVars == null) ? 0 : 
  +		sort._closureVars.size();
  +
  +	    for (int i = 0; i < length; i++) {
  +		final VariableRef varRef = (VariableRef) sort._closureVars.get(i);
  +
  +		// Discard duplicate variable references
  +		if (dups.contains(varRef)) continue;
  +
  +		final VariableBase var = varRef.getVariable();
  +		sortRecordFactory.addField(new Field(ACC_PUBLIC, 
  +					   cpg.addUtf8(var.getVariable()),
  +					   cpg.addUtf8(var.getType().toSignature()),
  +					   null, cpg.getConstantPool()));
  +		dups.add(varRef);
  +	    }
  +	}
  +
  +	// Define a constructor for this class
  +	final org.apache.bcel.generic.Type[] argTypes = 
  +	    new org.apache.bcel.generic.Type[5];
  +	argTypes[0] = Util.getJCRefType(DOM_INTF_SIG);
  +	argTypes[1] = Util.getJCRefType(STRING_SIG);
  +	argTypes[2] = Util.getJCRefType(TRANSLET_INTF_SIG);
  +	argTypes[3] = Util.getJCRefType("[" + STRING_SIG);
  +	argTypes[4] = Util.getJCRefType("[" + STRING_SIG);
  +
  +	final String[] argNames = new String[5];
  +	argNames[0] = DOCUMENT_PNAME;
  +	argNames[1] = "className";
  +	argNames[2] = TRANSLET_PNAME;
  +	argNames[3] = "order";
  +	argNames[4] = "type";
  +
  +	InstructionList il = new InstructionList();
  +	final MethodGenerator constructor =
  +	    new MethodGenerator(ACC_PUBLIC,
  +				org.apache.bcel.generic.Type.VOID, 
  +				argTypes, argNames, "<init>", 
  +				className, il, cpg);
  +
  +	// Push all parameters onto the stack and called super.<init>()
  +	il.append(ALOAD_0);
  +	il.append(ALOAD_1);
  +	il.append(ALOAD_2);
  +	il.append(new ALOAD(3));
  +	il.append(new ALOAD(4));
  +	il.append(new ALOAD(5));
  +	il.append(new INVOKESPECIAL(cpg.addMethodref(NODE_SORT_FACTORY,
  +	    "<init>", 
  +	    "(" + DOM_INTF_SIG 
  +		+ STRING_SIG 
  +		+ TRANSLET_INTF_SIG 
  +		+ "[" + STRING_SIG
  +		+ "[" + STRING_SIG + ")V")));
  +	il.append(RETURN);
  +
  +	// Override the definition of makeNodeSortRecord()
  +	il = new InstructionList(); 
  +	final MethodGenerator makeNodeSortRecord =
  +	    new MethodGenerator(ACC_PUBLIC,
  +		Util.getJCRefType(NODE_SORT_RECORD_SIG), 
  +		new org.apache.bcel.generic.Type[] { 
  +		    org.apache.bcel.generic.Type.INT,
  +		    org.apache.bcel.generic.Type.INT },
  +		new String[] { "node", "last" }, "makeNodeSortRecord",
  +		className, il, cpg);
  +
  +	il.append(ALOAD_0);
  +	il.append(ILOAD_1);
  +	il.append(ILOAD_2);
  +	il.append(new INVOKESPECIAL(cpg.addMethodref(NODE_SORT_FACTORY,
  +	    "makeNodeSortRecord", "(II)" + NODE_SORT_RECORD_SIG)));
  +	il.append(DUP);
  +	il.append(new CHECKCAST(cpg.addClass(sortRecordClass)));
  +
  +	// Initialize closure in record class
  +	final int ndups = dups.size();
  +	for (int i = 0; i < ndups; i++) {
  +	    final VariableRef varRef = (VariableRef) dups.get(i);
  +	    final VariableBase var = varRef.getVariable();
  +	    final Type varType = var.getType();
  +	    
  +	    il.append(DUP);
  +
  +	    // Get field from factory class
  +	    il.append(ALOAD_0);
  +	    il.append(new GETFIELD(
  +		cpg.addFieldref(className,
  +		    var.getVariable(), varType.toSignature())));
  +
  +	    // Put field in record class
  +	    il.append(new PUTFIELD(
  +		cpg.addFieldref(sortRecordClass,
  +		    var.getVariable(), varType.toSignature())));
  +	}
  +	il.append(POP);
  +	il.append(ARETURN);
  +
  +	constructor.setMaxLocals();
  +	constructor.setMaxStack();
  +	sortRecordFactory.addMethod(constructor.getMethod());
  +	makeNodeSortRecord.setMaxLocals();
  +	makeNodeSortRecord.setMaxStack();
  +	sortRecordFactory.addMethod(makeNodeSortRecord.getMethod());
  +	xsltc.dumpClass(sortRecordFactory.getJavaClass());
  +
  +	return className;
       }
   
       /**
  @@ -313,7 +532,34 @@
   					classGen.getStylesheet());
   	
   	final ConstantPoolGen cpg = sortRecord.getConstantPool();	
  -	
  +
  +	// Add a new instance variable for each var in closure
  +	final int nsorts = sortObjects.size();
  +	final ArrayList dups = new ArrayList();
  +
  +	for (int j = 0; j < nsorts; j++) {
  +	    final Sort sort = (Sort) sortObjects.get(j);
  +
  +	    // Set the name of the inner class in this sort object
  +	    sort.setInnerClassName(className);	
  +
  +	    final int length = (sort._closureVars == null) ? 0 : 
  +		sort._closureVars.size();
  +	    for (int i = 0; i < length; i++) {
  +		final VariableRef varRef = (VariableRef) sort._closureVars.get(i);
  +
  +		// Discard duplicate variable references
  +		if (dups.contains(varRef)) continue;
  +
  +		final VariableBase var = varRef.getVariable();
  +		sortRecord.addField(new Field(ACC_PUBLIC, 
  +				    cpg.addUtf8(var.getVariable()),
  +				    cpg.addUtf8(var.getType().toSignature()),
  +				    null, cpg.getConstantPool()));
  +		dups.add(varRef);
  +	    }
  +	}
  +
   	Method clinit = compileClassInit(sortObjects, sortRecord,
   					 cpg, className);
   	Method extract = compileExtract(sortObjects, sortRecord,
  
  
  
  1.21      +2 -18     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/SyntaxTreeNode.java
  
  Index: SyntaxTreeNode.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/SyntaxTreeNode.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- SyntaxTreeNode.java	24 Apr 2002 17:03:15 -0000	1.20
  +++ SyntaxTreeNode.java	26 Aug 2002 16:03:00 -0000	1.21
  @@ -406,23 +406,7 @@
        * @return Symbol table.
        */
       protected final SymbolTable getSymbolTable() {
  -	if (_parser != null)
  -	    return _parser.getSymbolTable();
  -	else
  -	    return null;
  -    }
  -
  -    /**
  -     * Local variables that are accessible from a given syntax tree node will
  -     * be put on the JVM's stack. A closure is a record that contains a pointer
  -     * to a node's outer variable frame (not only global variables, but also
  -     * variables in parent nodes). This method returns true if this node's code
  -     * is implemented by code outside of ApplyTemplates (the only such case is
  -     * the Predicates class). This methid is only called by the VariableRef).
  -     * @return 'true' if node's code is implemented outside of ApplyTemplates
  -     */
  -    protected boolean isClosureBoundary() {
  -	return false;
  +	return (_parser == null) ? null : _parser.getSymbolTable();
       }
   
       /**
  
  
  
  1.18      +1 -47     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Template.java
  
  Index: Template.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Template.java,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -r1.17 -r1.18
  --- Template.java	10 May 2002 15:40:02 -0000	1.17
  +++ Template.java	26 Aug 2002 16:03:00 -0000	1.18
  @@ -85,14 +85,6 @@
       private int     _position; // Position within stylesheet (prio. resolution)
       private boolean _disabled = false;
       private boolean _compiled = false;//make sure it is compiled only once
  -
  -    /**
  -     * Set to <tt>true</tt> by the XPath parser if this template
  -     * needs to create a variable frame. Variable frames are needed
  -     * when certain parts of a template are compiled in external
  -     * classes (e.g., predicates, xsl:number, xsl:sort).
  -     */
  -    private boolean _hasVariableFrame;
       private boolean _hasParams = false;
       private boolean _simplified = false;
   
  @@ -165,29 +157,6 @@
   	    return 0;
       }
   
  -    private Hashtable _variables;
  -    private int _nextIndex;
  -
  -    public int allocateIndex(QName varName) {
  -	if (_variables == null) { // first time
  -	    _hasVariableFrame = true;
  -	    (_variables = new Hashtable()).put(varName, new Integer(0));
  -	    _nextIndex = 1;
  -	    return 0;
  -	}
  -	else {
  -	    Integer index = (Integer)_variables.get(varName);
  -	    if (index == null) {
  -		_variables.put(varName, index = new Integer(_nextIndex++));
  -	    }
  -	    return index.intValue();
  -	}
  -    }
  -
  -    private final int localVariablesCount() {
  -	return _variables == null ? 0 : _variables.size();
  -    }
  -    
       public void display(int indent) {
   	Util.println('\n');
   	indent(indent);
  @@ -354,24 +323,9 @@
   	if (_compiled) return;
   	_compiled = true; 
   	
  -	if (_hasVariableFrame) {
  -	    il.append(classGen.loadTranslet());
  -	    il.append(new PUSH(cpg, localVariablesCount()));
  -	    il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS,
  -							 PUSH_VAR_FRAME,
  -							 PUSH_VAR_FRAME_SIG)));
  -	}
  -	
   	final InstructionHandle start = il.getEnd();
   	translateContents(classGen, methodGen);
   	final InstructionHandle end = il.getEnd();
   	il.setPositions(true);
  -	
  -	if (_hasVariableFrame) {
  -	    il.append(classGen.loadTranslet());
  -	    il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS, 
  -							 POP_VAR_FRAME,
  -							 POP_VAR_FRAME_SIG)));
  -	}
       }
   }
  
  
  
  1.23      +3 -45     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Variable.java
  
  Index: Variable.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Variable.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- Variable.java	1 Feb 2002 20:07:09 -0000	1.22
  +++ Variable.java	26 Aug 2002 16:03:00 -0000	1.23
  @@ -77,37 +77,14 @@
   
   final class Variable extends VariableBase {
   
  -    // Index of this variable in the variable stack relative to base ptr
  -    private int _stackIndex = -1;
  -
  -    private boolean _escapes; // 'true' if the variable's value can change
  -
  -    /**
  -     * This method returns 'true' if the variable value can change over time,
  -     * such as with varibles inside a for-each loop.
  -     */
  -    public void setEscapes() {
  -	_escapes = true;
  -	if (_stackIndex == -1) { // unassigned
  -	    Template template = getTemplate();
  -	    if (template != null) {
  -		_stackIndex = template.allocateIndex(_name);
  -	    }
  -	}
  -    }
  -
  -    /**
  -     *
  -     */
  -    public int getStackIndex() {
  -	return _stackIndex;
  +    public int getIndex() {
  +	return (_local != null) ? _local.getIndex() : -1;
       }
   
       /**
        * Parse the contents of the variable
        */
       public void parseContents(Parser parser) {
  -
   	// Parse 'name' and 'select' attributes plus parameter contents
   	super.parseContents(parser);
   
  @@ -210,20 +187,9 @@
   	_ignore = true;
   
   	if (isLocal()) {
  -	    // Push args to call addVariable()
  -	    if (_escapes) {
  -		il.append(classGen.loadTranslet());
  -		il.append(new PUSH(cpg, _stackIndex));
  -	    }
  -
   	    // Compile variable value computation
   	    translateValue(classGen, methodGen);
   
  -	    // Dup value only when needed
  -	    if (_escapes) {
  -		il.append(_type.DUP());
  -	    }
  -
   	    // Add a new local variable and store value
   	    if (_refs.isEmpty()) { // Remove it if nobody uses the value
   		il.append(_type.POP());
  @@ -232,14 +198,6 @@
   	    else {		   // Store in local var slot if referenced
   		if (_local == null) mapRegister(methodGen);
   		il.append(_type.STORE(_local.getIndex()));
  -	    }
  -
  -	    // Store boxed value into the template's variable stack
  -	    if (_escapes) {
  -		_type.translateBox(classGen, methodGen);
  -		il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS,
  -							     ADD_VARIABLE,
  -							     ADD_VARIABLE_SIG)));
   	    }
   	}
   	else {
  
  
  
  1.13      +19 -36    xml-xalan/java/src/org/apache/xalan/xsltc/compiler/VariableRef.java
  
  Index: VariableRef.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/VariableRef.java,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- VariableRef.java	13 Aug 2002 19:12:32 -0000	1.12
  +++ VariableRef.java	26 Aug 2002 16:03:00 -0000	1.13
  @@ -71,33 +71,10 @@
   
   final class VariableRef extends VariableRefBase {
   
  -    private boolean _escaped;
  -	
       public VariableRef(Variable variable) {
   	super(variable);
       }
   
  -    public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  -	if ( (_variable.isLocal()) && (_escaped = isEscaped()) )
  -	    ((Variable)_variable).setEscapes();
  -	return super.typeCheck(stable);
  -    }
  -
  -    private boolean isEscaped() {
  -	final SyntaxTreeNode limit = _variable.getParent();
  -	SyntaxTreeNode parent = getParent();
  -	do {
  -	    if (parent.isClosureBoundary()) {
  -		return true;
  -	    }
  -	    else {
  -		parent = parent.getParent();
  -	    }
  -	}
  -	while (parent != limit);
  -	return limit.isClosureBoundary();
  -    }
  -
       public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
   	final ConstantPoolGen cpg = classGen.getConstantPool();
   	final InstructionList il = methodGen.getInstructionList();
  @@ -106,17 +83,26 @@
   	if (_type.implementedAsMethod()) return;
   
   	final String name = _variable.getVariable();
  +	final String signature = _type.toSignature();
   
   	if (_variable.isLocal()) {
  -	    if (classGen.isExternal() || _escaped) {
  -		il.append(classGen.loadTranslet());
  -		final int sindex = ((Variable)_variable).getStackIndex();
  -		il.append(new PUSH(cpg, sindex));
  -		final int getVar = cpg.addMethodref(TRANSLET_CLASS, 
  -						    GET_VARIABLE,
  -						    GET_VARIABLE_SIG);
  -		il.append(new INVOKEVIRTUAL(getVar));
  -		_type.translateUnBox(classGen, methodGen);
  +	    if (classGen.isExternal()) {
  +		Closure variableClosure = _closure;
  +		while (variableClosure != null) {
  +		    if (variableClosure.inInnerClass()) break;
  +		    variableClosure = variableClosure.getParentClosure();
  +		}
  +	    
  +		if (variableClosure != null) {
  +		    il.append(ALOAD_0);
  +		    il.append(new GETFIELD(
  +			cpg.addFieldref(variableClosure.getInnerClassName(), 
  +			    name, signature)));
  +		}
  +		else {
  +		    il.append(_variable.loadInstruction());
  +		    _variable.removeReference(this);
  +		}
   	    }
   	    else {
   		il.append(_variable.loadInstruction());
  @@ -124,10 +110,8 @@
   	    }
   	}
   	else {
  -	    final String signature = _type.toSignature();
   	    final String className = classGen.getClassName();
   	    il.append(classGen.loadTranslet());
  -	    // If inside a predicate we must cast this ref down
   	    if (classGen.isExternal()) {
   		il.append(new CHECKCAST(cpg.addClass(className)));
   	    }
  @@ -142,6 +126,5 @@
   							NODE_ITERATOR_SIG);
   	    il.append(new INVOKEINTERFACE(clone, 1));
   	}
  -
       }
   }
  
  
  
  1.9       +50 -14    xml-xalan/java/src/org/apache/xalan/xsltc/compiler/VariableRefBase.java
  
  Index: VariableRefBase.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/VariableRefBase.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- VariableRefBase.java	1 Feb 2002 20:07:09 -0000	1.8
  +++ VariableRefBase.java	26 Aug 2002 16:03:00 -0000	1.9
  @@ -57,6 +57,7 @@
    * <http://www.apache.org/>.
    *
    * @author Morten Jorgensen
  + * @author Santiago Pericas-Geertsen
    *
    */
   
  @@ -68,16 +69,17 @@
   
   class VariableRefBase extends Expression {
   
  -    protected final VariableBase _variable; // Reference to the associated var.
  +    /**
  +     * A reference to the associated variable.
  +     */
  +    protected final VariableBase _variable; 
   
       /**
  -     * Created a new variable or parameter reference. Note that this base-
  -     * class is not here mostly because variable and parameter references share
  -     * a lot of functionality. The base class is needed more for having a
  -     * single class to run 'if (instanceof)' on in the compiler code. The same
  -     * holds for the variable base class.
  -     * @param variable The referenced variable
  +     * A reference to the enclosing expression/instruction for which a
  +     * closure is needed (Predicate, Number or Sort).
        */
  +    protected Closure _closure = null;
  +
       public VariableRefBase(VariableBase variable) {
   	_variable = variable;
   	variable.addReference(this);
  @@ -89,23 +91,34 @@
   
       /**
        * Returns a reference to the associated variable
  -     * @return The referenced variable
        */
       public VariableBase getVariable() {
  -	return(_variable);
  +	return _variable;
       }
   
       /**
        * Returns a reference to any parent variable
  -     * @return Parent variable (or null if none)
        */
       public VariableBase findParentVariable() {
   	SyntaxTreeNode node = this;
  -	while ((node != null) && (!(node instanceof VariableBase)))
  +	while (node != null && !(node instanceof VariableBase)) {
   	    node = node.getParent();
  -	return (VariableBase)node;
  +	}
  +	return (VariableBase) node;
       }
   
  +    /**
  +     * Two variable references are deemed equal if they refer to the 
  +     * same variable.
  +     */
  +    public boolean equals(Object obj) {
  +	try {
  +	    return (_variable == ((VariableRefBase) obj)._variable);
  +	} 
  +	catch (ClassCastException e) {
  +	    return false;
  +	}
  +    }
   
       /**
        * Returns a string representation of this variable reference on the
  @@ -116,7 +129,30 @@
   	return "variable-ref("+_variable.getName()+'/'+_variable.getType()+')';
       }
   
  -    public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  +    public Type typeCheck(SymbolTable stable) 
  +	throws TypeCheckError 
  +    {
  +	// Returned cached type if available
  +	if (_type != null) return _type;
  +
  +	// Find nearest closure to add a variable reference
  +	if (_variable.isLocal()) {
  +	    SyntaxTreeNode node = getParent();
  +	    do {
  +		if (node instanceof Closure) {
  +		    _closure = (Closure) node;
  +		    break;
  +		}
  +		if (node instanceof TopLevelElement) {
  +		    break;	// way up in the tree
  +		}
  +		node = node.getParent();
  +	    } while (node != null);
  +
  +	    if (_closure != null) {
  +		_closure.addVariable(this);
  +	    }
  +	}
   
   	// Insert a dependency link from one variable to another
   	VariableBase parent = findParentVariable();
  
  
  
  1.43      +2 -2      xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XSLTC.java
  
  Index: XSLTC.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/XSLTC.java,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -r1.42 -r1.43
  --- XSLTC.java	23 Jul 2002 19:47:42 -0000	1.42
  +++ XSLTC.java	26 Aug 2002 16:03:00 -0000	1.43
  @@ -727,7 +727,7 @@
   	// create the manifest
   	final Manifest manifest = new Manifest();
   	final java.util.jar.Attributes atrs = manifest.getMainAttributes();
  -	atrs.put(java.util.jar.Attributes.Name.MANIFEST_VERSION,"1.1");
  +	atrs.put(java.util.jar.Attributes.Name.MANIFEST_VERSION,"1.2");
   
   	final Map map = manifest.getEntries();
   	// create manifest
  
  
  
  1.1                  xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Closure.java
  
  Index: Closure.java
  ===================================================================
  /*
   * @(#)$Id: Closure.java,v 1.1 2002/08/26 16:03:00 santiagopg Exp $
   *
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2001, Sun
   * Microsystems., http://www.sun.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * @author Santiago Pericas-Geertsen
   *
   */
  
  package org.apache.xalan.xsltc.compiler;
  
  public interface Closure {
  
      /**
       * Returns true if this closure is compiled in an inner class (i.e.
       * if this is a real closure).
       */
      public boolean inInnerClass();
  
      /**
       * Returns a reference to its parent closure or null if outermost.
       */
      public Closure getParentClosure();
  
      /**
       * Returns the name of the auxiliary class or null if this predicate 
       * is compiled inside the Translet.
       */
      public String getInnerClassName();
  
      /**
       * Add new variable to the closure.
       */
      public void addVariable(VariableRefBase variableRef);
  }
  
  
  
  1.1                  xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/NodeSortRecordFactGenerator.java
  
  Index: NodeSortRecordFactGenerator.java
  ===================================================================
  /*
   * @(#)$Id: NodeSortRecordFactGenerator.java,v 1.1 2002/08/26 16:03:00 santiagopg Exp $
   *
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xalan" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation and was
   * originally based on software copyright (c) 2001, Sun
   * Microsystems., http://www.sun.com.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   *
   * @author Santiago Pericas-Geertsen
   *
   */
  
  package org.apache.xalan.xsltc.compiler.util;
  
  import org.apache.xalan.xsltc.compiler.util.Type;
  import org.apache.bcel.generic.*;
  import org.apache.xalan.xsltc.compiler.util.*;
  
  import org.apache.xalan.xsltc.compiler.Stylesheet;
  
  /**
   * Generator for subclasses of NodeSortRecordFactory.
   */
  public final class NodeSortRecordFactGenerator extends ClassGenerator {
  
      public NodeSortRecordFactGenerator(String className, String superClassName,
  				   String fileName,
  				   int accessFlags, String[] interfaces,
  				   Stylesheet stylesheet) {
  	super(className, superClassName, fileName,
  	      accessFlags, interfaces, stylesheet);
      }
      
      /**
       * Returns <tt>true</tt> since this class is external to the
       * translet.
       */
      public boolean isExternal() {
  	return true;
      }
  }
  
  
  
  1.43      +2 -51     xml-xalan/java/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java
  
  Index: AbstractTranslet.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java,v
  retrieving revision 1.42
  retrieving revision 1.43
  diff -u -r1.42 -r1.43
  --- AbstractTranslet.java	25 Jul 2002 11:45:28 -0000	1.42
  +++ AbstractTranslet.java	26 Aug 2002 16:03:01 -0000	1.43
  @@ -111,9 +111,6 @@
       public void printInternalState() {
   	System.out.println("-------------------------------------");
   	System.out.println("AbstractTranslet this = " + this);
  -	System.out.println("vbase = " + vbase);
  -	System.out.println("vframe = " + vframe);
  -	System.out.println("varsStack.size() = " + varsStack.size());
   	System.out.println("pbase = " + pbase);
   	System.out.println("vframe = " + pframe);
   	System.out.println("paramsStack.size() = " + paramsStack.size());
  @@ -137,14 +134,9 @@
       }
   
       /************************************************************************
  -     * Variable and parameter handling
  +     * Parameter handling
        ************************************************************************/
   
  -    // Variable's stack: <tt>vbase</tt> and <tt>vframe</tt> are used 
  -    // to denote the current variable frame.
  -    protected int vbase = 0, vframe = 0;
  -    protected ArrayList varsStack = new ArrayList();
  -
       // Parameter's stack: <tt>pbase</tt> and <tt>pframe</tt> are used 
       // to denote the current parameter frame.
       protected int pbase = 0, pframe = 0;
  @@ -228,47 +220,6 @@
   	    if (param._name.equals(name)) return param._value;
   	}
   	return null;
  -    }
  -
  -    /**
  -     * Push a new variable frame.
  -     */
  -    public final void pushVarFrame(int frameSize) {
  -	varsStack.add(vframe, new Integer(vbase));
  -	vbase = ++vframe;
  -	vframe += frameSize;
  -
  -	// Clear stack frame
  -	for (int i = vbase; i <= vframe + 1; i++) {
  -	    varsStack.add(i, null);
  -	}
  -    }
  -
  -    /**
  -     * Pop the topmost variable frame.
  -     */
  -    public final void popVarFrame() {
  -	if (vbase > 0) {
  -	    final int oldvbase = ((Integer)varsStack.get(--vbase)).intValue();
  -	    for (int i = vbase; i < vframe; i++) {
  -		varsStack.set(i, null);		// for the GC
  -	    }
  -	    vframe = vbase; vbase = oldvbase;
  -	}
  -    }
  -
  -    /**
  -     * Get the value of a variable given its index.
  -     */
  -    public final Object getVariable(int vindex) {
  -	return varsStack.get(vbase + vindex);
  -    }
  -	
  -    /**
  -     * Set the value of a variable in the current frame.
  -     */
  -    public final void addVariable(int vindex, Object value) {
  -	varsStack.set(vbase + vindex, value);
       }
   
       /************************************************************************
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org


Mime
View raw message