In class inference add rules for known types of method parameters
and method return value
@@ -53,6 +53,7 @@ import org.teavm.model.instructions.CloneArrayInstruction;
import org.teavm.model.instructions.ConstructArrayInstruction;
import org.teavm.model.instructions.ConstructInstruction;
import org.teavm.model.instructions.ConstructMultiArrayInstruction;
+import org.teavm.model.instructions.ExitInstruction;
import org.teavm.model.instructions.GetElementInstruction;
import org.teavm.model.instructions.GetFieldInstruction;
import org.teavm.model.instructions.InvocationType;
@@ -81,11 +82,24 @@ public class ClassInference {
}
public void infer(Program program, MethodReference methodReference) {
- buildGraphs(program);
-
MethodDependencyInfo thisMethodDep = dependencyInfo.getMethod(methodReference);
- for (String thisType : thisMethodDep.getVariable(0).getTypes()) {
- initialTasks.add(new Task(0, 0, thisType));
+ buildGraphs(program, thisMethodDep);
+
+ for (int i = 0; i <= methodReference.parameterCount(); ++i) {
+ ValueDependencyInfo paramDep = thisMethodDep.getVariable(i);
+ if (paramDep != null) {
+ int degree = 0;
+ while (true) {
+ for (String paramType : paramDep.getTypes()) {
+ initialTasks.add(new Task(i, degree, paramType));
+ }
+ if (!paramDep.hasArrayType()) {
+ break;
+ }
+ paramDep = paramDep.getArrayItem();
+ degree++;
+ }
+ }
}
types = new ArrayList<>(program.variableCount());
@@ -118,8 +132,9 @@ public class ClassInference {
return finalTypes.get(variableIndex).toArray(new String[0]);
}
- private void buildGraphs(Program program) {
+ private void buildGraphs(Program program, MethodDependencyInfo thisMethodDep) {
GraphBuildingVisitor visitor = new GraphBuildingVisitor(program.variableCount(), dependencyInfo);
+ visitor.thisMethodDep = thisMethodDep;
for (BasicBlock block : program.getBasicBlocks()) {
visitor.currentBlock = block;
for (Phi phi : block.getPhis()) {
@@ -279,6 +294,7 @@ public class ClassInference {
GraphBuilder cloneGraphBuilder;
GraphBuilder arrayGraphBuilder;
GraphBuilder itemGraphBuilder;
+ MethodDependencyInfo thisMethodDep;
List<IntObjectMap<ValueType>> casts = new ArrayList<>();
IntObjectMap<IntSet> exceptionMap = new IntObjectOpenHashMap<>();
List<Task> tasks = new ArrayList<>();
@@ -388,6 +404,20 @@ public class ClassInference {
arrayGraphBuilder.addEdge(insn.getValue().getIndex(), insn.getArray().getIndex());
}
+ @Override
+ public void visit(ExitInstruction insn) {
+ if (insn.getValueToReturn() != null) {
+ ValueDependencyInfo resultDependency = thisMethodDep.getResult();
+ int resultDegree = 0;
+ while (resultDependency.hasArrayType()) {
+ resultDependency = resultDependency.getArrayItem();
+ for (String paramType : resultDependency.getTypes()) {
+ tasks.add(new Task(insn.getValueToReturn().getIndex(), ++resultDegree, paramType));
+ }
+ }
+ }
+ }
+
@Override
public void visit(InvokeInstruction insn) {
if (insn.getType() == InvocationType.VIRTUAL) {
@@ -412,7 +442,7 @@ public class ClassInference {
}
MethodDependencyInfo methodDep = dependencyInfo.getMethod(insn.getMethod());
-
+ if (methodDep != null) {
if (insn.getReceiver() != null) {
readValue(methodDep.getResult(), insn.getReceiver(), tasks);
}
@@ -426,6 +456,7 @@ public class ClassInference {
}
}
}
+ }
private static void readValue(ValueDependencyInfo valueDep, Variable receiver, Collection<Task> tasks) {
int depth = 0;
