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

import java.security.AccessController;
import java.security.PrivilegedAction;

/** Generator for sun.reflect.MethodAccessor and
    sun.reflect.ConstructorAccessor objects using bytecodes to
    implement reflection. A java.lang.reflect.Method or
    java.lang.reflect.Constructor object can delegate its invoke or
    newInstance method to an accessor using native code or to one
    generated by this class. (Methods and Constructors were merged
    together in this class to ensure maximum code sharing.) */

class MethodAccessorGenerator extends AccessorGenerator {

    private static final short NUM_BASE_CPOOL_ENTRIES   = (short) 12;
    // One for invoke() plus one for constructor
    private static final short NUM_METHODS              = (short) 2;
    // Only used if forSerialization is true
    private static final short NUM_SERIALIZATION_CPOOL_ENTRIES = (short) 2;

    private static volatile int methodSymnum = 0;
    private static volatile int constructorSymnum = 0;
    private static volatile int serializationConstructorSymnum = 0;

    private Class<?>   declaringClass;
    private Class<?>[] parameterTypes;
    private Class<?>   returnType;
    private boolean    isConstructor;
    private boolean    forSerialization;

    private short targetMethodRef;
    private short invokeIdx;
    private short invokeDescriptorIdx;
    // Constant pool index of CONSTANT_Class_info for first
    // non-primitive parameter type. Should be incremented by 2.
    private short nonPrimitiveParametersBaseIdx;

    MethodAccessorGenerator() {
    }

    /** This routine is not thread-safe */
    public MethodAccessor generateMethod(Class<?> declaringClass,
                                         String   name,
                                         Class<?>[] parameterTypes,
                                         Class<?>   returnType,
                                         Class<?>[] checkedExceptions,
                                         int modifiers)
    {
        return (MethodAccessor) generate(declaringClass,
                                         name,
                                         parameterTypes,
                                         returnType,
                                         checkedExceptions,
                                         modifiers,
                                         false,
                                         false,
                                         null);
    }

    /** This routine is not thread-safe */
    public ConstructorAccessor generateConstructor(Class<?> declaringClass,
                                                   Class<?>[] parameterTypes,
                                                   Class<?>[] checkedExceptions,
                                                   int modifiers)
    {
        return (ConstructorAccessor) generate(declaringClass,
                                              "<init>",
                                              parameterTypes,
                                              Void.TYPE,
                                              checkedExceptions,
                                              modifiers,
                                              true,
                                              false,
                                              null);
    }

    /** This routine is not thread-safe */
    public SerializationConstructorAccessorImpl
    generateSerializationConstructor(Class<?> declaringClass,
                                     Class<?>[] parameterTypes,
                                     Class<?>[] checkedExceptions,
                                     int modifiers,
                                     Class<?> targetConstructorClass)
    {
        return (SerializationConstructorAccessorImpl)
            generate(declaringClass,
                     "<init>",
                     parameterTypes,
                     Void.TYPE,
                     checkedExceptions,
                     modifiers,
                     true,
                     true,
                     targetConstructorClass);
    }

