/*
 * Copyright (c) 2001, 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 sun.reflect;

import java.lang.reflect.*;
import sun.misc.Unsafe;

/** Shared functionality for all accessor generators */

class AccessorGenerator implements ClassFileConstants {
    static final Unsafe unsafe = Unsafe.getUnsafe();

    // Constants because there's no way to say "short integer constant",
    // i.e., "1S"
    protected static final short S0 = (short) 0;
    protected static final short S1 = (short) 1;
    protected static final short S2 = (short) 2;
    protected static final short S3 = (short) 3;
    protected static final short S4 = (short) 4;
    protected static final short S5 = (short) 5;
    protected static final short S6 = (short) 6;

    // Instance variables for shared functionality between
    // FieldAccessorGenerator and MethodAccessorGenerator
    protected ClassFileAssembler asm;
    protected int   modifiers;
    protected short thisClass;
    protected short superClass;
    protected short targetClass;
    // Common constant pool entries to FieldAccessor and MethodAccessor
    protected short throwableClass;
    protected short classCastClass;
    protected short nullPointerClass;
    protected short illegalArgumentClass;
    protected short invocationTargetClass;
    protected short initIdx;
    protected short initNameAndTypeIdx;
    protected short initStringNameAndTypeIdx;
    protected short nullPointerCtorIdx;
    protected short illegalArgumentCtorIdx;
    protected short illegalArgumentStringCtorIdx;
    protected short invocationTargetCtorIdx;
    protected short superCtorIdx;
    protected short objectClass;
    protected short toStringIdx;
    protected short codeIdx;
    protected short exceptionsIdx;
    // Boxing
    protected short booleanIdx;
    protected short booleanCtorIdx;
    protected short booleanUnboxIdx;
    protected short byteIdx;
    protected short byteCtorIdx;
    protected short byteUnboxIdx;
    protected short characterIdx;
    protected short characterCtorIdx;
    protected short characterUnboxIdx;
    protected short doubleIdx;
    protected short doubleCtorIdx;
    protected short doubleUnboxIdx;
    protected short floatIdx;
    protected short floatCtorIdx;
    protected short floatUnboxIdx;
    protected short integerIdx;
    protected short integerCtorIdx;
    protected short integerUnboxIdx;
    protected short longIdx;
    protected short longCtorIdx;
    protected short longUnboxIdx;
    protected short shortIdx;
    protected short shortCtorIdx;
    protected short shortUnboxIdx;

    protected final short NUM_COMMON_CPOOL_ENTRIES = (short) 30;
    protected final short NUM_BOXING_CPOOL_ENTRIES = (short) 72;

