Hey Marco,

1) No it's not possible to get directly the variable name when you call
s.length(). In Bytecode, s.length gets translated into two instructions:
aload_1
invokevirtual<java/lang/String.length>

aload_1 gets the object reference from local variable[1] (s) and pushes it
on the stack.
invokevirtual only has information about the class and method names and uses
the object reference that you pushed earlier. In other words, by the time
the instruction arrives to invokevirtual, there's no way to know directly
that the object reference on the stack came from local variable "s".

That doesn't mean that there's no other way to get it indirectly. I can
think of two solutions. Either track (or simulate) the execution of every
instruction (i.e. keep track that the object reference on the stack came
from local variable "s"). Another way would be to analyze the source code
itself  from the line number of invokevirtual (which you can get from the
line number table).

2) To simplify. In Java there are two "types" of variables:
- local variables which belong to a method and can be manipulated using the
bytecode instructions: load & store
- fields which belong to a class and can be manipulated using the bytecode
instructions: getfield, putfield, getstatic, putstatic. You know what is the
type of the variable by checking which instruction you are using.

3) aload_0 mean: load from local_variable_table[0]. What is in this position
depends on the method.
Examples:

(a)
public static void foo()
{
  int x;
  int y;
}

local_variable_table = [x,y]

(b)
public static void foo(int a, int b)
{
  int x;
  int y;
}

local_variable_table = [a,b,x,y]

(c)
public void foo(int a)
{
  int x;
  int y;
}

local_variable_table = [this,a,x,y]
In this case, an instance method has always a reference to the enclosing
object (this) at local_variable_table[0].

Hence, you can deduce why aload_0 refer to args in the main method.

I see that you lack some basic concepts in Bytecode and the JVM. I recommend
you to read this old but excellent book: Inside the Java Virtual Machine by
Bill Venners (McGraw Hill)

Good luck

Habib


On Mon, Jun 14, 2010 at 2:12 PM, Marco Bessi <bessima...@gmail.com> wrote:

> Hi all,
> I have same problem with bcel api, so I try to answere in this list.
>
> 1) How can I get the class variable name about the method that is invoked?
> Explain: I have this example code.
> String s = "hello";
> String g = "world";
> int i = s.lenght();
> How can I retrieve the name of the variable where i call the method
> lenght()? I want the variable name "s"!
>
> Because if I lunch the command "javap -verbose ClassName" I obtain the
> bytecode for the class ClassName and I can't get directly the name of
> the class where the method is called. For the example code I can get
> only that lenght() is a method of the class String but not the name of
> the variable "s".
>
> 2) If I didn't compile the file class with "javac -g" I can't have the
> LocalVariableTable, ok? But can I know if a variable is declarated
> internally in the method or is a global variable of the class?
> HashSet<String> argsVar = new HashSet<String>();
> String[] args = mg.getArgumentNames(); //mg is a MethodGen variable
> int k = 0;
> int nArgs = args.length;
> while(k < nArgs){
>        argsVar.add(args[k]);
>        k++;
> }
>
> 3) The bytecode instructions aload_0 refears always at: args if the
> method is the main; this otherwise?
>
> Sorry for my bad English.
> Thanks for the attention.
> Marco.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: bcel-user-unsubscr...@jakarta.apache.org
> For additional commands, e-mail: bcel-user-h...@jakarta.apache.org
>
>

Reply via email to