< prev index next >

src/java.base/share/classes/jdk/internal/org/objectweb/asm/commons/LocalVariablesSorter.java

Print this page




  88      * index i of size 2 is remapped to 'mapping[2*i+1]'.
  89      */
  90     private int[] mapping = new int[40];
  91 
  92     /**
  93      * Array used to store stack map local variable types after remapping.
  94      */
  95     private Object[] newLocals = new Object[20];
  96 
  97     /**
  98      * Index of the first local variable, after formal parameters.
  99      */
 100     protected final int firstLocal;
 101 
 102     /**
 103      * Index of the next local variable to be created by {@link #newLocal}.
 104      */
 105     protected int nextLocal;
 106 
 107     /**
 108      * Indicates if at least one local variable has moved due to remapping.
 109      */
 110     private boolean changed;
 111 
 112     /**
 113      * Creates a new {@link LocalVariablesSorter}. <i>Subclasses must not use
 114      * this constructor</i>. Instead, they must use the
 115      * {@link #LocalVariablesSorter(int, int, String, MethodVisitor)} version.
 116      *
 117      * @param access
 118      *            access flags of the adapted method.
 119      * @param desc
 120      *            the method's descriptor (see {@link Type Type}).
 121      * @param mv
 122      *            the method visitor to which this adapter delegates calls.
 123      * @throws IllegalStateException
 124      *             If a subclass calls this constructor.
 125      */
 126     public LocalVariablesSorter(final int access, final String desc,
 127             final MethodVisitor mv) {
 128         this(Opcodes.ASM5, access, desc, mv);
 129         if (getClass() != LocalVariablesSorter.class) {
 130             throw new IllegalStateException();
 131         }
 132     }


 211     public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
 212             TypePath typePath, Label[] start, Label[] end, int[] index,
 213             String desc, boolean visible) {
 214         Type t = Type.getType(desc);
 215         int[] newIndex = new int[index.length];
 216         for (int i = 0; i < newIndex.length; ++i) {
 217             newIndex[i] = remap(index[i], t);
 218         }
 219         return mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
 220                 newIndex, desc, visible);
 221     }
 222 
 223     @Override
 224     public void visitFrame(final int type, final int nLocal,
 225             final Object[] local, final int nStack, final Object[] stack) {
 226         if (type != Opcodes.F_NEW) { // uncompressed frame
 227             throw new IllegalStateException(
 228                     "ClassReader.accept() should be called with EXPAND_FRAMES flag");
 229         }
 230 
 231         if (!changed) { // optimization for the case where mapping = identity
 232             mv.visitFrame(type, nLocal, local, nStack, stack);
 233             return;
 234         }
 235 
 236         // creates a copy of newLocals
 237         Object[] oldLocals = new Object[newLocals.length];
 238         System.arraycopy(newLocals, 0, oldLocals, 0, oldLocals.length);
 239 
 240         updateNewLocals(newLocals);
 241 
 242         // copies types from 'local' to 'newLocals'
 243         // 'newLocals' already contains the variables added with 'newLocal'
 244 
 245         int index = 0; // old local variable index
 246         int number = 0; // old local variable number
 247         for (; number < nLocal; ++number) {
 248             Object t = local[number];
 249             int size = t == Opcodes.LONG || t == Opcodes.DOUBLE ? 2 : 1;
 250             if (t != Opcodes.TOP) {
 251                 Type typ = OBJECT_TYPE;
 252                 if (t == Opcodes.INTEGER) {
 253                     typ = Type.INT_TYPE;
 254                 } else if (t == Opcodes.FLOAT) {
 255                     typ = Type.FLOAT_TYPE;


 311         case Type.FLOAT:
 312             t = Opcodes.FLOAT;
 313             break;
 314         case Type.LONG:
 315             t = Opcodes.LONG;
 316             break;
 317         case Type.DOUBLE:
 318             t = Opcodes.DOUBLE;
 319             break;
 320         case Type.ARRAY:
 321             t = type.getDescriptor();
 322             break;
 323         // case Type.OBJECT:
 324         default:
 325             t = type.getInternalName();
 326             break;
 327         }
 328         int local = newLocalMapping(type);
 329         setLocalType(local, type);
 330         setFrameLocal(local, t);
 331         changed = true;
 332         return local;
 333     }
 334 
 335     /**
 336      * Notifies subclasses that a new stack map frame is being visited. The
 337      * array argument contains the stack map frame types corresponding to the
 338      * local variables added with {@link #newLocal}. This method can update
 339      * these types in place for the stack map frame being visited. The default
 340      * implementation of this method does nothing, i.e. a local variable added
 341      * with {@link #newLocal} will have the same type in all stack map frames.
 342      * But this behavior is not always the desired one, for instance if a local
 343      * variable is added in the middle of a try/catch block: the frame for the
 344      * exception handler should have a TOP type for this new local.
 345      *
 346      * @param newLocals
 347      *            the stack map frame types corresponding to the local variables
 348      *            added with {@link #newLocal} (and null for the others). The
 349      *            format of this array is the same as in
 350      *            {@link MethodVisitor#visitFrame}, except that long and double
 351      *            types use two slots. The types for the current stack map frame


 379 
 380     private int remap(final int var, final Type type) {
 381         if (var + type.getSize() <= firstLocal) {
 382             return var;
 383         }
 384         int key = 2 * var + type.getSize() - 1;
 385         int size = mapping.length;
 386         if (key >= size) {
 387             int[] newMapping = new int[Math.max(2 * size, key + 1)];
 388             System.arraycopy(mapping, 0, newMapping, 0, size);
 389             mapping = newMapping;
 390         }
 391         int value = mapping[key];
 392         if (value == 0) {
 393             value = newLocalMapping(type);
 394             setLocalType(value, type);
 395             mapping[key] = value + 1;
 396         } else {
 397             value--;
 398         }
 399         if (value != var) {
 400             changed = true;
 401         }
 402         return value;
 403     }
 404 
 405     protected int newLocalMapping(final Type type) {
 406         int local = nextLocal;
 407         nextLocal += type.getSize();
 408         return local;
 409     }
 410 }


  88      * index i of size 2 is remapped to 'mapping[2*i+1]'.
  89      */
  90     private int[] mapping = new int[40];
  91 
  92     /**
  93      * Array used to store stack map local variable types after remapping.
  94      */
  95     private Object[] newLocals = new Object[20];
  96 
  97     /**
  98      * Index of the first local variable, after formal parameters.
  99      */
 100     protected final int firstLocal;
 101 
 102     /**
 103      * Index of the next local variable to be created by {@link #newLocal}.
 104      */
 105     protected int nextLocal;
 106 
 107     /**





 108      * Creates a new {@link LocalVariablesSorter}. <i>Subclasses must not use
 109      * this constructor</i>. Instead, they must use the
 110      * {@link #LocalVariablesSorter(int, int, String, MethodVisitor)} version.
 111      *
 112      * @param access
 113      *            access flags of the adapted method.
 114      * @param desc
 115      *            the method's descriptor (see {@link Type Type}).
 116      * @param mv
 117      *            the method visitor to which this adapter delegates calls.
 118      * @throws IllegalStateException
 119      *             If a subclass calls this constructor.
 120      */
 121     public LocalVariablesSorter(final int access, final String desc,
 122             final MethodVisitor mv) {
 123         this(Opcodes.ASM5, access, desc, mv);
 124         if (getClass() != LocalVariablesSorter.class) {
 125             throw new IllegalStateException();
 126         }
 127     }


 206     public AnnotationVisitor visitLocalVariableAnnotation(int typeRef,
 207             TypePath typePath, Label[] start, Label[] end, int[] index,
 208             String desc, boolean visible) {
 209         Type t = Type.getType(desc);
 210         int[] newIndex = new int[index.length];
 211         for (int i = 0; i < newIndex.length; ++i) {
 212             newIndex[i] = remap(index[i], t);
 213         }
 214         return mv.visitLocalVariableAnnotation(typeRef, typePath, start, end,
 215                 newIndex, desc, visible);
 216     }
 217 
 218     @Override
 219     public void visitFrame(final int type, final int nLocal,
 220             final Object[] local, final int nStack, final Object[] stack) {
 221         if (type != Opcodes.F_NEW) { // uncompressed frame
 222             throw new IllegalStateException(
 223                     "ClassReader.accept() should be called with EXPAND_FRAMES flag");
 224         }
 225 





 226         // creates a copy of newLocals
 227         Object[] oldLocals = new Object[newLocals.length];
 228         System.arraycopy(newLocals, 0, oldLocals, 0, oldLocals.length);
 229 
 230         updateNewLocals(newLocals);
 231 
 232         // copies types from 'local' to 'newLocals'
 233         // 'newLocals' already contains the variables added with 'newLocal'
 234 
 235         int index = 0; // old local variable index
 236         int number = 0; // old local variable number
 237         for (; number < nLocal; ++number) {
 238             Object t = local[number];
 239             int size = t == Opcodes.LONG || t == Opcodes.DOUBLE ? 2 : 1;
 240             if (t != Opcodes.TOP) {
 241                 Type typ = OBJECT_TYPE;
 242                 if (t == Opcodes.INTEGER) {
 243                     typ = Type.INT_TYPE;
 244                 } else if (t == Opcodes.FLOAT) {
 245                     typ = Type.FLOAT_TYPE;


 301         case Type.FLOAT:
 302             t = Opcodes.FLOAT;
 303             break;
 304         case Type.LONG:
 305             t = Opcodes.LONG;
 306             break;
 307         case Type.DOUBLE:
 308             t = Opcodes.DOUBLE;
 309             break;
 310         case Type.ARRAY:
 311             t = type.getDescriptor();
 312             break;
 313         // case Type.OBJECT:
 314         default:
 315             t = type.getInternalName();
 316             break;
 317         }
 318         int local = newLocalMapping(type);
 319         setLocalType(local, type);
 320         setFrameLocal(local, t);

 321         return local;
 322     }
 323 
 324     /**
 325      * Notifies subclasses that a new stack map frame is being visited. The
 326      * array argument contains the stack map frame types corresponding to the
 327      * local variables added with {@link #newLocal}. This method can update
 328      * these types in place for the stack map frame being visited. The default
 329      * implementation of this method does nothing, i.e. a local variable added
 330      * with {@link #newLocal} will have the same type in all stack map frames.
 331      * But this behavior is not always the desired one, for instance if a local
 332      * variable is added in the middle of a try/catch block: the frame for the
 333      * exception handler should have a TOP type for this new local.
 334      *
 335      * @param newLocals
 336      *            the stack map frame types corresponding to the local variables
 337      *            added with {@link #newLocal} (and null for the others). The
 338      *            format of this array is the same as in
 339      *            {@link MethodVisitor#visitFrame}, except that long and double
 340      *            types use two slots. The types for the current stack map frame


 368 
 369     private int remap(final int var, final Type type) {
 370         if (var + type.getSize() <= firstLocal) {
 371             return var;
 372         }
 373         int key = 2 * var + type.getSize() - 1;
 374         int size = mapping.length;
 375         if (key >= size) {
 376             int[] newMapping = new int[Math.max(2 * size, key + 1)];
 377             System.arraycopy(mapping, 0, newMapping, 0, size);
 378             mapping = newMapping;
 379         }
 380         int value = mapping[key];
 381         if (value == 0) {
 382             value = newLocalMapping(type);
 383             setLocalType(value, type);
 384             mapping[key] = value + 1;
 385         } else {
 386             value--;
 387         }



 388         return value;
 389     }
 390 
 391     protected int newLocalMapping(final Type type) {
 392         int local = nextLocal;
 393         nextLocal += type.getSize();
 394         return local;
 395     }
 396 }
< prev index next >