aries-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dav...@apache.org
Subject svn commit: r1176865 - in /aries/trunk/spi-fly: spi-fly-dynamic-bundle/src/main/java/org/apache/aries/spifly/dynamic/ClientWeavingHook.java spi-fly-weaver/src/main/java/org/apache/aries/spifly/weaver/TCCLSetterVisitor.java
Date Wed, 28 Sep 2011 13:06:57 GMT
Author: davidb
Date: Wed Sep 28 13:06:56 2011
New Revision: 1176865

URL: http://svn.apache.org/viewvc?rev=1176865&view=rev
Log:
Improved weaving code thanks to Tim Ward!


Modified:
    aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/main/java/org/apache/aries/spifly/dynamic/ClientWeavingHook.java
    aries/trunk/spi-fly/spi-fly-weaver/src/main/java/org/apache/aries/spifly/weaver/TCCLSetterVisitor.java

Modified: aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/main/java/org/apache/aries/spifly/dynamic/ClientWeavingHook.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/main/java/org/apache/aries/spifly/dynamic/ClientWeavingHook.java?rev=1176865&r1=1176864&r2=1176865&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/main/java/org/apache/aries/spifly/dynamic/ClientWeavingHook.java
(original)
+++ aries/trunk/spi-fly/spi-fly-dynamic-bundle/src/main/java/org/apache/aries/spifly/dynamic/ClientWeavingHook.java
Wed Sep 28 13:06:56 2011
@@ -57,7 +57,7 @@ public class ClientWeavingHook implement
 	        ClassReader cr = new ClassReader(wovenClass.getBytes());
 	        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
 	        TCCLSetterVisitor tsv = new TCCLSetterVisitor(cw, wovenClass.getClassName(), wd);
-	        cr.accept(tsv, 0);
+	        cr.accept(tsv, ClassReader.SKIP_FRAMES);
 	        wovenClass.setBytes(cw.toByteArray());
 	        if (tsv.additionalImportRequired())
 	            wovenClass.getDynamicImports().add(addedImport);

Modified: aries/trunk/spi-fly/spi-fly-weaver/src/main/java/org/apache/aries/spifly/weaver/TCCLSetterVisitor.java
URL: http://svn.apache.org/viewvc/aries/trunk/spi-fly/spi-fly-weaver/src/main/java/org/apache/aries/spifly/weaver/TCCLSetterVisitor.java?rev=1176865&r1=1176864&r2=1176865&view=diff
==============================================================================
--- aries/trunk/spi-fly/spi-fly-weaver/src/main/java/org/apache/aries/spifly/weaver/TCCLSetterVisitor.java
(original)
+++ aries/trunk/spi-fly/spi-fly-weaver/src/main/java/org/apache/aries/spifly/weaver/TCCLSetterVisitor.java
Wed Sep 28 13:06:56 2011
@@ -28,22 +28,28 @@ import org.apache.aries.spifly.WeavingDa
 import org.objectweb.asm.ClassAdapter;
 import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.Label;
-import org.objectweb.asm.MethodAdapter;
 import org.objectweb.asm.MethodVisitor;
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
+import org.objectweb.asm.commons.GeneratorAdapter;
+import org.objectweb.asm.commons.Method;
 
 /**
  * This class implements an ASM ClassVisitor which puts the appropriate ThreadContextClassloader
  * calls around applicable method invocations. It does the actual bytecode weaving.
  */
 public class TCCLSetterVisitor extends ClassAdapter implements ClassVisitor, Opcodes {
+    private static final Type CLASSLOADER_TYPE = Type.getType(ClassLoader.class);
+
     private static final String GENERATED_METHOD_NAME = "$$FCCL$$";
 
-    private static final String UTIL_CLASS = Util.class.getName().replace('.', '/');
-    private static final String VOID_RETURN_TYPE = "()V";
+    private static final Type UTIL_CLASS = Type.getType(Util.class);
+
+    private static final Type CLASS_TYPE = Type.getType(Class.class);
+    
+    private static final Type String_TYPE = Type.getType(String.class);
 
-    private final String targetClass;
+    private final Type targetClass;
     private final Set<WeavingData> weavingData;
 
     // Set to true when the weaving code has changed the client such that an additional import
@@ -52,7 +58,7 @@ public class TCCLSetterVisitor extends C
 
     public TCCLSetterVisitor(ClassVisitor cv, String className, Set<WeavingData> weavingData)
{
         super(cv);
-        this.targetClass = className.replace('.', '/');
+        this.targetClass = Type.getType("L" + className.replace('.', '/') + ";");
         this.weavingData = weavingData;
     }
 
@@ -62,7 +68,7 @@ public class TCCLSetterVisitor extends C
         System.out.println("@@@ " + access + ": " + name + "#" + desc + "#" + signature +
"~" + Arrays.toString(exceptions));
 
         MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
-        return new TCCLSetterMethodVisitor(mv);
+        return new TCCLSetterMethodVisitor(mv, access, name, desc);
     }
 
     @Override