    /** This routine is not thread-safe */
    private MagicAccessorImpl generate(final Class<?> declaringClass,
                                       String name,
                                       Class<?>[] parameterTypes,
                                       Class<?>   returnType,
                                       Class<?>[] checkedExceptions,
                                       int modifiers,
                                       boolean isConstructor,
                                       boolean forSerialization,
                                       Class<?> serializationTargetClass)
    {
        ByteVector vec = ByteVectorFactory.create();
        asm = new ClassFileAssembler(vec);
        this.declaringClass = declaringClass;
        this.parameterTypes = parameterTypes;
        this.returnType = returnType;
        this.modifiers = modifiers;
        this.isConstructor = isConstructor;
        this.forSerialization = forSerialization;

        asm.emitMagicAndVersion();

        // Constant pool entries:
        // ( * = Boxing information: optional)
        // (+  = Shared entries provided by AccessorGenerator)
        // (^  = Only present if generating SerializationConstructorAccessor)
        //     [UTF-8] [This class's name]
        //     [CONSTANT_Class_info] for above
        //     [UTF-8] "sun/reflect/{MethodAccessorImpl,ConstructorAccessorImpl,SerializationConstructorAccessorImpl}"
        //     [CONSTANT_Class_info] for above
        //     [UTF-8] [Target class's name]
        //     [CONSTANT_Class_info] for above
        // ^   [UTF-8] [Serialization: Class's name in which to invoke constructor]
        // ^   [CONSTANT_Class_info] for above
        //     [UTF-8] target method or constructor name
        //     [UTF-8] target method or constructor signature
        //     [CONSTANT_NameAndType_info] for above
        //     [CONSTANT_Methodref_info or CONSTANT_InterfaceMethodref_info] for target method
        //     [UTF-8] "invoke" or "newInstance"
        //     [UTF-8] invoke or newInstance descriptor
        //     [UTF-8] descriptor for type of non-primitive parameter 1
        //     [CONSTANT_Class_info] for type of non-primitive parameter 1
        //     ...
        //     [UTF-8] descriptor for type of non-primitive parameter n
        //     [CONSTANT_Class_info] for type of non-primitive parameter n
        // +   [UTF-8] "java/lang/Exception"
        // +   [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"
        //  *  [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

        short numCPEntries = NUM_BASE_CPOOL_ENTRIES + NUM_COMMON_CPOOL_ENTRIES;
        boolean usesPrimitives = usesPrimitiveTypes();
        if (usesPrimitives) {
            numCPEntries += NUM_BOXING_CPOOL_ENTRIES;
        }
        if (forSerialization) {
            numCPEntries += NUM_SERIALIZATION_CPOOL_ENTRIES;
        }

        // Add in variable-length number of entries to be able to describe
        // non-primitive parameter types and checked exceptions.
        numCPEntries += (short) (2 * numNonPrimitiveParameterTypes());

        asm.emitShort(add(numCPEntries, S1));

        final String generatedName = generateName(isConstructor, forSerialization);
        asm.emitConstantPoolUTF8(generatedName);
        asm.emitConstantPoolClass(asm.cpi());
        thisClass = asm.cpi();
        if (isConstructor) {
            if (forSerialization) {
                asm.emitConstantPoolUTF8
                    ("sun/reflect/SerializationConstructorAccessorImpl");
            } else {
                asm.emitConstantPoolUTF8("sun/reflect/ConstructorAccessorImpl");
            }
        } else {
            asm.emitConstantPoolUTF8("sun/reflect/MethodAccessorImpl");
        }
        asm.emitConstantPoolClass(asm.cpi());
        superClass = asm.cpi();
        asm.emitConstantPoolUTF8(getClassName(declaringClass, false));
        asm.emitConstantPoolClass(asm.cpi());
        targetClass = asm.cpi();
        short serializationTargetClassIdx = (short) 0;
        if (forSerialization) {
            asm.emitConstantPoolUTF8(getClassName(serializationTargetClass, false));
            asm.emitConstantPoolClass(asm.cpi());
            serializationTargetClassIdx = asm.cpi();
        }
        asm.emitConstantPoolUTF8(name);
        asm.emitConstantPoolUTF8(buildInternalSignature());
        asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
        if (isInterface()) {
            asm.emitConstantPoolInterfaceMethodref(targetClass, asm.cpi());
        } else {
            if (forSerialization) {
                asm.emitConstantPoolMethodref(serializationTargetClassIdx, asm.cpi());
            } else {
                asm.emitConstantPoolMethodref(targetClass, asm.cpi());
            }
        }
        targetMethodRef = asm.cpi();
        if (isConstructor) {
            asm.emitConstantPoolUTF8("newInstance");
        } else {
            asm.emitConstantPoolUTF8("invoke");
        }
        invokeIdx = asm.cpi();
        if (isConstructor) {
            asm.emitConstantPoolUTF8("([Ljava/lang/Object;)Ljava/lang/Object;");
        } else {
            asm.emitConstantPoolUTF8
                ("(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;");
        }
        invokeDescriptorIdx = asm.cpi();

        // Output class information for non-primitive parameter types
        nonPrimitiveParametersBaseIdx = add(asm.cpi(), S2);
        for (int i = 0; i < parameterTypes.length; i++) {
            Class<?> c = parameterTypes[i];
            if (!isPrimitive(c)) {
                asm.emitConstantPoolUTF8(getClassName(c, false));
                asm.emitConstantPoolClass(asm.cpi());
            }
        }

        // Entries common to FieldAccessor, MethodAccessor and ConstructorAccessor
        emitCommonConstantPoolEntries();

        // Boxing entries
        if (usesPrimitives) {
            emitBoxingContantPoolEntries();
        }

        if (asm.cpi() != numCPEntries) {
            throw new InternalError("Adjust this code (cpi = " + asm.cpi() +
                                    ", numCPEntries = " + numCPEntries + ")");
        }

        // Access flags
        asm.emitShort(ACC_PUBLIC);

        // This class
        asm.emitShort(thisClass);

        // Superclass
        asm.emitShort(superClass);

        // Interfaces count and interfaces
        asm.emitShort(S0);

        // Fields count and fields
        asm.emitShort(S0);

        // Methods count and methods
        asm.emitShort(NUM_METHODS);

        emitConstructor();
        emitInvoke();

        // Additional attributes (none)
        asm.emitShort(S0);

        // Load class
        vec.trim();
        final byte[] bytes = vec.getData();
        // Note: the class loader is the only thing that really matters
        // here -- it's important to get the generated code into the
        // same namespace as the target class. Since the generated code
        // is privileged anyway, the protection domain probably doesn't
        // matter.
        return AccessController.doPrivileged(
            new PrivilegedAction<MagicAccessorImpl>() {
                public MagicAccessorImpl run() {
                        try {
                        return (MagicAccessorImpl)
                        ClassDefiner.defineClass
                                (generatedName,
                                 bytes,
                                 0,
                                 bytes.length,
                                 declaringClass.getClassLoader()).newInstance();
                        } catch (InstantiationException | IllegalAccessException e) {
                            throw new InternalError(e);
                        }
                    }
                });
    }

