Wasm: generate nested DIEs for namespaces/classes/methods

This commit is contained in:
Alexey Andreev 2022-11-20 16:12:00 +01:00
parent 6222241651
commit 8fac3237ba
6 changed files with 246 additions and 39 deletions

View File

@ -40,6 +40,7 @@ import org.teavm.backend.lowlevel.generate.NameProvider;
import org.teavm.backend.lowlevel.generate.NameProviderWithSpecialNames; import org.teavm.backend.lowlevel.generate.NameProviderWithSpecialNames;
import org.teavm.backend.lowlevel.transform.CoroutineTransformation; import org.teavm.backend.lowlevel.transform.CoroutineTransformation;
import org.teavm.backend.wasm.binary.BinaryWriter; import org.teavm.backend.wasm.binary.BinaryWriter;
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.generate.WasmClassGenerator; import org.teavm.backend.wasm.generate.WasmClassGenerator;
import org.teavm.backend.wasm.generate.WasmDependencyListener; import org.teavm.backend.wasm.generate.WasmDependencyListener;
@ -445,9 +446,10 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
BinaryWriter binaryWriter = new BinaryWriter(256); BinaryWriter binaryWriter = new BinaryWriter(256);
var names = new NameProviderWithSpecialNames(new WasmNameProvider(), controller.getUnprocessedClassSource()); var names = new NameProviderWithSpecialNames(new WasmNameProvider(), controller.getUnprocessedClassSource());
var metadataRequirements = new ClassMetadataRequirements(controller.getDependencyInfo()); var metadataRequirements = new ClassMetadataRequirements(controller.getDependencyInfo());
var dwarfClassGen = debugging ? new DwarfClassGenerator() : null;
var classGenerator = new WasmClassGenerator(classes, controller.getUnprocessedClassSource(), var classGenerator = new WasmClassGenerator(classes, controller.getUnprocessedClassSource(),
vtableProvider, tagRegistry, binaryWriter, names, metadataRequirements, vtableProvider, tagRegistry, binaryWriter, names, metadataRequirements,
controller.getClassInitializerInfo(), characteristics); controller.getClassInitializerInfo(), characteristics, dwarfClassGen);
Decompiler decompiler = new Decompiler(classes, new HashSet<>(), false); Decompiler decompiler = new Decompiler(classes, new HashSet<>(), false);
var stringPool = classGenerator.getStringPool(); var stringPool = classGenerator.getStringPool();
@ -501,7 +503,7 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
var generator = new WasmGenerator(decompiler, classes, context, classGenerator, binaryWriter, var generator = new WasmGenerator(decompiler, classes, context, classGenerator, binaryWriter,
asyncMethods::contains); asyncMethods::contains);
generateMethods(classes, context, generator, classGenerator, binaryWriter, module); generateMethods(classes, context, generator, classGenerator, binaryWriter, module, dwarfClassGen);
new WasmInteropFunctionGenerator(classGenerator).generateFunctions(module); new WasmInteropFunctionGenerator(classGenerator).generateFunctions(module);
exceptionHandlingIntrinsic.postProcess(CallSiteDescriptor.extract(classes, classes.getClassNames())); exceptionHandlingIntrinsic.postProcess(CallSiteDescriptor.extract(classes, classes.getClassNames()));
generateIsSupertypeFunctions(tagRegistry, module, classGenerator); generateIsSupertypeFunctions(tagRegistry, module, classGenerator);
@ -545,8 +547,8 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
} }
var writer = new WasmBinaryWriter(); var writer = new WasmBinaryWriter();
var renderer = new WasmBinaryRenderer(writer, version, obfuscated, dwarfGenerator); var renderer = new WasmBinaryRenderer(writer, version, obfuscated, dwarfGenerator, dwarfClassGen);
renderer.render(module, buildDwarf(dwarfGenerator)); renderer.render(module, buildDwarf(dwarfGenerator, dwarfClassGen));
try (OutputStream output = buildTarget.createResource(outputName)) { try (OutputStream output = buildTarget.createResource(outputName)) {
output.write(writer.getData()); output.write(writer.getData());
@ -565,11 +567,13 @@ 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();
}; };
@ -710,7 +714,8 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
} }
private void generateMethods(ListableClassHolderSource classes, WasmGenerationContext context, private void generateMethods(ListableClassHolderSource classes, WasmGenerationContext context,
WasmGenerator generator, WasmClassGenerator classGenerator, BinaryWriter binaryWriter, WasmModule module) { WasmGenerator generator, WasmClassGenerator classGenerator, BinaryWriter binaryWriter, WasmModule module,
DwarfClassGenerator dwarfClassGen) {
List<MethodHolder> methods = new ArrayList<>(); List<MethodHolder> methods = new ArrayList<>();
for (String className : classes.getClassNames()) { for (String className : classes.getClassNames()) {
ClassHolder cls = classes.get(className); ClassHolder cls = classes.get(className);
@ -772,6 +777,11 @@ public class WasmTarget implements TeaVMTarget, TeaVMWasmHost {
} else { } else {
generateStub(context.names, module, method, implementor); generateStub(context.names, module, method, implementor);
} }
if (dwarfClassGen != null) {
var dwarfClass = dwarfClassGen.getClass(method.getOwnerName());
var dwarfSubprogram = dwarfClass.getSubprogram(method.getDescriptor());
dwarfClassGen.registerSubprogram(context.names.forMethod(method.getReference()), dwarfSubprogram);
}
if (controller.wasCancelled()) { if (controller.wasCancelled()) {
return; return;
} }

View File

@ -20,15 +20,20 @@ public final class DwarfConstants {
public static final int DW_UT_COMPILE = 0x01; public static final int DW_UT_COMPILE = 0x01;
public static final int DW_TAG_CLASS_TYPE = 0x02;
public static final int DW_TAG_COMPILE_UNIT = 0x11; public static final int DW_TAG_COMPILE_UNIT = 0x11;
public static final int DW_TAG_SUBPROGRAM = 0x2E; public static final int DW_TAG_SUBPROGRAM = 0x2E;
public static final int DW_TAG_NAMESPACE = 0x39;
public static final int DW_AT_NAME = 0x03; public static final int DW_AT_NAME = 0x03;
public static final int DW_AT_STMT_LIST = 0x10; public static final int DW_AT_STMT_LIST = 0x10;
public static final int DW_AT_LOW_PC = 0x11; public static final int DW_AT_LOW_PC = 0x11;
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_PRODUCER = 0x25; public static final int DW_AT_PRODUCER = 0x25;
public static final int DW_LANG_JAVA = 0x0b;
public static final int DW_CHILDREN_YES = 1; public static final int DW_CHILDREN_YES = 1;
public static final int DW_CHILDREN_NO = 0; public static final int DW_CHILDREN_NO = 0;

View File

@ -0,0 +1,188 @@
/*
* Copyright 2022 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
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_LOW_PC;
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_STRP;
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_SUBPROGRAM;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.teavm.backend.wasm.dwarf.DwarfAbbreviation;
import org.teavm.backend.wasm.dwarf.DwarfInfoWriter;
import org.teavm.model.MethodDescriptor;
public class DwarfClassGenerator {
final Namespace root = new Namespace(null);
final Map<String, Subprogram> subprogramsByFunctionName = new HashMap<>();
final List<Subprogram> rootSubprograms = new ArrayList<>();
private DwarfInfoWriter infoWriter;
private DwarfStrings strings;
private DwarfAbbreviation nsAbbrev;
private DwarfAbbreviation classTypeAbbrev;
private DwarfAbbreviation methodAbbrev;
public ClassType getClass(String fullName) {
var index = 0;
var ns = root;
while (true) {
var next = fullName.indexOf('.', index);
if (next < 0) {
break;
}
ns = ns.getNamespace(fullName.substring(index, next));
index = next + 1;
}
return ns.getClass(fullName.substring(index));
}
public void registerSubprogram(String functionName, Subprogram subprogram) {
subprogramsByFunctionName.put(functionName, subprogram);
}
public Subprogram getSubprogram(String 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) {
this.infoWriter = infoWriter;
this.strings = strings;
root.writeChildren();
for (var subprogram : rootSubprograms) {
subprogram.write();
}
this.infoWriter = null;
this.strings = null;
methodAbbrev = null;
}
private DwarfAbbreviation getMethodAbbrev() {
if (methodAbbrev == null) {
methodAbbrev = infoWriter.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 methodAbbrev;
}
private DwarfAbbreviation getNsAbbrev() {
if (nsAbbrev == null) {
nsAbbrev = infoWriter.abbreviation(DW_TAG_NAMESPACE, true, data -> {
data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP);
});
}
return nsAbbrev;
}
private DwarfAbbreviation getClassTypeAbbrev() {
if (classTypeAbbrev == null) {
classTypeAbbrev = infoWriter.abbreviation(DW_TAG_CLASS_TYPE, true, data -> {
data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP);
});
}
return classTypeAbbrev;
}
public class Namespace {
public final String name;
final Map<String, Namespace> namespaces = new LinkedHashMap<>();
final Map<String, ClassType> classes = new LinkedHashMap<>();
private Namespace(String name) {
this.name = name;
}
private Namespace getNamespace(String name) {
return namespaces.computeIfAbsent(name, Namespace::new);
}
private void write() {
infoWriter.tag(getNsAbbrev());
infoWriter.writeInt(strings.stringRef(name));
writeChildren();
infoWriter.emptyTag();
}
private void writeChildren() {
for (var child : namespaces.values()) {
child.write();
}
for (var child : classes.values()) {
child.write();
}
}
ClassType getClass(String name) {
return classes.computeIfAbsent(name, ClassType::new);
}
}
public class ClassType {
public final String name;
final Map<MethodDescriptor, Subprogram> subprograms = new LinkedHashMap<>();
private ClassType(String name) {
this.name = name;
}
public Subprogram getSubprogram(MethodDescriptor desc) {
return subprograms.computeIfAbsent(desc, d -> new Subprogram(d.getName()));
}
private void write() {
infoWriter.tag(getClassTypeAbbrev());
infoWriter.writeInt(strings.stringRef(name));
for (var child : subprograms.values()) {
child.write();
}
infoWriter.emptyTag();
}
}
public class Subprogram {
public final String name;
public int startAddress;
public int endAddress;
private Subprogram(String name) {
this.name = name;
}
private void write() {
infoWriter.tag(getMethodAbbrev());
infoWriter.writeInt(strings.stringRef(name));
infoWriter.writeInt(startAddress);
infoWriter.writeInt(endAddress);
infoWriter.emptyTag();
}
}
}

View File

@ -16,11 +16,21 @@
package org.teavm.backend.wasm.generate; package org.teavm.backend.wasm.generate;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DWARF_VERSION; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DWARF_VERSION;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_HIGH_PC;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_LANGUAGE;
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_PRODUCER;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_AT_STMT_LIST;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_ADDR;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_DATA2;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_SEC_OFFSET;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_FORM_STRP;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_LANG_JAVA;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_COMPILE_UNIT; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_TAG_COMPILE_UNIT;
import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_UT_COMPILE; import static org.teavm.backend.wasm.dwarf.DwarfConstants.DW_UT_COMPILE;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import org.teavm.backend.wasm.dwarf.DwarfConstants;
import org.teavm.backend.wasm.dwarf.DwarfInfoWriter; import org.teavm.backend.wasm.dwarf.DwarfInfoWriter;
import org.teavm.backend.wasm.dwarf.DwarfPlaceholder; import org.teavm.backend.wasm.dwarf.DwarfPlaceholder;
import org.teavm.backend.wasm.dwarf.blob.Blob; import org.teavm.backend.wasm.dwarf.blob.Blob;
@ -64,13 +74,15 @@ public class DwarfGenerator {
private void compilationUnit() { private void compilationUnit() {
infoWriter.tag(infoWriter.abbreviation(DW_TAG_COMPILE_UNIT, true, data -> { infoWriter.tag(infoWriter.abbreviation(DW_TAG_COMPILE_UNIT, true, data -> {
data.writeLEB(DwarfConstants.DW_AT_PRODUCER).writeLEB(DwarfConstants.DW_FORM_STRP); data.writeLEB(DW_AT_PRODUCER).writeLEB(DW_FORM_STRP);
data.writeLEB(DwarfConstants.DW_AT_NAME).writeLEB(DwarfConstants.DW_FORM_STRP); data.writeLEB(DW_AT_LANGUAGE).writeLEB(DW_FORM_DATA2);
data.writeLEB(DwarfConstants.DW_AT_STMT_LIST).writeLEB(DwarfConstants.DW_FORM_SEC_OFFSET); data.writeLEB(DW_AT_NAME).writeLEB(DW_FORM_STRP);
data.writeLEB(DwarfConstants.DW_AT_LOW_PC).writeLEB(DwarfConstants.DW_FORM_ADDR); data.writeLEB(DW_AT_STMT_LIST).writeLEB(DW_FORM_SEC_OFFSET);
data.writeLEB(DwarfConstants.DW_AT_HIGH_PC).writeLEB(DwarfConstants.DW_FORM_ADDR); data.writeLEB(DW_AT_LOW_PC).writeLEB(DW_FORM_ADDR);
data.writeLEB(DW_AT_HIGH_PC).writeLEB(DW_FORM_ADDR);
})); }));
infoWriter.writeInt(strings.stringRef("TeaVM")); infoWriter.writeInt(strings.stringRef("TeaVM"));
infoWriter.writeShort(DW_LANG_JAVA);
infoWriter.writeInt(strings.stringRef("classes.wasm")); infoWriter.writeInt(strings.stringRef("classes.wasm"));
infoWriter.writeInt(0); infoWriter.writeInt(0);
infoWriter.writeInt(0); infoWriter.writeInt(0);

View File

@ -97,6 +97,7 @@ public class WasmClassGenerator {
private int classCount; private int classCount;
private ClassMetadataRequirements metadataRequirements; private ClassMetadataRequirements metadataRequirements;
private ClassInitializerInfo classInitializerInfo; private ClassInitializerInfo classInitializerInfo;
private DwarfClassGenerator dwarfClassGenerator;
private static final int CLASS_SIZE = 1; private static final int CLASS_SIZE = 1;
private static final int CLASS_FLAGS = 2; private static final int CLASS_FLAGS = 2;
@ -117,7 +118,8 @@ public class WasmClassGenerator {
public WasmClassGenerator(ClassReaderSource processedClassSource, ClassReaderSource classSource, public WasmClassGenerator(ClassReaderSource processedClassSource, ClassReaderSource classSource,
VirtualTableProvider vtableProvider, TagRegistry tagRegistry, BinaryWriter binaryWriter, VirtualTableProvider vtableProvider, TagRegistry tagRegistry, BinaryWriter binaryWriter,
NameProvider names, ClassMetadataRequirements metadataRequirements, NameProvider names, ClassMetadataRequirements metadataRequirements,
ClassInitializerInfo classInitializerInfo, Characteristics characteristics) { ClassInitializerInfo classInitializerInfo, Characteristics characteristics,
DwarfClassGenerator dwarfClassGenerator) {
this.processedClassSource = processedClassSource; this.processedClassSource = processedClassSource;
this.classSource = classSource; this.classSource = classSource;
this.vtableProvider = vtableProvider; this.vtableProvider = vtableProvider;
@ -128,6 +130,7 @@ public class WasmClassGenerator {
this.metadataRequirements = metadataRequirements; this.metadataRequirements = metadataRequirements;
this.classInitializerInfo = classInitializerInfo; this.classInitializerInfo = classInitializerInfo;
this.characteristics = characteristics; this.characteristics = characteristics;
this.dwarfClassGenerator = dwarfClassGenerator;
} }
public WasmStringPool getStringPool() { public WasmStringPool getStringPool() {
@ -173,13 +176,16 @@ public class WasmClassGenerator {
binaryData.start = binaryWriter.append(binaryData.data); binaryData.start = binaryWriter.append(binaryData.data);
} else if (type instanceof ValueType.Object) { } else if (type instanceof ValueType.Object) {
String className = ((ValueType.Object) type).getClassName(); String className = ((ValueType.Object) type).getClassName();
ClassReader cls = classSource.get(className); var cls = classSource.get(className);
if (cls != null) { if (cls != null) {
calculateLayout(cls, binaryData); calculateLayout(cls, binaryData);
if (binaryData.start >= 0) { if (binaryData.start >= 0) {
binaryData.start = binaryWriter.append(createStructure(binaryData)); binaryData.start = binaryWriter.append(createStructure(binaryData));
} }
if (dwarfClassGenerator != null) {
dwarfClassGenerator.getClass(className);
}
} }
} else if (type instanceof ValueType.Array) { } else if (type instanceof ValueType.Array) {
ValueType itemType = ((ValueType.Array) type).getItemType(); ValueType itemType = ((ValueType.Array) type).getItemType();

View File

@ -15,7 +15,6 @@
*/ */
package org.teavm.backend.wasm.render; package org.teavm.backend.wasm.render;
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;
@ -24,9 +23,7 @@ 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.generate.DwarfClassGenerator;
import org.teavm.backend.wasm.dwarf.DwarfConstants;
import org.teavm.backend.wasm.dwarf.DwarfInfoWriter;
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;
import org.teavm.backend.wasm.model.WasmFunction; import org.teavm.backend.wasm.model.WasmFunction;
@ -59,16 +56,15 @@ public class WasmBinaryRenderer {
private Map<String, Integer> functionIndexes = new HashMap<>(); private Map<String, Integer> functionIndexes = new HashMap<>();
private boolean obfuscated; private boolean obfuscated;
private DwarfGenerator dwarfGenerator; private DwarfGenerator dwarfGenerator;
private DwarfInfoWriter infoWriter; private DwarfClassGenerator dwarfClassGen;
private DwarfAbbreviation methodAbbrev;
public WasmBinaryRenderer(WasmBinaryWriter output, WasmBinaryVersion version, boolean obfuscated, public WasmBinaryRenderer(WasmBinaryWriter output, WasmBinaryVersion version, boolean obfuscated,
DwarfGenerator dwarfGenerator) { DwarfGenerator dwarfGenerator, DwarfClassGenerator dwarfClassGen) {
this.output = output; this.output = output;
this.version = version; this.version = version;
this.obfuscated = obfuscated; this.obfuscated = obfuscated;
this.dwarfGenerator = dwarfGenerator; this.dwarfGenerator = dwarfGenerator;
infoWriter = dwarfGenerator != null ? dwarfGenerator.getInfoWriter() : null; this.dwarfClassGen = dwarfClassGen;
} }
public void render(WasmModule module) { public void render(WasmModule module) {
@ -328,28 +324,18 @@ public class WasmBinaryRenderer {
} }
code.writeByte(0x0B); code.writeByte(0x0B);
if (dwarfGenerator != null && function.getName() != null) { if (dwarfClassGen != null && function.getName() != null) {
infoWriter.tag(getMethodAbbrev()); var dwarfSubprogram = dwarfClassGen.getSubprogram(function.getName());
infoWriter.writeInt(dwarfGenerator.strings.stringRef(function.getName())); if (dwarfSubprogram == null) {
infoWriter.writeInt(offset); dwarfSubprogram = dwarfClassGen.createSubprogram(function.getName());
infoWriter.writeInt(offset + code.getPosition() - 1); }
infoWriter.emptyTag(); dwarfSubprogram.startAddress = offset;
dwarfSubprogram.endAddress = offset + code.getPosition();
} }
return code.getData(); return code.getData();
} }
private DwarfAbbreviation getMethodAbbrev() {
if (methodAbbrev == null) {
methodAbbrev = infoWriter.abbreviation(DW_TAG_SUBPROGRAM, true, data -> {
data.writeLEB(DwarfConstants.DW_AT_NAME).writeLEB(DwarfConstants.DW_FORM_STRP);
data.writeLEB(DwarfConstants.DW_AT_LOW_PC).writeLEB(DwarfConstants.DW_FORM_ADDR);
data.writeLEB(DwarfConstants.DW_AT_HIGH_PC).writeLEB(DwarfConstants.DW_FORM_ADDR);
});
}
return methodAbbrev;
}
private void renderInitializer(WasmBinaryWriter output, int value) { private void renderInitializer(WasmBinaryWriter output, int value) {
output.writeByte(0x41); output.writeByte(0x41);
output.writeLEB(value); output.writeLEB(value);