Wasm: fix issue with forward references in DWARF, generate class references as pointer types

This commit is contained in:
Alexey Andreev 2022-11-23 11:20:07 +01:00
parent f938db798b
commit 646c8ec488
3 changed files with 29 additions and 2 deletions

View File

@ -22,6 +22,7 @@ public final class DwarfConstants {
public static final int DW_TAG_CLASS_TYPE = 0x02; public static final int DW_TAG_CLASS_TYPE = 0x02;
public static final int DW_TAG_FORMAL_PARAMETER = 0x05; public static final int DW_TAG_FORMAL_PARAMETER = 0x05;
public static final int DW_TAG_POINTER_TYPE = 0x0F;
public static final int DW_TAG_COMPILE_UNIT = 0x11; public static final int DW_TAG_COMPILE_UNIT = 0x11;
public static final int DW_TAG_BASE_TYPE = 0x24; public static final int DW_TAG_BASE_TYPE = 0x24;
public static final int DW_TAG_SUBPROGRAM = 0x2E; public static final int DW_TAG_SUBPROGRAM = 0x2E;

View File

@ -31,8 +31,8 @@ public class DwarfPlaceholder {
void addForwardRef(DwarfPlaceholderWriter writer, Marker marker) { void addForwardRef(DwarfPlaceholderWriter writer, Marker marker) {
if (forwardReferences == null) { if (forwardReferences == null) {
forwardReferences = new ArrayList<>(); forwardReferences = new ArrayList<>();
forwardReferences.add(new ForwardRef(writer, marker));
} }
forwardReferences.add(new ForwardRef(writer, marker));
} }
static class ForwardRef { static class ForwardRef {

View File

@ -23,12 +23,15 @@ import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_BYTE_SIZE;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_DECLARATION; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_DECLARATION;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_ENCODING; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_ENCODING;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_NAME; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_NAME;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_TYPE;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_DATA1; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_DATA1;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_FLAG_PRESENT; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_FLAG_PRESENT;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_REF4;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_STRP; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_STRP;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_BASE_TYPE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_BASE_TYPE;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_CLASS_TYPE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_CLASS_TYPE;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_NAMESPACE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_NAMESPACE;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_POINTER_TYPE;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_SUBPROGRAM; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_SUBPROGRAM;
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 java.util.ArrayList; import java.util.ArrayList;
@ -39,6 +42,7 @@ import java.util.Map;
import org.teavm.backend.wasm.dwarf.DwarfAbbreviation; import org.teavm.backend.wasm.dwarf.DwarfAbbreviation;
import org.teavm.backend.wasm.dwarf.DwarfInfoWriter; import org.teavm.backend.wasm.dwarf.DwarfInfoWriter;
import org.teavm.backend.wasm.dwarf.DwarfPlaceholder; import org.teavm.backend.wasm.dwarf.DwarfPlaceholder;
import org.teavm.backend.wasm.dwarf.blob.Blob;
import org.teavm.model.MethodDescriptor; import org.teavm.model.MethodDescriptor;
import org.teavm.model.PrimitiveType; import org.teavm.model.PrimitiveType;
import org.teavm.model.ValueType; import org.teavm.model.ValueType;
@ -57,6 +61,7 @@ public class DwarfClassGenerator {
private DwarfPlaceholder[] primitiveTypes = new DwarfPlaceholder[PrimitiveType.values().length]; private DwarfPlaceholder[] primitiveTypes = new DwarfPlaceholder[PrimitiveType.values().length];
private DwarfPlaceholder unspecifiedType; private DwarfPlaceholder unspecifiedType;
private DwarfAbbreviation baseTypeAbbrev; private DwarfAbbreviation baseTypeAbbrev;
private DwarfAbbreviation pointerAbbrev;
private List<Runnable> postponedWrites = new ArrayList<>(); private List<Runnable> postponedWrites = new ArrayList<>();
public DwarfClassGenerator(DwarfInfoWriter writer, DwarfStrings strings) { public DwarfClassGenerator(DwarfInfoWriter writer, DwarfStrings strings) {
@ -164,7 +169,7 @@ public class DwarfClassGenerator {
} }
private DwarfPlaceholder getClassType(String name) { private DwarfPlaceholder getClassType(String name) {
return getClass(name).ptr; return getClass(name).getPointerPtr();
} }
private DwarfPlaceholder getPrimitivePtr(ValueType.Primitive type) { private DwarfPlaceholder getPrimitivePtr(ValueType.Primitive type) {
@ -242,6 +247,15 @@ public class DwarfClassGenerator {
return baseTypeAbbrev; return baseTypeAbbrev;
} }
private DwarfAbbreviation getPointerAbbrev() {
if (pointerAbbrev == null) {
pointerAbbrev = writer.abbreviation(DW_TAG_POINTER_TYPE, false, blob -> {
blob.writeLEB(DW_AT_TYPE).writeLEB(DW_FORM_REF4);
});
}
return pointerAbbrev;
}
public class Namespace { public class Namespace {
public final String name; public final String name;
final Map<String, Namespace> namespaces = new LinkedHashMap<>(); final Map<String, Namespace> namespaces = new LinkedHashMap<>();
@ -279,6 +293,7 @@ public class DwarfClassGenerator {
public class ClassType { public class ClassType {
public final String name; public final String name;
final DwarfPlaceholder ptr; final DwarfPlaceholder ptr;
private DwarfPlaceholder pointerPtr;
final Map<MethodDescriptor, Subprogram> subprograms = new LinkedHashMap<>(); final Map<MethodDescriptor, Subprogram> subprograms = new LinkedHashMap<>();
private ClassType(String name) { private ClassType(String name) {
@ -290,12 +305,23 @@ public class DwarfClassGenerator {
return subprograms.computeIfAbsent(desc, d -> new Subprogram(d.getName(), desc)); return subprograms.computeIfAbsent(desc, d -> new Subprogram(d.getName(), desc));
} }
public DwarfPlaceholder getPointerPtr() {
if (pointerPtr == null) {
pointerPtr = writer.placeholder(4);
}
return pointerPtr;
}
private void write() { private void write() {
writer.mark(ptr).tag(getClassTypeAbbrev()); writer.mark(ptr).tag(getClassTypeAbbrev());
writer.writeInt(strings.stringRef(name)); writer.writeInt(strings.stringRef(name));
for (var child : subprograms.values()) { for (var child : subprograms.values()) {
child.write(); child.write();
} }
if (pointerPtr != null) {
writer.mark(pointerPtr).tag(getPointerAbbrev());
writer.ref(ptr, Blob::writeInt);
}
writer.emptyTag(); writer.emptyTag();
} }
} }