History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/reflect/AccessorGenerator.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/reflect/AccessorGenerator.java+712−0
@@ -0,0 +1,712 @@
1+/*
2+ * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.reflect;
27+
28+import java.lang.reflect.*;
29+import sun.misc.Unsafe;
30+
31+/** Shared functionality for all accessor generators */
32+
33+class AccessorGenerator implements ClassFileConstants {
34+ static final Unsafe unsafe = Unsafe.getUnsafe();
35+
36+ // Constants because there's no way to say "short integer constant",
37+ // i.e., "1S"
38+ protected static final short S0 = (short) 0;
39+ protected static final short S1 = (short) 1;
40+ protected static final short S2 = (short) 2;
41+ protected static final short S3 = (short) 3;
42+ protected static final short S4 = (short) 4;
43+ protected static final short S5 = (short) 5;
44+ protected static final short S6 = (short) 6;
45+
46+ // Instance variables for shared functionality between
47+ // FieldAccessorGenerator and MethodAccessorGenerator
48+ protected ClassFileAssembler asm;
49+ protected int modifiers;
50+ protected short thisClass;
51+ protected short superClass;
52+ protected short targetClass;
53+ // Common constant pool entries to FieldAccessor and MethodAccessor
54+ protected short throwableClass;
55+ protected short classCastClass;
56+ protected short nullPointerClass;
57+ protected short illegalArgumentClass;
58+ protected short invocationTargetClass;
59+ protected short initIdx;
60+ protected short initNameAndTypeIdx;
61+ protected short initStringNameAndTypeIdx;
62+ protected short nullPointerCtorIdx;
63+ protected short illegalArgumentCtorIdx;
64+ protected short illegalArgumentStringCtorIdx;
65+ protected short invocationTargetCtorIdx;
66+ protected short superCtorIdx;
67+ protected short objectClass;
68+ protected short toStringIdx;
69+ protected short codeIdx;
70+ protected short exceptionsIdx;
71+ // Boxing
72+ protected short booleanIdx;
73+ protected short booleanCtorIdx;
74+ protected short booleanUnboxIdx;
75+ protected short byteIdx;
76+ protected short byteCtorIdx;
77+ protected short byteUnboxIdx;
78+ protected short characterIdx;
79+ protected short characterCtorIdx;
80+ protected short characterUnboxIdx;
81+ protected short doubleIdx;
82+ protected short doubleCtorIdx;
83+ protected short doubleUnboxIdx;
84+ protected short floatIdx;
85+ protected short floatCtorIdx;
86+ protected short floatUnboxIdx;
87+ protected short integerIdx;
88+ protected short integerCtorIdx;
89+ protected short integerUnboxIdx;
90+ protected short longIdx;
91+ protected short longCtorIdx;
92+ protected short longUnboxIdx;
93+ protected short shortIdx;
94+ protected short shortCtorIdx;
95+ protected short shortUnboxIdx;
96+
97+ protected final short NUM_COMMON_CPOOL_ENTRIES = (short) 30;
98+ protected final short NUM_BOXING_CPOOL_ENTRIES = (short) 72;
99+
100+ // Requires that superClass has been set up
101+ protected void emitCommonConstantPoolEntries() {
102+ // + [UTF-8] "java/lang/Throwable"
103+ // + [CONSTANT_Class_info] for above
104+ // + [UTF-8] "java/lang/ClassCastException"
105+ // + [CONSTANT_Class_info] for above
106+ // + [UTF-8] "java/lang/NullPointerException"
107+ // + [CONSTANT_Class_info] for above
108+ // + [UTF-8] "java/lang/IllegalArgumentException"
109+ // + [CONSTANT_Class_info] for above
110+ // + [UTF-8] "java/lang/InvocationTargetException"
111+ // + [CONSTANT_Class_info] for above
112+ // + [UTF-8] "<init>"
113+ // + [UTF-8] "()V"
114+ // + [CONSTANT_NameAndType_info] for above
115+ // + [CONSTANT_Methodref_info] for NullPointerException's constructor
116+ // + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor
117+ // + [UTF-8] "(Ljava/lang/String;)V"
118+ // + [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/String;)V"
119+ // + [CONSTANT_Methodref_info] for IllegalArgumentException's constructor taking a String
120+ // + [UTF-8] "(Ljava/lang/Throwable;)V"
121+ // + [CONSTANT_NameAndType_info] for "<init>(Ljava/lang/Throwable;)V"
122+ // + [CONSTANT_Methodref_info] for InvocationTargetException's constructor
123+ // + [CONSTANT_Methodref_info] for "super()"
124+ // + [UTF-8] "java/lang/Object"
125+ // + [CONSTANT_Class_info] for above
126+ // + [UTF-8] "toString"
127+ // + [UTF-8] "()Ljava/lang/String;"
128+ // + [CONSTANT_NameAndType_info] for "toString()Ljava/lang/String;"
129+ // + [CONSTANT_Methodref_info] for Object's toString method
130+ // + [UTF-8] "Code"
131+ // + [UTF-8] "Exceptions"
132+ asm.emitConstantPoolUTF8("java/lang/Throwable");
133+ asm.emitConstantPoolClass(asm.cpi());
134+ throwableClass = asm.cpi();
135+ asm.emitConstantPoolUTF8("java/lang/ClassCastException");
136+ asm.emitConstantPoolClass(asm.cpi());
137+ classCastClass = asm.cpi();
138+ asm.emitConstantPoolUTF8("java/lang/NullPointerException");
139+ asm.emitConstantPoolClass(asm.cpi());
140+ nullPointerClass = asm.cpi();
141+ asm.emitConstantPoolUTF8("java/lang/IllegalArgumentException");
142+ asm.emitConstantPoolClass(asm.cpi());
143+ illegalArgumentClass = asm.cpi();
144+ asm.emitConstantPoolUTF8("java/lang/reflect/InvocationTargetException");
145+ asm.emitConstantPoolClass(asm.cpi());
146+ invocationTargetClass = asm.cpi();
147+ asm.emitConstantPoolUTF8("<init>");
148+ initIdx = asm.cpi();
149+ asm.emitConstantPoolUTF8("()V");
150+ asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
151+ initNameAndTypeIdx = asm.cpi();
152+ asm.emitConstantPoolMethodref(nullPointerClass, initNameAndTypeIdx);
153+ nullPointerCtorIdx = asm.cpi();
154+ asm.emitConstantPoolMethodref(illegalArgumentClass, initNameAndTypeIdx);
155+ illegalArgumentCtorIdx = asm.cpi();
156+ asm.emitConstantPoolUTF8("(Ljava/lang/String;)V");
157+ asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
158+ initStringNameAndTypeIdx = asm.cpi();
159+ asm.emitConstantPoolMethodref(illegalArgumentClass, initStringNameAndTypeIdx);
160+ illegalArgumentStringCtorIdx = asm.cpi();
161+ asm.emitConstantPoolUTF8("(Ljava/lang/Throwable;)V");
162+ asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
163+ asm.emitConstantPoolMethodref(invocationTargetClass, asm.cpi());
164+ invocationTargetCtorIdx = asm.cpi();
165+ asm.emitConstantPoolMethodref(superClass, initNameAndTypeIdx);
166+ superCtorIdx = asm.cpi();
167+ asm.emitConstantPoolUTF8("java/lang/Object");
168+ asm.emitConstantPoolClass(asm.cpi());
169+ objectClass = asm.cpi();
170+ asm.emitConstantPoolUTF8("toString");
171+ asm.emitConstantPoolUTF8("()Ljava/lang/String;");
172+ asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
173+ asm.emitConstantPoolMethodref(objectClass, asm.cpi());
174+ toStringIdx = asm.cpi();
175+ asm.emitConstantPoolUTF8("Code");
176+ codeIdx = asm.cpi();
177+ asm.emitConstantPoolUTF8("Exceptions");
178+ exceptionsIdx = asm.cpi();
179+ }
180+
181+ /** Constant pool entries required to be able to box/unbox primitive
182+ types. Note that we don't emit these if we don't need them. */
183+ protected void emitBoxingContantPoolEntries() {
184+ // * [UTF-8] "java/lang/Boolean"
185+ // * [CONSTANT_Class_info] for above
186+ // * [UTF-8] "(Z)V"
187+ // * [CONSTANT_NameAndType_info] for above
188+ // * [CONSTANT_Methodref_info] for above
189+ // * [UTF-8] "booleanValue"
190+ // * [UTF-8] "()Z"
191+ // * [CONSTANT_NameAndType_info] for above
192+ // * [CONSTANT_Methodref_info] for above
193+ // * [UTF-8] "java/lang/Byte"
194+ // * [CONSTANT_Class_info] for above
195+ // * [UTF-8] "(B)V"
196+ // * [CONSTANT_NameAndType_info] for above
197+ // * [CONSTANT_Methodref_info] for above
198+ // * [UTF-8] "byteValue"
199+ // * [UTF-8] "()B"
200+ // * [CONSTANT_NameAndType_info] for above
201+ // * [CONSTANT_Methodref_info] for above
202+ // * [UTF-8] "java/lang/Character"
203+ // * [CONSTANT_Class_info] for above
204+ // * [UTF-8] "(C)V"
205+ // * [CONSTANT_NameAndType_info] for above
206+ // * [CONSTANT_Methodref_info] for above
207+ // * [UTF-8] "charValue"
208+ // * [UTF-8] "()C"
209+ // * [CONSTANT_NameAndType_info] for above
210+ // * [CONSTANT_Methodref_info] for above
211+ // * [UTF-8] "java/lang/Double"
212+ // * [CONSTANT_Class_info] for above
213+ // * [UTF-8] "(D)V"
214+ // * [CONSTANT_NameAndType_info] for above
215+ // * [CONSTANT_Methodref_info] for above
216+ // * [UTF-8] "doubleValue"
217+ // * [UTF-8] "()D"
218+ // * [CONSTANT_NameAndType_info] for above
219+ // * [CONSTANT_Methodref_info] for above
220+ // * [UTF-8] "java/lang/Float"
221+ // * [CONSTANT_Class_info] for above
222+ // * [UTF-8] "(F)V"
223+ // * [CONSTANT_NameAndType_info] for above
224+ // * [CONSTANT_Methodref_info] for above
225+ // * [UTF-8] "floatValue"
226+ // * [UTF-8] "()F"
227+ // * [CONSTANT_NameAndType_info] for above
228+ // * [CONSTANT_Methodref_info] for above
229+ // * [UTF-8] "java/lang/Integer"
230+ // * [CONSTANT_Class_info] for above
231+ // * [UTF-8] "(I)V"
232+ // * [CONSTANT_NameAndType_info] for above
233+ // * [CONSTANT_Methodref_info] for above
234+ // * [UTF-8] "intValue"
235+ // * [UTF-8] "()I"
236+ // * [CONSTANT_NameAndType_info] for above
237+ // * [CONSTANT_Methodref_info] for above
238+ // * [UTF-8] "java/lang/Long"
239+ // * [CONSTANT_Class_info] for above
240+ // * [UTF-8] "(J)V"
241+ // * [CONSTANT_NameAndType_info] for above
242+ // * [CONSTANT_Methodref_info] for above
243+ // * [UTF-8] "longValue"
244+ // * [UTF-8] "()J"
245+ // * [CONSTANT_NameAndType_info] for above
246+ // * [CONSTANT_Methodref_info] for above
247+ // * [UTF-8] "java/lang/Short"
248+ // * [CONSTANT_Class_info] for above
249+ // * [UTF-8] "(S)V"
250+ // * [CONSTANT_NameAndType_info] for above
251+ // * [CONSTANT_Methodref_info] for above
252+ // * [UTF-8] "shortValue"
253+ // * [UTF-8] "()S"
254+ // * [CONSTANT_NameAndType_info] for above
255+ // * [CONSTANT_Methodref_info] for above
256+ // Boolean
257+ asm.emitConstantPoolUTF8("java/lang/Boolean");
258+ asm.emitConstantPoolClass(asm.cpi());
259+ booleanIdx = asm.cpi();
260+ asm.emitConstantPoolUTF8("(Z)V");
261+ asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
262+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
263+ booleanCtorIdx = asm.cpi();
264+ asm.emitConstantPoolUTF8("booleanValue");
265+ asm.emitConstantPoolUTF8("()Z");
266+ asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
267+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
268+ booleanUnboxIdx = asm.cpi();
269+
270+ // Byte
271+ asm.emitConstantPoolUTF8("java/lang/Byte");
272+ asm.emitConstantPoolClass(asm.cpi());
273+ byteIdx = asm.cpi();
274+ asm.emitConstantPoolUTF8("(B)V");
275+ asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
276+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
277+ byteCtorIdx = asm.cpi();
278+ asm.emitConstantPoolUTF8("byteValue");
279+ asm.emitConstantPoolUTF8("()B");
280+ asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
281+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
282+ byteUnboxIdx = asm.cpi();
283+
284+ // Character
285+ asm.emitConstantPoolUTF8("java/lang/Character");
286+ asm.emitConstantPoolClass(asm.cpi());
287+ characterIdx = asm.cpi();
288+ asm.emitConstantPoolUTF8("(C)V");
289+ asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
290+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
291+ characterCtorIdx = asm.cpi();
292+ asm.emitConstantPoolUTF8("charValue");
293+ asm.emitConstantPoolUTF8("()C");
294+ asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
295+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
296+ characterUnboxIdx = asm.cpi();
297+
298+ // Double
299+ asm.emitConstantPoolUTF8("java/lang/Double");
300+ asm.emitConstantPoolClass(asm.cpi());
301+ doubleIdx = asm.cpi();
302+ asm.emitConstantPoolUTF8("(D)V");
303+ asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
304+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
305+ doubleCtorIdx = asm.cpi();
306+ asm.emitConstantPoolUTF8("doubleValue");
307+ asm.emitConstantPoolUTF8("()D");
308+ asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
309+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
310+ doubleUnboxIdx = asm.cpi();
311+
312+ // Float
313+ asm.emitConstantPoolUTF8("java/lang/Float");
314+ asm.emitConstantPoolClass(asm.cpi());
315+ floatIdx = asm.cpi();
316+ asm.emitConstantPoolUTF8("(F)V");
317+ asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
318+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
319+ floatCtorIdx = asm.cpi();
320+ asm.emitConstantPoolUTF8("floatValue");
321+ asm.emitConstantPoolUTF8("()F");
322+ asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
323+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
324+ floatUnboxIdx = asm.cpi();
325+
326+ // Integer
327+ asm.emitConstantPoolUTF8("java/lang/Integer");
328+ asm.emitConstantPoolClass(asm.cpi());
329+ integerIdx = asm.cpi();
330+ asm.emitConstantPoolUTF8("(I)V");
331+ asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
332+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
333+ integerCtorIdx = asm.cpi();
334+ asm.emitConstantPoolUTF8("intValue");
335+ asm.emitConstantPoolUTF8("()I");
336+ asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
337+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
338+ integerUnboxIdx = asm.cpi();
339+
340+ // Long
341+ asm.emitConstantPoolUTF8("java/lang/Long");
342+ asm.emitConstantPoolClass(asm.cpi());
343+ longIdx = asm.cpi();
344+ asm.emitConstantPoolUTF8("(J)V");
345+ asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
346+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
347+ longCtorIdx = asm.cpi();
348+ asm.emitConstantPoolUTF8("longValue");
349+ asm.emitConstantPoolUTF8("()J");
350+ asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
351+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
352+ longUnboxIdx = asm.cpi();
353+
354+ // Short
355+ asm.emitConstantPoolUTF8("java/lang/Short");
356+ asm.emitConstantPoolClass(asm.cpi());
357+ shortIdx = asm.cpi();
358+ asm.emitConstantPoolUTF8("(S)V");
359+ asm.emitConstantPoolNameAndType(initIdx, asm.cpi());
360+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S2), asm.cpi());
361+ shortCtorIdx = asm.cpi();
362+ asm.emitConstantPoolUTF8("shortValue");
363+ asm.emitConstantPoolUTF8("()S");
364+ asm.emitConstantPoolNameAndType(sub(asm.cpi(), S1), asm.cpi());
365+ asm.emitConstantPoolMethodref(sub(asm.cpi(), S6), asm.cpi());
366+ shortUnboxIdx = asm.cpi();
367+ }
368+
369+ // Necessary because of Java's annoying promotion rules
370+ protected static short add(short s1, short s2) {
371+ return (short) (s1 + s2);
372+ }
373+
374+ protected static short sub(short s1, short s2) {
375+ return (short) (s1 - s2);
376+ }
377+
378+ protected boolean isStatic() {
379+ return Modifier.isStatic(modifiers);
380+ }
381+
382+ /** Returns class name in "internal" form (i.e., '/' separators
383+ instead of '.') */
384+ protected static String getClassName
385+ (Class c, boolean addPrefixAndSuffixForNonPrimitiveTypes)
386+ {
387+ if (c.isPrimitive()) {
388+ if (c == Boolean.TYPE) {
389+ return "Z";
390+ } else if (c == Byte.TYPE) {
391+ return "B";
392+ } else if (c == Character.TYPE) {
393+ return "C";
394+ } else if (c == Double.TYPE) {
395+ return "D";
396+ } else if (c == Float.TYPE) {
397+ return "F";
398+ } else if (c == Integer.TYPE) {
399+ return "I";
400+ } else if (c == Long.TYPE) {
401+ return "J";
402+ } else if (c == Short.TYPE) {
403+ return "S";
404+ } else if (c == Void.TYPE) {
405+ return "V";
406+ }
407+ throw new InternalError("Should have found primitive type");
408+ } else if (c.isArray()) {
409+ return "[" + getClassName(c.getComponentType(), true);
410+ } else {
411+ if (addPrefixAndSuffixForNonPrimitiveTypes) {
412+ return internalize("L" + c.getName() + ";");
413+ } else {
414+ return internalize(c.getName());
415+ }
416+ }
417+ }
418+
419+ private static String internalize(String className) {
420+ return className.replace('.', '/');
421+ }
422+
423+ protected void emitConstructor() {
424+ // Generate code into fresh code buffer
425+ ClassFileAssembler cb = new ClassFileAssembler();
426+ // 0 incoming arguments
427+ cb.setMaxLocals(1);
428+ cb.opc_aload_0();
429+ cb.opc_invokespecial(superCtorIdx, 0, 0);
430+ cb.opc_return();
431+
432+ // Emit method
433+ emitMethod(initIdx, cb.getMaxLocals(), cb, null, null);
434+ }
435+
436+ // The descriptor's index in the constant pool must be (1 +
437+ // nameIdx). "numArgs" must indicate ALL arguments, including the
438+ // implicit "this" argument; double and long arguments each count
439+ // as 2 in this count. The code buffer must NOT contain the code
440+ // length. The exception table may be null, but if non-null must
441+ // NOT contain the exception table's length. The checked exception
442+ // indices may be null.
443+ protected void emitMethod(short nameIdx,
444+ int numArgs,
445+ ClassFileAssembler code,
446+ ClassFileAssembler exceptionTable,
447+ short[] checkedExceptionIndices)
448+ {
449+ int codeLen = code.getLength();
450+ int excLen = 0;
451+ if (exceptionTable != null) {
452+ excLen = exceptionTable.getLength();
453+ if ((excLen % 8) != 0) {
454+ throw new IllegalArgumentException("Illegal exception table");
455+ }
456+ }
457+ int attrLen = 12 + codeLen + excLen;
458+ excLen = excLen / 8; // No-op if no exception table
459+
460+ asm.emitShort(ACC_PUBLIC);
461+ asm.emitShort(nameIdx);
462+ asm.emitShort(add(nameIdx, S1));
463+ if (checkedExceptionIndices == null) {
464+ // Code attribute only
465+ asm.emitShort(S1);
466+ } else {
467+ // Code and Exceptions attributes
468+ asm.emitShort(S2);
469+ }
470+ // Code attribute
471+ asm.emitShort(codeIdx);
472+ asm.emitInt(attrLen);
473+ asm.emitShort(code.getMaxStack());
474+ asm.emitShort((short) Math.max(numArgs, code.getMaxLocals()));
475+ asm.emitInt(codeLen);
476+ asm.append(code);
477+ asm.emitShort((short) excLen);
478+ if (exceptionTable != null) {
479+ asm.append(exceptionTable);
480+ }
481+ asm.emitShort(S0); // No additional attributes for Code attribute
482+ if (checkedExceptionIndices != null) {
483+ // Exceptions attribute
484+ asm.emitShort(exceptionsIdx);
485+ asm.emitInt(2 + 2 * checkedExceptionIndices.length);
486+ asm.emitShort((short) checkedExceptionIndices.length);
487+ for (int i = 0; i < checkedExceptionIndices.length; i++) {
488+ asm.emitShort(checkedExceptionIndices[i]);
489+ }
490+ }
491+ }
492+
493+ protected short indexForPrimitiveType(Class type) {
494+ if (type == Boolean.TYPE) {
495+ return booleanIdx;
496+ } else if (type == Byte.TYPE) {
497+ return byteIdx;
498+ } else if (type == Character.TYPE) {
499+ return characterIdx;
500+ } else if (type == Double.TYPE) {
501+ return doubleIdx;
502+ } else if (type == Float.TYPE) {
503+ return floatIdx;
504+ } else if (type == Integer.TYPE) {
505+ return integerIdx;
506+ } else if (type == Long.TYPE) {
507+ return longIdx;
508+ } else if (type == Short.TYPE) {
509+ return shortIdx;
510+ }
511+ throw new InternalError("Should have found primitive type");
512+ }
513+
514+ protected short ctorIndexForPrimitiveType(Class type) {
515+ if (type == Boolean.TYPE) {
516+ return booleanCtorIdx;
517+ } else if (type == Byte.TYPE) {
518+ return byteCtorIdx;
519+ } else if (type == Character.TYPE) {
520+ return characterCtorIdx;
521+ } else if (type == Double.TYPE) {
522+ return doubleCtorIdx;
523+ } else if (type == Float.TYPE) {
524+ return floatCtorIdx;
525+ } else if (type == Integer.TYPE) {
526+ return integerCtorIdx;
527+ } else if (type == Long.TYPE) {
528+ return longCtorIdx;
529+ } else if (type == Short.TYPE) {
530+ return shortCtorIdx;
531+ }
532+ throw new InternalError("Should have found primitive type");
533+ }
534+
535+ /** Returns true for widening or identity conversions for primitive
536+ types only */
537+ protected static boolean canWidenTo(Class type, Class otherType) {
538+ if (!type.isPrimitive()) {
539+ return false;
540+ }
541+
542+ // Widening conversions (from JVM spec):
543+ // byte to short, int, long, float, or double
544+ // short to int, long, float, or double
545+ // char to int, long, float, or double
546+ // int to long, float, or double
547+ // long to float or double
548+ // float to double
549+
550+ if (type == Boolean.TYPE) {
551+ if (otherType == Boolean.TYPE) {
552+ return true;
553+ }
554+ } else if (type == Byte.TYPE) {
555+ if ( otherType == Byte.TYPE
556+ || otherType == Short.TYPE
557+ || otherType == Integer.TYPE
558+ || otherType == Long.TYPE
559+ || otherType == Float.TYPE
560+ || otherType == Double.TYPE) {
561+ return true;
562+ }
563+ } else if (type == Short.TYPE) {
564+ if ( otherType == Short.TYPE
565+ || otherType == Integer.TYPE
566+ || otherType == Long.TYPE
567+ || otherType == Float.TYPE
568+ || otherType == Double.TYPE) {
569+ return true;
570+ }
571+ } else if (type == Character.TYPE) {
572+ if ( otherType == Character.TYPE
573+ || otherType == Integer.TYPE
574+ || otherType == Long.TYPE
575+ || otherType == Float.TYPE
576+ || otherType == Double.TYPE) {
577+ return true;
578+ }
579+ } else if (type == Integer.TYPE) {
580+ if ( otherType == Integer.TYPE
581+ || otherType == Long.TYPE
582+ || otherType == Float.TYPE
583+ || otherType == Double.TYPE) {
584+ return true;
585+ }
586+ } else if (type == Long.TYPE) {
587+ if ( otherType == Long.TYPE
588+ || otherType == Float.TYPE
589+ || otherType == Double.TYPE) {
590+ return true;
591+ }
592+ } else if (type == Float.TYPE) {
593+ if ( otherType == Float.TYPE
594+ || otherType == Double.TYPE) {
595+ return true;
596+ }
597+ } else if (type == Double.TYPE) {
598+ if (otherType == Double.TYPE) {
599+ return true;
600+ }
601+ }
602+
603+ return false;
604+ }
605+
606+ /** Emits the widening bytecode for the given primitive conversion
607+ (or none if the identity conversion). Requires that a primitive
608+ conversion exists; i.e., canWidenTo must have already been
609+ called and returned true. */
610+ protected static void emitWideningBytecodeForPrimitiveConversion
611+ (ClassFileAssembler cb,
612+ Class fromType,
613+ Class toType)
614+ {
615+ // Note that widening conversions for integral types (i.e., "b2s",
616+ // "s2i") are no-ops since values on the Java stack are
617+ // sign-extended.
618+
619+ // Widening conversions (from JVM spec):
620+ // byte to short, int, long, float, or double
621+ // short to int, long, float, or double
622+ // char to int, long, float, or double
623+ // int to long, float, or double
624+ // long to float or double
625+ // float to double
626+
627+ if ( fromType == Byte.TYPE
628+ || fromType == Short.TYPE
629+ || fromType == Character.TYPE
630+ || fromType == Integer.TYPE) {
631+ if (toType == Long.TYPE) {
632+ cb.opc_i2l();
633+ } else if (toType == Float.TYPE) {
634+ cb.opc_i2f();
635+ } else if (toType == Double.TYPE) {
636+ cb.opc_i2d();
637+ }
638+ } else if (fromType == Long.TYPE) {
639+ if (toType == Float.TYPE) {
640+ cb.opc_l2f();
641+ } else if (toType == Double.TYPE) {
642+ cb.opc_l2d();
643+ }
644+ } else if (fromType == Float.TYPE) {
645+ if (toType == Double.TYPE) {
646+ cb.opc_f2d();
647+ }
648+ }
649+
650+ // Otherwise, was identity or no-op conversion. Fall through.
651+ }
652+
653+ protected short unboxingMethodForPrimitiveType(Class primType) {
654+ if (primType == Boolean.TYPE) {
655+ return booleanUnboxIdx;
656+ } else if (primType == Byte.TYPE) {
657+ return byteUnboxIdx;
658+ } else if (primType == Character.TYPE) {
659+ return characterUnboxIdx;
660+ } else if (primType == Short.TYPE) {
661+ return shortUnboxIdx;
662+ } else if (primType == Integer.TYPE) {
663+ return integerUnboxIdx;
664+ } else if (primType == Long.TYPE) {
665+ return longUnboxIdx;
666+ } else if (primType == Float.TYPE) {
667+ return floatUnboxIdx;
668+ } else if (primType == Double.TYPE) {
669+ return doubleUnboxIdx;
670+ }
671+ throw new InternalError("Illegal primitive type " + primType.getName());
672+ }
673+
674+ protected static final Class[] primitiveTypes = new Class[] {
675+ Boolean.TYPE,
676+ Byte.TYPE,
677+ Character.TYPE,
678+ Short.TYPE,
679+ Integer.TYPE,
680+ Long.TYPE,
681+ Float.TYPE,
682+ Double.TYPE
683+ };
684+
685+ /** We don't consider "Void" to be a primitive type */
686+ protected static boolean isPrimitive(Class c) {
687+ return (c.isPrimitive() && c != Void.TYPE);
688+ }
689+
690+ protected int typeSizeInStackSlots(Class c) {
691+ if (c == Void.TYPE) {
692+ return 0;
693+ }
694+ if (c == Long.TYPE || c == Double.TYPE) {
695+ return 2;
696+ }
697+ return 1;
698+ }
699+
700+ private ClassFileAssembler illegalArgumentCodeBuffer;
701+ protected ClassFileAssembler illegalArgumentCodeBuffer() {
702+ if (illegalArgumentCodeBuffer == null) {
703+ illegalArgumentCodeBuffer = new ClassFileAssembler();
704+ illegalArgumentCodeBuffer.opc_new(illegalArgumentClass);
705+ illegalArgumentCodeBuffer.opc_dup();
706+ illegalArgumentCodeBuffer.opc_invokespecial(illegalArgumentCtorIdx, 0, 0);
707+ illegalArgumentCodeBuffer.opc_athrow();
708+ }
709+
710+ return illegalArgumentCodeBuffer;
711+ }
712+}