decompiling - How do Java decompilers discern a for-loop from a while-loop? -
consider these 2 methods:
public static void forloop(int start, int limit) { (int = start; < limit; i++) { } } public static void whileloop(int start, int limit) { int = start; while (i < limit) { i++; } }
when compiled, produce bytecode (this verbose output of javap
):
public static void forloop(int, int); descriptor: (ii)v flags: acc_public, acc_static code: stack=2, locals=3, args_size=2 0: iload_0 1: istore_2 2: iload_2 3: iload_1 4: if_icmpge 13 7: iinc 2, 1 10: goto 2 13: return linenumbertable: line 6: 0 line 9: 13 localvariabletable: start length slot name signature 2 11 2 0 14 0 start 0 14 1 limit public static void whileloop(int, int); descriptor: (ii)v flags: acc_public, acc_static code: stack=2, locals=3, args_size=2 0: iload_0 1: istore_2 2: iload_2 3: iload_1 4: if_icmpge 13 7: iinc 2, 1 10: goto 2 13: return linenumbertable: line 12: 0 line 13: 2 line 14: 7 line 16: 13 localvariabletable: start length slot name signature 0 14 0 start 0 14 1 limit 2 12 2
as can see, code section both of these methods exactly same. however, when decompile class using jd, correctly produces:
public static void forloop(int start, int limit) { (int = start; < limit; i++) {} } public static void whileloop(int start, int limit) { int = start; while (i < limit) { i++; } }
how able this? bytecode of these methods same! despite fact linenumbertable
, localvariabletable
attributes different each method, reluctant believe reason since not required attributes code
attribute of method contain (per section 4.7 of java language specification, java se 8 edition).
the line numbers , local variable scope.
for
loop:
linenumbertable: line 6: 0 line 9: 13 localvariabletable: start length slot name signature 2 11 2 0 14 0 start 0 14 1 limit
while
loop:
linenumbertable: line 12: 0 line 13: 2 line 14: 7 line 16: 13 localvariabletable: start length slot name signature 0 14 0 start 0 14 1 limit 2 12 2
the for
loop has fewer distinct lines of code - makes sense because wraps initialization , increment in 1 line.
Comments
Post a Comment