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 {
|
||||
private TextLocation location;
|
||||
private int variableIndex = -1;
|
||||
|
||||
public abstract void acceptVisitor(ExprVisitor visitor);
|
||||
|
||||
public int getVariableIndex() {
|
||||
return variableIndex;
|
||||
}
|
||||
|
||||
public void setVariableIndex(int variableIndex) {
|
||||
this.variableIndex = variableIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expr clone() {
|
||||
return clone(new HashMap<>());
|
||||
|
@ -41,6 +50,7 @@ public abstract class Expr implements Cloneable {
|
|||
public static Expr var(int index) {
|
||||
VariableExpr expr = new VariableExpr();
|
||||
expr.setIndex(index);
|
||||
expr.setVariableIndex(index);
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
|
|
@ -211,6 +211,7 @@ class StatementGenerator implements InstructionVisitor {
|
|||
public void visit(CastInstruction insn) {
|
||||
CastExpr expr = new CastExpr();
|
||||
expr.setLocation(insn.getLocation());
|
||||
expr.setVariableIndex(insn.getReceiver().getIndex());
|
||||
expr.setValue(Expr.var(insn.getValue().getIndex()));
|
||||
expr.setTarget(insn.getTargetType());
|
||||
assign(expr, insn.getReceiver());
|
||||
|
@ -219,6 +220,8 @@ class StatementGenerator implements InstructionVisitor {
|
|||
@Override
|
||||
public void visit(CastNumberInstruction insn) {
|
||||
PrimitiveCastExpr expr = new PrimitiveCastExpr();
|
||||
expr.setLocation(insn.getLocation());
|
||||
expr.setVariableIndex(insn.getReceiver().getIndex());
|
||||
expr.setSource(mapOperandType(insn.getSourceType()));
|
||||
expr.setTarget(mapOperandType(insn.getTargetType()));
|
||||
expr.setValue(Expr.var(insn.getValue().getIndex()));
|
||||
|
@ -495,6 +498,7 @@ class StatementGenerator implements InstructionVisitor {
|
|||
}
|
||||
AssignmentStatement stmt;
|
||||
if (insn.getReceiver() != null) {
|
||||
invocationExpr.setVariableIndex(insn.getReceiver().getIndex());
|
||||
stmt = Statement.assign(Expr.var(insn.getReceiver().getIndex()), invocationExpr);
|
||||
} else {
|
||||
stmt = Statement.assign(null, invocationExpr);
|
||||
|
@ -518,6 +522,8 @@ class StatementGenerator implements InstructionVisitor {
|
|||
|
||||
private void assign(Expr source, Variable target) {
|
||||
AssignmentStatement stmt = Statement.assign(Expr.var(target.getIndex()), source);
|
||||
source.setLocation(currentLocation);
|
||||
source.setVariableIndex(target.getIndex());
|
||||
stmt.setLocation(currentLocation);
|
||||
statements.add(stmt);
|
||||
}
|
||||
|
@ -647,7 +653,6 @@ class StatementGenerator implements InstructionVisitor {
|
|||
if (insn.getArray() != null) {
|
||||
expr.setArray(Expr.var(insn.getArray().getIndex()));
|
||||
}
|
||||
expr.setLocation(insn.getLocation());
|
||||
assign(expr, insn.getReceiver());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -190,6 +190,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
|||
Expr result = BinaryExpr.binary(expr.getOperation(), comparison.getType(),
|
||||
comparison.getFirstOperand(), comparison.getSecondOperand());
|
||||
result.setLocation(comparison.getLocation());
|
||||
result.setVariableIndex(comparison.getVariableIndex());
|
||||
if (invert) {
|
||||
result = ExprOptimizer.invert(result);
|
||||
}
|
||||
|
@ -294,6 +295,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
|||
ConstantExpr constantExpr = new ConstantExpr();
|
||||
constantExpr.setValue(constants[index]);
|
||||
constantExpr.setLocation(expr.getLocation());
|
||||
constantExpr.setVariableIndex(expr.getVariableIndex());
|
||||
resultExpr = constantExpr;
|
||||
return;
|
||||
}
|
||||
|
@ -483,6 +485,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
|||
args = Arrays.copyOfRange(args, 1, args.length);
|
||||
InvocationExpr constructrExpr = Expr.constructObject(expr.getMethod(), args);
|
||||
constructrExpr.setLocation(expr.getLocation());
|
||||
constructrExpr.setVariableIndex(constructed.getVariableIndex());
|
||||
assignment.setRightValue(constructrExpr);
|
||||
readFrequencies[var.getIndex()]--;
|
||||
return true;
|
||||
|
@ -823,6 +826,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
|||
private void applyArrayOptimization(ArrayOptimization optimization) {
|
||||
AssignmentStatement assign = (AssignmentStatement) resultSequence.get(optimization.index);
|
||||
ArrayFromDataExpr arrayFromData = new ArrayFromDataExpr();
|
||||
arrayFromData.setVariableIndex(optimization.array.getVariableIndex());
|
||||
arrayFromData.setLocation(optimization.array.getLocation());
|
||||
arrayFromData.setType(optimization.array.getType());
|
||||
arrayFromData.getData().addAll(optimization.elements);
|
||||
|
@ -1096,6 +1100,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
|||
AssignmentStatement assignment = new AssignmentStatement();
|
||||
assignment.setLocation(conditionalExpr.getLocation());
|
||||
VariableExpr lhs = new VariableExpr();
|
||||
lhs.setVariableIndex(firstLhs.getIndex());
|
||||
lhs.setIndex(firstLhs.getIndex());
|
||||
assignment.setLeftValue(lhs);
|
||||
assignment.setRightValue(conditionalExpr);
|
||||
|
@ -1166,6 +1171,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
|||
if (statement.getCondition() != null) {
|
||||
Expr newCondition = Expr.binary(BinaryOperation.AND, null, statement.getCondition(),
|
||||
ExprOptimizer.invert(cond.getCondition()));
|
||||
newCondition.setVariableIndex(statement.getCondition().getVariableIndex());
|
||||
newCondition.setLocation(statement.getCondition().getLocation());
|
||||
statement.setCondition(newCondition);
|
||||
} else {
|
||||
|
|
|
@ -470,7 +470,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
if (type instanceof ValueType.Object) {
|
||||
fillClassFields(fields, ((ValueType.Object) type).getClassName());
|
||||
} 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) {
|
||||
var wasmArray = new WasmArray(null, () -> typeMapper.mapStorageType(elementType));
|
||||
private void fillArrayFields(WasmGCClassInfo classInfo, ValueType 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);
|
||||
classInfo.structure.getFields().add(wasmArray.getReference().asStorage());
|
||||
classInfo.array = wasmArray;
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.teavm.ast.InvocationExpr;
|
|||
import org.teavm.ast.QualificationExpr;
|
||||
import org.teavm.ast.SubscriptExpr;
|
||||
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.gc.classes.WasmGCClassInfoProvider;
|
||||
import org.teavm.backend.wasm.model.WasmArray;
|
||||
|
@ -63,12 +64,14 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
|||
private WasmGCGenerationContext context;
|
||||
private WasmGCGenerationUtil generationUtil;
|
||||
private WasmType expectedType;
|
||||
private PreciseTypeInference types;
|
||||
|
||||
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);
|
||||
this.context = context;
|
||||
generationUtil = new WasmGCGenerationUtil(context.classInfoProvider(), tempVars);
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -384,6 +387,12 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
|||
}
|
||||
arrayGet.setLocation(expr.getLocation());
|
||||
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
|
||||
|
|
|
@ -250,7 +250,7 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
|
|||
|
||||
addInitializerErase(method, function);
|
||||
var visitor = new WasmGCGenerationVisitor(getGenerationContext(), method.getReference(),
|
||||
function, firstVar, false);
|
||||
function, firstVar, false, typeInference);
|
||||
visitor.generate(ast.getBody(), function.getBody());
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
package org.teavm.backend.wasm.model;
|
||||
|
||||
public abstract class WasmStorageType {
|
||||
private static final Packed INT16 = new Packed(WasmPackedType.INT16);
|
||||
private static final Packed INT8 = new Packed(WasmPackedType.INT8);
|
||||
public static final Packed INT16 = new Packed(WasmPackedType.INT16);
|
||||
public static final Packed INT8 = new Packed(WasmPackedType.INT8);
|
||||
|
||||
private WasmStorageType() {
|
||||
}
|
||||
|
|
|
@ -238,12 +238,15 @@ public abstract class BaseTypeInference<T> {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T typeOf(Variable variable) {
|
||||
ensure();
|
||||
return (T) types[variable.getIndex()];
|
||||
return typeOf(variable.getIndex());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public T typeOf(int index) {
|
||||
ensure();
|
||||
return (T) types[index];
|
||||
}
|
||||
|
||||
protected abstract T mapType(ValueType type);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user