javap/src/main/java/org/apidesign/javap/MethodData.java
author Lubomir Nerad <lubomir.nerad@oracle.com>
Thu, 29 Nov 2012 20:19:00 +0100
branchregisters
changeset 221 3ee23267706c
parent 167 77f7135b6eb1
child 282 a98d6c5a545e
permissions -rw-r--r--
Register based VM
     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 import java.io.*;
    29 import org.apidesign.bck2brwsr.core.JavaScriptBody;
    30 
    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 String[] getAccess(){
   239 
   240         Vector v = new Vector();
   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     public StackMapIterator createStackMapIterator() {
   339         return new StackMapIterator(stackMapTable);
   340     }
   341 
   342     /**
   343      * Return number of arguments of that method.
   344      */
   345     public int getArgumentlength(){
   346         return new TypeSignature(getInternalSig()).getArgumentlength();
   347     }
   348 
   349     /**
   350      * Return true if method is static
   351      */
   352     public boolean isStatic(){
   353         if ((access & ACC_STATIC)   !=0) return true;
   354         return false;
   355     }
   356 
   357 
   358     /**
   359      * Return max depth of operand stack.
   360      */
   361     public int getMaxStack(){
   362         return  max_stack;
   363     }
   364 
   365 
   366     /**
   367      * Return number of local variables.
   368      */
   369     public int getMaxLocals(){
   370         return max_locals;
   371     }
   372 
   373 
   374     /**
   375      * Return exception index table in Exception attribute.
   376      */
   377     public int []get_exc_index_table(){
   378         return  exc_index_table;
   379     }
   380 
   381 
   382     /**
   383      * Return exception table in code attributre.
   384      */
   385     public Vector getexception_table(){
   386         return exception_table;
   387     }
   388 
   389 
   390     /**
   391      * Return method attributes.
   392      */
   393     public Vector getAttributes(){
   394         return attrs;
   395     }
   396 
   397 
   398     /**
   399      * Return code attributes.
   400      */
   401     public Vector getCodeAttributes(){
   402         return code_attrs;
   403     }
   404 
   405 
   406     /**
   407      * Return true if method id synthetic.
   408      */
   409     public boolean isSynthetic(){
   410         return isSynthetic;
   411     }
   412 
   413 
   414     /**
   415      * Return true if method is deprecated.
   416      */
   417     public boolean isDeprecated(){
   418         return isDeprecated;
   419     }
   420 
   421     public byte[] findAnnotationData(boolean classRetention) {
   422         String n = classRetention ?
   423             "RuntimeInvisibleAnnotations" : // NOI18N
   424             "RuntimeVisibleAnnotations"; // NOI18N
   425         AttrData[] arr = new AttrData[attrs.size()];
   426         attrs.copyInto(arr);
   427         return ClassData.findAttr(n, arr);
   428     }
   429 }