Fixes dependency checking of arrays

This commit is contained in:
konsoletyper 2014-02-14 16:19:51 +04:00
parent afc85c9780
commit d310409db3
6 changed files with 51 additions and 9 deletions

View File

@ -18,6 +18,7 @@ package org.teavm.dependency;
import java.util.List;
import org.teavm.model.*;
import org.teavm.model.instructions.*;
import org.teavm.model.util.ListingBuilder;
/**
*
@ -38,6 +39,10 @@ class DependencyGraphBuilder {
return;
}
program = method.getProgram();
if (DependencyChecker.shouldLog) {
System.out.println("Method achieved: " + method.getReference());
System.out.println(new ListingBuilder().buildListing(program, " "));
}
resultNode = graph.getResult();
nodes = graph.getVariables();
for (int i = 0; i < program.basicBlockCount(); ++i) {

View File

@ -60,6 +60,9 @@ public class DependencyNode implements DependencyValueInformation {
public void connect(DependencyNode node, DependencyTypeFilter filter) {
DependencyNodeToNodeTransition transition = new DependencyNodeToNodeTransition(this, node, filter);
if (transitions.putIfAbsent(node, transition) == null) {
if (DependencyChecker.shouldLog) {
System.out.println("Connecting " + tag + " to " + node.tag);
}
addConsumer(transition);
}
}
@ -74,6 +77,9 @@ public class DependencyNode implements DependencyValueInformation {
if (result == null) {
result = new DependencyNode(dependencyChecker);
if (arrayItemNode.compareAndSet(null, result)) {
if (DependencyChecker.shouldLog) {
arrayItemNode.get().tag = tag + "[";
}
arrayItemNodeLatch.countDown();
arrayItemNodeLatch = null;
} else {

View File

@ -36,12 +36,13 @@ class DependencyNodeToNodeTransition implements DependencyConsumer {
if (filter != null && !filter.match(type)) {
return;
}
if (type.startsWith("[")) {
type = "java.lang.Object";
}
if (!destination.hasType(type)) {
destination.propagate(type);
if (type.startsWith("[")) {
source.getArrayItem().connect(destination.getArrayItem());
destination.getArrayItem().connect(destination.getArrayItem());
}
source.getArrayItem().connect(destination.getArrayItem());
destination.getArrayItem().connect(source.getArrayItem());
}
}
}

View File

@ -29,6 +29,7 @@ public class JavaScriptBodyDependency implements DependencyListener {
@Override
public void started(DependencyChecker dependencyChecker) {
allClassesNode = dependencyChecker.createNode();
allClassesNode.setTag("JavaScriptBody:global");
}
@Override
@ -47,6 +48,12 @@ public class JavaScriptBodyDependency implements DependencyListener {
if (graph.getResult() != null) {
allClassesNode.connect(graph.getResult());
}
for (int i = 0; i < graph.getParameterCount(); ++i) {
graph.getVariable(i).connect(allClassesNode);
allClassesNode.getArrayItem().connect(graph.getVariable(i).getArrayItem());
allClassesNode.getArrayItem().getArrayItem().connect(graph.getVariable(i)
.getArrayItem().getArrayItem());
}
if (javacall != null && javacall.getBoolean()) {
String body = annot.getValue("body").getString();
new GeneratorJsCallback(dependencyChecker.getClassSource(), dependencyChecker).parse(body);

View File

@ -55,7 +55,7 @@ public class JavaScriptBodyGenerator implements Generator {
writer.append(",").ws();
writer.append(context.getParameterName(i + 1));
}
writer.append(");");
writer.append(");").softNewLine();
}
private static class GeneratorJsCallback extends JsCallback {

View File

@ -15,7 +15,7 @@
*/
package org.teavm.html4j.test;
import static org.junit.Assert.*;
import static org.junit.Assert.assertEquals;
import net.java.html.js.JavaScriptBody;
import org.junit.Test;
@ -29,15 +29,28 @@ public class JavaScriptBodyTests {
assertEquals(23, simpleNativeMethod());
}
@JavaScriptBody(args = {}, body = "return 23;")
private native int simpleNativeMethod();
@Test
public void dependencyPropagated() {
A a = (A)returnValuePassed(new AImpl());
assertEquals(23, a.foo());
}
@Test
public void dependencyPropagatedThroughProperty() {
storeObject(new AImpl());
A a = (A)retrieveObject();
assertEquals(23, a.foo());
}
@Test
public void dependencyPropagatedThroughArray() {
A[] first = new A[1];
storeObject(first);
Object[] second = (Object[])retrieveObject();
second[0] = new AImpl();
assertEquals(23, first[0].foo());
}
private static interface A {
public int foo();
}
@ -46,6 +59,16 @@ public class JavaScriptBodyTests {
return 23;
}
}
@JavaScriptBody(args = {}, body = "return 23;")
private native int simpleNativeMethod();
@JavaScriptBody(args = { "value" }, body = "return value;")
private native Object returnValuePassed(Object value);
@JavaScriptBody(args = { "obj" }, body = "window._global_ = obj;")
private native void storeObject(Object obj);
@JavaScriptBody(args = {}, body = "return window._global_;")
private native Object retrieveObject();
}