/*
 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.sun.tools.javac.comp;

import com.sun.tools.javac.code.*;
import com.sun.tools.javac.jvm.*;
import com.sun.tools.javac.util.*;

import static com.sun.tools.javac.code.TypeTag.BOOLEAN;

import static com.sun.tools.javac.jvm.ByteCodes.*;

/** Helper class for constant folding, used by the attribution phase.
 *  This class is marked strictfp as mandated by JLS 15.4.
 *
 *  <p><b>This is NOT part of any supported API.
 *  If you write code that depends on this, you do so at your own risk.
 *  This code and its internal interfaces are subject to change or
 *  deletion without notice.</b>
 */
strictfp class ConstFold {
    protected static final Context.Key<ConstFold> constFoldKey =
        new Context.Key<ConstFold>();

    private Symtab syms;

    public static ConstFold instance(Context context) {
        ConstFold instance = context.get(constFoldKey);
        if (instance == null)
            instance = new ConstFold(context);
        return instance;
    }

    private ConstFold(Context context) {
        context.put(constFoldKey, this);

        syms = Symtab.instance(context);
    }

    static final Integer minusOne = -1;
    static final Integer zero     = 0;
    static final Integer one      = 1;

   /** Convert boolean to integer (true = 1, false = 0).
    */
    private static Integer b2i(boolean b) {
        return b ? one : zero;
    }
    private static int intValue(Object x) { return ((Number)x).intValue(); }
    private static long longValue(Object x) { return ((Number)x).longValue(); }
    private static float floatValue(Object x) { return ((Number)x).floatValue(); }
    private static double doubleValue(Object x) { return ((Number)x).doubleValue(); }

    /** Fold binary or unary operation, returning constant type reflecting the
     *  operations result. Return null if fold failed due to an
     *  arithmetic exception.
     *  @param opcode    The operation's opcode instruction (usually a byte code),
     *                   as entered by class Symtab.
     *  @param argtypes  The operation's argument types (a list of length 1 or 2).
     *                   Argument types are assumed to have non-null constValue's.
     */
    Type fold(int opcode, List<Type> argtypes) {
        int argCount = argtypes.length();
        if (argCount == 1)
            return fold1(opcode, argtypes.head);
        else if (argCount == 2)
            return fold2(opcode, argtypes.head, argtypes.tail.head);
        else
            throw new AssertionError();
    }

    /** Fold unary operation.
     *  @param opcode    The operation's opcode instruction (usually a byte code),
     *                   as entered by class Symtab.
     *                   opcode's ifeq to ifge are for postprocessing
     *                   xcmp; ifxx pairs of instructions.
     *  @param operand   The operation's operand type.
     *                   Argument types are assumed to have non-null constValue's.
     */
    Type fold1(int opcode, Type operand) {
        try {
            Object od = operand.constValue();
            switch (opcode) {
            case nop:
                return operand;
            case ineg: // unary -
                return syms.intType.constType(-intValue(od));
            case ixor: // ~
                return syms.intType.constType(~intValue(od));
            case bool_not: // !
                return syms.booleanType.constType(b2i(intValue(od) == 0));
            case ifeq:
                return syms.booleanType.constType(b2i(intValue(od) == 0));
            case ifne:
                return syms.booleanType.constType(b2i(intValue(od) != 0));
            case iflt:
                return syms.booleanType.constType(b2i(intValue(od) < 0));
            case ifgt:
                return syms.booleanType.constType(b2i(intValue(od) > 0));
            case ifle:
                return syms.booleanType.constType(b2i(intValue(od) <= 0));
            case ifge:
                return syms.booleanType.constType(b2i(intValue(od) >= 0));

            case lneg: // unary -
                return syms.longType.constType(new Long(-longValue(od)));
            case lxor: // ~
                return syms.longType.constType(new Long(~longValue(od)));

            case fneg: // unary -
                return syms.floatType.constType(new Float(-floatValue(od)));

            case dneg: // ~
                return syms.doubleType.constType(new Double(-doubleValue(od)));

            default:
                return null;
            }
        } catch (ArithmeticException e) {
            return null;
        }
    }

    /** Fold binary operation.
     *  @param opcode    The operation's opcode instruction (usually a byte code),
     *                   as entered by class Symtab.
     *                   opcode's ifeq to ifge are for postprocessing
     *                   xcmp; ifxx pairs of instructions.
     *  @param left      The type of the operation's left operand.
     *  @param right     The type of the operation's right operand.
     */
    Type fold2(int opcode, Type left, Type right) {
        try {
            if (opcode > ByteCodes.preMask) {
                // we are seeing a composite instruction of the form xcmp; ifxx.
                // In this case fold both instructions separately.
                Type t1 = fold2(opcode >> ByteCodes.preShift, left, right);
                return (t1.constValue() == null) ? t1
                    : fold1(opcode & ByteCodes.preMask, t1);
            } else {
                Object l = left.constValue();
                Object r = right.constValue();
                switch (opcode) {
                case iadd:
                    return syms.intType.constType(intValue(l) + intValue(r));
                case isub:
                    return syms.intType.constType(intValue(l) - intValue(r));
                case imul:
                    return syms.intType.constType(intValue(l) * intValue(r));
                case idiv:
                    return syms.intType.constType(intValue(l) / intValue(r));
                case imod:
                    return syms.intType.constType(intValue(l) % intValue(r));
                case iand:
                    return (left.hasTag(BOOLEAN)
                      ? syms.booleanType : syms.intType)
                      .constType(intValue(l) & intValue(r));
                case bool_and:
                    return syms.booleanType.constType(b2i((intValue(l) & intValue(r)) != 0));
                case ior:
                    return (left.hasTag(BOOLEAN)
                      ? syms.booleanType : syms.intType)
                      .constType(intValue(l) | intValue(r));
                case bool_or:
                    return syms.booleanType.constType(b2i((intValue(l) | intValue(r)) != 0));
                case ixor:
                    return (left.hasTag(BOOLEAN)
                      ? syms.booleanType : syms.intType)
                      .constType(intValue(l) ^ intValue(r));
                case ishl: case ishll:
                    return syms.intType.constType(intValue(l) << intValue(r));
                case ishr: case ishrl:
                    return syms.intType.constType(intValue(l) >> intValue(r));
                case iushr: case iushrl:
                    return syms.intType.constType(intValue(l) >>> intValue(r));
                case if_icmpeq:
                    return syms.booleanType.constType(
                        b2i(intValue(l) == intValue(r)));
                case if_icmpne:
                    return syms.booleanType.constType(
                        b2i(intValue(l) != intValue(r)));
                case if_icmplt:
                    return syms.booleanType.constType(
                        b2i(intValue(l) < intValue(r)));
                case if_icmpgt:
                    return syms.booleanType.constType(
                        b2i(intValue(l) > intValue(r)));
                case if_icmple:
                    return syms.booleanType.constType(
                        b2i(intValue(l) <= intValue(r)));
                case if_icmpge:
                    return syms.booleanType.constType(
                        b2i(intValue(l) >= intValue(r)));

                case ladd:
                    return syms.longType.constType(
                        new Long(longValue(l) + longValue(r)));
                case lsub:
                    return syms.longType.constType(
                        new Long(longValue(l) - longValue(r)));
                case lmul:
                    return syms.longType.constType(
                        new Long(longValue(l) * longValue(r)));
                case ldiv:
                    return syms.longType.constType(
                        new Long(longValue(l) / longValue(r)));
                case lmod:
                    return syms.longType.constType(
                        new Long(longValue(l) % longValue(r)));
                case land:
                    return syms.longType.constType(
                        new Long(longValue(l) & longValue(r)));
                case lor:
                    return syms.longType.constType(
                        new Long(longValue(l) | longValue(r)));
                case lxor:
                    return syms.longType.constType(
                        new Long(longValue(l) ^ longValue(r)));
                case lshl: case lshll:
                    return syms.longType.constType(
                        new Long(longValue(l) << intValue(r)));
                case lshr: case lshrl:
                    return syms.longType.constType(
                        new Long(longValue(l) >> intValue(r)));
                case lushr:
                    return syms.longType.constType(
                        new Long(longValue(l) >>> intValue(r)));
                case lcmp:
                    if (longValue(l) < longValue(r))
                        return syms.intType.constType(minusOne);
                    else if (longValue(l) > longValue(r))
                        return syms.intType.constType(one);
                    else
                        return syms.intType.constType(zero);
                case fadd:
                    return syms.floatType.constType(
                        new Float(floatValue(l) + floatValue(r)));
                case fsub:
                    return syms.floatType.constType(
                        new Float(floatValue(l) - floatValue(r)));
                case fmul:
                    return syms.floatType.constType(
                        new Float(floatValue(l) * floatValue(r)));
                case fdiv:
                    return syms.floatType.constType(
                        new Float(floatValue(l) / floatValue(r)));
                case fmod:
                    return syms.floatType.constType(
                        new Float(floatValue(l) % floatValue(r)));
                case fcmpg: case fcmpl:
                    if (floatValue(l) < floatValue(r))
                        return syms.intType.constType(minusOne);
                    else if (floatValue(l) > floatValue(r))
                        return syms.intType.constType(one);
                    else if (floatValue(l) == floatValue(r))
                        return syms.intType.constType(zero);
                    else if (opcode == fcmpg)
                        return syms.intType.constType(one);
                    else
                        return syms.intType.constType(minusOne);
                case dadd:
                    return syms.doubleType.constType(
                        new Double(doubleValue(l) + doubleValue(r)));
                case dsub:
                    return syms.doubleType.constType(
                        new Double(doubleValue(l) - doubleValue(r)));
                case dmul:
                    return syms.doubleType.constType(
                        new Double(doubleValue(l) * doubleValue(r)));
                case ddiv:
                    return syms.doubleType.constType(
                        new Double(doubleValue(l) / doubleValue(r)));
                case dmod:
                    return syms.doubleType.constType(
                        new Double(doubleValue(l) % doubleValue(r)));
                case dcmpg: case dcmpl:
                    if (doubleValue(l) < doubleValue(r))
                        return syms.intType.constType(minusOne);
                    else if (doubleValue(l) > doubleValue(r))
                        return syms.intType.constType(one);
                    else if (doubleValue(l) == doubleValue(r))
                        return syms.intType.constType(zero);
                    else if (opcode == dcmpg)
                        return syms.intType.constType(one);
                    else
                        return syms.intType.constType(minusOne);
                case if_acmpeq:
                    return syms.booleanType.constType(b2i(l.equals(r)));
                case if_acmpne:
                    return syms.booleanType.constType(b2i(!l.equals(r)));
                case string_add:
                    return syms.stringType.constType(
                        left.stringValue() + right.stringValue());
                default:
                    return null;
                }
            }
        } catch (ArithmeticException e) {
            return null;
        }
    }

    /** Coerce constant type to target type.
     *  @param etype      The source type of the coercion,
     *                    which is assumed to be a constant type compatible with
     *                    ttype.
     *  @param ttype      The target type of the coercion.
     */
     Type coerce(Type etype, Type ttype) {
         // WAS if (etype.baseType() == ttype.baseType())
         if (etype.tsym.type == ttype.tsym.type)
             return etype;
         if (etype.isNumeric()) {
             Object n = etype.constValue();
             switch (ttype.getTag()) {
             case BYTE:
                 return syms.byteType.constType(0 + (byte)intValue(n));
             case CHAR:
                 return syms.charType.constType(0 + (char)intValue(n));
             case SHORT:
                 return syms.shortType.constType(0 + (short)intValue(n));
             case INT:
                 return syms.intType.constType(intValue(n));
             case LONG:
                 return syms.longType.constType(longValue(n));
             case FLOAT:
                 return syms.floatType.constType(floatValue(n));
             case DOUBLE:
                 return syms.doubleType.constType(doubleValue(n));
             }
         }
         return ttype;
     }
}
