mirror of
https://github.com/revanced/smali.git
synced 2025-05-29 04:10:13 +02:00
Use an iterable rather than a list for debug items
This commit is contained in:
parent
6dd026a0bd
commit
08840432d4
@ -109,7 +109,7 @@ public class DexBackedMethodImplementation implements MethodImplementation {
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public List<? extends DebugItem> getDebugItems() {
|
public Iterable<? extends DebugItem> getDebugItems() {
|
||||||
final int debugInfoOffset = dexBuf.readSmallUint(codeOffset + DEBUG_OFFSET_OFFSET);
|
final int debugInfoOffset = dexBuf.readSmallUint(codeOffset + DEBUG_OFFSET_OFFSET);
|
||||||
if (debugInfoOffset > 0) {
|
if (debugInfoOffset > 0) {
|
||||||
return new DebugItemList(dexBuf, debugInfoOffset, method);
|
return new DebugItemList(dexBuf, debugInfoOffset, method);
|
||||||
|
@ -46,9 +46,10 @@ import org.jf.util.ExceptionWithContext;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.NoSuchElementException;
|
import java.util.NoSuchElementException;
|
||||||
|
|
||||||
public class DebugItemList extends VariableSizeListWithContext<DebugItem> {
|
public class DebugItemList implements Iterable<DebugItem> {
|
||||||
@Nonnull public final DexBuffer dexBuf;
|
@Nonnull public final DexBuffer dexBuf;
|
||||||
private final int debugInfoOffset;
|
private final int debugInfoOffset;
|
||||||
@Nonnull private final Method method;
|
@Nonnull private final Method method;
|
||||||
@ -75,7 +76,7 @@ public class DebugItemList extends VariableSizeListWithContext<DebugItem> {
|
|||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
@Override
|
@Override
|
||||||
public Iterator listIterator() {
|
public Iterator<DebugItem> iterator() {
|
||||||
DexReader initialReader = dexBuf.readerAt(debugInfoOffset);
|
DexReader initialReader = dexBuf.readerAt(debugInfoOffset);
|
||||||
// TODO: this unsigned value could legitimally be > MAX_INT
|
// TODO: this unsigned value could legitimally be > MAX_INT
|
||||||
final int lineNumberStart = initialReader.readSmallUleb128();
|
final int lineNumberStart = initialReader.readSmallUleb128();
|
||||||
@ -89,7 +90,7 @@ public class DebugItemList extends VariableSizeListWithContext<DebugItem> {
|
|||||||
// information, the method obviously has an implementation.
|
// information, the method obviously has an implementation.
|
||||||
VariableSizeList<? extends MethodParameter> parameters =
|
VariableSizeList<? extends MethodParameter> parameters =
|
||||||
(VariableSizeList<? extends MethodParameter>)method.getParameters();
|
(VariableSizeList<? extends MethodParameter>)method.getParameters();
|
||||||
VariableSizeList<? extends MethodParameter>.Iterator parameterIterator = parameters.listIterator();
|
final VariableSizeList<? extends MethodParameter>.Iterator parameterIterator = parameters.listIterator();
|
||||||
|
|
||||||
{ // local scope for i
|
{ // local scope for i
|
||||||
int i=0;
|
int i=0;
|
||||||
@ -113,23 +114,25 @@ public class DebugItemList extends VariableSizeListWithContext<DebugItem> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Iterator(dexBuf, parameterIterator.getReaderOffset()) {
|
return new Iterator<DebugItem>() {
|
||||||
|
@Nonnull private DexReader reader = dexBuf.readerAt(parameterIterator.getReaderOffset());
|
||||||
private boolean finished = false;
|
private boolean finished = false;
|
||||||
private int codeAddress = 0;
|
private int codeAddress = 0;
|
||||||
private int lineNumber = lineNumberStart;
|
private int lineNumber = lineNumberStart;
|
||||||
|
|
||||||
@Nonnull
|
@Nullable private DebugItem nextItem;
|
||||||
@Override
|
|
||||||
protected DebugItem readItem(@Nonnull DexReader reader, int index) {
|
@Nullable
|
||||||
|
protected DebugItem readItem() {
|
||||||
if (finished) {
|
if (finished) {
|
||||||
throw new NoSuchElementException();
|
return null;
|
||||||
}
|
}
|
||||||
while (true) {
|
while (true) {
|
||||||
int next = reader.readUbyte();
|
int next = reader.readUbyte();
|
||||||
switch (next) {
|
switch (next) {
|
||||||
case DebugItemType.END_SEQUENCE: {
|
case DebugItemType.END_SEQUENCE: {
|
||||||
finished = true;
|
finished = true;
|
||||||
throw new NoSuchElementException();
|
return null;
|
||||||
}
|
}
|
||||||
case DebugItemType.ADVANCE_PC: {
|
case DebugItemType.ADVANCE_PC: {
|
||||||
int addressDiff = reader.readSmallUleb128();
|
int addressDiff = reader.readSmallUleb128();
|
||||||
@ -209,19 +212,36 @@ public class DebugItemList extends VariableSizeListWithContext<DebugItem> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void skipItem(@Nonnull DexReader reader, int index) {
|
public boolean hasNext() {
|
||||||
super.skipItem(reader, index);
|
if (finished || nextItem != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nextItem = readItem();
|
||||||
|
return nextItem != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull
|
||||||
|
@Override
|
||||||
|
public DebugItem next() {
|
||||||
|
if (finished) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
if (nextItem == null) {
|
||||||
|
DebugItem ret = readItem();
|
||||||
|
if (ret == null) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
DebugItem ret = nextItem;
|
||||||
|
nextItem = null;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void checkBounds(int index) {
|
public void remove() {
|
||||||
// skip the bounds check here. We'll throw NoSuchElementException directly from readItem
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int size() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -41,5 +41,5 @@ public interface MethodImplementation {
|
|||||||
int getRegisterCount();
|
int getRegisterCount();
|
||||||
@Nonnull List<? extends Instruction> getInstructions();
|
@Nonnull List<? extends Instruction> getInstructions();
|
||||||
@Nonnull List<? extends TryBlock> getTryBlocks();
|
@Nonnull List<? extends TryBlock> getTryBlocks();
|
||||||
@Nonnull List<? extends DebugItem> getDebugItems();
|
@Nonnull Iterable<? extends DebugItem> getDebugItems();
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ public class ImmutableMethodImplementation implements MethodImplementation {
|
|||||||
public ImmutableMethodImplementation(int registerCount,
|
public ImmutableMethodImplementation(int registerCount,
|
||||||
@Nullable List<? extends Instruction> instructions,
|
@Nullable List<? extends Instruction> instructions,
|
||||||
@Nullable List<? extends TryBlock> tryBlocks,
|
@Nullable List<? extends TryBlock> tryBlocks,
|
||||||
@Nullable List<? extends DebugItem> debugItems) {
|
@Nullable Iterable<? extends DebugItem> debugItems) {
|
||||||
this.registerCount = registerCount;
|
this.registerCount = registerCount;
|
||||||
this.instructions = ImmutableInstruction.immutableListOf(instructions);
|
this.instructions = ImmutableInstruction.immutableListOf(instructions);
|
||||||
this.tryBlocks = ImmutableTryBlock.immutableListOf(tryBlocks);
|
this.tryBlocks = ImmutableTryBlock.immutableListOf(tryBlocks);
|
||||||
|
@ -77,7 +77,7 @@ public abstract class ImmutableDebugItem implements DebugItem {
|
|||||||
@Override public int getCodeAddress() { return codeAddress; }
|
@Override public int getCodeAddress() { return codeAddress; }
|
||||||
|
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public static ImmutableList<ImmutableDebugItem> immutableListOf(@Nullable List<? extends DebugItem> list) {
|
public static ImmutableList<ImmutableDebugItem> immutableListOf(@Nullable Iterable<? extends DebugItem> list) {
|
||||||
return CONVERTER.convert(list);
|
return CONVERTER.convert(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class converts a list of items to an immutable list of immutable items
|
* This class converts a list of items to an immutable list of immutable items
|
||||||
@ -51,18 +50,18 @@ public abstract class ImmutableListConverter<ImmutableItem, Item> {
|
|||||||
* If the provided list is already an ImmutableList of ImmutableItems, then the list is not copied and is returned
|
* If the provided list is already an ImmutableList of ImmutableItems, then the list is not copied and is returned
|
||||||
* as-is. If the list is null, an empty ImmutableList will be returned
|
* as-is. If the list is null, an empty ImmutableList will be returned
|
||||||
*
|
*
|
||||||
* @param list The list of items to convert.
|
* @param iterable The iterable of items to convert.
|
||||||
* @return An ImmutableList of ImmutableItem. If list is null, an empty list will be returned.
|
* @return An ImmutableList of ImmutableItem. If list is null, an empty list will be returned.
|
||||||
*/
|
*/
|
||||||
@Nonnull
|
@Nonnull
|
||||||
public ImmutableList<ImmutableItem> convert(@Nullable final List<? extends Item> list) {
|
public ImmutableList<ImmutableItem> convert(@Nullable final Iterable<? extends Item> iterable) {
|
||||||
if (list == null) {
|
if (iterable == null) {
|
||||||
return ImmutableList.of();
|
return ImmutableList.of();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean needsCopy = false;
|
boolean needsCopy = false;
|
||||||
if (list instanceof ImmutableList) {
|
if (iterable instanceof ImmutableList) {
|
||||||
for (Item element: list) {
|
for (Item element: iterable) {
|
||||||
if (isImmutable(element)) {
|
if (isImmutable(element)) {
|
||||||
needsCopy = true;
|
needsCopy = true;
|
||||||
break;
|
break;
|
||||||
@ -73,28 +72,15 @@ public abstract class ImmutableListConverter<ImmutableItem, Item> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!needsCopy) {
|
if (!needsCopy) {
|
||||||
return (ImmutableList<ImmutableItem>)list;
|
return (ImmutableList<ImmutableItem>)iterable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final Iterator<? extends Item> iter = iterable.iterator();
|
||||||
|
|
||||||
return ImmutableList.copyOf(new Iterator<ImmutableItem>() {
|
return ImmutableList.copyOf(new Iterator<ImmutableItem>() {
|
||||||
protected int index = 0;
|
@Override public boolean hasNext() { return iter.hasNext(); }
|
||||||
|
@Override public ImmutableItem next() { return makeImmutable(iter.next()); }
|
||||||
@Override
|
@Override public void remove() { iter.remove(); }
|
||||||
public boolean hasNext() {
|
|
||||||
return index < list.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ImmutableItem next() {
|
|
||||||
ImmutableItem item = makeImmutable(list.get(index));
|
|
||||||
index++;
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void remove() {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user