Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/tools/java/BinaryConstantPool.java
38918 views
/*1* Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.tools.java;2627import java.io.IOException;28import java.io.DataInputStream;29import java.io.DataOutputStream;30import java.util.Vector;31import java.util.Hashtable;3233/**34* This class is used to represent a constant table once35* it is read from a class file.36*37* WARNING: The contents of this source file are not part of any38* supported API. Code that depends on them does so at its own risk:39* they are subject to change or removal without notice.40*/41public final42class BinaryConstantPool implements Constants {43private byte types[];44private Object cpool[];4546/**47* Constructor48*/49BinaryConstantPool(DataInputStream in) throws IOException {50// JVM 4.1 ClassFile.constant_pool_count51types = new byte[in.readUnsignedShort()];52cpool = new Object[types.length];53for (int i = 1 ; i < cpool.length ; i++) {54int j = i;55// JVM 4.4 cp_info.tag56switch(types[i] = in.readByte()) {57case CONSTANT_UTF8:58cpool[i] = in.readUTF();59break;6061case CONSTANT_INTEGER:62cpool[i] = new Integer(in.readInt());63break;64case CONSTANT_FLOAT:65cpool[i] = new Float(in.readFloat());66break;67case CONSTANT_LONG:68cpool[i++] = new Long(in.readLong());69break;70case CONSTANT_DOUBLE:71cpool[i++] = new Double(in.readDouble());72break;7374case CONSTANT_CLASS:75case CONSTANT_STRING:76// JVM 4.4.3 CONSTANT_String_info.string_index77// or JVM 4.4.1 CONSTANT_Class_info.name_index78cpool[i] = new Integer(in.readUnsignedShort());79break;8081case CONSTANT_FIELD:82case CONSTANT_METHOD:83case CONSTANT_INTERFACEMETHOD:84case CONSTANT_NAMEANDTYPE:85// JVM 4.4.2 CONSTANT_*ref_info.class_index & name_and_type_index86cpool[i] = new Integer((in.readUnsignedShort() << 16) | in.readUnsignedShort());87break;8889case CONSTANT_METHODHANDLE:90cpool[i] = readBytes(in, 3);91break;92case CONSTANT_METHODTYPE:93cpool[i] = readBytes(in, 2);94break;95case CONSTANT_INVOKEDYNAMIC:96cpool[i] = readBytes(in, 4);97break;9899case 0:100default:101throw new ClassFormatError("invalid constant type: " + (int)types[i]);102}103}104}105106private byte[] readBytes(DataInputStream in, int cnt) throws IOException {107byte[] b = new byte[cnt];108in.readFully(b);109return b;110}111112/**113* get a integer114*/115public int getInteger(int n) {116return (n == 0) ? 0 : ((Number)cpool[n]).intValue();117}118119/**120* get a value121*/122public Object getValue(int n) {123return (n == 0) ? null : cpool[n];124}125126/**127* get a string128*/129public String getString(int n) {130return (n == 0) ? null : (String)cpool[n];131}132133/**134* get an identifier135*/136public Identifier getIdentifier(int n) {137return (n == 0) ? null : Identifier.lookup(getString(n));138}139140/**141* get class declaration142*/143public ClassDeclaration getDeclarationFromName(Environment env, int n) {144return (n == 0) ? null : env.getClassDeclaration(Identifier.lookup(getString(n).replace('/','.')));145}146147/**148* get class declaration149*/150public ClassDeclaration getDeclaration(Environment env, int n) {151return (n == 0) ? null : getDeclarationFromName(env, getInteger(n));152}153154/**155* get a type from a type signature156*/157public Type getType(int n) {158return Type.tType(getString(n));159}160161/**162* get the type of constant given an index163*/164public int getConstantType(int n) {165return types[n];166}167168/**169* get the n-th constant from the constant pool170*/171public Object getConstant(int n, Environment env) {172int constant_type = getConstantType(n);173switch (constant_type) {174case CONSTANT_INTEGER:175case CONSTANT_FLOAT:176case CONSTANT_LONG:177case CONSTANT_DOUBLE:178case CONSTANT_METHODHANDLE:179case CONSTANT_METHODTYPE:180case CONSTANT_INVOKEDYNAMIC:181return getValue(n);182183case CONSTANT_CLASS:184return getDeclaration(env, n);185186case CONSTANT_STRING:187return getString(getInteger(n));188189case CONSTANT_FIELD:190case CONSTANT_METHOD:191case CONSTANT_INTERFACEMETHOD:192try {193int key = getInteger(n);194ClassDefinition clazz =195getDeclaration(env, key >> 16).getClassDefinition(env);196int name_and_type = getInteger(key & 0xFFFF);197Identifier id = getIdentifier(name_and_type >> 16);198Type type = getType(name_and_type & 0xFFFF);199200for (MemberDefinition field = clazz.getFirstMatch(id);201field != null;202field = field.getNextMatch()) {203Type field_type = field.getType();204if ((constant_type == CONSTANT_FIELD)205? (field_type == type)206: (field_type.equalArguments(type)))207return field;208}209} catch (ClassNotFound e) {210}211return null;212213default:214throw new ClassFormatError("invalid constant type: " +215constant_type);216}217}218219220/**221* Get a list of dependencies, ie: all the classes referenced in this222* constant pool.223*/224public Vector getDependencies(Environment env) {225Vector v = new Vector();226for (int i = 1 ; i < cpool.length ; i++) {227switch(types[i]) {228case CONSTANT_CLASS:229v.addElement(getDeclarationFromName(env, getInteger(i)));230break;231}232}233return v;234}235236Hashtable indexHashObject, indexHashAscii;237Vector MoreStuff;238239/**240* Find the index of an Object in the constant pool241*/242public int indexObject(Object obj, Environment env) {243if (indexHashObject == null)244createIndexHash(env);245Integer result = (Integer)indexHashObject.get(obj);246if (result == null)247throw new IndexOutOfBoundsException("Cannot find object " + obj + " of type " +248obj.getClass() + " in constant pool");249return result.intValue();250}251252/**253* Find the index of an ascii string in the constant pool. If it's not in254* the constant pool, then add it at the end.255*/256public int indexString(String string, Environment env) {257if (indexHashObject == null)258createIndexHash(env);259Integer result = (Integer)indexHashAscii.get(string);260if (result == null) {261if (MoreStuff == null) MoreStuff = new Vector();262result = new Integer(cpool.length + MoreStuff.size());263MoreStuff.addElement(string);264indexHashAscii.put(string, result);265}266return result.intValue();267}268269/**270* Create a hash table of all the items in the constant pool that could271* possibly be referenced from the outside.272*/273274public void createIndexHash(Environment env) {275indexHashObject = new Hashtable();276indexHashAscii = new Hashtable();277for (int i = 1; i < cpool.length; i++) {278if (types[i] == CONSTANT_UTF8) {279indexHashAscii.put(cpool[i], new Integer(i));280} else {281try {282indexHashObject.put(getConstant(i, env), new Integer(i));283} catch (ClassFormatError e) { }284}285}286}287288289/**290* Write out the contents of the constant pool, including any additions291* that have been added.292*/293public void write(DataOutputStream out, Environment env) throws IOException {294int length = cpool.length;295if (MoreStuff != null)296length += MoreStuff.size();297out.writeShort(length);298for (int i = 1 ; i < cpool.length; i++) {299int type = types[i];300Object x = cpool[i];301out.writeByte(type);302switch (type) {303case CONSTANT_UTF8:304out.writeUTF((String) x);305break;306case CONSTANT_INTEGER:307out.writeInt(((Number)x).intValue());308break;309case CONSTANT_FLOAT:310out.writeFloat(((Number)x).floatValue());311break;312case CONSTANT_LONG:313out.writeLong(((Number)x).longValue());314i++;315break;316case CONSTANT_DOUBLE:317out.writeDouble(((Number)x).doubleValue());318i++;319break;320case CONSTANT_CLASS:321case CONSTANT_STRING:322out.writeShort(((Number)x).intValue());323break;324case CONSTANT_FIELD:325case CONSTANT_METHOD:326case CONSTANT_INTERFACEMETHOD:327case CONSTANT_NAMEANDTYPE: {328int value = ((Number)x).intValue();329out.writeShort(value >> 16);330out.writeShort(value & 0xFFFF);331break;332}333case CONSTANT_METHODHANDLE:334case CONSTANT_METHODTYPE:335case CONSTANT_INVOKEDYNAMIC:336out.write((byte[])x, 0, ((byte[])x).length);337break;338default:339throw new ClassFormatError("invalid constant type: "340+ (int)types[i]);341}342}343for (int i = cpool.length; i < length; i++) {344String string = (String)(MoreStuff.elementAt(i - cpool.length));345out.writeByte(CONSTANT_UTF8);346out.writeUTF(string);347}348}349350}351352353