mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: fix issues with casts
This commit is contained in:
parent
7e622d8bc7
commit
7784969bb8
|
@ -121,9 +121,15 @@ public class WasmGCTarget implements TeaVMTarget, TeaVMWasmGCHost {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeOptimizations(Program program, MethodReader method) {
|
public void beforeInlining(Program program, MethodReader method) {
|
||||||
if (strict) {
|
if (strict) {
|
||||||
nullCheckInsertion.transformProgram(program, method.getReference());
|
nullCheckInsertion.transformProgram(program, method.getReference());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeOptimizations(Program program, MethodReader method) {
|
||||||
|
if (strict) {
|
||||||
boundCheckInsertion.transformProgram(program, method.getReference());
|
boundCheckInsertion.transformProgram(program, method.getReference());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -782,7 +782,7 @@ public class DisassemblyCodeListener extends BaseDisassemblyListener implements
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cast(WasmHollowType.Reference type) {
|
public void cast(WasmHollowType.Reference type) {
|
||||||
writer.address().write("ref.cast (ref ");
|
writer.address().write("ref.cast ");
|
||||||
writeType(type);
|
writeType(type);
|
||||||
writer.eol();
|
writer.eol();
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,21 +164,6 @@ public class WasmGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
super.visit(expr);
|
super.visit(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected WasmExpression generateCast(WasmExpression value, WasmType targetType) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected WasmType mapCastSourceType(WasmType type) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean validateCastTypes(WasmType sourceType, WasmType targetType, TextLocation location) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected WasmType mapType(ValueType type) {
|
protected WasmType mapType(ValueType type) {
|
||||||
return WasmGeneratorUtil.mapType(type);
|
return WasmGeneratorUtil.mapType(type);
|
||||||
|
|
|
@ -1186,19 +1186,13 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
public void visit(CastExpr expr) {
|
public void visit(CastExpr expr) {
|
||||||
var wasmTargetType = mapType(expr.getTarget());
|
var wasmTargetType = mapType(expr.getTarget());
|
||||||
acceptWithType(expr.getValue(), expr.getTarget());
|
acceptWithType(expr.getValue(), expr.getTarget());
|
||||||
|
result.acceptVisitor(typeInference);
|
||||||
|
var wasmSourceType = typeInference.getResult();
|
||||||
if (!expr.isWeak()) {
|
if (!expr.isWeak()) {
|
||||||
result.acceptVisitor(typeInference);
|
|
||||||
var wasmSourceType = typeInference.getResult();
|
|
||||||
if (wasmSourceType == null) {
|
if (wasmSourceType == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wasmSourceType = mapCastSourceType(wasmSourceType);
|
|
||||||
|
|
||||||
if (!validateCastTypes(wasmSourceType, wasmTargetType, expr.getLocation())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var block = new WasmBlock(false);
|
var block = new WasmBlock(false);
|
||||||
block.setType(wasmSourceType);
|
block.setType(wasmSourceType);
|
||||||
block.setLocation(expr.getLocation());
|
block.setLocation(expr.getLocation());
|
||||||
|
@ -1223,16 +1217,9 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
||||||
valueToCast.release();
|
valueToCast.release();
|
||||||
result = block;
|
result = block;
|
||||||
}
|
}
|
||||||
result = generateCast(result, wasmTargetType);
|
|
||||||
result.setLocation(expr.getLocation());
|
result.setLocation(expr.getLocation());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract WasmType mapCastSourceType(WasmType type);
|
|
||||||
|
|
||||||
protected abstract boolean validateCastTypes(WasmType sourceType, WasmType targetType, TextLocation location);
|
|
||||||
|
|
||||||
protected abstract WasmExpression generateCast(WasmExpression value, WasmType targetType);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(InitClassStatement statement) {
|
public void visit(InitClassStatement statement) {
|
||||||
if (needsClassInitializer(statement.getClassName())) {
|
if (needsClassInitializer(statement.getClassName())) {
|
||||||
|
|
|
@ -108,7 +108,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
private WasmGCVirtualTableProvider virtualTables;
|
private WasmGCVirtualTableProvider virtualTables;
|
||||||
private BaseWasmFunctionRepository functionProvider;
|
private BaseWasmFunctionRepository functionProvider;
|
||||||
private Map<ValueType, WasmGCClassInfo> classInfoMap = new LinkedHashMap<>();
|
private Map<ValueType, WasmGCClassInfo> classInfoMap = new LinkedHashMap<>();
|
||||||
private Queue<WasmGCClassInfo> classInfoQueue = new ArrayDeque<>();
|
private Queue<Runnable> queue = new ArrayDeque<>();
|
||||||
private ObjectIntMap<FieldReference> fieldIndexes = new ObjectIntHashMap<>();
|
private ObjectIntMap<FieldReference> fieldIndexes = new ObjectIntHashMap<>();
|
||||||
private Map<FieldReference, WasmGlobal> staticFieldLocations = new HashMap<>();
|
private Map<FieldReference, WasmGlobal> staticFieldLocations = new HashMap<>();
|
||||||
private List<Consumer<WasmFunction>> staticFieldInitializers = new ArrayList<>();
|
private List<Consumer<WasmFunction>> staticFieldInitializers = new ArrayList<>();
|
||||||
|
@ -171,7 +171,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
standardClasses = new WasmGCStandardClasses(this);
|
standardClasses = new WasmGCStandardClasses(this);
|
||||||
strings = new WasmGCStringPool(standardClasses, module, functionProvider, names, functionTypes);
|
strings = new WasmGCStringPool(standardClasses, module, functionProvider, names, functionTypes);
|
||||||
supertypeGenerator = new WasmGCSupertypeFunctionGenerator(module, this, names, tagRegistry, functionTypes);
|
supertypeGenerator = new WasmGCSupertypeFunctionGenerator(module, this, names, tagRegistry, functionTypes);
|
||||||
newArrayGenerator = new WasmGCNewArrayFunctionGenerator(module, functionTypes, this, names);
|
newArrayGenerator = new WasmGCNewArrayFunctionGenerator(module, functionTypes, this, names, queue);
|
||||||
typeMapper = new WasmGCTypeMapper(classSource, this, functionTypes, module);
|
typeMapper = new WasmGCTypeMapper(classSource, this, functionTypes, module);
|
||||||
var customTypeMapperFactoryContext = customTypeMapperFactoryContext();
|
var customTypeMapperFactoryContext = customTypeMapperFactoryContext();
|
||||||
typeMapper.setCustomTypeMappers(customTypeMapperFactories.stream()
|
typeMapper.setCustomTypeMappers(customTypeMapperFactories.stream()
|
||||||
|
@ -213,13 +213,12 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean process() {
|
public boolean process() {
|
||||||
if (classInfoQueue.isEmpty()) {
|
if (queue.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
while (!classInfoQueue.isEmpty()) {
|
while (!queue.isEmpty()) {
|
||||||
var classInfo = classInfoQueue.remove();
|
var action = queue.remove();
|
||||||
classInfo.initializer.accept(initializerFunctionStatements);
|
action.run();
|
||||||
classInfo.initializer = null;
|
|
||||||
initStructures();
|
initStructures();
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -245,20 +244,13 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
function.getBody().addAll(initializerFunctionStatements);
|
function.getBody().addAll(initializerFunctionStatements);
|
||||||
initializerFunctionStatements.clear();
|
initializerFunctionStatements.clear();
|
||||||
for (var classInfo : classInfoMap.values()) {
|
for (var classInfo : classInfoMap.values()) {
|
||||||
var req = metadataRequirements.getInfo(classInfo.getValueType());
|
if (classInfo.supertypeFunction != null) {
|
||||||
if (req != null) {
|
function.getBody().add(setClassField(classInfo, classSupertypeFunctionOffset,
|
||||||
if (req.isAssignable()) {
|
new WasmFunctionReference(classInfo.supertypeFunction)));
|
||||||
var supertypeFunction = supertypeGenerator.getIsSupertypeFunction(classInfo.getValueType());
|
}
|
||||||
supertypeFunction.setReferenced(true);
|
if (classInfo.initArrayFunction != null) {
|
||||||
function.getBody().add(setClassField(classInfo, classSupertypeFunctionOffset,
|
function.getBody().add(setClassField(classInfo, classNewArrayOffset,
|
||||||
new WasmFunctionReference(supertypeFunction)));
|
new WasmFunctionReference(classInfo.initArrayFunction)));
|
||||||
}
|
|
||||||
if (req.newArray()) {
|
|
||||||
var newArrayFunction = getArrayConstructor(ValueType.arrayOf(classInfo.getValueType()));
|
|
||||||
newArrayFunction.setReferenced(true);
|
|
||||||
function.getBody().add(setClassField(classInfo, classNewArrayOffset,
|
|
||||||
new WasmFunctionReference(newArrayFunction)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (var consumer : staticFieldInitializers) {
|
for (var consumer : staticFieldInitializers) {
|
||||||
|
@ -271,7 +263,11 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
var classInfo = classInfoMap.get(type);
|
var classInfo = classInfoMap.get(type);
|
||||||
if (classInfo == null) {
|
if (classInfo == null) {
|
||||||
classInfo = new WasmGCClassInfo(type);
|
classInfo = new WasmGCClassInfo(type);
|
||||||
classInfoQueue.add(classInfo);
|
var finalClassInfo = classInfo;
|
||||||
|
queue.add(() -> {
|
||||||
|
finalClassInfo.initializer.accept(initializerFunctionStatements);
|
||||||
|
finalClassInfo.initializer = null;
|
||||||
|
});
|
||||||
classInfoMap.put(type, classInfo);
|
classInfoMap.put(type, classInfo);
|
||||||
WasmGCVirtualTable virtualTable = null;
|
WasmGCVirtualTable virtualTable = null;
|
||||||
if (!(type instanceof ValueType.Primitive)) {
|
if (!(type instanceof ValueType.Primitive)) {
|
||||||
|
@ -284,7 +280,6 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
isInterface = true;
|
isInterface = true;
|
||||||
classInfo.structure = standardClasses.objectClass().structure;
|
classInfo.structure = standardClasses.objectClass().structure;
|
||||||
} else {
|
} else {
|
||||||
var finalClassInfo = classInfo;
|
|
||||||
if (type instanceof ValueType.Array) {
|
if (type instanceof ValueType.Array) {
|
||||||
var itemType = ((ValueType.Array) type).getItemType();
|
var itemType = ((ValueType.Array) type).getItemType();
|
||||||
if (!(itemType instanceof ValueType.Primitive) && !itemType.equals(OBJECT_TYPE)) {
|
if (!(itemType instanceof ValueType.Primitive) && !itemType.equals(OBJECT_TYPE)) {
|
||||||
|
@ -346,6 +341,18 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
} else if (type instanceof ValueType.Object) {
|
} else if (type instanceof ValueType.Object) {
|
||||||
initRegularClass(classInfo, virtualTable, classStructure, ((ValueType.Object) type).getClassName());
|
initRegularClass(classInfo, virtualTable, classStructure, ((ValueType.Object) type).getClassName());
|
||||||
}
|
}
|
||||||
|
var req = metadataRequirements.getInfo(type);
|
||||||
|
if (req != null) {
|
||||||
|
if (req.newArray()) {
|
||||||
|
classInfo.initArrayFunction = getArrayConstructor(ValueType.arrayOf(classInfo.getValueType()));
|
||||||
|
classInfo.initArrayFunction.setReferenced(true);
|
||||||
|
}
|
||||||
|
if (req.isAssignable()) {
|
||||||
|
var supertypeFunction = supertypeGenerator.getIsSupertypeFunction(classInfo.getValueType());
|
||||||
|
supertypeFunction.setReferenced(true);
|
||||||
|
classInfo.supertypeFunction = supertypeFunction;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return classInfo;
|
return classInfo;
|
||||||
}
|
}
|
||||||
|
@ -490,6 +497,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
||||||
private void initRegularClass(WasmGCClassInfo classInfo, WasmGCVirtualTable virtualTable,
|
private void initRegularClass(WasmGCClassInfo classInfo, WasmGCVirtualTable virtualTable,
|
||||||
WasmStructure classStructure, String name) {
|
WasmStructure classStructure, String name) {
|
||||||
var cls = classSource.get(name);
|
var cls = classSource.get(name);
|
||||||
|
|
||||||
if (classInitializerInfo.isDynamicInitializer(name)) {
|
if (classInitializerInfo.isDynamicInitializer(name)) {
|
||||||
if (cls != null && cls.getMethod(CLINIT_METHOD_DESC) != null) {
|
if (cls != null && cls.getMethod(CLINIT_METHOD_DESC) != null) {
|
||||||
var clinitType = functionTypes.of(null);
|
var clinitType = functionTypes.of(null);
|
||||||
|
|
|
@ -33,6 +33,8 @@ public class WasmGCClassInfo {
|
||||||
WasmGlobal initializerPointer;
|
WasmGlobal initializerPointer;
|
||||||
Consumer<List<WasmExpression>> initializer;
|
Consumer<List<WasmExpression>> initializer;
|
||||||
WasmFunction newArrayFunction;
|
WasmFunction newArrayFunction;
|
||||||
|
WasmFunction initArrayFunction;
|
||||||
|
WasmFunction supertypeFunction;
|
||||||
|
|
||||||
WasmGCClassInfo(ValueType valueType) {
|
WasmGCClassInfo(ValueType valueType) {
|
||||||
this.valueType = valueType;
|
this.valueType = valueType;
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
package org.teavm.backend.wasm.generate.gc.classes;
|
package org.teavm.backend.wasm.generate.gc.classes;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Queue;
|
||||||
import org.teavm.backend.wasm.WasmFunctionTypes;
|
import org.teavm.backend.wasm.WasmFunctionTypes;
|
||||||
import org.teavm.backend.wasm.generate.TemporaryVariablePool;
|
import org.teavm.backend.wasm.generate.TemporaryVariablePool;
|
||||||
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
|
import org.teavm.backend.wasm.generate.gc.WasmGCNameProvider;
|
||||||
|
@ -35,13 +36,16 @@ class WasmGCNewArrayFunctionGenerator {
|
||||||
private WasmGCClassInfoProvider classInfoProvider;
|
private WasmGCClassInfoProvider classInfoProvider;
|
||||||
private WasmFunctionType newArrayFunctionType;
|
private WasmFunctionType newArrayFunctionType;
|
||||||
private WasmGCNameProvider names;
|
private WasmGCNameProvider names;
|
||||||
|
private Queue<Runnable> queue;
|
||||||
|
|
||||||
WasmGCNewArrayFunctionGenerator(WasmModule module, WasmFunctionTypes functionTypes,
|
WasmGCNewArrayFunctionGenerator(WasmModule module, WasmFunctionTypes functionTypes,
|
||||||
WasmGCClassInfoProvider classInfoProvider, WasmGCNameProvider names) {
|
WasmGCClassInfoProvider classInfoProvider, WasmGCNameProvider names,
|
||||||
|
Queue<Runnable> queue) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
this.functionTypes = functionTypes;
|
this.functionTypes = functionTypes;
|
||||||
this.classInfoProvider = classInfoProvider;
|
this.classInfoProvider = classInfoProvider;
|
||||||
this.names = names;
|
this.names = names;
|
||||||
|
this.queue = queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
WasmFunction generateNewArrayFunction(ValueType itemType) {
|
WasmFunction generateNewArrayFunction(ValueType itemType) {
|
||||||
|
@ -53,14 +57,17 @@ class WasmGCNewArrayFunctionGenerator {
|
||||||
var function = new WasmFunction(functionType);
|
var function = new WasmFunction(functionType);
|
||||||
function.setName(names.topLevel("Array<" + names.suggestForType(itemType) + ">@new"));
|
function.setName(names.topLevel("Array<" + names.suggestForType(itemType) + ">@new"));
|
||||||
module.functions.add(function);
|
module.functions.add(function);
|
||||||
var sizeLocal = new WasmLocal(WasmType.INT32, "length");
|
|
||||||
function.add(sizeLocal);
|
queue.add(() -> {
|
||||||
var tempVars = new TemporaryVariablePool(function);
|
var sizeLocal = new WasmLocal(WasmType.INT32, "length");
|
||||||
var genUtil = new WasmGCGenerationUtil(classInfoProvider, tempVars);
|
function.add(sizeLocal);
|
||||||
var targetVar = new WasmLocal(classInfo.getType(), "result");
|
var tempVars = new TemporaryVariablePool(function);
|
||||||
function.add(targetVar);
|
var genUtil = new WasmGCGenerationUtil(classInfoProvider, tempVars);
|
||||||
genUtil.allocateArray(itemType, () -> new WasmGetLocal(sizeLocal), null, targetVar, function.getBody());
|
var targetVar = new WasmLocal(classInfo.getType(), "result");
|
||||||
function.getBody().add(new WasmReturn(new WasmGetLocal(targetVar)));
|
function.add(targetVar);
|
||||||
|
genUtil.allocateArray(itemType, () -> new WasmGetLocal(sizeLocal), null, targetVar, function.getBody());
|
||||||
|
function.getBody().add(new WasmReturn(new WasmGetLocal(targetVar)));
|
||||||
|
});
|
||||||
return function;
|
return function;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@ import org.teavm.backend.wasm.model.expression.WasmArrayGet;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmArrayLength;
|
import org.teavm.backend.wasm.model.expression.WasmArrayLength;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmArraySet;
|
import org.teavm.backend.wasm.model.expression.WasmArraySet;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmBlock;
|
import org.teavm.backend.wasm.model.expression.WasmBlock;
|
||||||
|
import org.teavm.backend.wasm.model.expression.WasmBranch;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmCall;
|
import org.teavm.backend.wasm.model.expression.WasmCall;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmCallReference;
|
import org.teavm.backend.wasm.model.expression.WasmCallReference;
|
||||||
import org.teavm.backend.wasm.model.expression.WasmCast;
|
import org.teavm.backend.wasm.model.expression.WasmCast;
|
||||||
|
@ -443,26 +444,76 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(CastExpr expr) {
|
public void visit(CastExpr expr) {
|
||||||
var type = expr.getTarget();
|
var needsCast = true;
|
||||||
if (!expr.isWeak() && canCastNatively(type)) {
|
acceptWithType(expr.getValue(), expr.getTarget());
|
||||||
var wasmType = context.classInfoProvider().getClassInfo(type).getType();
|
result.acceptVisitor(typeInference);
|
||||||
var block = new WasmBlock(false);
|
var sourceType = (WasmType.Reference) typeInference.getResult();
|
||||||
acceptWithType(expr.getValue(), type);
|
if (sourceType == null) {
|
||||||
var wasmValue = result;
|
return;
|
||||||
result.acceptVisitor(typeInference);
|
}
|
||||||
var sourceWasmType = (WasmType.Reference) typeInference.getResult();
|
|
||||||
if (sourceWasmType == null || !validateCastTypes(sourceWasmType, wasmType, expr.getLocation())) {
|
var targetType = (WasmType.Reference) context.typeMapper().mapType(expr.getTarget());
|
||||||
|
WasmStructure targetStruct = null;
|
||||||
|
if (targetType instanceof WasmType.CompositeReference) {
|
||||||
|
var targetComposite = ((WasmType.CompositeReference) targetType).composite;
|
||||||
|
if (targetComposite instanceof WasmStructure) {
|
||||||
|
targetStruct = (WasmStructure) targetComposite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var canInsertCast = true;
|
||||||
|
if (targetStruct != null && sourceType instanceof WasmType.CompositeReference) {
|
||||||
|
var sourceComposite = (WasmType.CompositeReference) sourceType;
|
||||||
|
if (!sourceType.isNullable()) {
|
||||||
|
sourceType = sourceComposite.composite.getReference();
|
||||||
|
}
|
||||||
|
var sourceStruct = (WasmStructure) sourceComposite.composite;
|
||||||
|
if (targetStruct.isSupertypeOf(sourceStruct)) {
|
||||||
|
canInsertCast = false;
|
||||||
|
} else if (!sourceStruct.isSupertypeOf(targetStruct)) {
|
||||||
|
var block = new WasmBlock(false);
|
||||||
|
block.setLocation(expr.getLocation());
|
||||||
|
block.getBody().add(result);
|
||||||
|
block.getBody().add(new WasmUnreachable());
|
||||||
|
result = block;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
block.setType(wasmType);
|
if (!expr.isWeak()) {
|
||||||
|
result.acceptVisitor(typeInference);
|
||||||
|
|
||||||
|
var block = new WasmBlock(false);
|
||||||
block.setLocation(expr.getLocation());
|
block.setLocation(expr.getLocation());
|
||||||
block.getBody().add(new WasmCastBranch(WasmCastCondition.SUCCESS, wasmValue, sourceWasmType,
|
block.setType(targetType);
|
||||||
wasmType, block));
|
if (canCastNatively(expr.getTarget())) {
|
||||||
|
if (!canInsertCast) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
block.getBody().add(new WasmCastBranch(WasmCastCondition.SUCCESS, result, sourceType,
|
||||||
|
targetType, block));
|
||||||
|
result = block;
|
||||||
|
} else {
|
||||||
|
var nonNullValue = new WasmNullBranch(WasmNullCondition.NULL, result, block);
|
||||||
|
nonNullValue.setResult(new WasmNullConstant(sourceType));
|
||||||
|
var valueToCast = exprCache.create(nonNullValue, sourceType, expr.getLocation(), block.getBody());
|
||||||
|
|
||||||
|
var supertypeCall = generateInstanceOf(valueToCast.expr(), expr.getTarget());
|
||||||
|
var breakIfPassed = new WasmBranch(supertypeCall, block);
|
||||||
|
breakIfPassed.setResult(valueToCast.expr());
|
||||||
|
block.getBody().add(new WasmDrop(breakIfPassed));
|
||||||
|
|
||||||
|
result = block;
|
||||||
|
if (canInsertCast) {
|
||||||
|
var cast = new WasmCast(result, targetType);
|
||||||
|
cast.setLocation(expr.getLocation());
|
||||||
|
result = cast;
|
||||||
|
}
|
||||||
|
}
|
||||||
generateThrowCCE(expr.getLocation(), block.getBody());
|
generateThrowCCE(expr.getLocation(), block.getBody());
|
||||||
result = block;
|
} else if (canInsertCast) {
|
||||||
} else {
|
result = new WasmCast(result, targetType);
|
||||||
super.visit(expr);
|
result.setLocation(expr.getLocation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -478,44 +529,6 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
||||||
return !cls.hasModifier(ElementModifier.INTERFACE);
|
return !cls.hasModifier(ElementModifier.INTERFACE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected WasmExpression generateCast(WasmExpression value, WasmType targetType) {
|
|
||||||
return new WasmCast(value, (WasmType.Reference) targetType);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected WasmType mapCastSourceType(WasmType type) {
|
|
||||||
if (!(type instanceof WasmType.CompositeReference)) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
var refType = (WasmType.CompositeReference) type;
|
|
||||||
return refType.isNullable() ? refType : refType.composite.getReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected boolean validateCastTypes(WasmType sourceType, WasmType targetType, TextLocation location) {
|
|
||||||
if (!(sourceType instanceof WasmType.CompositeReference)
|
|
||||||
|| !(targetType instanceof WasmType.CompositeReference)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
var sourceRefType = (WasmType.CompositeReference) sourceType;
|
|
||||||
var targetRefType = (WasmType.CompositeReference) targetType;
|
|
||||||
if (sourceRefType.composite instanceof WasmStructure
|
|
||||||
&& targetRefType.composite instanceof WasmStructure) {
|
|
||||||
var sourceStruct = (WasmStructure) sourceRefType.composite;
|
|
||||||
var targetStruct = (WasmStructure) targetRefType.composite;
|
|
||||||
if (targetStruct.isSupertypeOf(sourceStruct)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!sourceStruct.isSupertypeOf(targetStruct)) {
|
|
||||||
result = new WasmUnreachable();
|
|
||||||
result.setLocation(location);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean needsClassInitializer(String className) {
|
protected boolean needsClassInitializer(String className) {
|
||||||
return context.classInfoProvider().getClassInfo(className).getInitializerPointer() != null;
|
return context.classInfoProvider().getClassInfo(className).getInitializerPointer() != null;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user