wasm: fix exceptions in DWARF generator

This commit is contained in:
Alexey Andreev 2023-08-28 13:18:26 +02:00
parent 36060b37e3
commit bd2d2cb49b
2 changed files with 45 additions and 0 deletions

View File

@ -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_STRUCTURE_TYPE;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_UNSPECIFIED_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 static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_VARIABLE;
import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Queue;
import org.teavm.backend.wasm.blob.Blob; import org.teavm.backend.wasm.blob.Blob;
import org.teavm.backend.wasm.debug.info.VariableType; import org.teavm.backend.wasm.debug.info.VariableType;
import org.teavm.backend.wasm.dwarf.DwarfAbbreviation; import org.teavm.backend.wasm.dwarf.DwarfAbbreviation;
@ -82,6 +84,7 @@ public class DwarfClassGenerator {
private ClassType classClass; private ClassType classClass;
private DwarfFunctionGenerator functionGen; private DwarfFunctionGenerator functionGen;
private DwarfPlaceholder fakeClassPtrStruct; private DwarfPlaceholder fakeClassPtrStruct;
private Queue<Subprogram> subprogramsToPrepare = new ArrayDeque<>();
public DwarfClassGenerator(DwarfInfoWriter writer, DwarfStrings strings) { public DwarfClassGenerator(DwarfInfoWriter writer, DwarfStrings strings) {
this.writer = writer; this.writer = writer;
@ -137,6 +140,7 @@ public class DwarfClassGenerator {
public void registerSubprogram(String functionName, Subprogram subprogram) { public void registerSubprogram(String functionName, Subprogram subprogram) {
subprogramsByFunctionName.put(functionName, subprogram); subprogramsByFunctionName.put(functionName, subprogram);
subprogramsToPrepare.add(subprogram);
} }
public Subprogram getSubprogram(String functionName) { public Subprogram getSubprogram(String functionName) {
@ -146,6 +150,12 @@ public class DwarfClassGenerator {
public void write() { public void write() {
classClass = getClass("java.lang.Class"); classClass = getClass("java.lang.Class");
createFakeClassPtrStruct(); createFakeClassPtrStruct();
for (var subprogram : rootSubprograms) {
subprogram.prepare();
}
while (!subprogramsToPrepare.isEmpty()) {
subprogramsToPrepare.remove().prepare();
}
root.writeChildren(); root.writeChildren();
for (var subprogram : rootSubprograms) { for (var subprogram : rootSubprograms) {
subprogram.write(); subprogram.write();
@ -484,6 +494,12 @@ public class DwarfClassGenerator {
this.descriptor = descriptor; this.descriptor = descriptor;
} }
private void prepare() {
if (functionGen != null) {
functionGen.prepareContent(this);
}
}
private void write() { private void write() {
if (function != null) { if (function != null) {
functionGen.writeContent(this); functionGen.writeContent(this);

View File

@ -48,6 +48,35 @@ public class DwarfFunctionGenerator {
this.strings = strings; 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) { public void writeContent(DwarfClassGenerator.Subprogram subprogram) {
if (subprogram.function.getName() == null) { if (subprogram.function.getName() == null) {
return; return;