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

Sat, 29 Dec 2012 17:33:17 -0800

author
jjg
date
Sat, 29 Dec 2012 17:33:17 -0800
changeset 1473
31780dd06ec7
parent 972
694ff82ca68e
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8004727: Add compiler support for parameter reflection
Reviewed-by: jjg
Contributed-by: eric.mccorkle@oracle.com

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

mercurial