Browse Source

Upgraded to ASM 5.0.1

Issue: SPR-11239
pull/497/head
Juergen Hoeller 11 years ago
parent
commit
9280ca7749
  1. 20
      spring-core/src/main/java/org/springframework/asm/ClassWriter.java
  2. 79
      spring-core/src/main/java/org/springframework/asm/MethodWriter.java

20
spring-core/src/main/java/org/springframework/asm/ClassWriter.java

@ -756,11 +756,29 @@ public class ClassWriter extends ClassVisitor { @@ -756,11 +756,29 @@ public class ClassWriter extends ClassVisitor {
if (innerClasses == null) {
innerClasses = new ByteVector();
}
// §4.7.6 of the JVMS states "Every CONSTANT_Class_info entry in the
// constant_pool table which represents a class or interface C that is
// not a package member must have exactly one corresponding entry in the
// classes array". To avoid duplicates we keep track in the intVal field
// of the Item of each CONSTANT_Class_info entry C whether an inner
// class entry has already been added for C (this field is unused for
// class entries, and changing its value does not change the hashcode
// and equality tests). If so we store the index of this inner class
// entry (plus one) in intVal. This hack allows duplicate detection in
// O(1) time.
Item nameItem = newClassItem(name);
if (nameItem.intVal == 0) {
++innerClassesCount;
innerClasses.putShort(name == null ? 0 : newClass(name));
innerClasses.putShort(nameItem.index);
innerClasses.putShort(outerName == null ? 0 : newClass(outerName));
innerClasses.putShort(innerName == null ? 0 : newUTF8(innerName));
innerClasses.putShort(access);
nameItem.intVal = innerClassesCount;
} else {
// Compare the inner classes entry nameItem.intVal - 1 with the
// arguments of this method and throw an exception if there is a
// difference?
}
}
@Override

79
spring-core/src/main/java/org/springframework/asm/MethodWriter.java

@ -1401,6 +1401,14 @@ class MethodWriter extends MethodVisitor { @@ -1401,6 +1401,14 @@ class MethodWriter extends MethodVisitor {
@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;
@ -2022,14 +2030,6 @@ class MethodWriter extends MethodVisitor { @@ -2022,14 +2030,6 @@ class MethodWriter extends MethodVisitor {
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) {
@ -2686,50 +2686,51 @@ class MethodWriter extends MethodVisitor { @@ -2686,50 +2686,51 @@ class MethodWriter extends MethodVisitor {
}
}
// recomputes the stack map frames
if (frameCount > 0) {
// updates the stack map frame labels
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.
* 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 ((l.status & Label.STORE) != 0 || (u >= 0 && resize[u])) {
getNewOffset(allIndexes, allSizes, l);
// TODO update offsets in UNINITIALIZED values
visitFrame(l.frame);
if (u >= 0 && resize[u]) {
l.status |= Label.TARGET;
}
getNewOffset(allIndexes, allSizes, l);
l = l.successor;
}
} else {
// 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.
* 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) {

Loading…
Cancel
Save