1674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/*** 2674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * ASM: a very small and fast Java bytecode manipulation framework 3674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Copyright (c) 2000-2007 INRIA, France Telecom 4674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * All rights reserved. 5674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 6674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Redistribution and use in source and binary forms, with or without 7674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * modification, are permitted provided that the following conditions 8674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * are met: 9674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 1. Redistributions of source code must retain the above copyright 10674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * notice, this list of conditions and the following disclaimer. 11674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 2. Redistributions in binary form must reproduce the above copyright 12674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * notice, this list of conditions and the following disclaimer in the 13674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * documentation and/or other materials provided with the distribution. 14674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 3. Neither the name of the copyright holders nor the names of its 15674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * contributors may be used to endorse or promote products derived from 16674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * this software without specific prior written permission. 17674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 18674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 22674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 28674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * THE POSSIBILITY OF SUCH DAMAGE. 29674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 30674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpackage org.mockito.asm.tree.analysis; 31674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 32674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport java.util.ArrayList; 33674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport java.util.List; 34674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 35674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.Opcodes; 36674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.Type; 37674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.tree.AbstractInsnNode; 38674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.tree.IincInsnNode; 39674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.tree.MethodInsnNode; 40674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.tree.MultiANewArrayInsnNode; 41674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.tree.VarInsnNode; 42674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 43674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/** 44674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * A symbolic execution stack frame. A stack frame contains a set of local 45674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * variable slots, and an operand stack. Warning: long and double values are 46674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * represented by <i>two</i> slots in local variables, and by <i>one</i> slot 47674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * in the operand stack. 48674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 49674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @author Eric Bruneton 50674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 51674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpublic class Frame { 52674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 53674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 54674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * The local variables and operand stack of this frame. 55674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 56674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private Value[] values; 57674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 58674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 59674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * The number of local variables of this frame. 60674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 61674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private int locals; 62674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 63674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 64674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * The number of elements in the operand stack. 65674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 66674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen private int top; 67674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 68674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 69674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Constructs a new frame with the given size. 70674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 71674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @param nLocals the maximum number of local variables of the frame. 72674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @param nStack the maximum stack size of the frame. 73674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 74674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public Frame(final int nLocals, final int nStack) { 75674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen this.values = new Value[nLocals + nStack]; 76674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen this.locals = nLocals; 77674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 78674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 79674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 80674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Constructs a new frame that is identical to the given frame. 81674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 82674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @param src a frame. 83674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 84674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public Frame(final Frame src) { 85674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen this(src.locals, src.values.length - src.locals); 86674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen init(src); 87674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 88674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 89674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 90674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Copies the state of the given frame into this frame. 91674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 92674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @param src a frame. 93674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @return this frame. 94674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 95674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public Frame init(final Frame src) { 96674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen System.arraycopy(src.values, 0, values, 0, values.length); 97674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen top = src.top; 98674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return this; 99674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 100674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 101674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 102674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Returns the maximum number of local variables of this frame. 103674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 104674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @return the maximum number of local variables of this frame. 105674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 106674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public int getLocals() { 107674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return locals; 108674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 109674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 110674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 111674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Returns the value of the given local variable. 112674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 113674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @param i a local variable index. 114674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @return the value of the given local variable. 115674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @throws IndexOutOfBoundsException if the variable does not exist. 116674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 117674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public Value getLocal(final int i) throws IndexOutOfBoundsException { 118674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (i >= locals) { 119674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new IndexOutOfBoundsException("Trying to access an inexistant local variable"); 120674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 121674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return values[i]; 122674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 123674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 124674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 125674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Sets the value of the given local variable. 126674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 127674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @param i a local variable index. 128674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @param value the new value of this local variable. 129674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @throws IndexOutOfBoundsException if the variable does not exist. 130674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 131674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void setLocal(final int i, final Value value) 132674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throws IndexOutOfBoundsException 133674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen { 134674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (i >= locals) { 135674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new IndexOutOfBoundsException("Trying to access an inexistant local variable"); 136674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 137674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen values[i] = value; 138674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 139674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 140674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 141674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Returns the number of values in the operand stack of this frame. Long and 142674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * double values are treated as single values. 143674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 144674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @return the number of values in the operand stack of this frame. 145674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 146674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public int getStackSize() { 147674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return top; 148674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 149674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 150674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 151674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Returns the value of the given operand stack slot. 152674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 153674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @param i the index of an operand stack slot. 154674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @return the value of the given operand stack slot. 155674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @throws IndexOutOfBoundsException if the operand stack slot does not 156674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * exist. 157674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 158674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public Value getStack(final int i) throws IndexOutOfBoundsException { 159674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return values[i + locals]; 160674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 161674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 162674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 163674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Clears the operand stack of this frame. 164674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 165674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void clearStack() { 166674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen top = 0; 167674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 168674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 169674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 170674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Pops a value from the operand stack of this frame. 171674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 172674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @return the value that has been popped from the stack. 173674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @throws IndexOutOfBoundsException if the operand stack is empty. 174674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 175674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public Value pop() throws IndexOutOfBoundsException { 176674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (top == 0) { 177674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new IndexOutOfBoundsException("Cannot pop operand off an empty stack."); 178674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 179674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return values[--top + locals]; 180674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 181674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 182674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 183674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Pushes a value into the operand stack of this frame. 184674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 185674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @param value the value that must be pushed into the stack. 186674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @throws IndexOutOfBoundsException if the operand stack is full. 187674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 188674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void push(final Value value) throws IndexOutOfBoundsException { 189674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (top + locals >= values.length) { 190674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new IndexOutOfBoundsException("Insufficient maximum stack size."); 191674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 192674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen values[top++ + locals] = value; 193674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 194674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 195674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public void execute( 196674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen final AbstractInsnNode insn, 197674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen final Interpreter interpreter) throws AnalyzerException 198674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen { 199674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Value value1, value2, value3, value4; 200674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen List values; 201674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen int var; 202674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 203674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen switch (insn.getOpcode()) { 204674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.NOP: 205674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 206674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ACONST_NULL: 207674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ICONST_M1: 208674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ICONST_0: 209674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ICONST_1: 210674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ICONST_2: 211674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ICONST_3: 212674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ICONST_4: 213674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ICONST_5: 214674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LCONST_0: 215674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LCONST_1: 216674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FCONST_0: 217674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FCONST_1: 218674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FCONST_2: 219674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DCONST_0: 220674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DCONST_1: 221674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.BIPUSH: 222674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.SIPUSH: 223674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LDC: 224674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.newOperation(insn)); 225674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 226674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ILOAD: 227674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LLOAD: 228674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FLOAD: 229674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DLOAD: 230674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ALOAD: 231674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, 232674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen getLocal(((VarInsnNode) insn).var))); 233674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 234674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IALOAD: 235674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LALOAD: 236674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FALOAD: 237674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DALOAD: 238674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.AALOAD: 239674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.BALOAD: 240674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.CALOAD: 241674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.SALOAD: 242674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value2 = pop(); 243674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value1 = pop(); 244674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.binaryOperation(insn, value1, value2)); 245674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 246674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ISTORE: 247674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LSTORE: 248674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FSTORE: 249674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DSTORE: 250674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ASTORE: 251674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value1 = interpreter.copyOperation(insn, pop()); 252674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen var = ((VarInsnNode) insn).var; 253674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen setLocal(var, value1); 254674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value1.getSize() == 2) { 255674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen setLocal(var + 1, interpreter.newValue(null)); 256674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 257674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (var > 0) { 258674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Value local = getLocal(var - 1); 259674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (local != null && local.getSize() == 2) { 260674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen setLocal(var - 1, interpreter.newValue(null)); 261674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 262674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 263674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 264674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IASTORE: 265674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LASTORE: 266674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FASTORE: 267674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DASTORE: 268674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.AASTORE: 269674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.BASTORE: 270674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.CASTORE: 271674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.SASTORE: 272674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value3 = pop(); 273674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value2 = pop(); 274674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value1 = pop(); 275674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen interpreter.ternaryOperation(insn, value1, value2, value3); 276674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 277674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.POP: 278674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (pop().getSize() == 2) { 279674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new AnalyzerException("Illegal use of POP"); 280674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 281674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 282674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.POP2: 283674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (pop().getSize() == 1) { 284674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (pop().getSize() != 1) { 285674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new AnalyzerException("Illegal use of POP2"); 286674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 287674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 288674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 289674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DUP: 290674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value1 = pop(); 291674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value1.getSize() != 1) { 292674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new AnalyzerException("Illegal use of DUP"); 293674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 294674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 295674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 296674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 297674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DUP_X1: 298674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value1 = pop(); 299674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value2 = pop(); 300674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value1.getSize() != 1 || value2.getSize() != 1) { 301674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new AnalyzerException("Illegal use of DUP_X1"); 302674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 303674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 304674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value2)); 305674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 306674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 307674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DUP_X2: 308674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value1 = pop(); 309674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value1.getSize() == 1) { 310674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value2 = pop(); 311674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value2.getSize() == 1) { 312674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value3 = pop(); 313674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value3.getSize() == 1) { 314674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 315674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value3)); 316674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value2)); 317674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 318674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 319674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 320674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } else { 321674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 322674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value2)); 323674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 324674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 325674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 326674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 327674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new AnalyzerException("Illegal use of DUP_X2"); 328674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DUP2: 329674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value1 = pop(); 330674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value1.getSize() == 1) { 331674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value2 = pop(); 332674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value2.getSize() == 1) { 333674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value2)); 334674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 335674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value2)); 336674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 337674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 338674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 339674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } else { 340674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 341674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 342674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 343674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 344674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new AnalyzerException("Illegal use of DUP2"); 345674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DUP2_X1: 346674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value1 = pop(); 347674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value1.getSize() == 1) { 348674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value2 = pop(); 349674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value2.getSize() == 1) { 350674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value3 = pop(); 351674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value3.getSize() == 1) { 352674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value2)); 353674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 354674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value3)); 355674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value2)); 356674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 357674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 358674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 359674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 360674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } else { 361674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value2 = pop(); 362674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value2.getSize() == 1) { 363674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 364674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value2)); 365674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 366674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 367674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 368674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 369674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new AnalyzerException("Illegal use of DUP2_X1"); 370674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DUP2_X2: 371674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value1 = pop(); 372674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value1.getSize() == 1) { 373674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value2 = pop(); 374674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value2.getSize() == 1) { 375674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value3 = pop(); 376674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value3.getSize() == 1) { 377674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value4 = pop(); 378674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value4.getSize() == 1) { 379674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value2)); 380674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 381674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value4)); 382674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value3)); 383674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value2)); 384674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 385674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 386674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 387674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } else { 388674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value2)); 389674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 390674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value3)); 391674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value2)); 392674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 393674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 394674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 395674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 396674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } else { 397674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value2 = pop(); 398674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value2.getSize() == 1) { 399674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value3 = pop(); 400674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value3.getSize() == 1) { 401674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 402674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value3)); 403674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value2)); 404674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 405674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 406674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 407674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } else { 408674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 409674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value2)); 410674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 411674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 412674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 413674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 414674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new AnalyzerException("Illegal use of DUP2_X2"); 415674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.SWAP: 416674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value2 = pop(); 417674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value1 = pop(); 418674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (value1.getSize() != 1 || value2.getSize() != 1) { 419674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new AnalyzerException("Illegal use of SWAP"); 420674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 421674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value2)); 422674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.copyOperation(insn, value1)); 423674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 424674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IADD: 425674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LADD: 426674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FADD: 427674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DADD: 428674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ISUB: 429674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LSUB: 430674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FSUB: 431674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DSUB: 432674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IMUL: 433674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LMUL: 434674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FMUL: 435674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DMUL: 436674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IDIV: 437674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LDIV: 438674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FDIV: 439674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DDIV: 440674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IREM: 441674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LREM: 442674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FREM: 443674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DREM: 444674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value2 = pop(); 445674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value1 = pop(); 446674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.binaryOperation(insn, value1, value2)); 447674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 448674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.INEG: 449674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LNEG: 450674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FNEG: 451674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DNEG: 452674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.unaryOperation(insn, pop())); 453674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 454674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ISHL: 455674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LSHL: 456674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ISHR: 457674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LSHR: 458674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IUSHR: 459674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LUSHR: 460674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IAND: 461674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LAND: 462674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IOR: 463674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LOR: 464674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IXOR: 465674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LXOR: 466674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value2 = pop(); 467674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value1 = pop(); 468674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.binaryOperation(insn, value1, value2)); 469674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 470674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IINC: 471674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen var = ((IincInsnNode) insn).var; 472674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen setLocal(var, interpreter.unaryOperation(insn, getLocal(var))); 473674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 474674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.I2L: 475674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.I2F: 476674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.I2D: 477674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.L2I: 478674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.L2F: 479674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.L2D: 480674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.F2I: 481674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.F2L: 482674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.F2D: 483674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.D2I: 484674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.D2L: 485674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.D2F: 486674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.I2B: 487674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.I2C: 488674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.I2S: 489674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.unaryOperation(insn, pop())); 490674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 491674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LCMP: 492674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FCMPL: 493674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FCMPG: 494674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DCMPL: 495674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DCMPG: 496674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value2 = pop(); 497674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value1 = pop(); 498674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.binaryOperation(insn, value1, value2)); 499674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 500674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IFEQ: 501674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IFNE: 502674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IFLT: 503674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IFGE: 504674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IFGT: 505674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IFLE: 506674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen interpreter.unaryOperation(insn, pop()); 507674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 508674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IF_ICMPEQ: 509674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IF_ICMPNE: 510674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IF_ICMPLT: 511674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IF_ICMPGE: 512674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IF_ICMPGT: 513674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IF_ICMPLE: 514674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IF_ACMPEQ: 515674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IF_ACMPNE: 516674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value2 = pop(); 517674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value1 = pop(); 518674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen interpreter.binaryOperation(insn, value1, value2); 519674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 520674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.GOTO: 521674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 522674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.JSR: 523674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.newOperation(insn)); 524674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 525674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.RET: 526674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 527674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.TABLESWITCH: 528674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LOOKUPSWITCH: 529674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IRETURN: 530674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.LRETURN: 531674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.FRETURN: 532674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.DRETURN: 533674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ARETURN: 534674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen interpreter.unaryOperation(insn, pop()); 535674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 536674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.RETURN: 537674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 538674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.GETSTATIC: 539674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.newOperation(insn)); 540674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 541674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.PUTSTATIC: 542674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen interpreter.unaryOperation(insn, pop()); 543674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 544674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.GETFIELD: 545674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.unaryOperation(insn, pop())); 546674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 547674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.PUTFIELD: 548674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value2 = pop(); 549674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen value1 = pop(); 550674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen interpreter.binaryOperation(insn, value1, value2); 551674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 552674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.INVOKEVIRTUAL: 553674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.INVOKESPECIAL: 554674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.INVOKESTATIC: 555674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.INVOKEINTERFACE: 556674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen values = new ArrayList(); 557674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen String desc = ((MethodInsnNode) insn).desc; 558674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen for (int i = Type.getArgumentTypes(desc).length; i > 0; --i) { 559674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen values.add(0, pop()); 560674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 561674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (insn.getOpcode() != Opcodes.INVOKESTATIC) { 562674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen values.add(0, pop()); 563674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 564674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (Type.getReturnType(desc) == Type.VOID_TYPE) { 565674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen interpreter.naryOperation(insn, values); 566674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } else { 567674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.naryOperation(insn, values)); 568674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 569674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 570674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.NEW: 571674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.newOperation(insn)); 572674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 573674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.NEWARRAY: 574674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ANEWARRAY: 575674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ARRAYLENGTH: 576674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.unaryOperation(insn, pop())); 577674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 578674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.ATHROW: 579674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen interpreter.unaryOperation(insn, pop()); 580674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 581674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.CHECKCAST: 582674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.INSTANCEOF: 583674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.unaryOperation(insn, pop())); 584674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 585674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.MONITORENTER: 586674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.MONITOREXIT: 587674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen interpreter.unaryOperation(insn, pop()); 588674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 589674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.MULTIANEWARRAY: 590674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen values = new ArrayList(); 591674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen for (int i = ((MultiANewArrayInsnNode) insn).dims; i > 0; --i) { 592674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen values.add(0, pop()); 593674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 594674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen push(interpreter.naryOperation(insn, values)); 595674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 596674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IFNULL: 597674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen case Opcodes.IFNONNULL: 598674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen interpreter.unaryOperation(insn, pop()); 599674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen break; 600674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen default: 601674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new RuntimeException("Illegal opcode"); 602674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 603674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 604674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 605674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 606674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Merges this frame with the given frame. 607674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 608674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @param frame a frame. 609674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @param interpreter the interpreter used to merge values. 610674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @return <tt>true</tt> if this frame has been changed as a result of the 611674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * merge operation, or <tt>false</tt> otherwise. 612674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @throws AnalyzerException if the frames have incompatible sizes. 613674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 614674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public boolean merge(final Frame frame, final Interpreter interpreter) 615674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throws AnalyzerException 616674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen { 617674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (top != frame.top) { 618674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen throw new AnalyzerException("Incompatible stack heights"); 619674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 620674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen boolean changes = false; 621674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen for (int i = 0; i < locals + top; ++i) { 622674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen Value v = interpreter.merge(values[i], frame.values[i]); 623674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (v != values[i]) { 624674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen values[i] = v; 625674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen changes |= true; 626674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 627674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 628674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return changes; 629674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 630674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 631674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 632674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Merges this frame with the given frame (case of a RET instruction). 633674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 634674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @param frame a frame 635674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @param access the local variables that have been accessed by the 636674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * subroutine to which the RET instruction corresponds. 637674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @return <tt>true</tt> if this frame has been changed as a result of the 638674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * merge operation, or <tt>false</tt> otherwise. 639674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 640674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public boolean merge(final Frame frame, final boolean[] access) { 641674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen boolean changes = false; 642674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen for (int i = 0; i < locals; ++i) { 643674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen if (!access[i] && !values[i].equals(frame.values[i])) { 644674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen values[i] = frame.values[i]; 645674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen changes = true; 646674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 647674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 648674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return changes; 649674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 650674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen 651674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen /** 652674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Returns a string representation of this frame. 653674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * 654674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * @return a string representation of this frame. 655674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */ 656674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen public String toString() { 657674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen StringBuffer b = new StringBuffer(); 658674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen for (int i = 0; i < getLocals(); ++i) { 659674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen b.append(getLocal(i)); 660674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 661674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen b.append(' '); 662674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen for (int i = 0; i < getStackSize(); ++i) { 663674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen b.append(getStack(i).toString()); 664674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 665674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen return b.toString(); 666674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen } 667674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen} 668