javap/src/main/java/org/apidesign/javap/StackMapTableData.java
author Lubomir Nerad <lubomir.nerad@oracle.com>
Thu, 29 Nov 2012 20:19:00 +0100
branchregisters
changeset 221 3ee23267706c
parent 167 77f7135b6eb1
child 281 f2352e0b713e
permissions -rw-r--r--
Register based VM
     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 org.apidesign.javap;
    28 
    29 import java.io.*;
    30 
    31 import static org.apidesign.javap.RuntimeConstants.*;
    32 
    33 /* represents one entry of StackMapTable attribute
    34  */
    35 abstract class StackMapTableData {
    36     final int frameType;
    37     int offsetDelta;
    38 
    39     StackMapTableData(int frameType) {
    40         this.frameType = frameType;
    41     }
    42 
    43     abstract int getStackItemsCount();
    44 
    45     static class SameFrame extends StackMapTableData {
    46         SameFrame(int frameType, int offsetDelta) {
    47             super(frameType);
    48             this.offsetDelta = offsetDelta;
    49         }
    50 
    51         @Override
    52         int getStackItemsCount() {
    53             return 0;
    54         }
    55 
    56         @Override
    57         public String toString() {
    58             return "SAME"
    59                        + ((frameType == SAME_FRAME_EXTENDED)
    60                               ? "_FRAME_EXTENDED" : "")
    61                        + "(" + offsetDelta + ")";
    62         }
    63     }
    64 
    65     static class SameLocals1StackItem extends StackMapTableData {
    66         final int[] stack;
    67         SameLocals1StackItem(int frameType, int offsetDelta, int[] stack) {
    68             super(frameType);
    69             this.offsetDelta = offsetDelta;
    70             this.stack = stack;
    71         }
    72 
    73         @Override
    74         int getStackItemsCount() {
    75             return 1;
    76         }
    77 
    78         @Override
    79         public String toString() {
    80             return "SAME_LOCALS_1_STACK_ITEM"
    81                        + ((frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED)
    82                               ? "_EXTENDED" : "")
    83                        + "(" + offsetDelta + ")";
    84         }
    85     }
    86 
    87     static class ChopFrame extends StackMapTableData {
    88         ChopFrame(int frameType, int offsetDelta) {
    89             super(frameType);
    90             this.offsetDelta = offsetDelta;
    91         }
    92 
    93         @Override
    94         int getStackItemsCount() {
    95             return 0;
    96         }
    97 
    98         @Override
    99         public String toString() {
   100             return "CHOP(" + offsetDelta + ")";
   101         }
   102     }
   103 
   104     static class AppendFrame extends StackMapTableData {
   105         final int[] locals;
   106         AppendFrame(int frameType, int offsetDelta, int[] locals) {
   107             super(frameType);
   108             this.offsetDelta = offsetDelta;
   109             this.locals = locals;
   110         }
   111 
   112         @Override
   113         int getStackItemsCount() {
   114             return 0;
   115         }
   116 
   117         @Override
   118         public String toString() {
   119             return "APPEND(" + offsetDelta + ")";
   120         }
   121     }
   122 
   123     static class FullFrame extends StackMapTableData {
   124         final int[] locals;
   125         final int[] stack;
   126         FullFrame(int offsetDelta, int[] locals, int[] stack) {
   127             super(FULL_FRAME);
   128             this.offsetDelta = offsetDelta;
   129             this.locals = locals;
   130             this.stack = stack;
   131         }
   132 
   133         @Override
   134         int getStackItemsCount() {
   135             return stack.length;
   136         }
   137 
   138         @Override
   139         public String toString() {
   140             return "FULL(" + offsetDelta + ")";
   141         }
   142     }
   143 
   144     static StackMapTableData getInstance(DataInputStream in, MethodData method)
   145                   throws IOException {
   146         int frameType = in.readUnsignedByte();
   147 
   148         if (frameType < SAME_FRAME_BOUND) {
   149             // same_frame
   150             return new SameFrame(frameType, frameType);
   151         } else if (SAME_FRAME_BOUND <= frameType && frameType < SAME_LOCALS_1_STACK_ITEM_BOUND) {
   152             // same_locals_1_stack_item_frame
   153             // read additional single stack element
   154             return new SameLocals1StackItem(frameType,
   155                                             (frameType - SAME_FRAME_BOUND),
   156                                             StackMapData.readTypeArray(in, 1, method));
   157         } else if (frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
   158             // same_locals_1_stack_item_extended
   159             return new SameLocals1StackItem(frameType,
   160                                             in.readUnsignedShort(),
   161                                             StackMapData.readTypeArray(in, 1, method));
   162         } else if (SAME_LOCALS_1_STACK_ITEM_EXTENDED < frameType  && frameType < SAME_FRAME_EXTENDED) {
   163             // chop_frame or same_frame_extended
   164             return new ChopFrame(frameType, in.readUnsignedShort());
   165         } else if (frameType == SAME_FRAME_EXTENDED) {
   166             // chop_frame or same_frame_extended
   167             return new SameFrame(frameType, in.readUnsignedShort());
   168         } else if (SAME_FRAME_EXTENDED < frameType  && frameType < FULL_FRAME) {
   169             // append_frame
   170             return new AppendFrame(frameType, in.readUnsignedShort(),
   171                                    StackMapData.readTypeArray(in, frameType - SAME_FRAME_EXTENDED, method));
   172         } else if (frameType == FULL_FRAME) {
   173             // full_frame
   174             int offsetDelta = in.readUnsignedShort();
   175             int locals_size = in.readUnsignedShort();
   176             int[] locals = StackMapData.readTypeArray(in, locals_size, method);
   177             int stack_size = in.readUnsignedShort();
   178             int[] stack = StackMapData.readTypeArray(in, stack_size, method);
   179             return new FullFrame(offsetDelta, locals, stack);
   180         } else {
   181             throw new ClassFormatError("unrecognized frame_type in StackMapTable");
   182         }
   183     }
   184 }