2

While instrumenting a class for its different methods In order to make a method do a write operation in a text file. I first stored the string in a local variable 3160 explicitly defined. How to choose these variables to prevent conflicts with already existing variables.

Like in this snippet The code does the work of writing the class name to a text file every time it enters any method. In order to do so the string s had to be loaded on stack using variable 3160 ( value kept large so that the already defined variable names do not conflict with variable s (3160). My Question is how to define a local variables in a method during instrumentation with ASM Library. This question may seem kind of premature to many but that is because I am a beginner.

    String s= className;
    mv.visitLdcInsn(s);
    mv.visitVarInsn(Opcodes.ASTORE, 3160);
    mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder");
    mv.visitInsn(Opcodes.DUP);
    mv.visitVarInsn(Opcodes.ALOAD, 3160);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;");
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V");
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/me/database/dataCollectionFile/Info", "callMeAnyTime", "()Ljava/lang/String;");
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
Eugene Kuleshov
  • 31,461
  • 5
  • 66
  • 67
Sanyam Goel
  • 2,138
  • 22
  • 40

3 Answers3

2

You should use LocalVariablesSorter adapter (either extend your own visitor from it, or add it to the visitors chain before MethodWriter). Then when you'll need a new variable you can call LocalVariablesSorter.newLocal() method to get new variable slot allocated. Also see ASM guide for more details.

Eugene Kuleshov
  • 31,461
  • 5
  • 66
  • 67
  • Thank you, Yes let me implement it this is a more clean solution and will solve my problem :) +1 – Sanyam Goel Jul 26 '12 at 13:33
  • 1
    Can you explain how this allows you to add a local variable using only one pass. i.e. when you want to insert a local variable, how does it know how many local variables the rest of the code will use? – Peter Lawrey Jul 26 '12 at 13:34
  • Can you also sort out this problem? I want to know that when ever in bytecode we encounter a method call in bytecodes it has some form . I want ot know where the information about method being invoked is stored, is there any table and how can it be accessed.? – Sanyam Goel Jul 26 '12 at 13:36
  • 1
    @sand1988 one answer at a time. Please post this as a separate question. :) – Eugene Kuleshov Jul 26 '12 at 14:29
  • 2
    @PeterLawrey it doesn't need to know. It simply remaps variables before and after, so all in one pass without breaking the visitor design pattern. BTW, information about variables in debug info is scoped by code ranges, so it is rather hard to use. – Eugene Kuleshov Jul 26 '12 at 14:33
  • @EugeneKuleshov a related question to PeterLawrey's question here http://stackoverflow.com/questions/27073721/avoiding-variable-slot-collisions-with-asms-localvariablessorter – MeBigFatGuy Nov 22 '14 at 14:31
1

I would look at the local variables debug table and I would use the next available id which is more likely to be 2 or 10 rather than 3160.

If you don't have debugging information, you may need to scan the code more than once, first to see how many ids have been used.

Note: double and long require two ids for historical reasons.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • How may ids does a string take?? Can you kindly suggest some really good resources to learn easily on bytecodes , how they work etc:) – Sanyam Goel Jul 26 '12 at 13:00
  • The number of ids is like the number of local variables. I am not sure byte code was meant to be easy. If you want easy, use Java ;) http://en.wikibooks.org/wiki/Java_Programming/Byte_Code – Peter Lawrey Jul 26 '12 at 13:05
  • Its not impossible, but it never struck me as easy. ;) – Peter Lawrey Jul 26 '12 at 13:13
  • Down voted because it gives a non-specific and somewhat misleading answer without providing specifics related to use of the ASM bytecode framework. When using ASM framework you don't have to scan bytecode more then once, nor need to rely on debugging information. – Eugene Kuleshov Jul 26 '12 at 13:29
1

newLocal(Type.type) is what I found is going to help in my case thank you Eugene Kuleshov and

Peter Lawrey for helping out :)

Sanyam Goel
  • 2,138
  • 22
  • 40