mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
wasm gc: add subtyping information to types, fix generation of expressions
This commit is contained in:
parent
a1a776ea9b
commit
5572d4b5d7
|
@ -33,13 +33,11 @@ import org.teavm.model.MethodReference;
|
|||
import org.teavm.model.ValueType;
|
||||
|
||||
public class WasmGCModuleGenerator {
|
||||
private final WasmGCTarget wasmGCTarget;
|
||||
private WasmGCDeclarationsGenerator declarationsGenerator;
|
||||
private WasmFunction initializer;
|
||||
private WasmGlobal initializerRef;
|
||||
|
||||
public WasmGCModuleGenerator(WasmGCTarget wasmGCTarget, WasmGCDeclarationsGenerator declarationsGenerator) {
|
||||
this.wasmGCTarget = wasmGCTarget;
|
||||
public WasmGCModuleGenerator(WasmGCDeclarationsGenerator declarationsGenerator) {
|
||||
this.declarationsGenerator = declarationsGenerator;
|
||||
}
|
||||
|
||||
|
@ -64,8 +62,7 @@ public class WasmGCModuleGenerator {
|
|||
var tempVars = new TemporaryVariablePool(mainFunctionCaller);
|
||||
var genUtil = new WasmGCGenerationUtil(declarationsGenerator.classInfoProvider(), tempVars);
|
||||
var stringArrayType = declarationsGenerator.typeMapper()
|
||||
.mapType(ValueType.parse(String[].class))
|
||||
.asUnpackedType();
|
||||
.mapType(ValueType.parse(String[].class));
|
||||
var arrayVar = tempVars.acquire(stringArrayType);
|
||||
genUtil.allocateArray(ValueType.parse(String.class), new WasmInt32Constant(0), null,
|
||||
arrayVar, mainFunctionCaller.getBody());
|
||||
|
|
|
@ -118,7 +118,7 @@ public class WasmGCTarget implements TeaVMTarget {
|
|||
customGenerators
|
||||
);
|
||||
declarationsGenerator.setFriendlyToDebugger(controller.isFriendlyToDebugger());
|
||||
var moduleGenerator = new WasmGCModuleGenerator(this, declarationsGenerator);
|
||||
var moduleGenerator = new WasmGCModuleGenerator(declarationsGenerator);
|
||||
var mainFunction = moduleGenerator.generateMainFunction(controller.getEntryPoint());
|
||||
mainFunction.setExportName(controller.getEntryPointName());
|
||||
mainFunction.setName(controller.getEntryPointName());
|
||||
|
|
|
@ -761,7 +761,7 @@ public abstract class BaseWasmGenerationVisitor implements StatementVisitor, Exp
|
|||
var callSiteId = generateCallSiteId(expr.getLocation());
|
||||
if (needsCallSiteId() && isManagedCall(expr.getMethod())) {
|
||||
var invocation = generateInvocation(expr, callSiteId);
|
||||
var type = WasmGeneratorUtil.mapType(expr.getMethod().getReturnType());
|
||||
var type = mapType(expr.getMethod().getReturnType());
|
||||
|
||||
List<WasmExpression> targetList;
|
||||
WasmBlock block;
|
||||
|
|
|
@ -182,6 +182,14 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
? ((ValueType.Object) type).getClassName()
|
||||
: null;
|
||||
classInfo.structure = new WasmStructure(name != null ? names.forClass(name) : null);
|
||||
if (name != null) {
|
||||
var classReader = classSource.get(name);
|
||||
if (classReader != null && classReader.getParent() != null) {
|
||||
classInfo.structure.setSupertype(getClassInfo(classReader.getParent()).structure);
|
||||
}
|
||||
} else {
|
||||
classInfo.structure.setSupertype(standardClasses.objectClass().structure);
|
||||
}
|
||||
module.types.add(classInfo.structure);
|
||||
fillFields(classInfo.structure.getFields(), type);
|
||||
}
|
||||
|
@ -318,7 +326,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
call.getArguments().add(new WasmCast(new WasmGetLocal(instanceParam), castTarget));
|
||||
var params = new WasmLocal[method.parameterCount()];
|
||||
for (var i = 0; i < method.parameterCount(); ++i) {
|
||||
params[i] = new WasmLocal(typeMapper.mapType(method.parameterType(i)).asUnpackedType());
|
||||
params[i] = new WasmLocal(typeMapper.mapType(method.parameterType(i)));
|
||||
call.getArguments().add(new WasmGetLocal(params[i]));
|
||||
}
|
||||
wrapperFunction.getLocalVariables().addAll(List.of(params));
|
||||
|
@ -333,6 +341,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
private WasmStructure initRegularClassStructure(String className) {
|
||||
var virtualTable = virtualTables.lookup(className);
|
||||
var structure = new WasmStructure(names.forClassClass(className));
|
||||
structure.setSupertype(standardClasses.classClass().getStructure());
|
||||
module.types.add(structure);
|
||||
structure.getFields().add(standardClasses.classClass().getType().asStorage());
|
||||
structure.getFields().add(WasmType.Reference.ANY.asStorage());
|
||||
|
@ -354,12 +363,12 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
}
|
||||
|
||||
private WasmFunctionType getFunctionType(String className, MethodDescriptor methodDesc) {
|
||||
var returnType = typeMapper.mapType(methodDesc.getResultType()).asUnpackedType();
|
||||
var returnType = typeMapper.mapType(methodDesc.getResultType());
|
||||
var javaParamTypes = methodDesc.getParameterTypes();
|
||||
var paramTypes = new WasmType[javaParamTypes.length + 1];
|
||||
paramTypes[0] = getClassInfo(className).getType();
|
||||
for (var i = 0; i < javaParamTypes.length; ++i) {
|
||||
paramTypes[i + 1] = typeMapper.mapType(javaParamTypes[i]).asUnpackedType();
|
||||
paramTypes[i + 1] = typeMapper.mapType(javaParamTypes[i]);
|
||||
}
|
||||
return functionTypes.of(returnType, paramTypes);
|
||||
}
|
||||
|
@ -414,7 +423,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
javaType = ValueType.object("java.lang.Object");
|
||||
}
|
||||
|
||||
var type = typeMapper.mapType(javaType).asUnpackedType();
|
||||
var type = typeMapper.mapType(javaType);
|
||||
var global = new WasmGlobal(names.forStaticField(fieldRef), type, WasmExpression.defaultValueOfType(type));
|
||||
module.globals.add(global);
|
||||
|
||||
|
@ -462,7 +471,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
continue;
|
||||
}
|
||||
fieldIndexes.putIfAbsent(field.getReference(), fields.size());
|
||||
fields.add(typeMapper.mapType(field.getType()));
|
||||
fields.add(typeMapper.mapStorageType(field.getType()));
|
||||
}
|
||||
if (className.equals("java.lang.Class")) {
|
||||
classFlagsOffset = fields.size();
|
||||
|
@ -483,7 +492,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
|
|||
}
|
||||
|
||||
private void fillArrayField(List<WasmStorageType> fields, ValueType elementType) {
|
||||
var wasmArray = new WasmArray(null, () -> typeMapper.mapType(elementType));
|
||||
var wasmArray = new WasmArray(null, () -> typeMapper.mapStorageType(elementType));
|
||||
module.types.add(wasmArray);
|
||||
fields.add(wasmArray.getReference().asStorage());
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ public class WasmGCTypeMapper {
|
|||
this.classInfoProvider = classInfoProvider;
|
||||
}
|
||||
|
||||
public WasmStorageType mapType(ValueType type) {
|
||||
public WasmStorageType mapStorageType(ValueType type) {
|
||||
if (type instanceof ValueType.Primitive) {
|
||||
switch (((ValueType.Primitive) type).getKind()) {
|
||||
case BYTE:
|
||||
|
@ -51,4 +51,29 @@ public class WasmGCTypeMapper {
|
|||
return classInfoProvider.getClassInfo(type).getType().asStorage();
|
||||
}
|
||||
}
|
||||
|
||||
public WasmType mapType(ValueType type) {
|
||||
if (type instanceof ValueType.Primitive) {
|
||||
switch (((ValueType.Primitive) type).getKind()) {
|
||||
case BYTE:
|
||||
case BOOLEAN:
|
||||
case SHORT:
|
||||
case CHARACTER:
|
||||
case INTEGER:
|
||||
return WasmType.INT32;
|
||||
case LONG:
|
||||
return WasmType.INT64;
|
||||
case FLOAT:
|
||||
return WasmType.FLOAT32;
|
||||
case DOUBLE:
|
||||
return WasmType.FLOAT64;
|
||||
default:
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
} else if (type instanceof ValueType.Void) {
|
||||
return null;
|
||||
} else {
|
||||
return classInfoProvider.getClassInfo(type).getType();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -334,7 +334,7 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
|
|||
|
||||
@Override
|
||||
protected WasmType mapType(ValueType type) {
|
||||
return context.typeMapper().mapType(type).asUnpackedType();
|
||||
return context.typeMapper().mapType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -139,10 +139,10 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
|
|||
}
|
||||
|
||||
private WasmFunction createStaticFunction(MethodReference methodReference) {
|
||||
var returnType = typeMapper.mapType(methodReference.getReturnType()).asUnpackedType();
|
||||
var returnType = typeMapper.mapType(methodReference.getReturnType());
|
||||
var parameterTypes = new WasmType[methodReference.parameterCount()];
|
||||
for (var i = 0; i < parameterTypes.length; ++i) {
|
||||
parameterTypes[i] = typeMapper.mapType(methodReference.parameterType(i)).asUnpackedType();
|
||||
parameterTypes[i] = typeMapper.mapType(methodReference.parameterType(i));
|
||||
}
|
||||
var function = new WasmFunction(functionTypes.of(returnType, parameterTypes));
|
||||
function.setName(names.forMethod(methodReference));
|
||||
|
@ -166,11 +166,11 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
|
|||
}
|
||||
|
||||
private WasmFunction createInstanceFunction(MethodReference methodReference) {
|
||||
var returnType = typeMapper.mapType(methodReference.getReturnType()).asUnpackedType();
|
||||
var returnType = typeMapper.mapType(methodReference.getReturnType());
|
||||
var parameterTypes = new WasmType[methodReference.parameterCount() + 1];
|
||||
parameterTypes[0] = typeMapper.mapType(ValueType.object(methodReference.getClassName())).asUnpackedType();
|
||||
parameterTypes[0] = typeMapper.mapType(ValueType.object(methodReference.getClassName()));
|
||||
for (var i = 0; i < methodReference.parameterCount(); ++i) {
|
||||
parameterTypes[i + 1] = typeMapper.mapType(methodReference.parameterType(i)).asUnpackedType();
|
||||
parameterTypes[i + 1] = typeMapper.mapType(methodReference.parameterType(i));
|
||||
}
|
||||
var function = new WasmFunction(functionTypes.of(returnType, parameterTypes));
|
||||
function.setName(names.forMethod(methodReference));
|
||||
|
@ -236,7 +236,7 @@ public class WasmGCMethodGenerator implements BaseWasmFunctionRepository {
|
|||
for (var i = firstVar; i < ast.getVariables().size(); ++i) {
|
||||
var localVar = ast.getVariables().get(i);
|
||||
var representative = method.getProgram().variableAt(variableRepresentatives[i]);
|
||||
var type = typeMapper.mapType(typeInference.typeOf(representative)).asUnpackedType();
|
||||
var type = typeMapper.mapType(typeInference.typeOf(representative));
|
||||
var wasmLocal = new WasmLocal(type, localVar.getName());
|
||||
function.add(wasmLocal);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.List;
|
|||
|
||||
public class WasmStructure extends WasmCompositeType {
|
||||
private List<WasmStorageType> fields = new ArrayList<>();
|
||||
private WasmStructure supertype;
|
||||
|
||||
public WasmStructure(String name) {
|
||||
super(name);
|
||||
|
@ -29,6 +30,14 @@ public class WasmStructure extends WasmCompositeType {
|
|||
return fields;
|
||||
}
|
||||
|
||||
public WasmStructure getSupertype() {
|
||||
return supertype;
|
||||
}
|
||||
|
||||
public void setSupertype(WasmStructure supertype) {
|
||||
this.supertype = supertype;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptVisitor(WasmCompositeTypeVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
|
|
|
@ -42,6 +42,9 @@ final class WasmTypeGraphBuilder {
|
|||
|
||||
@Override
|
||||
public void visit(WasmStructure type) {
|
||||
if (type.getSupertype() != null) {
|
||||
addEdge(type.getSupertype().getReference());
|
||||
}
|
||||
for (var field : type.getFields()) {
|
||||
addEdge(field.asUnpackedType());
|
||||
}
|
||||
|
|
|
@ -1042,7 +1042,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
}
|
||||
writer.writeByte(0xfb);
|
||||
writer.writeByte(0);
|
||||
writer.writeInt32(module.types.indexOf(expression.getType()));
|
||||
writer.writeLEB(module.types.indexOf(expression.getType()));
|
||||
popLocation();
|
||||
}
|
||||
|
||||
|
@ -1051,7 +1051,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
pushLocation(expression);
|
||||
writer.writeByte(0xfb);
|
||||
writer.writeByte(1);
|
||||
writer.writeInt32(module.types.indexOf(expression.getType()));
|
||||
writer.writeLEB(module.types.indexOf(expression.getType()));
|
||||
popLocation();
|
||||
}
|
||||
|
||||
|
@ -1072,8 +1072,8 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
break;
|
||||
}
|
||||
}
|
||||
writer.writeInt32(module.types.indexOf(expression.getType()));
|
||||
writer.writeInt32(expression.getFieldIndex());
|
||||
writer.writeLEB(module.types.indexOf(expression.getType()));
|
||||
writer.writeLEB(expression.getFieldIndex());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
|
@ -1084,8 +1084,8 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
expression.getValue().acceptVisitor(this);
|
||||
writer.writeByte(0xfb);
|
||||
writer.writeByte(5);
|
||||
writer.writeInt32(module.types.indexOf(expression.getType()));
|
||||
writer.writeInt32(expression.getFieldIndex());
|
||||
writer.writeLEB(module.types.indexOf(expression.getType()));
|
||||
writer.writeLEB(expression.getFieldIndex());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
|
@ -1095,7 +1095,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
expression.getLength().acceptVisitor(this);
|
||||
writer.writeByte(0xfb);
|
||||
writer.writeByte(7);
|
||||
writer.writeInt32(module.types.indexOf(expression.getType()));
|
||||
writer.writeLEB(module.types.indexOf(expression.getType()));
|
||||
popLocation();
|
||||
}
|
||||
|
||||
|
@ -1117,7 +1117,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
break;
|
||||
}
|
||||
}
|
||||
writer.writeInt32(module.types.indexOf(expression.getType()));
|
||||
writer.writeLEB(module.types.indexOf(expression.getType()));
|
||||
popLocation();
|
||||
}
|
||||
|
||||
|
@ -1129,7 +1129,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
expression.getValue().acceptVisitor(this);
|
||||
writer.writeByte(0xfb);
|
||||
writer.writeByte(14);
|
||||
writer.writeInt32(module.types.indexOf(expression.getType()));
|
||||
writer.writeLEB(module.types.indexOf(expression.getType()));
|
||||
popLocation();
|
||||
}
|
||||
|
||||
|
|
|
@ -30,10 +30,6 @@ public class WasmBinaryWriter {
|
|||
}
|
||||
|
||||
public void writeType(WasmType type, WasmModule module) {
|
||||
writeType(type, module, false);
|
||||
}
|
||||
|
||||
public void writeType(WasmType type, WasmModule module, boolean isRecursiveMember) {
|
||||
if (type == null) {
|
||||
writeByte(0x40);
|
||||
return;
|
||||
|
|
|
@ -25,7 +25,6 @@ import org.teavm.backend.wasm.model.WasmStructure;
|
|||
public class WasmCompositeTypeBinaryRenderer implements WasmCompositeTypeVisitor {
|
||||
private WasmModule module;
|
||||
private WasmBinaryWriter section;
|
||||
private boolean reference;
|
||||
|
||||
public WasmCompositeTypeBinaryRenderer(WasmModule module, WasmBinaryWriter section) {
|
||||
this.module = module;
|
||||
|
@ -34,6 +33,13 @@ public class WasmCompositeTypeBinaryRenderer implements WasmCompositeTypeVisitor
|
|||
|
||||
@Override
|
||||
public void visit(WasmStructure type) {
|
||||
section.writeByte(0x50);
|
||||
if (type.getSupertype() != null) {
|
||||
section.writeLEB(1); // number of supertypes
|
||||
section.writeLEB(module.types.indexOf(type.getSupertype()));
|
||||
} else {
|
||||
section.writeLEB(0);
|
||||
}
|
||||
section.writeByte(0x5F);
|
||||
section.writeLEB(type.getFields().size());
|
||||
for (var fieldType : type.getFields()) {
|
||||
|
@ -75,7 +81,7 @@ public class WasmCompositeTypeBinaryRenderer implements WasmCompositeTypeVisitor
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
section.writeType(storageType.asUnpackedType(), module, true);
|
||||
section.writeType(storageType.asUnpackedType(), module);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user