mirror of
https://github.com/revanced/smali.git
synced 2025-05-29 12:20:11 +02:00
Implement debug items for the method impl builder
This commit is contained in:
parent
bb7937fd30
commit
688611814d
@ -0,0 +1,26 @@
|
|||||||
|
package org.jf.dexlib2.builder;
|
||||||
|
|
||||||
|
import org.jf.dexlib2.DebugItemType;
|
||||||
|
import org.jf.dexlib2.iface.debug.*;
|
||||||
|
import org.jf.dexlib2.iface.reference.StringReference;
|
||||||
|
import org.jf.dexlib2.iface.reference.TypeReference;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public abstract class BuilderDebugItem implements DebugItem {
|
||||||
|
@Nullable MethodLocation location;
|
||||||
|
|
||||||
|
public BuilderDebugItem(@Nonnull MethodLocation location) {
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getCodeAddress() {
|
||||||
|
if (location == null) {
|
||||||
|
throw new IllegalStateException("Cannot get the address of a BuilderDebugItem that isn't associated with " +
|
||||||
|
"a method.");
|
||||||
|
}
|
||||||
|
return location.getCodeAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -41,7 +41,7 @@ public class MethodImplementationBuilder<ReferenceType extends Reference> {
|
|||||||
if (label.isPlaced()) {
|
if (label.isPlaced()) {
|
||||||
throw new IllegalArgumentException("There is already a label with that name.");
|
throw new IllegalArgumentException("There is already a label with that name.");
|
||||||
} else {
|
} else {
|
||||||
currentLocation.addLabel(label);
|
currentLocation.getLabels().add(label);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
label = currentLocation.addNewLabel();
|
label = currentLocation.addNewLabel();
|
||||||
@ -86,25 +86,32 @@ public class MethodImplementationBuilder<ReferenceType extends Reference> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void addLineNumber(int lineNumber) {
|
public void addLineNumber(int lineNumber) {
|
||||||
|
currentLocation.addLineNumber(lineNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addStartLocal(int registerNumber, @Nullable StringReference name, @Nullable TypeReference type,
|
public void addStartLocal(int registerNumber, @Nullable StringReference name, @Nullable TypeReference type,
|
||||||
@Nullable StringReference signature) {
|
@Nullable StringReference signature) {
|
||||||
|
currentLocation.addStartLocal(registerNumber, name, type, signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEndLocal(int registerNumber) {
|
public void addEndLocal(int registerNumber) {
|
||||||
|
currentLocation.addEndLocal(registerNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRestartLocal(int registerNumber) {
|
public void addRestartLocal(int registerNumber) {
|
||||||
|
currentLocation.addRestartLocal(registerNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addPrologue() {
|
public void addPrologue() {
|
||||||
|
currentLocation.addPrologue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEpilogue() {
|
public void addEpilogue() {
|
||||||
|
currentLocation.addEpilogue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSetSourceFile(@Nullable BuilderStringReference sourceFile) {
|
public void addSetSourceFile(@Nullable BuilderStringReference sourceFile) {
|
||||||
|
currentLocation.addSetSourceFile(sourceFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addInstruction10t(@Nonnull Opcode opcode,
|
public void addInstruction10t(@Nonnull Opcode opcode,
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
package org.jf.dexlib2.builder;
|
package org.jf.dexlib2.builder;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import org.jf.dexlib2.builder.debug.*;
|
||||||
import org.jf.dexlib2.iface.instruction.Instruction;
|
import org.jf.dexlib2.iface.instruction.Instruction;
|
||||||
|
import org.jf.dexlib2.iface.reference.StringReference;
|
||||||
|
import org.jf.dexlib2.iface.reference.TypeReference;
|
||||||
|
import org.jf.dexlib2.writer.builder.BuilderStringReference;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Collection;
|
import java.util.*;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class MethodLocation {
|
public class MethodLocation {
|
||||||
@Nullable Instruction instruction;
|
@Nullable Instruction instruction;
|
||||||
@ -15,6 +17,7 @@ public class MethodLocation {
|
|||||||
int index;
|
int index;
|
||||||
|
|
||||||
private List<Label> labels = Lists.newArrayList();
|
private List<Label> labels = Lists.newArrayList();
|
||||||
|
List<BuilderDebugItem> debugItems = Lists.newArrayList();
|
||||||
|
|
||||||
MethodLocation(@Nullable Instruction instruction,
|
MethodLocation(@Nullable Instruction instruction,
|
||||||
int codeAddress, int index) {
|
int codeAddress, int index) {
|
||||||
@ -37,16 +40,47 @@ public class MethodLocation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public Collection<Label> getLabels() {
|
public Set<Label> getLabels() {
|
||||||
return Collections.unmodifiableCollection(labels);
|
return new AbstractSet<Label>() {
|
||||||
}
|
@Nonnull
|
||||||
|
@Override public Iterator<Label> iterator() {
|
||||||
|
final Iterator<Label> it = labels.iterator();
|
||||||
|
|
||||||
public void addLabel(@Nonnull Label label) {
|
return new Iterator<Label>() {
|
||||||
if (label.isPlaced()) {
|
private @Nullable Label currentLabel = null;
|
||||||
label.getLocation().removeLabel(label);
|
|
||||||
}
|
@Override public boolean hasNext() {
|
||||||
label.location = this;
|
return it.hasNext();
|
||||||
labels.add(label);
|
}
|
||||||
|
|
||||||
|
@Override public Label next() {
|
||||||
|
currentLabel = it.next();
|
||||||
|
return currentLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void remove() {
|
||||||
|
if (currentLabel != null) {
|
||||||
|
currentLabel.location = null;
|
||||||
|
}
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int size() {
|
||||||
|
return labels.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean add(@Nonnull Label label) {
|
||||||
|
if (label.isPlaced()) {
|
||||||
|
throw new IllegalArgumentException("Cannot add a label that is already placed. You must remove " +
|
||||||
|
"it from its current location first.");
|
||||||
|
}
|
||||||
|
label.location = MethodLocation.this;
|
||||||
|
labels.add(label);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@ -56,10 +90,76 @@ public class MethodLocation {
|
|||||||
return label;
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeLabel(@Nonnull Label label) {
|
@Nonnull
|
||||||
for (int i=0; i<labels.size(); i++) {
|
public Set<BuilderDebugItem> getDebugItems() {
|
||||||
labels.remove(label);
|
return new AbstractSet<BuilderDebugItem>() {
|
||||||
}
|
@Nonnull
|
||||||
label.location = null;
|
@Override public Iterator<BuilderDebugItem> iterator() {
|
||||||
|
final Iterator<BuilderDebugItem> it = debugItems.iterator();
|
||||||
|
|
||||||
|
return new Iterator<BuilderDebugItem>() {
|
||||||
|
private @Nullable BuilderDebugItem currentDebugItem = null;
|
||||||
|
|
||||||
|
@Override public boolean hasNext() {
|
||||||
|
return it.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public BuilderDebugItem next() {
|
||||||
|
currentDebugItem = it.next();
|
||||||
|
return currentDebugItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void remove() {
|
||||||
|
if (currentDebugItem != null) {
|
||||||
|
currentDebugItem.location = null;
|
||||||
|
}
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int size() {
|
||||||
|
return labels.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean add(@Nonnull BuilderDebugItem debugItem) {
|
||||||
|
if (debugItem.location != null) {
|
||||||
|
throw new IllegalArgumentException("Cannot add a debug item that has already been added to a " +
|
||||||
|
"method. You must remove it from its current location first.");
|
||||||
|
}
|
||||||
|
debugItem.location = MethodLocation.this;
|
||||||
|
debugItems.add(debugItem);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLineNumber(int lineNumber) {
|
||||||
|
debugItems.add(new BuilderLineNumber(this, lineNumber));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addStartLocal(int registerNumber, @Nullable StringReference name, @Nullable TypeReference type,
|
||||||
|
@Nullable StringReference signature) {
|
||||||
|
debugItems.add(new BuilderStartLocal(this, registerNumber, name, type, signature));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEndLocal(int registerNumber) {
|
||||||
|
debugItems.add(new BuilderEndLocal(this, registerNumber));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addRestartLocal(int registerNumber) {
|
||||||
|
debugItems.add(new BuilderRestartLocal(this, registerNumber));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPrologue() {
|
||||||
|
debugItems.add(new BuilderPrologueEnd(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addEpilogue() {
|
||||||
|
debugItems.add(new BuilderEpilogueBegin(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSetSourceFile(@Nullable BuilderStringReference sourceFile) {
|
||||||
|
debugItems.add(new BuilderSetSourceFile(this, sourceFile));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package org.jf.dexlib2.builder.debug;
|
||||||
|
|
||||||
|
import org.jf.dexlib2.DebugItemType;
|
||||||
|
import org.jf.dexlib2.builder.BuilderDebugItem;
|
||||||
|
import org.jf.dexlib2.builder.MethodLocation;
|
||||||
|
import org.jf.dexlib2.iface.debug.EndLocal;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class BuilderEndLocal extends BuilderDebugItem implements EndLocal {
|
||||||
|
private final int register;
|
||||||
|
|
||||||
|
public BuilderEndLocal(@Nonnull MethodLocation location,
|
||||||
|
int register) {
|
||||||
|
super(location);
|
||||||
|
this.register = register;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getRegister() { return register; }
|
||||||
|
@Nullable @Override public String getName() { return null; }
|
||||||
|
@Nullable @Override public String getType() { return null; }
|
||||||
|
@Nullable @Override public String getSignature() { return null; }
|
||||||
|
|
||||||
|
@Override public int getDebugItemType() { return DebugItemType.END_LOCAL; }
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package org.jf.dexlib2.builder.debug;
|
||||||
|
|
||||||
|
import org.jf.dexlib2.DebugItemType;
|
||||||
|
import org.jf.dexlib2.builder.BuilderDebugItem;
|
||||||
|
import org.jf.dexlib2.builder.MethodLocation;
|
||||||
|
import org.jf.dexlib2.iface.debug.EpilogueBegin;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public class BuilderEpilogueBegin extends BuilderDebugItem implements EpilogueBegin {
|
||||||
|
public BuilderEpilogueBegin(@Nonnull MethodLocation location) {
|
||||||
|
super(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getDebugItemType() { return DebugItemType.EPILOGUE_BEGIN; }
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package org.jf.dexlib2.builder.debug;
|
||||||
|
|
||||||
|
import org.jf.dexlib2.DebugItemType;
|
||||||
|
import org.jf.dexlib2.builder.BuilderDebugItem;
|
||||||
|
import org.jf.dexlib2.builder.MethodLocation;
|
||||||
|
import org.jf.dexlib2.iface.debug.LineNumber;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public class BuilderLineNumber extends BuilderDebugItem implements LineNumber {
|
||||||
|
private final int lineNumber;
|
||||||
|
|
||||||
|
public BuilderLineNumber(@Nonnull MethodLocation location,
|
||||||
|
int lineNumber) {
|
||||||
|
super(location);
|
||||||
|
this.lineNumber = lineNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getLineNumber() { return lineNumber; }
|
||||||
|
|
||||||
|
@Override public int getDebugItemType() { return DebugItemType.LINE_NUMBER; }
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package org.jf.dexlib2.builder.debug;
|
||||||
|
|
||||||
|
import org.jf.dexlib2.DebugItemType;
|
||||||
|
import org.jf.dexlib2.builder.BuilderDebugItem;
|
||||||
|
import org.jf.dexlib2.builder.MethodLocation;
|
||||||
|
import org.jf.dexlib2.iface.debug.PrologueEnd;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public class BuilderPrologueEnd extends BuilderDebugItem implements PrologueEnd {
|
||||||
|
public BuilderPrologueEnd(@Nonnull MethodLocation location) {
|
||||||
|
super(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getDebugItemType() { return DebugItemType.PROLOGUE_END; }
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package org.jf.dexlib2.builder.debug;
|
||||||
|
|
||||||
|
import org.jf.dexlib2.DebugItemType;
|
||||||
|
import org.jf.dexlib2.builder.BuilderDebugItem;
|
||||||
|
import org.jf.dexlib2.builder.MethodLocation;
|
||||||
|
import org.jf.dexlib2.iface.debug.RestartLocal;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class BuilderRestartLocal extends BuilderDebugItem implements RestartLocal {
|
||||||
|
private final int register;
|
||||||
|
|
||||||
|
public BuilderRestartLocal(@Nonnull MethodLocation location,
|
||||||
|
int register) {
|
||||||
|
super(location);
|
||||||
|
this.register = register;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getRegister() { return register; }
|
||||||
|
@Nullable @Override public String getName() { return null; }
|
||||||
|
@Nullable @Override public String getType() { return null; }
|
||||||
|
@Nullable @Override public String getSignature() { return null; }
|
||||||
|
|
||||||
|
@Override public int getDebugItemType() { return DebugItemType.RESTART_LOCAL; }
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package org.jf.dexlib2.builder.debug;
|
||||||
|
|
||||||
|
import org.jf.dexlib2.DebugItemType;
|
||||||
|
import org.jf.dexlib2.builder.BuilderDebugItem;
|
||||||
|
import org.jf.dexlib2.builder.MethodLocation;
|
||||||
|
import org.jf.dexlib2.iface.debug.SetSourceFile;
|
||||||
|
import org.jf.dexlib2.iface.reference.StringReference;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class BuilderSetSourceFile extends BuilderDebugItem implements SetSourceFile {
|
||||||
|
@Nullable
|
||||||
|
private final StringReference sourceFile;
|
||||||
|
|
||||||
|
public BuilderSetSourceFile(@Nonnull MethodLocation location,
|
||||||
|
@Nullable StringReference sourceFile) {
|
||||||
|
super(location);
|
||||||
|
this.sourceFile = sourceFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getDebugItemType() { return DebugItemType.SET_SOURCE_FILE; }
|
||||||
|
|
||||||
|
@Nullable @Override public String getSourceFile() {
|
||||||
|
return sourceFile==null?null:sourceFile.getString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable @Override public StringReference getSourceFileReference() {
|
||||||
|
return sourceFile;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package org.jf.dexlib2.builder.debug;
|
||||||
|
|
||||||
|
import org.jf.dexlib2.DebugItemType;
|
||||||
|
import org.jf.dexlib2.builder.BuilderDebugItem;
|
||||||
|
import org.jf.dexlib2.builder.MethodLocation;
|
||||||
|
import org.jf.dexlib2.iface.debug.StartLocal;
|
||||||
|
import org.jf.dexlib2.iface.reference.StringReference;
|
||||||
|
import org.jf.dexlib2.iface.reference.TypeReference;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public class BuilderStartLocal extends BuilderDebugItem implements StartLocal {
|
||||||
|
private final int register;
|
||||||
|
@Nullable private final StringReference name;
|
||||||
|
@Nullable private final TypeReference type;
|
||||||
|
@Nullable private final StringReference signature;
|
||||||
|
|
||||||
|
public BuilderStartLocal(@Nonnull MethodLocation location,
|
||||||
|
int register,
|
||||||
|
@Nullable StringReference name,
|
||||||
|
@Nullable TypeReference type,
|
||||||
|
@Nullable StringReference signature) {
|
||||||
|
super(location);
|
||||||
|
this.register = register;
|
||||||
|
this.name = name;
|
||||||
|
this.type = type;
|
||||||
|
this.signature = signature;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getRegister() { return register; }
|
||||||
|
|
||||||
|
@Nullable @Override public StringReference getNameReference() { return name; }
|
||||||
|
@Nullable @Override public TypeReference getTypeReference() { return type; }
|
||||||
|
@Nullable @Override public StringReference getSignatureReference() { return signature; }
|
||||||
|
|
||||||
|
@Nullable @Override public String getName() {
|
||||||
|
return name==null?null:name.getString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable @Override public String getType() {
|
||||||
|
return type==null?null:type.getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable @Override public String getSignature() {
|
||||||
|
return signature==null?null:signature.getString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public int getDebugItemType() { return DebugItemType.START_LOCAL; }
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user