javap/src/main/java/org/apidesign/javap/StackMapIterator.java
author Lubomir Nerad <lubomir.nerad@oracle.com>
Fri, 07 Dec 2012 15:02:35 +0100
branchregisters
changeset 281 f2352e0b713e
parent 221 3ee23267706c
child 307 eaf4e8387065
permissions -rw-r--r--
Type specific stack variables
lubomir@221
     1
/*
lubomir@221
     2
 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
lubomir@221
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
lubomir@221
     4
 *
lubomir@221
     5
 * This code is free software; you can redistribute it and/or modify it
lubomir@221
     6
 * under the terms of the GNU General Public License version 2 only, as
lubomir@221
     7
 * published by the Free Software Foundation.  Oracle designates this
lubomir@221
     8
 * particular file as subject to the "Classpath" exception as provided
lubomir@221
     9
 * by Oracle in the LICENSE file that accompanied this code.
lubomir@221
    10
 *
lubomir@221
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
lubomir@221
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
lubomir@221
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
lubomir@221
    14
 * version 2 for more details (a copy is included in the LICENSE file that
lubomir@221
    15
 * accompanied this code).
lubomir@221
    16
 *
lubomir@221
    17
 * You should have received a copy of the GNU General Public License version
lubomir@221
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
lubomir@221
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
lubomir@221
    20
 *
lubomir@221
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
lubomir@221
    22
 * or visit www.oracle.com if you need additional information or have any
lubomir@221
    23
 * questions.
lubomir@221
    24
 */
lubomir@221
    25
lubomir@221
    26
package org.apidesign.javap;
lubomir@221
    27
lubomir@221
    28
public final class StackMapIterator {
lubomir@221
    29
    private static final StackMapTableData INITIAL_FRAME =
lubomir@221
    30
            new StackMapTableData(-1) {
lubomir@221
    31
                @Override
lubomir@281
    32
                void applyTo(TypeArray localTypes, TypeArray stackTypes) {
lubomir@281
    33
                    localTypes.clear();
lubomir@281
    34
                    stackTypes.clear();
lubomir@221
    35
                }
lubomir@221
    36
lubomir@221
    37
                @Override
lubomir@221
    38
                public String toString() {
lubomir@281
    39
                    return toString("INITIAL", 0, null, null);
lubomir@221
    40
                }
lubomir@281
    41
lubomir@221
    42
            };
lubomir@221
    43
lubomir@221
    44
    private final StackMapTableData[] stackMapTable;
lubomir@281
    45
    private final TypeArray localTypes;
lubomir@281
    46
    private final TypeArray stackTypes;
lubomir@221
    47
lubomir@221
    48
    private int nextFrameIndex;
lubomir@221
    49
    private int lastFrameByteCodeOffset;
lubomir@221
    50
lubomir@221
    51
    private int byteCodeOffset;
lubomir@221
    52
lubomir@221
    53
    StackMapIterator(final StackMapTableData[] stackMapTable) {
lubomir@221
    54
        this.stackMapTable = (stackMapTable != null)
lubomir@221
    55
                                 ? stackMapTable
lubomir@221
    56
                                 : new StackMapTableData[0];
lubomir@281
    57
lubomir@281
    58
        localTypes = new TypeArray();
lubomir@281
    59
        stackTypes = new TypeArray();
lubomir@281
    60
        lastFrameByteCodeOffset = -1;
lubomir@221
    61
        advanceBy(0);
lubomir@221
    62
    }
lubomir@221
    63
lubomir@221
    64
    public String getFrameAsString() {
lubomir@221
    65
        return getCurrentFrame().toString();
lubomir@221
    66
    }
lubomir@221
    67
lubomir@221
    68
    public int getFrameIndex() {
lubomir@221
    69
        return nextFrameIndex;
lubomir@221
    70
    }
lubomir@221
    71
lubomir@281
    72
    public TypeArray getFrameStack() {
lubomir@281
    73
        return stackTypes;
lubomir@221
    74
    }
lubomir@221
    75
lubomir@221
    76
    public void advanceBy(final int numByteCodes) {
lubomir@221
    77
        if (numByteCodes < 0) {
lubomir@221
    78
            throw new IllegalStateException("Forward only iterator");
lubomir@221
    79
        }
lubomir@221
    80
lubomir@221
    81
        byteCodeOffset += numByteCodes;
lubomir@221
    82
        while ((nextFrameIndex < stackMapTable.length)
lubomir@221
    83
                    && ((byteCodeOffset - lastFrameByteCodeOffset)
lubomir@221
    84
                            >= (stackMapTable[nextFrameIndex].offsetDelta
lubomir@221
    85
                                    + 1))) {
lubomir@281
    86
            final StackMapTableData nextFrame = stackMapTable[nextFrameIndex];
lubomir@281
    87
lubomir@281
    88
            lastFrameByteCodeOffset += nextFrame.offsetDelta + 1;
lubomir@281
    89
            nextFrame.applyTo(localTypes, stackTypes);
lubomir@281
    90
lubomir@221
    91
            ++nextFrameIndex;
lubomir@221
    92
        }
lubomir@221
    93
    }
lubomir@221
    94
lubomir@221
    95
    public void advanceTo(final int nextByteCodeOffset) {
lubomir@221
    96
        advanceBy(nextByteCodeOffset - byteCodeOffset);
lubomir@221
    97
    }
lubomir@221
    98
lubomir@221
    99
    private StackMapTableData getCurrentFrame() {
lubomir@221
   100
        return (nextFrameIndex == 0)
lubomir@221
   101
                ? INITIAL_FRAME
lubomir@221
   102
                : stackMapTable[nextFrameIndex - 1];
lubomir@221
   103
    }
lubomir@221
   104
}