001: /*
002: * @(#)CVMMethodType.java 1.14 06/10/10
003: *
004: * Copyright 1990-2006 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 vm;
028:
029: import java.util.Vector;
030:
031: /*
032: * Representation of signatures.
033: * They're little numbers, which are indices into
034: * a table.
035: */
036: /*
037: * CVM has a complex scheme for representing types as 16-bit
038: * cookies. This code mimics the run-time code and thus builds the
039: * corresponding data structures, to be ROMed.
040: */
041: public class CVMMethodType implements CVMTypeCode, util.ClassFileConst {
042:
043: /* instance fields */
044: public int entryNo;
045: public CVMMethodType next; // hash chain
046: public CVMSigForm form;
047: public int nDetails;
048: public int details[]; // array of scalar-type cookies.
049: public int detailOffset; // for use by writer.
050: public CVMMethodType listNext; // for variety management.
051:
052: /* static fields */
053: public static Vector methodTypes = new Vector();
054:
055: /*
056: * When you change this, also change the constant NMETHODTYPEHASH
057: * in typeid_impl.h
058: */
059: public final static int NHASH = 13 * 37; // arbitrary number, contains no 2
060: public static CVMMethodType hashTable[] = new CVMMethodType[NHASH];
061:
062: /* constructor */
063:
064: CVMMethodType(CVMSigForm f, int nd, int d[]) {
065: form = f;
066: nDetails = nd;
067: // COPY the data, as it is probably in a reusable temporary
068: // buffer
069: details = new int[nd];
070: System.arraycopy(d, 0, details, 0, nd);
071: synchronized (methodTypes) {
072: methodTypes.addElement(this );
073: }
074: }
075:
076: /* static methods */
077:
078: private static CVMMethodType lookup(CVMSigForm f, int nd, int d[]) {
079: int hashBucket = (int) (((long) ((f.data[0] << 16) + (nd > 0 ? d[0]
080: : 0)) & 0xffffffffL) % NHASH);
081: CVMMethodType mt;
082: searchloop: for (mt = hashTable[hashBucket]; mt != null; mt = mt.next) {
083: if (mt.form != f)
084: continue;
085: for (int i = 0; i < nd; i++) {
086: if (mt.details[i] != d[i]) {
087: continue searchloop;
088: }
089: }
090: // found one.
091: return mt;
092: }
093: /* not in table */
094: mt = new CVMMethodType(f, nd, d);
095: mt.next = hashTable[hashBucket];
096: hashTable[hashBucket] = mt;
097: return mt;
098: }
099:
100: /*
101: * static buffers used by parseSignature (and its parser) only
102: */
103: static int detailsbuffer[] = new int[257];
104: static int formSyllables[] = new int[CVMSignatureParser.NDATAWORDS];
105:
106: public static CVMMethodType parseSignature(String sig) {
107: CVMSignatureParser p = new CVMSignatureParser(sig,
108: detailsbuffer, formSyllables);
109: p.parse();
110:
111: CVMSigForm f = CVMSigForm.lookup(p.nSyllables(), formSyllables);
112: return lookup(f, p.nDetails(), detailsbuffer);
113: }
114:
115: }
116:
117: class CVMSignatureParser extends util.SignatureIterator implements
118: CVMTypeCode, util.ClassFileConst {
119:
120: /* instance data */
121: int details[];
122: int formData[];
123: int detailNo = 0;
124: int sylNo = 0;
125:
126: /* static data */
127: public static final int NDATAWORDS = 1 + 257 / CVMSigForm.SYLLABLESPERDATUM;
128:
129: /* constructor */
130: public CVMSignatureParser(String sig, int detailArray[],
131: int formDataArray[]) {
132: super (sig);
133: details = detailArray;
134: formData = formDataArray;
135: }
136:
137: /* instance methods */
138: /* to return the number of details, form syllables */
139:
140: public int nDetails() {
141: return detailNo;
142: }
143:
144: public int nSyllables() {
145: return sylNo;
146: }
147:
148: /* to run the whole show, in the right order */
149: public boolean parse() {
150: for (int i = 0; i < NDATAWORDS; i++) {
151: formData[i] = 0;
152: }
153: try {
154: iterate_returntype();
155: iterate_parameters();
156: insertSyllable(CVM_T_ENDFUNC);
157: } catch (util.DataFormatException e) {
158: e.printStackTrace();
159: return false;
160: }
161: return true;
162: }
163:
164: /* to manipulate the form syllables */
165: private void insertSyllable(int v) {
166: int wordno = sylNo / CVMSigForm.SYLLABLESPERDATUM;
167: int nshift = 4 * (sylNo % CVMSigForm.SYLLABLESPERDATUM);
168: formData[wordno] |= v << nshift;
169: sylNo += 1;
170: }
171:
172: /* called back from iterate_parameters and iterate_returntype */
173: public void do_void() {
174: insertSyllable(CVM_T_VOID);
175: }
176:
177: public void do_int() {
178: insertSyllable(CVM_T_INT);
179: }
180:
181: public void do_boolean() {
182: insertSyllable(CVM_T_BOOLEAN);
183: }
184:
185: public void do_char() {
186: insertSyllable(CVM_T_CHAR);
187: }
188:
189: public void do_short() {
190: insertSyllable(CVM_T_SHORT);
191: }
192:
193: public void do_long() {
194: insertSyllable(CVM_T_LONG);
195: }
196:
197: public void do_double() {
198: insertSyllable(CVM_T_DOUBLE);
199: }
200:
201: public void do_float() {
202: insertSyllable(CVM_T_FLOAT);
203: }
204:
205: public void do_byte() {
206: insertSyllable(CVM_T_BYTE);
207: }
208:
209: public void do_array(int depth, int tstart, int tend) {
210: int cookie = CVMDataType.parseSignature(sig.substring(tstart
211: - depth, tend + 1));
212: insertSyllable(CVM_T_OBJ);
213: details[detailNo++] = cookie;
214: }
215:
216: public void do_object(int tstart, int tend) {
217: do_array(0, tstart, tend);
218: }
219: }
|