jaxp/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Expression.java
author joehw
Thu, 12 Apr 2012 08:38:26 -0700
changeset 12457 c348e06f0e82
parent 6 jaxp/src/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Expression.java@7f561c08de6b
permissions -rw-r--r--
7160496: Rename JDK8 JAXP source directory Summary: moving src/share/classes to src Reviewed-by: ohair
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
6
7f561c08de6b Initial load
duke
parents:
diff changeset
     1
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
     2
 * reserved comment block
7f561c08de6b Initial load
duke
parents:
diff changeset
     3
 * DO NOT REMOVE OR ALTER!
7f561c08de6b Initial load
duke
parents:
diff changeset
     4
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
     5
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
     6
 * Copyright 2001-2004 The Apache Software Foundation.
7f561c08de6b Initial load
duke
parents:
diff changeset
     7
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
     8
 * Licensed under the Apache License, Version 2.0 (the "License");
7f561c08de6b Initial load
duke
parents:
diff changeset
     9
 * you may not use this file except in compliance with the License.
7f561c08de6b Initial load
duke
parents:
diff changeset
    10
 * You may obtain a copy of the License at
7f561c08de6b Initial load
duke
parents:
diff changeset
    11
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    12
 *     http://www.apache.org/licenses/LICENSE-2.0
7f561c08de6b Initial load
duke
parents:
diff changeset
    13
 *
7f561c08de6b Initial load
duke
parents:
diff changeset
    14
 * Unless required by applicable law or agreed to in writing, software
7f561c08de6b Initial load
duke
parents:
diff changeset
    15
 * distributed under the License is distributed on an "AS IS" BASIS,
7f561c08de6b Initial load
duke
parents:
diff changeset
    16
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
7f561c08de6b Initial load
duke
parents:
diff changeset
    17
 * See the License for the specific language governing permissions and
7f561c08de6b Initial load
duke
parents:
diff changeset
    18
 * limitations under the License.
7f561c08de6b Initial load
duke
parents:
diff changeset
    19
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    20
/*
7f561c08de6b Initial load
duke
parents:
diff changeset
    21
 * $Id: Expression.java,v 1.2.4.1 2005/09/01 14:17:51 pvedula Exp $
7f561c08de6b Initial load
duke
parents:
diff changeset
    22
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    23
7f561c08de6b Initial load
duke
parents:
diff changeset
    24
package com.sun.org.apache.xalan.internal.xsltc.compiler;
7f561c08de6b Initial load
duke
parents:
diff changeset
    25
7f561c08de6b Initial load
duke
parents:
diff changeset
    26
import java.util.Vector;
7f561c08de6b Initial load
duke
parents:
diff changeset
    27
7f561c08de6b Initial load
duke
parents:
diff changeset
    28
import com.sun.org.apache.bcel.internal.generic.BranchHandle;
7f561c08de6b Initial load
duke
parents:
diff changeset
    29
import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
7f561c08de6b Initial load
duke
parents:
diff changeset
    30
import com.sun.org.apache.bcel.internal.generic.GOTO_W;
7f561c08de6b Initial load
duke
parents:
diff changeset
    31
import com.sun.org.apache.bcel.internal.generic.IFEQ;
7f561c08de6b Initial load
duke
parents:
diff changeset
    32
import com.sun.org.apache.bcel.internal.generic.InstructionHandle;
7f561c08de6b Initial load
duke
parents:
diff changeset
    33
import com.sun.org.apache.bcel.internal.generic.InstructionList;
7f561c08de6b Initial load
duke
parents:
diff changeset
    34
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.BooleanType;
7f561c08de6b Initial load
duke
parents:
diff changeset
    35
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator;
7f561c08de6b Initial load
duke
parents:
diff changeset
    36
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg;
7f561c08de6b Initial load
duke
parents:
diff changeset
    37
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator;
7f561c08de6b Initial load
duke
parents:
diff changeset
    38
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType;
7f561c08de6b Initial load
duke
parents:
diff changeset
    39
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.NodeSetType;
7f561c08de6b Initial load
duke
parents:
diff changeset
    40
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type;
7f561c08de6b Initial load
duke
parents:
diff changeset
    41
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError;
7f561c08de6b Initial load
duke
parents:
diff changeset
    42
7f561c08de6b Initial load
duke
parents:
diff changeset
    43
/**
7f561c08de6b Initial load
duke
parents:
diff changeset
    44
 * @author Jacek Ambroziak
7f561c08de6b Initial load
duke
parents:
diff changeset
    45
 * @author Santiago Pericas-Geertsen
7f561c08de6b Initial load
duke
parents:
diff changeset
    46
 * @author Morten Jorgensen
7f561c08de6b Initial load
duke
parents:
diff changeset
    47
 * @author Erwin Bolwidt <ejb@klomp.org>
7f561c08de6b Initial load
duke
parents:
diff changeset
    48
 */
