001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.harmony.pack200.bytecode;
018:
019: import java.util.ArrayList;
020: import java.util.Iterator;
021: import java.util.List;
022:
023: import org.apache.harmony.pack200.Segment;
024:
025: public class ClassConstantPool {
026:
027: // These are the domains in sorted order.
028: public static int DOMAIN_UNDEFINED = 0;
029: public static int DOMAIN_INTEGER = 1;
030: public static int DOMAIN_FLOAT = 2;
031: public static int DOMAIN_STRING = 3;
032: public static int DOMAIN_NORMALASCIIZ = 4;
033: public static int DOMAIN_LONG = 5;
034: public static int DOMAIN_DOUBLE = 6;
035: public static int DOMAIN_CLASSREF = 7;
036: public static int DOMAIN_SIGNATUREASCIIZ = 8;
037: public static int DOMAIN_NAMEANDTYPE = 9;
038: public static int DOMAIN_FIELD = 10;
039: public static int DOMAIN_METHOD = 11;
040: public static int DOMAIN_ATTRIBUTEASCIIZ = 12;
041: public static int NUM_DOMAINS = DOMAIN_ATTRIBUTEASCIIZ + 1;
042:
043: // protected SortedSet sortedEntries = new TreeSet(new PoolComparator());
044: protected ClassPoolSet classPoolSet = new ClassPoolSet();
045:
046: public String toString() {
047: return entries.toString();
048: }
049:
050: private List others = new ArrayList();
051:
052: private List entries = new ArrayList();
053:
054: private boolean resolved;
055:
056: public ClassFileEntry add(ClassFileEntry entry) {
057: // We don't want duplicates.
058: // Only add in constant pools, but resolve all types since they may
059: // introduce new constant pool entries
060: // This is a handy way to see what's adding a ClassFileEntry - set a breakpoint on the print
061: // if(entry instanceof CPFieldRef) {
062: // SegmentUtils.debug("AAH:" + ((CPFieldRef)entry).comparisonString());
063: // if (((CPUTF8)entry).underlyingString().matches("Code")) {
064: // SegmentUtils.debug("Adding");
065: // }
066: // }
067: if (entry instanceof ConstantPoolEntry) {
068: classPoolSet.add(entry);
069: if (!entries.contains(entry)) {
070: entries.add(entry);
071: if (entry instanceof CPLong
072: || entry instanceof CPDouble)
073: entries.add(entry); //these get 2 slots because of their size
074: }
075: } else {
076: if (!others.contains(entry))
077: others.add(entry);
078: }
079: ClassFileEntry[] nestedEntries = entry
080: .getNestedClassFileEntries();
081: for (int i = 0; i < nestedEntries.length; i++) {
082: add(nestedEntries[i]);
083: }
084: return entry;
085: }
086:
087: public int indexOf(ClassFileEntry entry) {
088: if (!resolved)
089: throw new IllegalStateException(
090: "Constant pool is not yet resolved; this does not make any sense");
091: int entryIndex = entries.indexOf(entry);
092: // If the entry isn't found, answer -1. Otherwise answer the entry.
093: if (entryIndex != -1) {
094: return entryIndex + 1;
095: }
096: return -1;
097: }
098:
099: public int size() {
100: return entries.size();
101: }
102:
103: public ClassFileEntry get(int i) {
104: if (!resolved)
105: throw new IllegalStateException(
106: "Constant pool is not yet resolved; this does not make any sense");
107: return (ClassFileEntry) entries.get(--i);
108: }
109:
110: public void resolve(Segment segment) {
111: entries = new ArrayList();
112: Iterator sortedIterator = classPoolSet.iterator();
113: while (sortedIterator.hasNext()) {
114: ConstantPoolEntry entry = (ConstantPoolEntry) sortedIterator
115: .next();
116: entries.add(entry);
117: // need to do this both here and in the sort below
118: // so the indices are correct.
119: if (entry instanceof CPLong || entry instanceof CPDouble)
120: entries.add(entry); //these get 2 slots because of their size
121: }
122: resolve();
123: }
124:
125: public void resolve() {
126: resolved = true;
127: Iterator it = entries.iterator();
128: while (it.hasNext()) {
129: ClassFileEntry entry = (ClassFileEntry) it.next();
130: entry.resolve(this );
131: }
132: it = others.iterator();
133: while (it.hasNext()) {
134: ClassFileEntry entry = (ClassFileEntry) it.next();
135: entry.resolve(this );
136: }
137:
138: // Now that everything has been resolved, do one
139: // final sort of the class pool. This fixes up
140: // references, which are sorted by index in the
141: // class pool.
142: it = entries.iterator();
143: ClassPoolSet finalSort = new ClassPoolSet();
144: while (it.hasNext()) {
145: finalSort.add(it.next());
146: }
147: it = finalSort.iterator();
148: entries = new ArrayList();
149: while (it.hasNext()) {
150: ClassFileEntry entry = (ClassFileEntry) it.next();
151: entries.add(entry);
152: if (entry instanceof CPLong || entry instanceof CPDouble)
153: entries.add(entry); //these get 2 slots because of their size
154: }
155:
156: // Now that the indices have been re-sorted, need
157: // to re-resolve to update references. This should
158: // not add any new entries this time through.
159: it = entries.iterator();
160: while (it.hasNext()) {
161: ClassFileEntry entry = (ClassFileEntry) it.next();
162: entry.resolve(this );
163: }
164: // Also need to re-resolve the others.
165: it = others.iterator();
166: while (it.hasNext()) {
167: ClassFileEntry entry = (ClassFileEntry) it.next();
168: entry.resolve(this );
169: }
170: }
171:
172: /**
173: * Answer the collection of CPClasses currently held
174: * by the ClassPoolSet. This is used to calculate relevant
175: * classes when generating the set of relevant inner
176: * classes (ic_relevant())
177: * @return ArrayList collection of all classes.
178: *
179: * NOTE: when this list is answered, the classes may not
180: * yet be resolved.
181: */
182: public List allClasses() {
183: List classesList = new ArrayList();
184: Iterator it = classPoolSet.partialIterator(DOMAIN_CLASSREF,
185: DOMAIN_CLASSREF);
186: while (it.hasNext()) {
187: classesList.add(it.next());
188: }
189: return classesList;
190: }
191: }
|