src/share/classes/jdk/internal/org/objectweb/asm/MethodWriter.java
Print this page
*** 1428,1437 ****
--- 1428,1445 ----
lineNumber.putShort(line);
}
@Override
public void visitMaxs(final int maxStack, final int maxLocals) {
+ if (resize) {
+ // replaces the temporary jump opcodes introduced by Label.resolve.
+ if (ClassReader.RESIZE) {
+ resizeInstructions();
+ } else {
+ throw new RuntimeException("Method code too large!");
+ }
+ }
if (ClassReader.FRAMES && compute == FRAMES) {
// completes the control flow graph with exception handler blocks
Handler handler = firstHandler;
while (handler != null) {
Label l = handler.start.getFirst();
*** 1985,2031 ****
break;
default:
stackMap.putByte(v);
}
} else {
! StringBuffer buf = new StringBuffer();
d >>= 28;
while (d-- > 0) {
! buf.append('[');
}
if ((t & Frame.BASE_KIND) == Frame.OBJECT) {
! buf.append('L');
! buf.append(cw.typeTable[t & Frame.BASE_VALUE].strVal1);
! buf.append(';');
} else {
switch (t & 0xF) {
case 1:
! buf.append('I');
break;
case 2:
! buf.append('F');
break;
case 3:
! buf.append('D');
break;
case 9:
! buf.append('Z');
break;
case 10:
! buf.append('B');
break;
case 11:
! buf.append('C');
break;
case 12:
! buf.append('S');
break;
default:
! buf.append('J');
}
}
! stackMap.putByte(7).putShort(cw.newClass(buf.toString()));
}
}
}
private void writeFrameType(final Object type) {
--- 1993,2039 ----
break;
default:
stackMap.putByte(v);
}
} else {
! StringBuilder sb = new StringBuilder();
d >>= 28;
while (d-- > 0) {
! sb.append('[');
}
if ((t & Frame.BASE_KIND) == Frame.OBJECT) {
! sb.append('L');
! sb.append(cw.typeTable[t & Frame.BASE_VALUE].strVal1);
! sb.append(';');
} else {
switch (t & 0xF) {
case 1:
! sb.append('I');
break;
case 2:
! sb.append('F');
break;
case 3:
! sb.append('D');
break;
case 9:
! sb.append('Z');
break;
case 10:
! sb.append('B');
break;
case 11:
! sb.append('C');
break;
case 12:
! sb.append('S');
break;
default:
! sb.append('J');
}
}
! stackMap.putByte(7).putShort(cw.newClass(sb.toString()));
}
}
}
private void writeFrameType(final Object type) {
*** 2049,2066 ****
*/
final int getSize() {
if (classReaderOffset != 0) {
return 6 + classReaderLength;
}
- if (resize) {
- // replaces the temporary jump opcodes introduced by Label.resolve.
- if (ClassReader.RESIZE) {
- resizeInstructions();
- } else {
- throw new RuntimeException("Method code too large!");
- }
- }
int size = 8;
if (code.length > 0) {
if (code.length > 65536) {
throw new RuntimeException("Method code too large!");
}
--- 2057,2066 ----
*** 2713,2766 ****
u += 4;
break;
}
}
! // recomputes the stack map frames
! if (frameCount > 0) {
if (compute == FRAMES) {
- frameCount = 0;
- stackMap = null;
- previousFrame = null;
- frame = null;
- Frame f = new Frame();
- f.owner = labels;
- Type[] args = Type.getArgumentTypes(descriptor);
- f.initInputFrame(cw, access, args, maxLocals);
- visitFrame(f);
Label l = labels;
while (l != null) {
/*
! * here we need the original label position. getNewOffset
! * must therefore never have been called for this label.
*/
u = l.position - 3;
! if ((l.status & Label.STORE) != 0 || (u >= 0 && resize[u])) {
! getNewOffset(allIndexes, allSizes, l);
! // TODO update offsets in UNINITIALIZED values
! visitFrame(l.frame);
}
l = l.successor;
}
! } else {
/*
! * Resizing an existing stack map frame table is really hard.
! * Not only the table must be parsed to update the offets, but
! * new frames may be needed for jump instructions that were
! * inserted by this method. And updating the offsets or
! * inserting frames can change the format of the following
! * frames, in case of packed frames. In practice the whole table
! * must be recomputed. For this the frames are marked as
! * potentially invalid. This will cause the whole class to be
! * reread and rewritten with the COMPUTE_FRAMES option (see the
! * ClassWriter.toByteArray method). This is not very efficient
! * but is much easier and requires much less code than any other
! * method I can think of.
*/
cw.invalidFrames = true;
}
- }
// updates the exception handler block labels
Handler h = firstHandler;
while (h != null) {
getNewOffset(allIndexes, allSizes, h.start);
getNewOffset(allIndexes, allSizes, h.end);
--- 2713,2767 ----
u += 4;
break;
}
}
! // updates the stack map frame labels
if (compute == FRAMES) {
Label l = labels;
while (l != null) {
/*
! * Detects the labels that are just after an IF instruction that
! * has been resized with the IFNOT GOTO_W pattern. These labels
! * are now the target of a jump instruction (the IFNOT
! * instruction). Note that we need the original label position
! * here. getNewOffset must therefore never have been called for
! * this label.
*/
u = l.position - 3;
! if (u >= 0 && resize[u]) {
! l.status |= Label.TARGET;
}
+ getNewOffset(allIndexes, allSizes, l);
l = l.successor;
}
! // Update the offsets in the uninitialized types
! for (i = 0; i < cw.typeTable.length; ++i) {
! Item item = cw.typeTable[i];
! if (item != null && item.type == ClassWriter.TYPE_UNINIT) {
! item.intVal = getNewOffset(allIndexes, allSizes, 0,
! item.intVal);
! }
! }
! // The stack map frames are not serialized yet, so we don't need
! // to update them. They will be serialized in visitMaxs.
! } else if (frameCount > 0) {
/*
! * Resizing an existing stack map frame table is really hard. Not
! * only the table must be parsed to update the offets, but new
! * frames may be needed for jump instructions that were inserted by
! * this method. And updating the offsets or inserting frames can
! * change the format of the following frames, in case of packed
! * frames. In practice the whole table must be recomputed. For this
! * the frames are marked as potentially invalid. This will cause the
! * whole class to be reread and rewritten with the COMPUTE_FRAMES
! * option (see the ClassWriter.toByteArray method). This is not very
! * efficient but is much easier and requires much less code than any
! * other method I can think of.
*/
cw.invalidFrames = true;
}
// updates the exception handler block labels
Handler h = firstHandler;
while (h != null) {
getNewOffset(allIndexes, allSizes, h.start);
getNewOffset(allIndexes, allSizes, h.end);