    /** This emits the code for either invoke() or newInstance() */
    private void emitInvoke() {
        // NOTE that this code will only handle 65535 parameters since we
        // use the sipush instruction to get the array index on the
        // operand stack.
        if (parameterTypes.length > 65535) {
            throw new InternalError("Can't handle more than 65535 parameters");
        }

        // Generate code into fresh code buffer
        ClassFileAssembler cb = new ClassFileAssembler();
        if (isConstructor) {
            // 1 incoming argument
            cb.setMaxLocals(2);
        } else {
            // 2 incoming arguments
            cb.setMaxLocals(3);
        }

        short illegalArgStartPC = 0;

        if (isConstructor) {
            // Instantiate target class before continuing
            // new <target class type>
            // dup
            cb.opc_new(targetClass);
            cb.opc_dup();
        } else {
            // Setup before iterating down argument list
            if (isPrimitive(returnType)) {
                // new <boxing type for primitive type>
                // dup
                // ... (see below:)
                // invokespecial <constructor for boxing type for primitive type>
                // areturn
                cb.opc_new(indexForPrimitiveType(returnType));
                cb.opc_dup();
            }

            // Get target object on operand stack if necessary.

            // We need to do an explicit null check here; we won't see
            // NullPointerExceptions from the invoke bytecode, since it's
            // covered by an exception handler.
            if (!isStatic()) {
                // aload_1
                // ifnonnull <checkcast label>
                // new <NullPointerException>
                // dup
                // invokespecial <NullPointerException ctor>
                // athrow
                // <checkcast label:>
                // aload_1
                // checkcast <target class's type>
                cb.opc_aload_1();
                Label l = new Label();
                cb.opc_ifnonnull(l);
                cb.opc_new(nullPointerClass);
                cb.opc_dup();
                cb.opc_invokespecial(nullPointerCtorIdx, 0, 0);
                cb.opc_athrow();
                l.bind();
                illegalArgStartPC = cb.getLength();
                cb.opc_aload_1();
                cb.opc_checkcast(targetClass);
            }
        }

        // Have to check length of incoming array and throw
        // IllegalArgumentException if not correct. A concession to the
        // JCK (isn't clearly specified in the spec): we allow null in the
        // case where the argument list is zero length.
        // if no-arg:
        //   aload_2 | aload_1 (Method | Constructor)
        //   ifnull <success label>
        // aload_2 | aload_1
        // arraylength
        // sipush <num parameter types>
        // if_icmpeq <success label>
        // new <IllegalArgumentException>
        // dup
        // invokespecial <IllegalArgumentException ctor>
        // athrow
        // <success label:>
        Label successLabel = new Label();
        if (parameterTypes.length == 0) {
            if (isConstructor) {
                cb.opc_aload_1();
            } else {
                cb.opc_aload_2();
            }
            cb.opc_ifnull(successLabel);
        }
        if (isConstructor) {
            cb.opc_aload_1();
        } else {
            cb.opc_aload_2();
        }
        cb.opc_arraylength();
        cb.opc_sipush((short) parameterTypes.length);
        cb.opc_if_icmpeq(successLabel);
        cb.opc_new(illegalArgumentClass);
        cb.opc_dup();
        cb.opc_invokespecial(illegalArgumentCtorIdx, 0, 0);
        cb.opc_athrow();
        successLabel.bind();

        // Iterate through incoming actual parameters, ensuring that each
        // is compatible with the formal parameter type, and pushing the
        // actual on the operand stack (unboxing and widening if necessary).

        short paramTypeCPIdx = nonPrimitiveParametersBaseIdx;
        Label nextParamLabel = null;
        byte count = 1; // both invokeinterface opcode's "count" as well as
        // num args of other invoke bytecodes
        for (int i = 0; i < parameterTypes.length; i++) {
            Class<?> paramType = parameterTypes[i];
            count += (byte) typeSizeInStackSlots(paramType);
            if (nextParamLabel != null) {
                nextParamLabel.bind();
                nextParamLabel = null;
            }
            // aload_2 | aload_1
            // sipush <index>
            // aaload
            if (isConstructor) {
                cb.opc_aload_1();
            } else {
                cb.opc_aload_2();
            }
            cb.opc_sipush((short) i);
            cb.opc_aaload();
            if (isPrimitive(paramType)) {
                // Unboxing code.
                // Put parameter into temporary local variable
                // astore_3 | astore_2
                if (isConstructor) {
                    cb.opc_astore_2();
                } else {
                    cb.opc_astore_3();
                }

                // repeat for all possible widening conversions:
                //   aload_3 | aload_2
                //   instanceof <primitive boxing type>
                //   ifeq <next unboxing label>
                //   aload_3 | aload_2
                //   checkcast <primitive boxing type> // Note: this is "redundant",
                //                                     // but necessary for the verifier
                //   invokevirtual <unboxing method>
                //   <widening conversion bytecode, if necessary>
                //   goto <next parameter label>
                // <next unboxing label:> ...
                // last unboxing label:
                //   new <IllegalArgumentException>
                //   dup
                //   invokespecial <IllegalArgumentException ctor>
                //   athrow

                Label l = null; // unboxing label
                nextParamLabel = new Label();

                for (int j = 0; j < primitiveTypes.length; j++) {
                    Class<?> c = primitiveTypes[j];
                    if (canWidenTo(c, paramType)) {
                        if (l != null) {
                            l.bind();
                        }
                        // Emit checking and unboxing code for this type
                        if (isConstructor) {
                            cb.opc_aload_2();
                        } else {
                            cb.opc_aload_3();
                        }
                        cb.opc_instanceof(indexForPrimitiveType(c));
                        l = new Label();
                        cb.opc_ifeq(l);
                        if (isConstructor) {
                            cb.opc_aload_2();
                        } else {
                            cb.opc_aload_3();
                        }
                        cb.opc_checkcast(indexForPrimitiveType(c));
                        cb.opc_invokevirtual(unboxingMethodForPrimitiveType(c),
                                             0,
                                             typeSizeInStackSlots(c));
                        emitWideningBytecodeForPrimitiveConversion(cb,
                                                                   c,
                                                                   paramType);
                        cb.opc_goto(nextParamLabel);
                    }
                }

                if (l == null) {
                    throw new InternalError
                        ("Must have found at least identity conversion");
                }

                // Fell through; given object is null or invalid. According to
                // the spec, we can throw IllegalArgumentException for both of
                // these cases.

                l.bind();
                cb.opc_new(illegalArgumentClass);
                cb.opc_dup();
                cb.opc_invokespecial(illegalArgumentCtorIdx, 0, 0);
                cb.opc_athrow();
            } else {
                // Emit appropriate checkcast
                cb.opc_checkcast(paramTypeCPIdx);
                paramTypeCPIdx = add(paramTypeCPIdx, S2);
                // Fall through to next argument
            }
        }
        // Bind last goto if present
        if (nextParamLabel != null) {
            nextParamLabel.bind();
        }

        short invokeStartPC = cb.getLength();

        // OK, ready to perform the invocation.
        if (isConstructor) {
            cb.opc_invokespecial(targetMethodRef, count, 0);
        } else {
            if (isStatic()) {
                cb.opc_invokestatic(targetMethodRef,
                                    count,
                                    typeSizeInStackSlots(returnType));
            } else {
                if (isInterface()) {
                    if (isPrivate()) {
                        cb.opc_invokespecial(targetMethodRef, count, 0);
                    } else {
                        cb.opc_invokeinterface(targetMethodRef,
                                               count,
                                               count,
                                               typeSizeInStackSlots(returnType));
                    }
                } else {
                    cb.opc_invokevirtual(targetMethodRef,
                                         count,
                                         typeSizeInStackSlots(returnType));
                }
            }
        }

        short invokeEndPC = cb.getLength();

        if (!isConstructor) {
            // Box return value if necessary
            if (isPrimitive(returnType)) {
                cb.opc_invokespecial(ctorIndexForPrimitiveType(returnType),
                                     typeSizeInStackSlots(returnType),
                                     0);
            } else if (returnType == Void.TYPE) {
                cb.opc_aconst_null();
            }
        }
        cb.opc_areturn();

        // We generate two exception handlers; one which is responsible
        // for catching ClassCastException and NullPointerException and
        // throwing IllegalArgumentException, and the other which catches
        // all java/lang/Throwable objects thrown from the target method
        // and wraps them in InvocationTargetExceptions.

        short classCastHandler = cb.getLength();

        // ClassCast, etc. exception handler
        cb.setStack(1);
        cb.opc_invokespecial(toStringIdx, 0, 1);
        cb.opc_new(illegalArgumentClass);
        cb.opc_dup_x1();
        cb.opc_swap();
        cb.opc_invokespecial(illegalArgumentStringCtorIdx, 1, 0);
        cb.opc_athrow();

        short invocationTargetHandler = cb.getLength();

        // InvocationTargetException exception handler
        cb.setStack(1);
        cb.opc_new(invocationTargetClass);
        cb.opc_dup_x1();
        cb.opc_swap();
        cb.opc_invokespecial(invocationTargetCtorIdx, 1, 0);
        cb.opc_athrow();

        // Generate exception table. We cover the entire code sequence
        // with an exception handler which catches ClassCastException and
        // converts it into an IllegalArgumentException.

        ClassFileAssembler exc = new ClassFileAssembler();

        exc.emitShort(illegalArgStartPC);       // start PC
        exc.emitShort(invokeStartPC);           // end PC
        exc.emitShort(classCastHandler);        // handler PC
        exc.emitShort(classCastClass);          // catch type

        exc.emitShort(illegalArgStartPC);       // start PC
        exc.emitShort(invokeStartPC);           // end PC
        exc.emitShort(classCastHandler);        // handler PC
        exc.emitShort(nullPointerClass);        // catch type

        exc.emitShort(invokeStartPC);           // start PC
        exc.emitShort(invokeEndPC);             // end PC
        exc.emitShort(invocationTargetHandler); // handler PC
        exc.emitShort(throwableClass);          // catch type

        emitMethod(invokeIdx, cb.getMaxLocals(), cb, exc,
                   new short[] { invocationTargetClass });
    }

