mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2025-01-03 05:44:10 -08:00
In class inference add rules for known types of method parameters
and method return value
This commit is contained in:
parent
8d9240df36
commit
293e82a3c0
|
@ -53,6 +53,7 @@ import org.teavm.model.instructions.CloneArrayInstruction;
|
||||||
import org.teavm.model.instructions.ConstructArrayInstruction;
|
import org.teavm.model.instructions.ConstructArrayInstruction;
|
||||||
import org.teavm.model.instructions.ConstructInstruction;
|
import org.teavm.model.instructions.ConstructInstruction;
|
||||||
import org.teavm.model.instructions.ConstructMultiArrayInstruction;
|
import org.teavm.model.instructions.ConstructMultiArrayInstruction;
|
||||||
|
import org.teavm.model.instructions.ExitInstruction;
|
||||||
import org.teavm.model.instructions.GetElementInstruction;
|
import org.teavm.model.instructions.GetElementInstruction;
|
||||||
import org.teavm.model.instructions.GetFieldInstruction;
|
import org.teavm.model.instructions.GetFieldInstruction;
|
||||||
import org.teavm.model.instructions.InvocationType;
|
import org.teavm.model.instructions.InvocationType;
|
||||||
|
@ -81,11 +82,24 @@ public class ClassInference {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void infer(Program program, MethodReference methodReference) {
|
public void infer(Program program, MethodReference methodReference) {
|
||||||
buildGraphs(program);
|
|
||||||
|
|
||||||
MethodDependencyInfo thisMethodDep = dependencyInfo.getMethod(methodReference);
|
MethodDependencyInfo thisMethodDep = dependencyInfo.getMethod(methodReference);
|
||||||
for (String thisType : thisMethodDep.getVariable(0).getTypes()) {
|
buildGraphs(program, thisMethodDep);
|
||||||
initialTasks.add(new Task(0, 0, thisType));
|
|
||||||
|
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());
|
types = new ArrayList<>(program.variableCount());
|
||||||
|
@ -118,8 +132,9 @@ public class ClassInference {
|
||||||
return finalTypes.get(variableIndex).toArray(new String[0]);
|
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);
|
GraphBuildingVisitor visitor = new GraphBuildingVisitor(program.variableCount(), dependencyInfo);
|
||||||
|
visitor.thisMethodDep = thisMethodDep;
|
||||||
for (BasicBlock block : program.getBasicBlocks()) {
|
for (BasicBlock block : program.getBasicBlocks()) {
|
||||||
visitor.currentBlock = block;
|
visitor.currentBlock = block;
|
||||||
for (Phi phi : block.getPhis()) {
|
for (Phi phi : block.getPhis()) {
|
||||||
|
@ -279,6 +294,7 @@ public class ClassInference {
|
||||||
GraphBuilder cloneGraphBuilder;
|
GraphBuilder cloneGraphBuilder;
|
||||||
GraphBuilder arrayGraphBuilder;
|
GraphBuilder arrayGraphBuilder;
|
||||||
GraphBuilder itemGraphBuilder;
|
GraphBuilder itemGraphBuilder;
|
||||||
|
MethodDependencyInfo thisMethodDep;
|
||||||
List<IntObjectMap<ValueType>> casts = new ArrayList<>();
|
List<IntObjectMap<ValueType>> casts = new ArrayList<>();
|
||||||
IntObjectMap<IntSet> exceptionMap = new IntObjectOpenHashMap<>();
|
IntObjectMap<IntSet> exceptionMap = new IntObjectOpenHashMap<>();
|
||||||
List<Task> tasks = new ArrayList<>();
|
List<Task> tasks = new ArrayList<>();
|
||||||
|
@ -388,6 +404,20 @@ public class ClassInference {
|
||||||
arrayGraphBuilder.addEdge(insn.getValue().getIndex(), insn.getArray().getIndex());
|
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
|
@Override
|
||||||
public void visit(InvokeInstruction insn) {
|
public void visit(InvokeInstruction insn) {
|
||||||
if (insn.getType() == InvocationType.VIRTUAL) {
|
if (insn.getType() == InvocationType.VIRTUAL) {
|
||||||
|
@ -412,7 +442,7 @@ public class ClassInference {
|
||||||
}
|
}
|
||||||
|
|
||||||
MethodDependencyInfo methodDep = dependencyInfo.getMethod(insn.getMethod());
|
MethodDependencyInfo methodDep = dependencyInfo.getMethod(insn.getMethod());
|
||||||
|
if (methodDep != null) {
|
||||||
if (insn.getReceiver() != null) {
|
if (insn.getReceiver() != null) {
|
||||||
readValue(methodDep.getResult(), insn.getReceiver(), tasks);
|
readValue(methodDep.getResult(), insn.getReceiver(), tasks);
|
||||||
}
|
}
|
||||||
|
@ -426,6 +456,7 @@ public class ClassInference {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void readValue(ValueDependencyInfo valueDep, Variable receiver, Collection<Task> tasks) {
|
private static void readValue(ValueDependencyInfo valueDep, Variable receiver, Collection<Task> tasks) {
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user