001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package components;
028:
029: import java.io.DataInput;
030: import java.io.DataOutput;
031: import java.io.IOException;
032: import jcc.Str2ID;
033: import util.*;
034: import jcc.Const;
035:
036: /*
037: * Represents an CONSTANT_Fieldref, CONSTANT_Methodref or
038: * CONSTANT_InterfaceMethodref.
039: */
040:
041: public class FMIrefConstant extends ConstantObject {
042: // These fields are filled in by Clas.resolveConstant().
043: public NameAndTypeConstant sig;
044: public ClassConstant clas;
045:
046: boolean computedID;
047: int ID;
048:
049: // These fields are read from the class file
050: public int classIndex;
051: public int sigIndex;
052:
053: FMIrefConstant() {
054: nSlots = 1;
055: }
056:
057: protected FMIrefConstant(int t, ClassConstant c,
058: NameAndTypeConstant s) {
059: tag = t;
060: clas = c;
061: sig = s;
062: resolved = true;
063: nSlots = 1;
064: }
065:
066: public void read(DataInput in) throws IOException {
067: classIndex = in.readUnsignedShort();
068: sigIndex = in.readUnsignedShort();
069: }
070:
071: public void resolve(ConstantObject table[]) {
072: if (resolved)
073: return;
074: try { //DEBUG
075: sig = (NameAndTypeConstant) table[sigIndex];
076: clas = (ClassConstant) table[classIndex];
077: } catch (RuntimeException t) {//DEBUG
078: System.out.println(Localizer.getString(
079: "fmirefconstant.trouble_processing", this
080: .toString()));
081: throw t;
082: }//end DEBUG
083: resolved = true;
084: }
085:
086: public void externalize(ConstantPool p) {
087: sig = (NameAndTypeConstant) p.add(sig);
088: clas = (ClassConstant) p.dup(clas);
089: }
090:
091: public void write(DataOutput out) throws IOException {
092: out.writeByte(tag);
093: if (resolved) {
094: out.writeShort(clas.index);
095: out.writeShort(sig.index);
096: } else {
097: throw new DataFormatException(
098: Localizer
099: .getString("fmirefconstant.unresolved_fmirefconstant.dataformatexception"));
100: //out.writeShort( classIndex );
101: //out.writeShort( sigIndex );
102: }
103: }
104:
105: public String toString() {
106: String t = (tag == Const.CONSTANT_FIELD) ? /*NOI18N*/"FieldRef: "
107: : (tag == Const.CONSTANT_METHOD) ? /*NOI18N*/"MethodRef: "
108: :
109: /*NOI18N*/"InterfaceRef: ";
110: if (resolved)
111: return t + clas.name.string + /*NOI18N*/" . "
112: + sig.name.string + /*NOI18N*/" : "
113: + sig.type.string;
114: else
115: return t + /*NOI18N*/"[ " + classIndex + /*NOI18N*/" . "
116: + sigIndex + /*NOI18N*/" ]";
117: }
118:
119: public void incReference() {
120: references++;
121: sig.incReference();
122: clas.incReference();
123: }
124:
125: public void decReference() {
126: references--;
127: sig.decReference();
128: clas.decReference();
129: }
130:
131: public int hashCode() {
132: return tag + sig.hashCode() + clas.hashCode();
133: }
134:
135: public boolean equals(Object o) {
136: if (o instanceof FMIrefConstant) {
137: FMIrefConstant f = (FMIrefConstant) o;
138: return tag == f.tag && clas.name.equals(f.clas.name)
139: && sig.name.equals(f.sig.name)
140: && sig.type.equals(f.sig.type);
141: } else {
142: return false;
143: }
144: }
145:
146: public int getID() {
147: if (!computedID) {
148: ID = Str2ID.sigHash.getID(sig.name, sig.type);
149: computedID = true;
150: }
151: return ID;
152: }
153:
154: public ClassComponent find(boolean isMethod) {
155: if (!computedID) {
156: ID = Str2ID.sigHash.getID(sig.name, sig.type);
157: computedID = true;
158: }
159: ClassInfo c = ClassInfo.lookupClass(clas.name.string);
160: while (c != null) {
161: ClassMemberInfo t[] = isMethod ? (ClassMemberInfo[]) c.methods
162: : (ClassMemberInfo[]) c.fields;
163: int l = t.length;
164: int this ID = this .getID();
165: for (int i = 0; i < l; i++) {
166: if (this ID == t[i].getID())
167: return t[i];
168: }
169: c = c.super ClassInfo;
170: }
171: return null;
172: }
173:
174: public boolean isResolved() {
175: return find(tag != Const.CONSTANT_FIELD) != null;
176: }
177: }
|