You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bcel-user@jakarta.apache.org by Marco Bessi <be...@gmail.com> on 2010/06/14 13:12:46 UTC

Same questions about variable names

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-unsubscribe@jakarta.apache.org
For additional commands, e-mail: bcel-user-help@jakarta.apache.org


Re: Same questions about variable names

Posted by Habib <ho...@gmail.com>.
Hello Marco,

1) No you can never suppose an order of instructions, unless specified by
the JVMS. Takes this example:

local_variable_table = [a:ref,x:int,y:int]

a.foo(x+y)

it gets compiled to

aload_0
iload_1
iload_2
iadd
invokevirtual <foo>

So you're assumptions will rarely hold. The way is to do some flow control
and track the execution of instructions (this is called Profiling).

2) BCEl parses the class file to get this information. If they're not there,
there's no way to get em.

Good luck

Habib


On Tue, Jun 15, 2010 at 12:05 PM, Marco Bessi <be...@gmail.com> wrote:

> Thanks Habib for your reply!
>
> 1) In "The Java Virtual Machine Specification (v1.0)" I have seen the
> bytecode instruction with their syntax and stack (before and after the
> instruction).
> Can I suppose that before a:
> - invokevirtual have always (in opposite order): N args load (where N
> is the number of parameter passed to the method), an aload (to get the
> objReference);
> - iastore have always (in opposite order): iconst (or iload), iconst
> (or iload), aload (to get the objReference) [and something like this
> for fastore/aastore/bastore/castore/sastore];
> - etc for other instructions...
> If I can suppose the previous sentences, How can I get the
> objReference of the aload? This is the reference of the variable over
> I call the method of the invokevirtual?
>
> 2) The [where mg is a MethodGen variable]
> mg.getLocalVariableTable(cp), mg.getArgumentNames() and
> LineNumberTable can only recuperated from the bytecode if it is
> generated with "java -g"? Or I can always get them?
>
> 3) Ok!
>
> I Will read the book. Thanks for the hint!
>
> Thanks.
> Marco.
>
>
> 2010/6/14 Habib
> > 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 <be...@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-unsubscribe@jakarta.apache.org
> >> For additional commands, e-mail: bcel-user-help@jakarta.apache.org
> >>
> >>
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: bcel-user-help@jakarta.apache.org
>
>

Re: Same questions about variable names

Posted by Marco Bessi <be...@gmail.com>.
Thanks Habib for your reply!

1) In "The Java Virtual Machine Specification (v1.0)" I have seen the
bytecode instruction with their syntax and stack (before and after the
instruction).
Can I suppose that before a:
- invokevirtual have always (in opposite order): N args load (where N
is the number of parameter passed to the method), an aload (to get the
objReference);
- iastore have always (in opposite order): iconst (or iload), iconst
(or iload), aload (to get the objReference) [and something like this
for fastore/aastore/bastore/castore/sastore];
- etc for other instructions...
If I can suppose the previous sentences, How can I get the
objReference of the aload? This is the reference of the variable over
I call the method of the invokevirtual?

2) The [where mg is a MethodGen variable]
mg.getLocalVariableTable(cp), mg.getArgumentNames() and
LineNumberTable can only recuperated from the bytecode if it is
generated with "java -g"? Or I can always get them?

3) Ok!

I Will read the book. Thanks for the hint!

Thanks.
Marco.


2010/6/14 Habib
> 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 <be...@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-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: bcel-user-help@jakarta.apache.org
>>
>>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: bcel-user-help@jakarta.apache.org


Re: Same questions about variable names

Posted by Habib <ho...@gmail.com>.
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 <be...@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-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: bcel-user-help@jakarta.apache.org
>
>