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 57f20b96b..a1bf68348 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 @@ -20,7 +20,6 @@ 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_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; @@ -28,7 +27,6 @@ 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; @@ -38,7 +36,6 @@ 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; @@ -51,6 +48,7 @@ import org.teavm.backend.wasm.debug.info.VariableType; import org.teavm.backend.wasm.dwarf.DwarfAbbreviation; import org.teavm.backend.wasm.dwarf.DwarfInfoWriter; import org.teavm.backend.wasm.dwarf.DwarfPlaceholder; +import org.teavm.backend.wasm.model.WasmFunction; import org.teavm.model.MethodDescriptor; import org.teavm.model.PrimitiveType; import org.teavm.model.ValueType; @@ -65,7 +63,6 @@ public class DwarfClassGenerator { 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; @@ -73,10 +70,12 @@ public class DwarfClassGenerator { private DwarfAbbreviation variableAbbrev; private List postponedWrites = new ArrayList<>(); private ClassType classClass; + private DwarfFunctionGenerator functionGen; public DwarfClassGenerator(DwarfInfoWriter writer, DwarfStrings strings) { this.writer = writer; this.strings = strings; + functionGen = new DwarfFunctionGenerator(this, writer, strings); } public void flushTypes() { @@ -117,16 +116,6 @@ public class DwarfClassGenerator { flushTypes(); } - private DwarfAbbreviation getMethodAbbrev() { - if (methodAbbrev == null) { - methodAbbrev = writer.abbreviation(DW_TAG_SUBPROGRAM, true, data -> { - data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP); - data.writeLEB(DW_AT_DECLARATION).writeLEB(DW_FORM_FLAG_PRESENT); - }); - } - return methodAbbrev; - } - private DwarfAbbreviation getNsAbbrev() { if (nsAbbrev == null) { nsAbbrev = writer.abbreviation(DW_TAG_NAMESPACE, true, data -> { @@ -391,18 +380,19 @@ public class DwarfClassGenerator { public final String name; public boolean isStatic; public final MethodDescriptor descriptor; - public final DwarfPlaceholder ref; + public int startOffset; + public int endOffset; + public WasmFunction function; private Subprogram(String name, MethodDescriptor descriptor) { this.name = name; this.descriptor = descriptor; - ref = writer.placeholder(4); } private void write() { - writer.mark(ref).tag(getMethodAbbrev()); - writer.writeInt(strings.stringRef(name)); - writer.emptyTag(); + if (function != null) { + functionGen.writeContent(this); + } } } } diff --git a/core/src/main/java/org/teavm/backend/wasm/generate/DwarfFunctionGenerator.java b/core/src/main/java/org/teavm/backend/wasm/generate/DwarfFunctionGenerator.java index e7fb4de8d..274dae66d 100644 --- a/core/src/main/java/org/teavm/backend/wasm/generate/DwarfFunctionGenerator.java +++ b/core/src/main/java/org/teavm/backend/wasm/generate/DwarfFunctionGenerator.java @@ -19,7 +19,6 @@ import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_HIGH_PC; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_LOCATION; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_LOW_PC; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_NAME; -import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_SPECIFICATION; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_TYPE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_ADDR; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_EXPRLOC; @@ -31,63 +30,46 @@ import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_FORMAL_PARAMETE import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_SUBPROGRAM; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_VARIABLE; import org.teavm.backend.wasm.blob.Blob; -import org.teavm.backend.wasm.blob.Marker; import org.teavm.backend.wasm.debug.info.VariableType; import org.teavm.backend.wasm.dwarf.DwarfAbbreviation; -import org.teavm.backend.wasm.model.WasmFunction; +import org.teavm.backend.wasm.dwarf.DwarfInfoWriter; public class DwarfFunctionGenerator { private DwarfClassGenerator classGen; - private DwarfGenerator generator; - private WasmFunction function; - private int offset; - private Marker endProgramMarker; + private DwarfInfoWriter writer; + private DwarfStrings strings; private DwarfAbbreviation methodAbbrev; - private DwarfAbbreviation functionAbbrev; private DwarfAbbreviation parameterAbbrev; private DwarfAbbreviation variableAbbrev; - private DwarfClassGenerator.Subprogram subprogram; - public DwarfFunctionGenerator(DwarfClassGenerator classGen, DwarfGenerator generator) { + public DwarfFunctionGenerator(DwarfClassGenerator classGen, DwarfInfoWriter writer, DwarfStrings strings) { this.classGen = classGen; - this.generator = generator; + this.writer = writer; + this.strings = strings; } - public void begin(WasmFunction function, int offset) { - if (function.getName() == null) { + public void writeContent(DwarfClassGenerator.Subprogram subprogram) { + if (subprogram.function.getName() == null) { return; } - subprogram = classGen.getSubprogram(function.getName()); - var writer = generator.getInfoWriter(); - var strings = generator.strings; - writer.tag(subprogram != null ? getMethodAbbrev() : getFunctionAbbrev()); - if (subprogram != null) { - writer.ref(subprogram.ref, Blob::writeInt); - } else { - writer.writeInt(strings.stringRef(subprogram != null ? subprogram.name : function.getName())); - } - writer.writeInt(offset); - endProgramMarker = writer.marker(); - writer.skip(4); + writer.tag(getMethodAbbrev()); + writer.writeInt(strings.stringRef(subprogram.name)); + writer.writeInt(subprogram.startOffset); + writer.writeInt(subprogram.endOffset); - this.function = function; - this.offset = offset; + writeLocals(subprogram); - writeLocals(); + writer.emptyTag(); } - private void writeLocals() { - if (subprogram == null) { - return; - } + private void writeLocals(DwarfClassGenerator.Subprogram subprogram) { var descriptor = subprogram.descriptor; if (descriptor == null) { return; } - var writer = generator.getInfoWriter(); - var strings = generator.strings; + 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) { @@ -124,29 +106,10 @@ public class DwarfFunctionGenerator { } } - public void end(int size) { - if (function == null) { - return; - } - - var writer = generator.getInfoWriter(); - if (endProgramMarker != null) { - var backup = writer.marker(); - endProgramMarker.rewind(); - writer.writeInt(offset + size); - backup.rewind(); - } - writer.emptyTag(); - classGen.flushTypes(); - subprogram = null; - endProgramMarker = null; - function = null; - } - private DwarfAbbreviation getMethodAbbrev() { if (methodAbbrev == null) { - methodAbbrev = generator.getInfoWriter().abbreviation(DW_TAG_SUBPROGRAM, true, data -> { - data.writeLEB(DW_AT_SPECIFICATION).writeLEB(DW_FORM_REF4); + methodAbbrev = writer.abbreviation(DW_TAG_SUBPROGRAM, true, data -> { + data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP); data.writeLEB(DW_AT_LOW_PC).writeLEB(DW_FORM_ADDR); data.writeLEB(DW_AT_HIGH_PC).writeLEB(DW_FORM_ADDR); }); @@ -154,20 +117,9 @@ public class DwarfFunctionGenerator { return methodAbbrev; } - private DwarfAbbreviation getFunctionAbbrev() { - if (functionAbbrev == null) { - functionAbbrev = generator.getInfoWriter().abbreviation(DW_TAG_SUBPROGRAM, true, data -> { - data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP); - data.writeLEB(DW_AT_LOW_PC).writeLEB(DW_FORM_ADDR); - data.writeLEB(DW_AT_HIGH_PC).writeLEB(DW_FORM_ADDR); - }); - } - return functionAbbrev; - } - private DwarfAbbreviation getParameterAbbrev() { if (parameterAbbrev == null) { - parameterAbbrev = generator.getInfoWriter().abbreviation(DW_TAG_FORMAL_PARAMETER, false, data -> { + parameterAbbrev = writer.abbreviation(DW_TAG_FORMAL_PARAMETER, false, data -> { data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP); data.writeLEB(DW_AT_TYPE).writeLEB(DW_FORM_REF4); data.writeLEB(DW_AT_LOCATION).writeLEB(DW_FORM_EXPRLOC); @@ -178,7 +130,7 @@ public class DwarfFunctionGenerator { private DwarfAbbreviation getVariableAbbrev() { if (variableAbbrev == null) { - variableAbbrev = generator.getInfoWriter().abbreviation(DW_TAG_VARIABLE, false, data -> { + variableAbbrev = writer.abbreviation(DW_TAG_VARIABLE, false, data -> { data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP); data.writeLEB(DW_AT_TYPE).writeLEB(DW_FORM_REF4); data.writeLEB(DW_AT_LOCATION).writeLEB(DW_FORM_EXPRLOC); diff --git a/core/src/main/java/org/teavm/backend/wasm/render/WasmBinaryRenderer.java b/core/src/main/java/org/teavm/backend/wasm/render/WasmBinaryRenderer.java index 1e4b95612..64496a2c1 100644 --- a/core/src/main/java/org/teavm/backend/wasm/render/WasmBinaryRenderer.java +++ b/core/src/main/java/org/teavm/backend/wasm/render/WasmBinaryRenderer.java @@ -26,7 +26,6 @@ import java.util.stream.Collectors; import org.teavm.backend.wasm.debug.DebugLines; import org.teavm.backend.wasm.debug.DebugVariables; import org.teavm.backend.wasm.generate.DwarfClassGenerator; -import org.teavm.backend.wasm.generate.DwarfFunctionGenerator; import org.teavm.backend.wasm.generate.DwarfGenerator; import org.teavm.backend.wasm.model.WasmCustomSection; import org.teavm.backend.wasm.model.WasmFunction; @@ -58,7 +57,7 @@ public class WasmBinaryRenderer { private Map functionIndexes = new HashMap<>(); private boolean obfuscated; private DwarfGenerator dwarfGenerator; - private DwarfFunctionGenerator dwarfFunctionGen; + private DwarfClassGenerator dwarfClassGen; private DebugLines debugLines; private DebugVariables debugVariables; private WasmBinaryStatsCollector statsCollector; @@ -70,7 +69,7 @@ public class WasmBinaryRenderer { this.version = version; this.obfuscated = obfuscated; this.dwarfGenerator = dwarfGenerator; - dwarfFunctionGen = dwarfClassGen != null ? new DwarfFunctionGenerator(dwarfClassGen, dwarfGenerator) : null; + this.dwarfClassGen = dwarfClassGen; this.debugLines = debugLines; this.debugVariables = debugVariables; this.statsCollector = statsCollector; @@ -300,8 +299,10 @@ public class WasmBinaryRenderer { private byte[] renderFunction(WasmFunction function, int offset) { var code = new WasmBinaryWriter(); - if (dwarfFunctionGen != null) { - dwarfFunctionGen.begin(function, offset); + var dwarfSubprogram = dwarfClassGen != null ? dwarfClassGen.getSubprogram(function.getName()) : null; + if (dwarfSubprogram != null) { + dwarfSubprogram.startOffset = offset - 4; + dwarfSubprogram.function = function; } if (debugLines != null && function.getJavaMethod() != null) { debugLines.start(function.getJavaMethod()); @@ -343,8 +344,8 @@ public class WasmBinaryRenderer { code.writeByte(0x0B); - if (dwarfFunctionGen != null) { - dwarfFunctionGen.end(code.getPosition()); + if (dwarfSubprogram != null) { + dwarfSubprogram.endOffset = code.getPosition() + offset; } if (debugVariables != null) { writeDebugVariables(function, offset, code.getPosition());