morten      01/07/31 02:11:52

  Modified:    java/src/org/apache/xalan/xsltc/compiler Expression.java
                        Param.java ParameterRef.java Predicate.java
                        Stylesheet.java SyntaxTreeNode.java Variable.java
                        VariableRef.java WithParam.java
  Log:
  Fix for parameter and variable handling. This fix makes sure variable slots
  are released once a variable goes out of scope. I have also extracted common
  functionality from Variable and Param into VariableBase, and similarly
  extracted some functionality from VariableRef and ParameterRef into a new
  class VariableRefBase. This can potentially make some code more efficient as
  one can test for 'if (blob instanceof VariableBase)' instead of testing on
  both Variable and Param.
  PR:           Bugzilla 2661 and 2699
  Obtained from:        n/a
  Submitted by: John Howard <[EMAIL PROTECTED]>
  Reviewed by:  [EMAIL PROTECTED]
  
  Revision  Changes    Path
  1.6       +2 -2      
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Expression.java
  
  Index: Expression.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Expression.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- Expression.java   2001/07/10 17:45:10     1.5
  +++ Expression.java   2001/07/31 09:11:51     1.6
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Expression.java,v 1.5 2001/07/10 17:45:10 morten Exp $
  + * @(#)$Id: Expression.java,v 1.6 2001/07/31 09:11:51 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -161,7 +161,7 @@
            return;             // nothing to do
        }
   
  -     if (this instanceof VariableRef) {
  +     if (this instanceof VariableRefBase) {
            // The method cloneIterator() also does resetting
            final int clone =
                cpg.addInterfaceMethodref(NODE_ITERATOR,
  
  
  
  1.9       +12 -55    
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Param.java
  
  Index: Param.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Param.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- Param.java        2001/07/10 17:45:21     1.8
  +++ Param.java        2001/07/31 09:11:51     1.9
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Param.java,v 1.8 2001/07/10 17:45:21 morten Exp $
  + * @(#)$Id: Param.java,v 1.9 2001/07/31 09:11:51 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -60,6 +60,7 @@
    * @author Santiago Pericas-Geertsen
    * @author Morten Jorgensen
    * @author Erwin Bolwidt <[EMAIL PROTECTED]>
  + * @author John Howard <[EMAIL PROTECTED]>
    *
    */
   
  @@ -76,22 +77,18 @@
   
   import org.apache.xalan.xsltc.compiler.util.*;
   
  -final class Param extends TopLevelElement {
  +final class Param extends VariableBase {
   
  -    private QName      _name;
  -    private boolean    _isLocal;     // true if the param is local
  -    private Expression _select;
  -    private Type       _type;
  -
  -    // a JavaClass construct to refer to a JVM var
  -    private LocalVariableGen _local;
  -    // cached JavaClass instruction to push the contents of this var
  -    private Instruction _loadInstruction;
  -    // references to this variable (when local)
  -    private Vector     _refs = new Vector(2);
  -    // to make sure parameter field is not added twice
  -    private boolean    _compiled = false;
  +    /**
  +     * Display variable as single string
  +     */
  +    public String toString() {
  +     return("param("+_name+")");
  +    }
   
  +    /**
  +     * Display variable in a full AST dump
  +     */
       public void display(int indent) {
        indent(indent);
        System.out.println("param " + _name);
  @@ -100,46 +97,6 @@
            System.out.println("select " + _select.toString());
        }
        displayContents(indent + IndentIncrement);
  -    }
  -
  -    public String toString() {
  -     return("param("+_name+")");
  -    }
  -
  -    public void addReference(ParameterRef pref) {
  -     _refs.addElement(pref);
  -    }
  -
  -    public void removeReference(ParameterRef pref) {
  -     _refs.remove(pref);
  -    }
  -    
  -    public void removeReference(ParameterRef pref, MethodGenerator 
methodGen) {
  -     _refs.remove(pref);
  -     if (_refs.isEmpty()) {
  -         _local.setEnd(methodGen.getInstructionList().getEnd());
  -         methodGen.removeLocalVariable(_local);
  -         _refs = null;
  -         _local = null;
  -     }
  -    }
  -
  -    public Instruction loadInstruction() {
  -     final Instruction instr = _loadInstruction;
  -     return instr != null
  -         ? instr : (_loadInstruction = _type.LOAD(_local.getIndex()));
  -    }
  -    
  -    public Type getType() {
  -     return _type;
  -    }
  -
  -    public boolean isLocal() {
  -     return _isLocal;
  -    }
  -
  -    public QName getName() {
  -     return _name;
       }
   
       public void parseContents(Parser parser) {
  
  
  
  1.3       +10 -12    
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.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ParameterRef.java 2001/07/10 17:45:23     1.2
  +++ ParameterRef.java 2001/07/31 09:11:51     1.3
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: ParameterRef.java,v 1.2 2001/07/10 17:45:23 morten Exp $
  + * @(#)$Id: ParameterRef.java,v 1.3 2001/07/31 09:11:51 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -69,16 +69,14 @@
   import de.fub.bytecode.generic.*;
   import org.apache.xalan.xsltc.compiler.util.*;
   
  -final class ParameterRef extends Expression {
  -    private final Param _param;
  -     
  +final class ParameterRef extends VariableRefBase {
  +
       public ParameterRef(Param param) {
  -     _param = param;
  -     param.addReference(this);
  +     super(param);
       }
   
       public String toString() {
  -     return "parameter-ref(" + _param.getName() + ')';
  +     return "parameter-ref(" + _variable.getName() + ')';
       }
   
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
  @@ -89,12 +87,12 @@
        final ConstantPoolGen cpg = classGen.getConstantPool();
        final InstructionList il = methodGen.getInstructionList();
                
  -     final Type parType = _param.getType();
  -     String parName = _param.getName().getLocalPart();
  +     final Type parType = _variable.getType();
  +     String parName = _variable.getName().getLocalPart();
        parName = parName.replace('.', '_');
        parName = parName.replace('-', '_');
   
  -     if (_param.isLocal()) {
  +     if (_variable.isLocal()) {
            if (classGen.isExternal()) {
                il.append(classGen.loadTranslet());
                il.append(new PUSH(cpg, parName));
  @@ -104,8 +102,8 @@
                il.append(new INVOKEVIRTUAL(index));
            }
            else {
  -             il.append(_param.loadInstruction());
  -             _param.removeReference(this, methodGen);
  +             il.append(_variable.loadInstruction());
  +             _variable.removeReference(this);
            }
        }
        else {
  
  
  
  1.7       +7 -8      
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.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- Predicate.java    2001/07/30 13:35:40     1.6
  +++ Predicate.java    2001/07/31 09:11:51     1.7
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Predicate.java,v 1.6 2001/07/30 13:35:40 morten Exp $
  + * @(#)$Id: Predicate.java,v 1.7 2001/07/31 09:11:51 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -114,9 +114,10 @@
                    _ptype = ((Step)exp).getNodeType();
                }
            }
  -         else if (parent instanceof VariableRef) {
  -             Variable var = ((VariableRef)parent).getVariable();
  -             Expression exp = var.getExpression();
  +         else if (parent instanceof VariableRefBase) {
  +             final VariableRefBase ref = (VariableRefBase)parent;
  +             final VariableBase var = ref.getVariable();
  +             final Expression exp = var.getExpression();
                if (exp instanceof Step) {
                    _ptype = ((Step)exp).getNodeType();
                }
  @@ -329,8 +330,7 @@
            try {
                if ((tleft == Type.String) && (!(left instanceof Step)))
                    _value = exp.getLeft();
  -             if ((left instanceof VariableRef) ||
  -                 (left instanceof ParameterRef))
  +             if (left instanceof VariableRefBase)
                    _value = new CastExpr(left, Type.String);
            }
            catch (TypeCheckError e) { }
  @@ -338,8 +338,7 @@
            try {
                if ((tright == Type.String) && (!(right instanceof Step)))
                    _value = exp.getRight();
  -             if ((right instanceof VariableRef) || 
  -                 (right instanceof ParameterRef))
  +             if (right instanceof VariableRefBase)
                    _value = new CastExpr(right, Type.String);
            }
            catch (TypeCheckError e) { }
  
  
  
  1.14      +5 -9      
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Stylesheet.java
  
  Index: Stylesheet.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Stylesheet.java,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- Stylesheet.java   2001/07/20 15:24:32     1.13
  +++ Stylesheet.java   2001/07/31 09:11:51     1.14
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Stylesheet.java,v 1.13 2001/07/20 15:24:32 morten Exp $
  + * @(#)$Id: Stylesheet.java,v 1.14 2001/07/31 09:11:51 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -328,7 +328,7 @@
        // variables and/or parameters before we parse the other elements...
        for (int i=0; i<count; i++) {
            SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i);
  -         if ((child instanceof Param) || (child instanceof Variable)) {
  +         if (child instanceof VariableBase) {
                parser.getSymbolTable().setCurrentNode(child);
                child.parseContents(parser);
            }
  @@ -337,7 +337,7 @@
        // Now go through all the other top-level elements...
        for (int i=0; i<count; i++) {
            SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i);
  -         if (!((child instanceof Param) || (child instanceof Variable))) {
  +         if (!(child instanceof VariableBase)) {
                parser.getSymbolTable().setCurrentNode(child);
                child.parseContents(parser);
            }
  @@ -611,12 +611,8 @@
            else if (element instanceof Whitespace) {
                whitespaceRules.addAll(((Whitespace)element).getRules());
            }
  -         // xsl:param
  -         else if (element instanceof Param) {
  -             ((Param)element).translate(classGen,toplevel);
  -         }
  -         // xsl:variable
  -         else if (element instanceof Variable) {
  +         // xsl:variable or xsl:param
  +         else if (element instanceof VariableBase) {
                ((Variable)element).translate(classGen,toplevel);
            }
        }
  
  
  
  1.11      +16 -1     
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.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- SyntaxTreeNode.java       2001/07/30 13:35:40     1.10
  +++ SyntaxTreeNode.java       2001/07/31 09:11:51     1.11
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: SyntaxTreeNode.java,v 1.10 2001/07/30 13:35:40 morten Exp $
  + * @(#)$Id: SyntaxTreeNode.java,v 1.11 2001/07/31 09:11:51 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -61,6 +61,7 @@
    * @author G. Todd Miller
    * @author Morten Jorensen
    * @author Erwin Bolwidt <[EMAIL PROTECTED]>
  + * @author John Howard <[EMAIL PROTECTED]>
    *
    */
   
  @@ -364,6 +365,20 @@
        for (int i = 0; i < n; i++) {
            final SyntaxTreeNode item = (SyntaxTreeNode)_contents.elementAt(i);
            item.translate(classGen, methodGen);
  +     }
  +
  +     /**
  +      * After translation, unmap any registers for any variables/parameters
  +      * that were declared in this scope. Performing this unmapping in the
  +      * same AST scope as the declaration deals with the problems of
  +      * references falling out-of-scope inside the for-each element.
  +      * (the cause of which being 'lazy' register allocation for references)
  +      */
  +     for (int i = 0; i < n; i++) {
  +         if( _contents.elementAt(i) instanceof VariableBase) {
  +             final VariableBase var = (VariableBase)_contents.elementAt(i);
  +             var.unmapRegister(methodGen);
  +         }
        }
       }
   
  
  
  
  1.11      +22 -91    
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.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- Variable.java     2001/07/30 13:35:40     1.10
  +++ Variable.java     2001/07/31 09:11:51     1.11
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: Variable.java,v 1.10 2001/07/30 13:35:40 morten Exp $
  + * @(#)$Id: Variable.java,v 1.11 2001/07/31 09:11:51 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -60,6 +60,7 @@
    * @author Santiago Pericas-Geertsen
    * @author Morten Jorgensen
    * @author Erwin Bolwidt <[EMAIL PROTECTED]>
  + * @author John Howard <[EMAIL PROTECTED]>
    *
    */
   
  @@ -74,45 +75,30 @@
   import org.apache.xalan.xsltc.compiler.util.*;
   import org.apache.xalan.xsltc.dom.Axis;
   
  -final class Variable extends TopLevelElement {
  +final class Variable extends VariableBase {
   
  -    // The name of the variable.
  -    private QName _name;
  -
  -    // The type of this variable.
  -    private Type _type;
  -
  -    // True if the variable is local.
  -    private boolean _isLocal;
  -    
  -    private LocalVariableGen _local;
  -    private Instruction _loadInstruction;
  -    
  -    // A reference to the select expression.
  -    private Expression _select;
  -     
       // Index of this variable in the variable stack relative to base ptr
       private int _stackIndex = -1;
   
       private boolean _escapes;
  -    private boolean _usedLocally;
   
  +    // If the variable is of result tree type, and this result tree 
  +    // is implemented as a method, this is the name of the method.
  +    private String _methodName = null;
  +
       /**
  -     * If the variable is of result tree type, and this result tree 
  -     * is implemented as a method, this is the name of the method.
  +     * Returns the method name for this variable. Used if the value of the
  +     * variable is a result tree and a separate method is used to build it.
  +     * The method name is generate in typeCheck(), so this method should 
never
  +     * be called before that.
        */
  -    private String _methodName;
  -
  -    // references to this variable (when local)
  -    private Vector _refs = new Vector(2);
  -
  -    // to make sure parameter field is not added twice
  -    private boolean    _compiled = false;
  -
  -    public void addReference(VariableRef vref) {
  -     _refs.addElement(vref);
  +    public String getMethodName() {
  +     return _methodName;
       }
   
  +    /**
  +     *
  +     */
       public void setEscapes() {
        _escapes = true;
        if (_stackIndex == -1) { // unassigned
  @@ -122,61 +108,10 @@
            }
        }
       }
  -
  -    public Expression getExpression() {
  -     return(_select);
  -    }
  -
  -    public String toString() {
  -     return("variable("+_name+")");
  -    }
  -
  -    public void setUsedLocally() {
  -     _usedLocally = true;
  -    }
  -
  -    public void removeReference(VariableRef vref, MethodGenerator methodGen) 
{
  -     _refs.remove(vref);
  -     if (_refs.isEmpty()) {
  -         _local.setEnd(methodGen.getInstructionList().getEnd());
  -         methodGen.removeLocalVariable(_local);
  -         _refs = null;
  -         _local = null;
  -     }
  -    }
  -    
  -    public Instruction loadInstruction() {
  -     final Instruction instr = _loadInstruction;
  -     return instr != null
  -         ? instr : (_loadInstruction = _type.LOAD(_local.getIndex()));
  -    }
  -    
  -    public void display(int indent) {
  -     indent(indent);
  -     System.out.println("Variable " + _name);
  -     if (_select != null) { 
  -         indent(indent + IndentIncrement);
  -         System.out.println("select " + _select.toString());
  -     }
  -     displayContents(indent + IndentIncrement);
  -    }
  -
  -    public String getMethodName() {
  -     return _methodName;
  -    }
   
  -    public Type getType() {
  -     return _type;
  -    }
  -
  -    public boolean isLocal() {
  -     return _isLocal;
  -    }
  -
  -    public QName getName() {
  -     return _name;
  -    }
  -
  +    /**
  +     *
  +     */
       public int getStackIndex() {
        return _stackIndex;
       }
  @@ -385,16 +320,12 @@
            }
   
            // Add a new local variable and store value
  -         if (_refs.isEmpty()) { // nobody uses the value
  +         if (_refs.isEmpty()) { // Remove it if nobody uses the value
                il.append(_type.POP());
                _local = null;
            }
  -         else {              // normal case
  -             if (_local == null) {
  -                 _local = methodGen.addLocalVariable2(name,
  -                                                      _type.toJCType(),
  -                                                      il.getEnd());
  -             }
  +         else {                 // Store in local var slot if referenced
  +             if (_local == null) mapRegister(methodGen);
                il.append(_type.STORE(_local.getIndex()));
            }
   
  
  
  
  1.4       +9 -21     
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.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- VariableRef.java  2001/07/10 17:45:33     1.3
  +++ VariableRef.java  2001/07/31 09:11:51     1.4
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: VariableRef.java,v 1.3 2001/07/10 17:45:33 morten Exp $
  + * @(#)$Id: VariableRef.java,v 1.4 2001/07/31 09:11:51 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -69,31 +69,18 @@
   import de.fub.bytecode.generic.*;
   import org.apache.xalan.xsltc.compiler.util.*;
   
  -final class VariableRef extends Expression {
  -    private final Variable _variable;
  +final class VariableRef extends VariableRefBase {
  +
       private boolean _escaped;
        
       public VariableRef(Variable variable) {
  -     _variable = variable;
  -     variable.addReference(this);
  -    }
  -
  -    public Variable getVariable() {
  -     return(_variable);
  -    }
  -
  -    public String toString() {
  -     return "variable-ref(" + _variable.getName() + ')';
  +     super(variable);
       }
   
       public Type typeCheck(SymbolTable stable) throws TypeCheckError {
        if (_variable.isLocal()) {
  -         if (_escaped = isEscaped()) {
  -             _variable.setEscapes();
  -         }
  -         else {
  -             _variable.setUsedLocally();
  -         }
  +         if (_escaped = isEscaped())
  +             ((Variable)_variable).setEscapes();
        }
        return _type = _variable.getType();
       }
  @@ -130,7 +117,8 @@
        if (_variable.isLocal()) {
            if (classGen.isExternal() || _escaped) {
                il.append(classGen.loadTranslet());
  -             il.append(new PUSH(cpg, _variable.getStackIndex()));
  +             final int sindex = ((Variable)_variable).getStackIndex();
  +             il.append(new PUSH(cpg, sindex));
                final int getVar = cpg.addMethodref(TRANSLET_CLASS, 
                                                    GET_VARIABLE,
                                                    GET_VARIABLE_SIG);
  @@ -139,7 +127,7 @@
            }
            else {
                il.append(_variable.loadInstruction());
  -             _variable.removeReference(this, methodGen);
  +             _variable.removeReference(this);
            }
        }
        else {
  
  
  
  1.5       +9 -2      
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/WithParam.java
  
  Index: WithParam.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/WithParam.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- WithParam.java    2001/07/09 10:17:44     1.4
  +++ WithParam.java    2001/07/31 09:11:51     1.5
  @@ -1,5 +1,5 @@
   /*
  - * @(#)$Id: WithParam.java,v 1.4 2001/07/09 10:17:44 morten Exp $
  + * @(#)$Id: WithParam.java,v 1.5 2001/07/31 09:11:51 morten Exp $
    *
    * The Apache Software License, Version 1.1
    *
  @@ -59,6 +59,7 @@
    * @author Jacek Ambroziak
    * @author Santiago Pericas-Geertsen
    * @author Morten Jorgensen
  + * @author John Howard <[EMAIL PROTECTED]>
    *
    */
   
  @@ -157,11 +158,17 @@
        final ConstantPoolGen cpg = classGen.getConstantPool();
        final InstructionList il = methodGen.getInstructionList();
   
  +     // Make name acceptable for use as field name in class
  +     // TODO: convert to escape sequence like $dot$ and $dash$
  +     String name = _name.getLocalPart(); // TODO: namespace ?
  +     name = name.replace('.', '_');
  +     name = name.replace('-', '_');
  +
        // Load reference to the translet (method is in AbstractTranslet)
        il.append(classGen.loadTranslet());
   
        // Load the name of the parameter
  -     il.append(new PUSH(cpg, _name.getLocalPart())); // TODO: namespace ?
  +     il.append(new PUSH(cpg, name)); // TODO: namespace ?
        // Generete the value of the parameter (use value in 'select' by def.)
        translateValue(classGen, methodGen);
        // Mark this parameter value is not being the default value
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to