Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/langtools/src/share/classes/com/sun/tools/classfile/ConstantPool.java
38899 views
1
/*
2
* Copyright (c) 2007, 2011, 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 com.sun.tools.classfile;
27
28
import java.io.DataOutputStream;
29
import java.io.IOException;
30
import java.io.OutputStream;
31
import java.util.Iterator;
32
33
/**
34
* See JVMS, section 4.5.
35
*
36
* <p><b>This is NOT part of any supported API.
37
* If you write code that depends on this, you do so at your own risk.
38
* This code and its internal interfaces are subject to change or
39
* deletion without notice.</b>
40
*/
41
public class ConstantPool {
42
43
public static class InvalidIndex extends ConstantPoolException {
44
private static final long serialVersionUID = -4350294289300939730L;
45
InvalidIndex(int index) {
46
super(index);
47
}
48
49
@Override
50
public String getMessage() {
51
// i18n
52
return "invalid index #" + index;
53
}
54
}
55
56
public static class UnexpectedEntry extends ConstantPoolException {
57
private static final long serialVersionUID = 6986335935377933211L;
58
UnexpectedEntry(int index, int expected_tag, int found_tag) {
59
super(index);
60
this.expected_tag = expected_tag;
61
this.found_tag = found_tag;
62
}
63
64
@Override
65
public String getMessage() {
66
// i18n?
67
return "unexpected entry at #" + index + " -- expected tag " + expected_tag + ", found " + found_tag;
68
}
69
70
public final int expected_tag;
71
public final int found_tag;
72
}
73
74
public static class InvalidEntry extends ConstantPoolException {
75
private static final long serialVersionUID = 1000087545585204447L;
76
InvalidEntry(int index, int tag) {
77
super(index);
78
this.tag = tag;
79
}
80
81
@Override
82
public String getMessage() {
83
// i18n?
84
return "unexpected tag at #" + index + ": " + tag;
85
}
86
87
public final int tag;
88
}
89
90
public static class EntryNotFound extends ConstantPoolException {
91
private static final long serialVersionUID = 2885537606468581850L;
92
EntryNotFound(Object value) {
93
super(-1);
94
this.value = value;
95
}
96
97
@Override
98
public String getMessage() {
99
// i18n?
100
return "value not found: " + value;
101
}
102
103
public final Object value;
104
}
105
106
public static final int CONSTANT_Utf8 = 1;
107
public static final int CONSTANT_Integer = 3;
108
public static final int CONSTANT_Float = 4;
109
public static final int CONSTANT_Long = 5;
110
public static final int CONSTANT_Double = 6;
111
public static final int CONSTANT_Class = 7;
112
public static final int CONSTANT_String = 8;
113
public static final int CONSTANT_Fieldref = 9;
114
public static final int CONSTANT_Methodref = 10;
115
public static final int CONSTANT_InterfaceMethodref = 11;
116
public static final int CONSTANT_NameAndType = 12;
117
public static final int CONSTANT_MethodHandle = 15;
118
public static final int CONSTANT_MethodType = 16;
119
public static final int CONSTANT_InvokeDynamic = 18;
120
121
public static enum RefKind {
122
REF_getField(1, "getfield"),
123
REF_getStatic(2, "getstatic"),
124
REF_putField(3, "putfield"),
125
REF_putStatic(4, "putstatic"),
126
REF_invokeVirtual(5, "invokevirtual"),
127
REF_invokeStatic(6, "invokestatic"),
128
REF_invokeSpecial(7, "invokespecial"),
129
REF_newInvokeSpecial(8, "newinvokespecial"),
130
REF_invokeInterface(9, "invokeinterface");
131
132
public final int tag;
133
public final String name;
134
135
RefKind(int tag, String name) {
136
this.tag = tag;
137
this.name = name;
138
}
139
140
static RefKind getRefkind(int tag) {
141
switch(tag) {
142
case 1:
143
return REF_getField;
144
case 2:
145
return REF_getStatic;
146
case 3:
147
return REF_putField;
148
case 4:
149
return REF_putStatic;
150
case 5:
151
return REF_invokeVirtual;
152
case 6:
153
return REF_invokeStatic;
154
case 7:
155
return REF_invokeSpecial;
156
case 8:
157
return REF_newInvokeSpecial;
158
case 9:
159
return REF_invokeInterface;
160
default:
161
return null;
162
}
163
}
164
}
165
166
ConstantPool(ClassReader cr) throws IOException, InvalidEntry {
167
int count = cr.readUnsignedShort();
168
pool = new CPInfo[count];
169
for (int i = 1; i < count; i++) {
170
int tag = cr.readUnsignedByte();
171
switch (tag) {
172
case CONSTANT_Class:
173
pool[i] = new CONSTANT_Class_info(this, cr);
174
break;
175
176
case CONSTANT_Double:
177
pool[i] = new CONSTANT_Double_info(cr);
178
i++;
179
break;
180
181
case CONSTANT_Fieldref:
182
pool[i] = new CONSTANT_Fieldref_info(this, cr);
183
break;
184
185
case CONSTANT_Float:
186
pool[i] = new CONSTANT_Float_info(cr);
187
break;
188
189
case CONSTANT_Integer:
190
pool[i] = new CONSTANT_Integer_info(cr);
191
break;
192
193
case CONSTANT_InterfaceMethodref:
194
pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr);
195
break;
196
197
case CONSTANT_InvokeDynamic:
198
pool[i] = new CONSTANT_InvokeDynamic_info(this, cr);
199
break;
200
201
case CONSTANT_Long:
202
pool[i] = new CONSTANT_Long_info(cr);
203
i++;
204
break;
205
206
case CONSTANT_MethodHandle:
207
pool[i] = new CONSTANT_MethodHandle_info(this, cr);
208
break;
209
210
case CONSTANT_MethodType:
211
pool[i] = new CONSTANT_MethodType_info(this, cr);
212
break;
213
214
case CONSTANT_Methodref:
215
pool[i] = new CONSTANT_Methodref_info(this, cr);
216
break;
217
218
case CONSTANT_NameAndType:
219
pool[i] = new CONSTANT_NameAndType_info(this, cr);
220
break;
221
222
case CONSTANT_String:
223
pool[i] = new CONSTANT_String_info(this, cr);
224
break;
225
226
case CONSTANT_Utf8:
227
pool[i] = new CONSTANT_Utf8_info(cr);
228
break;
229
230
default:
231
throw new InvalidEntry(i, tag);
232
}
233
}
234
}
235
236
public ConstantPool(CPInfo[] pool) {
237
this.pool = pool;
238
}
239
240
public int size() {
241
return pool.length;
242
}
243
244
public int byteLength() {
245
int length = 2;
246
for (int i = 1; i < size(); ) {
247
CPInfo cpInfo = pool[i];
248
length += cpInfo.byteLength();
249
i += cpInfo.size();
250
}
251
return length;
252
}
253
254
public CPInfo get(int index) throws InvalidIndex {
255
if (index <= 0 || index >= pool.length)
256
throw new InvalidIndex(index);
257
CPInfo info = pool[index];
258
if (info == null) {
259
// this occurs for indices referencing the "second half" of an
260
// 8 byte constant, such as CONSTANT_Double or CONSTANT_Long
261
throw new InvalidIndex(index);
262
}
263
return pool[index];
264
}
265
266
private CPInfo get(int index, int expected_type) throws InvalidIndex, UnexpectedEntry {
267
CPInfo info = get(index);
268
if (info.getTag() != expected_type)
269
throw new UnexpectedEntry(index, expected_type, info.getTag());
270
return info;
271
}
272
273
public CONSTANT_Utf8_info getUTF8Info(int index) throws InvalidIndex, UnexpectedEntry {
274
return ((CONSTANT_Utf8_info) get(index, CONSTANT_Utf8));
275
}
276
277
public CONSTANT_Class_info getClassInfo(int index) throws InvalidIndex, UnexpectedEntry {
278
return ((CONSTANT_Class_info) get(index, CONSTANT_Class));
279
}
280
281
public CONSTANT_NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry {
282
return ((CONSTANT_NameAndType_info) get(index, CONSTANT_NameAndType));
283
}
284
285
public String getUTF8Value(int index) throws InvalidIndex, UnexpectedEntry {
286
return getUTF8Info(index).value;
287
}
288
289
public int getUTF8Index(String value) throws EntryNotFound {
290
for (int i = 1; i < pool.length; i++) {
291
CPInfo info = pool[i];
292
if (info instanceof CONSTANT_Utf8_info &&
293
((CONSTANT_Utf8_info) info).value.equals(value))
294
return i;
295
}
296
throw new EntryNotFound(value);
297
}
298
299
public Iterable<CPInfo> entries() {
300
return new Iterable<CPInfo>() {
301
public Iterator<CPInfo> iterator() {
302
return new Iterator<CPInfo>() {
303
304
public boolean hasNext() {
305
return next < pool.length;
306
}
307
308
public CPInfo next() {
309
current = pool[next];
310
switch (current.getTag()) {
311
case CONSTANT_Double:
312
case CONSTANT_Long:
313
next += 2;
314
break;
315
default:
316
next += 1;
317
}
318
return current;
319
}
320
321
public void remove() {
322
throw new UnsupportedOperationException();
323
}
324
325
private CPInfo current;
326
private int next = 1;
327
328
};
329
}
330
};
331
}
332
333
private CPInfo[] pool;
334
335
public interface Visitor<R,P> {
336
R visitClass(CONSTANT_Class_info info, P p);
337
R visitDouble(CONSTANT_Double_info info, P p);
338
R visitFieldref(CONSTANT_Fieldref_info info, P p);
339
R visitFloat(CONSTANT_Float_info info, P p);
340
R visitInteger(CONSTANT_Integer_info info, P p);
341
R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);
342
R visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, P p);
343
R visitLong(CONSTANT_Long_info info, P p);
344
R visitNameAndType(CONSTANT_NameAndType_info info, P p);
345
R visitMethodref(CONSTANT_Methodref_info info, P p);
346
R visitMethodHandle(CONSTANT_MethodHandle_info info, P p);
347
R visitMethodType(CONSTANT_MethodType_info info, P p);
348
R visitString(CONSTANT_String_info info, P p);
349
R visitUtf8(CONSTANT_Utf8_info info, P p);
350
}
351
352
public static abstract class CPInfo {
353
CPInfo() {
354
this.cp = null;
355
}
356
357
CPInfo(ConstantPool cp) {
358
this.cp = cp;
359
}
360
361
public abstract int getTag();
362
363
/** The number of slots in the constant pool used by this entry.
364
* 2 for CONSTANT_Double and CONSTANT_Long; 1 for everything else. */
365
public int size() {
366
return 1;
367
}
368
369
public abstract int byteLength();
370
371
public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
372
373
protected final ConstantPool cp;
374
}
375
376
public static abstract class CPRefInfo extends CPInfo {
377
protected CPRefInfo(ConstantPool cp, ClassReader cr, int tag) throws IOException {
378
super(cp);
379
this.tag = tag;
380
class_index = cr.readUnsignedShort();
381
name_and_type_index = cr.readUnsignedShort();
382
}
383
384
protected CPRefInfo(ConstantPool cp, int tag, int class_index, int name_and_type_index) {
385
super(cp);
386
this.tag = tag;
387
this.class_index = class_index;
388
this.name_and_type_index = name_and_type_index;
389
}
390
391
public int getTag() {
392
return tag;
393
}
394
395
public int byteLength() {
396
return 5;
397
}
398
399
public CONSTANT_Class_info getClassInfo() throws ConstantPoolException {
400
return cp.getClassInfo(class_index);
401
}
402
403
public String getClassName() throws ConstantPoolException {
404
return cp.getClassInfo(class_index).getName();
405
}
406
407
public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {
408
return cp.getNameAndTypeInfo(name_and_type_index);
409
}
410
411
public final int tag;
412
public final int class_index;
413
public final int name_and_type_index;
414
}
415
416
public static class CONSTANT_Class_info extends CPInfo {
417
CONSTANT_Class_info(ConstantPool cp, ClassReader cr) throws IOException {
418
super(cp);
419
name_index = cr.readUnsignedShort();
420
}
421
422
public CONSTANT_Class_info(ConstantPool cp, int name_index) {
423
super(cp);
424
this.name_index = name_index;
425
}
426
427
public int getTag() {
428
return CONSTANT_Class;
429
}
430
431
public int byteLength() {
432
return 3;
433
}
434
435
/**
436
* Get the raw value of the class referenced by this constant pool entry.
437
* This will either be the name of the class, in internal form, or a
438
* descriptor for an array class.
439
* @return the raw value of the class
440
*/
441
public String getName() throws ConstantPoolException {
442
return cp.getUTF8Value(name_index);
443
}
444
445
/**
446
* If this constant pool entry identifies either a class or interface type,
447
* or a possibly multi-dimensional array of a class of interface type,
448
* return the name of the class or interface in internal form. Otherwise,
449
* (i.e. if this is a possibly multi-dimensional array of a primitive type),
450
* return null.
451
* @return the base class or interface name
452
*/
453
public String getBaseName() throws ConstantPoolException {
454
String name = getName();
455
if (name.startsWith("[")) {
456
int index = name.indexOf("[L");
457
if (index == -1)
458
return null;
459
return name.substring(index + 2, name.length() - 1);
460
} else
461
return name;
462
}
463
464
public int getDimensionCount() throws ConstantPoolException {
465
String name = getName();
466
int count = 0;
467
while (name.charAt(count) == '[')
468
count++;
469
return count;
470
}
471
472
@Override
473
public String toString() {
474
return "CONSTANT_Class_info[name_index: " + name_index + "]";
475
}
476
477
public <R, D> R accept(Visitor<R, D> visitor, D data) {
478
return visitor.visitClass(this, data);
479
}
480
481
public final int name_index;
482
}
483
484
public static class CONSTANT_Double_info extends CPInfo {
485
CONSTANT_Double_info(ClassReader cr) throws IOException {
486
value = cr.readDouble();
487
}
488
489
public CONSTANT_Double_info(double value) {
490
this.value = value;
491
}
492
493
public int getTag() {
494
return CONSTANT_Double;
495
}
496
497
public int byteLength() {
498
return 9;
499
}
500
501
@Override
502
public int size() {
503
return 2;
504
}
505
506
@Override
507
public String toString() {
508
return "CONSTANT_Double_info[value: " + value + "]";
509
}
510
511
public <R, D> R accept(Visitor<R, D> visitor, D data) {
512
return visitor.visitDouble(this, data);
513
}
514
515
public final double value;
516
}
517
518
public static class CONSTANT_Fieldref_info extends CPRefInfo {
519
CONSTANT_Fieldref_info(ConstantPool cp, ClassReader cr) throws IOException {
520
super(cp, cr, CONSTANT_Fieldref);
521
}
522
523
public CONSTANT_Fieldref_info(ConstantPool cp, int class_index, int name_and_type_index) {
524
super(cp, CONSTANT_Fieldref, class_index, name_and_type_index);
525
}
526
527
@Override
528
public String toString() {
529
return "CONSTANT_Fieldref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
530
}
531
532
public <R, D> R accept(Visitor<R, D> visitor, D data) {
533
return visitor.visitFieldref(this, data);
534
}
535
}
536
537
public static class CONSTANT_Float_info extends CPInfo {
538
CONSTANT_Float_info(ClassReader cr) throws IOException {
539
value = cr.readFloat();
540
}
541
542
public CONSTANT_Float_info(float value) {
543
this.value = value;
544
}
545
546
public int getTag() {
547
return CONSTANT_Float;
548
}
549
550
public int byteLength() {
551
return 5;
552
}
553
554
@Override
555
public String toString() {
556
return "CONSTANT_Float_info[value: " + value + "]";
557
}
558
559
public <R, D> R accept(Visitor<R, D> visitor, D data) {
560
return visitor.visitFloat(this, data);
561
}
562
563
public final float value;
564
}
565
566
public static class CONSTANT_Integer_info extends CPInfo {
567
CONSTANT_Integer_info(ClassReader cr) throws IOException {
568
value = cr.readInt();
569
}
570
571
public CONSTANT_Integer_info(int value) {
572
this.value = value;
573
}
574
575
public int getTag() {
576
return CONSTANT_Integer;
577
}
578
579
public int byteLength() {
580
return 5;
581
}
582
583
@Override
584
public String toString() {
585
return "CONSTANT_Integer_info[value: " + value + "]";
586
}
587
588
public <R, D> R accept(Visitor<R, D> visitor, D data) {
589
return visitor.visitInteger(this, data);
590
}
591
592
public final int value;
593
}
594
595
public static class CONSTANT_InterfaceMethodref_info extends CPRefInfo {
596
CONSTANT_InterfaceMethodref_info(ConstantPool cp, ClassReader cr) throws IOException {
597
super(cp, cr, CONSTANT_InterfaceMethodref);
598
}
599
600
public CONSTANT_InterfaceMethodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
601
super(cp, CONSTANT_InterfaceMethodref, class_index, name_and_type_index);
602
}
603
604
@Override
605
public String toString() {
606
return "CONSTANT_InterfaceMethodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
607
}
608
609
public <R, D> R accept(Visitor<R, D> visitor, D data) {
610
return visitor.visitInterfaceMethodref(this, data);
611
}
612
}
613
614
public static class CONSTANT_InvokeDynamic_info extends CPInfo {
615
CONSTANT_InvokeDynamic_info(ConstantPool cp, ClassReader cr) throws IOException {
616
super(cp);
617
bootstrap_method_attr_index = cr.readUnsignedShort();
618
name_and_type_index = cr.readUnsignedShort();
619
}
620
621
public CONSTANT_InvokeDynamic_info(ConstantPool cp, int bootstrap_method_index, int name_and_type_index) {
622
super(cp);
623
this.bootstrap_method_attr_index = bootstrap_method_index;
624
this.name_and_type_index = name_and_type_index;
625
}
626
627
public int getTag() {
628
return CONSTANT_InvokeDynamic;
629
}
630
631
public int byteLength() {
632
return 5;
633
}
634
635
@Override
636
public String toString() {
637
return "CONSTANT_InvokeDynamic_info[bootstrap_method_index: " + bootstrap_method_attr_index + ", name_and_type_index: " + name_and_type_index + "]";
638
}
639
640
public <R, D> R accept(Visitor<R, D> visitor, D data) {
641
return visitor.visitInvokeDynamic(this, data);
642
}
643
644
public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {
645
return cp.getNameAndTypeInfo(name_and_type_index);
646
}
647
648
public final int bootstrap_method_attr_index;
649
public final int name_and_type_index;
650
}
651
652
public static class CONSTANT_Long_info extends CPInfo {
653
CONSTANT_Long_info(ClassReader cr) throws IOException {
654
value = cr.readLong();
655
}
656
657
public CONSTANT_Long_info(long value) {
658
this.value = value;
659
}
660
661
public int getTag() {
662
return CONSTANT_Long;
663
}
664
665
@Override
666
public int size() {
667
return 2;
668
}
669
670
public int byteLength() {
671
return 9;
672
}
673
674
@Override
675
public String toString() {
676
return "CONSTANT_Long_info[value: " + value + "]";
677
}
678
679
public <R, D> R accept(Visitor<R, D> visitor, D data) {
680
return visitor.visitLong(this, data);
681
}
682
683
public final long value;
684
}
685
686
public static class CONSTANT_MethodHandle_info extends CPInfo {
687
CONSTANT_MethodHandle_info(ConstantPool cp, ClassReader cr) throws IOException {
688
super(cp);
689
reference_kind = RefKind.getRefkind(cr.readUnsignedByte());
690
reference_index = cr.readUnsignedShort();
691
}
692
693
public CONSTANT_MethodHandle_info(ConstantPool cp, RefKind ref_kind, int member_index) {
694
super(cp);
695
this.reference_kind = ref_kind;
696
this.reference_index = member_index;
697
}
698
699
public int getTag() {
700
return CONSTANT_MethodHandle;
701
}
702
703
public int byteLength() {
704
return 4;
705
}
706
707
@Override
708
public String toString() {
709
return "CONSTANT_MethodHandle_info[ref_kind: " + reference_kind + ", member_index: " + reference_index + "]";
710
}
711
712
public <R, D> R accept(Visitor<R, D> visitor, D data) {
713
return visitor.visitMethodHandle(this, data);
714
}
715
716
public CPRefInfo getCPRefInfo() throws ConstantPoolException {
717
int expected = CONSTANT_Methodref;
718
int actual = cp.get(reference_index).getTag();
719
// allow these tag types also:
720
switch (actual) {
721
case CONSTANT_Fieldref:
722
case CONSTANT_InterfaceMethodref:
723
expected = actual;
724
}
725
return (CPRefInfo) cp.get(reference_index, expected);
726
}
727
728
public final RefKind reference_kind;
729
public final int reference_index;
730
}
731
732
public static class CONSTANT_MethodType_info extends CPInfo {
733
CONSTANT_MethodType_info(ConstantPool cp, ClassReader cr) throws IOException {
734
super(cp);
735
descriptor_index = cr.readUnsignedShort();
736
}
737
738
public CONSTANT_MethodType_info(ConstantPool cp, int signature_index) {
739
super(cp);
740
this.descriptor_index = signature_index;
741
}
742
743
public int getTag() {
744
return CONSTANT_MethodType;
745
}
746
747
public int byteLength() {
748
return 3;
749
}
750
751
@Override
752
public String toString() {
753
return "CONSTANT_MethodType_info[signature_index: " + descriptor_index + "]";
754
}
755
756
public <R, D> R accept(Visitor<R, D> visitor, D data) {
757
return visitor.visitMethodType(this, data);
758
}
759
760
public String getType() throws ConstantPoolException {
761
return cp.getUTF8Value(descriptor_index);
762
}
763
764
public final int descriptor_index;
765
}
766
767
public static class CONSTANT_Methodref_info extends CPRefInfo {
768
CONSTANT_Methodref_info(ConstantPool cp, ClassReader cr) throws IOException {
769
super(cp, cr, CONSTANT_Methodref);
770
}
771
772
public CONSTANT_Methodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
773
super(cp, CONSTANT_Methodref, class_index, name_and_type_index);
774
}
775
776
@Override
777
public String toString() {
778
return "CONSTANT_Methodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
779
}
780
781
public <R, D> R accept(Visitor<R, D> visitor, D data) {
782
return visitor.visitMethodref(this, data);
783
}
784
}
785
786
public static class CONSTANT_NameAndType_info extends CPInfo {
787
CONSTANT_NameAndType_info(ConstantPool cp, ClassReader cr) throws IOException {
788
super(cp);
789
name_index = cr.readUnsignedShort();
790
type_index = cr.readUnsignedShort();
791
}
792
793
public CONSTANT_NameAndType_info(ConstantPool cp, int name_index, int type_index) {
794
super(cp);
795
this.name_index = name_index;
796
this.type_index = type_index;
797
}
798
799
public int getTag() {
800
return CONSTANT_NameAndType;
801
}
802
803
public int byteLength() {
804
return 5;
805
}
806
807
public String getName() throws ConstantPoolException {
808
return cp.getUTF8Value(name_index);
809
}
810
811
public String getType() throws ConstantPoolException {
812
return cp.getUTF8Value(type_index);
813
}
814
815
public <R, D> R accept(Visitor<R, D> visitor, D data) {
816
return visitor.visitNameAndType(this, data);
817
}
818
819
@Override
820
public String toString() {
821
return "CONSTANT_NameAndType_info[name_index: " + name_index + ", type_index: " + type_index + "]";
822
}
823
824
public final int name_index;
825
public final int type_index;
826
}
827
828
public static class CONSTANT_String_info extends CPInfo {
829
CONSTANT_String_info(ConstantPool cp, ClassReader cr) throws IOException {
830
super(cp);
831
string_index = cr.readUnsignedShort();
832
}
833
834
public CONSTANT_String_info(ConstantPool cp, int string_index) {
835
super(cp);
836
this.string_index = string_index;
837
}
838
839
public int getTag() {
840
return CONSTANT_String;
841
}
842
843
public int byteLength() {
844
return 3;
845
}
846
847
public String getString() throws ConstantPoolException {
848
return cp.getUTF8Value(string_index);
849
}
850
851
public <R, D> R accept(Visitor<R, D> visitor, D data) {
852
return visitor.visitString(this, data);
853
}
854
855
@Override
856
public String toString() {
857
return "CONSTANT_String_info[class_index: " + string_index + "]";
858
}
859
860
public final int string_index;
861
}
862
863
public static class CONSTANT_Utf8_info extends CPInfo {
864
CONSTANT_Utf8_info(ClassReader cr) throws IOException {
865
value = cr.readUTF();
866
}
867
868
public CONSTANT_Utf8_info(String value) {
869
this.value = value;
870
}
871
872
public int getTag() {
873
return CONSTANT_Utf8;
874
}
875
876
public int byteLength() {
877
class SizeOutputStream extends OutputStream {
878
@Override
879
public void write(int b) {
880
size++;
881
}
882
int size;
883
}
884
SizeOutputStream sizeOut = new SizeOutputStream();
885
DataOutputStream out = new DataOutputStream(sizeOut);
886
try { out.writeUTF(value); } catch (IOException ignore) { }
887
return 1 + sizeOut.size;
888
}
889
890
@Override
891
public String toString() {
892
if (value.length() < 32 && isPrintableAscii(value))
893
return "CONSTANT_Utf8_info[value: \"" + value + "\"]";
894
else
895
return "CONSTANT_Utf8_info[value: (" + value.length() + " chars)]";
896
}
897
898
static boolean isPrintableAscii(String s) {
899
for (int i = 0; i < s.length(); i++) {
900
char c = s.charAt(i);
901
if (c < 32 || c >= 127)
902
return false;
903
}
904
return true;
905
}
906
907
public <R, D> R accept(Visitor<R, D> visitor, D data) {
908
return visitor.visitUtf8(this, data);
909
}
910
911
public final String value;
912
}
913
914
}
915
916