javap/src/main/java/org/apidesign/javap/StackMapIterator.java
author Lubomir Nerad <lubomir.nerad@oracle.com>
Thu, 29 Nov 2012 20:19:00 +0100
branchregisters
changeset 221 3ee23267706c
child 281 f2352e0b713e
permissions -rw-r--r--
Register based VM
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@221
    32
                int getStackItemsCount() {
lubomir@221
    33
                    return 0;
lubomir@221
    34
                }
lubomir@221
    35
lubomir@221
    36
                @Override
lubomir@221
    37
                public String toString() {
lubomir@221
    38
                    return "INITIAL(0)";
lubomir@221
    39
                }
lubomir@221
    40
            };
lubomir@221
    41
lubomir@221
    42
    private final StackMapTableData[] stackMapTable;
lubomir@221
    43
lubomir@221
    44
    private int nextFrameIndex;
lubomir@221
    45
    private int lastFrameByteCodeOffset;
lubomir@221
    46
lubomir@221
    47
    private int byteCodeOffset;
lubomir@221
    48
lubomir@221
    49
    StackMapIterator(final StackMapTableData[] stackMapTable) {
lubomir@221
    50
        this.stackMapTable = (stackMapTable != null)
lubomir@221
    51
                                 ? stackMapTable
lubomir@221
    52
                                 : new StackMapTableData[0];
lubomir@221
    53
        this.lastFrameByteCodeOffset = -1;
lubomir@221
    54
        advanceBy(0);
lubomir@221
    55
    }
lubomir@221
    56
lubomir@221
    57
    public String getFrameAsString() {
lubomir@221
    58
        return getCurrentFrame().toString();
lubomir@221
    59
    }
lubomir@221
    60
lubomir@221
    61
    public int getFrameIndex() {
lubomir@221
    62
        return nextFrameIndex;
lubomir@221
    63
    }
lubomir@221
    64
lubomir@221
    65
    public int getFrameStackItemsCount() {
lubomir@221
    66
        return getCurrentFrame().getStackItemsCount();
lubomir@221
    67
    }
lubomir@221
    68
lubomir@221
    69
    public void advanceBy(final int numByteCodes) {
lubomir@221
    70
        if (numByteCodes < 0) {
lubomir@221
    71
            throw new IllegalStateException("Forward only iterator");
lubomir@221
    72
        }
lubomir@221
    73
lubomir@221
    74
        byteCodeOffset += numByteCodes;
lubomir@221
    75
        while ((nextFrameIndex < stackMapTable.length)
lubomir@221
    76
                    && ((byteCodeOffset - lastFrameByteCodeOffset)
lubomir@221
    77
                            >= (stackMapTable[nextFrameIndex].offsetDelta
lubomir@221
    78
                                    + 1))) {
lubomir@221
    79
            lastFrameByteCodeOffset +=
lubomir@221
    80
                    stackMapTable[nextFrameIndex].offsetDelta + 1;
lubomir@221
    81
            ++nextFrameIndex;
lubomir@221
    82
        }
lubomir@221
    83
    }
lubomir@221
    84
lubomir@221
    85
    public void advanceTo(final int nextByteCodeOffset) {
lubomir@221
    86
        advanceBy(nextByteCodeOffset - byteCodeOffset);
lubomir@221
    87
    }
lubomir@221
    88
lubomir@221
    89
    private StackMapTableData getCurrentFrame() {
lubomir@221
    90
        return (nextFrameIndex == 0)
lubomir@221
    91
                ? INITIAL_FRAME
lubomir@221
    92
                : stackMapTable[nextFrameIndex - 1];
lubomir@221
    93
    }
lubomir@221
    94
}