    // Requires that superClass has been set up
    protected void emitCommonConstantPoolEntries() {
        // +   [UTF-8] "java/lang/Throwable"
        // +   [CONSTANT_Class_info] for above
        // +   [UTF-8] "java/lang/ClassCastException"
        // +   [CONSTANT_Class_info] for above
        // +   [UTF-8] "java/lang/NullPointerException"
        // +   [CONSTANT_Class_info] for above
        // +   [UTF-8] "java/lang/IllegalArgumentException"
        // +   [CONSTANT_Class_info] for above
        // +   [UTF-8] "java/lang/InvocationTargetException"
        // +   [CONSTANT_Class_info] for above
        // +   [UTF-8] "<init>"
        // +   [UTF-8] "()V"
        // +   [CONSTANT_NameAndType_info] for above
        // +   [CONSTANT_Methodref_info] for NullPointerException's constructor
        // +   [CONSTANT_Methodref_info] for IllegalArgumentException's constructor
        // +   [UTF-8] "(Ljava/lang/String;)V"
        // +   [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/String;)V"
        // +   [CONSTANT_Methodref_info] for IllegalArgumentException's constructor taking a String
        // +   [UTF-8] "(Ljava/lang/Throwable;)V"
        // +   [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/Throwable;)V"
        // +   [CONSTANT_Methodref_info] for InvocationTargetException's constructor
        // +   [CONSTANT_Methodref_info] for "super()"
        // +   [UTF-8] "java/lang/Object"
        // +   [CONSTANT_Class_info] for above
        // +   [UTF-8] "toString"
        // +   [UTF-8] "()Ljava/lang/String;"
        // +   [CONSTANT_NameAndType_info] for "toString()Ljava/lang/String;"
        // +   [CONSTANT_Methodref_info] for Object's toString method
        // +   [UTF-8] "Code"
        // +   [UTF-8] "Exceptions"
        asm.emitConstantPoolUTF8("java/lang/Throwable");
        asm.emitConstantPoolClass(asm.cpi());
        throwableClass = asm.cpi();
        asm.emitConstantPoolUTF8("java/lang/ClassCastException");
        asm.emitConstantPoolClass(asm.cpi());
        classCastClass = asm.cpi();
        asm.emitConstantPoolUTF8("java/lang/NullPointerException");
        asm.emitConstantPoolClass(asm.cpi());
        nullPointerClass = asm.cpi();
        asm.emitConstantPoolUTF8("java/lang/IllegalArgumentException");
        asm.emitConstantPoolClass(asm.cpi());
        illegalArgumentClass = asm.cpi();
        asm.emitConstantPoolUTF8("java/lang/reflect/InvocationTargetException");
        asm.emitConstantPoolClass(asm.cpi());
        invocationTargetClass = asm.cpi();
        asm.emitConstantPoolUTF8("<init>");
        initIdx = asm.cpi();
        asm.emitConstantPoolUTF8("()V");
        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
        initNameAndTypeIdx = asm.cpi();
        asm.emitConstantPoolMethodref(nullPointerClass, initNameAndTypeIdx);
        nullPointerCtorIdx = asm.cpi();
        asm.emitConstantPoolMethodref(illegalArgumentClass, initNameAndTypeIdx);
        illegalArgumentCtorIdx = asm.cpi();
        asm.emitConstantPoolUTF8("(Ljava/lang/String;)V");
        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
        initStringNameAndTypeIdx = asm.cpi();
        asm.emitConstantPoolMethodref(illegalArgumentClass, initStringNameAndTypeIdx);
        illegalArgumentStringCtorIdx = asm.cpi();
        asm.emitConstantPoolUTF8("(Ljava/lang/Throwable;)V");
        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
        asm.emitConstantPoolMethodref(invocationTargetClass, asm.cpi());
        invocationTargetCtorIdx = asm.cpi();
        asm.emitConstantPoolMethodref(superClass, initNameAndTypeIdx);
        superCtorIdx = asm.cpi();
        asm.emitConstantPoolUTF8("java/lang/Object");
        asm.emitConstantPoolClass(asm.cpi());
        objectClass = asm.cpi();
        asm.emitConstantPoolUTF8("toString");
        asm.emitConstantPoolUTF8("()Ljava/lang/String;");
        asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
        asm.emitConstantPoolMethodref(objectClass, asm.cpi());
        toStringIdx = asm.cpi();
        asm.emitConstantPoolUTF8("Code");
        codeIdx = asm.cpi();
        asm.emitConstantPoolUTF8("Exceptions");
        exceptionsIdx = asm.cpi();
    }