@@ -81,24 +87,28 @@ public class TCCLSetterVisitor extends C
                  continue;
 
              methodNames.add(methodName);
-             MethodVisitor mv = cv.visitMethod(ACC_PRIVATE + ACC_STATIC, methodName,
-                     "(Ljava/lang/Class;)V", "(Ljava/lang/Class<*>;)V", null);
-             mv.visitCode();
+             Method method = new Method(methodName, Type.VOID_TYPE, new Type[] {CLASS_TYPE});
+             
+             GeneratorAdapter mv = new GeneratorAdapter(cv.visitMethod(ACC_PRIVATE + ACC_STATIC,
methodName,
+                     method.getDescriptor(), null, null), ACC_PRIVATE + ACC_STATIC, methodName,
+                     method.getDescriptor());
+             
+             //Load the strings, method parameter and target
              mv.visitLdcInsn(wd.getClassName());
              mv.visitLdcInsn(wd.getMethodName());
-             mv.visitVarInsn(ALOAD, 0);
-             String typeIdentifier = "L" + targetClass + ";";
-             mv.visitLdcInsn(Type.getType(typeIdentifier));
-             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class",
-                     "getClassLoader", "()Ljava/lang/ClassLoader;");
-             mv.visitMethodInsn(
-                     INVOKESTATIC,
-                     "org/apache/aries/spifly/Util",
-                     "fixContextClassloader",
-                     "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/ClassLoader;)V");
-             mv.visitInsn(RETURN);
-             mv.visitMaxs(4, 1);
-             mv.visitEnd();
+             mv.loadArg(0);
+             mv.visitLdcInsn(targetClass);
+             
+             //Change the class on the stack into a classloader
+             mv.invokeVirtual(CLASS_TYPE, new Method("getClassLoader", 
+                 CLASSLOADER_TYPE, new Type[0]));
+             
+             //Call our util method
+             mv.invokeStatic(UTIL_CLASS, new Method("fixContextClassloader", Type.VOID_TYPE,

+                 new Type[] {String_TYPE, String_TYPE, CLASS_TYPE, CLASSLOADER_TYPE}));
+             
+             mv.returnValue();
+             mv.endMethod();
         }
 
         super.visitEnd();
@@ -118,12 +128,12 @@ public class TCCLSetterVisitor extends C
         return name.toString();
     }
 
