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
26package sun.reflect;
27
28import java.lang.reflect.*;
29import sun.misc.Unsafe;
30
31/** Shared functionality for all accessor generators */
32
33class 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}