    /** Constant pool entries required to be able to box/unbox primitive
        types. Note that we don't emit these if we don't need them. */
    protected void emitBoxingContantPoolEntries() {
        //  *  [UTF-8] "java/lang/Boolean"
        //  *  [CONSTANT_Class_info] for above
        //  *  [UTF-8] "(Z)V"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        //  *  [UTF-8] "booleanValue"
        //  *  [UTF-8] "()Z"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        //  *  [UTF-8] "java/lang/Byte"
        //  *  [CONSTANT_Class_info] for above
        //  *  [UTF-8] "(B)V"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        //  *  [UTF-8] "byteValue"
        //  *  [UTF-8] "()B"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        //  *  [UTF-8] "java/lang/Character"
        //  *  [CONSTANT_Class_info] for above
        //  *  [UTF-8] "(C)V"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        //  *  [UTF-8] "charValue"
        //  *  [UTF-8] "()C"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        //  *  [UTF-8] "java/lang/Double"
        //  *  [CONSTANT_Class_info] for above
        //  *  [UTF-8] "(D)V"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        //  *  [UTF-8] "doubleValue"
        //  *  [UTF-8] "()D"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        //  *  [UTF-8] "java/lang/Float"
        //  *  [CONSTANT_Class_info] for above
        //  *  [UTF-8] "(F)V"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        //  *  [UTF-8] "floatValue"
        //  *  [UTF-8] "()F"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        //  *  [UTF-8] "java/lang/Integer"
        //  *  [CONSTANT_Class_info] for above
        //  *  [UTF-8] "(I)V"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        //  *  [UTF-8] "intValue"
        //  *  [UTF-8] "()I"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        //  *  [UTF-8] "java/lang/Long"
        //  *  [CONSTANT_Class_info] for above
        //  *  [UTF-8] "(J)V"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        //  *  [UTF-8] "longValue"
        //  *  [UTF-8] "()J"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        //  *  [UTF-8] "java/lang/Short"
        //  *  [CONSTANT_Class_info] for above
        //  *  [UTF-8] "(S)V"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        //  *  [UTF-8] "shortValue"
        //  *  [UTF-8] "()S"
        //  *  [CONSTANT_NameAndType_info] for above
        //  *  [CONSTANT_Methodref_info] for above
        // Boolean
        asm.emitConstantPoolUTF8("java/lang/Boolean");
        asm.emitConstantPoolClass(asm.cpi());
        booleanIdx = asm.cpi();
        asm.emitConstantPoolUTF8("(Z)V");
        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
        booleanCtorIdx = asm.cpi();
        asm.emitConstantPoolUTF8("booleanValue");
        asm.emitConstantPoolUTF8("()Z");
        asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
        booleanUnboxIdx = asm.cpi();

        // Byte
        asm.emitConstantPoolUTF8("java/lang/Byte");
        asm.emitConstantPoolClass(asm.cpi());
        byteIdx = asm.cpi();
        asm.emitConstantPoolUTF8("(B)V");
        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
        byteCtorIdx = asm.cpi();
        asm.emitConstantPoolUTF8("byteValue");
        asm.emitConstantPoolUTF8("()B");
        asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
        byteUnboxIdx = asm.cpi();

        // Character
        asm.emitConstantPoolUTF8("java/lang/Character");
        asm.emitConstantPoolClass(asm.cpi());
        characterIdx = asm.cpi();
        asm.emitConstantPoolUTF8("(C)V");
        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
        characterCtorIdx = asm.cpi();
        asm.emitConstantPoolUTF8("charValue");
        asm.emitConstantPoolUTF8("()C");
        asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
        characterUnboxIdx = asm.cpi();

        // Double
        asm.emitConstantPoolUTF8("java/lang/Double");
        asm.emitConstantPoolClass(asm.cpi());
        doubleIdx = asm.cpi();
        asm.emitConstantPoolUTF8("(D)V");
        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
        doubleCtorIdx = asm.cpi();
        asm.emitConstantPoolUTF8("doubleValue");
        asm.emitConstantPoolUTF8("()D");
        asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
        doubleUnboxIdx = asm.cpi();

        // Float
        asm.emitConstantPoolUTF8("java/lang/Float");
        asm.emitConstantPoolClass(asm.cpi());
        floatIdx = asm.cpi();
        asm.emitConstantPoolUTF8("(F)V");
        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
        floatCtorIdx = asm.cpi();
        asm.emitConstantPoolUTF8("floatValue");
        asm.emitConstantPoolUTF8("()F");
        asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
        floatUnboxIdx = asm.cpi();

        // Integer
        asm.emitConstantPoolUTF8("java/lang/Integer");
        asm.emitConstantPoolClass(asm.cpi());
        integerIdx = asm.cpi();
        asm.emitConstantPoolUTF8("(I)V");
        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
        integerCtorIdx = asm.cpi();
        asm.emitConstantPoolUTF8("intValue");
        asm.emitConstantPoolUTF8("()I");
        asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
        integerUnboxIdx = asm.cpi();

        // Long
        asm.emitConstantPoolUTF8("java/lang/Long");
        asm.emitConstantPoolClass(asm.cpi());
        longIdx = asm.cpi();
        asm.emitConstantPoolUTF8("(J)V");
        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
        longCtorIdx = asm.cpi();
        asm.emitConstantPoolUTF8("longValue");
        asm.emitConstantPoolUTF8("()J");
        asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
        longUnboxIdx = asm.cpi();

        // Short
        asm.emitConstantPoolUTF8("java/lang/Short");
        asm.emitConstantPoolClass(asm.cpi());
        shortIdx = asm.cpi();
        asm.emitConstantPoolUTF8("(S)V");
        asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
        shortCtorIdx = asm.cpi();
        asm.emitConstantPoolUTF8("shortValue");
        asm.emitConstantPoolUTF8("()S");
        asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
        asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
        shortUnboxIdx = asm.cpi();
    }

