langtools/src/share/classes/com/sun/tools/javac/comp/ConstFold.java
author briangoetz
Wed, 18 Dec 2013 16:05:18 -0500
changeset 22163 3651128c74eb
parent 15385 ee1eebe7e210
permissions -rw-r--r--
8030244: Update langtools to use Diamond Reviewed-by: darcy
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
10
06bc494ca11e Initial load
duke
parents:
diff changeset
     1
/*
15385
ee1eebe7e210 8006775: JSR 308: Compiler changes in JDK8
jjg
parents: 14801
diff changeset
     2
 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
06bc494ca11e Initial load
duke
parents:
diff changeset
     4
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
06bc494ca11e Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5520
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 10
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
10
06bc494ca11e Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5520
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 10
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    10
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
06bc494ca11e Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
06bc494ca11e Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
06bc494ca11e Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
06bc494ca11e Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
06bc494ca11e Initial load
duke
parents:
diff changeset
    16
 *
06bc494ca11e Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
06bc494ca11e Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
06bc494ca11e Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
06bc494ca11e Initial load
duke
parents:
diff changeset
    20
 *
5520
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 10
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 10
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
86e4b9a9da40 6943119: Rebrand source copyright notices
ohair
parents: 10
diff changeset
    23
 * questions.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    24
 */
06bc494ca11e Initial load
duke
parents:
diff changeset
    25
06bc494ca11e Initial load
duke
parents:
diff changeset
    26
package com.sun.tools.javac.comp;
06bc494ca11e Initial load
duke
parents:
diff changeset
    27
06bc494ca11e Initial load
duke
parents:
diff changeset
    28
import com.sun.tools.javac.code.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    29
import com.sun.tools.javac.jvm.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    30
import com.sun.tools.javac.util.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    31
14359
d4099818ab70 7200915: convert TypeTags from a series of small ints to an enum
jjg
parents: 5847
diff changeset
    32
import static com.sun.tools.javac.code.TypeTag.BOOLEAN;
d4099818ab70 7200915: convert TypeTags from a series of small ints to an enum
jjg
parents: 5847
diff changeset
    33
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    34
import static com.sun.tools.javac.jvm.ByteCodes.*;
06bc494ca11e Initial load
duke
parents:
diff changeset
    35
06bc494ca11e Initial load
duke
parents:
diff changeset
    36
/** Helper class for constant folding, used by the attribution phase.
06bc494ca11e Initial load
duke
parents:
diff changeset
    37
 *  This class is marked strictfp as mandated by JLS 15.4.
06bc494ca11e Initial load
duke
parents:
diff changeset
    38
 *
5847
1908176fd6e3 6944312: Potential rebranding issues in openjdk/langtools repository sources
jjg
parents: 5520
diff changeset
    39
 *  <p><b>This is NOT part of any supported API.
1908176fd6e3 6944312: Potential rebranding issues in openjdk/langtools repository sources
jjg
parents: 5520
diff changeset
    40
 *  If you write code that depends on this, you do so at your own risk.
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    41
 *  This code and its internal interfaces are subject to change or
06bc494ca11e Initial load
duke
parents:
diff changeset
    42
 *  deletion without notice.</b>
06bc494ca11e Initial load
duke
parents:
diff changeset
    43
 */
06bc494ca11e Initial load
duke
parents:
diff changeset
    44
