Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/reflect/AccessorGenerator.java
38829 views
/*1* Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.reflect;2627import java.lang.reflect.*;28import sun.misc.Unsafe;2930/** Shared functionality for all accessor generators */3132class AccessorGenerator implements ClassFileConstants {33static final Unsafe unsafe = Unsafe.getUnsafe();3435// Constants because there's no way to say "short integer constant",36// i.e., "1S"37protected static final short S0 = (short) 0;38protected static final short S1 = (short) 1;39protected static final short S2 = (short) 2;40protected static final short S3 = (short) 3;41protected static final short S4 = (short) 4;42protected static final short S5 = (short) 5;43protected static final short S6 = (short) 6;4445// Instance variables for shared functionality between46// FieldAccessorGenerator and MethodAccessorGenerator47protected ClassFileAssembler asm;48protected int modifiers;49protected short thisClass;50protected short superClass;51protected short targetClass;52// Common constant pool entries to FieldAccessor and MethodAccessor53protected short throwableClass;54protected short classCastClass;55protected short nullPointerClass;56protected short illegalArgumentClass;57protected short invocationTargetClass;58protected short initIdx;59protected short initNameAndTypeIdx;60protected short initStringNameAndTypeIdx;61protected short nullPointerCtorIdx;62protected short illegalArgumentCtorIdx;63protected short illegalArgumentStringCtorIdx;64protected short invocationTargetCtorIdx;65protected short superCtorIdx;66protected short objectClass;67protected short toStringIdx;68protected short codeIdx;69protected short exceptionsIdx;70// Boxing71protected short booleanIdx;72protected short booleanCtorIdx;73protected short booleanUnboxIdx;74protected short byteIdx;75protected short byteCtorIdx;76protected short byteUnboxIdx;77protected short characterIdx;78protected short characterCtorIdx;79protected short characterUnboxIdx;80protected short doubleIdx;81protected short doubleCtorIdx;82protected short doubleUnboxIdx;83protected short floatIdx;84protected short floatCtorIdx;85protected short floatUnboxIdx;86protected short integerIdx;87protected short integerCtorIdx;88protected short integerUnboxIdx;89protected short longIdx;90protected short longCtorIdx;91protected short longUnboxIdx;92protected short shortIdx;93protected short shortCtorIdx;94protected short shortUnboxIdx;9596protected final short NUM_COMMON_CPOOL_ENTRIES = (short) 30;97protected final short NUM_BOXING_CPOOL_ENTRIES = (short) 72;9899// Requires that superClass has been set up100protected void emitCommonConstantPoolEntries() {101// + [UTF-8] "java/lang/Throwable"102// + [CONSTANT_Class_info] for above103// + [UTF-8] "java/lang/ClassCastException"104// + [CONSTANT_Class_info] for above105// + [UTF-8] "java/lang/NullPointerException"106// + [CONSTANT_Class_info] for above107// + [UTF-8] "java/lang/IllegalArgumentException"108// + [CONSTANT_Class_info] for above109// + [UTF-8] "java/lang/InvocationTargetException"110// + [CONSTANT_Class_info] for above111// + [UTF-8] "<init>"112// + [UTF-8] "()V"113// + [CONSTANT_NameAndType_info] for above114// + [CONSTANT_Methodref_info] for NullPointerException's constructor115// + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor116// + [UTF-8] "(Ljava/lang/String;)V"117// + [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/String;)V"118// + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor taking a String119// + [UTF-8] "(Ljava/lang/Throwable;)V"120// + [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/Throwable;)V"121// + [CONSTANT_Methodref_info] for InvocationTargetException's constructor122// + [CONSTANT_Methodref_info] for "super()"123// + [UTF-8] "java/lang/Object"124// + [CONSTANT_Class_info] for above125// + [UTF-8] "toString"126// + [UTF-8] "()Ljava/lang/String;"127// + [CONSTANT_NameAndType_info] for "toString()Ljava/lang/String;"128// + [CONSTANT_Methodref_info] for Object's toString method129// + [UTF-8] "Code"130// + [UTF-8] "Exceptions"131asm.emitConstantPoolUTF8("java/lang/Throwable");132asm.emitConstantPoolClass(asm.cpi());133throwableClass = asm.cpi();134asm.emitConstantPoolUTF8("java/lang/ClassCastException");135asm.emitConstantPoolClass(asm.cpi());136classCastClass = asm.cpi();137asm.emitConstantPoolUTF8("java/lang/NullPointerException");138asm.emitConstantPoolClass(asm.cpi());139nullPointerClass = asm.cpi();140asm.emitConstantPoolUTF8("java/lang/IllegalArgumentException");141asm.emitConstantPoolClass(asm.cpi());142illegalArgumentClass = asm.cpi();143asm.emitConstantPoolUTF8("java/lang/reflect/InvocationTargetException");144asm.emitConstantPoolClass(asm.cpi());145invocationTargetClass = asm.cpi();146asm.emitConstantPoolUTF8("<init>");147initIdx = asm.cpi();148asm.emitConstantPoolUTF8("()V");149asm.emitConstantPoolNameAndType(initIdx, asm.cpi());150initNameAndTypeIdx = asm.cpi();151asm.emitConstantPoolMethodref(nullPointerClass, initNameAndTypeIdx);152nullPointerCtorIdx = asm.cpi();153asm.emitConstantPoolMethodref(illegalArgumentClass, initNameAndTypeIdx);154illegalArgumentCtorIdx = asm.cpi();155asm.emitConstantPoolUTF8("(Ljava/lang/String;)V");156asm.emitConstantPoolNameAndType(initIdx, asm.cpi());157initStringNameAndTypeIdx = asm.cpi();158asm.emitConstantPoolMethodref(illegalArgumentClass, initStringNameAndTypeIdx);159illegalArgumentStringCtorIdx = asm.cpi();160asm.emitConstantPoolUTF8("(Ljava/lang/Throwable;)V");161asm.emitConstantPoolNameAndType(initIdx, asm.cpi());162asm.emitConstantPoolMethodref(invocationTargetClass, asm.cpi());163invocationTargetCtorIdx = asm.cpi();164asm.emitConstantPoolMethodref(superClass, initNameAndTypeIdx);165superCtorIdx = asm.cpi();166asm.emitConstantPoolUTF8("java/lang/Object");167asm.emitConstantPoolClass(asm.cpi());168objectClass = asm.cpi();169asm.emitConstantPoolUTF8("toString");170asm.emitConstantPoolUTF8("()Ljava/lang/String;");171asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());172asm.emitConstantPoolMethodref(objectClass, asm.cpi());173toStringIdx = asm.cpi();174asm.emitConstantPoolUTF8("Code");175codeIdx = asm.cpi();176asm.emitConstantPoolUTF8("Exceptions");177exceptionsIdx = asm.cpi();178}179180/** Constant pool entries required to be able to box/unbox primitive181types. Note that we don't emit these if we don't need them. */182protected void emitBoxingContantPoolEntries() {183// * [UTF-8] "java/lang/Boolean"184// * [CONSTANT_Class_info] for above185// * [UTF-8] "(Z)V"186// * [CONSTANT_NameAndType_info] for above187// * [CONSTANT_Methodref_info] for above188// * [UTF-8] "booleanValue"189// * [UTF-8] "()Z"190// * [CONSTANT_NameAndType_info] for above191// * [CONSTANT_Methodref_info] for above192// * [UTF-8] "java/lang/Byte"193// * [CONSTANT_Class_info] for above194// * [UTF-8] "(B)V"195// * [CONSTANT_NameAndType_info] for above196// * [CONSTANT_Methodref_info] for above197// * [UTF-8] "byteValue"198// * [UTF-8] "()B"199// * [CONSTANT_NameAndType_info] for above200// * [CONSTANT_Methodref_info] for above201// * [UTF-8] "java/lang/Character"202// * [CONSTANT_Class_info] for above203// * [UTF-8] "(C)V"204// * [CONSTANT_NameAndType_info] for above205// * [CONSTANT_Methodref_info] for above206// * [UTF-8] "charValue"207// * [UTF-8] "()C"208// * [CONSTANT_NameAndType_info] for above209// * [CONSTANT_Methodref_info] for above210// * [UTF-8] "java/lang/Double"211// * [CONSTANT_Class_info] for above212// * [UTF-8] "(D)V"213// * [CONSTANT_NameAndType_info] for above214// * [CONSTANT_Methodref_info] for above215// * [UTF-8] "doubleValue"216// * [UTF-8] "()D"217// * [CONSTANT_NameAndType_info] for above218// * [CONSTANT_Methodref_info] for above219// * [UTF-8] "java/lang/Float"220// * [CONSTANT_Class_info] for above221// * [UTF-8] "(F)V"222// * [CONSTANT_NameAndType_info] for above223// * [CONSTANT_Methodref_info] for above224// * [UTF-8] "floatValue"225// * [UTF-8] "()F"226// * [CONSTANT_NameAndType_info] for above227// * [CONSTANT_Methodref_info] for above228// * [UTF-8] "java/lang/Integer"229// * [CONSTANT_Class_info] for above230// * [UTF-8] "(I)V"231// * [CONSTANT_NameAndType_info] for above232// * [CONSTANT_Methodref_info] for above233// * [UTF-8] "intValue"234// * [UTF-8] "()I"235// * [CONSTANT_NameAndType_info] for above236// * [CONSTANT_Methodref_info] for above237// * [UTF-8] "java/lang/Long"238// * [CONSTANT_Class_info] for above239// * [UTF-8] "(J)V"240// * [CONSTANT_NameAndType_info] for above241// * [CONSTANT_Methodref_info] for above242// * [UTF-8] "longValue"243// * [UTF-8] "()J"244// * [CONSTANT_NameAndType_info] for above245// * [CONSTANT_Methodref_info] for above246// * [UTF-8] "java/lang/Short"247// * [CONSTANT_Class_info] for above248// * [UTF-8] "(S)V"249// * [CONSTANT_NameAndType_info] for above250// * [CONSTANT_Methodref_info] for above251// * [UTF-8] "shortValue"252// * [UTF-8] "()S"253// * [CONSTANT_NameAndType_info] for above254// * [CONSTANT_Methodref_info] for above255// Boolean256asm.emitConstantPoolUTF8("java/lang/Boolean");257asm.emitConstantPoolClass(asm.cpi());258booleanIdx = asm.cpi();259asm.emitConstantPoolUTF8("(Z)V");260asm.emitConstantPoolNameAndType(initIdx, asm.cpi());261asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());262booleanCtorIdx = asm.cpi();263asm.emitConstantPoolUTF8("booleanValue");264asm.emitConstantPoolUTF8("()Z");265asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());266asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());267booleanUnboxIdx = asm.cpi();268269// Byte270asm.emitConstantPoolUTF8("java/lang/Byte");271asm.emitConstantPoolClass(asm.cpi());272byteIdx = asm.cpi();273asm.emitConstantPoolUTF8("(B)V");274asm.emitConstantPoolNameAndType(initIdx, asm.cpi());275asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());276byteCtorIdx = asm.cpi();277asm.emitConstantPoolUTF8("byteValue");278asm.emitConstantPoolUTF8("()B");279asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());280asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());281byteUnboxIdx = asm.cpi();282283// Character284asm.emitConstantPoolUTF8("java/lang/Character");285asm.emitConstantPoolClass(asm.cpi());286characterIdx = asm.cpi();287asm.emitConstantPoolUTF8("(C)V");288asm.emitConstantPoolNameAndType(initIdx, asm.cpi());289asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());290characterCtorIdx = asm.cpi();291asm.emitConstantPoolUTF8("charValue");292asm.emitConstantPoolUTF8("()C");293asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());294asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());295characterUnboxIdx = asm.cpi();296297// Double298asm.emitConstantPoolUTF8("java/lang/Double");299asm.emitConstantPoolClass(asm.cpi());300doubleIdx = asm.cpi();301asm.emitConstantPoolUTF8("(D)V");302asm.emitConstantPoolNameAndType(initIdx, asm.cpi());303asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());304doubleCtorIdx = asm.cpi();305asm.emitConstantPoolUTF8("doubleValue");306asm.emitConstantPoolUTF8("()D");307asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());308asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());309doubleUnboxIdx = asm.cpi();310311// Float312asm.emitConstantPoolUTF8("java/lang/Float");313asm.emitConstantPoolClass(asm.cpi());314floatIdx = asm.cpi();315asm.emitConstantPoolUTF8("(F)V");316asm.emitConstantPoolNameAndType(initIdx, asm.cpi());317asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());318floatCtorIdx = asm.cpi();319asm.emitConstantPoolUTF8("floatValue");320asm.emitConstantPoolUTF8("()F");321asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());322asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());323floatUnboxIdx = asm.cpi();324325// Integer326asm.emitConstantPoolUTF8("java/lang/Integer");327asm.emitConstantPoolClass(asm.cpi());328integerIdx = asm.cpi();329asm.emitConstantPoolUTF8("(I)V");330asm.emitConstantPoolNameAndType(initIdx, asm.cpi());331asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());332integerCtorIdx = asm.cpi();333asm.emitConstantPoolUTF8("intValue");334asm.emitConstantPoolUTF8("()I");335asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());336asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());337integerUnboxIdx = asm.cpi();338339// Long340asm.emitConstantPoolUTF8("java/lang/Long");341asm.emitConstantPoolClass(asm.cpi());342longIdx = asm.cpi();343asm.emitConstantPoolUTF8("(J)V");344asm.emitConstantPoolNameAndType(initIdx, asm.cpi());345asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());346longCtorIdx = asm.cpi();347asm.emitConstantPoolUTF8("longValue");348asm.emitConstantPoolUTF8("()J");349asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());350asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());351longUnboxIdx = asm.cpi();352353// Short354asm.emitConstantPoolUTF8("java/lang/Short");355asm.emitConstantPoolClass(asm.cpi());356shortIdx = asm.cpi();357asm.emitConstantPoolUTF8("(S)V");358asm.emitConstantPoolNameAndType(initIdx, asm.cpi());359asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());360shortCtorIdx = asm.cpi();361asm.emitConstantPoolUTF8("shortValue");362asm.emitConstantPoolUTF8("()S");363asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());364asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());365shortUnboxIdx = asm.cpi();366}367368// Necessary because of Java's annoying promotion rules369protected static short add(short s1, short s2) {370return (short) (s1 + s2);371}372373protected static short sub(short s1, short s2) {374return (short) (s1 - s2);375}376377protected boolean isStatic() {378return Modifier.isStatic(modifiers);379}380381protected boolean isPrivate() {382return Modifier.isPrivate(modifiers);383}384385/** Returns class name in "internal" form (i.e., '/' separators386instead of '.') */387protected static String getClassName388(Class<?> c, boolean addPrefixAndSuffixForNonPrimitiveTypes)389{390if (c.isPrimitive()) {391if (c == Boolean.TYPE) {392return "Z";393} else if (c == Byte.TYPE) {394return "B";395} else if (c == Character.TYPE) {396return "C";397} else if (c == Double.TYPE) {398return "D";399} else if (c == Float.TYPE) {400return "F";401} else if (c == Integer.TYPE) {402return "I";403} else if (c == Long.TYPE) {404return "J";405} else if (c == Short.TYPE) {406return "S";407} else if (c == Void.TYPE) {408return "V";409}410throw new InternalError("Should have found primitive type");411} else if (c.isArray()) {412return "[" + getClassName(c.getComponentType(), true);413} else {414if (addPrefixAndSuffixForNonPrimitiveTypes) {415return internalize("L" + c.getName() + ";");416} else {417return internalize(c.getName());418}419}420}421422private static String internalize(String className) {423return className.replace('.', '/');424}425426protected void emitConstructor() {427// Generate code into fresh code buffer428ClassFileAssembler cb = new ClassFileAssembler();429// 0 incoming arguments430cb.setMaxLocals(1);431cb.opc_aload_0();432cb.opc_invokespecial(superCtorIdx, 0, 0);433cb.opc_return();434435// Emit method436emitMethod(initIdx, cb.getMaxLocals(), cb, null, null);437}438439// The descriptor's index in the constant pool must be (1 +440// nameIdx). "numArgs" must indicate ALL arguments, including the441// implicit "this" argument; double and long arguments each count442// as 2 in this count. The code buffer must NOT contain the code443// length. The exception table may be null, but if non-null must444// NOT contain the exception table's length. The checked exception445// indices may be null.446protected void emitMethod(short nameIdx,447int numArgs,448ClassFileAssembler code,449ClassFileAssembler exceptionTable,450short[] checkedExceptionIndices)451{452int codeLen = code.getLength();453int excLen = 0;454if (exceptionTable != null) {455excLen = exceptionTable.getLength();456if ((excLen % 8) != 0) {457throw new IllegalArgumentException("Illegal exception table");458}459}460int attrLen = 12 + codeLen + excLen;461excLen = excLen / 8; // No-op if no exception table462463asm.emitShort(ACC_PUBLIC);464asm.emitShort(nameIdx);465asm.emitShort(add(nameIdx, S1));466if (checkedExceptionIndices == null) {467// Code attribute only468asm.emitShort(S1);469} else {470// Code and Exceptions attributes471asm.emitShort(S2);472}473// Code attribute474asm.emitShort(codeIdx);475asm.emitInt(attrLen);476asm.emitShort(code.getMaxStack());477asm.emitShort((short) Math.max(numArgs, code.getMaxLocals()));478asm.emitInt(codeLen);479asm.append(code);480asm.emitShort((short) excLen);481if (exceptionTable != null) {482asm.append(exceptionTable);483}484asm.emitShort(S0); // No additional attributes for Code attribute485if (checkedExceptionIndices != null) {486// Exceptions attribute487asm.emitShort(exceptionsIdx);488asm.emitInt(2 + 2 * checkedExceptionIndices.length);489asm.emitShort((short) checkedExceptionIndices.length);490for (int i = 0; i < checkedExceptionIndices.length; i++) {491asm.emitShort(checkedExceptionIndices[i]);492}493}494}495496protected short indexForPrimitiveType(Class<?> type) {497if (type == Boolean.TYPE) {498return booleanIdx;499} else if (type == Byte.TYPE) {500return byteIdx;501} else if (type == Character.TYPE) {502return characterIdx;503} else if (type == Double.TYPE) {504return doubleIdx;505} else if (type == Float.TYPE) {506return floatIdx;507} else if (type == Integer.TYPE) {508return integerIdx;509} else if (type == Long.TYPE) {510return longIdx;511} else if (type == Short.TYPE) {512return shortIdx;513}514throw new InternalError("Should have found primitive type");515}516517protected short ctorIndexForPrimitiveType(Class<?> type) {518if (type == Boolean.TYPE) {519return booleanCtorIdx;520} else if (type == Byte.TYPE) {521return byteCtorIdx;522} else if (type == Character.TYPE) {523return characterCtorIdx;524} else if (type == Double.TYPE) {525return doubleCtorIdx;526} else if (type == Float.TYPE) {527return floatCtorIdx;528} else if (type == Integer.TYPE) {529return integerCtorIdx;530} else if (type == Long.TYPE) {531return longCtorIdx;532} else if (type == Short.TYPE) {533return shortCtorIdx;534}535throw new InternalError("Should have found primitive type");536}537538/** Returns true for widening or identity conversions for primitive539types only */540protected static boolean canWidenTo(Class<?> type, Class<?> otherType) {541if (!type.isPrimitive()) {542return false;543}544545// Widening conversions (from JVM spec):546// byte to short, int, long, float, or double547// short to int, long, float, or double548// char to int, long, float, or double549// int to long, float, or double550// long to float or double551// float to double552553if (type == Boolean.TYPE) {554if (otherType == Boolean.TYPE) {555return true;556}557} else if (type == Byte.TYPE) {558if ( otherType == Byte.TYPE559|| otherType == Short.TYPE560|| otherType == Integer.TYPE561|| otherType == Long.TYPE562|| otherType == Float.TYPE563|| otherType == Double.TYPE) {564return true;565}566} else if (type == Short.TYPE) {567if ( otherType == Short.TYPE568|| otherType == Integer.TYPE569|| otherType == Long.TYPE570|| otherType == Float.TYPE571|| otherType == Double.TYPE) {572return true;573}574} else if (type == Character.TYPE) {575if ( otherType == Character.TYPE576|| otherType == Integer.TYPE577|| otherType == Long.TYPE578|| otherType == Float.TYPE579|| otherType == Double.TYPE) {580return true;581}582} else if (type == Integer.TYPE) {583if ( otherType == Integer.TYPE584|| otherType == Long.TYPE585|| otherType == Float.TYPE586|| otherType == Double.TYPE) {587return true;588}589} else if (type == Long.TYPE) {590if ( otherType == Long.TYPE591|| otherType == Float.TYPE592|| otherType == Double.TYPE) {593return true;594}595} else if (type == Float.TYPE) {596if ( otherType == Float.TYPE597|| otherType == Double.TYPE) {598return true;599}600} else if (type == Double.TYPE) {601if (otherType == Double.TYPE) {602return true;603}604}605606return false;607}608609/** Emits the widening bytecode for the given primitive conversion610(or none if the identity conversion). Requires that a primitive611conversion exists; i.e., canWidenTo must have already been612called and returned true. */613protected static void emitWideningBytecodeForPrimitiveConversion614(ClassFileAssembler cb,615Class<?> fromType,616Class<?> toType)617{618// Note that widening conversions for integral types (i.e., "b2s",619// "s2i") are no-ops since values on the Java stack are620// sign-extended.621622// Widening conversions (from JVM spec):623// byte to short, int, long, float, or double624// short to int, long, float, or double625// char to int, long, float, or double626// int to long, float, or double627// long to float or double628// float to double629630if ( fromType == Byte.TYPE631|| fromType == Short.TYPE632|| fromType == Character.TYPE633|| fromType == Integer.TYPE) {634if (toType == Long.TYPE) {635cb.opc_i2l();636} else if (toType == Float.TYPE) {637cb.opc_i2f();638} else if (toType == Double.TYPE) {639cb.opc_i2d();640}641} else if (fromType == Long.TYPE) {642if (toType == Float.TYPE) {643cb.opc_l2f();644} else if (toType == Double.TYPE) {645cb.opc_l2d();646}647} else if (fromType == Float.TYPE) {648if (toType == Double.TYPE) {649cb.opc_f2d();650}651}652653// Otherwise, was identity or no-op conversion. Fall through.654}655656protected short unboxingMethodForPrimitiveType(Class<?> primType) {657if (primType == Boolean.TYPE) {658return booleanUnboxIdx;659} else if (primType == Byte.TYPE) {660return byteUnboxIdx;661} else if (primType == Character.TYPE) {662return characterUnboxIdx;663} else if (primType == Short.TYPE) {664return shortUnboxIdx;665} else if (primType == Integer.TYPE) {666return integerUnboxIdx;667} else if (primType == Long.TYPE) {668return longUnboxIdx;669} else if (primType == Float.TYPE) {670return floatUnboxIdx;671} else if (primType == Double.TYPE) {672return doubleUnboxIdx;673}674throw new InternalError("Illegal primitive type " + primType.getName());675}676677protected static final Class<?>[] primitiveTypes = new Class<?>[] {678Boolean.TYPE,679Byte.TYPE,680Character.TYPE,681Short.TYPE,682Integer.TYPE,683Long.TYPE,684Float.TYPE,685Double.TYPE686};687688/** We don't consider "Void" to be a primitive type */689protected static boolean isPrimitive(Class<?> c) {690return (c.isPrimitive() && c != Void.TYPE);691}692693protected int typeSizeInStackSlots(Class<?> c) {694if (c == Void.TYPE) {695return 0;696}697if (c == Long.TYPE || c == Double.TYPE) {698return 2;699}700return 1;701}702703private ClassFileAssembler illegalArgumentCodeBuffer;704protected ClassFileAssembler illegalArgumentCodeBuffer() {705if (illegalArgumentCodeBuffer == null) {706illegalArgumentCodeBuffer = new ClassFileAssembler();707illegalArgumentCodeBuffer.opc_new(illegalArgumentClass);708illegalArgumentCodeBuffer.opc_dup();709illegalArgumentCodeBuffer.opc_invokespecial(illegalArgumentCtorIdx, 0, 0);710illegalArgumentCodeBuffer.opc_athrow();711}712713return illegalArgumentCodeBuffer;714}715}716717718