    private boolean usesPrimitiveTypes() {
        // We need to emit boxing/unboxing constant pool information if
        // the method takes a primitive type for any of its parameters or
        // returns a primitive value (except void)
        if (returnType.isPrimitive()) {
            return true;
        }
        for (int i = 0; i < parameterTypes.length; i++) {
            if (parameterTypes[i].isPrimitive()) {
                return true;
            }
        }
        return false;
    }

    private int numNonPrimitiveParameterTypes() {
        int num = 0;
        for (int i = 0; i < parameterTypes.length; i++) {
            if (!parameterTypes[i].isPrimitive()) {
                ++num;
            }
        }
        return num;
    }

    private boolean isInterface() {
        return declaringClass.isInterface();
    }

    private String buildInternalSignature() {
        StringBuffer buf = new StringBuffer();
        buf.append("(");
        for (int i = 0; i < parameterTypes.length; i++) {
            buf.append(getClassName(parameterTypes[i], true));
        }
        buf.append(")");
        buf.append(getClassName(returnType, true));
        return buf.toString();
    }

    private static synchronized String generateName(boolean isConstructor,
                                                    boolean forSerialization)
    {
        if (isConstructor) {
            if (forSerialization) {
                int num = ++serializationConstructorSymnum;
                return "sun/reflect/GeneratedSerializationConstructorAccessor" + num;
            } else {
                int num = ++constructorSymnum;
                return "sun/reflect/GeneratedConstructorAccessor" + num;
            }
        } else {
            int num = ++methodSymnum;
            return "sun/reflect/GeneratedMethodAccessor" + num;
        }
    }
}
