From f8022f94656cc39d9dd7f1fc193af2a71f8daf4b Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 23 Sep 2024 20:23:24 +0200 Subject: [PATCH] wasm gc: fix issues in Java 17 switch expression and metaprogramming API --- .../gc/classes/WasmGCClassGenerator.java | 16 +++++----- .../gc/methods/WasmGCGenerationVisitor.java | 5 ++-- .../impl/CompositeMethodGenerator.java | 30 +++++++++++++++++-- 3 files changed, 39 insertions(+), 12 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 30a5a3da9..1e93c731b 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 @@ -134,7 +134,7 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit private int classNameOffset; private int classSimpleNameOffset; private int classCanonicalNameOffset; - private int classParentOffset; + private int classParentOffset = -1; private int classArrayOffset; private int classArrayItemOffset; private int classNewArrayOffset; @@ -1438,12 +1438,14 @@ public class WasmGCClassGenerator implements WasmGCClassInfoProvider, WasmGCInit classTagOffset, new WasmInt32Constant(0) )); - function.getBody().add(new WasmStructSet( - standardClasses.classClass().getStructure(), - new WasmGetLocal(targetVar), - classParentOffset, - new WasmGetGlobal(standardClasses.objectClass().pointer) - )); + if (classParentOffset >= 0) { + function.getBody().add(new WasmStructSet( + standardClasses.classClass().getStructure(), + new WasmGetLocal(targetVar), + classParentOffset, + new WasmGetGlobal(standardClasses.objectClass().pointer) + )); + } return function; } 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 e38951336..a89594ce0 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 @@ -480,9 +480,10 @@ public class WasmGCGenerationVisitor extends BaseWasmGenerationVisitor { canInsertCast = false; } else if (!sourceStruct.isSupertypeOf(targetStruct)) { var block = new WasmBlock(false); + block.setType(targetType); block.setLocation(expr.getLocation()); - block.getBody().add(result); - block.getBody().add(new WasmUnreachable()); + block.getBody().add(new WasmDrop(result)); + block.getBody().add(new WasmNullConstant(targetType)); result = block; return; } diff --git a/metaprogramming/impl/src/main/java/org/teavm/metaprogramming/impl/CompositeMethodGenerator.java b/metaprogramming/impl/src/main/java/org/teavm/metaprogramming/impl/CompositeMethodGenerator.java index 973774afc..880e67fda 100644 --- a/metaprogramming/impl/src/main/java/org/teavm/metaprogramming/impl/CompositeMethodGenerator.java +++ b/metaprogramming/impl/src/main/java/org/teavm/metaprogramming/impl/CompositeMethodGenerator.java @@ -878,7 +878,15 @@ public class CompositeMethodGenerator { case "get": { Variable var = program.createVariable(); GetFieldInstruction insn = new GetFieldInstruction(); - insn.setInstance(!field.field.hasModifier(ElementModifier.STATIC) ? var(arguments.get(0)) : null); + if (!field.field.hasModifier(ElementModifier.STATIC)) { + var cast = new CastInstruction(); + cast.setReceiver(program.createVariable()); + cast.setValue(var(arguments.get(0))); + cast.setWeak(true); + cast.setTargetType(ValueType.object(field.field.getOwnerName())); + add(cast); + insn.setInstance(cast.getReceiver()); + } insn.setReceiver(var); insn.setField(field.getBackingField().getReference()); insn.setFieldType(field.getBackingField().getType()); @@ -895,7 +903,15 @@ public class CompositeMethodGenerator { } case "set": { PutFieldInstruction insn = new PutFieldInstruction(); - insn.setInstance(!field.field.hasModifier(ElementModifier.STATIC) ? var(arguments.get(0)) : null); + if (!field.field.hasModifier(ElementModifier.STATIC)) { + var cast = new CastInstruction(); + cast.setReceiver(program.createVariable()); + cast.setValue(var(arguments.get(0))); + cast.setWeak(true); + cast.setTargetType(ValueType.object(field.field.getOwnerName())); + add(cast); + insn.setInstance(cast.getReceiver()); + } insn.setValue(unbox(var(arguments.get(1)), field.getBackingField().getType())); insn.setField(field.getBackingField().getReference()); insn.setFieldType(field.getBackingField().getType()); @@ -930,7 +946,15 @@ public class CompositeMethodGenerator { switch (method.getName()) { case "invoke": { InvokeInstruction insn = new InvokeInstruction(); - insn.setInstance(!Modifier.isStatic(reflectMethod.getModifiers()) ? var(arguments.get(0)) : null); + if (!Modifier.isStatic(reflectMethod.getModifiers())) { + var cast = new CastInstruction(); + cast.setReceiver(program.createVariable()); + cast.setValue(var(arguments.get(0))); + cast.setWeak(true); + cast.setTargetType(ValueType.object(reflectMethod.method.getOwnerName())); + add(cast); + insn.setInstance(cast.getReceiver()); + } insn.setType(Modifier.isStatic(reflectMethod.getModifiers()) ? InvocationType.SPECIAL : InvocationType.VIRTUAL); insn.setMethod(reflectMethod.method.getReference());