169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/* 269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit. 369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba, and others. All Rights Reserved. 469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version 669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with 769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License. Alternatively, the contents of this file may be used under 869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later. 969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis, 1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the 1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License. 1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.bytecode.analysis; 1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/** 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Represents the stack frame and local variable table at a particular point in time. 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @author Jason T. Greene 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class Frame { 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private Type[] locals; 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private Type[] stack; 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private int top; 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private boolean jsrMerged; 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private boolean retMerged; 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Create a new frame with the specified local variable table size, and max stack size 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param locals the number of local variable table entries 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param stack the maximum stack size 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Frame(int locals, int stack) { 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal this.locals = new Type[locals]; 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal this.stack = new Type[stack]; 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the local varaible table entry at index. 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param index the position in the table 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the type if one exists, or null if the position is empty 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Type getLocal(int index) { 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return locals[index]; 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Sets the local variable table entry at index to a type. 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param index the position in the table 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param type the type to set at the position 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setLocal(int index, Type type) { 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal locals[index] = type; 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the type on the stack at the specified index. 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param index the position on the stack 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the type of the stack position 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Type getStack(int index) { 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return stack[index]; 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Sets the type of the stack position 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param index the position on the stack 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param type the type to set 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setStack(int index, Type type) { 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack[index] = type; 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Empties the stack 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void clearStack() { 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal top = 0; 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Gets the index of the type sitting at the top of the stack. 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * This is not to be confused with a length operation which 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * would return the number of elements, not the position of 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the last element. 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the position of the element at the top of the stack 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int getTopIndex() { 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return top - 1; 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the number of local variable table entries, specified 10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * at construction. 10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the number of local variable table entries 10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int localsLength() { 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return locals.length; 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Gets the top of the stack without altering it 11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the top of the stack 11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Type peek() { 11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (top < 1) 11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new IndexOutOfBoundsException("Stack is empty"); 11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return stack[top - 1]; 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Alters the stack to contain one less element and return it. 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the element popped from the stack 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Type pop() { 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (top < 1) 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new IndexOutOfBoundsException("Stack is empty"); 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return stack[--top]; 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Alters the stack by placing the passed type on the top 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param type the type to add to the top 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void push(Type type) { 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack[top++] = type; 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Makes a shallow copy of this frame, i.e. the type instances will 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * remain the same. 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the shallow copy 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Frame copy() { 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Frame frame = new Frame(locals.length, stack.length); 15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal System.arraycopy(locals, 0, frame.locals, 0, locals.length); 15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal System.arraycopy(stack, 0, frame.stack, 0, stack.length); 15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal frame.top = top; 15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return frame; 15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Makes a shallow copy of the stack portion of this frame. The local 16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * variable table size will be copied, but its contents will be empty. 16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return the shallow copy of the stack 16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Frame copyStack() { 16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Frame frame = new Frame(locals.length, stack.length); 16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal System.arraycopy(stack, 0, frame.stack, 0, stack.length); 16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal frame.top = top; 16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return frame; 16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Merges all types on the stack of this frame instance with that of the specified frame. 17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The local variable table is left untouched. 17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param frame the frame to merge the stack from 17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return true if any changes where made 17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean mergeStack(Frame frame) { 17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean changed = false; 18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (top != frame.top) 18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new RuntimeException("Operand stacks could not be merged, they are different sizes!"); 18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < top; i++) { 18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (stack[i] != null) { 18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Type prev = stack[i]; 18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Type merged = prev.merge(frame.stack[i]); 18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (merged == Type.BOGUS) 18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new RuntimeException("Operand stacks could not be merged due to differing primitive types: pos = " + i); 18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack[i] = merged; 19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // always replace the instance in case a multi-interface type changes to a normal Type 19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if ((! merged.equals(prev)) || merged.popChanged()) { 19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal changed = true; 19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return changed; 19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Merges all types on the stack and local variable table of this frame with that of the specified 20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * type. 20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param frame the frame to merge with 20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return true if any changes to this frame where made by this merge 20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean merge(Frame frame) { 20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean changed = false; 21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // Local variable table 21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < locals.length; i++) { 21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (locals[i] != null) { 21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Type prev = locals[i]; 21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Type merged = prev.merge(frame.locals[i]); 21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // always replace the instance in case a multi-interface type changes to a normal Type 21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal locals[i] = merged; 21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (! merged.equals(prev) || merged.popChanged()) { 21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal changed = true; 22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } else if (frame.locals[i] != null) { 22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal locals[i] = frame.locals[i]; 22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal changed = true; 22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal changed |= mergeStack(frame); 22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return changed; 22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public String toString() { 23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal StringBuffer buffer = new StringBuffer(); 23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal buffer.append("locals = ["); 23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < locals.length; i++) { 23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal buffer.append(locals[i] == null ? "empty" : locals[i].toString()); 23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (i < locals.length - 1) 23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal buffer.append(", "); 23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal buffer.append("] stack = ["); 24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < top; i++) { 24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal buffer.append(stack[i]); 24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (i < top - 1) 24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal buffer.append(", "); 24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal buffer.append("]"); 24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return buffer.toString(); 24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Whether or not state from the source JSR instruction has been merged 25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return true if JSR state has been merged 25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean isJsrMerged() { 25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return jsrMerged; 25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Sets whether of not the state from the source JSR instruction has been merged 26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param jsrMerged true if merged, otherwise false 26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void setJsrMerged(boolean jsrMerged) { 26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal this.jsrMerged = jsrMerged; 26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Whether or not state from the RET instruction, of the subroutine that was jumped 27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to has been merged. 27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return true if RET state has been merged 27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean isRetMerged() { 27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return retMerged; 27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Sets whether or not state from the RET instruction, of the subroutine that was jumped 28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to has been merged. 28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 28369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param retMerged true if RET state has been merged 28469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 28569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal void setRetMerged(boolean retMerged) { 28669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal this.retMerged = retMerged; 28769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 28869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 289