Reputation: 178
I am evaluating the possibility of using ASM as framework for implementing some bytecode analysis. So far I have been playing with a few examples but there are a couple of things that I need to sort out: 1) I don't see how I can detect a method fully signature with the MethodVisitor class (full argument type names and formal names).
2) In case the .class file being analysed has the java source associated, how to link bytecode instructions with the line numbers in the source
3) How to differentiate between instance fields and static fields in a ClassVisitor
Upvotes: 0
Views: 1341
Reputation: 178
1) Actually I manage to extract detailed method signature (arguments types and names and return type) as part of a MethodVisitor implementation. Remark: this only works if the class file was compiled including debug info.
@Override
public MethodVisitor visitMethod(int access, String name,
String desc, String signature, String[] exceptions) {
try {
final LinkedList<String> parameters;
final boolean isStaticMethod;
Type[] args = Type.getArgumentTypes(desc);
Type ret = Type.getReturnType(desc);
parameters = new LinkedList<String>();
isStaticMethod = Modifier.isStatic(access);
return new MethodVisitor(Opcodes.ASM5) {
// assume static method until we get a first parameter name
public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) {
if (isStaticMethod && parameters.size() < args.length) {
parameters.add(args[index].getClassName()+" " +name);
} else if (index > 0 && parameters.size() < args.length) {
// for non-static the 0th arg is "this" so we need to offset by -1
parameters.add(args[index-1].getClassName() +" " +name);
}
}
@Override
public void visitEnd() {
System.out.println("Method: "+ret.getClassName()+" "+name+"("+String.join(", ", parameters)+")");
super.visitEnd();
}
};
} catch (Exception e) {
throw e;
}
Which will produce the following output for an standard main:
Method: void main(java.lang.String[] args)
2) The arguments Label start
and Label end
include information about the corresponding source as long as there is a source included when the compilation took place.
3) See @Peter Lawrey reply.
Upvotes: 0
Reputation: 533530
1) I don't see how I can detect a method fully signature with the MethodVisitor class (full argument type names and formal names).
You can't. The ClassVisitor receives a call like
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions)
and before you return the MethodVistor, you need to capture the information from the parameters you are interested in.
If the code was compiled with debugging information, you can obtain the parameter and local variable names with visitLocalVariable
2) In case the .class file being analysed has the java source associated, how to link bytecode instructions with the line numbers in the source
The code in the method will have source information "instruction" in the form of a visitLabel
3) How to differentiate between instance fields and static fields in a ClassVisitor
By the access
modifier. Use Modifier.isStatic(access)
Upvotes: 2