Label position offset by one
I am using asm to trace the local variable, that means to map the index in instructions like ALOAD or ASTORE to the actual local variable, my idea is to maintain a current local variables during read class. however, it seems the Label in asm has a offset-by-one issue. considering the following demo code
package test;
public class Foo {
void bar() {
for (int i = 0; i < 10; ++i) {
System.out.println(i);
}
for (int j = 0; j < 10; ++j) {
System.out.println(j);
}
}
}
and the corresponding bytecodes
// class version 49.0 (49)
// access flags 0x21
public class Foo {
// compiled from: Foo.java
// access flags 0x1
public <init>() : void
L0
LINENUMBER 3 L0
ALOAD 0: this
INVOKESPECIAL Object.<init> () : void
RETURN
L1
LOCALVARIABLE this Foo L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x0
bar() : void
L0
LINENUMBER 5 L0
ICONST_0
ISTORE 1
L1
GOTO L2
L3
LINENUMBER 6 L3
GETSTATIC System.out : PrintStream
ILOAD 1: i
INVOKEVIRTUAL PrintStream.println (int) : void
L4
LINENUMBER 5 L4
IINC 1: i 1
L2
ILOAD 1: i
BIPUSH 10
IF_ICMPLT L3
L5
LINENUMBER 9 L5
ICONST_0
ISTORE 1
L6
GOTO L7
L8
LINENUMBER 10 L8
GETSTATIC System.out : PrintStream
ILOAD 1: j
INVOKEVIRTUAL PrintStream.println (int) : void
L9
LINENUMBER 9 L9
IINC 1: j 1
L7
ILOAD 1: j
BIPUSH 10
IF_ICMPLT L8
L10
LINENUMBER 12 L10
RETURN
L11
LOCALVARIABLE this Foo L0 L11 0
LOCALVARIABLE i int L1 L5 1
LOCALVARIABLE j int L6 L10 1
MAXSTACK = 2
MAXLOCALS = 2
}
from the local variables table we can know the scope of variable j is between L6 and L10, however, the instruction 'ISTORE 1' above the L6 label is actual operating variable j, in all other more complicate scenario, the first usage of a local variable always ahead of its start label, i fully understand that the label is just a logic concept to understand the offset in jump instructions, current implementation in asm respect to the offset in original bytecode, however, this lead to difficult of analyzing the scope of local variables, I assume this can be fixed by generate the Label one position ahead during read class, and add one to the offset during write to reverse the change.