aboutsummaryrefslogtreecommitdiffstats
path: root/weaver
diff options
context:
space:
mode:
authorAndy Clement <andrew.clement@gmail.com>2012-04-18 14:07:59 -0700
committerAndy Clement <andrew.clement@gmail.com>2012-04-18 14:07:59 -0700
commit80ce56ea366dd81da7354855ef2a2e2ca65a4f93 (patch)
tree3a2d2779a2c92d582639dc9ffa476e6810a1807d /weaver
parent89c178fba21e32dd3a7d1ab23c8f8fc3e822c881 (diff)
downloadaspectj-80ce56ea366dd81da7354855ef2a2e2ca65a4f93.tar.gz
aspectj-80ce56ea366dd81da7354855ef2a2e2ca65a4f93.zip
Fix up J7 stackmap creation
Diffstat (limited to 'weaver')
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/asm/StackMapAdder.java36
1 files changed, 33 insertions, 3 deletions
diff --git a/weaver/src/org/aspectj/weaver/bcel/asm/StackMapAdder.java b/weaver/src/org/aspectj/weaver/bcel/asm/StackMapAdder.java
index 07477d1a9..2455a7382 100644
--- a/weaver/src/org/aspectj/weaver/bcel/asm/StackMapAdder.java
+++ b/weaver/src/org/aspectj/weaver/bcel/asm/StackMapAdder.java
@@ -15,14 +15,20 @@ import org.aspectj.weaver.ResolvedType;
import org.aspectj.weaver.UnresolvedType;
import org.aspectj.weaver.World;
-import aj.org.objectweb.asm.ClassReader;
-import aj.org.objectweb.asm.ClassWriter;
+import aj.org.objectweb.asm.*;
/**
* Uses asm to add the stack map attribute to methods in a class. The class is passed in as pure byte data and then a reader/writer
* process it. The writer is wired into the world so that types can be resolved and getCommonSuperClass() can be implemented without
* class loading using the context class loader.
*
+ * It is important that the constant pool is preserved here and asm does not try to remove unused entries. That is because some
+ * entries are refered to from classfile attributes. Asm cannot see into these attributes so does not realise the constant pool
+ * entries are in use. In order to ensure the copying of cp occurs, we use the variant super constructor call in AspectJConnectClassWriter
+ * that passes in the classreader. However, ordinarily that change causes a further optimization: that if a classreader sees
+ * a methodvisitor that has been created by a ClassWriter then it just copies the data across without changing it (and so it
+ * fails to attach the stackmapattribute). In order to avoid this further optimization we use our own minimal MethodVisitor.
+ *
* @author Andy Clement
*/
public class StackMapAdder {
@@ -31,7 +37,8 @@ public class StackMapAdder {
try {
ClassReader cr = new ClassReader(data);
ClassWriter cw = new AspectJConnectClassWriter(cr, world);
- cr.accept(cw, 0);
+ ClassVisitor cv = new AspectJClassVisitor(cw);
+ cr.accept(cv, 0);
return cw.toByteArray();
} catch (Throwable t) {
System.err.println("AspectJ Internal Error: unable to add stackmap attributes. " + t.getMessage());
@@ -39,6 +46,28 @@ public class StackMapAdder {
return data;
}
}
+
+ private static class AspectJClassVisitor extends ClassVisitor {
+
+ public AspectJClassVisitor(ClassVisitor classwriter) {
+ super(Opcodes.ASM4, classwriter);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+ MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
+ return new AJMethodVisitor(mv);
+ }
+
+ // Minimal pass through MethodVisitor just so that the ClassReader doesn't see one that has been directly
+ // created by a ClassWriter (see top level class comment)
+ static class AJMethodVisitor extends MethodVisitor {
+ public AJMethodVisitor(MethodVisitor mv) {
+ super(Opcodes.ASM4,mv);
+ }
+ }
+
+ }
private static class AspectJConnectClassWriter extends ClassWriter {
private final World world;
@@ -47,6 +76,7 @@ public class StackMapAdder {
super(cr, ClassWriter.COMPUTE_FRAMES); // passing in cr is necessary so cpool isnt modified (see 2.2.4 of asm doc)
this.world = w;
}
+
// Implementation of getCommonSuperClass() that avoids Class.forName()
protected String getCommonSuperClass(final String type1, final String type2) {