wasm gc: trying to fix type validation

This commit is contained in:
Alexey Andreev 2024-07-30 17:33:31 +02:00
parent 87aaa0b452
commit a1a776ea9b
3 changed files with 30 additions and 15 deletions

View File

@ -181,8 +181,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
var name = type instanceof ValueType.Object
? ((ValueType.Object) type).getClassName()
: null;
classInfo.structure = new WasmStructure(name);
classInfo.structure.getFields().add(standardClasses.classClass().getType().asStorage());
classInfo.structure = new WasmStructure(name != null ? names.forClass(name) : null);
module.types.add(classInfo.structure);
fillFields(classInfo.structure.getFields(), type);
}
@ -335,7 +334,9 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
var virtualTable = virtualTables.lookup(className);
var structure = new WasmStructure(names.forClassClass(className));
module.types.add(structure);
fillClassFields(structure.getFields(), "java.lang.Class");
structure.getFields().add(standardClasses.classClass().getType().asStorage());
structure.getFields().add(WasmType.Reference.ANY.asStorage());
fillSimpleClassFields(structure.getFields(), "java.lang.Class");
addVirtualTableFields(structure, virtualTable);
return structure;
}
@ -385,6 +386,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
@Override
public int getFieldIndex(FieldReference fieldRef) {
getClassInfo(fieldRef.getClassName());
var result = fieldIndexes.getOrDefault(fieldRef, -1);
if (result < 0) {
throw new IllegalStateException("Can't get offset of field " + fieldRef);
@ -430,6 +432,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
private void fillFields(List<WasmStorageType> fields, ValueType type) {
fields.add(standardClasses.classClass().getType().asStorage());
fields.add(WasmType.Reference.ANY.asStorage());
if (type instanceof ValueType.Object) {
fillClassFields(fields, ((ValueType.Object) type).getClassName());
} else if (type instanceof ValueType.Array) {
@ -450,10 +453,11 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit
var classReader = classSource.get(className);
if (classReader.getParent() != null) {
fillClassFields(fields, classReader.getParent());
} else {
fields.add(standardClasses.classClass().getType().asStorage());
}
for (var field : classReader.getFields()) {
if (className.equals("java.lang.Object") && field.getName().equals("monitor")) {
continue;
}
if (field.hasModifier(ElementModifier.STATIC)) {
continue;
}

View File

@ -230,18 +230,12 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor {
WasmExpression classRef = new WasmStructGet(instanceStruct, new WasmGetLocal(instance),
WasmGCClassInfoProvider.CLASS_FIELD_OFFSET);
var index = context.classInfoProvider().getVirtualMethodIndex(method);
var vtableType = (WasmType.CompositeReference) instanceStruct.getFields()
.get(WasmGCClassInfoProvider.CLASS_FIELD_OFFSET).asUnpackedType();
var vtableStruct = (WasmStructure) vtableType.composite;
var expectedVtableStruct = context.classInfoProvider().getClassInfo(vtable.getClassName())
var vtableStruct = context.classInfoProvider().getClassInfo(vtable.getClassName())
.getVirtualTableStructure();
if (expectedVtableStruct != vtableStruct) {
classRef = new WasmCast(classRef, expectedVtableStruct.getReference());
}
classRef = new WasmCast(classRef, vtableStruct.getReference());
var functionRef = new WasmStructGet(expectedVtableStruct, classRef, index);
var functionTypeRef = (WasmType.CompositeReference) expectedVtableStruct.getFields()
.get(index).asUnpackedType();
var functionRef = new WasmStructGet(vtableStruct, classRef, index);
var functionTypeRef = (WasmType.CompositeReference) vtableStruct.getFields().get(index).asUnpackedType();
var invoke = new WasmCallReference(functionRef, (WasmFunctionType) functionTypeRef.composite);
invoke.getArguments().addAll(arguments);
return invoke;

View File

@ -440,6 +440,23 @@ public class WasmBinaryRenderer {
section.writeLEB(payload.length);
section.writeBytes(payload);
var types = module.types.stream()
.filter(t -> t.getName() != null)
.collect(Collectors.toList());
if (!types.isEmpty()) {
var typesSubsection = new WasmBinaryWriter();
typesSubsection.writeLEB(types.size());
for (var type : types) {
typesSubsection.writeLEB(module.types.indexOf(type));
typesSubsection.writeAsciiString(type.getName());
}
payload = typesSubsection.getData();
section.writeLEB(4);
section.writeLEB(payload.length);
section.writeBytes(payload);
}
writeSection(SECTION_UNKNOWN, "name", section.getData());
}