void rewriteLocal(InstructionHandle fromH, InstructionHandle toH, int oldindex, int newindex) { InstructionHandle h = fromH; if (h.getPrev() != null) { h = h.getPrev(); // This instruction should contain the store. } while (h != null && h != toH) { Instruction ins = h.getInstruction(); if (ins instanceof LocalVariableInstruction) { LocalVariableInstruction lins = (LocalVariableInstruction) ins; if (lins.getIndex() == oldindex) { lins.setIndex(newindex); } } h = h.getNext(); } }
final LocalVariableGen getLocal(MethodGen m, LocalVariableInstruction curr, int pos) { int localNr = curr.getIndex(); LocalVariableGen[] lt = getLocalTable(m); for (int i = 0; i < lt.length; i++) { // Watch out. The first initialization seems not to be included in // the range given in the local variable table! if (localNr == lt[i].getIndex()) { // System.err.println("Looking for local " + localNr // + " on position " + pos); // System.err.println("found one with range " // + lt[i].getStart().getPrev().getPosition() + ", " // + lt[i].getEnd().getPosition()); if (pos >= lt[i].getStart().getPrev().getPosition() && pos < (lt[i].getEnd().getPosition())) { return lt[i]; } } } return null; }
InstructionHandle rewriteStore(MethodGen m, InstructionList il, InstructionHandle i, int maxLocals, String localClassName) { LocalVariableInstruction curr = (LocalVariableInstruction) (i .getInstruction()); Type type = mtab.getLocalType(m, curr, i.getPosition()); if (type == null) { return i; } String name = mtab.getLocalName(m, curr, i.getPosition()); String fieldName = MethodTable.generatedLocalName(type, name); i.setInstruction(new ALOAD(maxLocals)); i = i.getNext(); if (type.equals(Type.LONG) || type.equals(Type.DOUBLE)) { il.insert(i, new DUP_X2()); il.insert(i, new POP()); } else { il.insert(i, new SWAP()); } i = il.insert(i, ins_f.createFieldAccess(localClassName, fieldName, type, Constants.PUTFIELD)); return i; }
InstructionHandle rewriteLoad(MethodGen m, InstructionList il, InstructionHandle i, int maxLocals, String localClassName) { LocalVariableInstruction curr = (LocalVariableInstruction) (i .getInstruction()); Type type = mtab.getLocalType(m, curr, i.getPosition()); if (type == null) { return i; } String name = mtab.getLocalName(m, curr, i.getPosition()); String fieldName = MethodTable.generatedLocalName(type, name); i.setInstruction(new ALOAD(maxLocals)); i = i.getNext(); i = il.insert(i, ins_f.createFieldAccess(localClassName, fieldName, type, Constants.GETFIELD)); return i; }
String getLocalName(MethodGen m, LocalVariableInstruction curr, int pos) { LocalVariableGen a = getLocal(m, curr, pos); if (a == null) { return null; } return a.getName(); }
Type getLocalType(MethodGen m, LocalVariableInstruction curr, int pos) { LocalVariableGen a = getLocal(m, curr, pos); if (a == null) { return null; } return a.getType(); }
void removeUnusedLocals(Method mOrig, MethodGen m) { InstructionList il = m.getInstructionList(); InstructionHandle[] ins = il.getInstructionHandles(); for (int i = 0; i < ins.length; i++) { Instruction in = ins[i].getInstruction(); if (in instanceof LocalVariableInstruction) { LocalVariableInstruction curr = (LocalVariableInstruction) in; if (mtab.getLocal(m, curr, ins[i].getPosition()) != null && curr.getIndex() < m.getMaxLocals() - 5 && !mtab.isLocalUsedInInlet(mOrig, curr.getIndex())) { if (curr instanceof IINC) { ins[i].setInstruction(new NOP()); } else if (curr instanceof LSTORE || curr instanceof DSTORE) { ins[i].setInstruction(new POP2()); } else if (curr instanceof StoreInstruction) { ins[i].setInstruction(new POP()); } else if (curr instanceof ALOAD) { ins[i].setInstruction(new ACONST_NULL()); } else if (curr instanceof FLOAD) { ins[i].setInstruction(new FCONST((float) 0.0)); } else if (curr instanceof ILOAD) { ins[i].setInstruction(new ICONST(0)); } else if (curr instanceof DLOAD) { ins[i].setInstruction(new DCONST(0.0)); } else if (curr instanceof LLOAD) { ins[i].setInstruction(new LCONST(0L)); } else { System.out.println("unhandled ins in " + "removeUnusedLocals: " + curr); System.exit(1); } } } } }
void shiftLocals(InstructionList il, int shift) { InstructionHandle[] ih = il.getInstructionHandles(); for (int i = 0; i < ih.length; i++) { Instruction ins = ih[i].getInstruction(); if (ins instanceof LocalVariableInstruction) { LocalVariableInstruction l = (LocalVariableInstruction) ins; l.setIndex(l.getIndex() + shift); } } }
private void emitLocalVariableInstruction(Element xml_inst, LocalVariableInstruction inst) { Type type = inst.getType(cpg); xml_inst.setAttribute("type", type.toString()); xml_inst.setAttribute("index", java.lang.String.valueOf(inst.getIndex())); String op = inst.toString(); int i; for (i = 0; i < op.length(); i++) { char ch = op.toUpperCase().charAt(i); if (ch < 'A' || ch > 'Z') break; } op = op.substring(0, i); xml_inst.setName(op); }
private void registerInstructionSources() throws DataflowAnalysisException { for (Iterator<Location> i = cfg.locationIterator(); i.hasNext();) { Location location = i.next(); Instruction instruction = location.getHandle().getInstruction(); short opcode = instruction.getOpcode(); int produces = instruction.produceStack(cpg); if (instruction instanceof InvokeInstruction) { // Model return value registerReturnValueSource(location); } else if (opcode == Constants.GETFIELD || opcode == Constants.GETSTATIC) { // Model field loads registerFieldLoadSource(location); } else if (instruction instanceof LDC) { // Model constant values registerLDCValueSource(location); } else if (instruction instanceof LDC2_W) { // Model constant values registerLDC2ValueSource(location); } else if (instruction instanceof ConstantPushInstruction) { // Model constant values registerConstantPushSource(location); } else if (instruction instanceof ACONST_NULL) { // Model constant values registerPushNullSource(location); } else if ((produces == 1 || produces == 2) && !(instruction instanceof LocalVariableInstruction) && !(instruction instanceof CHECKCAST)){ // Model other sources registerOtherSource(location); } } }
public int[] getAccessedLocalsIndices(){ //TODO: Implement caching. Set acc = new HashSet(); if (theRET == null && this != TOPLEVEL){ throw new AssertionViolatedException("This subroutine object must be built up completely before calculating accessed locals."); } Iterator i = instructions.iterator(); while (i.hasNext()){ InstructionHandle ih = (InstructionHandle) i.next(); // RET is not a LocalVariableInstruction in the current version of BCEL. if (ih.getInstruction() instanceof LocalVariableInstruction || ih.getInstruction() instanceof RET){ int idx = ((IndexedInstruction) (ih.getInstruction())).getIndex(); acc.add(new Integer(idx)); // LONG? DOUBLE?. try{ // LocalVariableInstruction instances are typed without the need to look into // the constant pool. if (ih.getInstruction() instanceof LocalVariableInstruction){ int s = ((LocalVariableInstruction) ih.getInstruction()).getType(null).getSize(); if (s==2) { acc.add(new Integer(idx+1)); } } } catch(RuntimeException re){ throw new AssertionViolatedException("Oops. BCEL did not like NULL as a ConstantPoolGen object."); } } } int[] ret = new int[acc.size()]; i = acc.iterator(); int j=-1; while (i.hasNext()){ j++; ret[j] = ((Integer) i.next()).intValue(); } return ret; }
public void visitLocalVariableInstruction( LocalVariableInstruction i ) { short opcode = i.getOpcode(); Type type = i.getType(_cp); if (opcode == Constants.IINC) { _out.println("il.append(new IINC(" + i.getIndex() + ", " + ((IINC) i).getIncrement() + "));"); } else { String kind = (opcode < Constants.ISTORE) ? "Load" : "Store"; _out.println("il.append(_factory.create" + kind + "(" + BCELifier.printType(type) + ", " + i.getIndex() + "));"); } }
public int[] getAccessedLocalsIndices(){ //TODO: Implement caching. final Set<Integer> acc = new HashSet<Integer>(); if (theRET == null && this != TOPLEVEL){ throw new AssertionViolatedException("This subroutine object must be built up completely before calculating accessed locals."); } for (final InstructionHandle ih : instructions) { // RET is not a LocalVariableInstruction in the current version of BCEL. if (ih.getInstruction() instanceof LocalVariableInstruction || ih.getInstruction() instanceof RET){ int idx = IndexedInstruction.class.cast(ih.getInstruction()).getIndex(); acc.add(idx); // LONG? DOUBLE?. try { // LocalVariableInstruction instances are typed without the need to look into // the constant pool. if (ih.getInstruction() instanceof LocalVariableInstruction) { int s = LocalVariableInstruction.class.cast(ih.getInstruction()).getType(null).getSize(); if (s == 2) acc.add(idx + 1); } } catch(final RuntimeException re) { throw new AssertionViolatedException("Oops. BCEL did not like NULL as a ConstantPoolGen object."); } } } int[] ret = new int[acc.size()]; int j = 0; for (final int v : acc) { ret[j++] = v; } return ret; }