changeset 29:820b89dd6c97

Fixed a bug in the implementation for lambda support. Now, every invocation of invokedynamic that is associated with a lamabda expression including free variables leads to a new instance of a function object.
author nastaran <nastaran.shafiei@gmail.com>
date Fri, 16 Oct 2015 15:55:08 -0700
parents 7be90179bb3b
children 9dc9df847545
files src/main/gov/nasa/jpf/jvm/bytecode/INVOKEDYNAMIC.java src/tests/java8/LambdaTest.java
diffstat 2 files changed, 40 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/main/gov/nasa/jpf/jvm/bytecode/INVOKEDYNAMIC.java	Thu Jun 25 13:20:50 2015 -0700
+++ b/src/main/gov/nasa/jpf/jvm/bytecode/INVOKEDYNAMIC.java	Fri Oct 16 15:55:08 2015 -0700
@@ -95,7 +95,7 @@
     
     ElementInfo ei = ti.getHeap().get(funcObjRef);
     
-    if(ei==null || ei!=lastFuncObj) {
+    if(ei==null || ei!=lastFuncObj || freeVariableTypes.length>0) {
       ClassInfo fiClassInfo;
 
       // First, resolve the functional interface
--- a/src/tests/java8/LambdaTest.java	Thu Jun 25 13:20:50 2015 -0700
+++ b/src/tests/java8/LambdaTest.java	Fri Oct 16 15:55:08 2015 -0700
@@ -255,4 +255,43 @@
       assertEquals(fi.toString(10),"output:10");
     }
   }
+  
+  public static class Foo {
+    
+    Integer i = 0;
+    static Integer j = 1;
+    
+    
+    public FI1 invokSam(FI1 fi) {
+      fi.sam();
+      return fi;
+    }
+    
+    
+    public FI1 withFreeVar() {
+      return invokSam(()->{Foo foo = this;});
+    }
+    
+    public static FI1 withStatic(Foo foo) {
+      return foo.invokSam(()->{Foo.j = 10;});
+    }
+  }
+  
+  @Test
+  public void testFreeVariables() {
+    if(verifyNoPropertyViolation()) {
+      
+      Foo foo = new Foo();
+      
+      FI1 fi1 = foo.withFreeVar();  
+      FI1 fi2 = foo.withFreeVar();
+      
+      assertFalse(fi1==fi2);
+     
+      fi1 = Foo.withStatic(foo);
+      fi2 = Foo.withStatic(foo);
+      
+      assertSame(fi1,fi2);
+    }
+  }
 }