jtulach@144
|
1 |
/*
|
jtulach@144
|
2 |
* Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
|
jtulach@144
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
jtulach@144
|
4 |
*
|
jtulach@144
|
5 |
* This code is free software; you can redistribute it and/or modify it
|
jtulach@144
|
6 |
* under the terms of the GNU General Public License version 2 only, as
|
jtulach@144
|
7 |
* published by the Free Software Foundation. Oracle designates this
|
jtulach@144
|
8 |
* particular file as subject to the "Classpath" exception as provided
|
jtulach@144
|
9 |
* by Oracle in the LICENSE file that accompanied this code.
|
jtulach@144
|
10 |
*
|
jtulach@144
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT
|
jtulach@144
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
jtulach@144
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
jtulach@144
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that
|
jtulach@144
|
15 |
* accompanied this code).
|
jtulach@144
|
16 |
*
|
jtulach@144
|
17 |
* You should have received a copy of the GNU General Public License version
|
jtulach@144
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation,
|
jtulach@144
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
jtulach@144
|
20 |
*
|
jtulach@144
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
jtulach@144
|
22 |
* or visit www.oracle.com if you need additional information or have any
|
jtulach@144
|
23 |
* questions.
|
jtulach@144
|
24 |
*/
|
jtulach@144
|
25 |
|
jtulach@167
|
26 |
package org.apidesign.javap;
|
jtulach@144
|
27 |
|
jtulach@144
|
28 |
|
jaroslav@397
|
29 |
import java.io.DataInputStream;
|
jaroslav@397
|
30 |
import java.io.IOException;
|
jtulach@167
|
31 |
import static org.apidesign.javap.RuntimeConstants.*;
|
jtulach@144
|
32 |
|
jtulach@144
|
33 |
/**
|
jtulach@144
|
34 |
* Strores method data informastion.
|
jtulach@144
|
35 |
*
|
jtulach@144
|
36 |
* @author Sucheta Dambalkar (Adopted code from jdis)
|
jtulach@144
|
37 |
*/
|
jtulach@144
|
38 |
public class MethodData {
|
jtulach@144
|
39 |
|
jtulach@144
|
40 |
ClassData cls;
|
jtulach@144
|
41 |
int access;
|
jtulach@144
|
42 |
int name_index;
|
jtulach@144
|
43 |
int descriptor_index;
|
jtulach@144
|
44 |
int attributes_count;
|
jtulach@144
|
45 |
byte[] code;
|
jtulach@144
|
46 |
Vector exception_table = new Vector(0);
|
jtulach@144
|
47 |
Vector lin_num_tb = new Vector(0);
|
jtulach@144
|
48 |
Vector loc_var_tb = new Vector(0);
|
jtulach@144
|
49 |
StackMapTableData[] stackMapTable;
|
jtulach@144
|
50 |
StackMapData[] stackMap;
|
jtulach@144
|
51 |
int[] exc_index_table=null;
|
jtulach@144
|
52 |
Vector attrs=new Vector(0);
|
jtulach@144
|
53 |
Vector code_attrs=new Vector(0);
|
jtulach@144
|
54 |
int max_stack, max_locals;
|
jtulach@144
|
55 |
boolean isSynthetic=false;
|
jtulach@144
|
56 |
boolean isDeprecated=false;
|
jtulach@144
|
57 |
|
jtulach@144
|
58 |
public MethodData(ClassData cls){
|
jtulach@144
|
59 |
this.cls=cls;
|
jtulach@144
|
60 |
}
|
jtulach@144
|
61 |
|
jtulach@144
|
62 |
/**
|
jtulach@144
|
63 |
* Read method info.
|
jtulach@144
|
64 |
*/
|
jtulach@144
|
65 |
public void read(DataInputStream in) throws IOException {
|
jtulach@144
|
66 |
access = in.readUnsignedShort();
|
jtulach@144
|
67 |
name_index=in.readUnsignedShort();
|
jtulach@144
|
68 |
descriptor_index =in.readUnsignedShort();
|
jtulach@144
|
69 |
int attributes_count = in.readUnsignedShort();
|
jtulach@144
|
70 |
for (int i = 0; i < attributes_count; i++) {
|
jtulach@144
|
71 |
int attr_name_index=in.readUnsignedShort();
|
jtulach@144
|
72 |
|
jtulach@144
|
73 |
readAttr: {
|
jtulach@144
|
74 |
if (cls.getTag(attr_name_index)==CONSTANT_UTF8) {
|
jtulach@144
|
75 |
String attr_name=cls.getString(attr_name_index);
|
jtulach@144
|
76 |
if ( attr_name.equals("Code")){
|
jtulach@144
|
77 |
readCode (in);
|
jtulach@144
|
78 |
AttrData attr=new AttrData(cls);
|
jtulach@144
|
79 |
attr.read(attr_name_index);
|
jtulach@144
|
80 |
attrs.addElement(attr);
|
jtulach@144
|
81 |
break readAttr;
|
jtulach@144
|
82 |
} else if ( attr_name.equals("Exceptions")){
|
jtulach@144
|
83 |
readExceptions(in);
|
jtulach@144
|
84 |
AttrData attr=new AttrData(cls);
|
jtulach@144
|
85 |
attr.read(attr_name_index);
|
jtulach@144
|
86 |
attrs.addElement(attr);
|
jtulach@144
|
87 |
break readAttr;
|
jtulach@144
|
88 |
} else if (attr_name.equals("Synthetic")){
|
jtulach@144
|
89 |
if (in.readInt()!=0)
|
jtulach@144
|
90 |
throw new ClassFormatError("invalid Synthetic attr length");
|
jtulach@144
|
91 |
isSynthetic=true;
|
jtulach@144
|
92 |
AttrData attr=new AttrData(cls);
|
jtulach@144
|
93 |
attr.read(attr_name_index);
|
jtulach@144
|
94 |
attrs.addElement(attr);
|
jtulach@144
|
95 |
break readAttr;
|
jtulach@144
|
96 |
} else if (attr_name.equals("Deprecated")){
|
jtulach@144
|
97 |
if (in.readInt()!=0)
|
jtulach@144
|
98 |
throw new ClassFormatError("invalid Synthetic attr length");
|
jtulach@144
|
99 |
isDeprecated = true;
|
jtulach@144
|
100 |
AttrData attr=new AttrData(cls);
|
jtulach@144
|
101 |
attr.read(attr_name_index);
|
jtulach@144
|
102 |
attrs.addElement(attr);
|
jtulach@144
|
103 |
break readAttr;
|
jtulach@144
|
104 |
}
|
jtulach@144
|
105 |
}
|
jtulach@144
|
106 |
AttrData attr=new AttrData(cls);
|
jtulach@144
|
107 |
attr.read(attr_name_index, in);
|
jtulach@144
|
108 |
attrs.addElement(attr);
|
jtulach@144
|
109 |
}
|
jtulach@144
|
110 |
}
|
jtulach@144
|
111 |
}
|
jtulach@144
|
112 |
|
jtulach@144
|
113 |
/**
|
jtulach@144
|
114 |
* Read code attribute info.
|
jtulach@144
|
115 |
*/
|
jtulach@144
|
116 |
public void readCode(DataInputStream in) throws IOException {
|
jtulach@144
|
117 |
|
jtulach@144
|
118 |
int attr_length = in.readInt();
|
jtulach@144
|
119 |
max_stack=in.readUnsignedShort();
|
jtulach@144
|
120 |
max_locals=in.readUnsignedShort();
|
jtulach@144
|
121 |
int codelen=in.readInt();
|
jtulach@144
|
122 |
|
jtulach@144
|
123 |
code=new byte[codelen];
|
jtulach@144
|
124 |
int totalread = 0;
|
jtulach@144
|
125 |
while(totalread < codelen){
|
jtulach@144
|
126 |
totalread += in.read(code, totalread, codelen-totalread);
|
jtulach@144
|
127 |
}
|
jtulach@144
|
128 |
// in.read(code, 0, codelen);
|
jtulach@144
|
129 |
int clen = 0;
|
jtulach@144
|
130 |
readExceptionTable(in);
|
jtulach@144
|
131 |
int code_attributes_count = in.readUnsignedShort();
|
jtulach@144
|
132 |
|
jtulach@144
|
133 |
for (int k = 0 ; k < code_attributes_count ; k++) {
|
jtulach@144
|
134 |
int table_name_index=in.readUnsignedShort();
|
jtulach@144
|
135 |
int table_name_tag=cls.getTag(table_name_index);
|
jtulach@144
|
136 |
AttrData attr=new AttrData(cls);
|
jtulach@144
|
137 |
if (table_name_tag==CONSTANT_UTF8) {
|
jtulach@144
|
138 |
String table_name_tstr=cls.getString(table_name_index);
|
jtulach@144
|
139 |
if (table_name_tstr.equals("LineNumberTable")) {
|
jtulach@144
|
140 |
readLineNumTable(in);
|
jtulach@144
|
141 |
attr.read(table_name_index);
|
jtulach@144
|
142 |
} else if (table_name_tstr.equals("LocalVariableTable")) {
|
jtulach@144
|
143 |
readLocVarTable(in);
|
jtulach@144
|
144 |
attr.read(table_name_index);
|
jtulach@144
|
145 |
} else if (table_name_tstr.equals("StackMapTable")) {
|
jtulach@144
|
146 |
readStackMapTable(in);
|
jtulach@144
|
147 |
attr.read(table_name_index);
|
jtulach@144
|
148 |
} else if (table_name_tstr.equals("StackMap")) {
|
jtulach@144
|
149 |
readStackMap(in);
|
jtulach@144
|
150 |
attr.read(table_name_index);
|
jtulach@144
|
151 |
} else {
|
jtulach@144
|
152 |
attr.read(table_name_index, in);
|
jtulach@144
|
153 |
}
|
jtulach@144
|
154 |
code_attrs.addElement(attr);
|
jtulach@144
|
155 |
continue;
|
jtulach@144
|
156 |
}
|
jtulach@144
|
157 |
|
jtulach@144
|
158 |
attr.read(table_name_index, in);
|
jtulach@144
|
159 |
code_attrs.addElement(attr);
|
jtulach@144
|
160 |
}
|
jtulach@144
|
161 |
}
|
jtulach@144
|
162 |
|
jtulach@144
|
163 |
/**
|
jtulach@144
|
164 |
* Read exception table info.
|
jtulach@144
|
165 |
*/
|
jtulach@144
|
166 |
void readExceptionTable (DataInputStream in) throws IOException {
|
jtulach@144
|
167 |
int exception_table_len=in.readUnsignedShort();
|
jtulach@144
|
168 |
exception_table=new Vector(exception_table_len);
|
jtulach@144
|
169 |
for (int l = 0; l < exception_table_len; l++) {
|
jtulach@144
|
170 |
exception_table.addElement(new TrapData(in, l));
|
jtulach@144
|
171 |
}
|
jtulach@144
|
172 |
}
|
jtulach@144
|
173 |
|
jtulach@144
|
174 |
/**
|
jtulach@144
|
175 |
* Read LineNumberTable attribute info.
|
jtulach@144
|
176 |
*/
|
jtulach@144
|
177 |
void readLineNumTable (DataInputStream in) throws IOException {
|
jtulach@144
|
178 |
int attr_len = in.readInt(); // attr_length
|
jtulach@144
|
179 |
int lin_num_tb_len = in.readUnsignedShort();
|
jtulach@144
|
180 |
lin_num_tb=new Vector(lin_num_tb_len);
|
jtulach@144
|
181 |
for (int l = 0; l < lin_num_tb_len; l++) {
|
jtulach@144
|
182 |
lin_num_tb.addElement(new LineNumData(in));
|
jtulach@144
|
183 |
}
|
jtulach@144
|
184 |
}
|
jtulach@144
|
185 |
|
jtulach@144
|
186 |
/**
|
jtulach@144
|
187 |
* Read LocalVariableTable attribute info.
|
jtulach@144
|
188 |
*/
|
jtulach@144
|
189 |
void readLocVarTable (DataInputStream in) throws IOException {
|
jtulach@144
|
190 |
int attr_len=in.readInt(); // attr_length
|
jtulach@144
|
191 |
int loc_var_tb_len = in.readUnsignedShort();
|
jtulach@144
|
192 |
loc_var_tb = new Vector(loc_var_tb_len);
|
jtulach@144
|
193 |
for (int l = 0; l < loc_var_tb_len; l++) {
|
jtulach@144
|
194 |
loc_var_tb.addElement(new LocVarData(in));
|
jtulach@144
|
195 |
}
|
jtulach@144
|
196 |
}
|
jtulach@144
|
197 |
|
jtulach@144
|
198 |
/**
|
jtulach@144
|
199 |
* Read Exception attribute info.
|
jtulach@144
|
200 |
*/
|
jtulach@144
|
201 |
public void readExceptions(DataInputStream in) throws IOException {
|
jtulach@144
|
202 |
int attr_len=in.readInt(); // attr_length in prog
|
jtulach@144
|
203 |
int num_exceptions = in.readUnsignedShort();
|
jtulach@144
|
204 |
exc_index_table=new int[num_exceptions];
|
jtulach@144
|
205 |
for (int l = 0; l < num_exceptions; l++) {
|
jtulach@144
|
206 |
int exc=in.readShort();
|
jtulach@144
|
207 |
exc_index_table[l]=exc;
|
jtulach@144
|
208 |
}
|
jtulach@144
|
209 |
}
|
jtulach@144
|
210 |
|
jtulach@144
|
211 |
/**
|
jtulach@144
|
212 |
* Read StackMapTable attribute info.
|
jtulach@144
|
213 |
*/
|
jtulach@144
|
214 |
void readStackMapTable(DataInputStream in) throws IOException {
|
jtulach@144
|
215 |
int attr_len = in.readInt(); //attr_length
|
jtulach@144
|
216 |
int stack_map_tb_len = in.readUnsignedShort();
|
jtulach@144
|
217 |
stackMapTable = new StackMapTableData[stack_map_tb_len];
|
jtulach@144
|
218 |
for (int i=0; i<stack_map_tb_len; i++) {
|
jtulach@144
|
219 |
stackMapTable[i] = StackMapTableData.getInstance(in, this);
|
jtulach@144
|
220 |
}
|
jtulach@144
|
221 |
}
|
jtulach@144
|
222 |
|
jtulach@144
|
223 |
/**
|
jtulach@144
|
224 |
* Read StackMap attribute info.
|
jtulach@144
|
225 |
*/
|
jtulach@144
|
226 |
void readStackMap(DataInputStream in) throws IOException {
|
jtulach@144
|
227 |
int attr_len = in.readInt(); //attr_length
|
jtulach@144
|
228 |
int stack_map_len = in.readUnsignedShort();
|
jtulach@144
|
229 |
stackMap = new StackMapData[stack_map_len];
|
jtulach@144
|
230 |
for (int i = 0; i<stack_map_len; i++) {
|
jtulach@144
|
231 |
stackMap[i] = new StackMapData(in, this);
|
jtulach@144
|
232 |
}
|
jtulach@144
|
233 |
}
|
jtulach@144
|
234 |
|
jtulach@144
|
235 |
/**
|
jtulach@144
|
236 |
* Return access of the method.
|
jtulach@144
|
237 |
*/
|
jaroslav@392
|
238 |
public int getAccess(){
|
jaroslav@392
|
239 |
return access;
|
jtulach@144
|
240 |
}
|
jtulach@144
|
241 |
|
jtulach@144
|
242 |
/**
|
jtulach@144
|
243 |
* Return name of the method.
|
jtulach@144
|
244 |
*/
|
jtulach@144
|
245 |
public String getName(){
|
jtulach@144
|
246 |
return cls.getStringValue(name_index);
|
jtulach@144
|
247 |
}
|
jtulach@144
|
248 |
|
jtulach@144
|
249 |
/**
|
jtulach@144
|
250 |
* Return internal siganature of the method.
|
jtulach@144
|
251 |
*/
|
jtulach@144
|
252 |
public String getInternalSig(){
|
jtulach@144
|
253 |
return cls.getStringValue(descriptor_index);
|
jtulach@144
|
254 |
}
|
jtulach@144
|
255 |
|
jtulach@144
|
256 |
/**
|
jtulach@144
|
257 |
* Return code attribute data of a method.
|
jtulach@144
|
258 |
*/
|
jtulach@144
|
259 |
public byte[] getCode(){
|
jtulach@144
|
260 |
return code;
|
jtulach@144
|
261 |
}
|
jtulach@144
|
262 |
|
jtulach@144
|
263 |
/**
|
jtulach@144
|
264 |
* Return LineNumberTable size.
|
jtulach@144
|
265 |
*/
|
jtulach@144
|
266 |
public int getnumlines(){
|
jtulach@144
|
267 |
return lin_num_tb.size();
|
jtulach@144
|
268 |
}
|
jtulach@144
|
269 |
|
jtulach@144
|
270 |
/**
|
jtulach@144
|
271 |
* Return LineNumberTable
|
jtulach@144
|
272 |
*/
|
jtulach@144
|
273 |
public Vector getlin_num_tb(){
|
jtulach@144
|
274 |
return lin_num_tb;
|
jtulach@144
|
275 |
}
|
jtulach@144
|
276 |
|
jtulach@144
|
277 |
/**
|
jtulach@144
|
278 |
* Return LocalVariableTable size.
|
jtulach@144
|
279 |
*/
|
jtulach@144
|
280 |
public int getloc_var_tbsize(){
|
jtulach@144
|
281 |
return loc_var_tb.size();
|
jtulach@144
|
282 |
}
|
jtulach@144
|
283 |
|
jtulach@144
|
284 |
|
jtulach@144
|
285 |
/**
|
jtulach@144
|
286 |
* Return LocalVariableTable.
|
jtulach@144
|
287 |
*/
|
jtulach@144
|
288 |
public Vector getloc_var_tb(){
|
jtulach@144
|
289 |
return loc_var_tb;
|
jtulach@144
|
290 |
}
|
jtulach@144
|
291 |
|
jtulach@144
|
292 |
/**
|
jtulach@144
|
293 |
* Return StackMap.
|
jtulach@144
|
294 |
*/
|
jtulach@144
|
295 |
public StackMapData[] getStackMap() {
|
jtulach@144
|
296 |
return stackMap;
|
jtulach@144
|
297 |
}
|
jtulach@144
|
298 |
|
jtulach@144
|
299 |
/**
|
jtulach@144
|
300 |
* Return StackMapTable.
|
jtulach@144
|
301 |
*/
|
jtulach@144
|
302 |
public StackMapTableData[] getStackMapTable() {
|
jtulach@144
|
303 |
return stackMapTable;
|
jtulach@144
|
304 |
}
|
jtulach@144
|
305 |
|
lubomir@221
|
306 |
public StackMapIterator createStackMapIterator() {
|
lubomir@307
|
307 |
return new StackMapIterator(this);
|
lubomir@221
|
308 |
}
|
lubomir@221
|
309 |
|
jtulach@144
|
310 |
/**
|
jtulach@144
|
311 |
* Return true if method is static
|
jtulach@144
|
312 |
*/
|
jtulach@144
|
313 |
public boolean isStatic(){
|
jtulach@144
|
314 |
if ((access & ACC_STATIC) !=0) return true;
|
jtulach@144
|
315 |
return false;
|
jtulach@144
|
316 |
}
|
jtulach@144
|
317 |
|
jtulach@144
|
318 |
|
jtulach@144
|
319 |
/**
|
jtulach@144
|
320 |
* Return max depth of operand stack.
|
jtulach@144
|
321 |
*/
|
jtulach@144
|
322 |
public int getMaxStack(){
|
jtulach@144
|
323 |
return max_stack;
|
jtulach@144
|
324 |
}
|
jtulach@144
|
325 |
|
jtulach@144
|
326 |
|
jtulach@144
|
327 |
/**
|
jtulach@144
|
328 |
* Return number of local variables.
|
jtulach@144
|
329 |
*/
|
jtulach@144
|
330 |
public int getMaxLocals(){
|
jtulach@144
|
331 |
return max_locals;
|
jtulach@144
|
332 |
}
|
jtulach@144
|
333 |
|
jtulach@144
|
334 |
|
jtulach@144
|
335 |
/**
|
jtulach@144
|
336 |
* Return exception index table in Exception attribute.
|
jtulach@144
|
337 |
*/
|
jtulach@144
|
338 |
public int []get_exc_index_table(){
|
jtulach@144
|
339 |
return exc_index_table;
|
jtulach@144
|
340 |
}
|
jtulach@144
|
341 |
|
jtulach@144
|
342 |
|
jtulach@144
|
343 |
/**
|
jtulach@144
|
344 |
* Return exception table in code attributre.
|
jtulach@144
|
345 |
*/
|
jaroslav@288
|
346 |
public TrapDataIterator getTrapDataIterator(){
|
jaroslav@288
|
347 |
return new TrapDataIterator(exception_table);
|
jtulach@144
|
348 |
}
|
jaroslav@288
|
349 |
|
jtulach@144
|
350 |
|
jtulach@144
|
351 |
/**
|
jtulach@144
|
352 |
* Return method attributes.
|
jtulach@144
|
353 |
*/
|
jtulach@144
|
354 |
public Vector getAttributes(){
|
jtulach@144
|
355 |
return attrs;
|
jtulach@144
|
356 |
}
|
jtulach@144
|
357 |
|
jtulach@144
|
358 |
|
jtulach@144
|
359 |
/**
|
jtulach@144
|
360 |
* Return code attributes.
|
jtulach@144
|
361 |
*/
|
jtulach@144
|
362 |
public Vector getCodeAttributes(){
|
jtulach@144
|
363 |
return code_attrs;
|
jtulach@144
|
364 |
}
|
jtulach@144
|
365 |
|
jtulach@144
|
366 |
|
jtulach@144
|
367 |
/**
|
jtulach@144
|
368 |
* Return true if method id synthetic.
|
jtulach@144
|
369 |
*/
|
jtulach@144
|
370 |
public boolean isSynthetic(){
|
jtulach@144
|
371 |
return isSynthetic;
|
jtulach@144
|
372 |
}
|
jtulach@144
|
373 |
|
jtulach@144
|
374 |
|
jtulach@144
|
375 |
/**
|
jtulach@144
|
376 |
* Return true if method is deprecated.
|
jtulach@144
|
377 |
*/
|
jtulach@144
|
378 |
public boolean isDeprecated(){
|
jtulach@144
|
379 |
return isDeprecated;
|
jtulach@144
|
380 |
}
|
jaroslav@152
|
381 |
|
jaroslav@152
|
382 |
public byte[] findAnnotationData(boolean classRetention) {
|
jaroslav@152
|
383 |
String n = classRetention ?
|
jaroslav@152
|
384 |
"RuntimeInvisibleAnnotations" : // NOI18N
|
jaroslav@152
|
385 |
"RuntimeVisibleAnnotations"; // NOI18N
|
jaroslav@152
|
386 |
AttrData[] arr = new AttrData[attrs.size()];
|
jaroslav@152
|
387 |
attrs.copyInto(arr);
|
jaroslav@152
|
388 |
return ClassData.findAttr(n, arr);
|
jaroslav@152
|
389 |
}
|
jaroslav@397
|
390 |
|
jaroslav@397
|
391 |
public boolean isConstructor() {
|
jaroslav@397
|
392 |
return "<init>".equals(getName());
|
jaroslav@397
|
393 |
}
|
jtulach@144
|
394 |
}
|