Mon, 09 Mar 2009 13:29:06 -0700
6814575: Update copyright year
Summary: Update copyright for files that have been modified in 2009, up to 03/09
Reviewed-by: katleman, tbell, ohair
1 /*
2 * Copyright 2007-2009 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 */
26 package com.sun.tools.classfile;
28 import java.io.IOException;
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 {
40 public class InvalidIndex extends ConstantPoolException {
41 private static final long serialVersionUID = -4350294289300939730L;
42 InvalidIndex(int index) {
43 super(index);
44 }
46 @Override
47 public String getMessage() {
48 // i18n
49 return "invalid index #" + index;
50 }
51 }
53 public class UnexpectedEntry extends ConstantPoolException {
54 private static final long serialVersionUID = 6986335935377933211L;
55 UnexpectedEntry(int index, int expected_tag, int found_tag) {
56 super(index);
57 this.expected_tag = expected_tag;
58 this.found_tag = found_tag;
59 }
61 @Override
62 public String getMessage() {
63 // i18n?
64 return "unexpected entry at #" + index + " -- expected tag " + expected_tag + ", found " + found_tag;
65 }
67 public final int expected_tag;
68 public final int found_tag;
69 }
71 public class InvalidEntry extends ConstantPoolException {
72 private static final long serialVersionUID = 1000087545585204447L;
73 InvalidEntry(int index, int tag) {
74 super(index);
75 this.tag = tag;
76 }
78 @Override
79 public String getMessage() {
80 // i18n?
81 return "unexpected tag at #" + index + ": " + tag;
82 }
84 public final int tag;
85 }
87 public class EntryNotFound extends ConstantPoolException {
88 private static final long serialVersionUID = 2885537606468581850L;
89 EntryNotFound(Object value) {
90 super(-1);
91 this.value = value;
92 }
94 @Override
95 public String getMessage() {
96 // i18n?
97 return "value not found: " + value;
98 }
100 public final Object value;
101 }
103 public static final int CONSTANT_Utf8 = 1;
104 public static final int CONSTANT_Integer = 3;
105 public static final int CONSTANT_Float = 4;
106 public static final int CONSTANT_Long = 5;
107 public static final int CONSTANT_Double = 6;
108 public static final int CONSTANT_Class = 7;
109 public static final int CONSTANT_String = 8;
110 public static final int CONSTANT_Fieldref = 9;
111 public static final int CONSTANT_Methodref = 10;
112 public static final int CONSTANT_InterfaceMethodref = 11;
113 public static final int CONSTANT_NameAndType = 12;
115 ConstantPool(ClassReader cr) throws IOException, InvalidEntry {
116 int count = cr.readUnsignedShort();
117 pool = new CPInfo[count];
118 for (int i = 1; i < count; i++) {
119 int tag = cr.readUnsignedByte();
120 switch (tag) {
121 case CONSTANT_Class:
122 pool[i] = new CONSTANT_Class_info(this, cr);
123 break;
125 case CONSTANT_Double:
126 pool[i] = new CONSTANT_Double_info(cr);
127 i++;
128 break;
130 case CONSTANT_Fieldref:
131 pool[i] = new CONSTANT_Fieldref_info(this, cr);
132 break;
134 case CONSTANT_Float:
135 pool[i] = new CONSTANT_Float_info(cr);
136 break;
138 case CONSTANT_Integer:
139 pool[i] = new CONSTANT_Integer_info(cr);
140 break;
142 case CONSTANT_InterfaceMethodref:
143 pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr);
144 break;
146 case CONSTANT_Long:
147 pool[i] = new CONSTANT_Long_info(cr);
148 i++;
149 break;
151 case CONSTANT_Methodref:
152 pool[i] = new CONSTANT_Methodref_info(this, cr);
153 break;
155 case CONSTANT_NameAndType:
156 pool[i] = new CONSTANT_NameAndType_info(this, cr);
157 break;
159 case CONSTANT_String:
160 pool[i] = new CONSTANT_String_info(this, cr);
161 break;
163 case CONSTANT_Utf8:
164 pool[i] = new CONSTANT_Utf8_info(cr);
165 break;
167 default:
168 throw new InvalidEntry(i, tag);
169 }
170 }
171 }
173 public ConstantPool(CPInfo[] pool) {
174 this.pool = pool;
175 }
177 public int size() {
178 return pool.length;
179 }
181 public CPInfo get(int index) throws InvalidIndex {
182 if (index <= 0 || index >= pool.length)
183 throw new InvalidIndex(index);
184 CPInfo info = pool[index];
185 if (info == null) {
186 // this occurs for indices referencing the "second half" of an
187 // 8 byte constant, such as CONSTANT_Double or CONSTANT_Long
188 throw new InvalidIndex(index);
189 }
190 return pool[index];
191 }
193 private CPInfo get(int index, int expected_type) throws InvalidIndex, UnexpectedEntry {
194 CPInfo info = get(index);
195 if (info.getTag() != expected_type)
196 throw new UnexpectedEntry(index, expected_type, info.getTag());
197 return info;
198 }
200 public CONSTANT_Utf8_info getUTF8Info(int index) throws InvalidIndex, UnexpectedEntry {
201 return ((CONSTANT_Utf8_info) get(index, CONSTANT_Utf8));
202 }
204 public CONSTANT_Class_info getClassInfo(int index) throws InvalidIndex, UnexpectedEntry {
205 return ((CONSTANT_Class_info) get(index, CONSTANT_Class));
206 }
208 public CONSTANT_NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry {
209 return ((CONSTANT_NameAndType_info) get(index, CONSTANT_NameAndType));
210 }
212 public String getUTF8Value(int index) throws InvalidIndex, UnexpectedEntry {
213 return getUTF8Info(index).value;
214 }
216 public int getUTF8Index(String value) throws EntryNotFound {
217 for (int i = 1; i < pool.length; i++) {
218 CPInfo info = pool[i];
219 if (info instanceof CONSTANT_Utf8_info &&
220 ((CONSTANT_Utf8_info) info).value.equals(value))
221 return i;
222 }
223 throw new EntryNotFound(value);
224 }
226 private CPInfo[] pool;
228 public interface Visitor<R,P> {
229 R visitClass(CONSTANT_Class_info info, P p);
230 R visitDouble(CONSTANT_Double_info info, P p);
231 R visitFieldref(CONSTANT_Fieldref_info info, P p);
232 R visitFloat(CONSTANT_Float_info info, P p);
233 R visitInteger(CONSTANT_Integer_info info, P p);
234 R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p);
235 R visitLong(CONSTANT_Long_info info, P p);
236 R visitNameAndType(CONSTANT_NameAndType_info info, P p);
237 R visitMethodref(CONSTANT_Methodref_info info, P p);
238 R visitString(CONSTANT_String_info info, P p);
239 R visitUtf8(CONSTANT_Utf8_info info, P p);
240 }
242 public static abstract class CPInfo {
243 CPInfo() {
244 this.cp = null;
245 }
247 CPInfo(ConstantPool cp) {
248 this.cp = cp;
249 }
251 public abstract int getTag();
253 public abstract <R,D> R accept(Visitor<R,D> visitor, D data);
255 protected final ConstantPool cp;
256 }
258 public static abstract class CPRefInfo extends CPInfo {
259 protected CPRefInfo(ConstantPool cp, ClassReader cr, int tag) throws IOException {
260 super(cp);
261 this.tag = tag;
262 class_index = cr.readUnsignedShort();
263 name_and_type_index = cr.readUnsignedShort();
264 }
266 protected CPRefInfo(ConstantPool cp, int tag, int class_index, int name_and_type_index) {
267 super(cp);
268 this.tag = tag;
269 this.class_index = class_index;
270 this.name_and_type_index = name_and_type_index;
271 }
273 public int getTag() {
274 return tag;
275 }
277 public CONSTANT_Class_info getClassInfo() throws ConstantPoolException {
278 return cp.getClassInfo(class_index);
279 }
281 public String getClassName() throws ConstantPoolException {
282 return cp.getClassInfo(class_index).getName();
283 }
285 public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException {
286 return cp.getNameAndTypeInfo(name_and_type_index);
287 }
289 public final int tag;
290 public final int class_index;
291 public final int name_and_type_index;
292 }
294 public static class CONSTANT_Class_info extends CPInfo {
295 CONSTANT_Class_info(ConstantPool cp, ClassReader cr) throws IOException {
296 super(cp);
297 name_index = cr.readUnsignedShort();
298 }
300 public CONSTANT_Class_info(ConstantPool cp, int name_index) {
301 super(cp);
302 this.name_index = name_index;
303 }
305 public int getTag() {
306 return CONSTANT_Class;
307 }
309 public String getName() throws ConstantPoolException {
310 return cp.getUTF8Value(name_index);
311 }
313 @Override
314 public String toString() {
315 return "CONSTANT_Class_info[name_index: " + name_index + "]";
316 }
318 public <R, D> R accept(Visitor<R, D> visitor, D data) {
319 return visitor.visitClass(this, data);
320 }
322 public final int name_index;
323 }
325 public static class CONSTANT_Double_info extends CPInfo {
326 CONSTANT_Double_info(ClassReader cr) throws IOException {
327 value = cr.readDouble();
328 }
330 public CONSTANT_Double_info(double value) {
331 this.value = value;
332 }
334 public int getTag() {
335 return CONSTANT_Double;
336 }
338 @Override
339 public String toString() {
340 return "CONSTANT_Double_info[value: " + value + "]";
341 }
343 public <R, D> R accept(Visitor<R, D> visitor, D data) {
344 return visitor.visitDouble(this, data);
345 }
347 public final double value;
348 }
350 public static class CONSTANT_Fieldref_info extends CPRefInfo {
351 CONSTANT_Fieldref_info(ConstantPool cp, ClassReader cr) throws IOException {
352 super(cp, cr, CONSTANT_Fieldref);
353 }
355 public CONSTANT_Fieldref_info(ConstantPool cp, int class_index, int name_and_type_index) {
356 super(cp, CONSTANT_Fieldref, class_index, name_and_type_index);
357 }
359 @Override
360 public String toString() {
361 return "CONSTANT_Fieldref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
362 }
364 public <R, D> R accept(Visitor<R, D> visitor, D data) {
365 return visitor.visitFieldref(this, data);
366 }
367 }
369 public static class CONSTANT_Float_info extends CPInfo {
370 CONSTANT_Float_info(ClassReader cr) throws IOException {
371 value = cr.readFloat();
372 }
374 public CONSTANT_Float_info(float value) {
375 this.value = value;
376 }
378 public int getTag() {
379 return CONSTANT_Float;
380 }
382 @Override
383 public String toString() {
384 return "CONSTANT_Float_info[value: " + value + "]";
385 }
387 public <R, D> R accept(Visitor<R, D> visitor, D data) {
388 return visitor.visitFloat(this, data);
389 }
391 public final float value;
392 }
394 public static class CONSTANT_Integer_info extends CPInfo {
395 CONSTANT_Integer_info(ClassReader cr) throws IOException {
396 value = cr.readInt();
397 }
399 public CONSTANT_Integer_info(int value) {
400 this.value = value;
401 }
403 public int getTag() {
404 return CONSTANT_Integer;
405 }
407 @Override
408 public String toString() {
409 return "CONSTANT_Integer_info[value: " + value + "]";
410 }
412 public <R, D> R accept(Visitor<R, D> visitor, D data) {
413 return visitor.visitInteger(this, data);
414 }
416 public final int value;
417 }
419 public static class CONSTANT_InterfaceMethodref_info extends CPRefInfo {
420 CONSTANT_InterfaceMethodref_info(ConstantPool cp, ClassReader cr) throws IOException {
421 super(cp, cr, CONSTANT_InterfaceMethodref);
422 }
424 public CONSTANT_InterfaceMethodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
425 super(cp, CONSTANT_InterfaceMethodref, class_index, name_and_type_index);
426 }
428 @Override
429 public String toString() {
430 return "CONSTANT_InterfaceMethodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
431 }
433 public <R, D> R accept(Visitor<R, D> visitor, D data) {
434 return visitor.visitInterfaceMethodref(this, data);
435 }
436 }
438 public static class CONSTANT_Long_info extends CPInfo {
439 CONSTANT_Long_info(ClassReader cr) throws IOException {
440 value = cr.readLong();
441 }
443 public CONSTANT_Long_info(long value) {
444 this.value = value;
445 }
447 public int getTag() {
448 return CONSTANT_Long;
449 }
451 @Override
452 public String toString() {
453 return "CONSTANT_Long_info[value: " + value + "]";
454 }
456 public <R, D> R accept(Visitor<R, D> visitor, D data) {
457 return visitor.visitLong(this, data);
458 }
460 public final long value;
461 }
463 public static class CONSTANT_Methodref_info extends CPRefInfo {
464 CONSTANT_Methodref_info(ConstantPool cp, ClassReader cr) throws IOException {
465 super(cp, cr, CONSTANT_Methodref);
466 }
468 public CONSTANT_Methodref_info(ConstantPool cp, int class_index, int name_and_type_index) {
469 super(cp, CONSTANT_Methodref, class_index, name_and_type_index);
470 }
472 @Override
473 public String toString() {
474 return "CONSTANT_Methodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]";
475 }
477 public <R, D> R accept(Visitor<R, D> visitor, D data) {
478 return visitor.visitMethodref(this, data);
479 }
480 }
482 public static class CONSTANT_NameAndType_info extends CPInfo {
483 CONSTANT_NameAndType_info(ConstantPool cp, ClassReader cr) throws IOException {
484 super(cp);
485 name_index = cr.readUnsignedShort();
486 type_index = cr.readUnsignedShort();
487 }
489 public CONSTANT_NameAndType_info(ConstantPool cp, int name_index, int type_index) {
490 super(cp);
491 this.name_index = name_index;
492 this.type_index = type_index;
493 }
495 public int getTag() {
496 return CONSTANT_NameAndType;
497 }
499 public String getName() throws ConstantPoolException {
500 return cp.getUTF8Value(name_index);
501 }
503 public String getType() throws ConstantPoolException {
504 return cp.getUTF8Value(type_index);
505 }
507 public <R, D> R accept(Visitor<R, D> visitor, D data) {
508 return visitor.visitNameAndType(this, data);
509 }
511 public final int name_index;
512 public final int type_index;
513 }
515 public static class CONSTANT_String_info extends CPInfo {
516 CONSTANT_String_info(ConstantPool cp, ClassReader cr) throws IOException {
517 super(cp);
518 string_index = cr.readUnsignedShort();
519 }
521 public CONSTANT_String_info(ConstantPool cp, int string_index) {
522 super(cp);
523 this.string_index = string_index;
524 }
526 public int getTag() {
527 return CONSTANT_String;
528 }
530 public String getString() throws ConstantPoolException {
531 return cp.getUTF8Value(string_index);
532 }
534 public <R, D> R accept(Visitor<R, D> visitor, D data) {
535 return visitor.visitString(this, data);
536 }
538 public final int string_index;
539 }
541 public static class CONSTANT_Utf8_info extends CPInfo {
542 CONSTANT_Utf8_info(ClassReader cr) throws IOException {
543 value = cr.readUTF();
544 }
546 public CONSTANT_Utf8_info(String value) {
547 this.value = value;
548 }
550 public int getTag() {
551 return CONSTANT_Utf8;
552 }
554 @Override
555 public String toString() {
556 return "CONSTANT_Utf8_info[value: " + value + "]";
557 }
559 public <R, D> R accept(Visitor<R, D> visitor, D data) {
560 return visitor.visitUtf8(this, data);
561 }
563 public final String value;
564 }
567 }