You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by tc...@apache.org on 2009/12/22 15:04:05 UTC

svn commit: r893171 - /commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAdapter.java

Author: tcurdt
Date: Tue Dec 22 14:04:05 2009
New Revision: 893171

URL: http://svn.apache.org/viewvc?rev=893171&view=rev
Log:
patch from Valery Silaev <vs...@gmail.com> (see https://issues.apache.org/jira/browse/SANDBOX-277 )


Modified:
    commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAdapter.java

Modified: commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAdapter.java
URL: http://svn.apache.org/viewvc/commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAdapter.java?rev=893171&r1=893170&r2=893171&view=diff
==============================================================================
--- commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAdapter.java (original)
+++ commons/sandbox/javaflow/trunk/src/main/java/org/apache/commons/javaflow/bytecode/transformation/asm/ContinuationMethodAdapter.java Tue Dec 22 14:04:05 2009
@@ -100,7 +100,7 @@
             int lsize = frame.getLocals();
             for (int j = lsize - 1; j >= 0; j--) {
                 BasicValue value = (BasicValue) frame.getLocal(j);
-                if (value == null) {
+                if (isNull(value)) {
                     mv.visitInsn(ACONST_NULL);
                     mv.visitVarInsn(ASTORE, j);
                 } else if (value == BasicValue.UNINITIALIZED_VALUE) {
@@ -145,7 +145,7 @@
             int ssize = frame.getStackSize();
             for (int j = 0; j < ssize - argSize - ownerSize - initSize; j++) {
                 BasicValue value = (BasicValue) frame.getStack(j);
-                if (value == null) {
+                if (isNull(value)) {
                     mv.visitInsn(ACONST_NULL);
                 } else if (value == BasicValue.UNINITIALIZED_VALUE) {
                     // TODO ??
@@ -163,9 +163,16 @@
             }
 
             if (mnode.getOpcode() != INVOKESTATIC) {
-                mv.visitVarInsn(ALOAD, stackRecorderVar);
-                mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Reference", "()Ljava/lang/Object;");
-                mv.visitTypeInsn(CHECKCAST, ((BasicValue) frame.getStack(ssize - argSize - 1)).getType().getInternalName());
+                // Load the object whose method we are calling  
+                BasicValue value = ((BasicValue) frame.getStack(ssize - argSize - 1));
+                if (isNull(value)) { 
+                  // If user code causes NPE, then we keep this behavior: load null to get NPE at runtime 
+                  mv.visitInsn(ACONST_NULL);
+                } else {
+                  mv.visitVarInsn(ALOAD, stackRecorderVar);
+                  mv.visitMethodInsn(INVOKEVIRTUAL, STACK_RECORDER, POP_METHOD + "Reference", "()Ljava/lang/Object;");
+                  mv.visitTypeInsn(CHECKCAST, value.getType().getInternalName());
+                }
             }
 
             // Create null types for the parameters of the method invocation
@@ -216,7 +223,7 @@
             int ssize = currentFrame.getStackSize() - argSize - ownerSize;
             for (int i = ssize - 1; i >= 0; i--) {
                 BasicValue value = (BasicValue) currentFrame.getStack(i);
-                if (value == null) {
+                if (isNull(value)) {
                     mv.visitInsn(POP);
                 } else if (value == BasicValue.UNINITIALIZED_VALUE) {
                     // TODO ??
@@ -251,7 +258,7 @@
             int fsize = currentFrame.getLocals();
             for (int j = 0; j < fsize; j++) {
                 BasicValue value = (BasicValue) currentFrame.getLocal(j);
-                if (value == null) {
+                if (isNull(value)) {
                     // no need to save null
                 } else if (value == BasicValue.UNINITIALIZED_VALUE) {
                     // no need to save uninitialized objects
@@ -301,6 +308,15 @@
         mv.visitMaxs(0, 0);
     }
 
+    static boolean isNull(BasicValue value) {
+      if (null == value)
+        return true;
+      if (!value.isReference())
+        return false;
+      final Type type = value.getType();
+      return "Lnull;".equals(type.getDescriptor()); 
+    }
+
     void pushDefault(Type type) {
         switch (type.getSort()) {
         case Type.VOID: