javap/src/main/java/org/apidesign/javap/MethodData.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 07 Feb 2013 12:58:12 +0100
branchemul
changeset 694 0d277415ed02
parent 392 44a5802816be
permissions -rw-r--r--
Rebasing the Inflater support on jzlib which, unlike GNU ClassPath, has correct implementation of Huffman code. Making the implementation more easily testable by turning Inflater and ZipInputStream into pure delegates. Current implementation is going to need proper long support.
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
}