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
     1 /*
     2  * Copyright (c) 2012, 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 package org.apidesign.javap;
    27 
    28 public final class StackMapIterator {
    29     private static final StackMapTableData INITIAL_FRAME =
    30             new StackMapTableData(-1) {
    31                 @Override
    32                 void applyTo(TypeArray localTypes, TypeArray stackTypes) {
    33                     localTypes.clear();
    34                     stackTypes.clear();
    35                 }
    36 
    37                 @Override
    38                 public String toString() {
    39                     return toString("INITIAL", 0, null, null);
    40                 }
    41 
    42             };
    43 
    44     private final StackMapTableData[] stackMapTable;
    45     private final TypeArray localTypes;
    46     private final TypeArray stackTypes;
    47 
    48     private int nextFrameIndex;
    49     private int lastFrameByteCodeOffset;
    50 
    51     private int byteCodeOffset;
    52 
    53     StackMapIterator(final StackMapTableData[] stackMapTable) {
    54         this.stackMapTable = (stackMapTable != null)
    55                                  ? stackMapTable
    56                                  : new StackMapTableData[0];
    57 
    58         localTypes = new TypeArray();
    59         stackTypes = new TypeArray();
    60         lastFrameByteCodeOffset = -1;
    61         advanceBy(0);
    62     }
    63 
    64     public String getFrameAsString() {
    65         return getCurrentFrame().toString();
    66     }
    67 
    68     public int getFrameIndex() {
    69         return nextFrameIndex;
    70     }
    71 
    72     public TypeArray getFrameStack() {
    73         return stackTypes;
    74     }
    75 
    76     public void advanceBy(final int numByteCodes) {
    77         if (numByteCodes < 0) {
    78             throw new IllegalStateException("Forward only iterator");
    79         }
    80 
    81         byteCodeOffset += numByteCodes;
    82         while ((nextFrameIndex < stackMapTable.length)
    83                     && ((byteCodeOffset - lastFrameByteCodeOffset)
    84                             >= (stackMapTable[nextFrameIndex].offsetDelta
    85                                     + 1))) {
    86             final StackMapTableData nextFrame = stackMapTable[nextFrameIndex];
    87 
    88             lastFrameByteCodeOffset += nextFrame.offsetDelta + 1;
    89             nextFrame.applyTo(localTypes, stackTypes);
    90 
    91             ++nextFrameIndex;
    92         }
    93     }
    94 
    95     public void advanceTo(final int nextByteCodeOffset) {
    96         advanceBy(nextByteCodeOffset - byteCodeOffset);
    97     }
    98 
    99     private StackMapTableData getCurrentFrame() {
   100         return (nextFrameIndex == 0)
   101                 ? INITIAL_FRAME
   102                 : stackMapTable[nextFrameIndex - 1];
   103     }
   104 }