mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -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_POINTER_TYPE = 0x0F;
|
||||
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_SUBPROGRAM = 0x2E;
|
||||
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_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_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.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Consumer;
|
||||
import org.teavm.backend.wasm.dwarf.blob.BinaryDataConsumer;
|
||||
import org.teavm.backend.wasm.dwarf.blob.Blob;
|
||||
|
@ -115,6 +116,7 @@ public class DwarfInfoWriter {
|
|||
}
|
||||
|
||||
public DwarfInfoWriter mark(DwarfPlaceholder placeholder) {
|
||||
Objects.requireNonNull(placeholder);
|
||||
placements.add(new Placement(output.ptr()) {
|
||||
@Override
|
||||
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_DECLARATION;
|
||||
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_TYPE;
|
||||
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_REF4;
|
||||
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_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_POINTER_TYPE;
|
||||
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_VARIABLE;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
@ -57,12 +64,15 @@ public class DwarfClassGenerator {
|
|||
private final DwarfStrings strings;
|
||||
private DwarfAbbreviation nsAbbrev;
|
||||
private DwarfAbbreviation classTypeAbbrev;
|
||||
private DwarfAbbreviation inheritanceAbbrev;
|
||||
private DwarfAbbreviation methodAbbrev;
|
||||
private DwarfPlaceholder[] primitiveTypes = new DwarfPlaceholder[PrimitiveType.values().length];
|
||||
private DwarfPlaceholder unspecifiedType;
|
||||
private DwarfAbbreviation baseTypeAbbrev;
|
||||
private DwarfAbbreviation pointerAbbrev;
|
||||
private DwarfAbbreviation variableAbbrev;
|
||||
private List<Runnable> postponedWrites = new ArrayList<>();
|
||||
private ClassType classClass;
|
||||
|
||||
public DwarfClassGenerator(DwarfInfoWriter writer, DwarfStrings strings) {
|
||||
this.writer = writer;
|
||||
|
@ -99,10 +109,12 @@ public class DwarfClassGenerator {
|
|||
}
|
||||
|
||||
public void write() {
|
||||
classClass = getClass("java.lang.Class");
|
||||
root.writeChildren();
|
||||
for (var subprogram : rootSubprograms) {
|
||||
subprogram.write();
|
||||
}
|
||||
flushTypes();
|
||||
}
|
||||
|
||||
private DwarfAbbreviation getMethodAbbrev() {
|
||||
|
@ -128,11 +140,21 @@ public class DwarfClassGenerator {
|
|||
if (classTypeAbbrev == null) {
|
||||
classTypeAbbrev = writer.abbreviation(DW_TAG_CLASS_TYPE, true, data -> {
|
||||
data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP);
|
||||
data.writeLEB(DW_AT_BYTE_SIZE).writeLEB(DW_FORM_DATA2);
|
||||
});
|
||||
}
|
||||
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) {
|
||||
switch (type) {
|
||||
case INT:
|
||||
|
@ -169,7 +191,7 @@ public class DwarfClassGenerator {
|
|||
}
|
||||
|
||||
private DwarfPlaceholder getClassType(String name) {
|
||||
return getClass(name).getPointerPtr();
|
||||
return getClass(name).ptr;
|
||||
}
|
||||
|
||||
private DwarfPlaceholder getPrimitivePtr(ValueType.Primitive type) {
|
||||
|
@ -256,6 +278,17 @@ public class DwarfClassGenerator {
|
|||
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 final String name;
|
||||
final Map<String, Namespace> namespaces = new LinkedHashMap<>();
|
||||
|
@ -295,16 +328,31 @@ public class DwarfClassGenerator {
|
|||
final DwarfPlaceholder ptr;
|
||||
private DwarfPlaceholder pointerPtr;
|
||||
final Map<MethodDescriptor, Subprogram> subprograms = new LinkedHashMap<>();
|
||||
private ClassType superclass;
|
||||
private int size;
|
||||
private int pointer = -1;
|
||||
|
||||
private ClassType(String name) {
|
||||
ptr = writer.placeholder(4);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setSuperclass(ClassType superclass) {
|
||||
this.superclass = superclass;
|
||||
}
|
||||
|
||||
public Subprogram getSubprogram(MethodDescriptor 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() {
|
||||
if (pointerPtr == null) {
|
||||
pointerPtr = writer.placeholder(4);
|
||||
|
@ -315,6 +363,10 @@ public class DwarfClassGenerator {
|
|||
private void write() {
|
||||
writer.mark(ptr).tag(getClassTypeAbbrev());
|
||||
writer.writeInt(strings.stringRef(name));
|
||||
writer.writeShort(size);
|
||||
if (superclass != null) {
|
||||
writer.tag(getInheritanceAbbrev()).ref(superclass.ptr, Blob::writeInt);
|
||||
}
|
||||
for (var child : subprograms.values()) {
|
||||
child.write();
|
||||
}
|
||||
|
@ -322,6 +374,15 @@ public class DwarfClassGenerator {
|
|||
writer.mark(pointerPtr).tag(getPointerAbbrev());
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_REF4;
|
||||
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_TAG_FORMAL_PARAMETER;
|
||||
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.Marker;
|
||||
import org.teavm.backend.wasm.model.WasmFunction;
|
||||
import org.teavm.model.util.VariableType;
|
||||
|
||||
public class DwarfFunctionGenerator {
|
||||
private DwarfClassGenerator classGen;
|
||||
|
@ -114,6 +116,9 @@ public class DwarfFunctionGenerator {
|
|||
|
||||
var operations = new Blob();
|
||||
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());
|
||||
operations.newReader(writer::write).readRemaining();
|
||||
}
|
||||
|
|
|
@ -179,12 +179,22 @@ public class WasmClassGenerator {
|
|||
var cls = classSource.get(className);
|
||||
|
||||
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) {
|
||||
binaryData.start = binaryWriter.append(createStructure(binaryData));
|
||||
}
|
||||
if (dwarfClassGenerator != null) {
|
||||
dwarfClassGenerator.getClass(className);
|
||||
if (dwarfClass != null) {
|
||||
dwarfClass.setSize(binaryData.size);
|
||||
dwarfClass.setPointer(binaryData.start);
|
||||
}
|
||||
}
|
||||
} else if (type instanceof ValueType.Array) {
|
||||
|
@ -486,7 +496,7 @@ public class WasmClassGenerator {
|
|||
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())) {
|
||||
data.size = 0;
|
||||
data.start = -1;
|
||||
|
|
Loading…
Reference in New Issue
Block a user