wasm gc: fix issue with type inference for null values

This commit is contained in:
Alexey Andreev 2024-09-04 14:58:56 +02:00
parent d0707e5355
commit a9d46ac55e
2 changed files with 32 additions and 0 deletions

View File

@ -243,6 +243,13 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
} }
} }
} }
for (var i = 0; i < method.getProgram().variableCount(); ++i) {
var variable = method.getProgram().variableAt(i);
var varNodeIndex = variable.getRegister() >= 0 ? originalIndexToIndex[variable.getRegister()] : -1;
if (varNodeIndex >= 0 && variableRepresentatives[varNodeIndex] < 0) {
variableRepresentatives[varNodeIndex] = variable.getIndex();
}
}
for (var i = firstVar; i < ast.getVariables().size(); ++i) { for (var i = firstVar; i < ast.getVariables().size(); ++i) {
var localVar = ast.getVariables().get(i); var localVar = ast.getVariables().get(i);

View File

@ -54,6 +54,7 @@ import org.teavm.model.instructions.NegateInstruction;
import org.teavm.model.instructions.NullCheckInstruction; import org.teavm.model.instructions.NullCheckInstruction;
import org.teavm.model.instructions.NullConstantInstruction; import org.teavm.model.instructions.NullConstantInstruction;
import org.teavm.model.instructions.NumericOperandType; import org.teavm.model.instructions.NumericOperandType;
import org.teavm.model.instructions.PutElementInstruction;
import org.teavm.model.instructions.PutFieldInstruction; import org.teavm.model.instructions.PutFieldInstruction;
import org.teavm.model.instructions.StringConstantInstruction; import org.teavm.model.instructions.StringConstantInstruction;
import org.teavm.model.instructions.UnwrapArrayInstruction; import org.teavm.model.instructions.UnwrapArrayInstruction;
@ -64,6 +65,7 @@ public abstract class BaseTypeInference<T> {
private Object[] types; private Object[] types;
private Graph graph; private Graph graph;
private Graph arrayGraph; private Graph arrayGraph;
private Graph backArrayGraph;
private Graph arrayUnwrapGraph; private Graph arrayUnwrapGraph;
private boolean phisSkipped; private boolean phisSkipped;
private boolean backPropagation; private boolean backPropagation;
@ -112,6 +114,7 @@ public abstract class BaseTypeInference<T> {
} }
graph = visitor.graphBuilder.build(); graph = visitor.graphBuilder.build();
arrayGraph = visitor.arrayGraphBuilder.build(); arrayGraph = visitor.arrayGraphBuilder.build();
backArrayGraph = visitor.backArrayGraphBuilder.build();
arrayUnwrapGraph = visitor.arrayUnwrapGraphBuilder.build(); arrayUnwrapGraph = visitor.arrayUnwrapGraphBuilder.build();
} }
@ -191,6 +194,12 @@ public abstract class BaseTypeInference<T> {
stack.push(i); stack.push(i);
} }
} }
for (var j : backArrayGraph.incomingEdges(i)) {
if (!nullTypes[j]) {
typeStack.push(elementType((T) types[j]));
stack.push(i);
}
}
} }
} }
@ -228,6 +237,15 @@ public abstract class BaseTypeInference<T> {
} }
} }
} }
if (backArrayGraph.outgoingEdgesCount(variable) > 0) {
var elementType = elementType(type);
for (var succ : backArrayGraph.outgoingEdges(variable)) {
if (!Objects.equals(types[succ], elementType)) {
stack.push(succ);
typeStack.push(elementType);
}
}
}
} }
} }
@ -282,11 +300,13 @@ public abstract class BaseTypeInference<T> {
private class InitialTypeVisitor extends AbstractInstructionVisitor { private class InitialTypeVisitor extends AbstractInstructionVisitor {
private GraphBuilder graphBuilder; private GraphBuilder graphBuilder;
private GraphBuilder arrayGraphBuilder; private GraphBuilder arrayGraphBuilder;
private GraphBuilder backArrayGraphBuilder;
private GraphBuilder arrayUnwrapGraphBuilder; private GraphBuilder arrayUnwrapGraphBuilder;
InitialTypeVisitor(int size) { InitialTypeVisitor(int size) {
graphBuilder = new GraphBuilder(size); graphBuilder = new GraphBuilder(size);
arrayGraphBuilder = new GraphBuilder(size); arrayGraphBuilder = new GraphBuilder(size);
backArrayGraphBuilder = new GraphBuilder(size);
arrayUnwrapGraphBuilder = new GraphBuilder(size); arrayUnwrapGraphBuilder = new GraphBuilder(size);
} }
@ -428,6 +448,11 @@ public abstract class BaseTypeInference<T> {
arrayGraphBuilder.addEdge(insn.getArray().getIndex(), insn.getReceiver().getIndex()); arrayGraphBuilder.addEdge(insn.getArray().getIndex(), insn.getReceiver().getIndex());
} }
@Override
public void visit(PutElementInstruction insn) {
backArrayGraphBuilder.addEdge(insn.getArray().getIndex(), insn.getValue().getIndex());
}
@Override @Override
public void visit(AssignInstruction insn) { public void visit(AssignInstruction insn) {
graphBuilder.addEdge(insn.getAssignee().getIndex(), insn.getReceiver().getIndex()); graphBuilder.addEdge(insn.getAssignee().getIndex(), insn.getReceiver().getIndex());