Abdullah Odeh Al-Zaghameem | 1 Jul 2009 19:24
Picon
Favicon

Re: misunderstanding of InstructionFactory


Hi,
 
You do not mentioned the type of your problem. Is it a Runtime Exception or you just didn't get the
expected results?. If the second option is the case, then you my inject your code at the end of the
constructor which, as I can guess, fall after the RETURN instruction.
 
If the first option is the case, then AUCH!!, no way to see in dark man, because your code is corrct (the one
with ifact.createThis(), but try InstructionFactory.createThis();)
). 

Best Regards,

===============================
A b d u l l a h   O.  A l - Z a g h a m e e m
Technical University of  Berlin
Germany

--- On Mon, 6/15/09, casertap <pierre.caserta <at> loria.fr> wrote:

From: casertap <pierre.caserta <at> loria.fr>
Subject: misunderstanding of InstructionFactory
To: bcel-user <at> jakarta.apache.org
Date: Monday, June 15, 2009, 7:22 PM

I have a very basic class:
---------------
public class MyClass{
    public static LinkedList<Class> classesLoaded;
    public static void addClass(Object o){
(Continue reading)

Felix Dorner | 2 Jul 2009 10:23

Extract Constructor Code to new method

Hey,

Given a no-arg constructor, I'd like to insert a new public method and move all instructions into that new
method. After moving that code, the constructor would look like one that's automatically inserted by the
compiler, i.e. only calls <init> of its superclass and returns.

I've never done anything with BCEL, though I can follow the general information pages. Still, I have no Idea
how hard my problem is and therefore wanted to ask here for some guidance.

Thanks,
Felix
Abdullah Odeh Al-Zaghameem | 2 Jul 2009 15:31
Picon
Favicon

Re: Extract Constructor Code to new method

Hi,
 
One basic solution is to catch the old constructor and inject the new one. The following code do it in simple way:
 
InstructionList il = new InstructionList();
Method theOldConstructor = cg.containsMethod("<>", "()V");
MethodGen theNewConstructor = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, Type.NO_ARGS,
NO_STRINGS, "<init>", cg.getClassName(), il, cpg);
il.append(ifact.createInvoke(cg.getSuperclassName(), "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
il.append(InstructionConstants.RETURN);
cg.replaceMethod(theOldConstructor, theNewConstructor.getMethod()); 
il.dispose();
cg.setConstantPool(cpg);
 
 
Regards

===============================
A b d u l l a h   O.  A l - Z a g h a m e e m
Technical University of  Berlin
Germany

--- On Thu, 7/2/09, Felix Dorner <FDorner <at> zed.com> wrote:

From: Felix Dorner <FDorner <at> zed.com>
Subject: Extract Constructor Code to new method
To: "bcel-user <at> jakarta.apache.org" <bcel-user <at> jakarta.apache.org>
Date: Thursday, July 2, 2009, 11:23 AM

Hey,
(Continue reading)

Felix Dorner | 2 Jul 2009 16:54

RE: Extract Constructor Code to new method

Hi Abdullah,

> InstructionList il = new InstructionList(); Method
> theOldConstructor = cg.containsMethod("<>", "()V"); MethodGen
> theNewConstructor = new MethodGen(Constants.ACC_PUBLIC,
> Type.VOID, Type.NO_ARGS, NO_STRINGS, "<init>",
> cg.getClassName(), il, cpg);
> il.append(ifact.createInvoke(cg.getSuperclassName(),
> "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL));
> il.append(InstructionConstants.RETURN);
> cg.replaceMethod(theOldConstructor,
> theNewConstructor.getMethod()); il.dispose(); cg.setConstantPool(cpg);

Wouldn't this just 'delete' the old constructor, and create a new 'default' one?
What misses is to move the code that's inside the old constructor into an ordinairy method. What I came up
with so far was to:

/* look up the default constructor */
Method constructor_method = getConstructors().get(0);
ConstantPoolGen cpgen = new ConstantPoolGen(jc.getConstantPool());

MethodGen constructor = new MethodGen(constructor_method, jc.getClassName(), new ConstantPoolGen(jc.getConstantPool()));
InstructionList constructor_code = constructor.getInstructionList();

/* a new method. Later I'd need to find a unique name.. I also copy the constructor's instruction list*/
MethodGen newmethod = new MethodGen(Constants.ACC_PUBLIC, Type.VOID, new Type[] {}, new String[] {},
"xaxaxa", jc.getClassName(),  constructor_code.copy() , cpgen);

InstructionHandle[] newmethod_instructions = newmethod.getInstructionList().getInstructionHandles();

(Continue reading)

Felix Dorner | 3 Jul 2009 12:20

LocalVariableGen appearing twice in InstructionTargeters list

Hey,

I can see a LocalVariableGen _twice_ in the InstructionTargeter list for the first InstructionHandle of a
method. Why would this happen? The LocalVariableGen is the one that represents the 'this' variable. 

I assume the LocalVariableGen is an InstructionTargeter because it maintains the 'start' and 'end'
instructions which defines the scope of the variable?

The first instruction is always the 'start' instruction for the 'this' variables scope right? This would
explain why the LocalVariableGen has it targeted.

Thanks for hints,
Felix  
Laran Evans | 24 Jul 2009 18:04
Picon

Matching line numbers from debug-compiled code to original source

I've been reading through the documentation (mostly the BCEL JavaDocs)
to find out how to do this.

I'm compiling code with debugging info enabled. So, the line number
info is in there.

What I need to do is take the compiled .class file, and do something like this:

for each method in myClass:
- Code code  = method.getCode();
- String instructions = Utility.codeToString(code.getCode(),
code.getConstantPool(), 0, -1, false)
- Figure out the line number in the source code for each (or at least
some) instruction.

How would I do this?

I've been looking at LineNumberTable but haven't figured out how to
put the pieces together.

So, how would I do this?

Thanks.

Gmane