From a1a776ea9bdfbc1708bf71c8f6f21db09ea2f1d8 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 30 Jul 2024 17:33:31 +0200 Subject: [PATCH] wasm gc: trying to fix type validation --- .../gc/classes/WasmGCClassGenerator.java | 14 +++++++++----- .../gc/methods/WasmGCGenerationVisitor.java | 14 ++++---------- .../backend/wasm/render/WasmBinaryRenderer.java | 17 +++++++++++++++++ 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java b/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java index c2eb9bda1..b5b0687f5 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCClassGenerator.java @@ -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 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; } diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/gc/methods/WasmGCGenerationVisitor.java b/core/src/main/java/org/teavm/backend/wasm/generate/gc/methods/WasmGCGenerationVisitor.java index 40f715f98..7cb18c269 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/gc/methods/WasmGCGenerationVisitor.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/gc/methods/WasmGCGenerationVisitor.java @@ -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; diff --git a/core/src/main/java/org/teavm/backend/wasm/render/WasmBinaryRenderer.java b/core/src/main/java/org/teavm/backend/wasm/render/WasmBinaryRenderer.java index a591a63eb..a477341c7 100644 --- a/core/src/main/java/org/teavm/backend/wasm/render/WasmBinaryRenderer.java +++ b/core/src/main/java/org/teavm/backend/wasm/render/WasmBinaryRenderer.java @@ -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()); }