    // Necessary because of Java's annoying promotion rules
    protected static short add(short s1, short s2) {
        return (short) (s1 + s2);
    }

    protected static short sub(short s1, short s2) {
        return (short) (s1 - s2);
    }

    protected boolean isStatic() {
        return Modifier.isStatic(modifiers);
    }

    /** Returns class name in "internal" form (i.e., '/' separators
        instead of '.') */
    protected static String getClassName
        (Class c, boolean addPrefixAndSuffixForNonPrimitiveTypes)
    {
        if (c.isPrimitive()) {
            if (c == Boolean.TYPE) {
                return "Z";
            } else if (c == Byte.TYPE) {
                return "B";
            } else if (c == Character.TYPE) {
                return "C";
            } else if (c == Double.TYPE) {
                return "D";
            } else if (c == Float.TYPE) {
                return "F";
            } else if (c == Integer.TYPE) {
                return "I";
            } else if (c == Long.TYPE) {
                return "J";
            } else if (c == Short.TYPE) {
                return "S";
            } else if (c == Void.TYPE) {
                return "V";
            }
            throw new InternalError("Should have found primitive type");
        } else if (c.isArray()) {
            return "[" + getClassName(c.getComponentType(), true);
        } else {
            if (addPrefixAndSuffixForNonPrimitiveTypes) {
                return internalize("L" + c.getName() + ";");
            } else {
                return internalize(c.getName());
            }
        }
    }

    private static String internalize(String className) {
        return className.replace('.', '/');
    }

    protected void emitConstructor() {
        // Generate code into fresh code buffer
        ClassFileAssembler cb = new ClassFileAssembler();
        // 0 incoming arguments
        cb.setMaxLocals(1);
        cb.opc_aload_0();
        cb.opc_invokespecial(superCtorIdx, 0, 0);
        cb.opc_return();

        // Emit method
        emitMethod(initIdx, cb.getMaxLocals(), cb, null, null);
    }

    // The descriptor's index in the constant pool must be (1 +
    // nameIdx). "numArgs" must indicate ALL arguments, including the
    // implicit "this" argument; double and long arguments each count
    // as 2 in this count. The code buffer must NOT contain the code
    // length. The exception table may be null, but if non-null must
    // NOT contain the exception table's length. The checked exception
    // indices may be null.
    protected void emitMethod(short nameIdx,
                              int numArgs,
                              ClassFileAssembler code,
                              ClassFileAssembler exceptionTable,
                              short[] checkedExceptionIndices)
    {
        int codeLen = code.getLength();
        int excLen  = 0;
        if (exceptionTable != null) {
            excLen = exceptionTable.getLength();
            if ((excLen % 8) != 0) {
                throw new IllegalArgumentException("Illegal exception table");
            }
        }
        int attrLen = 12 + codeLen + excLen;
        excLen = excLen / 8; // No-op if no exception table

        asm.emitShort(ACC_PUBLIC);
        asm.emitShort(nameIdx);
        asm.emitShort(add(nameIdx, S1));
        if (checkedExceptionIndices == null) {
            // Code attribute only
            asm.emitShort(S1);
        } else {
            // Code and Exceptions attributes
            asm.emitShort(S2);
        }
        // Code attribute
        asm.emitShort(codeIdx);
        asm.emitInt(attrLen);
        asm.emitShort(code.getMaxStack());
        asm.emitShort((short) Math.max(numArgs, code.getMaxLocals()));
        asm.emitInt(codeLen);
        asm.append(code);
        asm.emitShort((short) excLen);
        if (exceptionTable != null) {
            asm.append(exceptionTable);
        }
        asm.emitShort(S0); // No additional attributes for Code attribute
        if (checkedExceptionIndices != null) {
            // Exceptions attribute
            asm.emitShort(exceptionsIdx);
            asm.emitInt(2 + 2 * checkedExceptionIndices.length);
            asm.emitShort((short) checkedExceptionIndices.length);
            for (int i = 0; i < checkedExceptionIndices.length; i++) {
                asm.emitShort(checkedExceptionIndices[i]);
            }
        }
    }

