1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/classes/com/sun/tools/classfile/ConstantPool.java Tue Jun 03 13:26:47 2008 -0700 1.3 @@ -0,0 +1,562 @@ 1.4 +/* 1.5 + * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Sun designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Sun in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.25 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.26 + * have any questions. 1.27 + */ 1.28 + 1.29 +package com.sun.tools.classfile; 1.30 + 1.31 +import java.io.IOException; 1.32 + 1.33 +/** 1.34 + * See JVMS3, section 4.5. 1.35 + * 1.36 + * <p><b>This is NOT part of any API supported by Sun Microsystems. If 1.37 + * you write code that depends on this, you do so at your own risk. 1.38 + * This code and its internal interfaces are subject to change or 1.39 + * deletion without notice.</b> 1.40 + */ 1.41 +public class ConstantPool { 1.42 + 1.43 + public class InvalidIndex extends ConstantPoolException { 1.44 + InvalidIndex(int index) { 1.45 + super(index); 1.46 + } 1.47 + 1.48 + @Override 1.49 + public String getMessage() { 1.50 + // i18n 1.51 + return "invalid index #" + index; 1.52 + } 1.53 + } 1.54 + 1.55 + public class UnexpectedEntry extends ConstantPoolException { 1.56 + UnexpectedEntry(int index, int expected_tag, int found_tag) { 1.57 + super(index); 1.58 + this.expected_tag = expected_tag; 1.59 + this.found_tag = found_tag; 1.60 + } 1.61 + 1.62 + @Override 1.63 + public String getMessage() { 1.64 + // i18n? 1.65 + return "unexpected entry at #" + index + " -- expected tag " + expected_tag + ", found " + found_tag; 1.66 + } 1.67 + 1.68 + public final int expected_tag; 1.69 + public final int found_tag; 1.70 + } 1.71 + 1.72 + public class InvalidEntry extends ConstantPoolException { 1.73 + InvalidEntry(int index, int tag) { 1.74 + super(index); 1.75 + this.tag = tag; 1.76 + } 1.77 + 1.78 + @Override 1.79 + public String getMessage() { 1.80 + // i18n? 1.81 + return "unexpected tag at #" + index + ": " + tag; 1.82 + } 1.83 + 1.84 + public final int tag; 1.85 + } 1.86 + 1.87 + public class EntryNotFound extends ConstantPoolException { 1.88 + EntryNotFound(Object value) { 1.89 + super(-1); 1.90 + this.value = value; 1.91 + } 1.92 + 1.93 + @Override 1.94 + public String getMessage() { 1.95 + // i18n? 1.96 + return "value not found: " + value; 1.97 + } 1.98 + 1.99 + public final Object value; 1.100 + } 1.101 + 1.102 + public static final int CONSTANT_Utf8 = 1; 1.103 + public static final int CONSTANT_Integer = 3; 1.104 + public static final int CONSTANT_Float = 4; 1.105 + public static final int CONSTANT_Long = 5; 1.106 + public static final int CONSTANT_Double = 6; 1.107 + public static final int CONSTANT_Class = 7; 1.108 + public static final int CONSTANT_String = 8; 1.109 + public static final int CONSTANT_Fieldref = 9; 1.110 + public static final int CONSTANT_Methodref = 10; 1.111 + public static final int CONSTANT_InterfaceMethodref = 11; 1.112 + public static final int CONSTANT_NameAndType = 12; 1.113 + 1.114 + ConstantPool(ClassReader cr) throws IOException, InvalidEntry { 1.115 + int count = cr.readUnsignedShort(); 1.116 + pool = new CPInfo[count]; 1.117 + for (int i = 1; i < count; i++) { 1.118 + int tag = cr.readUnsignedByte(); 1.119 + switch (tag) { 1.120 + case CONSTANT_Class: 1.121 + pool[i] = new CONSTANT_Class_info(this, cr); 1.122 + break; 1.123 + 1.124 + case CONSTANT_Double: 1.125 + pool[i] = new CONSTANT_Double_info(cr); 1.126 + i++; 1.127 + break; 1.128 + 1.129 + case CONSTANT_Fieldref: 1.130 + pool[i] = new CONSTANT_Fieldref_info(this, cr); 1.131 + break; 1.132 + 1.133 + case CONSTANT_Float: 1.134 + pool[i] = new CONSTANT_Float_info(cr); 1.135 + break; 1.136 + 1.137 + case CONSTANT_Integer: 1.138 + pool[i] = new CONSTANT_Integer_info(cr); 1.139 + break; 1.140 + 1.141 + case CONSTANT_InterfaceMethodref: 1.142 + pool[i] = new CONSTANT_InterfaceMethodref_info(this, cr); 1.143 + break; 1.144 + 1.145 + case CONSTANT_Long: 1.146 + pool[i] = new CONSTANT_Long_info(cr); 1.147 + i++; 1.148 + break; 1.149 + 1.150 + case CONSTANT_Methodref: 1.151 + pool[i] = new CONSTANT_Methodref_info(this, cr); 1.152 + break; 1.153 + 1.154 + case CONSTANT_NameAndType: 1.155 + pool[i] = new CONSTANT_NameAndType_info(this, cr); 1.156 + break; 1.157 + 1.158 + case CONSTANT_String: 1.159 + pool[i] = new CONSTANT_String_info(cr); 1.160 + break; 1.161 + 1.162 + case CONSTANT_Utf8: 1.163 + pool[i] = new CONSTANT_Utf8_info(cr); 1.164 + break; 1.165 + 1.166 + default: 1.167 + throw new InvalidEntry(i, tag); 1.168 + } 1.169 + } 1.170 + } 1.171 + 1.172 + public ConstantPool(CPInfo[] pool) { 1.173 + this.pool = pool; 1.174 + } 1.175 + 1.176 + public int size() { 1.177 + return pool.length; 1.178 + } 1.179 + 1.180 + public CPInfo get(int index) throws InvalidIndex { 1.181 + if (index <= 0 || index >= pool.length) 1.182 + throw new InvalidIndex(index); 1.183 + CPInfo info = pool[index]; 1.184 + if (info == null) { 1.185 + // this occurs for indices referencing the "second half" of an 1.186 + // 8 byte constant, such as CONSTANT_Double or CONSTANT_Long 1.187 + throw new InvalidIndex(index); 1.188 + } 1.189 + return pool[index]; 1.190 + } 1.191 + 1.192 + private CPInfo get(int index, int expected_type) throws InvalidIndex, UnexpectedEntry { 1.193 + CPInfo info = get(index); 1.194 + if (info.getTag() != expected_type) 1.195 + throw new UnexpectedEntry(index, expected_type, info.getTag()); 1.196 + return info; 1.197 + } 1.198 + 1.199 + public CONSTANT_Utf8_info getUTF8Info(int index) throws InvalidIndex, UnexpectedEntry { 1.200 + return ((CONSTANT_Utf8_info) get(index, CONSTANT_Utf8)); 1.201 + } 1.202 + 1.203 + public CONSTANT_Class_info getClassInfo(int index) throws InvalidIndex, UnexpectedEntry { 1.204 + return ((CONSTANT_Class_info) get(index, CONSTANT_Class)); 1.205 + } 1.206 + 1.207 + public CONSTANT_NameAndType_info getNameAndTypeInfo(int index) throws InvalidIndex, UnexpectedEntry { 1.208 + return ((CONSTANT_NameAndType_info) get(index, CONSTANT_NameAndType)); 1.209 + } 1.210 + 1.211 + public String getUTF8Value(int index) throws InvalidIndex, UnexpectedEntry { 1.212 + return getUTF8Info(index).value; 1.213 + } 1.214 + 1.215 + public int getUTF8Index(String value) throws EntryNotFound { 1.216 + for (int i = 1; i < pool.length; i++) { 1.217 + CPInfo info = pool[i]; 1.218 + if (info instanceof CONSTANT_Utf8_info && 1.219 + ((CONSTANT_Utf8_info) info).value.equals(value)) 1.220 + return i; 1.221 + } 1.222 + throw new EntryNotFound(value); 1.223 + } 1.224 + 1.225 + private CPInfo[] pool; 1.226 + 1.227 + public interface Visitor<R,P> { 1.228 + R visitClass(CONSTANT_Class_info info, P p); 1.229 + R visitDouble(CONSTANT_Double_info info, P p); 1.230 + R visitFieldref(CONSTANT_Fieldref_info info, P p); 1.231 + R visitFloat(CONSTANT_Float_info info, P p); 1.232 + R visitInteger(CONSTANT_Integer_info info, P p); 1.233 + R visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info info, P p); 1.234 + R visitLong(CONSTANT_Long_info info, P p); 1.235 + R visitNameAndType(CONSTANT_NameAndType_info info, P p); 1.236 + R visitMethodref(CONSTANT_Methodref_info info, P p); 1.237 + R visitString(CONSTANT_String_info info, P p); 1.238 + R visitUtf8(CONSTANT_Utf8_info info, P p); 1.239 + } 1.240 + 1.241 + public static abstract class CPInfo { 1.242 + CPInfo() { 1.243 + this.cp = null; 1.244 + } 1.245 + 1.246 + CPInfo(ConstantPool cp) { 1.247 + this.cp = cp; 1.248 + } 1.249 + 1.250 + public abstract int getTag(); 1.251 + 1.252 + public abstract <R,D> R accept(Visitor<R,D> visitor, D data); 1.253 + 1.254 + protected final ConstantPool cp; 1.255 + } 1.256 + 1.257 + public static abstract class CPRefInfo extends CPInfo { 1.258 + protected CPRefInfo(ConstantPool cp, ClassReader cr, int tag) throws IOException { 1.259 + super(cp); 1.260 + this.tag = tag; 1.261 + class_index = cr.readUnsignedShort(); 1.262 + name_and_type_index = cr.readUnsignedShort(); 1.263 + } 1.264 + 1.265 + protected CPRefInfo(ConstantPool cp, int tag, int class_index, int name_and_type_index) { 1.266 + super(cp); 1.267 + this.tag = tag; 1.268 + this.class_index = class_index; 1.269 + this.name_and_type_index = name_and_type_index; 1.270 + } 1.271 + 1.272 + public int getTag() { 1.273 + return tag; 1.274 + } 1.275 + 1.276 + public CONSTANT_Class_info getClassInfo() throws ConstantPoolException { 1.277 + return cp.getClassInfo(class_index); 1.278 + } 1.279 + 1.280 + public String getClassName() throws ConstantPoolException { 1.281 + return cp.getClassInfo(class_index).getName(); 1.282 + } 1.283 + 1.284 + public CONSTANT_NameAndType_info getNameAndTypeInfo() throws ConstantPoolException { 1.285 + return cp.getNameAndTypeInfo(name_and_type_index); 1.286 + } 1.287 + 1.288 + public final int tag; 1.289 + public final int class_index; 1.290 + public final int name_and_type_index; 1.291 + } 1.292 + 1.293 + public static class CONSTANT_Class_info extends CPInfo { 1.294 + CONSTANT_Class_info(ConstantPool cp, ClassReader cr) throws IOException { 1.295 + super(cp); 1.296 + name_index = cr.readUnsignedShort(); 1.297 + } 1.298 + 1.299 + public CONSTANT_Class_info(ConstantPool cp, int name_index) { 1.300 + super(cp); 1.301 + this.name_index = name_index; 1.302 + } 1.303 + 1.304 + public int getTag() { 1.305 + return CONSTANT_Class; 1.306 + } 1.307 + 1.308 + public String getName() throws ConstantPoolException { 1.309 + return cp.getUTF8Value(name_index); 1.310 + } 1.311 + 1.312 + @Override 1.313 + public String toString() { 1.314 + return "CONSTANT_Class_info[name_index: " + name_index + "]"; 1.315 + } 1.316 + 1.317 + public <R, D> R accept(Visitor<R, D> visitor, D data) { 1.318 + return visitor.visitClass(this, data); 1.319 + } 1.320 + 1.321 + public final int name_index; 1.322 + } 1.323 + 1.324 + public static class CONSTANT_Double_info extends CPInfo { 1.325 + CONSTANT_Double_info(ClassReader cr) throws IOException { 1.326 + value = cr.readDouble(); 1.327 + } 1.328 + 1.329 + public CONSTANT_Double_info(double value) { 1.330 + this.value = value; 1.331 + } 1.332 + 1.333 + public int getTag() { 1.334 + return CONSTANT_Double; 1.335 + } 1.336 + 1.337 + @Override 1.338 + public String toString() { 1.339 + return "CONSTANT_Double_info[value: " + value + "]"; 1.340 + } 1.341 + 1.342 + public <R, D> R accept(Visitor<R, D> visitor, D data) { 1.343 + return visitor.visitDouble(this, data); 1.344 + } 1.345 + 1.346 + public final double value; 1.347 + } 1.348 + 1.349 + public static class CONSTANT_Fieldref_info extends CPRefInfo { 1.350 + CONSTANT_Fieldref_info(ConstantPool cp, ClassReader cr) throws IOException { 1.351 + super(cp, cr, CONSTANT_Fieldref); 1.352 + } 1.353 + 1.354 + public CONSTANT_Fieldref_info(ConstantPool cp, int class_index, int name_and_type_index) { 1.355 + super(cp, CONSTANT_Fieldref, class_index, name_and_type_index); 1.356 + } 1.357 + 1.358 + @Override 1.359 + public String toString() { 1.360 + return "CONSTANT_Fieldref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]"; 1.361 + } 1.362 + 1.363 + public <R, D> R accept(Visitor<R, D> visitor, D data) { 1.364 + return visitor.visitFieldref(this, data); 1.365 + } 1.366 + } 1.367 + 1.368 + public static class CONSTANT_Float_info extends CPInfo { 1.369 + CONSTANT_Float_info(ClassReader cr) throws IOException { 1.370 + value = cr.readFloat(); 1.371 + } 1.372 + 1.373 + public CONSTANT_Float_info(float value) { 1.374 + this.value = value; 1.375 + } 1.376 + 1.377 + public int getTag() { 1.378 + return CONSTANT_Float; 1.379 + } 1.380 + 1.381 + @Override 1.382 + public String toString() { 1.383 + return "CONSTANT_Float_info[value: " + value + "]"; 1.384 + } 1.385 + 1.386 + public <R, D> R accept(Visitor<R, D> visitor, D data) { 1.387 + return visitor.visitFloat(this, data); 1.388 + } 1.389 + 1.390 + public final float value; 1.391 + } 1.392 + 1.393 + public static class CONSTANT_Integer_info extends CPInfo { 1.394 + CONSTANT_Integer_info(ClassReader cr) throws IOException { 1.395 + value = cr.readInt(); 1.396 + } 1.397 + 1.398 + public CONSTANT_Integer_info(int value) { 1.399 + this.value = value; 1.400 + } 1.401 + 1.402 + public int getTag() { 1.403 + return CONSTANT_Integer; 1.404 + } 1.405 + 1.406 + @Override 1.407 + public String toString() { 1.408 + return "CONSTANT_Integer_info[value: " + value + "]"; 1.409 + } 1.410 + 1.411 + public <R, D> R accept(Visitor<R, D> visitor, D data) { 1.412 + return visitor.visitInteger(this, data); 1.413 + } 1.414 + 1.415 + public final int value; 1.416 + } 1.417 + 1.418 + public static class CONSTANT_InterfaceMethodref_info extends CPRefInfo { 1.419 + CONSTANT_InterfaceMethodref_info(ConstantPool cp, ClassReader cr) throws IOException { 1.420 + super(cp, cr, CONSTANT_InterfaceMethodref); 1.421 + } 1.422 + 1.423 + public CONSTANT_InterfaceMethodref_info(ConstantPool cp, int class_index, int name_and_type_index) { 1.424 + super(cp, CONSTANT_InterfaceMethodref, class_index, name_and_type_index); 1.425 + } 1.426 + 1.427 + @Override 1.428 + public String toString() { 1.429 + return "CONSTANT_InterfaceMethodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]"; 1.430 + } 1.431 + 1.432 + public <R, D> R accept(Visitor<R, D> visitor, D data) { 1.433 + return visitor.visitInterfaceMethodref(this, data); 1.434 + } 1.435 + } 1.436 + 1.437 + public static class CONSTANT_Long_info extends CPInfo { 1.438 + CONSTANT_Long_info(ClassReader cr) throws IOException { 1.439 + value = cr.readLong(); 1.440 + } 1.441 + 1.442 + public CONSTANT_Long_info(long value) { 1.443 + this.value = value; 1.444 + } 1.445 + 1.446 + public int getTag() { 1.447 + return CONSTANT_Long; 1.448 + } 1.449 + 1.450 + @Override 1.451 + public String toString() { 1.452 + return "CONSTANT_Long_info[value: " + value + "]"; 1.453 + } 1.454 + 1.455 + public <R, D> R accept(Visitor<R, D> visitor, D data) { 1.456 + return visitor.visitLong(this, data); 1.457 + } 1.458 + 1.459 + public final long value; 1.460 + } 1.461 + 1.462 + public static class CONSTANT_Methodref_info extends CPRefInfo { 1.463 + CONSTANT_Methodref_info(ConstantPool cp, ClassReader cr) throws IOException { 1.464 + super(cp, cr, CONSTANT_Methodref); 1.465 + } 1.466 + 1.467 + public CONSTANT_Methodref_info(ConstantPool cp, int class_index, int name_and_type_index) { 1.468 + super(cp, CONSTANT_Methodref, class_index, name_and_type_index); 1.469 + } 1.470 + 1.471 + @Override 1.472 + public String toString() { 1.473 + return "CONSTANT_Methodref_info[class_index: " + class_index + ", name_and_type_index: " + name_and_type_index + "]"; 1.474 + } 1.475 + 1.476 + public <R, D> R accept(Visitor<R, D> visitor, D data) { 1.477 + return visitor.visitMethodref(this, data); 1.478 + } 1.479 + } 1.480 + 1.481 + public static class CONSTANT_NameAndType_info extends CPInfo { 1.482 + CONSTANT_NameAndType_info(ConstantPool cp, ClassReader cr) throws IOException { 1.483 + super(cp); 1.484 + name_index = cr.readUnsignedShort(); 1.485 + type_index = cr.readUnsignedShort(); 1.486 + } 1.487 + 1.488 + public CONSTANT_NameAndType_info(ConstantPool cp, int name_index, int type_index) { 1.489 + super(cp); 1.490 + this.name_index = name_index; 1.491 + this.type_index = type_index; 1.492 + } 1.493 + 1.494 + public int getTag() { 1.495 + return CONSTANT_NameAndType; 1.496 + } 1.497 + 1.498 + public String getName() throws ConstantPoolException { 1.499 + return cp.getUTF8Value(name_index); 1.500 + } 1.501 + 1.502 + public String getType() throws ConstantPoolException { 1.503 + return cp.getUTF8Value(type_index); 1.504 + } 1.505 + 1.506 + public <R, D> R accept(Visitor<R, D> visitor, D data) { 1.507 + return visitor.visitNameAndType(this, data); 1.508 + } 1.509 + 1.510 + public final int name_index; 1.511 + public final int type_index; 1.512 + } 1.513 + 1.514 + public static class CONSTANT_String_info extends CPInfo { 1.515 + CONSTANT_String_info(ClassReader cr) throws IOException { 1.516 + string_index = cr.readUnsignedShort(); 1.517 + } 1.518 + 1.519 + public CONSTANT_String_info(ConstantPool cp, int string_index) { 1.520 + super(cp); 1.521 + this.string_index = string_index; 1.522 + } 1.523 + 1.524 + public int getTag() { 1.525 + return CONSTANT_String; 1.526 + } 1.527 + 1.528 + public String getString() throws ConstantPoolException { 1.529 + return cp.getUTF8Value(string_index); 1.530 + } 1.531 + 1.532 + public <R, D> R accept(Visitor<R, D> visitor, D data) { 1.533 + return visitor.visitString(this, data); 1.534 + } 1.535 + 1.536 + public final int string_index; 1.537 + } 1.538 + 1.539 + public static class CONSTANT_Utf8_info extends CPInfo { 1.540 + CONSTANT_Utf8_info(ClassReader cr) throws IOException { 1.541 + value = cr.readUTF(); 1.542 + } 1.543 + 1.544 + public CONSTANT_Utf8_info(String value) { 1.545 + this.value = value; 1.546 + } 1.547 + 1.548 + public int getTag() { 1.549 + return CONSTANT_Utf8; 1.550 + } 1.551 + 1.552 + @Override 1.553 + public String toString() { 1.554 + return "CONSTANT_Utf8_info[value: " + value + "]"; 1.555 + } 1.556 + 1.557 + public <R, D> R accept(Visitor<R, D> visitor, D data) { 1.558 + return visitor.visitUtf8(this, data); 1.559 + } 1.560 + 1.561 + public final String value; 1.562 + } 1.563 + 1.564 + 1.565 +}