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 vm;
028:
029: import components.*;
030: import util.*;
031: import jcc.Const;
032:
033: /*
034: * An array is a class.
035: * It is a subclass of java.lang.Object.
036: * It has all the class-related runtime data structures, or at least
037: * may of them.
038: * It is not read in from class files, but is made up on-the-fly
039: * when the classresolver sees a reference to a classname starting with
040: * "[".
041: *
042: * In order to resolve such references early, we must do likewise here.
043: */
044: public class ArrayClassInfo extends ClassInfo {
045:
046: private static int nFake = 0;
047: public int arrayClassNumber;
048: public int depth;
049: public int baseType;
050: public String baseName;
051: public ClassConstant baseClass;
052: public ClassConstant subarrayClass;
053:
054: /*
055: * Given signature s,
056: * fill in
057: * depth ( i.e. number of opening [ )
058: * basetype ( i.e. thing after the last [ )
059: * and baseClass ( if basetype is a classtype )
060: */
061: private void fillInTypeInfo(String s) throws DataFormatException {
062: int index = 0;
063: char c;
064: while ((c = s.charAt(index)) == Const.SIGC_ARRAY)
065: index++;
066: depth = index;
067: switch (c) {
068: case Const.SIGC_INT:
069: baseType = Const.T_INT;
070: baseName = "Int";
071: break;
072: case Const.SIGC_LONG:
073: baseType = Const.T_LONG;
074: baseName = "Long";
075: break;
076: case Const.SIGC_FLOAT:
077: baseType = Const.T_FLOAT;
078: baseName = "Float";
079: break;
080: case Const.SIGC_DOUBLE:
081: baseType = Const.T_DOUBLE;
082: baseName = "Double";
083: break;
084: case Const.SIGC_BOOLEAN:
085: baseType = Const.T_BOOLEAN;
086: baseName = "Boolean";
087: break;
088: case Const.SIGC_BYTE:
089: baseType = Const.T_BYTE;
090: baseName = "Byte";
091: break;
092: case Const.SIGC_CHAR:
093: baseType = Const.T_CHAR;
094: baseName = "Char";
095: break;
096: case Const.SIGC_SHORT:
097: baseType = Const.T_SHORT;
098: baseName = "Short";
099: break;
100: case Const.SIGC_CLASS:
101: baseType = Const.T_CLASS;
102: int start = ++index;
103: while (s.charAt(index) != Const.SIGC_ENDCLASS) {
104: index++;
105: }
106:
107: baseClass = new ClassConstant(new UnicodeConstant(s
108: .substring(start, index)));
109: break;
110:
111: default:
112: throw new DataFormatException(
113: Localizer
114: .getString(
115: "arrayclassinfo.malformed_array_type_string.dataformatexception",
116: s));
117: }
118: // For EVM, we want to know the sub-class, which is different from
119: // the base class.
120: if (depth > 1) {
121: subarrayClass = new ClassConstant(new UnicodeConstant(s
122: .substring(1)));
123: } else if ((depth == 1) && (baseClass != null)) {
124: subarrayClass = baseClass;
125: }
126:
127: }
128:
129: private void fakeConstantPool() {
130: // 0 -- unused
131: // 1 -- depth as integer
132: // 2 -- base type tag as integer
133: // 3 -- base class ref, if a ref type
134: // 4 -- subarray class ref, if depth > 1
135: // base type if depth==1 && its a class ref array type
136: // 5 -- self class ref
137: // 6 -- UTF8 for entry 3
138: // 7 -- UTF8 for entry 4
139: // 8 -- UTF8 for entry 5
140:
141: // MAKE A CHANGE FOR KVM
142:
143: if (false) {
144: int nconstants = 9;
145: constants = new ConstantObject[nconstants];
146: constants[1] = new SingleValueConstant(depth);
147: constants[2] = new SingleValueConstant(baseType);
148: if (baseClass == null) {
149: constants[3] = new SingleValueConstant(0);
150: constants[6] = new SingleValueConstant(0);
151: } else {
152: constants[3] = baseClass;
153: constants[6] = baseClass.name;
154: }
155: // for EVM, point at the subarray type.
156: if (subarrayClass == null) {
157: constants[4] = new SingleValueConstant(0);
158: constants[7] = new SingleValueConstant(0);
159: } else {
160: constants[4] = subarrayClass;
161: constants[7] = subarrayClass.name;
162: }
163: constants[5] = this Class; // EVM 4 => 5
164: constants[8] = this Class.name; // EVM 5 => 7
165: } else {
166: int nconstants = 2;
167: constants = new ConstantObject[nconstants];
168: if (subarrayClass == null) {
169: constants[1] = new SingleValueConstant(baseType);
170: } else {
171: constants[1] = subarrayClass;
172: }
173: }
174: }
175:
176: public ArrayClassInfo(boolean v, String s)
177: throws DataFormatException {
178: super (v);
179: arrayClassNumber = nFake++;
180: fillInTypeInfo(s);
181: className = s;
182: this Class = new ClassConstant(new UnicodeConstant(s));
183: super ClassInfo = lookupClass(/*NOI18N*/"java/lang/Object");
184: super Class = super ClassInfo.this Class;
185: access = Const.ACC_FINAL | Const.ACC_ABSTRACT
186: | Const.ACC_PUBLIC;
187: fakeConstantPool();
188: methods = new MethodInfo[0];
189: fields = new FieldInfo[0];
190: enterClass(s);
191: }
192:
193: public boolean countReferences(boolean v) {
194: // some entries are magic. The others
195: // can get shared or whacked.
196: if (false) {
197: constants[1].incReference(); // depth
198: constants[2].incReference(); // baseType code
199: constants[3].incReference(); // base class pointer
200: constants[4].incReference(); // subarray class pointer
201: } else {
202: constants[1].incReference(); // base type
203: }
204: return super .countReferences(v);
205: }
206:
207: public void externalize(ConstantPool p) {
208: if (verbose) {
209: log.println(Localizer.getString(
210: "arrayclassinfo.externalizing_class", className));
211: }
212: externalizeConstants(p);
213: // DONT DO THISthisClass = (ClassConstant)p.dup( thisClass );
214: if (super Class != null) {
215: super Class = (ClassConstant) p.dup(super Class);
216: // THIS SHOULD WORK.
217: }
218: }
219:
220: protected String createGenericNativeName() {
221: return /*NOI18N*/"fakeArray" + arrayClassNumber;
222: }
223: }
|