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);