    protected short indexForPrimitiveType(Class type) {
        if (type == Boolean.TYPE) {
            return booleanIdx;
        } else if (type == Byte.TYPE) {
            return byteIdx;
        } else if (type == Character.TYPE) {
            return characterIdx;
        } else if (type == Double.TYPE) {
            return doubleIdx;
        } else if (type == Float.TYPE) {
            return floatIdx;
        } else if (type == Integer.TYPE) {
            return integerIdx;
        } else if (type == Long.TYPE) {
            return longIdx;
        } else if (type == Short.TYPE) {
            return shortIdx;
        }
        throw new InternalError("Should have found primitive type");
    }

    protected short ctorIndexForPrimitiveType(Class type) {
        if (type == Boolean.TYPE) {
            return booleanCtorIdx;
        } else if (type == Byte.TYPE) {
            return byteCtorIdx;
        } else if (type == Character.TYPE) {
            return characterCtorIdx;
        } else if (type == Double.TYPE) {
            return doubleCtorIdx;
        } else if (type == Float.TYPE) {
            return floatCtorIdx;
        } else if (type == Integer.TYPE) {
            return integerCtorIdx;
        } else if (type == Long.TYPE) {
            return longCtorIdx;
        } else if (type == Short.TYPE) {
            return shortCtorIdx;
        }
        throw new InternalError("Should have found primitive type");
    }

    /** Returns true for widening or identity conversions for primitive
        types only */
    protected static boolean canWidenTo(Class type, Class otherType) {
        if (!type.isPrimitive()) {
            return false;
        }

        // Widening conversions (from JVM spec):
        //  byte to short, int, long, float, or double
        //  short to int, long, float, or double
        //  char to int, long, float, or double
        //  int to long, float, or double
        //  long to float or double
        //  float to double

        if (type == Boolean.TYPE) {
            if (otherType == Boolean.TYPE) {
                return true;
            }
        } else if (type == Byte.TYPE) {
            if (   otherType == Byte.TYPE
                   || otherType == Short.TYPE
                   || otherType == Integer.TYPE
                   || otherType == Long.TYPE
                   || otherType == Float.TYPE
                   || otherType == Double.TYPE) {
                return true;
            }
        } else if (type == Short.TYPE) {
            if (   otherType == Short.TYPE
                   || otherType == Integer.TYPE
                   || otherType == Long.TYPE
                   || otherType == Float.TYPE
                   || otherType == Double.TYPE) {
                return true;
            }
        } else if (type == Character.TYPE) {
            if (   otherType == Character.TYPE
                   || otherType == Integer.TYPE
                   || otherType == Long.TYPE
                   || otherType == Float.TYPE
                   || otherType == Double.TYPE) {
                return true;
            }
        } else if (type == Integer.TYPE) {
            if (   otherType == Integer.TYPE
                   || otherType == Long.TYPE
                   || otherType == Float.TYPE
                   || otherType == Double.TYPE) {
                return true;
            }
        } else if (type == Long.TYPE) {
            if (   otherType == Long.TYPE
                   || otherType == Float.TYPE
                   || otherType == Double.TYPE) {
                return true;
            }
        } else if (type == Float.TYPE) {
            if (   otherType == Float.TYPE
                   || otherType == Double.TYPE) {
                return true;
            }
        } else if (type == Double.TYPE) {
            if (otherType == Double.TYPE) {
                return true;
            }
        }

        return false;
    }

