Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/reflect/AccessorGenerator.java
38829 views
1
/*
2
* Copyright (c) 2001, 2013, 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
protected boolean isPrivate() {
383
return Modifier.isPrivate(modifiers);
384
}
385
386
/** Returns class name in "internal" form (i.e., '/' separators
387
instead of '.') */
388
protected static String getClassName
389
(Class<?> c, boolean addPrefixAndSuffixForNonPrimitiveTypes)
390
{
391
if (c.isPrimitive()) {
392
if (c == Boolean.TYPE) {
393
return "Z";
394
} else if (c == Byte.TYPE) {
395
return "B";
396
} else if (c == Character.TYPE) {
397
return "C";
398
} else if (c == Double.TYPE) {
399
return "D";
400
} else if (c == Float.TYPE) {
401
return "F";
402
} else if (c == Integer.TYPE) {
403
return "I";
404
} else if (c == Long.TYPE) {
405
return "J";
406
} else if (c == Short.TYPE) {
407
return "S";
408
} else if (c == Void.TYPE) {
409
return "V";
410
}
411
throw new InternalError("Should have found primitive type");
412
} else if (c.isArray()) {
413
return "[" + getClassName(c.getComponentType(), true);
414
} else {
415
if (addPrefixAndSuffixForNonPrimitiveTypes) {
416
return internalize("L" + c.getName() + ";");
417
} else {
418
return internalize(c.getName());
419
}
420
}
421
}
422
423
private static String internalize(String className) {
424
return className.replace('.', '/');
425
}
426
427
protected void emitConstructor() {
428
// Generate code into fresh code buffer
429
ClassFileAssembler cb = new ClassFileAssembler();
430
// 0 incoming arguments
431
cb.setMaxLocals(1);
432
cb.opc_aload_0();
433
cb.opc_invokespecial(superCtorIdx, 0, 0);
434
cb.opc_return();
435
436
// Emit method
437
emitMethod(initIdx, cb.getMaxLocals(), cb, null, null);
438
}
439
440
// The descriptor's index in the constant pool must be (1 +
441
// nameIdx). "numArgs" must indicate ALL arguments, including the
442
// implicit "this" argument; double and long arguments each count
443
// as 2 in this count. The code buffer must NOT contain the code
444
// length. The exception table may be null, but if non-null must
445
// NOT contain the exception table's length. The checked exception
446
// indices may be null.
447
protected void emitMethod(short nameIdx,
448
int numArgs,
449
ClassFileAssembler code,
450
ClassFileAssembler exceptionTable,
451
short[] checkedExceptionIndices)
452
{
453
int codeLen = code.getLength();
454
int excLen = 0;
455
if (exceptionTable != null) {
456
excLen = exceptionTable.getLength();
457
if ((excLen % 8) != 0) {
458
throw new IllegalArgumentException("Illegal exception table");
459
}
460
}
461
int attrLen = 12 + codeLen + excLen;
462
excLen = excLen / 8; // No-op if no exception table
463
464
asm.emitShort(ACC_PUBLIC);
465
asm.emitShort(nameIdx);
466
asm.emitShort(add(nameIdx, S1));
467
if (checkedExceptionIndices == null) {
468
// Code attribute only
469
asm.emitShort(S1);
470
} else {
471
// Code and Exceptions attributes
472
asm.emitShort(S2);
473
}
474
// Code attribute
475
asm.emitShort(codeIdx);
476
asm.emitInt(attrLen);
477
asm.emitShort(code.getMaxStack());
478
asm.emitShort((short) Math.max(numArgs, code.getMaxLocals()));
479
asm.emitInt(codeLen);
480
asm.append(code);
481
asm.emitShort((short) excLen);
482
if (exceptionTable != null) {
483
asm.append(exceptionTable);
484
}
485
asm.emitShort(S0); // No additional attributes for Code attribute
486
if (checkedExceptionIndices != null) {
487
// Exceptions attribute
488
asm.emitShort(exceptionsIdx);
489
asm.emitInt(2 + 2 * checkedExceptionIndices.length);
490
asm.emitShort((short) checkedExceptionIndices.length);
491
for (int i = 0; i < checkedExceptionIndices.length; i++) {
492
asm.emitShort(checkedExceptionIndices[i]);
493
}
494
}
495
}
496
497
protected short indexForPrimitiveType(Class<?> type) {
498
if (type == Boolean.TYPE) {
499
return booleanIdx;
500
} else if (type == Byte.TYPE) {
501
return byteIdx;
502
} else if (type == Character.TYPE) {
503
return characterIdx;
504
} else if (type == Double.TYPE) {
505
return doubleIdx;
506
} else if (type == Float.TYPE) {
507
return floatIdx;
508
} else if (type == Integer.TYPE) {
509
return integerIdx;
510
} else if (type == Long.TYPE) {
511
return longIdx;
512
} else if (type == Short.TYPE) {
513
return shortIdx;
514
}
515
throw new InternalError("Should have found primitive type");
516
}
517
518
protected short ctorIndexForPrimitiveType(Class<?> type) {
519
if (type == Boolean.TYPE) {
520
return booleanCtorIdx;
521
} else if (type == Byte.TYPE) {
522
return byteCtorIdx;
523
} else if (type == Character.TYPE) {
524
return characterCtorIdx;
525
} else if (type == Double.TYPE) {
526
return doubleCtorIdx;
527
} else if (type == Float.TYPE) {
528
return floatCtorIdx;
529
} else if (type == Integer.TYPE) {
530
return integerCtorIdx;
531
} else if (type == Long.TYPE) {
532
return longCtorIdx;
533
} else if (type == Short.TYPE) {
534
return shortCtorIdx;
535
}
536
throw new InternalError("Should have found primitive type");
537
}
538
539
/** Returns true for widening or identity conversions for primitive
540
types only */
541
protected static boolean canWidenTo(Class<?> type, Class<?> otherType) {
542
if (!type.isPrimitive()) {
543
return false;
544
}
545
546
// Widening conversions (from JVM spec):
547
// byte to short, int, long, float, or double
548
// short to int, long, float, or double
549
// char to int, long, float, or double
550
// int to long, float, or double
551
// long to float or double
552
// float to double
553
554
if (type == Boolean.TYPE) {
555
if (otherType == Boolean.TYPE) {
556
return true;
557
}
558
} else if (type == Byte.TYPE) {
559
if ( otherType == Byte.TYPE
560
|| otherType == Short.TYPE
561
|| otherType == Integer.TYPE
562
|| otherType == Long.TYPE
563
|| otherType == Float.TYPE
564
|| otherType == Double.TYPE) {
565
return true;
566
}
567
} else if (type == Short.TYPE) {
568
if ( otherType == Short.TYPE
569
|| otherType == Integer.TYPE
570
|| otherType == Long.TYPE
571
|| otherType == Float.TYPE
572
|| otherType == Double.TYPE) {
573
return true;
574
}
575
} else if (type == Character.TYPE) {
576
if ( otherType == Character.TYPE
577
|| otherType == Integer.TYPE
578
|| otherType == Long.TYPE
579
|| otherType == Float.TYPE
580
|| otherType == Double.TYPE) {
581
return true;
582
}
583
} else if (type == Integer.TYPE) {
584
if ( otherType == Integer.TYPE
585
|| otherType == Long.TYPE
586
|| otherType == Float.TYPE
587
|| otherType == Double.TYPE) {
588
return true;
589
}
590
} else if (type == Long.TYPE) {
591
if ( otherType == Long.TYPE
592
|| otherType == Float.TYPE
593
|| otherType == Double.TYPE) {
594
return true;
595
}
596
} else if (type == Float.TYPE) {
597
if ( otherType == Float.TYPE
598
|| otherType == Double.TYPE) {
599
return true;
600
}
601
} else if (type == Double.TYPE) {
602
if (otherType == Double.TYPE) {
603
return true;
604
}
605
}
606
607
return false;
608
}
609
610
/** Emits the widening bytecode for the given primitive conversion
611
(or none if the identity conversion). Requires that a primitive
612
conversion exists; i.e., canWidenTo must have already been
613
called and returned true. */
614
protected static void emitWideningBytecodeForPrimitiveConversion
615
(ClassFileAssembler cb,
616
Class<?> fromType,
617
Class<?> toType)
618
{
619
// Note that widening conversions for integral types (i.e., "b2s",
620
// "s2i") are no-ops since values on the Java stack are
621
// sign-extended.
622
623
// Widening conversions (from JVM spec):
624
// byte to short, int, long, float, or double
625
// short to int, long, float, or double
626
// char to int, long, float, or double
627
// int to long, float, or double
628
// long to float or double
629
// float to double
630
631
if ( fromType == Byte.TYPE
632
|| fromType == Short.TYPE
633
|| fromType == Character.TYPE
634
|| fromType == Integer.TYPE) {
635
if (toType == Long.TYPE) {
636
cb.opc_i2l();
637
} else if (toType == Float.TYPE) {
638
cb.opc_i2f();
639
} else if (toType == Double.TYPE) {
640
cb.opc_i2d();
641
}
642
} else if (fromType == Long.TYPE) {
643
if (toType == Float.TYPE) {
644
cb.opc_l2f();
645
} else if (toType == Double.TYPE) {
646
cb.opc_l2d();
647
}
648
} else if (fromType == Float.TYPE) {
649
if (toType == Double.TYPE) {
650
cb.opc_f2d();
651
}
652
}
653
654
// Otherwise, was identity or no-op conversion. Fall through.
655
}
656
657
protected short unboxingMethodForPrimitiveType(Class<?> primType) {
658
if (primType == Boolean.TYPE) {
659
return booleanUnboxIdx;
660
} else if (primType == Byte.TYPE) {
661
return byteUnboxIdx;
662
} else if (primType == Character.TYPE) {
663
return characterUnboxIdx;
664
} else if (primType == Short.TYPE) {
665
return shortUnboxIdx;
666
} else if (primType == Integer.TYPE) {
667
return integerUnboxIdx;
668
} else if (primType == Long.TYPE) {
669
return longUnboxIdx;
670
} else if (primType == Float.TYPE) {
671
return floatUnboxIdx;
672
} else if (primType == Double.TYPE) {
673
return doubleUnboxIdx;
674
}
675
throw new InternalError("Illegal primitive type " + primType.getName());
676
}
677
678
protected static final Class<?>[] primitiveTypes = new Class<?>[] {
679
Boolean.TYPE,
680
Byte.TYPE,
681
Character.TYPE,
682
Short.TYPE,
683
Integer.TYPE,
684
Long.TYPE,
685
Float.TYPE,
686
Double.TYPE
687
};
688
689
/** We don't consider "Void" to be a primitive type */
690
protected static boolean isPrimitive(Class<?> c) {
691
return (c.isPrimitive() && c != Void.TYPE);
692
}
693
694
protected int typeSizeInStackSlots(Class<?> c) {
695
if (c == Void.TYPE) {
696
return 0;
697
}
698
if (c == Long.TYPE || c == Double.TYPE) {
699
return 2;
700
}
701
return 1;
702
}
703
704
private ClassFileAssembler illegalArgumentCodeBuffer;
705
protected ClassFileAssembler illegalArgumentCodeBuffer() {
706
if (illegalArgumentCodeBuffer == null) {
707
illegalArgumentCodeBuffer = new ClassFileAssembler();
708
illegalArgumentCodeBuffer.opc_new(illegalArgumentClass);
709
illegalArgumentCodeBuffer.opc_dup();
710
illegalArgumentCodeBuffer.opc_invokespecial(illegalArgumentCtorIdx, 0, 0);
711
illegalArgumentCodeBuffer.opc_athrow();
712
}
713
714
return illegalArgumentCodeBuffer;
715
}
716
}
717
718