santiagopg    2003/12/23 12:02:46

  Modified:    java/src/org/apache/xalan/xsltc/compiler CallTemplate.java
                        Param.java ParameterRef.java Template.java
                        VariableBase.java WithParam.java
               java/src/org/apache/xalan/xsltc/compiler/util
                        NamedMethodGenerator.java
  Log:
  The parameter optimization implemented in 2.5.2 does not work in all cases. 
The problem (see Bugzilla 25449) is that a param's default value needs to be 
compiled multiples when there are mulitple calls the a template none of which 
has a correspoding with-param. However, ASTs store an internal state which is 
not restored after compilation; consequently, only the first compilation is 
guaranteed to succeed. Stated differently, the AST cannot be operated as a 
graph because sub-tree sharing causes problems.
  
  The optimization has now been changed so that a param default value is 
compiled only once by the callee instead of multiple times by each caller. A 
caller will now pass 'null' when there is no with-param; a callee will only 
initialize a param if its value is 'null'. This ensures that default values are 
compiled exactly once while at the same time preserving the XSLT semantics.
  
  Revision  Changes    Path
  1.16      +46 -112   
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/CallTemplate.java
  
  Index: CallTemplate.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/CallTemplate.java,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- CallTemplate.java 6 Oct 2003 13:53:13 -0000       1.15
  +++ CallTemplate.java 23 Dec 2003 20:02:45 -0000      1.16
  @@ -80,23 +80,24 @@
   import java.util.Vector;
   
   final class CallTemplate extends Instruction {
  +    
  +    /**
  +     * Name of template to call.
  +     */
       private QName _name;
       
  -    // The array of effective parameters in this CallTemplate.
  -    // An object in this array can be either a WithParam or
  -    // a Param if no WithParam exists for a particular parameter.
  +    /** 
  +     * The array of effective parameters in this CallTemplate. An object in 
  +     * this array can be either a WithParam or a Param if no WithParam 
  +     * exists for a particular parameter.
  +     */
       private Object[] _parameters = null;
  -    
  -    // True if we need to create temporary variables to hold
  -    // the parameter values.
  -    private boolean _createTempVar = false;
  -    
  -    // The corresponding template which this CallTemplate calls.
  +        
  +    /**
  +     * The corresponding template which this CallTemplate calls.
  +     */
       private Template _calleeTemplate = null;
       
  -    // The array to hold the old load instructions for the parameters.
  -    private org.apache.bcel.generic.Instruction[] _oldLoadInstructions;
  -
       public void display(int indent) {
        indent(indent);
        System.out.print("CallTemplate");
  @@ -128,23 +129,16 @@
        return Type.Void;
       }
   
  -    /**
  -     * Translate call-template.
  -     * A parameter frame is pushed only if some template in the stylesheet
  -     * uses parameters.
  -     * TODO: optimize by checking if the callee has parameters.
  -     */
       public void translate(ClassGenerator classGen, MethodGenerator 
methodGen) {
        final Stylesheet stylesheet = classGen.getStylesheet();
        final ConstantPoolGen cpg = classGen.getConstantPool();
        final InstructionList il = methodGen.getInstructionList();
   
  -
  +        // If there are Params in the stylesheet or WithParams in this call?
        if (stylesheet.hasLocalParams() || hasContents()) {
            _calleeTemplate = getCalleeTemplate();
            
  -         // Build the parameter list if the called template is
  -         // a simple named template.
  +         // Build the parameter list if the called template is simple named
            if (_calleeTemplate != null) {
                buildParameterList();
            }
  @@ -157,95 +151,49 @@
                                                  PUSH_PARAM_FRAME_SIG);
                il.append(classGen.loadTranslet());
                il.append(new INVOKEVIRTUAL(push));
  -             // Translate with-params
                translateContents(classGen, methodGen);
            }
        }
   
  +        // Generate a valid Java method name
        final String className = stylesheet.getClassName();
  -     // Generate a valid Java method name
  -     String methodName = Util.escape(_name.toString());
  +        String methodName = Util.escape(_name.toString());
   
  +        // Load standard arguments
        il.append(classGen.loadTranslet());
        il.append(methodGen.loadDOM());
        il.append(methodGen.loadIterator());
        il.append(methodGen.loadHandler());
        il.append(methodGen.loadCurrentNode());
  -     String methodSig = "(" + DOM_INTF_SIG + NODE_ITERATOR_SIG
  -                        + TRANSLET_OUTPUT_SIG + NODE_SIG;
  +        
  +        // Initialize prefix of method signature
  +     StringBuffer methodSig = new StringBuffer("(" + DOM_INTF_SIG 
  +            + NODE_ITERATOR_SIG + TRANSLET_OUTPUT_SIG + NODE_SIG);
        
  +        // If calling a simply named template, push actual arguments
        if (_calleeTemplate != null) {
            Vector calleeParams = _calleeTemplate.getParameters();
            int numParams = _parameters.length;
  -         org.apache.bcel.generic.Type objectType = null;                     
            
  -         if (_createTempVar) {
  -             _oldLoadInstructions = new 
org.apache.bcel.generic.Instruction[numParams];
  -             objectType = Util.getJCRefType(OBJECT_SIG);
  -         }
  -         
  -         // Translate all effective WithParams and Params in the list
            for (int i = 0; i < numParams; i++) {
  -             methodSig = methodSig + OBJECT_SIG;
                SyntaxTreeNode node = (SyntaxTreeNode)_parameters[i];
  -             node.translate(classGen, methodGen);
  -             
  -             // Store the parameter value in a local variable if default
  -             // parameters are used. In this case the default value of a
  -             // parameter may reference another parameter declared earlier. 
  -             if (_createTempVar) {
  -                 il.append(DUP);
  -                 
  -                 // The name of the variable used to hold the value of a
  -                 // parameter
  -                 String name = "call$template$" + 
Util.escape(_name.toString())
  -                               + "$" + getParameterName(node);
  -                 
  -                 // Search for the local variable first, only add it
  -                 // if it does not exist.
  -                 LocalVariableGen local = methodGen.getLocalVariable(name);
  -                 
  -                 if (local == null) {
  -                     local = methodGen.addLocalVariable2(name,
  -                                         objectType,
  -                                         il.getEnd());
  -                 }
  -                 
  -                 // Store the parameter value into a variable.
  -                 il.append(new ASTORE(local.getIndex()));
  -                 
  -                 // Update the load instructions of the Param objects so that
  -                 // they point to the local variables. Store the old load
  -                 // instructions in the _oldLoadInstructions array so that
  -                 // we can restore them later. 
  -                 if (node instanceof Param) {
  -                     Param param = (Param)node;              
  -                     org.apache.bcel.generic.Instruction oldInstruction = 
  -                         param.setLoadInstruction(new 
ALOAD(local.getIndex()));                      
  -                     _oldLoadInstructions[param.getIndex()] = oldInstruction;
  -                 }
  -                 else if (node instanceof WithParam) {
  -                     Param param = (Param)calleeParams.elementAt(i);
  -                     org.apache.bcel.generic.Instruction oldInstruction = 
  -                         param.setLoadInstruction(new 
ALOAD(local.getIndex()));
  -                     _oldLoadInstructions[param.getIndex()] = oldInstruction;
  -                 }
  -             }
  -         }
  -         
  -         // Restore the old load instructions for the Params.
  -         if (_createTempVar) {
  -             for (int i = 0; i < numParams; i++) {
  -                 Param param = (Param)calleeParams.elementAt(i);
  -                 param.setLoadInstruction(_oldLoadInstructions[i]);     
  -             }
  -         }
  -     }
  -     
  -     methodSig = methodSig + ")V";
  +                methodSig.append(OBJECT_SIG);   // append Object to signature
  +                
  +                // Push 'null' if Param to indicate no actual parameter 
