Re: Problem reloading a local variable in ASM
Rémi Forax <[email protected]>
| Newsgroups | gmane.comp.java.objectweb.asm |
|---|---|
| Message-ID | <[email protected]> |
Hi nemo,
the top of the stack contains the last argument, not the receiver.
Or you have to spill all arguments and reconstruct the stack after,
or you can use the analyzer (cf package analysis) to insert your store
to a new local variable
when the receiver is pushed on the stack or if you use java 7, you can
generate
an invokedynamic instead of invokeinterface and construct a method
handle blob
that filter the first parameter (the receiver) to call your own routine.
cheers,
Rémi
On 10/05/2011 11:22 PM, Nemo Caviani wrote:
> Hi all,
>
> I have a weird problem with accessing a previously created local
> variable through ASM and I hope you expertise can help me.
>
> I am trying to retrieve the name of a class implementing a Java
> interface and then using this name as a key in a data structure to
> retrieve some code metrics about the class. Here is what I have done:
>
> public void visitMethodInsn(int opcode, String owner, String name,
> String desc) {
>
> int methodOwner =
> _lvs.newLocal(Type.getType("Ljava/lang/String;"));
>
> if (opcode == Opcodes.INVOKEINTERFACE) {
>
> // pop the operand stack to get to the object whose method
> is being called
>
> int callingObj = _lvs.newLocal(Type.getType(Object.class));
> this.visitVarInsn(Opcodes.ASTORE, callingObj);
> this.visitVarInsn(Opcodes.ALOAD, callingObj);
> this.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
> "java/lang/Object", "getClass", "()Ljava/lang/Class;");
> this.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
> "java/lang/Class", "getName", "()Ljava/lang/String;");
> this.visitVarInsn(Opcodes.ASTORE, methodOwner);
> this.visitVarInsn(Opcodes.ALOAD, callingObj);
>
> /// (1)
> /// some code using the methodOwner ....
> /// something like the following
> /// this.visitVarInsn(Opcodes.ALOAD, methodOwner);
>
> /// reconstruct the operand stack for the method to be invoked
> }
>
> super.visitMethodInsn(opcode, owner, name, desc);
>
> if (opcode == Opcodes.INVOKEINTERFACE) {
> /// (2)
> /// some more code using the methodOwner .....
> ///
> /// this.visitVarInsn(Opcodes.ALOAD, methodOwner);
> }
> }
>
> If I comment out code snippets in block (2) from the code above, it
> works. However when I try to access "methodOwner" in block (2), I
> receive the following verification error indicating that the string
> object is gone missing. I can't understand why.
>
> org.objectweb.asm.tree.analysis.AnalyzerException: Error at
> instruction 813: Expected an object reference, but found .
>
> Since calling "super.visitMethodInsn(opcode, owner, name, desc);" pops
> the object whose interface method is called, I can't get a reference
> to it again. I tried keeping a second copy of the object in another
> variable but same problem occurs.
>
> I wonder if you have any clue on what is wrong here and if you can
> give me some advice.
>
> thanks very much for your help,
> nemo
message-footer.txt
(text/plain, 238 B)
-- You receive this message as a subscriber of the [email protected] mailing list. To unsubscribe: mailto:[email protected] For general help: mailto:[email protected]?subject=help OW2 mailing lists service home page: http://www.ow2.org/wws