mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Wasm: trying to improve debug information emitter
This commit is contained in:
parent
1d2633ed76
commit
57e0227a02
|
@ -22,6 +22,8 @@ public interface DebugLines {
|
|||
|
||||
void location(String file, int line);
|
||||
|
||||
void emptyLocation();
|
||||
|
||||
void start(MethodReference methodReference);
|
||||
|
||||
void end();
|
||||
|
|
|
@ -66,6 +66,11 @@ public class DebugLinesBuilder extends DebugSectionBuilder implements DebugLines
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emptyLocation() {
|
||||
location(null, -1);
|
||||
}
|
||||
|
||||
private void flushPtr() {
|
||||
if (ptr != lastWrittenPtr) {
|
||||
blob.writeLEB(DebugConstants.LOC_PTR);
|
||||
|
|
|
@ -55,11 +55,16 @@ public class LineInfo {
|
|||
public void dump(PrintStream out) {
|
||||
for (var i = 0; i < sequences.length; ++i) {
|
||||
var sequence = sequences[i];
|
||||
out.println("Sequence " + i + ": " + sequence.method().fullName() + " [" + sequence.startAddress() + ".."
|
||||
+ sequence.endAddress() + ")");
|
||||
out.println("Sequence " + i + ": " + sequence.method().fullName() + " ["
|
||||
+ Integer.toHexString(sequence.startAddress()) + ".."
|
||||
+ Integer.toHexString(sequence.endAddress()) + ")");
|
||||
for (var location : sequence.unpack().locations()) {
|
||||
out.println(" at " + location.address() + " " + location.location().file().fullName() + ":"
|
||||
+ location.location().line());
|
||||
out.print(" at " + Integer.toHexString(location.address()) + " ");
|
||||
if (location.location() != null) {
|
||||
out.println(location.location().file().fullName() + ":" + location.location().line());
|
||||
} else {
|
||||
out.println("<unmapped>");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ public class LineInfoCommandExecutor implements LineInfoCommandVisitor {
|
|||
private InliningLocation inliningLocation;
|
||||
|
||||
public InstructionLocation createLocation() {
|
||||
return file != null ? new InstructionLocation(address, new Location(file, line, inliningLocation)) : null;
|
||||
return new InstructionLocation(address, file != null ? new Location(file, line, inliningLocation) : null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -56,7 +56,10 @@ public class LineInfoSequence {
|
|||
var locations = new ArrayList<InstructionLocation>();
|
||||
for (var command : commands) {
|
||||
command.acceptVisitor(commandExecutor);
|
||||
locations.add(commandExecutor.createLocation());
|
||||
var location = commandExecutor.createLocation();
|
||||
if (location != null) {
|
||||
locations.add(location);
|
||||
}
|
||||
}
|
||||
return new LineInfoUnpackedSequence(startAddress, endAddress, method, locations);
|
||||
}
|
||||
|
|
|
@ -328,13 +328,7 @@ public class WasmBinaryRenderer {
|
|||
for (var part : function.getBody()) {
|
||||
part.acceptVisitor(visitor);
|
||||
}
|
||||
|
||||
if (dwarfGenerator != null) {
|
||||
dwarfGenerator.endLineNumberSequence(offset + code.getPosition());
|
||||
}
|
||||
if (debugLines != null) {
|
||||
debugLines.end();
|
||||
}
|
||||
visitor.endLocation();
|
||||
|
||||
code.writeByte(0x0B);
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.util.Collections;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import org.teavm.backend.wasm.debug.DebugLines;
|
||||
import org.teavm.backend.wasm.generate.DwarfGenerator;
|
||||
import org.teavm.backend.wasm.model.WasmType;
|
||||
|
@ -56,6 +57,7 @@ import org.teavm.backend.wasm.model.expression.WasmStoreInt64;
|
|||
import org.teavm.backend.wasm.model.expression.WasmSwitch;
|
||||
import org.teavm.backend.wasm.model.expression.WasmUnreachable;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.TextLocation;
|
||||
|
||||
class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
||||
private WasmBinaryWriter writer;
|
||||
|
@ -70,6 +72,11 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
private Map<WasmBlock, Integer> blockDepths = new HashMap<>();
|
||||
private List<MethodReference> methodStack = new ArrayList<>();
|
||||
private List<MethodReference> currentMethodStack = new ArrayList<>();
|
||||
private TextLocation textLocationToEmit;
|
||||
private boolean deferTextLocationToEmit;
|
||||
private TextLocation lastEmittedLocation;
|
||||
private int positionToEmit;
|
||||
private List<TextLocation> locationStack = new ArrayList<>();
|
||||
|
||||
WasmBinaryRenderingVisitor(WasmBinaryWriter writer, WasmBinaryVersion version, Map<String, Integer> functionIndexes,
|
||||
Map<String, Integer> importedIndexes, Map<WasmSignature, Integer> signatureIndexes,
|
||||
|
@ -86,6 +93,8 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
|
||||
@Override
|
||||
public void visit(WasmBlock expression) {
|
||||
pushLocation(expression);
|
||||
pushLocation(expression);
|
||||
int blockDepth = 1;
|
||||
depth += blockDepth;
|
||||
blockDepths.put(expression, depth);
|
||||
|
@ -94,7 +103,9 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
for (WasmExpression part : expression.getBody()) {
|
||||
part.acceptVisitor(this);
|
||||
}
|
||||
popLocation();
|
||||
writer.writeByte(0x0B);
|
||||
popLocation();
|
||||
blockDepths.remove(expression);
|
||||
depth -= blockDepth;
|
||||
}
|
||||
|
@ -105,34 +116,32 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
|
||||
@Override
|
||||
public void visit(WasmBranch expression) {
|
||||
pushLocation(expression);
|
||||
if (expression.getResult() != null) {
|
||||
expression.getResult().acceptVisitor(this);
|
||||
}
|
||||
expression.getCondition().acceptVisitor(this);
|
||||
|
||||
emitLocation(expression);
|
||||
writer.writeByte(0x0D);
|
||||
|
||||
writeLabel(expression.getTarget());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmBreak expression) {
|
||||
pushLocation(expression);
|
||||
if (expression.getResult() != null) {
|
||||
expression.getResult().acceptVisitor(this);
|
||||
}
|
||||
|
||||
emitLocation(expression);
|
||||
writer.writeByte(0x0C);
|
||||
|
||||
writeLabel(expression.getTarget());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmSwitch expression) {
|
||||
pushLocation(expression);
|
||||
expression.getSelector().acceptVisitor(this);
|
||||
|
||||
emitLocation(expression);
|
||||
writer.writeByte(0x0E);
|
||||
|
||||
writer.writeLEB(expression.getTargets().size());
|
||||
|
@ -145,12 +154,14 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
int defaultDepth = blockDepths.get(expression.getDefaultTarget());
|
||||
int relativeDepth = depth - defaultDepth;
|
||||
writer.writeLEB(relativeDepth);
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmConditional expression) {
|
||||
pushLocation(expression);
|
||||
pushLocation(expression);
|
||||
expression.getCondition().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
writer.writeByte(0x04);
|
||||
writeBlockType(expression.getType());
|
||||
|
||||
|
@ -171,73 +182,84 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
}
|
||||
--depth;
|
||||
|
||||
popLocation();
|
||||
writer.writeByte(0x0B);
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmReturn expression) {
|
||||
pushLocation(expression);
|
||||
if (expression.getValue() != null) {
|
||||
expression.getValue().acceptVisitor(this);
|
||||
}
|
||||
emitLocation(expression);
|
||||
writer.writeByte(0x0F);
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmUnreachable expression) {
|
||||
emitLocation(expression);
|
||||
pushLocation(expression);
|
||||
writer.writeByte(0x0);
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmInt32Constant expression) {
|
||||
emitLocation(expression);
|
||||
pushLocation(expression);
|
||||
writer.writeByte(0x41);
|
||||
writer.writeSignedLEB(expression.getValue());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmInt64Constant expression) {
|
||||
emitLocation(expression);
|
||||
pushLocation(expression);
|
||||
writer.writeByte(0x42);
|
||||
writer.writeSignedLEB(expression.getValue());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmFloat32Constant expression) {
|
||||
emitLocation(expression);
|
||||
pushLocation(expression);
|
||||
writer.writeByte(0x43);
|
||||
writer.writeFixed(Float.floatToRawIntBits(expression.getValue()));
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmFloat64Constant expression) {
|
||||
emitLocation(expression);
|
||||
pushLocation(expression);
|
||||
writer.writeByte(0x44);
|
||||
writer.writeFixed(Double.doubleToRawLongBits(expression.getValue()));
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmGetLocal expression) {
|
||||
emitLocation(expression);
|
||||
pushLocation(expression);
|
||||
writer.writeByte(0x20);
|
||||
writer.writeLEB(expression.getLocal().getIndex());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmSetLocal expression) {
|
||||
pushLocation(expression);
|
||||
expression.getValue().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
writer.writeByte(0x21);
|
||||
writer.writeLEB(expression.getLocal().getIndex());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmIntBinary expression) {
|
||||
pushLocation(expression);
|
||||
expression.getFirst().acceptVisitor(this);
|
||||
expression.getSecond().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
render0xD(expression);
|
||||
popLocation();
|
||||
}
|
||||
|
||||
private void render0xD(WasmIntBinary expression) {
|
||||
|
@ -405,10 +427,11 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
|
||||
@Override
|
||||
public void visit(WasmFloatBinary expression) {
|
||||
pushLocation(expression);
|
||||
expression.getFirst().acceptVisitor(this);
|
||||
expression.getSecond().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
render0xD(expression);
|
||||
popLocation();
|
||||
}
|
||||
|
||||
private void render0xD(WasmFloatBinary expression) {
|
||||
|
@ -498,6 +521,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
|
||||
@Override
|
||||
public void visit(WasmIntUnary expression) {
|
||||
pushLocation(expression);
|
||||
expression.getOperand().acceptVisitor(this);
|
||||
switch (expression.getType()) {
|
||||
case INT32:
|
||||
|
@ -527,13 +551,15 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
}
|
||||
break;
|
||||
}
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmFloatUnary expression) {
|
||||
pushLocation(expression);
|
||||
expression.getOperand().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
render0xD(expression);
|
||||
popLocation();
|
||||
}
|
||||
|
||||
private void render0xD(WasmFloatUnary expression) {
|
||||
|
@ -599,8 +625,8 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
|
||||
@Override
|
||||
public void visit(WasmConversion expression) {
|
||||
pushLocation(expression);
|
||||
expression.getOperand().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
switch (expression.getSourceType()) {
|
||||
case INT32:
|
||||
switch (expression.getTargetType()) {
|
||||
|
@ -679,17 +705,18 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
}
|
||||
break;
|
||||
}
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmCall expression) {
|
||||
pushLocation(expression);
|
||||
for (WasmExpression argument : expression.getArguments()) {
|
||||
argument.acceptVisitor(this);
|
||||
}
|
||||
Integer functionIndex = !expression.isImported()
|
||||
? functionIndexes.get(expression.getFunctionName())
|
||||
: importedIndexes.get(expression.getFunctionName());
|
||||
emitLocation(expression);
|
||||
if (functionIndex == null) {
|
||||
writer.writeByte(0x00);
|
||||
return;
|
||||
|
@ -697,10 +724,12 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
|
||||
writer.writeByte(0x10);
|
||||
writer.writeLEB(functionIndex);
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmIndirectCall expression) {
|
||||
pushLocation(expression);
|
||||
for (WasmExpression argument : expression.getArguments()) {
|
||||
argument.acceptVisitor(this);
|
||||
}
|
||||
|
@ -715,19 +744,21 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
writer.writeLEB(signatureIndexes.get(new WasmSignature(signatureTypes)));
|
||||
|
||||
writer.writeByte(0);
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmDrop expression) {
|
||||
pushLocation(expression);
|
||||
expression.getOperand().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
writer.writeByte(0x1A);
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmLoadInt32 expression) {
|
||||
pushLocation(expression);
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
switch (expression.getConvertFrom()) {
|
||||
case INT8:
|
||||
writer.writeByte(0x2C);
|
||||
|
@ -747,12 +778,13 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
}
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmLoadInt64 expression) {
|
||||
pushLocation(expression);
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
switch (expression.getConvertFrom()) {
|
||||
case INT8:
|
||||
writer.writeByte(0x30);
|
||||
|
@ -778,31 +810,34 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
}
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmLoadFloat32 expression) {
|
||||
pushLocation(expression);
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
writer.writeByte(0x2A);
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmLoadFloat64 expression) {
|
||||
pushLocation(expression);
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
writer.writeByte(0x2B);
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmStoreInt32 expression) {
|
||||
pushLocation(expression);
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
expression.getValue().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
switch (expression.getConvertTo()) {
|
||||
case INT8:
|
||||
case UINT8:
|
||||
|
@ -818,13 +853,14 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
}
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmStoreInt64 expression) {
|
||||
pushLocation(expression);
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
expression.getValue().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
switch (expression.getConvertTo()) {
|
||||
case INT8:
|
||||
case UINT8:
|
||||
|
@ -844,34 +880,38 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
}
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmStoreFloat32 expression) {
|
||||
pushLocation(expression);
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
expression.getValue().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
writer.writeByte(0x38);
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmStoreFloat64 expression) {
|
||||
pushLocation(expression);
|
||||
expression.getIndex().acceptVisitor(this);
|
||||
expression.getValue().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
writer.writeByte(0x39);
|
||||
writer.writeByte(alignment(expression.getAlignment()));
|
||||
writer.writeLEB(expression.getOffset());
|
||||
popLocation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(WasmMemoryGrow expression) {
|
||||
pushLocation(expression);
|
||||
expression.getAmount().acceptVisitor(this);
|
||||
emitLocation(expression);
|
||||
writer.writeByte(0x40);
|
||||
writer.writeByte(0);
|
||||
popLocation();
|
||||
}
|
||||
|
||||
private int alignment(int value) {
|
||||
|
@ -883,18 +923,70 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
writer.writeLEB(depth - blockDepth);
|
||||
}
|
||||
|
||||
private void emitLocation(WasmExpression expression) {
|
||||
if (expression.getLocation() == null || expression.getLocation().getFileName() == null) {
|
||||
return;
|
||||
private void pushLocation(WasmExpression expression) {
|
||||
var location = expression.getLocation() != null
|
||||
? expression.getLocation()
|
||||
: locationStack.isEmpty() ? null : locationStack.get(locationStack.size() - 1);
|
||||
locationStack.add(location);
|
||||
if (location != null) {
|
||||
emitLocation(location);
|
||||
} else {
|
||||
emitDeferredLocation();
|
||||
}
|
||||
}
|
||||
|
||||
private void popLocation() {
|
||||
var location = locationStack.remove(locationStack.size() - 1);
|
||||
if (location != null) {
|
||||
emitLocation(location);
|
||||
}
|
||||
}
|
||||
|
||||
private void emitLocation(TextLocation location) {
|
||||
if (deferTextLocationToEmit && location != null) {
|
||||
textLocationToEmit = location;
|
||||
}
|
||||
flushLocation();
|
||||
textLocationToEmit = location;
|
||||
}
|
||||
|
||||
private void emitDeferredLocation() {
|
||||
flushLocation();
|
||||
textLocationToEmit = null;
|
||||
deferTextLocationToEmit = true;
|
||||
}
|
||||
|
||||
public void endLocation() {
|
||||
emitLocation(null);
|
||||
flushLocation();
|
||||
if (debugLines != null) {
|
||||
debugLines.end();
|
||||
}
|
||||
}
|
||||
|
||||
private void flushLocation() {
|
||||
if (writer.getPosition() != positionToEmit) {
|
||||
if (!Objects.equals(lastEmittedLocation, textLocationToEmit)) {
|
||||
doEmitLocation();
|
||||
}
|
||||
lastEmittedLocation = textLocationToEmit;
|
||||
positionToEmit = writer.getPosition();
|
||||
}
|
||||
}
|
||||
|
||||
private void doEmitLocation() {
|
||||
var address = positionToEmit + addressOffset;
|
||||
if (dwarfGenerator != null) {
|
||||
dwarfGenerator.lineNumber(writer.getPosition() + addressOffset, expression.getLocation().getFileName(),
|
||||
expression.getLocation().getLine());
|
||||
if (textLocationToEmit == null) {
|
||||
dwarfGenerator.endLineNumberSequence(address);
|
||||
} else {
|
||||
dwarfGenerator.lineNumber(address, textLocationToEmit.getFileName(), textLocationToEmit.getLine());
|
||||
}
|
||||
}
|
||||
if (debugLines != null) {
|
||||
debugLines.advance(writer.getPosition() + addressOffset);
|
||||
var loc = expression.getLocation();
|
||||
var inlining = loc.getInlining();
|
||||
debugLines.advance(address);
|
||||
var loc = textLocationToEmit;
|
||||
var inlining = loc != null ? loc.getInlining() : null;
|
||||
while (inlining != null) {
|
||||
currentMethodStack.add(loc.getInlining().getMethod());
|
||||
inlining = inlining.getParent();
|
||||
|
@ -915,7 +1007,11 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
|
|||
debugLines.start(method);
|
||||
}
|
||||
currentMethodStack.clear();
|
||||
debugLines.location(loc.getFileName(), loc.getLine());
|
||||
if (loc != null) {
|
||||
debugLines.location(loc.getFileName(), loc.getLine());
|
||||
} else {
|
||||
debugLines.emptyLocation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user