@@ -43,7 +43,7 @@ class MethodWriter extends MethodVisitor {
43
43
* Pseudo access flag used to denote constructors.
44
44
*/
45
45
static final int ACC_CONSTRUCTOR = 0x80000 ;
46
-
46
+
47
47
/**
48
48
* Frame has exactly the same locals as the previous stack map frame and
49
49
* number of stack items is zero.
@@ -1401,6 +1401,14 @@ public void visitLineNumber(final int line, final Label start) {
1401
1401
1402
1402
@ Override
1403
1403
public void visitMaxs (final int maxStack , final int maxLocals ) {
1404
+ if (resize ) {
1405
+ // replaces the temporary jump opcodes introduced by Label.resolve.
1406
+ if (ClassReader .RESIZE ) {
1407
+ resizeInstructions ();
1408
+ } else {
1409
+ throw new RuntimeException ("Method code too large!" );
1410
+ }
1411
+ }
1404
1412
if (ClassReader .FRAMES && compute == FRAMES ) {
1405
1413
// completes the control flow graph with exception handler blocks
1406
1414
Handler handler = firstHandler ;
@@ -2022,14 +2030,6 @@ final int getSize() {
2022
2030
if (classReaderOffset != 0 ) {
2023
2031
return 6 + classReaderLength ;
2024
2032
}
2025
- if (resize ) {
2026
- // replaces the temporary jump opcodes introduced by Label.resolve.
2027
- if (ClassReader .RESIZE ) {
2028
- resizeInstructions ();
2029
- } else {
2030
- throw new RuntimeException ("Method code too large!" );
2031
- }
2032
- }
2033
2033
int size = 8 ;
2034
2034
if (code .length > 0 ) {
2035
2035
if (code .length > 65536 ) {
@@ -2686,49 +2686,50 @@ private void resizeInstructions() {
2686
2686
}
2687
2687
}
2688
2688
2689
- // recomputes the stack map frames
2690
- if (frameCount > 0 ) {
2691
- if (compute == FRAMES ) {
2692
- frameCount = 0 ;
2693
- stackMap = null ;
2694
- previousFrame = null ;
2695
- frame = null ;
2696
- Frame f = new Frame ();
2697
- f .owner = labels ;
2698
- Type [] args = Type .getArgumentTypes (descriptor );
2699
- f .initInputFrame (cw , access , args , maxLocals );
2700
- visitFrame (f );
2701
- Label l = labels ;
2702
- while (l != null ) {
2703
- /*
2704
- * here we need the original label position. getNewOffset
2705
- * must therefore never have been called for this label.
2706
- */
2707
- u = l .position - 3 ;
2708
- if ((l .status & Label .STORE ) != 0 || (u >= 0 && resize [u ])) {
2709
- getNewOffset (allIndexes , allSizes , l );
2710
- // TODO update offsets in UNINITIALIZED values
2711
- visitFrame (l .frame );
2712
- }
2713
- l = l .successor ;
2714
- }
2715
- } else {
2689
+ // updates the stack map frame labels
2690
+ if (compute == FRAMES ) {
2691
+ Label l = labels ;
2692
+ while (l != null ) {
2716
2693
/*
2717
- * Resizing an existing stack map frame table is really hard.
2718
- * Not only the table must be parsed to update the offets, but
2719
- * new frames may be needed for jump instructions that were
2720
- * inserted by this method. And updating the offsets or
2721
- * inserting frames can change the format of the following
2722
- * frames, in case of packed frames. In practice the whole table
2723
- * must be recomputed. For this the frames are marked as
2724
- * potentially invalid. This will cause the whole class to be
2725
- * reread and rewritten with the COMPUTE_FRAMES option (see the
2726
- * ClassWriter.toByteArray method). This is not very efficient
2727
- * but is much easier and requires much less code than any other
2728
- * method I can think of.
2694
+ * Detects the labels that are just after an IF instruction that
2695
+ * has been resized with the IFNOT GOTO_W pattern. These labels
2696
+ * are now the target of a jump instruction (the IFNOT
2697
+ * instruction). Note that we need the original label position
2698
+ * here. getNewOffset must therefore never have been called for
2699
+ * this label.
2729
2700
*/
2730
- cw .invalidFrames = true ;
2701
+ u = l .position - 3 ;
2702
+ if (u >= 0 && resize [u ]) {
2703
+ l .status |= Label .TARGET ;
2704
+ }
2705
+ getNewOffset (allIndexes , allSizes , l );
2706
+ l = l .successor ;
2731
2707
}
2708
+ // Update the offsets in the uninitialized types
2709
+ for (i = 0 ; i < cw .typeTable .length ; ++i ) {
2710
+ Item item = cw .typeTable [i ];
2711
+ if (item != null && item .type == ClassWriter .TYPE_UNINIT ) {
2712
+ item .intVal = getNewOffset (allIndexes , allSizes , 0 ,
2713
+ item .intVal );
2714
+ }
2715
+ }
2716
+ // The stack map frames are not serialized yet, so we don't need
2717
+ // to update them. They will be serialized in visitMaxs.
2718
+ } else if (frameCount > 0 ) {
2719
+ /*
2720
+ * Resizing an existing stack map frame table is really hard. Not
2721
+ * only the table must be parsed to update the offets, but new
2722
+ * frames may be needed for jump instructions that were inserted by
2723
+ * this method. And updating the offsets or inserting frames can
2724
+ * change the format of the following frames, in case of packed
2725
+ * frames. In practice the whole table must be recomputed. For this
2726
+ * the frames are marked as potentially invalid. This will cause the
2727
+ * whole class to be reread and rewritten with the COMPUTE_FRAMES
2728
+ * option (see the ClassWriter.toByteArray method). This is not very
2729
+ * efficient but is much easier and requires much less code than any
2730
+ * other method I can think of.
2731
+ */
2732
+ cw .invalidFrames = true ;
2732
2733
}
2733
2734
// updates the exception handler block labels
2734
2735
Handler h = firstHandler ;
0 commit comments