mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: trying to fix issues with array covariance
This commit is contained in:
parent
dd2e4bb001
commit
92666e8cf0
|
@ -22,9 +22,18 @@ import org.teavm.model.*;
|
||||||
|
|
||||||
public abstract class Expr implements Cloneable {
|
public abstract class Expr implements Cloneable {
|
||||||
private TextLocation location;
|
private TextLocation location;
|
||||||
|
private int variableIndex = -1;
|
||||||
|
|
||||||
public abstract void acceptVisitor(ExprVisitor visitor);
|
public abstract void acceptVisitor(ExprVisitor visitor);
|
||||||
|
|
||||||
|
public int getVariableIndex() {
|
||||||
|
return variableIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVariableIndex(int variableIndex) {
|
||||||
|
this.variableIndex = variableIndex;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Expr clone() {
|
public Expr clone() {
|
||||||
return clone(new HashMap<>());
|
return clone(new HashMap<>());
|
||||||
|
@ -41,6 +50,7 @@ public abstract class Expr implements Cloneable {
|
||||||
public static Expr var(int index) {
|
public static Expr var(int index) {
|
||||||
VariableExpr expr = new VariableExpr();
|
VariableExpr expr = new VariableExpr();
|
||||||
expr.setIndex(index);
|
expr.setIndex(index);
|
||||||
|
expr.setVariableIndex(index);
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -211,6 +211,7 @@ class StatementGenerator implements InstructionVisitor {
|
||||||
public void visit(CastInstruction insn) {
|
public void visit(CastInstruction insn) {
|
||||||
CastExpr expr = new CastExpr();
|
CastExpr expr = new CastExpr();
|
||||||
expr.setLocation(insn.getLocation());
|
expr.setLocation(insn.getLocation());
|
||||||
|
expr.setVariableIndex(insn.getReceiver().getIndex());
|
||||||
expr.setValue(Expr.var(insn.getValue().getIndex()));
|
expr.setValue(Expr.var(insn.getValue().getIndex()));
|
||||||
expr.setTarget(insn.getTargetType());
|
expr.setTarget(insn.getTargetType());
|
||||||
assign(expr, insn.getReceiver());
|
assign(expr, insn.getReceiver());
|
||||||
|
@ -219,6 +220,8 @@ class StatementGenerator implements InstructionVisitor {
|
||||||
@Override
|
@Override
|
||||||
public void visit(CastNumberInstruction insn) {
|
public void visit(CastNumberInstruction insn) {
|
||||||
PrimitiveCastExpr expr = new PrimitiveCastExpr();
|
PrimitiveCastExpr expr = new PrimitiveCastExpr();
|
||||||
|
expr.setLocation(insn.getLocation());
|
||||||
|
expr.setVariableIndex(insn.getReceiver().getIndex());
|
||||||
expr.setSource(mapOperandType(insn.getSourceType()));
|
expr.setSource(mapOperandType(insn.getSourceType()));
|
||||||
expr.setTarget(mapOperandType(insn.getTargetType()));
|
expr.setTarget(mapOperandType(insn.getTargetType()));
|
||||||
expr.setValue(Expr.var(insn.getValue().getIndex()));
|
expr.setValue(Expr.var(insn.getValue().getIndex()));
|
||||||
|
@ -495,6 +498,7 @@ class StatementGenerator implements InstructionVisitor {
|
||||||
}
|
}
|
||||||
AssignmentStatement stmt;
|
AssignmentStatement stmt;
|
||||||
if (insn.getReceiver() != null) {
|
if (insn.getReceiver() != null) {
|
||||||
|
invocationExpr.setVariableIndex(insn.getReceiver().getIndex());
|
||||||
stmt = Statement.assign(Expr.var(insn.getReceiver().getIndex()), invocationExpr);
|
stmt = Statement.assign(Expr.var(insn.getReceiver().getIndex()), invocationExpr);
|
||||||
} else {
|
} else {
|
||||||
stmt = Statement.assign(null, invocationExpr);
|
stmt = Statement.assign(null, invocationExpr);
|
||||||
|
@ -518,6 +522,8 @@ class StatementGenerator implements InstructionVisitor {
|
||||||
|
|
||||||
private void assign(Expr source, Variable target) {
|
private void assign(Expr source, Variable target) {
|
||||||
AssignmentStatement stmt = Statement.assign(Expr.var(target.getIndex()), source);
|
AssignmentStatement stmt = Statement.assign(Expr.var(target.getIndex()), source);
|
||||||
|
source.setLocation(currentLocation);
|
||||||
|
source.setVariableIndex(target.getIndex());
|
||||||
stmt.setLocation(currentLocation);
|
stmt.setLocation(currentLocation);
|
||||||
statements.add(stmt);
|
statements.add(stmt);
|
||||||
}
|
}
|
||||||
|
@ -647,7 +653,6 @@ class StatementGenerator implements InstructionVisitor {
|
||||||
if (insn.getArray() != null) {
|
if (insn.getArray() != null) {
|
||||||
expr.setArray(Expr.var(insn.getArray().getIndex()));
|
expr.setArray(Expr.var(insn.getArray().getIndex()));
|
||||||
}
|
}
|
||||||
expr.setLocation(insn.getLocation());
|
|
||||||
assign(expr, insn.getReceiver());
|
assign(expr, insn.getReceiver());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -190,6 +190,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
Expr result = BinaryExpr.binary(expr.getOperation(), comparison.getType(),
|
Expr result = BinaryExpr.binary(expr.getOperation(), comparison.getType(),
|
||||||
comparison.getFirstOperand(), comparison.getSecondOperand());
|
comparison.getFirstOperand(), comparison.getSecondOperand());
|
||||||
result.setLocation(comparison.getLocation());
|
result.setLocation(comparison.getLocation());
|
||||||
|
result.setVariableIndex(comparison.getVariableIndex());
|
||||||
if (invert) {
|
if (invert) {
|
||||||
result = ExprOptimizer.invert(result);
|
result = ExprOptimizer.invert(result);
|
||||||
}
|
}
|
||||||
|
@ -294,6 +295,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
ConstantExpr constantExpr = new ConstantExpr();
|
ConstantExpr constantExpr = new ConstantExpr();
|
||||||
constantExpr.setValue(constants[index]);
|
constantExpr.setValue(constants[index]);
|
||||||
constantExpr.setLocation(expr.getLocation());
|
constantExpr.setLocation(expr.getLocation());
|
||||||
|
constantExpr.setVariableIndex(expr.getVariableIndex());
|
||||||
resultExpr = constantExpr;
|
resultExpr = constantExpr;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -483,6 +485,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
args = Arrays.copyOfRange(args, 1, args.length);
|
args = Arrays.copyOfRange(args, 1, args.length);
|
||||||
InvocationExpr constructrExpr = Expr.constructObject(expr.getMethod(), args);
|
InvocationExpr constructrExpr = Expr.constructObject(expr.getMethod(), args);
|
||||||
constructrExpr.setLocation(expr.getLocation());
|
constructrExpr.setLocation(expr.getLocation());
|
||||||
|
constructrExpr.setVariableIndex(constructed.getVariableIndex());
|
||||||
assignment.setRightValue(constructrExpr);
|
assignment.setRightValue(constructrExpr);
|
||||||
readFrequencies[var.getIndex()]--;
|
readFrequencies[var.getIndex()]--;
|
||||||
return true;
|
return true;
|
||||||
|
@ -823,6 +826,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
private void applyArrayOptimization(ArrayOptimization optimization) {
|
private void applyArrayOptimization(ArrayOptimization optimization) {
|
||||||
AssignmentStatement assign = (AssignmentStatement) resultSequence.get(optimization.index);
|
AssignmentStatement assign = (AssignmentStatement) resultSequence.get(optimization.index);
|
||||||
ArrayFromDataExpr arrayFromData = new ArrayFromDataExpr();
|
ArrayFromDataExpr arrayFromData = new ArrayFromDataExpr();
|
||||||
|
arrayFromData.setVariableIndex(optimization.array.getVariableIndex());
|
||||||
arrayFromData.setLocation(optimization.array.getLocation());
|
arrayFromData.setLocation(optimization.array.getLocation());
|
||||||
arrayFromData.setType(optimization.array.getType());
|
arrayFromData.setType(optimization.array.getType());
|
||||||
arrayFromData.getData().addAll(optimization.elements);
|
arrayFromData.getData().addAll(optimization.elements);
|
||||||
|
@ -1096,6 +1100,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
AssignmentStatement assignment = new AssignmentStatement();
|
AssignmentStatement assignment = new AssignmentStatement();
|
||||||
assignment.setLocation(conditionalExpr.getLocation());
|
assignment.setLocation(conditionalExpr.getLocation());
|
||||||
VariableExpr lhs = new VariableExpr();
|
VariableExpr lhs = new VariableExpr();
|
||||||
|
lhs.setVariableIndex(firstLhs.getIndex());
|
||||||
lhs.setIndex(firstLhs.getIndex());
|
lhs.setIndex(firstLhs.getIndex());
|
||||||
assignment.setLeftValue(lhs);
|
assignment.setLeftValue(lhs);
|
||||||
assignment.setRightValue(conditionalExpr);
|
assignment.setRightValue(conditionalExpr);
|
||||||
|
@ -1166,6 +1171,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
||||||
if (statement.getCondition() != null) {
|
if (statement.getCondition() != null) {
|
||||||
Expr newCondition = Expr.binary(BinaryOperation.AND, null, statement.getCondition(),
|
Expr newCondition = Expr.binary(BinaryOperation.AND, null, statement.getCondition(),
|
||||||
ExprOptimizer.invert(cond.getCondition()));
|
ExprOptimizer.invert(cond.getCondition()));
|
||||||
|
newCondition.setVariableIndex(statement.getCondition().getVariableIndex());
|
||||||
newCondition.setLocation(statement.getCondition().getLocation());
|
newCondition.setLocation(statement.getCondition().getLocation());
|
||||||
statement.setCondition(newCondition);
|
statement.setCondition(newCondition);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -470,7 +470,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
if (type instanceof ValueType.Object) {
|
if (type instanceof ValueType.Object) {
|
||||||
fillClassFields(fields, ((ValueType.Object) type).getClassName());
|
fillClassFields(fields, ((ValueType.Object) type).getClassName());
|
||||||
} else if (type instanceof ValueType.Array) {
|
} else if (type instanceof ValueType.Array) {
|
||||||
fillArrayField(classInfo, ((ValueType.Array) type).getItemType());
|
fillArrayFields(classInfo, ((ValueType.Array) type).getItemType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,8 +516,37 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fillArrayField(WasmGCClassInfo classInfo, ValueType elementType) {
|
private void fillArrayFields(WasmGCClassInfo classInfo, ValueType elementType) {
|
||||||
var wasmArray = new WasmArray(null, () -> typeMapper.mapStorageType(elementType));
|
WasmStorageType wasmElementType;
|
||||||
|
if (elementType instanceof ValueType.Primitive) {
|
||||||
|
switch (((ValueType.Primitive) elementType).getKind()) {
|
||||||
|
case BOOLEAN:
|
||||||
|
case BYTE:
|
||||||
|
wasmElementType = WasmStorageType.INT8;
|
||||||
|
break;
|
||||||
|
case SHORT:
|
||||||
|
case CHARACTER:
|
||||||
|
wasmElementType = WasmStorageType.INT16;
|
||||||
|
break;
|
||||||
|
case INTEGER:
|
||||||
|
wasmElementType = WasmType.INT32.asStorage();
|
||||||
|
break;
|
||||||
|
case LONG:
|
||||||
|
wasmElementType = WasmType.INT64.asStorage();
|
||||||
|
break;
|
||||||
|
case FLOAT:
|
||||||
|
wasmElementType = WasmType.FLOAT32.asStorage();
|
||||||
|
break;
|
||||||
|
case DOUBLE:
|
||||||
|
wasmElementType = WasmType.FLOAT64.asStorage();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
wasmElementType = WasmType.Reference.STRUCT.asStorage();
|
||||||
|
}
|
||||||
|
var wasmArray = new WasmArray(null, wasmElementType);
|
||||||
module.types.add(wasmArray);
|
module.types.add(wasmArray);
|
||||||
classInfo.structure.getFields().add(wasmArray.getReference().asStorage());
|
classInfo.structure.getFields().add(wasmArray.getReference().asStorage());
|
||||||
classInfo.array = wasmArray;
|
classInfo.array = wasmArray;
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.teavm.ast.InvocationExpr;
|
||||||
import org.teavm.ast.QualificationExpr;
|
import org.teavm.ast.QualificationExpr;
|
||||||
import org.teavm.ast.SubscriptExpr;
|
import org.teavm.ast.SubscriptExpr;
|
||||||
import org.teavm.ast.UnwrapArrayExpr;
|
import org.teavm.ast.UnwrapArrayExpr;
|
||||||
|
import org.teavm.backend.wasm.gc.PreciseTypeInference;
|
||||||
import org.teavm.backend.wasm.generate.common.methods.BaseWasmGenerationVisitor;
|
import org.teavm.backend.wasm.generate.common.methods.BaseWasmGenerationVisitor;
|
||||||
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
import org.teavm.backend.wasm.generate.gc.classes.WasmGCClassInfoProvider;
|
||||||
import org.teavm.backend.wasm.model.WasmArray;
|
import org.teavm.backend.wasm.model.WasmArray;
|
||||||
|
@ -63,12 +64,14 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
private WasmGCGenerationContext context;
|
private WasmGCGenerationContext context;
|
||||||
private WasmGCGenerationUtil generationUtil;
|
private WasmGCGenerationUtil generationUtil;
|
||||||
private WasmType expectedType;
|
private WasmType expectedType;
|
||||||
|
private PreciseTypeInference types;
|
||||||
|
|
||||||
public WasmGCGenerationVisitor(WasmGCGenerationContext context, MethodReference currentMethod,
|
public WasmGCGenerationVisitor(WasmGCGenerationContext context, MethodReference currentMethod,
|
||||||
WasmFunction function, int firstVariable, boolean async) {
|
WasmFunction function, int firstVariable, boolean async, PreciseTypeInference types) {
|
||||||
super(context, currentMethod, function, firstVariable, async);
|
super(context, currentMethod, function, firstVariable, async);
|
||||||
this.context = context;
|
this.context = context;
|
||||||
generationUtil = new WasmGCGenerationUtil(context.classInfoProvider(), tempVars);
|
generationUtil = new WasmGCGenerationUtil(context.classInfoProvider(), tempVars);
|
||||||
|
this.types = types;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -384,6 +387,12 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
}
|
}
|
||||||
arrayGet.setLocation(expr.getLocation());
|
arrayGet.setLocation(expr.getLocation());
|
||||||
result = arrayGet;
|
result = arrayGet;
|
||||||
|
if (expr.getType() == ArrayType.OBJECT && expr.getVariableIndex() >= 0) {
|
||||||
|
var targetType = types.typeOf(expr.getVariableIndex());
|
||||||
|
if (targetType != null) {
|
||||||
|
result = new WasmCast(result, (WasmType.Reference) mapType(targetType.valueType));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -250,7 +250,7 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
|
||||||
|
|
||||||
addInitializerErase(method, function);
|
addInitializerErase(method, function);
|
||||||
var visitor = new WasmGCGenerationVisitor(getGenerationContext(), method.getReference(),
|
var visitor = new WasmGCGenerationVisitor(getGenerationContext(), method.getReference(),
|
||||||
function, firstVar, false);
|
function, firstVar, false, typeInference);
|
||||||
visitor.generate(ast.getBody(), function.getBody());
|
visitor.generate(ast.getBody(), function.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
package org.teavm.backend.wasm.model;
|
package org.teavm.backend.wasm.model;
|
||||||
|
|
||||||
public abstract class WasmStorageType {
|
public abstract class WasmStorageType {
|
||||||
private static final Packed INT16 = new Packed(WasmPackedType.INT16);
|
public static final Packed INT16 = new Packed(WasmPackedType.INT16);
|
||||||
private static final Packed INT8 = new Packed(WasmPackedType.INT8);
|
public static final Packed INT8 = new Packed(WasmPackedType.INT8);
|
||||||
|
|
||||||
private WasmStorageType() {
|
private WasmStorageType() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -238,12 +238,15 @@ public abstract class BaseTypeInference<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public T typeOf(Variable variable) {
|
public T typeOf(Variable variable) {
|
||||||
ensure();
|
return typeOf(variable.getIndex());
|
||||||
return (T) types[variable.getIndex()];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public T typeOf(int index) {
|
||||||
|
ensure();
|
||||||
|
return (T) types[index];
|
||||||
|
}
|
||||||
|
|
||||||
protected abstract T mapType(ValueType type);
|
protected abstract T mapType(ValueType type);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user