1 30 package org.objectweb.asm.commons; 31 32 import java.util.HashMap ; 33 import java.util.Map ; 34 35 import org.objectweb.asm.Label; 36 import org.objectweb.asm.MethodAdapter; 37 import org.objectweb.asm.MethodVisitor; 38 import org.objectweb.asm.Opcodes; 39 import org.objectweb.asm.Type; 40 41 50 public class LocalVariablesSorter extends MethodAdapter { 51 52 private Map locals = new HashMap (); 53 54 protected final int firstLocal; 55 56 private int nextLocal; 57 58 public LocalVariablesSorter( 59 final int access, 60 final String desc, 61 final MethodVisitor mv) 62 { 63 super(mv); 64 Type[] args = Type.getArgumentTypes(desc); 65 nextLocal = ((Opcodes.ACC_STATIC & access) != 0) ? 0 : 1; 66 for (int i = 0; i < args.length; i++) { 67 nextLocal += args[i].getSize(); 68 } 69 firstLocal = nextLocal; 70 } 71 72 public void visitVarInsn(final int opcode, final int var) { 73 int size; 74 switch (opcode) { 75 case Opcodes.LLOAD: 76 case Opcodes.LSTORE: 77 case Opcodes.DLOAD: 78 case Opcodes.DSTORE: 79 size = 2; 80 break; 81 default: 82 size = 1; 83 } 84 mv.visitVarInsn(opcode, remap(var, size)); 85 } 86 87 public void visitIincInsn(final int var, final int increment) { 88 mv.visitIincInsn(remap(var, 1), increment); 89 } 90 91 public void visitMaxs(final int maxStack, final int maxLocals) { 92 mv.visitMaxs(0, 0); 93 } 94 95 public void visitLocalVariable( 96 final String name, 97 final String desc, 98 final String signature, 99 final Label start, 100 final Label end, 101 final int index) 102 { 103 mv.visitLocalVariable(name, desc, signature, start, end, remap(index)); 104 } 105 106 108 protected int newLocal(final int size) { 109 int var = nextLocal; 110 nextLocal += size; 111 return var; 112 } 113 114 private int remap(final int var, final int size) { 115 if (var < firstLocal) { 116 return var; 117 } 118 Integer key = new Integer (size == 2 ? ~var : var); 119 Integer value = (Integer ) locals.get(key); 120 if (value == null) { 121 value = new Integer (newLocal(size)); 122 locals.put(key, value); 123 } 124 return value.intValue(); 125 } 126 127 private int remap(final int var) { 128 if (var < firstLocal) { 129 return var; 130 } 131 Integer key = new Integer (var); 132 Integer value = (Integer ) locals.get(key); 133 if (value == null) { 134 key = new Integer (~var); 135 value = (Integer ) locals.get(key); 136 if (value == null) { 137 throw new IllegalStateException ("Unknown local variable " + var); 138 } 139 } 140 return value.intValue(); 141 } 142 } 143 | Popular Tags |