Using ASM Bytecode Can we identify for loops or while loops present in the method body?
问题:
回答1:
It depends on which information you want to extract. In principle, you can detect loops by searching for backward branches. A loop can’t work without and with usual code structures you won’t find backward branches which are not part of a loop.
So if you want to have them named explicitly, all of the bytecode instructions goto
, goto_w
, if_acmpeq
, if_acmpne
, if_icmpeq
, if_icmpge
, if_icmpgt
, if_icmple
, if_icmplt
, if_icmpne
, ifeq
, ifge
, ifgt
, ifle
, iflt
, ifne
, ifnonnull
, ifnull
may indicate a loop if they point backwards.
But in most cases you will have a hard time telling what kind of loop you have. There is no significant difference between a for
loop and a while
loop in the compiled code. E.g., the following code fragments are entirely equivalent:
for(a();b();c()) { d(); }
a(); for(;b();) { d(); c(); }
a(); for(;;) { if(!b()) break; d(); c(); }
a(); while(b()) { d(); c(); }
It will become even worse with more complicated structure, e.g. when you want to find out whether two backward branches pointing to the same code location belong to a single loop with a conditional continue
statement within the body or to two nested loops. It can turn out to be impossible.