@@ -58,8 +58,8 @@ public class ClassWriter extends ClassVisitor {
58
58
* {@link MethodVisitor#visitFrame} method are ignored, and the stack map
59
59
* frames are recomputed from the methods bytecode. The arguments of the
60
60
* {@link MethodVisitor#visitMaxs visitMaxs} method are also ignored and
61
- * recomputed from the bytecode. In other words, computeFrames implies
62
- * computeMaxs .
61
+ * recomputed from the bytecode. In other words, COMPUTE_FRAMES implies
62
+ * COMPUTE_MAXS .
63
63
*
64
64
* @see #ClassWriter(int)
65
65
*/
@@ -167,6 +167,22 @@ public class ClassWriter extends ClassVisitor {
167
167
*/
168
168
static final int WIDE_INSN = 17 ;
169
169
170
+ /**
171
+ * The type of the ASM pseudo instructions with an unsigned 2 bytes offset
172
+ * label (see Label#resolve).
173
+ */
174
+ static final int ASM_LABEL_INSN = 18 ;
175
+
176
+ /**
177
+ * Represents a frame inserted between already existing frames. This kind of
178
+ * frame can only be used if the frame content can be computed from the
179
+ * previous existing frame and from the instructions between this existing
180
+ * frame and the inserted one, without any knowledge of the type hierarchy.
181
+ * This kind of frame is only used when an unconditional jump is inserted in
182
+ * a method while expanding an ASM pseudo instruction (see ClassReader).
183
+ */
184
+ static final int F_INSERT = 256 ;
185
+
170
186
/**
171
187
* The instruction types of all JVM opcodes.
172
188
*/
@@ -484,25 +500,19 @@ public class ClassWriter extends ClassVisitor {
484
500
MethodWriter lastMethod ;
485
501
486
502
/**
487
- * <tt>true</tt> if the maximum stack size and number of local variables
488
- * must be automatically computed.
489
- */
490
- private boolean computeMaxs ;
491
-
492
- /**
493
- * <tt>true</tt> if the stack map frames must be recomputed from scratch.
503
+ * Indicates what must be automatically computed.
504
+ *
505
+ * @see MethodWriter#compute
494
506
*/
495
- private boolean computeFrames ;
507
+ private int compute ;
496
508
497
509
/**
498
- * <tt>true</tt> if the stack map tables of this class are invalid. The
499
- * {@link MethodWriter#resizeInstructions} method cannot transform existing
500
- * stack map tables, and so produces potentially invalid classes when it is
501
- * executed. In this case the class is reread and rewritten with the
502
- * {@link #COMPUTE_FRAMES} option (the resizeInstructions method can resize
503
- * stack map tables when this option is used).
510
+ * <tt>true</tt> if some methods have wide forward jumps using ASM pseudo
511
+ * instructions, which need to be expanded into sequences of standard
512
+ * bytecode instructions. In this case the class is re-read and re-written
513
+ * with a ClassReader -> ClassWriter chain to perform this transformation.
504
514
*/
505
- boolean invalidFrames ;
515
+ boolean hasAsmInsns ;
506
516
507
517
// ------------------------------------------------------------------------
508
518
// Static initializer
@@ -517,7 +527,7 @@ public class ClassWriter extends ClassVisitor {
517
527
String s = "AAAAAAAAAAAAAAAABCLMMDDDDDEEEEEEEEEEEEEEEEEEEEAAAAAAAADD"
518
528
+ "DDDEEEEEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
519
529
+ "AAAAAAAAAAAAAAAAANAAAAAAAAAAAAAAAAAAAAJJJJJJJJJJJJJJJJDOPAA"
520
- + "AAAAGGGGGGGHIFBFAAFFAARQJJKKJJJJJJJJJJJJJJJJJJ " ;
530
+ + "AAAAGGGGGGGHIFBFAAFFAARQJJKKSSSSSSSSSSSSSSSSSS " ;
521
531
for (i = 0 ; i < b .length ; ++i ) {
522
532
b [i ] = (byte ) (s .charAt (i ) - 'A' );
523
533
}
@@ -571,7 +581,7 @@ public class ClassWriter extends ClassVisitor {
571
581
// // temporary opcodes used internally by ASM - see Label and
572
582
// MethodWriter
573
583
// for (i = 202; i < 220; ++i) {
574
- // b[i] = LABEL_INSN ;
584
+ // b[i] = ASM_LABEL_INSN ;
575
585
// }
576
586
//
577
587
// // LDC(_W) instructions
@@ -614,8 +624,9 @@ public ClassWriter(final int flags) {
614
624
key2 = new Item ();
615
625
key3 = new Item ();
616
626
key4 = new Item ();
617
- this .computeMaxs = (flags & COMPUTE_MAXS ) != 0 ;
618
- this .computeFrames = (flags & COMPUTE_FRAMES ) != 0 ;
627
+ this .compute = (flags & COMPUTE_FRAMES ) != 0 ? MethodWriter .FRAMES
628
+ : ((flags & COMPUTE_MAXS ) != 0 ? MethodWriter .MAXS
629
+ : MethodWriter .NOTHING );
619
630
}
620
631
621
632
/**
@@ -645,9 +656,9 @@ public ClassWriter(final int flags) {
645
656
* @param flags
646
657
* option flags that can be used to modify the default behavior
647
658
* of this class. <i>These option flags do not affect methods
648
- * that are copied as is in the new class. This means that the
649
- * maximum stack size nor the stack frames will be computed for
650
- * these methods</i>. See {@link #COMPUTE_MAXS},
659
+ * that are copied as is in the new class. This means that
660
+ * neither the maximum stack size nor the stack frames will be
661
+ * computed for these methods</i>. See {@link #COMPUTE_MAXS},
651
662
* {@link #COMPUTE_FRAMES}.
652
663
*/
653
664
public ClassWriter (final ClassReader classReader , final int flags ) {
@@ -791,7 +802,7 @@ public final FieldVisitor visitField(final int access, final String name,
791
802
public final MethodVisitor visitMethod (final int access , final String name ,
792
803
final String desc , final String signature , final String [] exceptions ) {
793
804
return new MethodWriter (this , access , name , desc , signature ,
794
- exceptions , computeMaxs , computeFrames );
805
+ exceptions , compute );
795
806
}
796
807
797
808
@ Override
@@ -977,22 +988,20 @@ public byte[] toByteArray() {
977
988
if (attrs != null ) {
978
989
attrs .put (this , null , 0 , -1 , -1 , out );
979
990
}
980
- if (invalidFrames ) {
991
+ if (hasAsmInsns ) {
981
992
anns = null ;
982
993
ianns = null ;
983
994
attrs = null ;
984
995
innerClassesCount = 0 ;
985
996
innerClasses = null ;
986
- bootstrapMethodsCount = 0 ;
987
- bootstrapMethods = null ;
988
997
firstField = null ;
989
998
lastField = null ;
990
999
firstMethod = null ;
991
1000
lastMethod = null ;
992
- computeMaxs = false ;
993
- computeFrames = true ;
994
- invalidFrames = false ;
995
- new ClassReader ( out . data ). accept ( this , ClassReader .SKIP_FRAMES );
1001
+ compute = MethodWriter . INSERTED_FRAMES ;
1002
+ hasAsmInsns = false ;
1003
+ new ClassReader ( out . data ). accept ( this , ClassReader . EXPAND_FRAMES
1004
+ | ClassReader .EXPAND_ASM_INSNS );
996
1005
return toByteArray ();
997
1006
}
998
1007
return out .data ;
0 commit comments