Be sure to read up on the two following methods: instructionList.setPositions();
instructionList.redirectBranches(oldHandle, newHandle); And maybe: instructionList.redirectLocalVariables(methodGen.getLocalVariables(), oldHandle, newHandle); -----Original Message----- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] Sent: Tuesday, October 01, 2002 9:35 AM To: BCEL Users List Subject: Re: Instrumenting a constructor > Rather than rename the constructor which generates the problems you mention, > you could call a private method that you define which contains your code. Yeah, that's fine. It doesn't really make any difference to me whether I inline the logic or not. > I think you only have to identify the return statements (and the end of the > constructor) and do an insert of the call to your method (taking care about > pushing any necessary parameters). Don't all returns have to be explicit in bytecode? For example, when I look at the bytecode for public class Foo {} (compiled with jdk 1.4.1) I see Method Foo() 0 aload_0 1 invokespecial #1 <Method java.lang.Object()> 4 return > Be sure to only call insert on the instruction list object and the other > bytecode in it will be OK, e.g., targets for try should still work as these > bytecodes have just been shifted in the list. Do NOT work with a copy of the > list or else you inserts will not work as copies of the bytecodes have been > taken and then BCEL looses its notion of which bytecode it's dealing with (as > the instruction handle has changed) and so you have to do a lot of your own > work patching up the branches and try-catch blocks. Just to make sure I understand, you're saying that BCEL will do any jump patching for me, as long I use InstructionList.insert*, and then I won't have to do any manually patching at all? (I was actually looking for an insert method before, but managed to miss it all this time <sigh>). > I'm not sure about this, I would hope this would be in slot 0 right from the > start, as there is an implicit call to the super constructor which is > dispatched via the VM with respect to this (i.e., there is nothing at the > bytecode level to indicate super, 'this' is passed to the VM and it does the > step up to super). Not sure what you mean here. The super call is explicitly in the bytecode. Like my previous example, public class Foo {} (compiled with jdk 1.4.1) I see Method Foo() 0 aload_0 1 invokespecial #1 <Method java.lang.Object()> 4 return The compiler explicitly generated the language level implicit constructor and implicit super call. My point, which you don't see here, is that, for some methods, I've seen the compiler generate bytecode which overwrites slot 0, so the "this" reference that's placed there when the method begins execution is lost. So, if I were to try to invoke my private method, for example, I couldn't just insert aload_0 invokespecial #N (myMethod) because I couldn't depend on slot 0 containing the "this" reference. In fact, generally speaking, I can't depend upon the state of any slot or the stack at all, unless I build a small scale virtual machine, or insert code at the very beginning of a method. So, again, I'm just saying that, as far as I understand, I would have to "addLocalVariable" and then insert aload_0 astore_N (where N is LocalVariable.getIndex() ) to be able to get the "this" reference when I need it. IIUC, that applies to any local variable that I need to get a hold of. > If you leave the original alone and insert into its list I believe the > branches to the original bytecodes should be OK. Thanks very much for the help. God bless, -Toby Reyelts -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>
