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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.