javap/src/main/java/org/apidesign/javap/MethodData.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Tue, 05 Feb 2013 10:19:10 +0100
changeset 668 b4354a30d4dd
parent 392 44a5802816be
permissions -rw-r--r--
David pointed out that it is milli, micro, nano - e.g. we need to multiply by 10^6
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
}