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 <vsil...@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:


Reply via email to