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 Sigal package javassist.bytecode.stackmap; 1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.*; 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class Liveness { 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected static final byte UNKNOWN = 0; 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected static final byte READ = 1; 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected static final byte UPDATED = 2; 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected byte[] localsUsage; 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If true, all the arguments become alive within the whole method body. 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * To correctly compute a stack map table, all the arguments must 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * be alive (localsUsage[?] must be READ) at least in the first block. 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static boolean useArgs = true; 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void compute(CodeIterator ci, TypedBlock[] blocks, int maxLocals, 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypeData[] args) 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal computeUsage(ci, blocks, maxLocals); 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (useArgs) 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal useAllArgs(blocks, args); 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal computeLiveness1(blocks[0]); 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (hasChanged(blocks)) 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal computeLiveness2(blocks[0]); 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void useAllArgs(TypedBlock[] blocks, TypeData[] args) { 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int k = 0; k < blocks.length; k++) { 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal byte[] usage = blocks[k].localsUsage; 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < args.length; i++) 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (args[i] != TypeTag.TOP) 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal usage[i] = READ; 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static final int NOT_YET = 0; 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static final int CHANGED_LAST = 1; 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static final int DONE = 2; 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal static final int CHANGED_NOW = 3; 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void computeLiveness1(TypedBlock tb) { 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (tb.updating) { 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // a loop was detected. 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal computeLiveness1u(tb); 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (tb.inputs != null) 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.updating = true; 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal byte[] usage = tb.localsUsage; 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = usage.length; 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean[] in = new boolean[n]; 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; i++) 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal in[i] = usage[i] == READ; 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal BasicBlock.Catch handlers = tb.toCatch; 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (handlers != null) { 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypedBlock h = (TypedBlock)handlers.body; 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal computeLiveness1(h); 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int k = 0; k < n; k++) 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (h.inputs[k]) 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal in[k] = true; 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal handlers = handlers.next; 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (tb.exit != null) { 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < tb.exit.length; i++) { 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypedBlock e = (TypedBlock)tb.exit[i]; 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal computeLiveness1(e); 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int k = 0; k < n; k++) 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (!in[k]) 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal in[k] = usage[k] == UNKNOWN && e.inputs[k]; 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.updating = false; 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (tb.inputs == null) { 10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.inputs = in; 10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.status = DONE; 10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; i++) 10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (in[i] && !tb.inputs[i]) { 10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.inputs[i] = true; 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.status = CHANGED_NOW; 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void computeLiveness1u(TypedBlock tb) { 11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (tb.inputs == null) { 11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal byte[] usage = tb.localsUsage; 11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = usage.length; 11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean[] in = new boolean[n]; 11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; i++) 11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal in[i] = usage[i] == READ; 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.inputs = in; 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.status = DONE; 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void computeLiveness2(TypedBlock tb) { 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (tb.updating || tb.status >= DONE) 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return; 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.updating = true; 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (tb.exit == null) 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.status = DONE; 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean changed = false; 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < tb.exit.length; i++) { 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypedBlock e = (TypedBlock)tb.exit[i]; 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal computeLiveness2(e); 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (e.status != DONE) 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal changed = true; 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (changed) { 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal changed = false; 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal byte[] usage = tb.localsUsage; 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = usage.length; 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < tb.exit.length; i++) { 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypedBlock e = (TypedBlock)tb.exit[i]; 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (e.status != DONE) 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int k = 0; k < n; k++) 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (!tb.inputs[k]) { 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (usage[k] == UNKNOWN && e.inputs[k]) { 15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.inputs[k] = true; 15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal changed = true; 15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.status = changed ? CHANGED_NOW : DONE; 15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.status = DONE; 16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (computeLiveness2except(tb)) 16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.status = CHANGED_NOW; 16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.updating = false; 16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private boolean computeLiveness2except(TypedBlock tb) { 17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal BasicBlock.Catch handlers = tb.toCatch; 17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean changed = false; 17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (handlers != null) { 17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypedBlock h = (TypedBlock)handlers.body; 17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal computeLiveness2(h); 17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (h.status != DONE) { 17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean[] in = tb.inputs; 17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = in.length; 17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int k = 0; k < n; k++) 18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (!in[k] && h.inputs[k]) { 18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal in[k] = true; 18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal changed = true; 18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal handlers = handlers.next; 18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return changed; 19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private boolean hasChanged(TypedBlock[] blocks) { 19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = blocks.length; 19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean changed = false; 19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; i++) { 19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypedBlock tb = blocks[i]; 19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (tb.status == CHANGED_NOW) { 19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.status = CHANGED_LAST; 19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal changed = true; 20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal tb.status = NOT_YET; 20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return changed; 20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void computeUsage(CodeIterator ci, TypedBlock[] blocks, int maxLocals) 20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = blocks.length; 21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; i++) { 21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal TypedBlock tb = blocks[i]; 21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal localsUsage = tb.localsUsage = new byte[maxLocals]; 21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int pos = tb.position; 21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal analyze(ci, pos, pos + tb.length); 21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal localsUsage = null; 21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected final void readLocal(int reg) { 22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (localsUsage[reg] == UNKNOWN) 22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal localsUsage[reg] = READ; 22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected final void writeLocal(int reg) { 22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (localsUsage[reg] == UNKNOWN) 22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal localsUsage[reg] = UPDATED; 22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected void analyze(CodeIterator ci, int begin, int end) 23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws BadBytecode 23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.begin(); 23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ci.move(begin); 23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (ci.hasNext()) { 23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int index = ci.next(); 23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (index >= end) 23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int op = ci.byteAt(index); 24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (op < 96) 24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (op < 54) 24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal doOpcode0_53(ci, index, op); 24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal doOpcode54_95(ci, index, op); 24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (op == Opcode.IINC) { 24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // this does not call writeLocal(). 25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal readLocal(ci.byteAt(index + 1)); 25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (op == Opcode.WIDE) 25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal doWIDE(ci, index); 25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void doOpcode0_53(CodeIterator ci, int pos, int op) { 25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal switch (op) { 25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ILOAD : 26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.LLOAD : 26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.FLOAD : 26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.DLOAD : 26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ALOAD : 26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal readLocal(ci.byteAt(pos + 1)); 26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ILOAD_0 : 26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ILOAD_1 : 26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ILOAD_2 : 26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ILOAD_3 : 27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal readLocal(op - Opcode.ILOAD_0); 27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.LLOAD_0 : 27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.LLOAD_1 : 27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.LLOAD_2 : 27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.LLOAD_3 : 27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal readLocal(op - Opcode.LLOAD_0); 27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.FLOAD_0 : 27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.FLOAD_1 : 28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.FLOAD_2 : 28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.FLOAD_3 : 28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal readLocal(op - Opcode.FLOAD_0); 28369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 28469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.DLOAD_0 : 28569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.DLOAD_1 : 28669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.DLOAD_2 : 28769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.DLOAD_3 : 28869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal readLocal(op - Opcode.DLOAD_0); 28969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 29069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ALOAD_0 : 29169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ALOAD_1 : 29269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ALOAD_2 : 29369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ALOAD_3 : 29469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal readLocal(op - Opcode.ALOAD_0); 29569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 29669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 29769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 29869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 29969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void doOpcode54_95(CodeIterator ci, int pos, int op) { 30069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal switch (op) { 30169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ISTORE : 30269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.LSTORE : 30369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.FSTORE : 30469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.DSTORE : 30569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ASTORE : 30669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal writeLocal(ci.byteAt(pos + 1)); 30769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 30869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ISTORE_0 : 30969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ISTORE_1 : 31069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ISTORE_2 : 31169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ISTORE_3 : 31269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal writeLocal(op - Opcode.ISTORE_0); 31369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 31469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.LSTORE_0 : 31569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.LSTORE_1 : 31669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.LSTORE_2 : 31769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.LSTORE_3 : 31869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal writeLocal(op - Opcode.LSTORE_0); 31969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 32069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.FSTORE_0 : 32169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.FSTORE_1 : 32269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.FSTORE_2 : 32369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.FSTORE_3 : 32469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal writeLocal(op - Opcode.FSTORE_0); 32569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 32669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.DSTORE_0 : 32769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.DSTORE_1 : 32869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.DSTORE_2 : 32969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.DSTORE_3 : 33069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal writeLocal(op - Opcode.DSTORE_0); 33169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 33269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ASTORE_0 : 33369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ASTORE_1 : 33469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ASTORE_2 : 33569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ASTORE_3 : 33669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal writeLocal(op - Opcode.ASTORE_0); 33769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 33869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 33969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 34069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 34169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private void doWIDE(CodeIterator ci, int pos) throws BadBytecode { 34269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int op = ci.byteAt(pos + 1); 34369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int var = ci.u16bitAt(pos + 2); 34469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal switch (op) { 34569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ILOAD : 34669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.LLOAD : 34769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.FLOAD : 34869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.DLOAD : 34969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ALOAD : 35069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal readLocal(var); 35169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 35269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ISTORE : 35369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.LSTORE : 35469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.FSTORE : 35569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.DSTORE : 35669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.ASTORE : 35769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal writeLocal(var); 35869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 35969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal case Opcode.IINC : 36069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal readLocal(var); 36169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal // this does not call writeLocal(). 36269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal break; 36369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 36469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 36569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 366