jakarta-bcel-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Habib <hob...@gmail.com>
Subject Re: Same questions about variable names
Date Wed, 16 Jun 2010 10:00:38 GMT
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 <bessimarco@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 <bessimarco@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
>
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message