From 7029d3cff705a9133714b24164fc51348e4fb790 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 13 Sep 2024 19:46:11 +0200 Subject: [PATCH] wasm gc: implement branching instructions and null check instruction --- .../wasm/disasm/DisassemblyCodeListener.java | 26 ++++++ .../methods/BaseWasmGenerationVisitor.java | 2 +- .../WasmGCSupertypeFunctionGenerator.java | 5 +- .../gc/methods/WasmGCGenerationVisitor.java | 30 ++++++- .../wasm/generators/gc/ClassGenerators.java | 6 +- .../wasm/model/expression/WasmCastBranch.java | 89 +++++++++++++++++++ .../model/expression/WasmCastCondition.java | 21 +++++ .../WasmDefaultExpressionVisitor.java | 21 +++++ .../expression/WasmExpressionVisitor.java | 6 ++ .../wasm/model/expression/WasmIsNull.java | 39 ++++++++ .../wasm/model/expression/WasmNullBranch.java | 68 ++++++++++++++ .../model/expression/WasmNullCondition.java | 21 +++++ .../WasmReplacingExpressionVisitor.java | 26 ++++++ .../backend/wasm/parser/BranchOpcode.java | 4 +- .../backend/wasm/parser/CodeListener.java | 4 + .../teavm/backend/wasm/parser/CodeParser.java | 26 ++++++ .../org/teavm/backend/wasm/parser/Opcode.java | 3 +- .../render/WasmBinaryRenderingVisitor.java | 72 +++++++++++++++ .../wasm/render/WasmCRenderingVisitor.java | 18 ++++ .../wasm/render/WasmRenderingVisitor.java | 60 +++++++++++++ .../wasm/render/WasmTypeInference.java | 32 ++++++- 21 files changed, 567 insertions(+), 12 deletions(-) create mode 100644 core/src/main/java/org/teavm/backend/wasm/model/expression/WasmCastBranch.java create mode 100644 core/src/main/java/org/teavm/backend/wasm/model/expression/WasmCastCondition.java create mode 100644 core/src/main/java/org/teavm/backend/wasm/model/expression/WasmIsNull.java create mode 100644 core/src/main/java/org/teavm/backend/wasm/model/expression/WasmNullBranch.java create mode 100644 core/src/main/java/org/teavm/backend/wasm/model/expression/WasmNullCondition.java diff --git a/core/src/main/java/org/teavm/backend/wasm/disasm/DisassemblyCodeListener.java b/core/src/main/java/org/teavm/backend/wasm/disasm/DisassemblyCodeListener.java index ea65aee70..ecfff78c4 100644 --- a/core/src/main/java/org/teavm/backend/wasm/disasm/DisassemblyCodeListener.java +++ b/core/src/main/java/org/teavm/backend/wasm/disasm/DisassemblyCodeListener.java @@ -120,10 +120,33 @@ public void branch(BranchOpcode opcode, int depth, int target) { case BR_IF: writer.write("br_if"); break; + case BR_ON_NULL: + writer.write("br_on_null"); + break; + case BR_ON_NON_NULL: + writer.write("br_on_non_null"); + break; } writer.endLink().write(" $label_" + target).eol(); } + @Override + public void castBranch(boolean success, int depth, int target, WasmHollowType.Reference sourceType, + WasmHollowType.Reference targetType) { + writer.address().startLink("start" + target); + if (success) { + writer.write("br_if_cast"); + } else { + writer.write("br_if_cast_fail"); + } + writer.endLink().write(" $label_" + target); + writer.write(" "); + writeType(sourceType); + writer.write(" "); + writeType(sourceType); + writer.eol(); + } + @Override public void tableBranch(int[] depths, int[] targets, int defaultDepth, int defaultTarget) { writer.address(); @@ -162,6 +185,9 @@ public void opcode(Opcode opcode) { case ARRAY_LENGTH: writer.write("array.length"); break; + case IS_NULL: + writer.write("ref.is_null"); + break; } writer.eol(); } diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/common/methods/BaseWasmGenerationVisitor.java b/core/src/main/java/org/teavm/backend/wasm/generate/common/methods/BaseWasmGenerationVisitor.java index 620c680fc..c5fd83a9f 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/common/methods/BaseWasmGenerationVisitor.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/common/methods/BaseWasmGenerationVisitor.java @@ -449,7 +449,7 @@ public void visit(UnaryExpr expr) { protected abstract boolean isManagedCall(MethodReference method); - private WasmExpression nullCheck(Expr value, TextLocation location) { + protected WasmExpression nullCheck(Expr value, TextLocation location) { var block = new WasmBlock(false); block.setLocation(location); diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCSupertypeFunctionGenerator.java b/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCSupertypeFunctionGenerator.java index 0abca345b..de9667143 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCSupertypeFunctionGenerator.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/gc/classes/WasmGCSupertypeFunctionGenerator.java @@ -35,7 +35,7 @@ import org.teavm.backend.wasm.model.expression.WasmIntBinary; import org.teavm.backend.wasm.model.expression.WasmIntBinaryOperation; import org.teavm.backend.wasm.model.expression.WasmIntType; -import org.teavm.backend.wasm.model.expression.WasmNullConstant; +import org.teavm.backend.wasm.model.expression.WasmIsNull; import org.teavm.backend.wasm.model.expression.WasmReferencesEqual; import org.teavm.backend.wasm.model.expression.WasmReturn; import org.teavm.backend.wasm.model.expression.WasmSetLocal; @@ -156,8 +156,7 @@ private void generateIsArray(WasmLocal subtypeVar, ValueType itemType, List