You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ch...@apache.org on 2009/12/16 02:02:43 UTC

svn commit: r891093 - in /activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src: main/java/org/apache/activemq/actor/AsmActor.java test/java/org/apache/activemq/actor/AsmActorTest.java

Author: chirino
Date: Wed Dec 16 01:02:43 2009
New Revision: 891093

URL: http://svn.apache.org/viewvc?rev=891093&view=rev
Log:
Support non-void methods in the interface.


Modified:
    activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/AsmActor.java
    activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/test/java/org/apache/activemq/actor/AsmActorTest.java

Modified: activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/AsmActor.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/AsmActor.java?rev=891093&r1=891092&r2=891093&view=diff
==============================================================================
--- activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/AsmActor.java (original)
+++ activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/main/java/org/apache/activemq/actor/AsmActor.java Wed Dec 16 01:02:43 2009
@@ -12,6 +12,8 @@
 import org.objectweb.asm.Opcodes;
 import org.objectweb.asm.Type;
 
+import static org.objectweb.asm.Type.*;
+
 import static org.objectweb.asm.ClassWriter.*;
 
 public class AsmActor implements Opcodes {
@@ -44,7 +46,7 @@
     private static final class Generator<T> {
         
         private static final String RUNNABLE = "java/lang/Runnable";
-        private static final String OBJECT = "java/lang/Object";
+        private static final String OBJECT_CLASS = "java/lang/Object";
         private static final String DISPATCH_QUEUE = DispatchQueue.class.getName().replace('.','/');
 
         private final ClassLoader loader;
@@ -91,7 +93,7 @@
             Label start, end;
     
             // example: 
-            cw.visit(V1_4, ACC_PUBLIC + ACC_SUPER, proxyName, null, OBJECT, new String[] { interfaceName });
+            cw.visit(V1_4, ACC_PUBLIC + ACC_SUPER, proxyName, null, OBJECT_CLASS, new String[] { interfaceName });
             {
                 // example:
                 fv = cw.visitField(ACC_PRIVATE + ACC_FINAL, "queue", sig(DISPATCH_QUEUE), null, null);
@@ -110,7 +112,7 @@
                     start = new Label();
                     mv.visitLabel(start);
                     mv.visitVarInsn(ALOAD, 0);
-                    mv.visitMethodInsn(INVOKESPECIAL, OBJECT, "<init>", "()V");
+                    mv.visitMethodInsn(INVOKESPECIAL, OBJECT_CLASS, "<init>", "()V");
                     
                     // example: queue=queue;
                     mv.visitVarInsn(ALOAD, 0);
@@ -164,8 +166,12 @@
                         mv.visitMethodInsn(INVOKESPECIAL, runnable(index), "<init>", "(" + sig(interfaceName) + sig(params) +")V");
                         mv.visitMethodInsn(INVOKEINTERFACE, DISPATCH_QUEUE, "dispatchAsync", "(" + sig(RUNNABLE) + ")V");
                         
-                        // example: return;
-                        mv.visitInsn(RETURN);
+                        Type returnType = Type.getType(method.getReturnType());
+                        Integer returnValue = defaultConstant(returnType);
+                        if( returnValue!=null ) {
+                            mv.visitInsn(returnValue);
+                        }
+                        mv.visitInsn(returnType.getOpcode(IRETURN));
                         
                         end = new Label();
                         mv.visitLabel(end);
@@ -182,6 +188,32 @@
     
             return cw.toByteArray();
         }
+
+        private Integer defaultConstant(Type returnType) {
+            Integer value=null;
+            switch(returnType.getSort()) {
+            case BOOLEAN:
+            case CHAR:
+            case BYTE:
+            case SHORT:
+            case INT:
+                value = ICONST_0;
+                break;
+            case Type.LONG:
+                value = LCONST_0;
+                break;
+            case Type.FLOAT:
+                value = FCONST_0;
+                break;
+            case Type.DOUBLE:
+                value = DCONST_0;
+                break;
+            case ARRAY:
+            case OBJECT:
+                value = ACONST_NULL;
+            }
+            return value;
+        }
     
         public byte[] dumpRunnable(int index, Method method) throws Exception {
     
@@ -191,7 +223,7 @@
             Label start, end;
     
             // example: final class OrderRunnable implements Runnable
-            cw.visit(V1_4, ACC_FINAL + ACC_SUPER, runnable(index), null, OBJECT, new String[] { RUNNABLE });
+            cw.visit(V1_4, ACC_FINAL + ACC_SUPER, runnable(index), null, OBJECT_CLASS, new String[] { RUNNABLE });
             {
     
                 // example: private final IPizzaService target;
@@ -218,7 +250,7 @@
                     start = new Label();
                     mv.visitLabel(start);
                     mv.visitVarInsn(ALOAD, 0);
-                    mv.visitMethodInsn(INVOKESPECIAL, OBJECT, "<init>", "()V");
+                    mv.visitMethodInsn(INVOKESPECIAL, OBJECT_CLASS, "<init>", "()V");
                     
                     // example: this.target = target;
                     mv.visitVarInsn(ALOAD, 0);
@@ -266,7 +298,13 @@
                         mv.visitFieldInsn(GETFIELD, runnable(index), "param"+i, sig(params[i]));
                     }
                     
-                    mv.visitMethodInsn(INVOKEINTERFACE, interfaceName, method.getName(), "("+sig(params)+")V");
+                    String methodSig = Type.getMethodDescriptor(method);
+                    mv.visitMethodInsn(INVOKEINTERFACE, interfaceName, method.getName(), methodSig);
+                    
+                    Type returnType = Type.getType(method.getReturnType());
+                    if( returnType != VOID_TYPE ) {
+                        mv.visitInsn(POP);
+                    }
                     
                     // example: return;
                     mv.visitInsn(RETURN);

Modified: activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/test/java/org/apache/activemq/actor/AsmActorTest.java
URL: http://svn.apache.org/viewvc/activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/test/java/org/apache/activemq/actor/AsmActorTest.java?rev=891093&r1=891092&r2=891093&view=diff
==============================================================================
--- activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/test/java/org/apache/activemq/actor/AsmActorTest.java (original)
+++ activemq/sandbox/activemq-apollo-actor/activemq-dispatcher/src/test/java/org/apache/activemq/actor/AsmActorTest.java Wed Dec 16 01:02:43 2009
@@ -7,11 +7,20 @@
 
 import static junit.framework.Assert.*;
 
+import static junit.framework.Assert.*;
+
+import static junit.framework.Assert.*;
+
+import static junit.framework.Assert.*;
+
+import static junit.framework.Assert.*;
+
 public class AsmActorTest {
 
     public static interface TestInterface {
         void strings(String value, String[] value2);
         void shorts(short value, short[] value2);
+        String returnString();
     }
     
     static class TestMock implements TestInterface {
@@ -21,6 +30,9 @@
         public void strings(String value, String[] value2) {
             fail();
         }
+        public String returnString() {
+            return null;
+        }
     }
 
     private TestMock service;
@@ -42,8 +54,8 @@
         
         service = new TestMock() {
             public void strings(String actual1, String[] actual2) {
-                Assert.assertEquals(expected1, actual1);
-                Assert.assertEquals(expected2, actual2);
+                assertEquals(expected1, actual1);
+                assertEquals(expected2, actual2);
             }
         };
         
@@ -60,8 +72,8 @@
         
         service = new TestMock() {
             public void shorts(short actual1, short[] actual2) {
-                Assert.assertEquals(expected1, actual1);
-                Assert.assertEquals(expected2, actual2);
+                assertEquals(expected1, actual1);
+                assertEquals(expected2, actual2);
             }
         };
         
@@ -69,4 +81,18 @@
         proxy.shorts(expected1, expected2);
 
     }
-}
+    
+    @Test
+    public void returnString() throws Exception {
+
+        service = new TestMock() {
+            public String returnString() {
+                return "hello";
+            }
+        };
+        
+        proxy = AsmActor.create(TestInterface.class, service, createQueue());
+        String actual = proxy.returnString();
+        assertNull(actual);
+
+    }}