From bd2d2cb49bc6c4dfe3d16bc4f47d2fd2af011d47 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Mon, 28 Aug 2023 13:18:26 +0200 Subject: [PATCH] wasm: fix exceptions in DWARF generator --- .../wasm/generate/DwarfClassGenerator.java | 16 ++++++++++ .../wasm/generate/DwarfFunctionGenerator.java | 29 +++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/DwarfClassGenerator.java b/core/src/main/java/org/teavm/backend/wasm/generate/DwarfClassGenerator.java index 24238699b..e5976b5a1 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/DwarfClassGenerator.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/DwarfClassGenerator.java @@ -46,11 +46,13 @@ import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_POINTER_TYPE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_STRUCTURE_TYPE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_UNSPECIFIED_TYPE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_VARIABLE; +import java.util.ArrayDeque; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Queue; import org.teavm.backend.wasm.blob.Blob; import org.teavm.backend.wasm.debug.info.VariableType; import org.teavm.backend.wasm.dwarf.DwarfAbbreviation; @@ -82,6 +84,7 @@ public class DwarfClassGenerator { private ClassType classClass; private DwarfFunctionGenerator functionGen; private DwarfPlaceholder fakeClassPtrStruct; + private Queue subprogramsToPrepare = new ArrayDeque<>(); public DwarfClassGenerator(DwarfInfoWriter writer, DwarfStrings strings) { this.writer = writer; @@ -137,6 +140,7 @@ public class DwarfClassGenerator { public void registerSubprogram(String functionName, Subprogram subprogram) { subprogramsByFunctionName.put(functionName, subprogram); + subprogramsToPrepare.add(subprogram); } public Subprogram getSubprogram(String functionName) { @@ -146,6 +150,12 @@ public class DwarfClassGenerator { public void write() { classClass = getClass("java.lang.Class"); createFakeClassPtrStruct(); + for (var subprogram : rootSubprograms) { + subprogram.prepare(); + } + while (!subprogramsToPrepare.isEmpty()) { + subprogramsToPrepare.remove().prepare(); + } root.writeChildren(); for (var subprogram : rootSubprograms) { subprogram.write(); @@ -484,6 +494,12 @@ public class DwarfClassGenerator { this.descriptor = descriptor; } + private void prepare() { + if (functionGen != null) { + functionGen.prepareContent(this); + } + } + private void write() { if (function != null) { functionGen.writeContent(this); diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/DwarfFunctionGenerator.java b/core/src/main/java/org/teavm/backend/wasm/generate/DwarfFunctionGenerator.java index 29c82f753..2811dec92 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/DwarfFunctionGenerator.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/DwarfFunctionGenerator.java @@ -48,6 +48,35 @@ public class DwarfFunctionGenerator { this.strings = strings; } + public void prepareContent(DwarfClassGenerator.Subprogram subprogram) { + if (subprogram.function == null || subprogram.function.getName() == null) { + return; + } + var descriptor = subprogram.descriptor; + if (descriptor == null) { + return; + } + var function = subprogram.function; + + var offset = subprogram.isStatic ? 0 : 1; + int count = Math.min(function.getLocalVariables().size() - offset, descriptor.parameterCount()); + for (var i = 0; i < count; ++i) { + var local = function.getLocalVariables().get(i + offset); + if (local.getName() == null) { + continue; + } + classGen.getTypePtr(descriptor.parameterType(i)); + } + + for (var i = count + offset; i < function.getLocalVariables().size(); ++i) { + var local = function.getLocalVariables().get(i); + if (local.getName() == null || local.getJavaType() == null) { + continue; + } + classGen.getTypePtr(local.getJavaType()); + } + } + public void writeContent(DwarfClassGenerator.Subprogram subprogram) { if (subprogram.function.getName() == null) { return;