blob: 26f1577a1bb426452a71e4dc5c768b9c2f81f3ec [file] [log] [blame]
// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.graph;
import com.android.tools.r8.graph.DexDebugEvent.AdvanceLine;
import com.android.tools.r8.graph.DexDebugEvent.AdvancePC;
import com.android.tools.r8.graph.DexDebugEvent.Default;
import com.android.tools.r8.graph.DexDebugEvent.EndLocal;
import com.android.tools.r8.graph.DexDebugEvent.RestartLocal;
import com.android.tools.r8.graph.DexDebugEvent.SetEpilogueBegin;
import com.android.tools.r8.graph.DexDebugEvent.SetFile;
import com.android.tools.r8.graph.DexDebugEvent.SetPositionFrame;
import com.android.tools.r8.graph.DexDebugEvent.SetPrologueEnd;
import com.android.tools.r8.graph.DexDebugEvent.StartLocal;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.Position.SourcePosition;
import com.android.tools.r8.ir.code.Position.SyntheticPosition;
/**
* State machine to process and accumulate position-related DexDebugEvents. Clients should retrieve
* the current state using the getters after a Default event.
*/
public class DexDebugPositionState implements DexDebugEventVisitor {
private int currentPc = 0;
private int currentLine;
protected DexMethod currentMethod;
protected boolean isCurrentMethodD8R8Synthesized;
protected Position currentPosition;
public DexDebugPositionState(int startLine, DexMethod method, boolean isD8R8Synthesized) {
currentLine = startLine;
currentMethod = method;
isCurrentMethodD8R8Synthesized = isD8R8Synthesized;
}
@Override
public void visit(AdvancePC advancePC) {
assert advancePC.delta >= 0;
currentPc += advancePC.delta;
}
@Override
public void visit(AdvanceLine advanceLine) {
currentLine += advanceLine.delta;
}
@Override
public void visit(SetPositionFrame setPositionFrame) {
assert setPositionFrame.getPosition() != null;
Position position = setPositionFrame.getPosition();
currentMethod = position.getMethod();
isCurrentMethodD8R8Synthesized = position.isD8R8Synthesized();
currentPosition = position;
}
@Override
public void visit(Default defaultEvent) {
assert defaultEvent.getPCDelta() >= 0;
currentPc += defaultEvent.getPCDelta();
currentLine += defaultEvent.getLineDelta();
}
@Override
public void visit(SetFile setFile) {
// Empty.
}
@Override
public void visit(SetPrologueEnd setPrologueEnd) {
// Empty.
}
@Override
public void visit(SetEpilogueBegin setEpilogueBegin) {
// Empty.
}
@Override
public void visit(StartLocal startLocal) {
// Empty.
}
@Override
public void visit(EndLocal endLocal) {
// Empty.
}
@Override
public void visit(RestartLocal restartLocal) {
// Empty.
}
public int getCurrentPc() {
return currentPc;
}
public int getCurrentLine() {
return currentLine;
}
public Position getPosition() {
if (currentPosition == null) {
return (getCurrentLine() > 0 ? SourcePosition.builder() : SyntheticPosition.builder())
.setLine(getCurrentLine())
.setMethod(currentMethod)
.setIsD8R8Synthesized(isCurrentMethodD8R8Synthesized)
.build();
} else {
return currentPosition.builderWithCopy().setLine(getCurrentLine()).build();
}
}
}