-    private class TCCLSetterMethodVisitor extends MethodAdapter implements MethodVisitor
+    private class TCCLSetterMethodVisitor extends GeneratorAdapter implements MethodVisitor
     {
         Type lastLDCType;
 
-        public TCCLSetterMethodVisitor(MethodVisitor mv) {
-            super(mv);
+        public TCCLSetterMethodVisitor(MethodVisitor mv, int access, String name, String
descriptor) {
+            super(mv, access, name, descriptor);
         }
 
         /**
@@ -155,17 +165,18 @@ public class TCCLSetterVisitor extends C
                 System.out.println("+++ Gotcha!");
 
                 additionalImportRequired = true;
-
-                // try/finally setup
-                // Add: try {
-                Label l0 = new Label();
-                Label l1 = new Label();
-                mv.visitTryCatchBlock(l0, l1, l1, null);
-                mv.visitLabel(l0);
+                
+                Label startTry = newLabel();
+                Label endTry = newLabel();
+                
+                //start try block
+                visitTryCatchBlock(startTry, endTry, endTry, null);
+                mark(startTry);
+                
                 // Add: Util.storeContextClassloader();
-                mv.visitMethodInsn(INVOKESTATIC, UTIL_CLASS,
-                        "storeContextClassloader", VOID_RETURN_TYPE);
-
+                invokeStatic(UTIL_CLASS, new Method("storeContextClassloader", Type.VOID_TYPE,
new Type[0]));
+                
+                
                 // Add: MyClass.$$FCCL$$<classname>$<methodname>(<class>);
                 if (ServiceLoader.class.getName().equals(wd.getClassName()) &&
                     "load".equals(wd.getMethodName()) &&
@@ -173,6 +184,7 @@ public class TCCLSetterVisitor extends C
                     // ServiceLoader.load() is a special case because it's a general-purpose
service loader,
                     // therefore, the target class it the class being passed in to the ServiceLoader.load()
                     // call itself.
+                    
                     mv.visitLdcInsn(lastLDCType);
                 } else {
                     // In any other case, we're not dealing with a general-purpose service
loader, but rather
@@ -181,30 +193,27 @@ public class TCCLSetterVisitor extends C
                     Type type = Type.getObjectType(owner);
                     mv.visitLdcInsn(type);
                 }
-                mv.visitMethodInsn(INVOKESTATIC, targetClass,
-                        getGeneratedMethodName(wd), "(Ljava/lang/Class;)V");
+                invokeStatic(targetClass, new Method(getGeneratedMethodName(wd),
+                    Type.VOID_TYPE, new Type[] {CLASS_TYPE}));
 
+                //Call the original instruction
                 super.visitMethodInsn(opcode, owner, name, desc);
 
-                // end the try part and do the finally part
-                // Add: } finally { Util.restoreContextClassLoader(); }
-                Label l2 = new Label();
-                mv.visitJumpInsn(GOTO, l2);
-                mv.visitLabel(l1);
-                mv.visitFrame(F_FULL, 2, new Object[] {"[Ljava/lang/String;", "java/lang/ClassLoader"},
1, new Object[] {"java/lang/Throwable"});
-                mv.visitVarInsn(ASTORE, 2);
-                mv.visitMethodInsn(INVOKESTATIC, UTIL_CLASS,
-                        "restoreContextClassloader", VOID_RETURN_TYPE);
-//                mv.visitMethodInsn(INVOKESTATIC, UTIL_CLASS,
-//                        "storeContextClassloader", VOID_RETURN_TYPE);
-                mv.visitVarInsn(ALOAD, 2);
-                mv.visitInsn(ATHROW);
-                mv.visitLabel(l2);
-                mv.visitFrame(F_SAME, 0, null, 0, null);
-                mv.visitMethodInsn(INVOKESTATIC, UTIL_CLASS,
-                        "restoreContextClassloader", VOID_RETURN_TYPE);
-//                mv.visitMethodInsn(INVOKESTATIC, UTIL_CLASS,
-//                        "storeContextClassloader", VOID_RETURN_TYPE);
+                //If no exception then go to the finally (finally blocks are a catch block
with a jump)
+                Label afterCatch = newLabel();
+                goTo(afterCatch);
+                
+                
+                //start the catch 
+                mark(endTry);
+                //Run the restore method then throw on the exception
+                invokeStatic(UTIL_CLASS, new Method("restoreContextClassloader", Type.VOID_TYPE,
new Type[0]));
+                throwException();
+                
+                //start the finally
+                mark(afterCatch);
+                //Run the restore and continue
+                invokeStatic(UTIL_CLASS, new Method("restoreContextClassloader", Type.VOID_TYPE,
new Type[0]));
             } else {
                 super.visitMethodInsn(opcode, owner, name, desc);
             }



Mime
View raw message