mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Wasm: write more info about classes in DWARF
This commit is contained in:
parent
646c8ec488
commit
7e95e935d1
|
@ -24,6 +24,7 @@ public final class DwarfConstants {
|
||||||
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_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_INHERITANCE = 0x1C;
|
||||||
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;
|
||||||
public static final int DW_TAG_VARIABLE = 0x34;
|
public static final int DW_TAG_VARIABLE = 0x34;
|
||||||
|
@ -72,6 +73,8 @@ public final class DwarfConstants {
|
||||||
public static final int DW_FORM_FLAG_PRESENT = 0x19;
|
public static final int DW_FORM_FLAG_PRESENT = 0x19;
|
||||||
public static final int DW_FORM_LINE_STRP = 0x1F;
|
public static final int DW_FORM_LINE_STRP = 0x1F;
|
||||||
|
|
||||||
|
public static final int DW_OP_ADDR = 0x03;
|
||||||
|
public static final int DW_OP_STACK_VALUE = 0x9F;
|
||||||
public static final int DW_OP_WASM_LOCATION = 0xED;
|
public static final int DW_OP_WASM_LOCATION = 0xED;
|
||||||
|
|
||||||
public static final int DW_LNS_COPY = 0x01;
|
public static final int DW_LNS_COPY = 0x01;
|
||||||
|
|
|
@ -20,6 +20,7 @@ import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_CHILDREN_YES;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import org.teavm.backend.wasm.dwarf.blob.BinaryDataConsumer;
|
import org.teavm.backend.wasm.dwarf.blob.BinaryDataConsumer;
|
||||||
import org.teavm.backend.wasm.dwarf.blob.Blob;
|
import org.teavm.backend.wasm.dwarf.blob.Blob;
|
||||||
|
@ -115,6 +116,7 @@ public class DwarfInfoWriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DwarfInfoWriter mark(DwarfPlaceholder placeholder) {
|
public DwarfInfoWriter mark(DwarfPlaceholder placeholder) {
|
||||||
|
Objects.requireNonNull(placeholder);
|
||||||
placements.add(new Placement(output.ptr()) {
|
placements.add(new Placement(output.ptr()) {
|
||||||
@Override
|
@Override
|
||||||
void write(Blob blob) {
|
void write(Blob blob) {
|
||||||
|
|
|
@ -22,18 +22,25 @@ import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_ATE_UTF;
|
||||||
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_BYTE_SIZE;
|
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_LOCATION;
|
||||||
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_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_DATA2;
|
||||||
|
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_EXPRLOC;
|
||||||
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_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_OP_ADDR;
|
||||||
|
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_OP_STACK_VALUE;
|
||||||
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_INHERITANCE;
|
||||||
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_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 static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_VARIABLE;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
|
@ -57,12 +64,15 @@ public class DwarfClassGenerator {
|
||||||
private final DwarfStrings strings;
|
private final DwarfStrings strings;
|
||||||
private DwarfAbbreviation nsAbbrev;
|
private DwarfAbbreviation nsAbbrev;
|
||||||
private DwarfAbbreviation classTypeAbbrev;
|
private DwarfAbbreviation classTypeAbbrev;
|
||||||
|
private DwarfAbbreviation inheritanceAbbrev;
|
||||||
private DwarfAbbreviation methodAbbrev;
|
private DwarfAbbreviation methodAbbrev;
|
||||||
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 DwarfAbbreviation pointerAbbrev;
|
||||||
|
private DwarfAbbreviation variableAbbrev;
|
||||||
private List<Runnable> postponedWrites = new ArrayList<>();
|
private List<Runnable> postponedWrites = new ArrayList<>();
|
||||||
|
private ClassType classClass;
|
||||||
|
|
||||||
public DwarfClassGenerator(DwarfInfoWriter writer, DwarfStrings strings) {
|
public DwarfClassGenerator(DwarfInfoWriter writer, DwarfStrings strings) {
|
||||||
this.writer = writer;
|
this.writer = writer;
|
||||||
|
@ -99,10 +109,12 @@ public class DwarfClassGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write() {
|
public void write() {
|
||||||
|
classClass = getClass("java.lang.Class");
|
||||||
root.writeChildren();
|
root.writeChildren();
|
||||||
for (var subprogram : rootSubprograms) {
|
for (var subprogram : rootSubprograms) {
|
||||||
subprogram.write();
|
subprogram.write();
|
||||||
}
|
}
|
||||||
|
flushTypes();
|
||||||
}
|
}
|
||||||
|
|
||||||
private DwarfAbbreviation getMethodAbbrev() {
|
private DwarfAbbreviation getMethodAbbrev() {
|
||||||
|
@ -128,11 +140,21 @@ public class DwarfClassGenerator {
|
||||||
if (classTypeAbbrev == null) {
|
if (classTypeAbbrev == null) {
|
||||||
classTypeAbbrev = writer.abbreviation(DW_TAG_CLASS_TYPE, true, data -> {
|
classTypeAbbrev = writer.abbreviation(DW_TAG_CLASS_TYPE, true, data -> {
|
||||||
data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP);
|
data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP);
|
||||||
|
data.writeLEB(DW_AT_BYTE_SIZE).writeLEB(DW_FORM_DATA2);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return classTypeAbbrev;
|
return classTypeAbbrev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DwarfAbbreviation getInheritanceAbbrev() {
|
||||||
|
if (inheritanceAbbrev == null) {
|
||||||
|
inheritanceAbbrev = writer.abbreviation(DW_TAG_INHERITANCE, false, data -> {
|
||||||
|
data.writeLEB(DW_AT_TYPE).writeLEB(DW_FORM_REF4);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return inheritanceAbbrev;
|
||||||
|
}
|
||||||
|
|
||||||
public DwarfPlaceholder getTypePtr(VariableType type) {
|
public DwarfPlaceholder getTypePtr(VariableType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case INT:
|
case INT:
|
||||||
|
@ -169,7 +191,7 @@ public class DwarfClassGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
private DwarfPlaceholder getClassType(String name) {
|
private DwarfPlaceholder getClassType(String name) {
|
||||||
return getClass(name).getPointerPtr();
|
return getClass(name).ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DwarfPlaceholder getPrimitivePtr(ValueType.Primitive type) {
|
private DwarfPlaceholder getPrimitivePtr(ValueType.Primitive type) {
|
||||||
|
@ -256,6 +278,17 @@ public class DwarfClassGenerator {
|
||||||
return pointerAbbrev;
|
return pointerAbbrev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private DwarfAbbreviation getVariableAbbrev() {
|
||||||
|
if (variableAbbrev == null) {
|
||||||
|
variableAbbrev = writer.abbreviation(DW_TAG_VARIABLE, false, blob -> {
|
||||||
|
blob.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP);
|
||||||
|
blob.writeLEB(DW_AT_TYPE).writeLEB(DW_FORM_REF4);
|
||||||
|
blob.writeLEB(DW_AT_LOCATION).writeLEB(DW_FORM_EXPRLOC);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return variableAbbrev;
|
||||||
|
}
|
||||||
|
|
||||||
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<>();
|
||||||
|
@ -295,16 +328,31 @@ public class DwarfClassGenerator {
|
||||||
final DwarfPlaceholder ptr;
|
final DwarfPlaceholder ptr;
|
||||||
private DwarfPlaceholder pointerPtr;
|
private DwarfPlaceholder pointerPtr;
|
||||||
final Map<MethodDescriptor, Subprogram> subprograms = new LinkedHashMap<>();
|
final Map<MethodDescriptor, Subprogram> subprograms = new LinkedHashMap<>();
|
||||||
|
private ClassType superclass;
|
||||||
|
private int size;
|
||||||
|
private int pointer = -1;
|
||||||
|
|
||||||
private ClassType(String name) {
|
private ClassType(String name) {
|
||||||
ptr = writer.placeholder(4);
|
ptr = writer.placeholder(4);
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSuperclass(ClassType superclass) {
|
||||||
|
this.superclass = superclass;
|
||||||
|
}
|
||||||
|
|
||||||
public Subprogram getSubprogram(MethodDescriptor desc) {
|
public Subprogram getSubprogram(MethodDescriptor desc) {
|
||||||
return subprograms.computeIfAbsent(desc, d -> new Subprogram(d.getName(), desc));
|
return subprograms.computeIfAbsent(desc, d -> new Subprogram(d.getName(), desc));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSize(int size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPointer(int pointer) {
|
||||||
|
this.pointer = pointer;
|
||||||
|
}
|
||||||
|
|
||||||
public DwarfPlaceholder getPointerPtr() {
|
public DwarfPlaceholder getPointerPtr() {
|
||||||
if (pointerPtr == null) {
|
if (pointerPtr == null) {
|
||||||
pointerPtr = writer.placeholder(4);
|
pointerPtr = writer.placeholder(4);
|
||||||
|
@ -315,6 +363,10 @@ public class DwarfClassGenerator {
|
||||||
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));
|
||||||
|
writer.writeShort(size);
|
||||||
|
if (superclass != null) {
|
||||||
|
writer.tag(getInheritanceAbbrev()).ref(superclass.ptr, Blob::writeInt);
|
||||||
|
}
|
||||||
for (var child : subprograms.values()) {
|
for (var child : subprograms.values()) {
|
||||||
child.write();
|
child.write();
|
||||||
}
|
}
|
||||||
|
@ -322,6 +374,15 @@ public class DwarfClassGenerator {
|
||||||
writer.mark(pointerPtr).tag(getPointerAbbrev());
|
writer.mark(pointerPtr).tag(getPointerAbbrev());
|
||||||
writer.ref(ptr, Blob::writeInt);
|
writer.ref(ptr, Blob::writeInt);
|
||||||
}
|
}
|
||||||
|
if (pointer >= 0) {
|
||||||
|
writer.tag(getVariableAbbrev());
|
||||||
|
writer.writeInt(strings.stringRef("__class__"));
|
||||||
|
writer.ref(classClass.ptr, Blob::writeInt);
|
||||||
|
var ops = new Blob();
|
||||||
|
ops.writeByte(DW_OP_ADDR).writeInt(pointer).writeByte(DW_OP_STACK_VALUE);
|
||||||
|
writer.writeLEB(ops.size());
|
||||||
|
ops.newReader(writer::write).readRemaining();
|
||||||
|
}
|
||||||
writer.emptyTag();
|
writer.emptyTag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_ADDR;
|
||||||
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_EXPRLOC;
|
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_EXPRLOC;
|
||||||
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_REF4;
|
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_OP_STACK_VALUE;
|
||||||
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_OP_WASM_LOCATION;
|
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_OP_WASM_LOCATION;
|
||||||
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_FORMAL_PARAMETER;
|
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_FORMAL_PARAMETER;
|
||||||
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_SUBPROGRAM;
|
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_SUBPROGRAM;
|
||||||
|
@ -33,6 +34,7 @@ import org.teavm.backend.wasm.dwarf.DwarfAbbreviation;
|
||||||
import org.teavm.backend.wasm.dwarf.blob.Blob;
|
import org.teavm.backend.wasm.dwarf.blob.Blob;
|
||||||
import org.teavm.backend.wasm.dwarf.blob.Marker;
|
import org.teavm.backend.wasm.dwarf.blob.Marker;
|
||||||
import org.teavm.backend.wasm.model.WasmFunction;
|
import org.teavm.backend.wasm.model.WasmFunction;
|
||||||
|
import org.teavm.model.util.VariableType;
|
||||||
|
|
||||||
public class DwarfFunctionGenerator {
|
public class DwarfFunctionGenerator {
|
||||||
private DwarfClassGenerator classGen;
|
private DwarfClassGenerator classGen;
|
||||||
|
@ -114,6 +116,9 @@ public class DwarfFunctionGenerator {
|
||||||
|
|
||||||
var operations = new Blob();
|
var operations = new Blob();
|
||||||
operations.writeByte(DW_OP_WASM_LOCATION).writeByte(0).writeLEB(i + 1);
|
operations.writeByte(DW_OP_WASM_LOCATION).writeByte(0).writeLEB(i + 1);
|
||||||
|
if (local.getJavaType() == VariableType.OBJECT) {
|
||||||
|
operations.writeByte(DW_OP_STACK_VALUE);
|
||||||
|
}
|
||||||
writer.writeLEB(operations.size());
|
writer.writeLEB(operations.size());
|
||||||
operations.newReader(writer::write).readRemaining();
|
operations.newReader(writer::write).readRemaining();
|
||||||
}
|
}
|
||||||
|
|
|
@ -179,12 +179,22 @@ public class WasmClassGenerator {
|
||||||
var cls = classSource.get(className);
|
var cls = classSource.get(className);
|
||||||
|
|
||||||
if (cls != null) {
|
if (cls != null) {
|
||||||
calculateLayout(cls, binaryData);
|
DwarfClassGenerator.ClassType dwarfClass;
|
||||||
|
if (dwarfClassGenerator != null) {
|
||||||
|
dwarfClass = dwarfClassGenerator.getClass(className);
|
||||||
|
dwarfClass.setSuperclass(cls.getParent() != null
|
||||||
|
? dwarfClassGenerator.getClass(cls.getParent())
|
||||||
|
: null);
|
||||||
|
} else {
|
||||||
|
dwarfClass = null;
|
||||||
|
}
|
||||||
|
calculateLayout(cls, binaryData, dwarfClass);
|
||||||
if (binaryData.start >= 0) {
|
if (binaryData.start >= 0) {
|
||||||
binaryData.start = binaryWriter.append(createStructure(binaryData));
|
binaryData.start = binaryWriter.append(createStructure(binaryData));
|
||||||
}
|
}
|
||||||
if (dwarfClassGenerator != null) {
|
if (dwarfClass != null) {
|
||||||
dwarfClassGenerator.getClass(className);
|
dwarfClass.setSize(binaryData.size);
|
||||||
|
dwarfClass.setPointer(binaryData.start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (type instanceof ValueType.Array) {
|
} else if (type instanceof ValueType.Array) {
|
||||||
|
@ -486,7 +496,7 @@ public class WasmClassGenerator {
|
||||||
return binaryDataMap.get(type).function;
|
return binaryDataMap.get(type).function;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void calculateLayout(ClassReader cls, ClassBinaryData data) {
|
private void calculateLayout(ClassReader cls, ClassBinaryData data, DwarfClassGenerator.ClassType dwarfClass) {
|
||||||
if (cls.getName().equals(Structure.class.getName()) || cls.getName().equals(Address.class.getName())) {
|
if (cls.getName().equals(Structure.class.getName()) || cls.getName().equals(Address.class.getName())) {
|
||||||
data.size = 0;
|
data.size = 0;
|
||||||
data.start = -1;
|
data.start = -1;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user