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.
     1 /*
     2  * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    25 
    26 package org.apidesign.javap;
    27 
    28 
    29 import java.io.DataInputStream;
    30 import java.io.IOException;
    31 import static org.apidesign.javap.RuntimeConstants.*;
    32 
    33 /**
    34  * Strores method data informastion.
    35  *
    36  * @author  Sucheta Dambalkar (Adopted code from jdis)
    37  */
    38 public class MethodData {
    39 
    40     ClassData cls;
    41     int access;
    42     int name_index;
    43     int descriptor_index;
    44     int attributes_count;
    45     byte[] code;
    46     Vector exception_table = new Vector(0);
    47     Vector lin_num_tb = new Vector(0);
    48     Vector loc_var_tb = new Vector(0);
    49     StackMapTableData[] stackMapTable;
    50     StackMapData[] stackMap;
    51     int[] exc_index_table=null;
    52     Vector attrs=new Vector(0);
    53     Vector code_attrs=new Vector(0);
    54     int max_stack,  max_locals;
    55     boolean isSynthetic=false;
    56     boolean isDeprecated=false;
    57 
    58     public MethodData(ClassData cls){
    59         this.cls=cls;
    60     }
    61 
    62     /**
    63      * Read method info.
    64      */
    65     public void read(DataInputStream in) throws IOException {
    66         access = in.readUnsignedShort();
    67         name_index=in.readUnsignedShort();
    68         descriptor_index =in.readUnsignedShort();
    69         int attributes_count = in.readUnsignedShort();
    70         for (int i = 0; i < attributes_count; i++) {
    71             int attr_name_index=in.readUnsignedShort();
    72 
    73         readAttr: {
    74                 if (cls.getTag(attr_name_index)==CONSTANT_UTF8) {
    75                     String  attr_name=cls.getString(attr_name_index);
    76                     if ( attr_name.equals("Code")){
    77                         readCode (in);
    78                         AttrData attr=new AttrData(cls);
    79                         attr.read(attr_name_index);
    80                         attrs.addElement(attr);
    81                         break readAttr;
    82                     } else if ( attr_name.equals("Exceptions")){
    83                         readExceptions(in);
    84                         AttrData attr=new AttrData(cls);
    85                         attr.read(attr_name_index);
    86                         attrs.addElement(attr);
    87                         break readAttr;
    88                     } else if (attr_name.equals("Synthetic")){
    89                         if (in.readInt()!=0)
    90                             throw new ClassFormatError("invalid Synthetic attr length");
    91                         isSynthetic=true;
    92                         AttrData attr=new AttrData(cls);
    93                         attr.read(attr_name_index);
    94                         attrs.addElement(attr);
    95                         break readAttr;
    96                     } else if (attr_name.equals("Deprecated")){
    97                         if (in.readInt()!=0)
    98                             throw new ClassFormatError("invalid Synthetic attr length");
    99                         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(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(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(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 int getAccess(){
   239         return access;
   240     }
   241 
   242     /**
   243      * Return name of the method.
   244      */
   245     public String getName(){
   246         return cls.getStringValue(name_index);
   247     }
   248 
   249     /**
   250      * Return internal siganature of the method.
   251      */
   252     public String getInternalSig(){
   253         return cls.getStringValue(descriptor_index);
   254     }
   255 
   256     /**
   257      * Return code attribute data of a method.
   258      */
   259     public byte[] getCode(){
   260         return code;
   261     }
   262 
   263     /**
   264      * Return LineNumberTable size.
   265      */
   266     public int getnumlines(){
   267         return lin_num_tb.size();
   268     }
   269 
   270     /**
   271      * Return LineNumberTable
   272      */
   273     public Vector getlin_num_tb(){
   274         return lin_num_tb;
   275     }
   276 
   277     /**
   278      * Return LocalVariableTable size.
   279      */
   280     public int getloc_var_tbsize(){
   281         return loc_var_tb.size();
   282     }
   283 
   284 
   285     /**
   286      * Return LocalVariableTable.
   287      */
   288     public Vector getloc_var_tb(){
   289         return loc_var_tb;
   290     }
   291 
   292     /**
   293      * Return StackMap.
   294      */
   295     public StackMapData[] getStackMap() {
   296         return stackMap;
   297     }
   298 
   299     /**
   300      * Return StackMapTable.
   301      */
   302     public StackMapTableData[] getStackMapTable() {
   303         return stackMapTable;
   304     }
   305 
   306     public StackMapIterator createStackMapIterator() {
   307         return new StackMapIterator(this);
   308     }
   309 
   310     /**
   311      * Return true if method is static
   312      */
   313     public boolean isStatic(){
   314         if ((access & ACC_STATIC)   !=0) return true;
   315         return false;
   316     }
   317 
   318 
   319     /**
   320      * Return max depth of operand stack.
   321      */
   322     public int getMaxStack(){
   323         return  max_stack;
   324     }
   325 
   326 
   327     /**
   328      * Return number of local variables.
   329      */
   330     public int getMaxLocals(){
   331         return max_locals;
   332     }
   333 
   334 
   335     /**
   336      * Return exception index table in Exception attribute.
   337      */
   338     public int []get_exc_index_table(){
   339         return  exc_index_table;
   340     }
   341 
   342 
   343     /**
   344      * Return exception table in code attributre.
   345      */
   346     public TrapDataIterator getTrapDataIterator(){
   347         return new TrapDataIterator(exception_table);
   348     }
   349     
   350 
   351     /**
   352      * Return method attributes.
   353      */
   354     public Vector getAttributes(){
   355         return attrs;
   356     }
   357 
   358 
   359     /**
   360      * Return code attributes.
   361      */
   362     public Vector getCodeAttributes(){
   363         return code_attrs;
   364     }
   365 
   366 
   367     /**
   368      * Return true if method id synthetic.
   369      */
   370     public boolean isSynthetic(){
   371         return isSynthetic;
   372     }
   373 
   374 
   375     /**
   376      * Return true if method is deprecated.
   377      */
   378     public boolean isDeprecated(){
   379         return isDeprecated;
   380     }
   381 
   382     public byte[] findAnnotationData(boolean classRetention) {
   383         String n = classRetention ?
   384             "RuntimeInvisibleAnnotations" : // NOI18N
   385             "RuntimeVisibleAnnotations"; // NOI18N
   386         AttrData[] arr = new AttrData[attrs.size()];
   387         attrs.copyInto(arr);
   388         return ClassData.findAttr(n, arr);
   389     }
   390 
   391     public boolean isConstructor() {
   392         return "<init>".equals(getName());
   393     }
   394 }