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