This first part gets some general information about what class we're in and what the name of the function is. This is accomplished by creating an exception and parsing the first 2 entries of the stack trace. The first entry is the line that the exception is thrown on which we can grab the methodName from and the second entry is where the function was called from.
java.lang.Exception
at E.getParamName(E.java:28)
at E.main(E.java:17)
The first entry is the line that the exception is thrown on which we can grab the methodName from and the second entry is where the function was called from.
Putting it all together
public static void main(java.lang.String[]);
Code:
...
18: getstatic #19 // Field java/lang/System.out:Ljava/io/PrintStream;
21: aload_1
22: aload_2
23: invokevirtual #25 // Method getParamName:(Ljava/lang/String;)Ljava/lang/String;
...
LineNumberTable:
...
line 17: 18
line 18: 29
line 19: 40
...
LocalVariableTable:
Start Length Slot Name Signature
0 83 0 args [Ljava/lang/String;
8 75 1 e LE;
11 72 2 str Ljava/lang/String;
14 69 3 str2 Ljava/lang/String;
18 65 4 str4 Ljava/lang/String;
77 5 5 e1 Ljava/lang/Exception;
This is basically what we're looking at. In the example code the first invocation is line 17. line 17 in the LineNumberTable shows that the beginning of that line is bytecode line index 18. That is the System.out
load. Then we have aload_2
right before the method call so we look for the variable in slot 2 of the LocalVariableTable which is str
in this case.