LocalListpublic final class LocalList extends com.android.dx.util.FixedSizeList List of local variables. Each local variable entry indicates a
range of code which it is valid for, a register number, a name,
and a type. |
Fields Summary |
---|
public static final LocalList | EMPTYnon-null; empty instance | private static final boolean | DEBUGwhether to run the self-check code |
Constructors Summary |
---|
public LocalList(int size)Constructs an instance. All indices initially contain null .
super(size);
|
Methods Summary |
---|
public void | debugPrint(java.io.PrintStream out, java.lang.String prefix)Does a human-friendly dump of this instance.
int sz = size();
for (int i = 0; i < sz; i++) {
out.print(prefix);
out.println(get(i));
}
| private static void | debugVerify(com.android.dx.dex.code.LocalList locals)Debugging helper that verifies the constraint that a list doesn't
contain any redundant local starts and that local ends that are
due to replacements are properly annotated.
try {
debugVerify0(locals);
} catch (RuntimeException ex) {
int sz = locals.size();
for (int i = 0; i < sz; i++) {
System.err.println(locals.get(i));
}
throw ex;
}
| private static void | debugVerify0(com.android.dx.dex.code.LocalList locals)Helper for {@link #debugVerify} which does most of the work.
int sz = locals.size();
Entry[] active = new Entry[65536];
for (int i = 0; i < sz; i++) {
Entry e = locals.get(i);
int reg = e.getRegister();
if (e.isStart()) {
Entry already = active[reg];
if ((already != null) && e.matches(already)) {
throw new RuntimeException("redundant start at " +
Integer.toHexString(e.getAddress()) + ": got " +
e + "; had " + already);
}
active[reg] = e;
} else {
if (active[reg] == null) {
throw new RuntimeException("redundant end at " +
Integer.toHexString(e.getAddress()));
}
int addr = e.getAddress();
boolean foundStart = false;
for (int j = i + 1; j < sz; j++) {
Entry test = locals.get(j);
if (test.getAddress() != addr) {
break;
}
if (test.getRegisterSpec().getReg() == reg) {
if (test.isStart()) {
if (e.getDisposition()
!= Disposition.END_REPLACED) {
throw new RuntimeException(
"improperly marked end at " +
Integer.toHexString(addr));
}
foundStart = true;
} else {
throw new RuntimeException(
"redundant end at " +
Integer.toHexString(addr));
}
}
}
if (!foundStart &&
(e.getDisposition() == Disposition.END_REPLACED)) {
throw new RuntimeException(
"improper end replacement claim at " +
Integer.toHexString(addr));
}
active[reg] = null;
}
}
| public com.android.dx.dex.code.LocalList$Entry | get(int n)Gets the element at the given index. It is an error to call
this with the index for an element which was never set; if you
do that, this will throw NullPointerException .
return (Entry) get0(n);
| public static com.android.dx.dex.code.LocalList | make(DalvInsnList insns)Constructs an instance for the given method, based on the given
block order and intermediate local information.
int sz = insns.size();
/*
* Go through the insn list, looking for all the local
* variable pseudoinstructions, splitting out LocalSnapshots
* into separate per-variable starts, adding explicit ends
* wherever a variable is replaced or moved, and collecting
* these and all the other local variable "activity"
* together into an output list (without the other insns).
*
* Note: As of this writing, this method won't be handed any
* insn lists that contain local ends, but I (danfuzz) expect
* that to change at some point, when we start feeding that
* info explicitly into the rop layer rather than only trying
* to infer it. So, given that expectation, this code is
* written to deal with them.
*/
MakeState state = new MakeState(sz);
for (int i = 0; i < sz; i++) {
DalvInsn insn = insns.get(i);
if (insn instanceof LocalSnapshot) {
RegisterSpecSet snapshot =
((LocalSnapshot) insn).getLocals();
state.snapshot(insn.getAddress(), snapshot);
} else if (insn instanceof LocalStart) {
RegisterSpec local = ((LocalStart) insn).getLocal();
state.startLocal(insn.getAddress(), local);
} else if (insn instanceof LocalEnd) {
RegisterSpec local = ((LocalEnd) insn).getLocal();
state.endLocal(insn.getAddress(), local);
}
}
LocalList result = state.finish();
if (DEBUG) {
debugVerify(result);
}
return result;
| public void | set(int n, com.android.dx.dex.code.LocalList$Entry entry)Sets the entry at the given index.
set0(n, entry);
|
|