javap/src/main/java/sun/tools/javap/StackMapTableData.java
author Jaroslav Tulach <jtulach@netbeans.org>
Fri, 09 Nov 2012 21:33:22 +0100
branchjavap
changeset 144 b06660b614db
child 149 32653a09f0db
permissions -rw-r--r--
javap as of revision jdk6-4ab5d66aaf2b
     1 /*
     2  * Copyright (c) 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 
    27 package sun.tools.javap;
    28 
    29 import java.util.*;
    30 import java.io.*;
    31 
    32 import static sun.tools.javap.RuntimeConstants.*;
    33 
    34 /* represents one entry of StackMapTable attribute
    35  */
    36 class StackMapTableData {
    37     final int frameType;
    38     int offsetDelta;
    39 
    40     StackMapTableData(int frameType) {
    41         this.frameType = frameType;
    42     }
    43 
    44     void print(JavapPrinter p) {
    45         p.out.print("   frame_type = " + frameType);
    46     }
    47 
    48     static class SameFrame extends StackMapTableData {
    49         SameFrame(int frameType, int offsetDelta) {
    50             super(frameType);
    51             this.offsetDelta = offsetDelta;
    52         }
    53         void print(JavapPrinter p) {
    54             super.print(p);
    55             if (frameType < SAME_FRAME_BOUND) {
    56                 p.out.println(" /* same */");
    57             } else {
    58                 p.out.println(" /* same_frame_extended */");
    59                 p.out.println("     offset_delta = " + offsetDelta);
    60             }
    61         }
    62     }
    63 
    64     static class SameLocals1StackItem extends StackMapTableData {
    65         final int[] stack;
    66         SameLocals1StackItem(int frameType, int offsetDelta, int[] stack) {
    67             super(frameType);
    68             this.offsetDelta = offsetDelta;
    69             this.stack = stack;
    70         }
    71         void print(JavapPrinter p) {
    72             super.print(p);
    73             if (frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
    74                 p.out.println(" /* same_locals_1_stack_item_frame_extended */");
    75                 p.out.println("     offset_delta = " + offsetDelta);
    76             } else {
    77                 p.out.println(" /* same_locals_1_stack_item */");
    78             }
    79             p.printMap("     stack = [", stack);
    80         }
    81     }
    82 
    83     static class ChopFrame extends StackMapTableData {
    84         ChopFrame(int frameType, int offsetDelta) {
    85             super(frameType);
    86             this.offsetDelta = offsetDelta;
    87         }
    88         void print(JavapPrinter p) {
    89             super.print(p);
    90             p.out.println(" /* chop */");
    91             p.out.println("     offset_delta = " + offsetDelta);
    92         }
    93     }
    94 
    95     static class AppendFrame extends StackMapTableData {
    96         final int[] locals;
    97         AppendFrame(int frameType, int offsetDelta, int[] locals) {
    98             super(frameType);
    99             this.offsetDelta = offsetDelta;
   100             this.locals = locals;
   101         }
   102         void print(JavapPrinter p) {
   103             super.print(p);
   104             p.out.println(" /* append */");
   105             p.out.println("     offset_delta = " + offsetDelta);
   106             p.printMap("     locals = [", locals);
   107         }
   108     }
   109 
   110     static class FullFrame extends StackMapTableData {
   111         final int[] locals;
   112         final int[] stack;
   113         FullFrame(int offsetDelta, int[] locals, int[] stack) {
   114             super(FULL_FRAME);
   115             this.offsetDelta = offsetDelta;
   116             this.locals = locals;
   117             this.stack = stack;
   118         }
   119         void print(JavapPrinter p) {
   120             super.print(p);
   121             p.out.println(" /* full_frame */");
   122             p.out.println("     offset_delta = " + offsetDelta);
   123             p.printMap("     locals = [", locals);
   124             p.printMap("     stack = [", stack);
   125         }
   126     }
   127 
   128     static StackMapTableData getInstance(DataInputStream in, MethodData method)
   129                   throws IOException {
   130         int frameType = in.readUnsignedByte();
   131 
   132         if (frameType < SAME_FRAME_BOUND) {
   133             // same_frame
   134             return new SameFrame(frameType, frameType);
   135         } else if (SAME_FRAME_BOUND <= frameType && frameType < SAME_LOCALS_1_STACK_ITEM_BOUND) {
   136             // same_locals_1_stack_item_frame
   137             // read additional single stack element
   138             return new SameLocals1StackItem(frameType,
   139                                             (frameType - SAME_FRAME_BOUND),
   140                                             StackMapData.readTypeArray(in, 1, method));
   141         } else if (frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
   142             // same_locals_1_stack_item_extended
   143             return new SameLocals1StackItem(frameType,
   144                                             in.readUnsignedShort(),
   145                                             StackMapData.readTypeArray(in, 1, method));
   146         } else if (SAME_LOCALS_1_STACK_ITEM_EXTENDED < frameType  && frameType < SAME_FRAME_EXTENDED) {
   147             // chop_frame or same_frame_extended
   148             return new ChopFrame(frameType, in.readUnsignedShort());
   149         } else if (frameType == SAME_FRAME_EXTENDED) {
   150             // chop_frame or same_frame_extended
   151             return new SameFrame(frameType, in.readUnsignedShort());
   152         } else if (SAME_FRAME_EXTENDED < frameType  && frameType < FULL_FRAME) {
   153             // append_frame
   154             return new AppendFrame(frameType, in.readUnsignedShort(),
   155                                    StackMapData.readTypeArray(in, frameType - SAME_FRAME_EXTENDED, method));
   156         } else if (frameType == FULL_FRAME) {
   157             // full_frame
   158             int offsetDelta = in.readUnsignedShort();
   159             int locals_size = in.readUnsignedShort();
   160             int[] locals = StackMapData.readTypeArray(in, locals_size, method);
   161             int stack_size = in.readUnsignedShort();
   162             int[] stack = StackMapData.readTypeArray(in, stack_size, method);
   163             return new FullFrame(offsetDelta, locals, stack);
   164         } else {
   165             throw new ClassFormatError("unrecognized frame_type in StackMapTable");
   166         }
   167     }
   168 }