From 36060b37e3513493bcc8434f220dcbc4e6c1dbfb Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Sun, 27 Aug 2023 00:26:03 +0200 Subject: [PATCH] wasm: another attempt to make class reference visible in chrome dev tools --- .../backend/wasm/dwarf/DwarfConstants.java | 3 ++ .../wasm/generate/DwarfClassGenerator.java | 51 +++++++++++-------- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/core/src/main/java/org/teavm/backend/wasm/dwarf/DwarfConstants.java b/core/src/main/java/org/teavm/backend/wasm/dwarf/DwarfConstants.java index ab9a6f288..744a70c72 100644 --- a/core/src/main/java/org/teavm/backend/wasm/dwarf/DwarfConstants.java +++ b/core/src/main/java/org/teavm/backend/wasm/dwarf/DwarfConstants.java @@ -25,6 +25,7 @@ public final class DwarfConstants { public static final int DW_TAG_MEMBER = 0x0d; public static final int DW_TAG_POINTER_TYPE = 0x0F; public static final int DW_TAG_COMPILE_UNIT = 0x11; + public static final int DW_TAG_STRUCTURE_TYPE = 0x13; 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; @@ -48,6 +49,7 @@ public final class DwarfConstants { public static final int DW_AT_ENCODING = 0x3E; public static final int DW_AT_SPECIFICATION = 0x47; public static final int DW_AT_TYPE = 0x49; + public static final int DW_AT_DATA_LOCATION = 0x50; public static final int DW_AT_LINKAGE_NAME = 0x6E; public static final int DW_ATE_ADDRESS = 0x01; @@ -84,6 +86,7 @@ public final class DwarfConstants { public static final int DW_OP_SHL = 0x24; public static final int DW_OP_LIT0 = 0x30; public static final int DW_OP_LIT3 = 0x33; + public static final int DW_OP_PUSH_OBJECT_ADDRESS = 0x97; public static final int DW_OP_STACK_VALUE = 0x9F; public static final int DW_OP_WASM_LOCATION = 0xED; 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 3f50ae04c..24238699b 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 @@ -15,21 +15,17 @@ */ package org.teavm.backend.wasm.generate; -import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_ACCESS_PUBLIC; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_ATE_BOOLEAN; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_ATE_FLOAT; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_ATE_SIGNED; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_ATE_UTF; -import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_ACCESSIBILITY; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_BYTE_SIZE; -import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_CALLING_CONVENTION; -import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_CONTAINING_TYPE; +import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_DATA_LOCATION; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_DATA_MEMBER_LOCATION; 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_CC_PASS_BY_REFERENCE; 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; @@ -38,13 +34,16 @@ 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_DEREF; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_OP_LIT3; +import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_OP_PUSH_OBJECT_ADDRESS; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_OP_SHL; +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_MEMBER; 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_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.ArrayList; @@ -82,11 +81,33 @@ public class DwarfClassGenerator { private List postponedWrites = new ArrayList<>(); private ClassType classClass; private DwarfFunctionGenerator functionGen; + private DwarfPlaceholder fakeClassPtrStruct; public DwarfClassGenerator(DwarfInfoWriter writer, DwarfStrings strings) { this.writer = writer; this.strings = strings; functionGen = new DwarfFunctionGenerator(this, writer, strings); + fakeClassPtrStruct = writer.placeholder(4); + } + + private void createFakeClassPtrStruct() { + var abbrev = writer.abbreviation(DW_TAG_STRUCTURE_TYPE, true, data -> { + data.writeLEB(DW_AT_DATA_LOCATION).writeLEB(DW_FORM_EXPRLOC); + }); + + writer.mark(fakeClassPtrStruct).tag(abbrev); + + var ops = new Blob(); + ops.writeByte(DW_OP_PUSH_OBJECT_ADDRESS).writeByte(DW_OP_DEREF).writeByte(DW_OP_LIT3).writeByte(DW_OP_SHL); + writer.writeLEB(ops.size()); + ops.newReader(writer::write).readRemaining(); + + writer.tag(getImmutableMemberAbbrev()); + writer.writeInt(strings.stringRef("value")); + writer.ref(classClass.getPointerPtr(), Blob::writeInt); + writer.writeShort(0); + + writer.emptyTag(); } public void flushTypes() { @@ -124,6 +145,7 @@ public class DwarfClassGenerator { public void write() { classClass = getClass("java.lang.Class"); + createFakeClassPtrStruct(); root.writeChildren(); for (var subprogram : rootSubprograms) { subprogram.write(); @@ -144,9 +166,7 @@ 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_CONTAINING_TYPE).writeLEB(DW_FORM_REF4); data.writeLEB(DW_AT_BYTE_SIZE).writeLEB(DW_FORM_DATA2); - data.writeLEB(DW_AT_CALLING_CONVENTION).writeLEB(DW_FORM_DATA1); }); } return classTypeAbbrev; @@ -166,8 +186,7 @@ public class DwarfClassGenerator { immutableMemberAbbrev = writer.abbreviation(DW_TAG_MEMBER, false, data -> { data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP); data.writeLEB(DW_AT_TYPE).writeLEB(DW_FORM_REF4); - data.writeLEB(DW_AT_DATA_MEMBER_LOCATION).writeLEB(DW_FORM_EXPRLOC); - data.writeLEB(DW_AT_ACCESSIBILITY).writeLEB(DW_FORM_DATA1); + data.writeLEB(DW_AT_DATA_MEMBER_LOCATION).writeLEB(DW_FORM_DATA2); }); } return immutableMemberAbbrev; @@ -179,7 +198,6 @@ public class DwarfClassGenerator { data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP); data.writeLEB(DW_AT_TYPE).writeLEB(DW_FORM_REF4); data.writeLEB(DW_AT_DATA_MEMBER_LOCATION).writeLEB(DW_FORM_DATA2); - data.writeLEB(DW_AT_ACCESSIBILITY).writeLEB(DW_FORM_DATA1); }); } return memberAbbrev; @@ -410,9 +428,7 @@ public class DwarfClassGenerator { private void write() { writer.mark(ptr).tag(getClassTypeAbbrev()); writer.writeInt(strings.stringRef(name)); - writer.ref(ptr, Blob::writeInt); writer.writeShort(size); - writer.writeByte(DW_CC_PASS_BY_REFERENCE); if (superclass != null) { writer.tag(getInheritanceAbbrev()).ref(superclass.ptr, Blob::writeInt); } @@ -428,7 +444,7 @@ public class DwarfClassGenerator { writer.writeInt(strings.stringRef("__classData__")); writer.ref(classClass.getPointerPtr(), Blob::writeInt); var ops = new Blob(); - ops.writeByte(DW_OP_ADDR).writeInt(pointer); + ops.writeByte(DW_OP_ADDR).writeInt(pointer).writeByte(DW_OP_STACK_VALUE); writer.writeLEB(ops.size()); ops.newReader(writer::write).readRemaining(); } @@ -442,12 +458,8 @@ public class DwarfClassGenerator { private void writeClassPointerField() { writer.tag(getImmutableMemberAbbrev()); writer.writeInt(strings.stringRef("__class__")); - writer.ref(classClass.ptr, Blob::writeInt); - var ops = new Blob(); - ops.writeByte(DW_OP_DEREF).writeByte(DW_OP_LIT3).writeByte(DW_OP_SHL); - writer.writeLEB(ops.size()); - ops.newReader(writer::write).readRemaining(); - writer.writeByte(DW_ACCESS_PUBLIC); + writer.ref(fakeClassPtrStruct, Blob::writeInt); + writer.writeShort(0); } private void writeFields() { @@ -504,7 +516,6 @@ public class DwarfClassGenerator { writer.writeInt(strings.stringRef(name)); writer.ref(getTypePtr(type), Blob::writeInt); writer.writeShort(offset); - writer.writeByte(DW_ACCESS_PUBLIC); } }