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()) {
|
||||
throw new IllegalArgumentException("There is already a label with that name.");
|
||||
} else {
|
||||
currentLocation.addLabel(label);
|
||||
currentLocation.getLabels().add(label);
|
||||
}
|
||||
} else {
|
||||
label = currentLocation.addNewLabel();
|
||||
@ -86,25 +86,32 @@ public class MethodImplementationBuilder<ReferenceType extends Reference> {
|
||||
}
|
||||
|
||||
public void addLineNumber(int lineNumber) {
|
||||
currentLocation.addLineNumber(lineNumber);
|
||||
}
|
||||
|
||||
public void addStartLocal(int registerNumber, @Nullable StringReference name, @Nullable TypeReference type,
|
||||
@Nullable StringReference signature) {
|
||||
currentLocation.addStartLocal(registerNumber, name, type, signature);
|
||||
}
|
||||
|
||||
public void addEndLocal(int registerNumber) {
|
||||
currentLocation.addEndLocal(registerNumber);
|
||||
}
|
||||
|
||||
public void addRestartLocal(int registerNumber) {
|
||||
currentLocation.addRestartLocal(registerNumber);
|
||||
}
|
||||
|
||||
public void addPrologue() {
|
||||
currentLocation.addPrologue();
|
||||
}
|
||||
|
||||
public void addEpilogue() {
|
||||
currentLocation.addEpilogue();
|
||||
}
|
||||
|
||||
public void addSetSourceFile(@Nullable BuilderStringReference sourceFile) {
|
||||
currentLocation.addSetSourceFile(sourceFile);
|
||||
}
|
||||
|
||||
public void addInstruction10t(@Nonnull Opcode opcode,
|
||||
|
@ -1,13 +1,15 @@
|
||||
package org.jf.dexlib2.builder;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import org.jf.dexlib2.builder.debug.*;
|
||||
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.Nullable;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class MethodLocation {
|
||||
@Nullable Instruction instruction;
|
||||
@ -15,6 +17,7 @@ public class MethodLocation {
|
||||
int index;
|
||||
|
||||
private List<Label> labels = Lists.newArrayList();
|
||||
List<BuilderDebugItem> debugItems = Lists.newArrayList();
|
||||
|
||||
MethodLocation(@Nullable Instruction instruction,
|
||||
int codeAddress, int index) {
|
||||
@ -37,16 +40,47 @@ public class MethodLocation {
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public Collection<Label> getLabels() {
|
||||
return Collections.unmodifiableCollection(labels);
|
||||
}
|
||||
public Set<Label> getLabels() {
|
||||
return new AbstractSet<Label>() {
|
||||
@Nonnull
|
||||
@Override public Iterator<Label> iterator() {
|
||||
final Iterator<Label> it = labels.iterator();
|
||||
|
||||
public void addLabel(@Nonnull Label label) {
|
||||
if (label.isPlaced()) {
|
||||
label.getLocation().removeLabel(label);
|
||||
}
|
||||
label.location = this;
|
||||
labels.add(label);
|
||||
return new Iterator<Label>() {
|
||||
private @Nullable Label currentLabel = null;
|
||||
|
||||
@Override public boolean hasNext() {
|
||||
return it.hasNext();
|
||||
}
|
||||
|
||||
@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
|
||||
@ -56,10 +90,76 @@ public class MethodLocation {
|
||||
return label;
|
||||
}
|
||||
|
||||
public void removeLabel(@Nonnull Label label) {
|
||||
for (int i=0; i<labels.size(); i++) {
|
||||
labels.remove(label);
|
||||
}
|
||||
label.location = null;
|
||||
@Nonnull
|
||||
public Set<BuilderDebugItem> getDebugItems() {
|
||||
return new AbstractSet<BuilderDebugItem>() {
|
||||
@Nonnull
|
||||
@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