Wasm: trying to improve debug information emitter

This commit is contained in:
Alexey Andreev 2022-12-01 17:33:35 +01:00
parent 1d2633ed76
commit 57e0227a02
7 changed files with 158 additions and 53 deletions

View File

@ -22,6 +22,8 @@ public interface DebugLines {
void location(String file, int line); void location(String file, int line);
void emptyLocation();
void start(MethodReference methodReference); void start(MethodReference methodReference);
void end(); void end();

View File

@ -66,6 +66,11 @@ public class DebugLinesBuilder extends DebugSectionBuilder implements DebugLines
} }
} }
@Override
public void emptyLocation() {
location(null, -1);
}
private void flushPtr() { private void flushPtr() {
if (ptr != lastWrittenPtr) { if (ptr != lastWrittenPtr) {
blob.writeLEB(DebugConstants.LOC_PTR); blob.writeLEB(DebugConstants.LOC_PTR);

View File

@ -55,11 +55,16 @@ public class LineInfo {
public void dump(PrintStream out) { public void dump(PrintStream out) {
for (var i = 0; i < sequences.length; ++i) { for (var i = 0; i < sequences.length; ++i) {
var sequence = sequences[i]; var sequence = sequences[i];
out.println("Sequence " + i + ": " + sequence.method().fullName() + " [" + sequence.startAddress() + ".." out.println("Sequence " + i + ": " + sequence.method().fullName() + " ["
+ sequence.endAddress() + ")"); + Integer.toHexString(sequence.startAddress()) + ".."
+ Integer.toHexString(sequence.endAddress()) + ")");
for (var location : sequence.unpack().locations()) { for (var location : sequence.unpack().locations()) {
out.println(" at " + location.address() + " " + location.location().file().fullName() + ":" out.print(" at " + Integer.toHexString(location.address()) + " ");
+ location.location().line()); if (location.location() != null) {
out.println(location.location().file().fullName() + ":" + location.location().line());
} else {
out.println("<unmapped>");
}
} }
} }
} }

View File

@ -22,7 +22,7 @@ public class LineInfoCommandExecutor implements LineInfoCommandVisitor {
private InliningLocation inliningLocation; private InliningLocation inliningLocation;
public InstructionLocation createLocation() { 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 @Override

View File

@ -56,7 +56,10 @@ public class LineInfoSequence {
var locations = new ArrayList<InstructionLocation>(); var locations = new ArrayList<InstructionLocation>();
for (var command : commands) { for (var command : commands) {
command.acceptVisitor(commandExecutor); command.acceptVisitor(commandExecutor);
locations.add(commandExecutor.createLocation()); var location = commandExecutor.createLocation();
if (location != null) {
locations.add(location);
}
} }
return new LineInfoUnpackedSequence(startAddress, endAddress, method, locations); return new LineInfoUnpackedSequence(startAddress, endAddress, method, locations);
} }

View File

@ -328,13 +328,7 @@ public class WasmBinaryRenderer {
for (var part : function.getBody()) { for (var part : function.getBody()) {
part.acceptVisitor(visitor); part.acceptVisitor(visitor);
} }
visitor.endLocation();
if (dwarfGenerator != null) {
dwarfGenerator.endLineNumberSequence(offset + code.getPosition());
}
if (debugLines != null) {
debugLines.end();
}
code.writeByte(0x0B); code.writeByte(0x0B);

View File

@ -20,6 +20,7 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import org.teavm.backend.wasm.debug.DebugLines; import org.teavm.backend.wasm.debug.DebugLines;
import org.teavm.backend.wasm.generate.DwarfGenerator; import org.teavm.backend.wasm.generate.DwarfGenerator;
import org.teavm.backend.wasm.model.WasmType; 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.WasmSwitch;
import org.teavm.backend.wasm.model.expression.WasmUnreachable; import org.teavm.backend.wasm.model.expression.WasmUnreachable;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.model.TextLocation;
class WasmBinaryRenderingVisitor implements WasmExpressionVisitor { class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
private WasmBinaryWriter writer; private WasmBinaryWriter writer;
@ -70,6 +72,11 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
private Map<WasmBlock, Integer> blockDepths = new HashMap<>(); private Map<WasmBlock, Integer> blockDepths = new HashMap<>();
private List<MethodReference> methodStack = new ArrayList<>(); private List<MethodReference> methodStack = new ArrayList<>();
private List<MethodReference> currentMethodStack = 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, WasmBinaryRenderingVisitor(WasmBinaryWriter writer, WasmBinaryVersion version, Map<String, Integer> functionIndexes,
Map<String, Integer> importedIndexes, Map<WasmSignature, Integer> signatureIndexes, Map<String, Integer> importedIndexes, Map<WasmSignature, Integer> signatureIndexes,
@ -86,6 +93,8 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
@Override @Override
public void visit(WasmBlock expression) { public void visit(WasmBlock expression) {
pushLocation(expression);
pushLocation(expression);
int blockDepth = 1; int blockDepth = 1;
depth += blockDepth; depth += blockDepth;
blockDepths.put(expression, depth); blockDepths.put(expression, depth);
@ -94,7 +103,9 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
for (WasmExpression part : expression.getBody()) { for (WasmExpression part : expression.getBody()) {
part.acceptVisitor(this); part.acceptVisitor(this);
} }
popLocation();
writer.writeByte(0x0B); writer.writeByte(0x0B);
popLocation();
blockDepths.remove(expression); blockDepths.remove(expression);
depth -= blockDepth; depth -= blockDepth;
} }
@ -105,34 +116,32 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
@Override @Override
public void visit(WasmBranch expression) { public void visit(WasmBranch expression) {
pushLocation(expression);
if (expression.getResult() != null) { if (expression.getResult() != null) {
expression.getResult().acceptVisitor(this); expression.getResult().acceptVisitor(this);
} }
expression.getCondition().acceptVisitor(this); expression.getCondition().acceptVisitor(this);
emitLocation(expression);
writer.writeByte(0x0D); writer.writeByte(0x0D);
writeLabel(expression.getTarget()); writeLabel(expression.getTarget());
popLocation();
} }
@Override @Override
public void visit(WasmBreak expression) { public void visit(WasmBreak expression) {
pushLocation(expression);
if (expression.getResult() != null) { if (expression.getResult() != null) {
expression.getResult().acceptVisitor(this); expression.getResult().acceptVisitor(this);
} }
emitLocation(expression);
writer.writeByte(0x0C); writer.writeByte(0x0C);
writeLabel(expression.getTarget()); writeLabel(expression.getTarget());
popLocation();
} }
@Override @Override
public void visit(WasmSwitch expression) { public void visit(WasmSwitch expression) {
pushLocation(expression);
expression.getSelector().acceptVisitor(this); expression.getSelector().acceptVisitor(this);
emitLocation(expression);
writer.writeByte(0x0E); writer.writeByte(0x0E);
writer.writeLEB(expression.getTargets().size()); writer.writeLEB(expression.getTargets().size());
@ -145,12 +154,14 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
int defaultDepth = blockDepths.get(expression.getDefaultTarget()); int defaultDepth = blockDepths.get(expression.getDefaultTarget());
int relativeDepth = depth - defaultDepth; int relativeDepth = depth - defaultDepth;
writer.writeLEB(relativeDepth); writer.writeLEB(relativeDepth);
popLocation();
} }
@Override @Override
public void visit(WasmConditional expression) { public void visit(WasmConditional expression) {
pushLocation(expression);
pushLocation(expression);
expression.getCondition().acceptVisitor(this); expression.getCondition().acceptVisitor(this);
emitLocation(expression);
writer.writeByte(0x04); writer.writeByte(0x04);
writeBlockType(expression.getType()); writeBlockType(expression.getType());
@ -171,73 +182,84 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
} }
--depth; --depth;
popLocation();
writer.writeByte(0x0B); writer.writeByte(0x0B);
popLocation();
} }
@Override @Override
public void visit(WasmReturn expression) { public void visit(WasmReturn expression) {
pushLocation(expression);
if (expression.getValue() != null) { if (expression.getValue() != null) {
expression.getValue().acceptVisitor(this); expression.getValue().acceptVisitor(this);
} }
emitLocation(expression);
writer.writeByte(0x0F); writer.writeByte(0x0F);
popLocation();
} }
@Override @Override
public void visit(WasmUnreachable expression) { public void visit(WasmUnreachable expression) {
emitLocation(expression); pushLocation(expression);
writer.writeByte(0x0); writer.writeByte(0x0);
popLocation();
} }
@Override @Override
public void visit(WasmInt32Constant expression) { public void visit(WasmInt32Constant expression) {
emitLocation(expression); pushLocation(expression);
writer.writeByte(0x41); writer.writeByte(0x41);
writer.writeSignedLEB(expression.getValue()); writer.writeSignedLEB(expression.getValue());
popLocation();
} }
@Override @Override
public void visit(WasmInt64Constant expression) { public void visit(WasmInt64Constant expression) {
emitLocation(expression); pushLocation(expression);
writer.writeByte(0x42); writer.writeByte(0x42);
writer.writeSignedLEB(expression.getValue()); writer.writeSignedLEB(expression.getValue());
popLocation();
} }
@Override @Override
public void visit(WasmFloat32Constant expression) { public void visit(WasmFloat32Constant expression) {
emitLocation(expression); pushLocation(expression);
writer.writeByte(0x43); writer.writeByte(0x43);
writer.writeFixed(Float.floatToRawIntBits(expression.getValue())); writer.writeFixed(Float.floatToRawIntBits(expression.getValue()));
popLocation();
} }
@Override @Override
public void visit(WasmFloat64Constant expression) { public void visit(WasmFloat64Constant expression) {
emitLocation(expression); pushLocation(expression);
writer.writeByte(0x44); writer.writeByte(0x44);
writer.writeFixed(Double.doubleToRawLongBits(expression.getValue())); writer.writeFixed(Double.doubleToRawLongBits(expression.getValue()));
popLocation();
} }
@Override @Override
public void visit(WasmGetLocal expression) { public void visit(WasmGetLocal expression) {
emitLocation(expression); pushLocation(expression);
writer.writeByte(0x20); writer.writeByte(0x20);
writer.writeLEB(expression.getLocal().getIndex()); writer.writeLEB(expression.getLocal().getIndex());
popLocation();
} }
@Override @Override
public void visit(WasmSetLocal expression) { public void visit(WasmSetLocal expression) {
pushLocation(expression);
expression.getValue().acceptVisitor(this); expression.getValue().acceptVisitor(this);
emitLocation(expression);
writer.writeByte(0x21); writer.writeByte(0x21);
writer.writeLEB(expression.getLocal().getIndex()); writer.writeLEB(expression.getLocal().getIndex());
popLocation();
} }
@Override @Override
public void visit(WasmIntBinary expression) { public void visit(WasmIntBinary expression) {
pushLocation(expression);
expression.getFirst().acceptVisitor(this); expression.getFirst().acceptVisitor(this);
expression.getSecond().acceptVisitor(this); expression.getSecond().acceptVisitor(this);
emitLocation(expression);
render0xD(expression); render0xD(expression);
popLocation();
} }
private void render0xD(WasmIntBinary expression) { private void render0xD(WasmIntBinary expression) {
@ -405,10 +427,11 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
@Override @Override
public void visit(WasmFloatBinary expression) { public void visit(WasmFloatBinary expression) {
pushLocation(expression);
expression.getFirst().acceptVisitor(this); expression.getFirst().acceptVisitor(this);
expression.getSecond().acceptVisitor(this); expression.getSecond().acceptVisitor(this);
emitLocation(expression);
render0xD(expression); render0xD(expression);
popLocation();
} }
private void render0xD(WasmFloatBinary expression) { private void render0xD(WasmFloatBinary expression) {
@ -498,6 +521,7 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
@Override @Override
public void visit(WasmIntUnary expression) { public void visit(WasmIntUnary expression) {
pushLocation(expression);
expression.getOperand().acceptVisitor(this); expression.getOperand().acceptVisitor(this);
switch (expression.getType()) { switch (expression.getType()) {
case INT32: case INT32:
@ -527,13 +551,15 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
} }
break; break;
} }
popLocation();
} }
@Override @Override
public void visit(WasmFloatUnary expression) { public void visit(WasmFloatUnary expression) {
pushLocation(expression);
expression.getOperand().acceptVisitor(this); expression.getOperand().acceptVisitor(this);
emitLocation(expression);
render0xD(expression); render0xD(expression);
popLocation();
} }
private void render0xD(WasmFloatUnary expression) { private void render0xD(WasmFloatUnary expression) {
@ -599,8 +625,8 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
@Override @Override
public void visit(WasmConversion expression) { public void visit(WasmConversion expression) {
pushLocation(expression);
expression.getOperand().acceptVisitor(this); expression.getOperand().acceptVisitor(this);
emitLocation(expression);
switch (expression.getSourceType()) { switch (expression.getSourceType()) {
case INT32: case INT32:
switch (expression.getTargetType()) { switch (expression.getTargetType()) {
@ -679,17 +705,18 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
} }
break; break;
} }
popLocation();
} }
@Override @Override
public void visit(WasmCall expression) { public void visit(WasmCall expression) {
pushLocation(expression);
for (WasmExpression argument : expression.getArguments()) { for (WasmExpression argument : expression.getArguments()) {
argument.acceptVisitor(this); argument.acceptVisitor(this);
} }
Integer functionIndex = !expression.isImported() Integer functionIndex = !expression.isImported()
? functionIndexes.get(expression.getFunctionName()) ? functionIndexes.get(expression.getFunctionName())
: importedIndexes.get(expression.getFunctionName()); : importedIndexes.get(expression.getFunctionName());
emitLocation(expression);
if (functionIndex == null) { if (functionIndex == null) {
writer.writeByte(0x00); writer.writeByte(0x00);
return; return;
@ -697,10 +724,12 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
writer.writeByte(0x10); writer.writeByte(0x10);
writer.writeLEB(functionIndex); writer.writeLEB(functionIndex);
popLocation();
} }
@Override @Override
public void visit(WasmIndirectCall expression) { public void visit(WasmIndirectCall expression) {
pushLocation(expression);
for (WasmExpression argument : expression.getArguments()) { for (WasmExpression argument : expression.getArguments()) {
argument.acceptVisitor(this); argument.acceptVisitor(this);
} }
@ -715,19 +744,21 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
writer.writeLEB(signatureIndexes.get(new WasmSignature(signatureTypes))); writer.writeLEB(signatureIndexes.get(new WasmSignature(signatureTypes)));
writer.writeByte(0); writer.writeByte(0);
popLocation();
} }
@Override @Override
public void visit(WasmDrop expression) { public void visit(WasmDrop expression) {
pushLocation(expression);
expression.getOperand().acceptVisitor(this); expression.getOperand().acceptVisitor(this);
emitLocation(expression);
writer.writeByte(0x1A); writer.writeByte(0x1A);
popLocation();
} }
@Override @Override
public void visit(WasmLoadInt32 expression) { public void visit(WasmLoadInt32 expression) {
pushLocation(expression);
expression.getIndex().acceptVisitor(this); expression.getIndex().acceptVisitor(this);
emitLocation(expression);
switch (expression.getConvertFrom()) { switch (expression.getConvertFrom()) {
case INT8: case INT8:
writer.writeByte(0x2C); writer.writeByte(0x2C);
@ -747,12 +778,13 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
} }
writer.writeByte(alignment(expression.getAlignment())); writer.writeByte(alignment(expression.getAlignment()));
writer.writeLEB(expression.getOffset()); writer.writeLEB(expression.getOffset());
popLocation();
} }
@Override @Override
public void visit(WasmLoadInt64 expression) { public void visit(WasmLoadInt64 expression) {
pushLocation(expression);
expression.getIndex().acceptVisitor(this); expression.getIndex().acceptVisitor(this);
emitLocation(expression);
switch (expression.getConvertFrom()) { switch (expression.getConvertFrom()) {
case INT8: case INT8:
writer.writeByte(0x30); writer.writeByte(0x30);
@ -778,31 +810,34 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
} }
writer.writeByte(alignment(expression.getAlignment())); writer.writeByte(alignment(expression.getAlignment()));
writer.writeLEB(expression.getOffset()); writer.writeLEB(expression.getOffset());
popLocation();
} }
@Override @Override
public void visit(WasmLoadFloat32 expression) { public void visit(WasmLoadFloat32 expression) {
pushLocation(expression);
expression.getIndex().acceptVisitor(this); expression.getIndex().acceptVisitor(this);
emitLocation(expression);
writer.writeByte(0x2A); writer.writeByte(0x2A);
writer.writeByte(alignment(expression.getAlignment())); writer.writeByte(alignment(expression.getAlignment()));
writer.writeLEB(expression.getOffset()); writer.writeLEB(expression.getOffset());
popLocation();
} }
@Override @Override
public void visit(WasmLoadFloat64 expression) { public void visit(WasmLoadFloat64 expression) {
pushLocation(expression);
expression.getIndex().acceptVisitor(this); expression.getIndex().acceptVisitor(this);
emitLocation(expression);
writer.writeByte(0x2B); writer.writeByte(0x2B);
writer.writeByte(alignment(expression.getAlignment())); writer.writeByte(alignment(expression.getAlignment()));
writer.writeLEB(expression.getOffset()); writer.writeLEB(expression.getOffset());
popLocation();
} }
@Override @Override
public void visit(WasmStoreInt32 expression) { public void visit(WasmStoreInt32 expression) {
pushLocation(expression);
expression.getIndex().acceptVisitor(this); expression.getIndex().acceptVisitor(this);
expression.getValue().acceptVisitor(this); expression.getValue().acceptVisitor(this);
emitLocation(expression);
switch (expression.getConvertTo()) { switch (expression.getConvertTo()) {
case INT8: case INT8:
case UINT8: case UINT8:
@ -818,13 +853,14 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
} }
writer.writeByte(alignment(expression.getAlignment())); writer.writeByte(alignment(expression.getAlignment()));
writer.writeLEB(expression.getOffset()); writer.writeLEB(expression.getOffset());
popLocation();
} }
@Override @Override
public void visit(WasmStoreInt64 expression) { public void visit(WasmStoreInt64 expression) {
pushLocation(expression);
expression.getIndex().acceptVisitor(this); expression.getIndex().acceptVisitor(this);
expression.getValue().acceptVisitor(this); expression.getValue().acceptVisitor(this);
emitLocation(expression);
switch (expression.getConvertTo()) { switch (expression.getConvertTo()) {
case INT8: case INT8:
case UINT8: case UINT8:
@ -844,34 +880,38 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
} }
writer.writeByte(alignment(expression.getAlignment())); writer.writeByte(alignment(expression.getAlignment()));
writer.writeLEB(expression.getOffset()); writer.writeLEB(expression.getOffset());
popLocation();
} }
@Override @Override
public void visit(WasmStoreFloat32 expression) { public void visit(WasmStoreFloat32 expression) {
pushLocation(expression);
expression.getIndex().acceptVisitor(this); expression.getIndex().acceptVisitor(this);
expression.getValue().acceptVisitor(this); expression.getValue().acceptVisitor(this);
emitLocation(expression);
writer.writeByte(0x38); writer.writeByte(0x38);
writer.writeByte(alignment(expression.getAlignment())); writer.writeByte(alignment(expression.getAlignment()));
writer.writeLEB(expression.getOffset()); writer.writeLEB(expression.getOffset());
popLocation();
} }
@Override @Override
public void visit(WasmStoreFloat64 expression) { public void visit(WasmStoreFloat64 expression) {
pushLocation(expression);
expression.getIndex().acceptVisitor(this); expression.getIndex().acceptVisitor(this);
expression.getValue().acceptVisitor(this); expression.getValue().acceptVisitor(this);
emitLocation(expression);
writer.writeByte(0x39); writer.writeByte(0x39);
writer.writeByte(alignment(expression.getAlignment())); writer.writeByte(alignment(expression.getAlignment()));
writer.writeLEB(expression.getOffset()); writer.writeLEB(expression.getOffset());
popLocation();
} }
@Override @Override
public void visit(WasmMemoryGrow expression) { public void visit(WasmMemoryGrow expression) {
pushLocation(expression);
expression.getAmount().acceptVisitor(this); expression.getAmount().acceptVisitor(this);
emitLocation(expression);
writer.writeByte(0x40); writer.writeByte(0x40);
writer.writeByte(0); writer.writeByte(0);
popLocation();
} }
private int alignment(int value) { private int alignment(int value) {
@ -883,18 +923,70 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
writer.writeLEB(depth - blockDepth); writer.writeLEB(depth - blockDepth);
} }
private void emitLocation(WasmExpression expression) { private void pushLocation(WasmExpression expression) {
if (expression.getLocation() == null || expression.getLocation().getFileName() == null) { var location = expression.getLocation() != null
return; ? 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) { if (dwarfGenerator != null) {
dwarfGenerator.lineNumber(writer.getPosition() + addressOffset, expression.getLocation().getFileName(), if (textLocationToEmit == null) {
expression.getLocation().getLine()); dwarfGenerator.endLineNumberSequence(address);
} else {
dwarfGenerator.lineNumber(address, textLocationToEmit.getFileName(), textLocationToEmit.getLine());
}
} }
if (debugLines != null) { if (debugLines != null) {
debugLines.advance(writer.getPosition() + addressOffset); debugLines.advance(address);
var loc = expression.getLocation(); var loc = textLocationToEmit;
var inlining = loc.getInlining(); var inlining = loc != null ? loc.getInlining() : null;
while (inlining != null) { while (inlining != null) {
currentMethodStack.add(loc.getInlining().getMethod()); currentMethodStack.add(loc.getInlining().getMethod());
inlining = inlining.getParent(); inlining = inlining.getParent();
@ -915,7 +1007,11 @@ class WasmBinaryRenderingVisitor implements WasmExpressionVisitor {
debugLines.start(method); debugLines.start(method);
} }
currentMethodStack.clear(); currentMethodStack.clear();
debugLines.location(loc.getFileName(), loc.getLine()); if (loc != null) {
debugLines.location(loc.getFileName(), loc.getLine());
} else {
debugLines.emptyLocation();
}
} }
} }
} }