mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-31 12:24:10 -08:00
Wasm: generate nested DIEs for namespaces/classes/methods
This commit is contained in:
parent
6222241651
commit
8fac3237ba
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user