Incorrect stack frame handling in AnalyzerAdapter
Hi all,
I use the AnalyzerAdapter for tracking the stack frames as suggested
in the documentation. At certain points I copy the state (locals and
stack) for later recovery.
When I replay the state using visitFrame(...), it is not recovered
as expected. The problem is that the following function introduces
an additional TOP for each LONG and DOUBLE:
private static void visitFrameTypes(
final int n,
final Object[] types,
final List result)
{
for (int i = 0; i < n; ++i) {
Object type = types[i];
result.add(type);
if (type == Opcodes.LONG || type == Opcodes.DOUBLE) {
result.add(Opcodes.TOP);
}
}
}
May be I misused the AnalyzerAdapter, when I introduced it behind
the transforming class. Actually I might change this, but I think
the problem is more general and would result in incorrect informa-
tion whenever there are LONGs and DOUBLEs on the stack before the
AnalyzerAdapter gets called. If the Language Specs expect TOPs on
the stack, than the function should assume them to exist, itself.
Thus, the function should either check for TOPs after LONG or
DOUBLE as below or ignore such concerns completely, as shown
below:
private static void visitFrameTypes(
final int n,
final Object[] types,
final List result)
{
for (int i = 0; i < n; ++i) {
Object type = types[i];
result.add(type);
if (type == Opcodes.LONG || type == Opcodes.DOUBLE) {
if ((index++ > size) || (types[index] != Opcodes.TOP)) {
throw new IllegalArgumentException("error: stack/locals");
}
result.add(Opcodes.TOP);
}
}
}
private static void visitFrameTypes(
final int n,
final Object[] types,
final List result)
{
for (int i = 0; i < n; ++i) {
result.add(types[i]);
}
}
Both behaviors would be acceptable.