strictfp class ConstFold {
22163
3651128c74eb 8030244: Update langtools to use Diamond
briangoetz
parents: 15385
diff changeset
    45
    protected static final Context.Key<ConstFold> constFoldKey = new Context.Key<>();
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    46
06bc494ca11e Initial load
duke
parents:
diff changeset
    47
    private Symtab syms;
06bc494ca11e Initial load
duke
parents:
diff changeset
    48
06bc494ca11e Initial load
duke
parents:
diff changeset
    49
    public static ConstFold instance(Context context) {
06bc494ca11e Initial load
duke
parents:
diff changeset
    50
        ConstFold instance = context.get(constFoldKey);
06bc494ca11e Initial load
duke
parents:
diff changeset
    51
        if (instance == null)
06bc494ca11e Initial load
duke
parents:
diff changeset
    52
            instance = new ConstFold(context);
06bc494ca11e Initial load
duke
parents:
diff changeset
    53
        return instance;
06bc494ca11e Initial load
duke
parents:
diff changeset
    54
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
    55
06bc494ca11e Initial load
duke
parents:
diff changeset
    56
    private ConstFold(Context context) {
06bc494ca11e Initial load
duke
parents:
diff changeset
    57
        context.put(constFoldKey, this);
06bc494ca11e Initial load
duke
parents:
diff changeset
    58
06bc494ca11e Initial load
duke
parents:
diff changeset
    59
        syms = Symtab.instance(context);
06bc494ca11e Initial load
duke
parents:
diff changeset
    60
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
    61
14801
d66cab4ef397 8003967: detect and remove all mutable implicit static enum fields in langtools
vromero
parents: 14359
diff changeset
    62
    static final Integer minusOne = -1;
d66cab4ef397 8003967: detect and remove all mutable implicit static enum fields in langtools
vromero
parents: 14359
diff changeset
    63
    static final Integer zero     = 0;
d66cab4ef397 8003967: detect and remove all mutable implicit static enum fields in langtools
vromero
parents: 14359
diff changeset
    64
    static final Integer one      = 1;
10
06bc494ca11e Initial load
duke
parents:
diff changeset
    65
06bc494ca11e Initial load
duke
parents:
diff changeset
    66
   /** Convert boolean to integer (true = 1, false = 0).
06bc494ca11e Initial load
duke
parents:
diff changeset
    67
    */
06bc494ca11e Initial load
duke
parents:
diff changeset
    68
    private static Integer b2i(boolean b) {
06bc494ca11e Initial load
duke
parents:
diff changeset
    69
        return b ? one : zero;
06bc494ca11e Initial load
duke
parents:
diff changeset
    70
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
    71
    private static int intValue(Object x) { return ((Number)x).intValue(); }
06bc494ca11e Initial load
duke
parents:
diff changeset
    72
    private static long longValue(Object x) { return ((Number)x).longValue(); }
06bc494ca11e Initial load
duke
parents:
diff changeset
    73
    private static float floatValue(Object x) { return ((Number)x).floatValue(); }
06bc494ca11e Initial load
duke
parents:
diff changeset
    74
    private static double doubleValue(Object x) { return ((Number)x).doubleValue(); }
06bc494ca11e Initial load
duke
parents:
diff changeset
    75
06bc494ca11e Initial load
duke
parents:
diff changeset
    76
    /** Fold binary or unary operation, returning constant type reflecting the
06bc494ca11e Initial load
duke
parents:
diff changeset
    77
     *  operations result. Return null if fold failed due to an
06bc494ca11e Initial load
duke
parents:
diff changeset
    78
     *  arithmetic exception.
06bc494ca11e Initial load
duke
parents:
diff changeset
    79
     *  @param opcode    The operation's opcode instruction (usually a byte code),
06bc494ca11e Initial load
duke
parents:
diff changeset
    80
     *                   as entered by class Symtab.
06bc494ca11e Initial load
duke
parents:
diff changeset
    81
     *  @param argtypes  The operation's argument types (a list of length 1 or 2).
06bc494ca11e Initial load
duke
parents:
diff changeset
    82
     *                   Argument types are assumed to have non-null constValue's.
06bc494ca11e Initial load
duke
parents:
diff changeset
    83
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
    84
    Type fold(int opcode, List<Type> argtypes) {
06bc494ca11e Initial load
duke
parents:
diff changeset
    85
        int argCount = argtypes.length();
06bc494ca11e Initial load
duke
parents:
diff changeset
    86
        if (argCount == 1)
06bc494ca11e Initial load
duke
parents:
diff changeset
    87
            return fold1(opcode, argtypes.head);
06bc494ca11e Initial load
duke
parents:
diff changeset
    88
        else if (argCount == 2)
06bc494ca11e Initial load
duke
parents:
diff changeset
    89
            return fold2(opcode, argtypes.head, argtypes.tail.head);
06bc494ca11e Initial load
duke
parents:
diff changeset
    90
        else
06bc494ca11e Initial load
duke
parents:
diff changeset
    91
            throw new AssertionError();
06bc494ca11e Initial load
duke
parents:
diff changeset
    92
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
    93
06bc494ca11e Initial load
duke
parents:
diff changeset
    94
    /** Fold unary operation.
06bc494ca11e Initial load
duke
parents:
diff changeset
    95
     *  @param opcode    The operation's opcode instruction (usually a byte code),
06bc494ca11e Initial load
duke
parents:
diff changeset
    96
     *                   as entered by class Symtab.
06bc494ca11e Initial load
duke
parents:
diff changeset
    97
     *                   opcode's ifeq to ifge are for postprocessing
06bc494ca11e Initial load
duke
parents:
diff changeset
    98
     *                   xcmp; ifxx pairs of instructions.
06bc494ca11e Initial load
duke
parents:
diff changeset
    99
     *  @param operand   The operation's operand type.
06bc494ca11e Initial load
duke
parents:
diff changeset
   100
     *                   Argument types are assumed to have non-null constValue's.
06bc494ca11e Initial load
duke
parents:
diff changeset
   101
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   102
    Type fold1(int opcode, Type operand) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   103
        try {
06bc494ca11e Initial load
duke
parents:
diff changeset
   104
            Object od = operand.constValue();
06bc494ca11e Initial load
duke
parents:
diff changeset
   105
            switch (opcode) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   106
            case nop:
06bc494ca11e Initial load
duke
parents:
diff changeset
   107
                return operand;
06bc494ca11e Initial load
duke
parents:
diff changeset
   108
            case ineg: // unary -
06bc494ca11e Initial load
duke
parents:
diff changeset
   109
                return syms.intType.constType(-intValue(od));
06bc494ca11e Initial load
duke
parents:
diff changeset
   110
            case ixor: // ~
06bc494ca11e Initial load
duke
parents:
diff changeset
   111
                return syms.intType.constType(~intValue(od));
06bc494ca11e Initial load
duke
parents:
diff changeset
   112
            case bool_not: // !
06bc494ca11e Initial load
duke
parents:
diff changeset
   113
                return syms.booleanType.constType(b2i(intValue(od) == 0));
06bc494ca11e Initial load
duke
parents:
diff changeset
   114
            case ifeq:
06bc494ca11e Initial load
duke
parents:
diff changeset
   115
                return syms.booleanType.constType(b2i(intValue(od) == 0));
06bc494ca11e Initial load
duke
parents:
diff changeset
   116
            case ifne:
06bc494ca11e Initial load
duke
parents:
diff changeset
   117
                return syms.booleanType.constType(b2i(intValue(od) != 0));
06bc494ca11e Initial load
duke
parents:
diff changeset
   118
            case iflt:
06bc494ca11e Initial load
duke
parents:
diff changeset
   119
                return syms.booleanType.constType(b2i(intValue(od) < 0));
06bc494ca11e Initial load
duke
parents:
diff changeset
   120
            case ifgt:
06bc494ca11e Initial load
duke
parents:
diff changeset
   121
                return syms.booleanType.constType(b2i(intValue(od) > 0));
06bc494ca11e Initial load
duke
parents:
diff changeset
   122
            case ifle:
06bc494ca11e Initial load
duke
parents:
diff changeset
   123
                return syms.booleanType.constType(b2i(intValue(od) <= 0));
06bc494ca11e Initial load
duke
parents:
diff changeset
   124
            case ifge:
06bc494ca11e Initial load
duke
parents:
diff changeset
   125
                return syms.booleanType.constType(b2i(intValue(od) >= 0));
06bc494ca11e Initial load
duke
parents:
diff changeset
   126
06bc494ca11e Initial load
duke
parents:
diff changeset
   127
            case lneg: // unary -
06bc494ca11e Initial load
duke
parents:
diff changeset
   128
                return syms.longType.constType(new Long(-longValue(od)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   129
            case lxor: // ~
06bc494ca11e Initial load
duke
parents:
diff changeset
   130
                return syms.longType.constType(new Long(~longValue(od)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   131
06bc494ca11e Initial load
duke
parents:
diff changeset
   132
            case fneg: // unary -
06bc494ca11e Initial load
duke
parents:
diff changeset
   133
                return syms.floatType.constType(new Float(-floatValue(od)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   134
06bc494ca11e Initial load
duke
parents:
diff changeset
   135
            case dneg: // ~
06bc494ca11e Initial load
duke
parents:
diff changeset
   136
                return syms.doubleType.constType(new Double(-doubleValue(od)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   137
06bc494ca11e Initial load
duke
parents:
diff changeset
   138
            default:
06bc494ca11e Initial load
duke
parents:
diff changeset
   139
                return null;
06bc494ca11e Initial load
duke
parents:
diff changeset
   140
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   141
        } catch (ArithmeticException e) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   142
            return null;
06bc494ca11e Initial load
duke
parents:
diff changeset
   143
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   144
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   145
06bc494ca11e Initial load
duke
parents:
diff changeset
   146
    /** Fold binary operation.
06bc494ca11e Initial load
duke
parents:
diff changeset
   147
     *  @param opcode    The operation's opcode instruction (usually a byte code),
06bc494ca11e Initial load
duke
parents:
diff changeset
   148
     *                   as entered by class Symtab.
06bc494ca11e Initial load
duke
parents:
diff changeset
   149
     *                   opcode's ifeq to ifge are for postprocessing
06bc494ca11e Initial load
duke
parents:
diff changeset
   150
     *                   xcmp; ifxx pairs of instructions.
06bc494ca11e Initial load
duke
parents:
diff changeset
   151
     *  @param left      The type of the operation's left operand.
06bc494ca11e Initial load
duke
parents:
diff changeset
   152
     *  @param right     The type of the operation's right operand.
06bc494ca11e Initial load
duke
parents:
diff changeset
   153
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   154
    Type fold2(int opcode, Type left, Type right) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   155
        try {
06bc494ca11e Initial load
duke
parents:
diff changeset
   156
            if (opcode > ByteCodes.preMask) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   157
                // we are seeing a composite instruction of the form xcmp; ifxx.
06bc494ca11e Initial load
duke
parents:
diff changeset
   158
                // In this case fold both instructions separately.
06bc494ca11e Initial load
duke
parents:
diff changeset
   159
                Type t1 = fold2(opcode >> ByteCodes.preShift, left, right);
06bc494ca11e Initial load
duke
parents:
diff changeset
   160
                return (t1.constValue() == null) ? t1
06bc494ca11e Initial load
duke
parents:
diff changeset
   161
                    : fold1(opcode & ByteCodes.preMask, t1);
06bc494ca11e Initial load
duke
parents:
diff changeset
   162
            } else {
06bc494ca11e Initial load
duke
parents:
diff changeset
   163
                Object l = left.constValue();
06bc494ca11e Initial load
duke
parents:
diff changeset
   164
                Object r = right.constValue();
06bc494ca11e Initial load
duke
parents:
diff changeset
   165
                switch (opcode) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   166
                case iadd:
06bc494ca11e Initial load
duke
parents:
diff changeset
   167
                    return syms.intType.constType(intValue(l) + intValue(r));
06bc494ca11e Initial load
duke
parents:
diff changeset
   168
                case isub:
06bc494ca11e Initial load
duke
parents:
diff changeset
   169
                    return syms.intType.constType(intValue(l) - intValue(r));
06bc494ca11e Initial load
duke
parents:
diff changeset
   170
                case imul:
06bc494ca11e Initial load
duke
parents:
diff changeset
   171
                    return syms.intType.constType(intValue(l) * intValue(r));
06bc494ca11e Initial load
duke
parents:
diff changeset
   172
                case idiv:
06bc494ca11e Initial load
duke
parents:
diff changeset
   173
                    return syms.intType.constType(intValue(l) / intValue(r));
06bc494ca11e Initial load
duke
parents:
diff changeset
   174
                case imod:
06bc494ca11e Initial load
duke
parents:
diff changeset
   175
                    return syms.intType.constType(intValue(l) % intValue(r));
06bc494ca11e Initial load
duke
parents:
diff changeset
   176
                case iand:
14359
d4099818ab70 7200915: convert TypeTags from a series of small ints to an enum
jjg
parents: 5847
diff changeset
   177
                    return (left.hasTag(BOOLEAN)
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   178
                      ? syms.booleanType : syms.intType)
06bc494ca11e Initial load
duke
parents:
diff changeset
   179
                      .constType(intValue(l) & intValue(r));
06bc494ca11e Initial load
duke
parents:
diff changeset
   180
                case bool_and:
06bc494ca11e Initial load
duke
parents:
diff changeset
   181
                    return syms.booleanType.constType(b2i((intValue(l) & intValue(r)) != 0));
06bc494ca11e Initial load
duke
parents:
diff changeset
   182
                case ior:
14359
d4099818ab70 7200915: convert TypeTags from a series of small ints to an enum
jjg
parents: 5847
diff changeset
   183
                    return (left.hasTag(BOOLEAN)
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   184
                      ? syms.booleanType : syms.intType)
06bc494ca11e Initial load
duke
parents:
diff changeset
   185
                      .constType(intValue(l) | intValue(r));
06bc494ca11e Initial load
duke
parents:
diff changeset
   186
                case bool_or:
06bc494ca11e Initial load
duke
parents:
diff changeset
   187
                    return syms.booleanType.constType(b2i((intValue(l) | intValue(r)) != 0));
06bc494ca11e Initial load
duke
parents:
diff changeset
   188
                case ixor:
14359
d4099818ab70 7200915: convert TypeTags from a series of small ints to an enum
jjg
parents: 5847
diff changeset
   189
                    return (left.hasTag(BOOLEAN)
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   190
                      ? syms.booleanType : syms.intType)
06bc494ca11e Initial load
duke
parents:
diff changeset
   191
                      .constType(intValue(l) ^ intValue(r));
06bc494ca11e Initial load
duke
parents:
diff changeset
   192
                case ishl: case ishll:
06bc494ca11e Initial load
duke
parents:
diff changeset
   193
                    return syms.intType.constType(intValue(l) << intValue(r));
06bc494ca11e Initial load
duke
parents:
diff changeset
   194
                case ishr: case ishrl:
06bc494ca11e Initial load
duke
parents:
diff changeset
   195
                    return syms.intType.constType(intValue(l) >> intValue(r));
06bc494ca11e Initial load
duke
parents:
diff changeset
   196
                case iushr: case iushrl:
06bc494ca11e Initial load
duke
parents:
diff changeset
   197
                    return syms.intType.constType(intValue(l) >>> intValue(r));
06bc494ca11e Initial load
duke
parents:
diff changeset
   198
                case if_icmpeq:
06bc494ca11e Initial load
duke
parents:
diff changeset
   199
                    return syms.booleanType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   200
                        b2i(intValue(l) == intValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   201
                case if_icmpne:
06bc494ca11e Initial load
duke
parents:
diff changeset
   202
                    return syms.booleanType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   203
                        b2i(intValue(l) != intValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   204
                case if_icmplt:
06bc494ca11e Initial load
duke
parents:
diff changeset
   205
                    return syms.booleanType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   206
                        b2i(intValue(l) < intValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   207
                case if_icmpgt:
06bc494ca11e Initial load
duke
parents:
diff changeset
   208
                    return syms.booleanType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   209
                        b2i(intValue(l) > intValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   210
                case if_icmple:
06bc494ca11e Initial load
duke
parents:
diff changeset
   211
                    return syms.booleanType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   212
                        b2i(intValue(l) <= intValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   213
                case if_icmpge:
06bc494ca11e Initial load
duke
parents:
diff changeset
   214
                    return syms.booleanType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   215
                        b2i(intValue(l) >= intValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   216
06bc494ca11e Initial load
duke
parents:
diff changeset
   217
                case ladd:
06bc494ca11e Initial load
duke
parents:
diff changeset
   218
                    return syms.longType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   219
                        new Long(longValue(l) + longValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   220
                case lsub:
06bc494ca11e Initial load
duke
parents:
diff changeset
   221
                    return syms.longType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   222
                        new Long(longValue(l) - longValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   223
                case lmul:
06bc494ca11e Initial load
duke
parents:
diff changeset
   224
                    return syms.longType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   225
                        new Long(longValue(l) * longValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   226
                case ldiv:
06bc494ca11e Initial load
duke
parents:
diff changeset
   227
                    return syms.longType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   228
                        new Long(longValue(l) / longValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   229
                case lmod:
06bc494ca11e Initial load
duke
parents:
diff changeset
   230
                    return syms.longType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   231
                        new Long(longValue(l) % longValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   232
                case land:
06bc494ca11e Initial load
duke
parents:
diff changeset
   233
                    return syms.longType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   234
                        new Long(longValue(l) & longValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   235
                case lor:
06bc494ca11e Initial load
duke
parents:
diff changeset
   236
                    return syms.longType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   237
                        new Long(longValue(l) | longValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   238
                case lxor:
06bc494ca11e Initial load
duke
parents:
diff changeset
   239
                    return syms.longType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   240
                        new Long(longValue(l) ^ longValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   241
                case lshl: case lshll:
06bc494ca11e Initial load
duke
parents:
diff changeset
   242
                    return syms.longType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   243
                        new Long(longValue(l) << intValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   244
                case lshr: case lshrl:
06bc494ca11e Initial load
duke
parents:
diff changeset
   245
                    return syms.longType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   246
                        new Long(longValue(l) >> intValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   247
                case lushr:
06bc494ca11e Initial load
duke
parents:
diff changeset
   248
                    return syms.longType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   249
                        new Long(longValue(l) >>> intValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   250
                case lcmp:
06bc494ca11e Initial load
duke
parents:
diff changeset
   251
                    if (longValue(l) < longValue(r))
06bc494ca11e Initial load
duke
parents:
diff changeset
   252
                        return syms.intType.constType(minusOne);
06bc494ca11e Initial load
duke
parents:
diff changeset
   253
                    else if (longValue(l) > longValue(r))
06bc494ca11e Initial load
duke
parents:
diff changeset
   254
                        return syms.intType.constType(one);
06bc494ca11e Initial load
duke
parents:
diff changeset
   255
                    else
06bc494ca11e Initial load
duke
parents:
diff changeset
   256
                        return syms.intType.constType(zero);
06bc494ca11e Initial load
duke
parents:
diff changeset
   257
                case fadd:
06bc494ca11e Initial load
duke
parents:
diff changeset
   258
                    return syms.floatType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   259
                        new Float(floatValue(l) + floatValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   260
                case fsub:
06bc494ca11e Initial load
duke
parents:
diff changeset
   261
                    return syms.floatType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   262
                        new Float(floatValue(l) - floatValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   263
                case fmul:
06bc494ca11e Initial load
duke
parents:
diff changeset
   264
                    return syms.floatType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   265
                        new Float(floatValue(l) * floatValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   266
                case fdiv:
06bc494ca11e Initial load
duke
parents:
diff changeset
   267
                    return syms.floatType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   268
                        new Float(floatValue(l) / floatValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   269
                case fmod:
06bc494ca11e Initial load
duke
parents:
diff changeset
   270
                    return syms.floatType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   271
                        new Float(floatValue(l) % floatValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   272
                case fcmpg: case fcmpl:
06bc494ca11e Initial load
duke
parents:
diff changeset
   273
                    if (floatValue(l) < floatValue(r))
06bc494ca11e Initial load
duke
parents:
diff changeset
   274
                        return syms.intType.constType(minusOne);
06bc494ca11e Initial load
duke
parents:
diff changeset
   275
                    else if (floatValue(l) > floatValue(r))
06bc494ca11e Initial load
duke
parents:
diff changeset
   276
                        return syms.intType.constType(one);
06bc494ca11e Initial load
duke
parents:
diff changeset
   277
                    else if (floatValue(l) == floatValue(r))
06bc494ca11e Initial load
duke
parents:
diff changeset
   278
                        return syms.intType.constType(zero);
06bc494ca11e Initial load
duke
parents:
diff changeset
   279
                    else if (opcode == fcmpg)
06bc494ca11e Initial load
duke
parents:
diff changeset
   280
                        return syms.intType.constType(one);
06bc494ca11e Initial load
duke
parents:
diff changeset
   281
                    else
06bc494ca11e Initial load
duke
parents:
diff changeset
   282
                        return syms.intType.constType(minusOne);
06bc494ca11e Initial load
duke
parents:
diff changeset
   283
                case dadd:
06bc494ca11e Initial load
duke
parents:
diff changeset
   284
                    return syms.doubleType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   285
                        new Double(doubleValue(l) + doubleValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   286
                case dsub:
06bc494ca11e Initial load
duke
parents:
diff changeset
   287
                    return syms.doubleType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   288
                        new Double(doubleValue(l) - doubleValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   289
                case dmul:
06bc494ca11e Initial load
duke
parents:
diff changeset
   290
                    return syms.doubleType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   291
                        new Double(doubleValue(l) * doubleValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   292
                case ddiv:
06bc494ca11e Initial load
duke
parents:
diff changeset
   293
                    return syms.doubleType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   294
                        new Double(doubleValue(l) / doubleValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   295
                case dmod:
06bc494ca11e Initial load
duke
parents:
diff changeset
   296
                    return syms.doubleType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   297
                        new Double(doubleValue(l) % doubleValue(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   298
                case dcmpg: case dcmpl:
06bc494ca11e Initial load
duke
parents:
diff changeset
   299
                    if (doubleValue(l) < doubleValue(r))
06bc494ca11e Initial load
duke
parents:
diff changeset
   300
                        return syms.intType.constType(minusOne);
06bc494ca11e Initial load
duke
parents:
diff changeset
   301
                    else if (doubleValue(l) > doubleValue(r))
06bc494ca11e Initial load
duke
parents:
diff changeset
   302
                        return syms.intType.constType(one);
06bc494ca11e Initial load
duke
parents:
diff changeset
   303
                    else if (doubleValue(l) == doubleValue(r))
06bc494ca11e Initial load
duke
parents:
diff changeset
   304
                        return syms.intType.constType(zero);
06bc494ca11e Initial load
duke
parents:
diff changeset
   305
                    else if (opcode == dcmpg)
06bc494ca11e Initial load
duke
parents:
diff changeset
   306
                        return syms.intType.constType(one);
06bc494ca11e Initial load
duke
parents:
diff changeset
   307
                    else
06bc494ca11e Initial load
duke
parents:
diff changeset
   308
                        return syms.intType.constType(minusOne);
06bc494ca11e Initial load
duke
parents:
diff changeset
   309
                case if_acmpeq:
06bc494ca11e Initial load
duke
parents:
diff changeset
   310
                    return syms.booleanType.constType(b2i(l.equals(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   311
                case if_acmpne:
06bc494ca11e Initial load
duke
parents:
diff changeset
   312
                    return syms.booleanType.constType(b2i(!l.equals(r)));
06bc494ca11e Initial load
duke
parents:
diff changeset
   313
                case string_add:
06bc494ca11e Initial load
duke
parents:
diff changeset
   314
                    return syms.stringType.constType(
06bc494ca11e Initial load
duke
parents:
diff changeset
   315
                        left.stringValue() + right.stringValue());
06bc494ca11e Initial load
duke
parents:
diff changeset
   316
                default:
06bc494ca11e Initial load
duke
parents:
diff changeset
   317
                    return null;
06bc494ca11e Initial load
duke
parents:
diff changeset
   318
                }
06bc494ca11e Initial load
duke
parents:
diff changeset
   319
            }
06bc494ca11e Initial load
duke
parents:
diff changeset
   320
        } catch (ArithmeticException e) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   321
            return null;
06bc494ca11e Initial load
duke
parents:
diff changeset
   322
        }
06bc494ca11e Initial load
duke
parents:
diff changeset
   323
    }
06bc494ca11e Initial load
duke
parents:
diff changeset
   324
06bc494ca11e Initial load
duke
parents:
diff changeset
   325
    /** Coerce constant type to target type.
06bc494ca11e Initial load
duke
parents:
diff changeset
   326
     *  @param etype      The source type of the coercion,
14359
d4099818ab70 7200915: convert TypeTags from a series of small ints to an enum
jjg
parents: 5847
diff changeset
   327
     *                    which is assumed to be a constant type compatible with
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   328
     *                    ttype.
06bc494ca11e Initial load
duke
parents:
diff changeset
   329
     *  @param ttype      The target type of the coercion.
06bc494ca11e Initial load
duke
parents:
diff changeset
   330
     */
06bc494ca11e Initial load
duke
parents:
diff changeset
   331
     Type coerce(Type etype, Type ttype) {
06bc494ca11e Initial load
duke
parents:
diff changeset
   332
         // WAS if (etype.baseType() == ttype.baseType())
06bc494ca11e Initial load
duke
parents:
diff changeset
   333
         if (etype.tsym.type == ttype.tsym.type)
06bc494ca11e Initial load
duke
parents:
diff changeset
   334
             return etype;
14359
d4099818ab70 7200915: convert TypeTags from a series of small ints to an enum
jjg
parents: 5847
diff changeset
   335
         if (etype.isNumeric()) {
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   336
             Object n = etype.constValue();
14359
d4099818ab70 7200915: convert TypeTags from a series of small ints to an enum
jjg
parents: 5847
diff changeset
   337
             switch (ttype.getTag()) {
10
06bc494ca11e Initial load
duke
parents:
diff changeset
   338
             case BYTE:
06bc494ca11e Initial load
duke
parents:
diff changeset
   339
                 return syms.byteType.constType(0 + (byte)intValue(n));
06bc494ca11e Initial load
duke
parents:
diff changeset
   340
             case CHAR:
06bc494ca11e Initial load
duke
parents:
diff changeset
   341
                 return syms.charType.constType(0 + (char)intValue(n));
06bc494ca11e Initial load
duke
parents:
diff changeset
   342
             case SHORT:
06bc494ca11e Initial load
duke
parents:
diff changeset
   343
                 return syms.shortType.constType(0 + (short)intValue(n));
06bc494ca11e Initial load
duke
parents:
diff changeset
   344
             case INT:
06bc494ca11e Initial load
duke
parents:
diff changeset
   345
                 return syms.intType.constType(intValue(n));
06bc494ca11e Initial load
duke
parents:
diff changeset
   346
             case LONG:
06bc494ca11e Initial load
duke
parents:
diff changeset
   347
                 return syms.longType.constType(longValue(n));
06bc494ca11e Initial load
duke
parents:
diff changeset
   348
             case FLOAT:
06bc494ca11e Initial load
duke
parents:
diff changeset
   349
                 return syms.floatType.constType(floatValue(n));
06bc494ca11e Initial load
duke
parents:
diff changeset
   350
             case DOUBLE:
06bc494ca11e Initial load
duke
parents:
diff changeset
   351
                 return syms.doubleType.constType(doubleValue(n));
06bc494ca11e Initial load
duke
parents:
diff changeset
   352
             }
06bc494ca11e Initial load
duke
parents:
diff changeset
   353
         }
06bc494ca11e Initial load
duke
parents:
diff changeset
   354
         return ttype;
06bc494ca11e Initial load
duke
parents:
diff changeset
   355
     }
06bc494ca11e Initial load
duke
parents:
diff changeset
   356
}