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 dw...@students.cs.uu.nl on 2004/01/08 14:15:37 UTC
Incorrect LocalVariable and some other questions
Intrumenting the main using the following code (partial) results in all
methods printing that they are invoked.
//...
InstructionList ilEntryPrint = new InstructionList();
ilEntryPrint.append(new GETSTATIC(_out));
ilEntryPrint.append(new PUSH(cp,sMgs + " entered"));
ilEntryPrint.append(new INVOKEVIRTUAL(_println));
// Get byte-code from current method
MethodGen mg = new MethodGen(methods[i],
cg.getJavaClass().getClassName(), cp);
InstructionList il = mg.getInstructionList();
if(il == null) // method has no body
break;
InstructionHandle[] ihs = il.getInstructionHandles();
// Check if method is a constructor
if (sName.equals("<init>"))
{
// First let the super or other constructor be called
for (int j = 1; j < ihs.length; j++)
{
if (ihs[j].getInstruction() instanceof INVOKESPECIAL)
{
// Append log instructions after the super or
constructor invocation
il.append(ihs[j], ilEntryPrint);
break;
}
}
}
else // Method is not a constructor
{
// Insert log instructions the beginning of the method body
il.insert(ihs[0], ilEntryPrint);
}
// Set attributes and overwrite method with modified one
mg.setMaxLocals();
mg.setMaxStack();
methods[i] = mg.getMethod();
il.dispose();
//DEBUG
Code code = methods[i].getCode();
if (code != null)
System.out.println(code);
//...
The 'System.out.println(code);' part yields the following for some main
method and my first question
is about 'LocalVariable(start_pc = 8, length = 27, index = 0:String[]
args)'; shouldn't this be
something like 'LocalVariable(start_pc = 0, length = 35, index =
0:String[] args)' since maybe not
in this case but I could have decided to use some element of args to be
printed and now it is not
in the scope, right?
Code(max_stack = 2, max_locals = 3, code_length = 35)
0: getstatic java.lang.System.out Ljava/io/PrintStream; (35)
3: ldc "Method: public static void main(String[] arg0) from Class Test
entered" (45)
5: invokevirtual java.io.PrintStream.println (Ljava/lang/String;)V (41)
8: new <ClassB> (2)
11: dup
12: invokespecial ClassB.<init> ()V (3)
15: astore_1
16: iconst_0
17: istore_2
18: iload_2
19: bipush 10
21: if_icmpge #34
24: aload_1
25: invokevirtual ClassB.printMsg ()V (4)
28: iinc %2 1
31: goto #18
34: return
Attribute(s) =
LocalVariable(start_pc = 8, length = 27, index = 0:String[] args)
LocalVariable(start_pc = 16, length = 19, index = 1:ClassB bb)
LocalVariable(start_pc = 18, length = 17, index = 2:int i)
LineNumber(8, 5), LineNumber(16, 6), LineNumber(24, 7), LineNumber(28, 6),
LineNumber(34, 8)
Another question I have is on when to use the JavaClass directly and when
use ClassGen. I mean, ran into the problem when modifying some code using
a JavaClass instance and adding a method using a ClassGen created from
this instance of JavaClass does not 'effect' the initial JavaClass so not
all changes/additions were incorporated when I used
somecg.getJavaClass().dump(somefile); or somejavaclass.dump(somfile); made
on. I mean one had the changes and the other only the addition.. This must
be something people run into often. I solved it by using ClassGen for both
but maybe there is some nice rule of thumb or anything?.. Maybe a pointer
to src that does both modifying existing methods and adding new ones..
Finally, what do the LineNumber(x,y) attributes tell me and why don't all
methods have one?
Any help would be highly appreciated.
---------------------------------------------------------------------
To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: bcel-user-help@jakarta.apache.org