mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-23 00:24:11 -08:00
Wasm: split declarations and specifications of methods in DWARF
This commit is contained in:
parent
8fac3237ba
commit
13cc56feb5
|
@ -547,8 +547,11 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
||||||
}
|
}
|
||||||
|
|
||||||
var writer = new WasmBinaryWriter();
|
var writer = new WasmBinaryWriter();
|
||||||
|
if (dwarfClassGen != null) {
|
||||||
|
dwarfClassGen.write(dwarfGenerator.getInfoWriter(), dwarfGenerator.strings);
|
||||||
|
}
|
||||||
var renderer = new WasmBinaryRenderer(writer, version, obfuscated, dwarfGenerator, dwarfClassGen);
|
var renderer = new WasmBinaryRenderer(writer, version, obfuscated, dwarfGenerator, dwarfClassGen);
|
||||||
renderer.render(module, buildDwarf(dwarfGenerator, dwarfClassGen));
|
renderer.render(module, buildDwarf(dwarfGenerator));
|
||||||
|
|
||||||
try (OutputStream output = buildTarget.createResource(outputName)) {
|
try (OutputStream output = buildTarget.createResource(outputName)) {
|
||||||
output.write(writer.getData());
|
output.write(writer.getData());
|
||||||
|
@ -567,13 +570,11 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Supplier<Collection<? extends WasmCustomSection>> buildDwarf(DwarfGenerator generator,
|
private Supplier<Collection<? extends WasmCustomSection>> buildDwarf(DwarfGenerator generator) {
|
||||||
DwarfClassGenerator classGen) {
|
|
||||||
if (generator == null) {
|
if (generator == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return () -> {
|
return () -> {
|
||||||
classGen.write(generator.getInfoWriter(), generator.strings);
|
|
||||||
generator.end();
|
generator.end();
|
||||||
return generator.createSections();
|
return generator.createSections();
|
||||||
};
|
};
|
||||||
|
|
|
@ -31,6 +31,9 @@ public final class DwarfConstants {
|
||||||
public static final int DW_AT_HIGH_PC = 0x12;
|
public static final int DW_AT_HIGH_PC = 0x12;
|
||||||
public static final int DW_AT_LANGUAGE = 0x13;
|
public static final int DW_AT_LANGUAGE = 0x13;
|
||||||
public static final int DW_AT_PRODUCER = 0x25;
|
public static final int DW_AT_PRODUCER = 0x25;
|
||||||
|
public static final int DW_AT_DECLARATION = 0x3c;
|
||||||
|
public static final int DW_AT_SPECIFICATION = 0x47;
|
||||||
|
public static final int DW_AT_LINKAGE_NAME = 0x6E;
|
||||||
|
|
||||||
public static final int DW_LANG_JAVA = 0x0b;
|
public static final int DW_LANG_JAVA = 0x0b;
|
||||||
|
|
||||||
|
@ -43,8 +46,11 @@ public final class DwarfConstants {
|
||||||
public static final int DW_FORM_ADDR = 0x01;
|
public static final int DW_FORM_ADDR = 0x01;
|
||||||
public static final int DW_FORM_DATA2 = 0x05;
|
public static final int DW_FORM_DATA2 = 0x05;
|
||||||
public static final int DW_FORM_DATA4 = 0x06;
|
public static final int DW_FORM_DATA4 = 0x06;
|
||||||
|
public static final int DW_FORM_FLAG = 0x0C;
|
||||||
public static final int DW_FORM_STRP = 0x0E;
|
public static final int DW_FORM_STRP = 0x0E;
|
||||||
|
public static final int DW_FORM_REF4 = 0x13;
|
||||||
public static final int DW_FORM_SEC_OFFSET = 0x17;
|
public static final int DW_FORM_SEC_OFFSET = 0x17;
|
||||||
|
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_LNS_COPY = 0x01;
|
public static final int DW_LNS_COPY = 0x01;
|
||||||
|
|
|
@ -15,10 +15,9 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.backend.wasm.generate;
|
package org.teavm.backend.wasm.generate;
|
||||||
|
|
||||||
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_HIGH_PC;
|
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_DECLARATION;
|
||||||
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_NAME;
|
||||||
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_ADDR;
|
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_FLAG_PRESENT;
|
||||||
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_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;
|
||||||
|
@ -30,6 +29,7 @@ import java.util.List;
|
||||||
import java.util.Map;
|
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.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
|
|
||||||
public class DwarfClassGenerator {
|
public class DwarfClassGenerator {
|
||||||
|
@ -64,13 +64,6 @@ public class DwarfClassGenerator {
|
||||||
return subprogramsByFunctionName.get(functionName);
|
return subprogramsByFunctionName.get(functionName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Subprogram createSubprogram(String functionName) {
|
|
||||||
var subprogram = new Subprogram(functionName);
|
|
||||||
subprogramsByFunctionName.put(functionName, subprogram);
|
|
||||||
rootSubprograms.add(subprogram);
|
|
||||||
return subprogram;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void write(DwarfInfoWriter infoWriter, DwarfStrings strings) {
|
public void write(DwarfInfoWriter infoWriter, DwarfStrings strings) {
|
||||||
this.infoWriter = infoWriter;
|
this.infoWriter = infoWriter;
|
||||||
this.strings = strings;
|
this.strings = strings;
|
||||||
|
@ -87,8 +80,7 @@ public class DwarfClassGenerator {
|
||||||
if (methodAbbrev == null) {
|
if (methodAbbrev == null) {
|
||||||
methodAbbrev = infoWriter.abbreviation(DW_TAG_SUBPROGRAM, true, data -> {
|
methodAbbrev = infoWriter.abbreviation(DW_TAG_SUBPROGRAM, true, data -> {
|
||||||
data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP);
|
data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP);
|
||||||
data.writeLEB(DW_AT_LOW_PC).writeLEB(DW_FORM_ADDR);
|
data.writeLEB(DW_AT_DECLARATION).writeLEB(DW_FORM_FLAG_PRESENT);
|
||||||
data.writeLEB(DW_AT_HIGH_PC).writeLEB(DW_FORM_ADDR);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return methodAbbrev;
|
return methodAbbrev;
|
||||||
|
@ -170,18 +162,16 @@ public class DwarfClassGenerator {
|
||||||
|
|
||||||
public class Subprogram {
|
public class Subprogram {
|
||||||
public final String name;
|
public final String name;
|
||||||
public int startAddress;
|
public DwarfPlaceholder ref;
|
||||||
public int endAddress;
|
|
||||||
|
|
||||||
private Subprogram(String name) {
|
private Subprogram(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void write() {
|
private void write() {
|
||||||
infoWriter.tag(getMethodAbbrev());
|
ref = infoWriter.placeholder(4);
|
||||||
|
infoWriter.mark(ref).tag(getMethodAbbrev());
|
||||||
infoWriter.writeInt(strings.stringRef(name));
|
infoWriter.writeInt(strings.stringRef(name));
|
||||||
infoWriter.writeInt(startAddress);
|
|
||||||
infoWriter.writeInt(endAddress);
|
|
||||||
infoWriter.emptyTag();
|
infoWriter.emptyTag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,14 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.backend.wasm.render;
|
package org.teavm.backend.wasm.render;
|
||||||
|
|
||||||
|
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_HIGH_PC;
|
||||||
|
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_FORM_ADDR;
|
||||||
|
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_TAG_SUBPROGRAM;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -23,6 +31,9 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
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.generate.DwarfClassGenerator;
|
import org.teavm.backend.wasm.generate.DwarfClassGenerator;
|
||||||
import org.teavm.backend.wasm.generate.DwarfGenerator;
|
import org.teavm.backend.wasm.generate.DwarfGenerator;
|
||||||
import org.teavm.backend.wasm.model.WasmCustomSection;
|
import org.teavm.backend.wasm.model.WasmCustomSection;
|
||||||
|
@ -57,6 +68,8 @@ public class WasmBinaryRenderer {
|
||||||
private boolean obfuscated;
|
private boolean obfuscated;
|
||||||
private DwarfGenerator dwarfGenerator;
|
private DwarfGenerator dwarfGenerator;
|
||||||
private DwarfClassGenerator dwarfClassGen;
|
private DwarfClassGenerator dwarfClassGen;
|
||||||
|
private DwarfAbbreviation methodAbbrev;
|
||||||
|
private DwarfAbbreviation functionAbbrev;
|
||||||
|
|
||||||
public WasmBinaryRenderer(WasmBinaryWriter output, WasmBinaryVersion version, boolean obfuscated,
|
public WasmBinaryRenderer(WasmBinaryWriter output, WasmBinaryVersion version, boolean obfuscated,
|
||||||
DwarfGenerator dwarfGenerator, DwarfClassGenerator dwarfClassGen) {
|
DwarfGenerator dwarfGenerator, DwarfClassGenerator dwarfClassGen) {
|
||||||
|
@ -286,6 +299,25 @@ public class WasmBinaryRenderer {
|
||||||
private byte[] renderFunction(WasmFunction function, int offset) {
|
private byte[] renderFunction(WasmFunction function, int offset) {
|
||||||
var code = new WasmBinaryWriter();
|
var code = new WasmBinaryWriter();
|
||||||
|
|
||||||
|
Marker endProgramMarker;
|
||||||
|
if (dwarfClassGen != null && function.getName() != null) {
|
||||||
|
var dwarfSubprogram = dwarfClassGen.getSubprogram(function.getName());
|
||||||
|
var writer = dwarfGenerator.getInfoWriter();
|
||||||
|
var strings = dwarfGenerator.strings;
|
||||||
|
writer.tag(dwarfSubprogram != null ? getMethodAbbrev() : getFunctionAbbrev());
|
||||||
|
if (dwarfSubprogram != null) {
|
||||||
|
writer.ref(dwarfSubprogram.ref, Blob::writeInt);
|
||||||
|
} else {
|
||||||
|
writer.writeInt(strings.stringRef(
|
||||||
|
dwarfSubprogram != null ? dwarfSubprogram.name : function.getName()));
|
||||||
|
}
|
||||||
|
writer.writeInt(offset);
|
||||||
|
endProgramMarker = writer.marker();
|
||||||
|
writer.skip(4);
|
||||||
|
} else {
|
||||||
|
endProgramMarker = null;
|
||||||
|
}
|
||||||
|
|
||||||
List<WasmLocal> localVariables = function.getLocalVariables();
|
List<WasmLocal> localVariables = function.getLocalVariables();
|
||||||
int parameterCount = Math.min(function.getParameters().size(), localVariables.size());
|
int parameterCount = Math.min(function.getParameters().size(), localVariables.size());
|
||||||
localVariables = localVariables.subList(parameterCount, localVariables.size());
|
localVariables = localVariables.subList(parameterCount, localVariables.size());
|
||||||
|
@ -324,13 +356,14 @@ public class WasmBinaryRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
code.writeByte(0x0B);
|
code.writeByte(0x0B);
|
||||||
if (dwarfClassGen != null && function.getName() != null) {
|
|
||||||
var dwarfSubprogram = dwarfClassGen.getSubprogram(function.getName());
|
if (endProgramMarker != null) {
|
||||||
if (dwarfSubprogram == null) {
|
var dwarfWriter = dwarfGenerator.getInfoWriter();
|
||||||
dwarfSubprogram = dwarfClassGen.createSubprogram(function.getName());
|
var backup = dwarfWriter.marker();
|
||||||
}
|
endProgramMarker.rewind();
|
||||||
dwarfSubprogram.startAddress = offset;
|
dwarfWriter.writeInt(offset + code.getPosition());
|
||||||
dwarfSubprogram.endAddress = offset + code.getPosition();
|
backup.rewind();
|
||||||
|
dwarfWriter.emptyTag();
|
||||||
}
|
}
|
||||||
|
|
||||||
return code.getData();
|
return code.getData();
|
||||||
|
@ -432,4 +465,27 @@ public class WasmBinaryRenderer {
|
||||||
|
|
||||||
output.writeBytes(data);
|
output.writeBytes(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private DwarfAbbreviation getMethodAbbrev() {
|
||||||
|
if (methodAbbrev == null) {
|
||||||
|
methodAbbrev = dwarfGenerator.getInfoWriter().abbreviation(DW_TAG_SUBPROGRAM, true, data -> {
|
||||||
|
data.writeLEB(DW_AT_SPECIFICATION).writeLEB(DW_FORM_REF4);
|
||||||
|
data.writeLEB(DW_AT_LOW_PC).writeLEB(DW_FORM_ADDR);
|
||||||
|
data.writeLEB(DW_AT_HIGH_PC).writeLEB(DW_FORM_ADDR);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return methodAbbrev;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DwarfAbbreviation getFunctionAbbrev() {
|
||||||
|
if (functionAbbrev == null) {
|
||||||
|
functionAbbrev = dwarfGenerator.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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user