001: /*
002: * Copyright 1994-2003 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.tools.asm;
027:
028: import sun.tools.java.*;
029: import sun.tools.tree.StringExpression;
030: import java.util.Enumeration;
031: import java.util.Hashtable;
032: import java.util.Vector;
033: import java.io.IOException;
034: import java.io.DataOutputStream;
035:
036: /**
037: * A table of constants
038: *
039: * WARNING: The contents of this source file are not part of any
040: * supported API. Code that depends on them does so at its own risk:
041: * they are subject to change or removal without notice.
042: */
043: public final class ConstantPool implements RuntimeConstants {
044: Hashtable hash = new Hashtable(101);
045:
046: /**
047: * Find an entry, may return 0
048: */
049: public int index(Object obj) {
050: return ((ConstantPoolData) hash.get(obj)).index;
051: }
052:
053: /**
054: * Add an entry
055: */
056: public void put(Object obj) {
057: ConstantPoolData data = (ConstantPoolData) hash.get(obj);
058: if (data == null) {
059: if (obj instanceof String) {
060: data = new StringConstantData(this , (String) obj);
061: } else if (obj instanceof StringExpression) {
062: data = new StringExpressionConstantData(this ,
063: (StringExpression) obj);
064: } else if (obj instanceof ClassDeclaration) {
065: data = new ClassConstantData(this ,
066: (ClassDeclaration) obj);
067: } else if (obj instanceof Type) {
068: data = new ClassConstantData(this , (Type) obj);
069: } else if (obj instanceof MemberDefinition) {
070: data = new FieldConstantData(this ,
071: (MemberDefinition) obj);
072: } else if (obj instanceof NameAndTypeData) {
073: data = new NameAndTypeConstantData(this ,
074: (NameAndTypeData) obj);
075: } else if (obj instanceof Number) {
076: data = new NumberConstantData(this , (Number) obj);
077: }
078: hash.put(obj, data);
079: }
080: }
081:
082: /**
083: * Write to output
084: */
085: public void write(Environment env, DataOutputStream out)
086: throws IOException {
087: ConstantPoolData list[] = new ConstantPoolData[hash.size()];
088: String keys[] = new String[list.length];
089: int index = 1, count = 0;
090:
091: // Make a list of all the constant pool items
092: for (int n = 0; n < 5; n++) {
093: int first = count;
094: for (Enumeration e = hash.elements(); e.hasMoreElements();) {
095: ConstantPoolData data = (ConstantPoolData) e
096: .nextElement();
097: if (data.order() == n) {
098: keys[count] = sortKey(data);
099: list[count++] = data;
100: }
101: }
102: xsort(list, keys, first, count - 1);
103: }
104:
105: // Assign an index to each constant pool item
106: for (int n = 0; n < list.length; n++) {
107: ConstantPoolData data = list[n];
108: data.index = index;
109: index += data.width();
110: }
111:
112: // Write length
113: out.writeShort(index);
114:
115: // Write each constant pool item
116: for (int n = 0; n < count; n++) {
117: list[n].write(env, out, this );
118: }
119: }
120:
121: private static String sortKey(ConstantPoolData f) {
122: if (f instanceof NumberConstantData) {
123: Number num = ((NumberConstantData) f).num;
124: String str = num.toString();
125: int key = 3;
126: if (num instanceof Integer)
127: key = 0;
128: else if (num instanceof Float)
129: key = 1;
130: else if (num instanceof Long)
131: key = 2;
132: return "\0" + (char) (str.length() + key << 8) + str;
133: }
134: if (f instanceof StringExpressionConstantData)
135: return (String) ((StringExpressionConstantData) f).str
136: .getValue();
137: if (f instanceof FieldConstantData) {
138: MemberDefinition fd = ((FieldConstantData) f).field;
139: return fd.getName() + " " + fd.getType().getTypeSignature()
140: + " " + fd.getClassDeclaration().getName();
141: }
142: if (f instanceof NameAndTypeConstantData)
143: return ((NameAndTypeConstantData) f).name + " "
144: + ((NameAndTypeConstantData) f).type;
145: if (f instanceof ClassConstantData)
146: return ((ClassConstantData) f).name;
147: return ((StringConstantData) f).str;
148: }
149:
150: /**
151: * Quick sort an array of pool entries and a corresponding array of Strings
152: * that are the sort keys for the field.
153: */
154: private static void xsort(ConstantPoolData ff[], String ss[],
155: int left, int right) {
156: if (left >= right)
157: return;
158: String pivot = ss[left];
159: int l = left;
160: int r = right;
161: while (l < r) {
162: while (l <= right && ss[l].compareTo(pivot) <= 0)
163: l++;
164: while (r >= left && ss[r].compareTo(pivot) > 0)
165: r--;
166: if (l < r) {
167: // swap items at l and at r
168: ConstantPoolData def = ff[l];
169: String name = ss[l];
170: ff[l] = ff[r];
171: ff[r] = def;
172: ss[l] = ss[r];
173: ss[r] = name;
174: }
175: }
176: int middle = r;
177: // swap left and middle
178: ConstantPoolData def = ff[left];
179: String name = ss[left];
180: ff[left] = ff[middle];
181: ff[middle] = def;
182: ss[left] = ss[middle];
183: ss[middle] = name;
184: xsort(ff, ss, left, middle - 1);
185: xsort(ff, ss, middle + 1, right);
186: }
187:
188: }
|