Skip to content

Commit

Permalink
Reverted change which removed clinit wrappers for private static meth…
Browse files Browse the repository at this point in the history
…ods. That

change broke certain lambdas. (fixes #914) (fixes #972)
  • Loading branch information
ntherning committed May 6, 2015
1 parent 4257026 commit 4a4bf39
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 25 deletions.
22 changes: 1 addition & 21 deletions compiler/src/main/java/org/robovm/compiler/ClassCompiler.java
Expand Up @@ -755,7 +755,7 @@ private void compile(Clazz clazz, OutputStream out) throws IOException {


createLookupFunction(method); createLookupFunction(method);
} }
if (needsClassInitWrapper(method)) { if (method.isStatic() && !name.equals("<clinit>")) {
String fnName = method.isSynchronized() String fnName = method.isSynchronized()
? Symbols.synchronizedWrapperSymbol(method) ? Symbols.synchronizedWrapperSymbol(method)
: Symbols.methodSymbol(method); : Symbols.methodSymbol(method);
Expand Down Expand Up @@ -858,26 +858,6 @@ private void compile(Clazz clazz, OutputStream out) throws IOException {
clazz.saveClazzInfo(); clazz.saveClazzInfo();
} }


private boolean needsClassInitWrapper(SootMethod method) {
if (!method.isStatic()) {
return false;
}
if ((method.getModifiers() & 0x1000 /*ACC_SYNTHETIC*/) > 0) {
/*
* For some lambdas the Java 8 compiler generates static synthetic
* private methods for the lambda implementation. The generated
* inner class for the lambda will call the generated method by
* calling the clinit wrapper function for that method. We have to
* make sure that these methods generated for lambdas get clinit
* wrappers even if they are private. See #972.
*/
if (method.getName().matches("lambda\\$\\d+")) {
return true;
}
}
return !method.isPrivate() && !method.getName().equals("<clinit>");
}

private static void addDependencyIfNeeded(Clazz clazz, soot.Type type) { private static void addDependencyIfNeeded(Clazz clazz, soot.Type type) {
if (type instanceof RefLikeType) { if (type instanceof RefLikeType) {
addDependencyIfNeeded(clazz, getDescriptor(type)); addDependencyIfNeeded(clazz, getDescriptor(type));
Expand Down
38 changes: 34 additions & 4 deletions tests/robovm/src/test/java/org/robovm/rt/LambdasTest.java
Expand Up @@ -28,20 +28,42 @@ public class LambdasTest {


@Test @Test
public void testSimple() throws Exception { public void testSimple() throws Exception {
assertEquals("foo", run(() -> "foo")); assertEquals("foo", runCallable(() -> "foo"));
} }


@Test @Test
public void testAccessPrivateInstanceMethod() throws Exception { public void testAccessPrivateInstanceMethod() throws Exception {
assertEquals("foo", run(() -> privateInstanceMethod(() -> "foo"))); assertEquals("foo", runCallable(() -> privateInstanceMethod(() -> "foo")));
}

@Test
public void testAccessPrivateInstanceMethodReference() throws Exception {
assertEquals("foo", runCallable(this::privateInstanceMethod));
} }


@Test @Test
public void testAccessPrivateClassMethod() throws Exception { public void testAccessPrivateClassMethod() throws Exception {
assertEquals("foo", run(() -> privateClassMethod(() -> "foo"))); assertEquals("foo", runCallable(() -> privateClassMethod(() -> "foo")));
}

@Test
public void testAccessPrivateClassMethodReference() throws Exception {
assertEquals("foo", runCallable(LambdasTest::privateClassMethod));
} }


private <T> T run(Callable<T> callable) throws Exception { @Test
public void testAccessVarInSurroundingScope() throws Exception {
StringBuilder sb = new StringBuilder();
runRunnable(() -> sb.append("foo"));
runRunnable(() -> sb.append("bar"));
assertEquals("foobar", sb.toString());
}

private void runRunnable(Runnable r) throws Exception {
r.run();
}

private <T> T runCallable(Callable<T> callable) throws Exception {
return callable.call(); return callable.call();
} }


Expand All @@ -52,4 +74,12 @@ private <T> T privateInstanceMethod(Callable<T> callable) throws Exception {
private static <T> T privateClassMethod(Callable<T> callable) throws Exception { private static <T> T privateClassMethod(Callable<T> callable) throws Exception {
return callable.call(); return callable.call();
} }

private String privateInstanceMethod() throws Exception {
return "foo";
}

private static String privateClassMethod() throws Exception {
return "foo";
}
} }

0 comments on commit 4a4bf39

Please sign in to comment.