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]