javap/src/main/java/org/apidesign/javap/StackMapTableData.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 07 Feb 2013 12:58:12 +0100
branchemul
changeset 694 0d277415ed02
parent 281 f2352e0b713e
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) 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@144
    26
jtulach@167
    27
package org.apidesign.javap;
jtulach@144
    28
jtulach@144
    29
import java.io.*;
jtulach@144
    30
jtulach@167
    31
import static org.apidesign.javap.RuntimeConstants.*;
jtulach@144
    32
jtulach@144
    33
/* represents one entry of StackMapTable attribute
jtulach@144
    34
 */
lubomir@221
    35
abstract class StackMapTableData {
jtulach@144
    36
    final int frameType;
jtulach@144
    37
    int offsetDelta;
jtulach@144
    38
jtulach@144
    39
    StackMapTableData(int frameType) {
jtulach@144
    40
        this.frameType = frameType;
jtulach@144
    41
    }
jtulach@144
    42
lubomir@281
    43
    abstract void applyTo(TypeArray localTypes, TypeArray stackTypes);
lubomir@281
    44
lubomir@281
    45
    protected static String toString(
lubomir@281
    46
            final String frameType,
lubomir@281
    47
            final int offset,
lubomir@281
    48
            final int[] localTypes,
lubomir@281
    49
            final int[] stackTypes) {
lubomir@281
    50
        final StringBuilder sb = new StringBuilder(frameType);
lubomir@281
    51
lubomir@281
    52
        sb.append("(off: +").append(offset);
lubomir@281
    53
        if (localTypes != null) {
lubomir@281
    54
            sb.append(", locals: ");
lubomir@281
    55
            appendTypes(sb, localTypes);
lubomir@281
    56
        }
lubomir@281
    57
        if (stackTypes != null) {
lubomir@281
    58
            sb.append(", stack: ");
lubomir@281
    59
            appendTypes(sb, stackTypes);
lubomir@281
    60
        }
lubomir@281
    61
        sb.append(')');
lubomir@281
    62
lubomir@281
    63
        return sb.toString();
lubomir@281
    64
    }
lubomir@281
    65
lubomir@281
    66
    private static void appendTypes(final StringBuilder sb, final int[] types) {
lubomir@281
    67
        sb.append('[');
lubomir@281
    68
        if (types.length > 0) {
lubomir@307
    69
            sb.append(TypeArray.typeString(types[0]));
lubomir@281
    70
            for (int i = 1; i < types.length; ++i) {
lubomir@281
    71
                sb.append(", ");
lubomir@307
    72
                sb.append(TypeArray.typeString(types[i]));
lubomir@281
    73
            }
lubomir@281
    74
        }
lubomir@281
    75
        sb.append(']');
lubomir@281
    76
    }
lubomir@281
    77
jtulach@144
    78
    static class SameFrame extends StackMapTableData {
jtulach@144
    79
        SameFrame(int frameType, int offsetDelta) {
jtulach@144
    80
            super(frameType);
jtulach@144
    81
            this.offsetDelta = offsetDelta;
jtulach@144
    82
        }
lubomir@221
    83
lubomir@221
    84
        @Override
lubomir@281
    85
        void applyTo(TypeArray localTypes, TypeArray stackTypes) {
lubomir@281
    86
            stackTypes.clear();
lubomir@221
    87
        }
lubomir@221
    88
lubomir@221
    89
        @Override
lubomir@221
    90
        public String toString() {
lubomir@281
    91
            return toString("SAME" + ((frameType == SAME_FRAME_EXTENDED)
lubomir@281
    92
                                          ? "_FRAME_EXTENDED" : ""),
lubomir@281
    93
                            offsetDelta,
lubomir@281
    94
                            null, null);
lubomir@221
    95
        }
jtulach@144
    96
    }
jtulach@144
    97
jtulach@144
    98
    static class SameLocals1StackItem extends StackMapTableData {
jtulach@144
    99
        final int[] stack;
jtulach@144
   100
        SameLocals1StackItem(int frameType, int offsetDelta, int[] stack) {
jtulach@144
   101
            super(frameType);
jtulach@144
   102
            this.offsetDelta = offsetDelta;
jtulach@144
   103
            this.stack = stack;
jtulach@144
   104
        }
lubomir@221
   105
lubomir@221
   106
        @Override
lubomir@281
   107
        void applyTo(TypeArray localTypes, TypeArray stackTypes) {
lubomir@281
   108
            stackTypes.setAll(stack);
lubomir@221
   109
        }
lubomir@221
   110
lubomir@221
   111
        @Override
lubomir@221
   112
        public String toString() {
lubomir@281
   113
            return toString(
lubomir@281
   114
                       "SAME_LOCALS_1_STACK_ITEM"
lubomir@281
   115
                           + ((frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED)
lubomir@281
   116
                                  ? "_EXTENDED" : ""),
lubomir@281
   117
                       offsetDelta,
lubomir@281
   118
                       null, stack);
lubomir@221
   119
        }
jtulach@144
   120
    }
jtulach@144
   121
jtulach@144
   122
    static class ChopFrame extends StackMapTableData {
jtulach@144
   123
        ChopFrame(int frameType, int offsetDelta) {
jtulach@144
   124
            super(frameType);
jtulach@144
   125
            this.offsetDelta = offsetDelta;
jtulach@144
   126
        }
lubomir@221
   127
lubomir@221
   128
        @Override
lubomir@281
   129
        void applyTo(TypeArray localTypes, TypeArray stackTypes) {
lubomir@281
   130
            localTypes.setSize(localTypes.getSize()
lubomir@281
   131
                                   - (SAME_FRAME_EXTENDED - frameType));
lubomir@281
   132
            stackTypes.clear();
lubomir@221
   133
        }
lubomir@221
   134
lubomir@221
   135
        @Override
lubomir@221
   136
        public String toString() {
lubomir@281
   137
            return toString("CHOP", offsetDelta, null, null);
lubomir@221
   138
        }
jtulach@144
   139
    }
jtulach@144
   140
jtulach@144
   141
    static class AppendFrame extends StackMapTableData {
jtulach@144
   142
        final int[] locals;
jtulach@144
   143
        AppendFrame(int frameType, int offsetDelta, int[] locals) {
jtulach@144
   144
            super(frameType);
jtulach@144
   145
            this.offsetDelta = offsetDelta;
jtulach@144
   146
            this.locals = locals;
jtulach@144
   147
        }
lubomir@221
   148
lubomir@221
   149
        @Override
lubomir@281
   150
        void applyTo(TypeArray localTypes, TypeArray stackTypes) {
lubomir@281
   151
            localTypes.addAll(locals);
lubomir@281
   152
            stackTypes.clear();
lubomir@221
   153
        }
lubomir@221
   154
lubomir@221
   155
        @Override
lubomir@221
   156
        public String toString() {
lubomir@281
   157
            return toString("APPEND", offsetDelta, locals, null);
lubomir@221
   158
        }
jtulach@144
   159
    }
jtulach@144
   160
jtulach@144
   161
    static class FullFrame extends StackMapTableData {
jtulach@144
   162
        final int[] locals;
jtulach@144
   163
        final int[] stack;
jtulach@144
   164
        FullFrame(int offsetDelta, int[] locals, int[] stack) {
jtulach@144
   165
            super(FULL_FRAME);
jtulach@144
   166
            this.offsetDelta = offsetDelta;
jtulach@144
   167
            this.locals = locals;
jtulach@144
   168
            this.stack = stack;
jtulach@144
   169
        }
lubomir@221
   170
lubomir@221
   171
        @Override
lubomir@281
   172
        void applyTo(TypeArray localTypes, TypeArray stackTypes) {
lubomir@281
   173
            localTypes.setAll(locals);
lubomir@281
   174
            stackTypes.setAll(stack);
lubomir@221
   175
        }
lubomir@221
   176
lubomir@221
   177
        @Override
lubomir@221
   178
        public String toString() {
lubomir@281
   179
            return toString("FULL", offsetDelta, locals, stack);
lubomir@221
   180
        }
jtulach@144
   181
    }
jtulach@144
   182
jtulach@144
   183
    static StackMapTableData getInstance(DataInputStream in, MethodData method)
jtulach@144
   184
                  throws IOException {
jtulach@144
   185
        int frameType = in.readUnsignedByte();
jtulach@144
   186
jtulach@144
   187
        if (frameType < SAME_FRAME_BOUND) {
jtulach@144
   188
            // same_frame
jtulach@144
   189
            return new SameFrame(frameType, frameType);
jtulach@144
   190
        } else if (SAME_FRAME_BOUND <= frameType && frameType < SAME_LOCALS_1_STACK_ITEM_BOUND) {
jtulach@144
   191
            // same_locals_1_stack_item_frame
jtulach@144
   192
            // read additional single stack element
jtulach@144
   193
            return new SameLocals1StackItem(frameType,
jtulach@144
   194
                                            (frameType - SAME_FRAME_BOUND),
jtulach@144
   195
                                            StackMapData.readTypeArray(in, 1, method));
jtulach@144
   196
        } else if (frameType == SAME_LOCALS_1_STACK_ITEM_EXTENDED) {
jtulach@144
   197
            // same_locals_1_stack_item_extended
jtulach@144
   198
            return new SameLocals1StackItem(frameType,
jtulach@144
   199
                                            in.readUnsignedShort(),
jtulach@144
   200
                                            StackMapData.readTypeArray(in, 1, method));
jtulach@144
   201
        } else if (SAME_LOCALS_1_STACK_ITEM_EXTENDED < frameType  && frameType < SAME_FRAME_EXTENDED) {
jtulach@144
   202
            // chop_frame or same_frame_extended
jtulach@144
   203
            return new ChopFrame(frameType, in.readUnsignedShort());
jtulach@144
   204
        } else if (frameType == SAME_FRAME_EXTENDED) {
jtulach@144
   205
            // chop_frame or same_frame_extended
jtulach@144
   206
            return new SameFrame(frameType, in.readUnsignedShort());
jtulach@144
   207
        } else if (SAME_FRAME_EXTENDED < frameType  && frameType < FULL_FRAME) {
jtulach@144
   208
            // append_frame
jtulach@144
   209
            return new AppendFrame(frameType, in.readUnsignedShort(),
jtulach@144
   210
                                   StackMapData.readTypeArray(in, frameType - SAME_FRAME_EXTENDED, method));
jtulach@144
   211
        } else if (frameType == FULL_FRAME) {
jtulach@144
   212
            // full_frame
jtulach@144
   213
            int offsetDelta = in.readUnsignedShort();
jtulach@144
   214
            int locals_size = in.readUnsignedShort();
jtulach@144
   215
            int[] locals = StackMapData.readTypeArray(in, locals_size, method);
jtulach@144
   216
            int stack_size = in.readUnsignedShort();
jtulach@144
   217
            int[] stack = StackMapData.readTypeArray(in, stack_size, method);
jtulach@144
   218
            return new FullFrame(offsetDelta, locals, stack);
jtulach@144
   219
        } else {
jtulach@144
   220
            throw new ClassFormatError("unrecognized frame_type in StackMapTable");
jtulach@144
   221
        }
jtulach@144
   222
    }
jtulach@144
   223
}