169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/* 269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit. 369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. 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 Sigal 1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.bytecode; 1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/** 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Utility for computing <code>max_stack</code>. 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalclass CodeAnalyzer implements Opcode { 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private ConstPool constPool; 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private CodeAttribute codeAttr; 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public CodeAnalyzer(CodeAttribute ca) { 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal codeAttr = ca; 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal constPool = ca.getConstPool(); 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int computeMaxStack() 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* d = stack[i] 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * d == 0: not visited 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * d > 0: the depth is d - 1 after executing the bytecode at i. 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * d < 0: not visited. the initial depth (before execution) is 1 - d. 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CodeIterator ci = codeAttr.iterator(); 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int length = ci.getCodeLength(); 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int[] stack = new int[length]; 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal constPool = codeAttr.getConstPool(); 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal initStack(stack, codeAttr); 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean repeat; 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal do { 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal repeat = false; 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < length; ++i) 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (stack[i] < 0) { 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal repeat = true; 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal visitBytecode(ci, stack, i); 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } while (repeat); 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int maxStack = 1; 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < length; ++i) 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (stack[i] > maxStack) 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal maxStack = stack[i]; 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return maxStack - 1; // the base is 1. 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void initStack(int[] stack, CodeAttribute ca) { 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack[0] = -1; 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ExceptionTable et = ca.getExceptionTable(); 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (et != null) { 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int size = et.size(); 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < size; ++i) 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack[et.handlerPc(i)] = -2; // an exception is on stack 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void visitBytecode(CodeIterator ci, int[] stack, int index) 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int codeLength = stack.length; 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.move(index); 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int stackDepth = -stack[index]; 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int[] jsrDepth = new int[1]; 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal jsrDepth[0] = -1; 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (ci.hasNext()) { 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index = ci.next(); 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack[index] = stackDepth; 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int op = ci.byteAt(index); 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stackDepth = visitInst(op, ci, index, stackDepth); 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (stackDepth < 1) 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new BadBytecode("stack underflow at " + index); 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (processBranch(op, ci, index, codeLength, stack, stackDepth, jsrDepth)) 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (isEnd(op)) // return, ireturn, athrow, ... 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (op == JSR || op == JSR_W) 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal --stackDepth; 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private boolean processBranch(int opcode, CodeIterator ci, int index, 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int codeLength, int[] stack, int stackDepth, int[] jsrDepth) 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if ((IFEQ <= opcode && opcode <= IF_ACMPNE) 10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal || opcode == IFNULL || opcode == IFNONNULL) { 10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int target = index + ci.s16bitAt(index + 1); 10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal checkTarget(index, target, codeLength, stack, stackDepth); 10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int target, index2; 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal switch (opcode) { 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case GOTO : 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal target = index + ci.s16bitAt(index + 1); 11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal checkTarget(index, target, codeLength, stack, stackDepth); 11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return true; 11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case GOTO_W : 11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal target = index + ci.s32bitAt(index + 1); 11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal checkTarget(index, target, codeLength, stack, stackDepth); 11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return true; 11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case JSR : 11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case JSR_W : 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (opcode == JSR) 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal target = index + ci.s16bitAt(index + 1); 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal target = index + ci.s32bitAt(index + 1); 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal checkTarget(index, target, codeLength, stack, stackDepth); 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /* 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * It is unknown which RET comes back to this JSR. 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * So we assume that if the stack depth at one JSR instruction 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * is N, then it is also N at other JSRs and N - 1 at all RET 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * instructions. Note that STACK_GROW[JSR] is 1 since it pushes 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * a return address on the operand stack. 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (jsrDepth[0] < 0) { 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal jsrDepth[0] = stackDepth; 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return false; 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (stackDepth == jsrDepth[0]) 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return false; 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new BadBytecode( 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal "sorry, cannot compute this data flow due to JSR: " 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal + stackDepth + "," + jsrDepth[0]); 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case RET : 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (jsrDepth[0] < 0) { 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal jsrDepth[0] = stackDepth + 1; 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return false; 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (stackDepth + 1 == jsrDepth[0]) 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return true; 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new BadBytecode( 15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal "sorry, cannot compute this data flow due to RET: " 15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal + stackDepth + "," + jsrDepth[0]); 15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case LOOKUPSWITCH : 15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case TABLESWITCH : 15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index2 = (index & ~3) + 4; 15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal target = index + ci.s32bitAt(index2); 15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal checkTarget(index, target, codeLength, stack, stackDepth); 15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (opcode == LOOKUPSWITCH) { 16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int npairs = ci.s32bitAt(index2 + 4); 16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index2 += 12; 16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < npairs; ++i) { 16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal target = index + ci.s32bitAt(index2); 16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal checkTarget(index, target, codeLength, 16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack, stackDepth); 16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index2 += 8; 16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int low = ci.s32bitAt(index2 + 4); 17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int high = ci.s32bitAt(index2 + 8); 17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = high - low + 1; 17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index2 += 12; 17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; ++i) { 17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal target = index + ci.s32bitAt(index2); 17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal checkTarget(index, target, codeLength, 17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack, stackDepth); 17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index2 += 4; 17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return true; // always branch. 18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return false; // may not branch. 18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void checkTarget(int opIndex, int target, int codeLength, 19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int[] stack, int stackDepth) 19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (target < 0 || codeLength <= target) 19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new BadBytecode("bad branch offset at " + opIndex); 19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int d = stack[target]; 19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (d == 0) 19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack[target] = -stackDepth; 19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (d != stackDepth && d != -stackDepth) 20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new BadBytecode("verification error (" + stackDepth + 20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal "," + d + ") at " + opIndex); 20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static boolean isEnd(int opcode) { 20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return (IRETURN <= opcode && opcode <= RETURN) || opcode == ATHROW; 20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Visits an instruction. 21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private int visitInst(int op, CodeIterator ci, int index, int stack) 21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String desc; 21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal switch (op) { 21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case GETFIELD : 21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack += getFieldSize(ci, index) - 1; 21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case PUTFIELD : 22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack -= getFieldSize(ci, index) + 1; 22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case GETSTATIC : 22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack += getFieldSize(ci, index); 22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case PUTSTATIC : 22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack -= getFieldSize(ci, index); 22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case INVOKEVIRTUAL : 22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case INVOKESPECIAL : 23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal desc = constPool.getMethodrefType(ci.u16bitAt(index + 1)); 23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack += Descriptor.dataSize(desc) - 1; 23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case INVOKESTATIC : 23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal desc = constPool.getMethodrefType(ci.u16bitAt(index + 1)); 23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack += Descriptor.dataSize(desc); 23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case INVOKEINTERFACE : 23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal desc = constPool.getInterfaceMethodrefType( 23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.u16bitAt(index + 1)); 24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack += Descriptor.dataSize(desc) - 1; 24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case ATHROW : 24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack = 1; // the stack becomes empty (1 means no values). 24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case MULTIANEWARRAY : 24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack += 1 - ci.byteAt(index + 3); 24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case WIDE : 24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal op = ci.byteAt(index + 1); 25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // don't break here. 25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal default : 25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stack += STACK_GROW[op]; 25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return stack; 25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private int getFieldSize(CodeIterator ci, int index) { 25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String desc = constPool.getFieldrefType(ci.u16bitAt(index + 1)); 26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return Descriptor.dataSize(desc); 26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 263