specified
  +                if (node instanceof Param) {
  +                    il.append(ACONST_NULL);
  +                }
  +                else {  // translate WithParam
  +                    node.translate(classGen, methodGen);
  +                }
  +            }
  +        }
  +
  +        // Complete signature and generate invokevirtual call
  +     methodSig.append(")V");
        il.append(new INVOKEVIRTUAL(cpg.addMethodref(className,
                                                     methodName,
  -                                                  methodSig)));
  +                                                  methodSig.toString())));
        
        // Do not need to call Translet.popParamFrame() if we are
        // calling a simple named template.
  @@ -270,8 +218,7 @@
               WithParam withParam = (WithParam)node;
               return Util.escape(withParam.getName().toString());
           }
  -        else
  -            return null;
  +        return null;
       }
       
       /**
  @@ -282,6 +229,7 @@
       public Template getCalleeTemplate() {
        Stylesheet stylesheet = getXSLTC().getStylesheet();
        Vector templates = stylesheet.getAllValidTemplates();
  +        
        int size = templates.size();
        for (int i = 0; i < size; i++) {
            Template t = (Template)templates.elementAt(i);
  @@ -312,9 +260,13 @@
        int count = elementCount();
        for (int i = 0; i < count; i++) {
            Object node = elementAt(i);
  +            
  +            // Ignore if not WithParam
            if (node instanceof WithParam) {
                WithParam withParam = (WithParam)node;
                QName name = withParam.getName();
  +                
  +                // Search for a Param with the same name
                for (int k = 0; k < numParams; k++) {
                    Object object = _parameters[k];
                    if (object instanceof Param 
  @@ -332,24 +284,6 @@
                }               
            }
        }
  -     
  -     // Set the _createTempVar flag to true if the select expression
  -     // in a parameter may reference another parameter.
  -     for (int i = 0; i < numParams; i++) {
  -         if (_parameters[i] instanceof Param) {
  -             Param param = (Param)_parameters[i];
  -             Expression expr = param.getExpression();
  -             if ((expr != null || param.elementCount() != 0)
  -                 && !(expr instanceof CastExpr
  -                     && (((CastExpr)expr).getExpr() instanceof LiteralExpr
  -                         || ((CastExpr)expr).getExpr() instanceof 
BooleanExpr)))
  -             {
  -                 _createTempVar = true;
  -                 break;      
  -             }
  -         }
  -     }
  -    }
  -    
  +     }
   }
       
  
  
  
  1.26      +34 -39    
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.25
  retrieving revision 1.26
  diff -u -r1.25 -r1.26
  --- Param.java        11 Nov 2003 14:40:28 -0000      1.25
  +++ Param.java        23 Dec 2003 20:02:45 -0000      1.26
  @@ -67,7 +67,9 @@
   package org.apache.xalan.xsltc.compiler;
   
   import org.apache.bcel.classfile.Field;
  +import org.apache.bcel.generic.BranchHandle;
   import org.apache.bcel.generic.CHECKCAST;
  +import org.apache.bcel.generic.IFNONNULL;
   import org.apache.bcel.generic.ConstantPoolGen;
   import org.apache.bcel.generic.INVOKEVIRTUAL;
   import org.apache.bcel.generic.Instruction;
  @@ -80,38 +82,42 @@
   import org.apache.xalan.xsltc.compiler.util.ReferenceType;
   import org.apache.xalan.xsltc.compiler.util.Type;
   import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
  -
   import org.apache.xalan.xsltc.runtime.BasisLibrary;
  +
   final class Param extends VariableBase {
   
  -    // True if this Param is declared in a simple named template.
  -    // This is used to optimize codegen for parameter passing
  -    // in named templates.
  +    /**
  +     * True if this Param is declared in a simple named template.
  +     * This is used to optimize codegen for parameter passing
  +     * in named templates.
  +     */
       private boolean _isInSimpleNamedTemplate = false;
   
  -    // The order index of the parameter, which is only used when
  -    // the Param is declared in a simple named template.
  -    private int _index = 0;
  -
       /**
        * Display variable as single string
        */
       public String toString() {
  -     return("param("+_name+")");
  +     return "param(" + _name + ")";
       }
   
       /**
  -     * Set the index of this parameter
  +     * Set the instruction for loading the value of this variable onto the 
  +     * JVM stack and returns the old instruction.
        */
  -    public void setIndex(int index) {
  -        _index = index;
  +    public Instruction setLoadInstruction(Instruction instruction) {
  +        Instruction tmp = _loadInstruction;
  +        _loadInstruction = instruction;
  +        return tmp;
       }
   
       /**
  -     * Return the index of this parameter
  +     * Set the instruction for storing a value from the stack into this
  +     * variable and returns the old instruction.
        */
  -    public int getIndex() {
  -        return _index;
  +    public Instruction setStoreInstruction(Instruction instruction) {
  +        Instruction tmp = _storeInstruction;
  +        _storeInstruction = instruction;
  +        return tmp;
       }
   
       /**
  @@ -198,33 +204,33 @@
       }
   
       public void translate(ClassGenerator classGen, MethodGenerator 
methodGen) {
  -
        final ConstantPoolGen cpg = classGen.getConstantPool();
        final InstructionList il = methodGen.getInstructionList();
   
        if (_ignore) return;
  -     // _ignore = true;
  +     _ignore = true;
   
           /*
            * To fix bug 24518 related to setting parameters of the form
  -         * {namespaceuri}localName
  -         * which will get mapped to an instance variable in the class
  -         * Hence  a parameter of the form "{http://foo.bar}xyz";
  -         * will be replaced with the corresponding values
  -         * by the BasisLibrary's utility method mapQNametoJavaName
  -         * and thus get mapped to legal java variable names
  +         * {namespaceuri}localName which will get mapped to an instance 
  +         * variable in the class.
            */
        final String name = BasisLibrary.mapQNameToJavaName(_name.toString());
        final String signature = _type.toSignature();
        final String className = _type.getClassName();
   
        if (isLocal()) {
  -
  -            // %OPT% Only translate the value and put it on the
  -            // stack if this Param is in a simple named template.
  -            // No need to call Translet.addParameter().
  +            /*
  +              * If simple named template then generate a conditional init of 
the 
  +              * param using its default value: 
  +              *       if (param == null) param = <default-value>
  +              */
               if (_isInSimpleNamedTemplate) {
  +             il.append(loadInstruction());
  +                BranchHandle ifBlock = il.append(new IFNONNULL(null));
                   translateValue(classGen, methodGen);
  +                il.append(storeInstruction());
  +                ifBlock.setTarget(il.append(NOP));
                   return;
               }
               
  @@ -282,15 +288,4 @@
            }
        }
       }
  -
  -    /**
  -     * Set the instruction handle for loading the value of this
  -     * variable onto the JVM stack and returns the old instruction handle.
  -     */
  -    public Instruction setLoadInstruction(Instruction instruction) {
  -        Instruction tmp = _loadInstruction;
  -        _loadInstruction = instruction;
  -        return tmp;
  -    }
  -
   }
  
  
  
  1.16      +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.15
  retrieving revision 1.16
  diff -u -r1.15 -r1.16
  --- ParameterRef.java 11 Nov 2003 14:40:28 -0000      1.15
  +++ ParameterRef.java 23 Dec 2003 20:02:45 -0000      1.16
  @@ -73,11 +73,15 @@
   import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
   import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
   import org.apache.xalan.xsltc.compiler.util.NodeSetType;
  -
   import org.apache.xalan.xsltc.runtime.BasisLibrary;
  +
   final class ParameterRef extends VariableRefBase {
   
  -    QName _name= null ;
  +    /**
  +     * Name of param being referenced.
  +     */
  +    QName _name = null;
  +    
       public ParameterRef(Param param) {
        super(param);
           _name = param._name;
  @@ -88,22 +92,16 @@
        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();
   
           /*
            * To fix bug 24518 related to setting parameters of the form
  -         * {namespaceuri}localName
  -         * which will get mapped to an instance variable in the class
  -         * Hence  a parameter of the form "{http://foo.bar}xyz";
  -         * will be replaced with the corresponding values 
  -         * by the BasisLibrary's utility method mapQNametoJavaName
  -         * and thus get mapped to legal java variable names 
  +         * {namespaceuri}localName, which will get mapped to an instance 
  +         * variable in the class.
            */
  -
           final String name = BasisLibrary.mapQNameToJavaName 
(_name.toString());
  -
        final String signature = _type.toSignature();
   
        if (_variable.isLocal()) {
  
  
  
  1.23      +8 -48     
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.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- Template.java     8 Jul 2003 20:32:51 -0000       1.22
  +++ Template.java     23 Dec 2003 20:02:45 -0000      1.23
  @@ -115,7 +115,6 @@
       }
       
       public void addParameter(Param param) {
  -     param.setIndex(_parameters.size());
        _parameters.addElement(param);
       }
       
  @@ -352,58 +351,19 @@
                
        // %OPT% Special handling for simple named templates.
        if (_isSimpleNamedTemplate && methodGen instanceof 
NamedMethodGenerator) {
  -         NamedMethodGenerator namedMethodGen = 
(NamedMethodGenerator)methodGen;
            int numParams = _parameters.size();
  -         // Update the load instructions of the Params, so that they
  -         // are loaded from the method parameters. 
  +         NamedMethodGenerator namedMethodGen = 
(NamedMethodGenerator)methodGen;
  +            
  +            // Update load/store instructions to access Params from the stack
            for (int i = 0; i < numParams; i++) {
                Param param = (Param)_parameters.elementAt(i);
                param.setLoadInstruction(namedMethodGen.loadParameter(i));
  +             param.setStoreInstruction(namedMethodGen.storeParameter(i));
            }
  -         // Translate all children except the parameters.
  -         // The parameters are translated in CallTemplates if necessary.
  -         translateContentsWithoutParams(classGen, methodGen);
        }
  -     else {
  -         translateContents(classGen, methodGen);
  -     }
  -     
  +        
  +        translateContents(classGen, methodGen);
        il.setPositions(true);
       }
  -    
  -    /**
  -     * Call translate() on all child syntax tree nodes except the parameters.
  -     * 
  -     * This is used for a simple named template, where the paramters are
  -     * translated in the CallTemplate if necessary.
  -     * 
  -     * @param classGen BCEL Java class generator
  -     * @param methodGen BCEL Java method generator
  -     */
  -    protected void translateContentsWithoutParams(
  -        ClassGenerator classGen,
  -        MethodGenerator methodGen) {
  -        // Call translate() on all child nodes
  -        final int n = elementCount();
  -        for (int i = 0; i < n; i++) {
  -            final SyntaxTreeNode item = (SyntaxTreeNode) elementAt(i);
  -            if (!(item instanceof Param)) {
  -                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 (elementAt(i) instanceof Variable) {
  -                final Variable var = (Variable) elementAt(i);
  -                var.unmapRegister(methodGen);
  -            }
  -        }
  -    }
  -    
  +        
   }
  
  
  
  1.21      +18 -4     
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/VariableBase.java
  
  Index: VariableBase.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/VariableBase.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- VariableBase.java 19 Dec 2003 15:26:48 -0000      1.20
  +++ VariableBase.java 23 Dec 2003 20:02:45 -0000      1.21
  @@ -90,6 +90,7 @@
       protected boolean     _isLocal;         // True if the variable is local.
       protected LocalVariableGen _local;      // Reference to JVM variable
       protected Instruction _loadInstruction; // Instruction to load JVM 
variable
  +    protected Instruction _storeInstruction; // Instruction to load JVM 
variable
       protected Expression  _select;          // Reference to variable 
expression
       protected String      select;           // Textual repr. of variable 
expr.
   
  @@ -173,14 +174,27 @@
       }
   
       /**
  -     * Returns a handle to the instruction for loading the value of this
  -     * variable onto the JVM stack.
  +     * Returns an instruction for loading the value of this variable onto 
  +     * the JVM stack.
        */
       public Instruction loadInstruction() {
        final Instruction instr = _loadInstruction;
  -     if (_loadInstruction == null) 
  +     if (_loadInstruction == null) {
            _loadInstruction = _type.LOAD(_local.getIndex());
  +        }
        return _loadInstruction;
  +    }
  +
  +    /**
  +     * Returns an instruction for storing a value from the JVM stack
  +     * into this variable.
  +     */
  +    public Instruction storeInstruction() {
  +     final Instruction instr = _storeInstruction;
  +     if (_storeInstruction == null) {
  +         _storeInstruction = _type.STORE(_local.getIndex());
  +        }
  +     return _storeInstruction;
       }
   
       /**
  
  
  
  1.15      +14 -7     
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.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- WithParam.java    19 Dec 2003 15:26:48 -0000      1.14
  +++ WithParam.java    23 Dec 2003 20:02:45 -0000      1.15
  @@ -79,14 +79,22 @@
   
   final class WithParam extends Instruction {
   
  +    /**
  +     * Parameter's name.
  +     */
       private QName _name;
  +    
  +    /**
  +     * Parameter's default value.
  +     */
       private Expression _select;
   
  -    // %OPT% This is set to true when the WithParam is used in a
  -    // CallTemplate for a simple named template. If this is true,
  -    // the parameters are passed to the named template through method
  -    // arguments rather than using the expensive Translet.addParameter()
  -    // call.
  +    /**
  +     * %OPT% This is set to true when the WithParam is used in a CallTemplate
  +     * for a simple named template. If this is true, the parameters are 
  +     * passed to the named template through method arguments rather than
  +     * using the expensive Translet.addParameter() call.
  +     */
       private boolean _doParameterOptimization = false;
   
       /**
  @@ -116,7 +124,6 @@
        _doParameterOptimization = flag;
       }
       
  -
       /**
        * The contents of a <xsl:with-param> elements are either in the 
element's
        * 'select' attribute (this has precedence) or in the element body.
  
  
  
  1.6       +6 -1      
xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/NamedMethodGenerator.java
  
  Index: NamedMethodGenerator.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/util/NamedMethodGenerator.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- NamedMethodGenerator.java 23 Jun 2003 18:23:15 -0000      1.5
  +++ NamedMethodGenerator.java 23 Dec 2003 20:02:46 -0000      1.6
  @@ -64,6 +64,7 @@
   package org.apache.xalan.xsltc.compiler.util;
   
   import org.apache.bcel.generic.ALOAD;
  +import org.apache.bcel.generic.ASTORE;
   import org.apache.bcel.generic.ConstantPoolGen;
   import org.apache.bcel.generic.Instruction;
   import org.apache.bcel.generic.InstructionList;
  @@ -96,5 +97,9 @@
   
       public Instruction loadParameter(int index) {
           return new ALOAD(index + PARAM_START_INDEX);
  +    }
  +    
  +    public Instruction storeParameter(int index) {
  +        return new ASTORE(index + PARAM_START_INDEX);
       }
   }
  
  
  

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

Reply via email to