    /** Emits the widening bytecode for the given primitive conversion
        (or none if the identity conversion). Requires that a primitive
        conversion exists; i.e., canWidenTo must have already been
        called and returned true. */
    protected static void emitWideningBytecodeForPrimitiveConversion
        (ClassFileAssembler cb,
         Class fromType,
         Class toType)
    {
        // Note that widening conversions for integral types (i.e., "b2s",
        // "s2i") are no-ops since values on the Java stack are
        // sign-extended.

        // Widening conversions (from JVM spec):
        //  byte to short, int, long, float, or double
        //  short to int, long, float, or double
        //  char to int, long, float, or double
        //  int to long, float, or double
        //  long to float or double
        //  float to double

        if (   fromType == Byte.TYPE
               || fromType == Short.TYPE
               || fromType == Character.TYPE
               || fromType == Integer.TYPE) {
            if (toType == Long.TYPE) {
                cb.opc_i2l();
            } else if (toType == Float.TYPE) {
                cb.opc_i2f();
            } else if (toType == Double.TYPE) {
                cb.opc_i2d();
            }
        } else if (fromType == Long.TYPE) {
            if (toType == Float.TYPE) {
                cb.opc_l2f();
            } else if (toType == Double.TYPE) {
                cb.opc_l2d();
            }
        } else if (fromType == Float.TYPE) {
            if (toType == Double.TYPE) {
                cb.opc_f2d();
            }
        }

        // Otherwise, was identity or no-op conversion. Fall through.
    }

    protected short unboxingMethodForPrimitiveType(Class primType) {
        if (primType == Boolean.TYPE) {
            return booleanUnboxIdx;
        } else if (primType == Byte.TYPE) {
            return byteUnboxIdx;
        } else if (primType == Character.TYPE) {
            return characterUnboxIdx;
        } else if (primType == Short.TYPE) {
            return shortUnboxIdx;
        } else if (primType == Integer.TYPE) {
            return integerUnboxIdx;
        } else if (primType == Long.TYPE) {
            return longUnboxIdx;
        } else if (primType == Float.TYPE) {
            return floatUnboxIdx;
        } else if (primType == Double.TYPE) {
            return doubleUnboxIdx;
        }
        throw new InternalError("Illegal primitive type " + primType.getName());
    }

    protected static final Class[] primitiveTypes = new Class[] {
        Boolean.TYPE,
        Byte.TYPE,
        Character.TYPE,
        Short.TYPE,
        Integer.TYPE,
        Long.TYPE,
        Float.TYPE,
        Double.TYPE
    };

    /** We don't consider "Void" to be a primitive type */
    protected static boolean isPrimitive(Class c) {
        return (c.isPrimitive() && c != Void.TYPE);
    }

    protected int typeSizeInStackSlots(Class c) {
        if (c == Void.TYPE) {
            return 0;
        }
        if (c == Long.TYPE || c == Double.TYPE) {
            return 2;
        }
        return 1;
    }

    private ClassFileAssembler illegalArgumentCodeBuffer;
    protected ClassFileAssembler illegalArgumentCodeBuffer() {
        if (illegalArgumentCodeBuffer == null) {
            illegalArgumentCodeBuffer = new ClassFileAssembler();
            illegalArgumentCodeBuffer.opc_new(illegalArgumentClass);
            illegalArgumentCodeBuffer.opc_dup();
            illegalArgumentCodeBuffer.opc_invokespecial(illegalArgumentCtorIdx, 0, 0);
            illegalArgumentCodeBuffer.opc_athrow();
        }

        return illegalArgumentCodeBuffer;
    }
}