7f561c08de6b Initial load
duke
parents:
diff changeset
    49
abstract class Expression extends SyntaxTreeNode {
7f561c08de6b Initial load
duke
parents:
diff changeset
    50
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    51
     * The type of this expression. It is set after calling
7f561c08de6b Initial load
duke
parents:
diff changeset
    52
     * <code>typeCheck()</code>.
7f561c08de6b Initial load
duke
parents:
diff changeset
    53
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    54
    protected Type _type;
7f561c08de6b Initial load
duke
parents:
diff changeset
    55
7f561c08de6b Initial load
duke
parents:
diff changeset
    56
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    57
     * Instruction handles that comprise the true list.
7f561c08de6b Initial load
duke
parents:
diff changeset
    58
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    59
    protected FlowList _trueList = new FlowList();
7f561c08de6b Initial load
duke
parents:
diff changeset
    60
7f561c08de6b Initial load
duke
parents:
diff changeset
    61
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    62
     * Instruction handles that comprise the false list.
7f561c08de6b Initial load
duke
parents:
diff changeset
    63
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    64
    protected FlowList _falseList = new FlowList();
7f561c08de6b Initial load
duke
parents:
diff changeset
    65
7f561c08de6b Initial load
duke
parents:
diff changeset
    66
    public Type getType() {
7f561c08de6b Initial load
duke
parents:
diff changeset
    67
        return _type;
7f561c08de6b Initial load
duke
parents:
diff changeset
    68
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
    69
7f561c08de6b Initial load
duke
parents:
diff changeset
    70
    public abstract String toString();
7f561c08de6b Initial load
duke
parents:
diff changeset
    71
7f561c08de6b Initial load
duke
parents:
diff changeset
    72
    public boolean hasPositionCall() {
7f561c08de6b Initial load
duke
parents:
diff changeset
    73
        return false;           // default should be 'false' for StepPattern
7f561c08de6b Initial load
duke
parents:
diff changeset
    74
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
    75
7f561c08de6b Initial load
duke
parents:
diff changeset
    76
    public boolean hasLastCall() {
7f561c08de6b Initial load
duke
parents:
diff changeset
    77
        return false;
7f561c08de6b Initial load
duke
parents:
diff changeset
    78
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
    79
7f561c08de6b Initial load
duke
parents:
diff changeset
    80
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    81
     * Returns an object representing the compile-time evaluation
7f561c08de6b Initial load
duke
parents:
diff changeset
    82
     * of an expression. We are only using this for function-available
7f561c08de6b Initial load
duke
parents:
diff changeset
    83
     * and element-available at this time.
7f561c08de6b Initial load
duke
parents:
diff changeset
    84
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    85
    public Object evaluateAtCompileTime() {
7f561c08de6b Initial load
duke
parents:
diff changeset
    86
        return null;
7f561c08de6b Initial load
duke
parents:
diff changeset
    87
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
    88
7f561c08de6b Initial load
duke
parents:
diff changeset
    89
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    90
     * Type check all the children of this node.
7f561c08de6b Initial load
duke
parents:
diff changeset
    91
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    92
    public Type typeCheck(SymbolTable stable) throws TypeCheckError {
7f561c08de6b Initial load
duke
parents:
diff changeset
    93
        return typeCheckContents(stable);
7f561c08de6b Initial load
duke
parents:
diff changeset
    94
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
    95
7f561c08de6b Initial load
duke
parents:
diff changeset
    96
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
    97
     * Translate this node into JVM bytecodes.
7f561c08de6b Initial load
duke
parents:
diff changeset
    98
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
    99
    public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   100
        ErrorMsg msg = new ErrorMsg(ErrorMsg.NOT_IMPLEMENTED_ERR,
7f561c08de6b Initial load
duke
parents:
diff changeset
   101
                                    getClass(), this);
7f561c08de6b Initial load
duke
parents:
diff changeset
   102
        getParser().reportError(FATAL, msg);
7f561c08de6b Initial load
duke
parents:
diff changeset
   103
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   104
7f561c08de6b Initial load
duke
parents:
diff changeset
   105
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   106
     * Translate this node into a fresh instruction list.
7f561c08de6b Initial load
duke
parents:
diff changeset
   107
     * The original instruction list is saved and restored.
7f561c08de6b Initial load
duke
parents:
diff changeset
   108
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   109
    public final InstructionList compile(ClassGenerator classGen,
7f561c08de6b Initial load
duke
parents:
diff changeset
   110
                                         MethodGenerator methodGen) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   111
        final InstructionList result, save = methodGen.getInstructionList();
7f561c08de6b Initial load
duke
parents:
diff changeset
   112
        methodGen.setInstructionList(result = new InstructionList());
7f561c08de6b Initial load
duke
parents:
diff changeset
   113
        translate(classGen, methodGen);
7f561c08de6b Initial load
duke
parents:
diff changeset
   114
        methodGen.setInstructionList(save);
7f561c08de6b Initial load
duke
parents:
diff changeset
   115
        return result;
7f561c08de6b Initial load
duke
parents:
diff changeset
   116
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   117
7f561c08de6b Initial load
duke
parents:
diff changeset
   118
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   119
     * Redefined by expressions of type boolean that use flow lists.
7f561c08de6b Initial load
duke
parents:
diff changeset
   120
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   121
    public void translateDesynthesized(ClassGenerator classGen,
7f561c08de6b Initial load
duke
parents:
diff changeset
   122
                                       MethodGenerator methodGen) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   123
        translate(classGen, methodGen);
7f561c08de6b Initial load
duke
parents:
diff changeset
   124
        if (_type instanceof BooleanType) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   125
            desynthesize(classGen, methodGen);
7f561c08de6b Initial load
duke
parents:
diff changeset
   126
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   127
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   128
7f561c08de6b Initial load
duke
parents:
diff changeset
   129
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   130
     * If this expression is of type node-set and it is not a variable
7f561c08de6b Initial load
duke
parents:
diff changeset
   131
     * reference, then call setStartNode() passing the context node.
7f561c08de6b Initial load
duke
parents:
diff changeset
   132
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   133
    public void startIterator(ClassGenerator classGen,
7f561c08de6b Initial load
duke
parents:
diff changeset
   134
                                   MethodGenerator methodGen) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   135
        // Ignore if type is not node-set
7f561c08de6b Initial load
duke
parents:
diff changeset
   136
        if (_type instanceof NodeSetType == false) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   137
            return;
7f561c08de6b Initial load
duke
parents:
diff changeset
   138
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   139
7f561c08de6b Initial load
duke
parents:
diff changeset
   140
        // setStartNode() should not be called if expr is a variable ref
7f561c08de6b Initial load
duke
parents:
diff changeset
   141
        Expression expr = this;
7f561c08de6b Initial load
duke
parents:
diff changeset
   142
        if (expr instanceof CastExpr) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   143
            expr = ((CastExpr) expr).getExpr();
7f561c08de6b Initial load
duke
parents:
diff changeset
   144
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   145
        if (expr instanceof VariableRefBase == false) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   146
            final InstructionList il = methodGen.getInstructionList();
7f561c08de6b Initial load
duke
parents:
diff changeset
   147
            il.append(methodGen.loadContextNode());
7f561c08de6b Initial load
duke
parents:
diff changeset
   148
            il.append(methodGen.setStartNode());
7f561c08de6b Initial load
duke
parents:
diff changeset
   149
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   150
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   151
7f561c08de6b Initial load
duke
parents:
diff changeset
   152
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   153
     * Synthesize a boolean expression, i.e., either push a 0 or 1 onto the
7f561c08de6b Initial load
duke
parents:
diff changeset
   154
     * operand stack for the next statement to succeed. Returns the handle
7f561c08de6b Initial load
duke
parents:
diff changeset
   155
     * of the instruction to be backpatched.
7f561c08de6b Initial load
duke
parents:
diff changeset
   156
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   157
    public void synthesize(ClassGenerator classGen, MethodGenerator methodGen) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   158
        final ConstantPoolGen cpg = classGen.getConstantPool();
7f561c08de6b Initial load
duke
parents:
diff changeset
   159
        final InstructionList il = methodGen.getInstructionList();
7f561c08de6b Initial load
duke
parents:
diff changeset
   160
        _trueList.backPatch(il.append(ICONST_1));
7f561c08de6b Initial load
duke
parents:
diff changeset
   161
        final BranchHandle truec = il.append(new GOTO_W(null));
7f561c08de6b Initial load
duke
parents:
diff changeset
   162
        _falseList.backPatch(il.append(ICONST_0));
7f561c08de6b Initial load
duke
parents:
diff changeset
   163
        truec.setTarget(il.append(NOP));
7f561c08de6b Initial load
duke
parents:
diff changeset
   164
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   165
7f561c08de6b Initial load
duke
parents:
diff changeset
   166
    public void desynthesize(ClassGenerator classGen,
7f561c08de6b Initial load
duke
parents:
diff changeset
   167
                             MethodGenerator methodGen) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   168
        final InstructionList il = methodGen.getInstructionList();
7f561c08de6b Initial load
duke
parents:
diff changeset
   169
        _falseList.add(il.append(new IFEQ(null)));
7f561c08de6b Initial load
duke
parents:
diff changeset
   170
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   171
7f561c08de6b Initial load
duke
parents:
diff changeset
   172
    public FlowList getFalseList() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   173
        return _falseList;
7f561c08de6b Initial load
duke
parents:
diff changeset
   174
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   175
7f561c08de6b Initial load
duke
parents:
diff changeset
   176
    public FlowList getTrueList() {
7f561c08de6b Initial load
duke
parents:
diff changeset
   177
        return _trueList;
7f561c08de6b Initial load
duke
parents:
diff changeset
   178
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   179
7f561c08de6b Initial load
duke
parents:
diff changeset
   180
    public void backPatchFalseList(InstructionHandle ih) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   181
        _falseList.backPatch(ih);
7f561c08de6b Initial load
duke
parents:
diff changeset
   182
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   183
7f561c08de6b Initial load
duke
parents:
diff changeset
   184
    public void backPatchTrueList(InstructionHandle ih) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   185
        _trueList.backPatch(ih);
7f561c08de6b Initial load
duke
parents:
diff changeset
   186
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   187
7f561c08de6b Initial load
duke
parents:
diff changeset
   188
    /**
7f561c08de6b Initial load
duke
parents:
diff changeset
   189
     * Search for a primop in the symbol table that matches the method type
7f561c08de6b Initial load
duke
parents:
diff changeset
   190
     * <code>ctype</code>. Two methods match if they have the same arity.
7f561c08de6b Initial load
duke
parents:
diff changeset
   191
     * If a primop is overloaded then the "closest match" is returned. The
7f561c08de6b Initial load
duke
parents:
diff changeset
   192
     * first entry in the vector of primops that has the right arity is
7f561c08de6b Initial load
duke
parents:
diff changeset
   193
     * considered to be the default one.
7f561c08de6b Initial load
duke
parents:
diff changeset
   194
     */
7f561c08de6b Initial load
duke
parents:
diff changeset
   195
    public MethodType lookupPrimop(SymbolTable stable, String op,
7f561c08de6b Initial load
duke
parents:
diff changeset
   196
                                   MethodType ctype) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   197
        MethodType result = null;
7f561c08de6b Initial load
duke
parents:
diff changeset
   198
        final Vector primop = stable.lookupPrimop(op);
7f561c08de6b Initial load
duke
parents:
diff changeset
   199
        if (primop != null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   200
            final int n = primop.size();
7f561c08de6b Initial load
duke
parents:
diff changeset
   201
            int minDistance = Integer.MAX_VALUE;
7f561c08de6b Initial load
duke
parents:
diff changeset
   202
            for (int i = 0; i < n; i++) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   203
                final MethodType ptype = (MethodType) primop.elementAt(i);
7f561c08de6b Initial load
duke
parents:
diff changeset
   204
                // Skip if different arity
7f561c08de6b Initial load
duke
parents:
diff changeset
   205
                if (ptype.argsCount() != ctype.argsCount()) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   206
                    continue;
7f561c08de6b Initial load
duke
parents:
diff changeset
   207
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   208
7f561c08de6b Initial load
duke
parents:
diff changeset
   209
                // The first method with the right arity is the default
7f561c08de6b Initial load
duke
parents:
diff changeset
   210
                if (result == null) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   211
                    result = ptype;             // default method
7f561c08de6b Initial load
duke
parents:
diff changeset
   212
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   213
7f561c08de6b Initial load
duke
parents:
diff changeset
   214
                // Check if better than last one found
7f561c08de6b Initial load
duke
parents:
diff changeset
   215
                final int distance = ctype.distanceTo(ptype);
7f561c08de6b Initial load
duke
parents:
diff changeset
   216
                if (distance < minDistance) {
7f561c08de6b Initial load
duke
parents:
diff changeset
   217
                    minDistance = distance;
7f561c08de6b Initial load
duke
parents:
diff changeset
   218
                    result = ptype;
7f561c08de6b Initial load
duke
parents:
diff changeset
   219
                }
7f561c08de6b Initial load
duke
parents:
diff changeset
   220
            }
7f561c08de6b Initial load
duke
parents:
diff changeset
   221
        }
7f561c08de6b Initial load
duke
parents:
diff changeset
   222
        return result;
7f561c08de6b Initial load
duke
parents:
diff changeset
   223
    }
7f561c08de6b Initial load
duke
parents:
diff changeset
   224
}