001: /*
002: * Copyright 2002-2005 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.javap;
027:
028: import java.util.*;
029: import java.io.*;
030:
031: import static sun.tools.javap.RuntimeConstants.*;
032:
033: /**
034: * Strores method data informastion.
035: *
036: * @author Sucheta Dambalkar (Adopted code from jdis)
037: */
038: public class MethodData {
039:
040: ClassData cls;
041: int access;
042: int name_index;
043: int descriptor_index;
044: int attributes_count;
045: byte[] code;
046: Vector exception_table = new Vector(0);
047: Vector lin_num_tb = new Vector(0);
048: Vector loc_var_tb = new Vector(0);
049: StackMapTableData[] stackMapTable;
050: StackMapData[] stackMap;
051: int[] exc_index_table = null;
052: Vector attrs = new Vector(0);
053: Vector code_attrs = new Vector(0);
054: int max_stack, max_locals;
055: boolean isSynthetic = false;
056: boolean isDeprecated = false;
057:
058: public MethodData(ClassData cls) {
059: this .cls = cls;
060: }
061:
062: /**
063: * Read method info.
064: */
065: public void read(DataInputStream in) throws IOException {
066: access = in.readUnsignedShort();
067: name_index = in.readUnsignedShort();
068: descriptor_index = in.readUnsignedShort();
069: int attributes_count = in.readUnsignedShort();
070: for (int i = 0; i < attributes_count; i++) {
071: int attr_name_index = in.readUnsignedShort();
072:
073: readAttr: {
074: if (cls.getTag(attr_name_index) == CONSTANT_UTF8) {
075: String attr_name = cls.getString(attr_name_index);
076: if (attr_name.equals("Code")) {
077: readCode(in);
078: AttrData attr = new AttrData(cls);
079: attr.read(attr_name_index);
080: attrs.addElement(attr);
081: break readAttr;
082: } else if (attr_name.equals("Exceptions")) {
083: readExceptions(in);
084: AttrData attr = new AttrData(cls);
085: attr.read(attr_name_index);
086: attrs.addElement(attr);
087: break readAttr;
088: } else if (attr_name.equals("Synthetic")) {
089: if (in.readInt() != 0)
090: throw new ClassFormatError(
091: "invalid Synthetic attr length");
092: isSynthetic = true;
093: AttrData attr = new AttrData(cls);
094: attr.read(attr_name_index);
095: attrs.addElement(attr);
096: break readAttr;
097: } else if (attr_name.equals("Deprecated")) {
098: if (in.readInt() != 0)
099: throw new ClassFormatError(
100: "invalid Synthetic attr length");
101: isDeprecated = true;
102: AttrData attr = new AttrData(cls);
103: attr.read(attr_name_index);
104: attrs.addElement(attr);
105: break readAttr;
106: }
107: }
108: AttrData attr = new AttrData(cls);
109: attr.read(attr_name_index, in);
110: attrs.addElement(attr);
111: }
112: }
113: }
114:
115: /**
116: * Read code attribute info.
117: */
118: public void readCode(DataInputStream in) throws IOException {
119:
120: int attr_length = in.readInt();
121: max_stack = in.readUnsignedShort();
122: max_locals = in.readUnsignedShort();
123: int codelen = in.readInt();
124:
125: code = new byte[codelen];
126: int totalread = 0;
127: while (totalread < codelen) {
128: totalread += in.read(code, totalread, codelen - totalread);
129: }
130: // in.read(code, 0, codelen);
131: int clen = 0;
132: readExceptionTable(in);
133: int code_attributes_count = in.readUnsignedShort();
134:
135: for (int k = 0; k < code_attributes_count; k++) {
136: int table_name_index = in.readUnsignedShort();
137: int table_name_tag = cls.getTag(table_name_index);
138: AttrData attr = new AttrData(cls);
139: if (table_name_tag == CONSTANT_UTF8) {
140: String table_name_tstr = cls
141: .getString(table_name_index);
142: if (table_name_tstr.equals("LineNumberTable")) {
143: readLineNumTable(in);
144: attr.read(table_name_index);
145: } else if (table_name_tstr.equals("LocalVariableTable")) {
146: readLocVarTable(in);
147: attr.read(table_name_index);
148: } else if (table_name_tstr.equals("StackMapTable")) {
149: readStackMapTable(in);
150: attr.read(table_name_index);
151: } else if (table_name_tstr.equals("StackMap")) {
152: readStackMap(in);
153: attr.read(table_name_index);
154: } else {
155: attr.read(table_name_index, in);
156: }
157: code_attrs.addElement(attr);
158: continue;
159: }
160:
161: attr.read(table_name_index, in);
162: code_attrs.addElement(attr);
163: }
164: }
165:
166: /**
167: * Read exception table info.
168: */
169: void readExceptionTable(DataInputStream in) throws IOException {
170: int exception_table_len = in.readUnsignedShort();
171: exception_table = new Vector(exception_table_len);
172: for (int l = 0; l < exception_table_len; l++) {
173: exception_table.addElement(new TrapData(in, l));
174: }
175: }
176:
177: /**
178: * Read LineNumberTable attribute info.
179: */
180: void readLineNumTable(DataInputStream in) throws IOException {
181: int attr_len = in.readInt(); // attr_length
182: int lin_num_tb_len = in.readUnsignedShort();
183: lin_num_tb = new Vector(lin_num_tb_len);
184: for (int l = 0; l < lin_num_tb_len; l++) {
185: lin_num_tb.addElement(new LineNumData(in));
186: }
187: }
188:
189: /**
190: * Read LocalVariableTable attribute info.
191: */
192: void readLocVarTable(DataInputStream in) throws IOException {
193: int attr_len = in.readInt(); // attr_length
194: int loc_var_tb_len = in.readUnsignedShort();
195: loc_var_tb = new Vector(loc_var_tb_len);
196: for (int l = 0; l < loc_var_tb_len; l++) {
197: loc_var_tb.addElement(new LocVarData(in));
198: }
199: }
200:
201: /**
202: * Read Exception attribute info.
203: */
204: public void readExceptions(DataInputStream in) throws IOException {
205: int attr_len = in.readInt(); // attr_length in prog
206: int num_exceptions = in.readUnsignedShort();
207: exc_index_table = new int[num_exceptions];
208: for (int l = 0; l < num_exceptions; l++) {
209: int exc = in.readShort();
210: exc_index_table[l] = exc;
211: }
212: }
213:
214: /**
215: * Read StackMapTable attribute info.
216: */
217: void readStackMapTable(DataInputStream in) throws IOException {
218: int attr_len = in.readInt(); //attr_length
219: int stack_map_tb_len = in.readUnsignedShort();
220: stackMapTable = new StackMapTableData[stack_map_tb_len];
221: for (int i = 0; i < stack_map_tb_len; i++) {
222: stackMapTable[i] = StackMapTableData.getInstance(in, this );
223: }
224: }
225:
226: /**
227: * Read StackMap attribute info.
228: */
229: void readStackMap(DataInputStream in) throws IOException {
230: int attr_len = in.readInt(); //attr_length
231: int stack_map_len = in.readUnsignedShort();
232: stackMap = new StackMapData[stack_map_len];
233: for (int i = 0; i < stack_map_len; i++) {
234: stackMap[i] = new StackMapData(in, this );
235: }
236: }
237:
238: /**
239: * Return access of the method.
240: */
241: public String[] getAccess() {
242:
243: Vector v = new Vector();
244: if ((access & ACC_PUBLIC) != 0)
245: v.addElement("public");
246: if ((access & ACC_PRIVATE) != 0)
247: v.addElement("private");
248: if ((access & ACC_PROTECTED) != 0)
249: v.addElement("protected");
250: if ((access & ACC_STATIC) != 0)
251: v.addElement("static");
252: if ((access & ACC_FINAL) != 0)
253: v.addElement("final");
254: if ((access & ACC_SYNCHRONIZED) != 0)
255: v.addElement("synchronized");
256: if ((access & ACC_NATIVE) != 0)
257: v.addElement("native");
258: if ((access & ACC_ABSTRACT) != 0)
259: v.addElement("abstract");
260: if ((access & ACC_STRICT) != 0)
261: v.addElement("strictfp");
262:
263: String[] accflags = new String[v.size()];
264: v.copyInto(accflags);
265: return accflags;
266: }
267:
268: /**
269: * Return name of the method.
270: */
271: public String getName() {
272: return cls.getStringValue(name_index);
273: }
274:
275: /**
276: * Return internal siganature of the method.
277: */
278: public String getInternalSig() {
279: return cls.getStringValue(descriptor_index);
280: }
281:
282: /**
283: * Return java return type signature of method.
284: */
285: public String getReturnType() {
286:
287: String rttype = (new TypeSignature(getInternalSig()))
288: .getReturnType();
289: return rttype;
290: }
291:
292: /**
293: * Return java type parameter signature.
294: */
295: public String getParameters() {
296: String ptype = (new TypeSignature(getInternalSig()))
297: .getParameters();
298:
299: return ptype;
300: }
301:
302: /**
303: * Return code attribute data of a method.
304: */
305: public byte[] getCode() {
306: return code;
307: }
308:
309: /**
310: * Return LineNumberTable size.
311: */
312: public int getnumlines() {
313: return lin_num_tb.size();
314: }
315:
316: /**
317: * Return LineNumberTable
318: */
319: public Vector getlin_num_tb() {
320: return lin_num_tb;
321: }
322:
323: /**
324: * Return LocalVariableTable size.
325: */
326: public int getloc_var_tbsize() {
327: return loc_var_tb.size();
328: }
329:
330: /**
331: * Return LocalVariableTable.
332: */
333: public Vector getloc_var_tb() {
334: return loc_var_tb;
335: }
336:
337: /**
338: * Return StackMap.
339: */
340: public StackMapData[] getStackMap() {
341: return stackMap;
342: }
343:
344: /**
345: * Return StackMapTable.
346: */
347: public StackMapTableData[] getStackMapTable() {
348: return stackMapTable;
349: }
350:
351: /**
352: * Return number of arguments of that method.
353: */
354: public int getArgumentlength() {
355: return new TypeSignature(getInternalSig()).getArgumentlength();
356: }
357:
358: /**
359: * Return true if method is static
360: */
361: public boolean isStatic() {
362: if ((access & ACC_STATIC) != 0)
363: return true;
364: return false;
365: }
366:
367: /**
368: * Return max depth of operand stack.
369: */
370: public int getMaxStack() {
371: return max_stack;
372: }
373:
374: /**
375: * Return number of local variables.
376: */
377: public int getMaxLocals() {
378: return max_locals;
379: }
380:
381: /**
382: * Return exception index table in Exception attribute.
383: */
384: public int[] get_exc_index_table() {
385: return exc_index_table;
386: }
387:
388: /**
389: * Return exception table in code attributre.
390: */
391: public Vector getexception_table() {
392: return exception_table;
393: }
394:
395: /**
396: * Return method attributes.
397: */
398: public Vector getAttributes() {
399: return attrs;
400: }
401:
402: /**
403: * Return code attributes.
404: */
405: public Vector getCodeAttributes() {
406: return code_attrs;
407: }
408:
409: /**
410: * Return true if method id synthetic.
411: */
412: public boolean isSynthetic() {
413: return isSynthetic;
414: }
415:
416: /**
417: * Return true if method is deprecated.
418: */
419: public boolean isDeprecated() {
420: return isDeprecated;
421: }
422: }
|