src/share/classes/com/sun/tools/classfile/ConstantPool.java

changeset 46
7708bd6d800d
child 52
3cb4fb6e0720
equal deleted inserted replaced
42:f7e64b33d5a4 46:7708bd6d800d
1 /*
2 * Copyright 2007 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package com.sun.tools.classfile;
27
28 import java.io.IOException;
29
30 /**
31 * See JVMS3, section 4.5.
32 *
33 * <p><b>This is NOT part of any API supported by Sun Microsystems. If
34 * you write code that depends on this, you do so at your own risk.
35 * This code and its internal interfaces are subject to change or
36 * deletion without notice.</b>
37 */
38 public class ConstantPool {
39
40 public class InvalidIndex extends ConstantPoolException {
41 InvalidIndex(int index) {
42 super(index);
43 }
44
45 @Override
46 public String getMessage() {
47 // i18n
48 return "invalid index #" + index;
49 }
50 }
51
52 public class UnexpectedEntry extends ConstantPoolException {
53 UnexpectedEntry(int index, int expected_tag, int found_tag) {
54 super(index);
55 this.expected_tag = expected_tag;
56 this.found_tag = found_tag;
57 }
58
59 @Override
60 public String getMessage() {
61 // i18n?
62 return "unexpected entry at #" + index + " -- expected tag " + expected_tag + ", found " + found_tag;
63 }
64
65 public final int expected_tag;
66 public final int found_tag;
67 }
68
69 public class InvalidEntry extends ConstantPoolException {
70 InvalidEntry(int index, int tag) {
71 super(index);
72 this.tag = tag;
73 }
74
75 @Override
76 public String getMessage() {
77 // i18n?
78 return "unexpected tag at #" + index + ": " + tag;
79 }
80
81 public final int tag;
82 }
83
84 public class EntryNotFound extends ConstantPoolException {
85 EntryNotFound(Object value) {
86 super(-1);
87 this.value = value;
88 }
89
90 @Override
91 public String getMessage() {
92 // i18n?
93 return "value not found: " + value;
94 }
95
96 public final Object value;
97 }
98
99 public static final int CONSTANT_Utf8 = 1;
100 public static final int CONSTANT_Integer = 3;
101 public static final int CONSTANT_Float = 4;
102 public static final int CONSTANT_Long = 5;
103 public static final int CONSTANT_Double = 6;
104 public static final int CONSTANT_Class = 7;
105 public static final int CONSTANT_String = 8;
106 public static final int CONSTANT_Fieldref = 9;
107 public static final int CONSTANT_Methodref = 10;
108 public static final int CONSTANT_InterfaceMethodref = 11;
109 public static final int CONSTANT_NameAndType = 12;
110
111 ConstantPool(ClassReader cr) throws IOException, InvalidEntry {
112 int count = cr.readUnsignedShort();
113 pool = new CPInfo[count];
114 for (int i = 1; i < count; i++) {
115 int tag = cr.readUnsignedByte();
116 switch (tag) {
117 case CONSTANT_Class:
118 pool[i] = new CONSTANT_Class_info(this, cr);
119 break;
120
121 case CONSTANT_Double:
122 pool[i] = new CONSTANT_Double_info(cr);
123 i++;
124 break;
125
126 case CONSTANT_Fieldref:
127 pool[i] = new CONSTANT_Fieldref_info(this, cr);
128 break;
129
130 case CONSTANT_Float:
131 pool[i] = new CONSTANT_Float_info(cr);
132 break;
133
134 case CONSTANT_Integer:
135 pool[i] = new CONSTANT_Integer_info(cr);
136 break;
137
138 case CONSTANT_InterfaceMethodref:
139 pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr);
140 break;
141
142 case CONSTANT_Long:
143 pool[i] = new CONSTANT_Long_info(cr);
144 i++;
145 break;
146
147 case CONSTANT_Methodref:
148 pool[i] = new CONSTANT_Methodref_info(this, cr);
149 break;
150
151 case CONSTANT_NameAndType:
152 pool[i] = new CONSTANT_NameAndType_info(this, cr);
153 break;
154
155 case CONSTANT_String:
156 pool[i] = new CONSTANT_String_info(cr);
157 break;
158
159 case CONSTANT_Utf8:
160 pool[i] = new CONSTANT_Utf8_info(cr);
161 break;
162
163 default:
164 throw new InvalidEntry(i, tag);
165 }
166 }
167 }
168
169 public ConstantPool(CPInfo[] pool) {
170 this.pool = pool;
171 }
172
173 public int size() {
174 return pool.length;
175 }
176
177 public CPInfo get(int index) throws InvalidIndex {
178 if (index <= 0 || index >= pool.length)
179 throw new InvalidIndex(index);
180 CPInfo info = pool[index];
181 if (info == null) {
182 // this occurs for indices referencing the "second half" of an
183 // 8 byte constant, such as CONSTANT_Double or CONSTANT_Long
184 throw new InvalidIndex(index);
185 }
186 return pool[index];
187 }
188
189 private CPInfo get(int index, int expected_type) throws InvalidIndex, UnexpectedEntry {
190 CPInfo info = get(index);
191 if (info.getTag() != expected_type)
192 throw new UnexpectedEntry(index, expected_type, info.getTag());
193 return info;
194 }
195
196 public CONSTANT_Utf8_info getUTF8Info(int index) throws InvalidIndex, UnexpectedEntry {
197 return ((CONSTANT_Utf8_info) get(index, CONSTANT_Utf8));
198 }
199
200 public CONSTANT_Class_info getClassInfo(int index) throws InvalidIndex, UnexpectedEntry {
201 return ((CONSTANT_Class_info) get(index, CONSTANT_Class));
202 }
203
204 public CONSTANT_NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry {
205 return ((CONSTANT_NameAndType_info) get(index, CONSTANT_NameAndType));
206 }
207
208 public String getUTF8Value(int index) throws InvalidIndex, UnexpectedEntry {
209 return getUTF8Info(index).value;
210 }
211
212 public int getUTF8Index(String value) throws EntryNotFound {
213 for (int i = 1; i < pool.length; i++) {
214 CPInfo info = pool[i];
215 if (info instanceof CONSTANT_Utf8_info &&
216 ((CONSTANT_Utf8_info) info).value.equals(value))
217 return i;
218 }
219 throw new EntryNotFound(value);
220 }
221
222 private CPInfo[] pool;
223
224 public interface Visitor<R,P> {
225 R visitClass(CONSTANT_Class_info info, P p);
226 R visitDouble(CONSTANT_Double_info info, P p);
227 R visitFieldref(CONSTANT_Fieldref_info info, P p);
228 R visitFloat(CONSTANT_Float_info info, P p);
229 R visitInteger(CONSTANT_Integer_info info, P p);
230 R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);
231 R visitLong(CONSTANT_Long_info info, P p);
232 R visitNameAndType(CONSTANT_NameAndType_info info, P p);
233 R visitMethodref(CONSTANT_Methodref_info info, P p);
234 R visitString(CONSTANT_String_info info, P p);
235 R visitUtf8(CONSTANT_Utf8_info info, P p);
236 }
237
238 public static abstract class CPInfo {
239 CPInfo() {
240 this.cp = null;
241 }
242
243 CPInfo(ConstantPool cp) {
244 this.cp = cp;
245 }
246
247 public abstract int getTag();
248
249 public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
250
251 protected final ConstantPool cp;
252 }
253
254 public static abstract class CPRefInfo extends CPInfo {
255 protected CPRefInfo(ConstantPool cp, ClassReader cr, int tag) throws IOException {
256 super(cp);
257 this.tag = tag;
258 class_index = cr.readUnsignedShort();
259 name_and_type_index = cr.readUnsignedShort();
260 }
261
262 protected CPRefInfo(ConstantPool cp, int tag, int class_index, int name_and_type_index) {
263 super(cp);
264 this.tag = tag;
265 this.class_index = class_index;
266 this.name_and_type_index = name_and_type_index;
267 }
268
269 public int getTag() {
270 return tag;
271 }
272
273 public CONSTANT_Class_info getClassInfo() throws ConstantPoolException {
274 return cp.getClassInfo(class_index);
275 }
276
277 public String getClassName() throws ConstantPoolException {
278 return cp.getClassInfo(class_index).getName();
279 }
280
281 public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {
282 return cp.getNameAndTypeInfo(name_and_type_index);
283 }
284
285 public final int tag;
286 public final int class_index;
287 public final int name_and_type_index;
288 }
289
290 public static class CONSTANT_Class_info extends CPInfo {
291 CONSTANT_Class_info(ConstantPool cp, ClassReader cr) throws IOException {
292 super(cp);
293 name_index = cr.readUnsignedShort();
294 }
295
296 public CONSTANT_Class_info(ConstantPool cp, int name_index) {
297 super(cp);
298 this.name_index = name_index;
299 }
300
301 public int getTag() {
302 return CONSTANT_Class;
303 }
304
305 public String getName() throws ConstantPoolException {
306 return cp.getUTF8Value(name_index);
307 }
308
309 @Override
310 public String toString() {
311 return "CONSTANT_Class_info[name_index: " + name_index + "]";
312 }
313
314 public <R, D> R accept(Visitor<R, D> visitor, D data) {
315 return visitor.visitClass(this, data);
316 }
317
318 public final int name_index;
319 }
320
321 public static class CONSTANT_Double_info extends CPInfo {
322 CONSTANT_Double_info(ClassReader cr) throws IOException {
323 value = cr.readDouble();
324 }
325
326 public CONSTANT_Double_info(double value) {
327 this.value = value;
328 }
329
330 public int getTag() {
331 return CONSTANT_Double;
332 }
333
334 @Override
335 public String toString() {
336 return "CONSTANT_Double_info[value: " + value + "]";
337 }
338
339 public <R, D> R accept(Visitor<R, D> visitor, D data) {
340 return visitor.visitDouble(this, data);
341 }
342
343 public final double value;
344 }
345
346 public static class CONSTANT_Fieldref_info extends CPRefInfo {
347 CONSTANT_Fieldref_info(ConstantPool cp, ClassReader cr) throws IOException {
348 super(cp, cr, CONSTANT_Fieldref);
349 }
350
351 public CONSTANT_Fieldref_info(ConstantPool cp, int class_index, int name_and_type_index) {
352 super(cp, CONSTANT_Fieldref, class_index, name_and_type_index);
353 }
354
355 @Override
356 public String toString() {
357 return "CONSTANT_Fieldref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
358 }
359
360 public <R, D> R accept(Visitor<R, D> visitor, D data) {
361 return visitor.visitFieldref(this, data);
362 }
363 }
364
365 public static class CONSTANT_Float_info extends CPInfo {
366 CONSTANT_Float_info(ClassReader cr) throws IOException {
367 value = cr.readFloat();
368 }
369
370 public CONSTANT_Float_info(float value) {
371 this.value = value;
372 }
373
374 public int getTag() {
375 return CONSTANT_Float;
376 }
377
378 @Override
379 public String toString() {
380 return "CONSTANT_Float_info[value: " + value + "]";
381 }
382
383 public <R, D> R accept(Visitor<R, D> visitor, D data) {
384 return visitor.visitFloat(this, data);
385 }
386
387 public final float value;
388 }
389
390 public static class CONSTANT_Integer_info extends CPInfo {
391 CONSTANT_Integer_info(ClassReader cr) throws IOException {
392 value = cr.readInt();
393 }
394
395 public CONSTANT_Integer_info(int value) {
396 this.value = value;
397 }
398
399 public int getTag() {
400 return CONSTANT_Integer;
401 }
402
403 @Override
404 public String toString() {
405 return "CONSTANT_Integer_info[value: " + value + "]";
406 }
407
408 public <R, D> R accept(Visitor<R, D> visitor, D data) {
409 return visitor.visitInteger(this, data);
410 }
411
412 public final int value;
413 }
414
415 public static class CONSTANT_InterfaceMethodref_info extends CPRefInfo {
416 CONSTANT_InterfaceMethodref_info(ConstantPool cp, ClassReader cr) throws IOException {
417 super(cp, cr, CONSTANT_InterfaceMethodref);
418 }
419
420 public CONSTANT_InterfaceMethodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
421 super(cp, CONSTANT_InterfaceMethodref, class_index, name_and_type_index);
422 }
423
424 @Override
425 public String toString() {
426 return "CONSTANT_InterfaceMethodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
427 }
428
429 public <R, D> R accept(Visitor<R, D> visitor, D data) {
430 return visitor.visitInterfaceMethodref(this, data);
431 }
432 }
433
434 public static class CONSTANT_Long_info extends CPInfo {
435 CONSTANT_Long_info(ClassReader cr) throws IOException {
436 value = cr.readLong();
437 }
438
439 public CONSTANT_Long_info(long value) {
440 this.value = value;
441 }
442
443 public int getTag() {
444 return CONSTANT_Long;
445 }
446
447 @Override
448 public String toString() {
449 return "CONSTANT_Long_info[value: " + value + "]";
450 }
451
452 public <R, D> R accept(Visitor<R, D> visitor, D data) {
453 return visitor.visitLong(this, data);
454 }
455
456 public final long value;
457 }
458
459 public static class CONSTANT_Methodref_info extends CPRefInfo {
460 CONSTANT_Methodref_info(ConstantPool cp, ClassReader cr) throws IOException {
461 super(cp, cr, CONSTANT_Methodref);
462 }
463
464 public CONSTANT_Methodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
465 super(cp, CONSTANT_Methodref, class_index, name_and_type_index);
466 }
467
468 @Override
469 public String toString() {
470 return "CONSTANT_Methodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
471 }
472
473 public <R, D> R accept(Visitor<R, D> visitor, D data) {
474 return visitor.visitMethodref(this, data);
475 }
476 }
477
478 public static class CONSTANT_NameAndType_info extends CPInfo {
479 CONSTANT_NameAndType_info(ConstantPool cp, ClassReader cr) throws IOException {
480 super(cp);
481 name_index = cr.readUnsignedShort();
482 type_index = cr.readUnsignedShort();
483 }
484
485 public CONSTANT_NameAndType_info(ConstantPool cp, int name_index, int type_index) {
486 super(cp);
487 this.name_index = name_index;
488 this.type_index = type_index;
489 }
490
491 public int getTag() {
492 return CONSTANT_NameAndType;
493 }
494
495 public String getName() throws ConstantPoolException {
496 return cp.getUTF8Value(name_index);
497 }
498
499 public String getType() throws ConstantPoolException {
500 return cp.getUTF8Value(type_index);
501 }
502
503 public <R, D> R accept(Visitor<R, D> visitor, D data) {
504 return visitor.visitNameAndType(this, data);
505 }
506
507 public final int name_index;
508 public final int type_index;
509 }
510
511 public static class CONSTANT_String_info extends CPInfo {
512 CONSTANT_String_info(ClassReader cr) throws IOException {
513 string_index = cr.readUnsignedShort();
514 }
515
516 public CONSTANT_String_info(ConstantPool cp, int string_index) {
517 super(cp);
518 this.string_index = string_index;
519 }
520
521 public int getTag() {
522 return CONSTANT_String;
523 }
524
525 public String getString() throws ConstantPoolException {
526 return cp.getUTF8Value(string_index);
527 }
528
529 public <R, D> R accept(Visitor<R, D> visitor, D data) {
530 return visitor.visitString(this, data);
531 }
532
533 public final int string_index;
534 }
535
536 public static class CONSTANT_Utf8_info extends CPInfo {
537 CONSTANT_Utf8_info(ClassReader cr) throws IOException {
538 value = cr.readUTF();
539 }
540
541 public CONSTANT_Utf8_info(String value) {
542 this.value = value;
543 }
544
545 public int getTag() {
546 return CONSTANT_Utf8;
547 }
548
549 @Override
550 public String toString() {
551 return "CONSTANT_Utf8_info[value: " + value + "]";
552 }
553
554 public <R, D> R accept(Visitor<R, D> visitor, D data) {
555 return visitor.visitUtf8(this, data);
556 }
557
558 public final String value;
559 }
560
561
562 }

mercurial