WG: ASMifier
Zanella David <[email protected]>
| Newsgroups | gmane.comp.java.objectweb.asm |
|---|---|
| Message-ID | <2D6CA1E59A2A5340BB40755995CEF8040269EB51207E@HEFRMAIL.sofr.hefr.lan> |
Hi,
I'm a CS student at College of Engineering and Architecture of Fribourg (www.eia-fr.ch). I worked on ASMifier for a semester project, and now I would like to get some feedback.
The goal of the project was to make the ASMifier output easier readable for a human. For that, I have extended/modified the ASMifier -debug output :
- Added some commends
- Changed the order of instructions (to group label declarations e.g.)
- Replaced the local variable index (in xxLOAD/xxSTORE) with named constants, which try to mimic the variable names used in the source code
- highlight labeled sections with Java blocks {}
- and some other minor changes
To have the best result, you should use the command line instruction. On that result, you should only correct the indentation (in eclipse: select code, alt+i) [not reformat, you will lose some spaces for the alignment]. In this e-mail, i have attached only one example of the new output layout, but you can find the plugin .jar file as well as the whole source code at my project site : http://david.zanella.home.hefr.ch/asm -> sources.
It would be nice to have some feedback from you for my project defense.
If you have any question, don't hesitate to contact me per e-mail.
Greetings
David Zanella
Hello.java
(text/x-java, 378 B)
package example;
public class Hello {
private String name;
public static final int TIMES = 10;
public Hello(String name){
this.name = name;
}
public void sayHello(){
System.out.println("Hello" + name);
}
public static void main(String[] args) {
Hello hi = new Hello("YourName");
for(int i = 0; i < Hello.TIMES; i++){
hi.sayHello();
}
}
}
HelloDump.java
(text/x-java, 5.7 KB)
package asm.example;
import java.util.*;
import org.objectweb.asm.*;
import org.objectweb.asm.attrs.*;
public class HelloDump implements Opcodes {
public static byte[] dump () throws Exception {
ClassWriter cw = new ClassWriter(0);
FieldVisitor fv;
MethodVisitor mv;
AnnotationVisitor av0;
cw.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "example/Hello", null, "java/lang/Object", null);
cw.visitSource("Hello.java", null);
// ** Field : name **
{
fv = cw.visitField(ACC_PRIVATE, "name", "Ljava/lang/String;", null, null);
fv.visitEnd();
}
// ** Constant : TIMES **
{
fv = cw.visitField(ACC_PUBLIC + ACC_FINAL + ACC_STATIC, "TIMES", "I", null, new Integer(10));
fv.visitEnd();
}
// == Constructor ==
{
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/String;)V", null, null);
// --- Declaration of Labels ---
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
Label l3 = new Label();
// --- Declaration of Variables ---
final int VAR_this_l0_l3 = 0; // Original Typ: Lexample/Hello;
final int VAR_name_l0_l3 = 1; // Original Typ: Ljava/lang/String;
// --- Start of Method Code ---
mv.visitCode();
mv.visitLabel(l0);
{
/* 9 */mv.visitLineNumber(9, l0);/* 9 */
mv.visitVarInsn (ALOAD, VAR_this_l0_l3);
mv.visitMethodInsn (INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
}
mv.visitLabel(l1);
{
/* 10 */mv.visitLineNumber(10, l1);/* 10 */
mv.visitVarInsn (ALOAD, VAR_this_l0_l3);
mv.visitVarInsn (ALOAD, VAR_name_l0_l3);
mv.visitFieldInsn (PUTFIELD, "example/Hello", "name", "Ljava/lang/String;");
}
mv.visitLabel(l2);
{
/* 11 */mv.visitLineNumber(11, l2);/* 11 */
mv.visitInsn (RETURN);
}
mv.visitLabel(l3);
{
mv.visitLocalVariable("this", "Lexample/Hello;", null, l0, l3, 0);
mv.visitLocalVariable("name", "Ljava/lang/String;", null, l0, l3, 1);
mv.visitMaxs(2, 2);
mv.visitEnd();
}
}
// == Method sayHello : ()V ==
{
mv = cw.visitMethod(ACC_PUBLIC, "sayHello", "()V", null, null);
// --- Declaration of Labels ---
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
// --- Declaration of Variables ---
final int VAR_this_l0_l2 = 0; // Original Typ: Lexample/Hello;
// --- Start of Method Code ---
mv.visitCode();
mv.visitLabel(l0);
{
/* 14 */mv.visitLineNumber(14, l0);/* 14 */
mv.visitFieldInsn (GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitTypeInsn (NEW, "java/lang/StringBuilder");
mv.visitInsn (DUP);
mv.visitLdcInsn ("Hello");
mv.visitMethodInsn (INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "(Ljava/lang/String;)V");
mv.visitVarInsn (ALOAD, VAR_this_l0_l2);
mv.visitFieldInsn (GETFIELD, "example/Hello", "name", "Ljava/lang/String;");
mv.visitMethodInsn (INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
mv.visitMethodInsn (INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
mv.visitMethodInsn (INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
}
mv.visitLabel(l1);
{
/* 15 */mv.visitLineNumber(15, l1);/* 15 */
mv.visitInsn (RETURN);
}
mv.visitLabel(l2);
{
mv.visitLocalVariable("this", "Lexample/Hello;", null, l0, l2, 0);
mv.visitMaxs(4, 1);
mv.visitEnd();
}
}
// == Method main : ([Ljava/lang/String;)V ==
{
mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
// --- Declaration of Labels ---
Label l0 = new Label();
Label l1 = new Label();
Label l2 = new Label();
Label l3 = new Label();
Label l4 = new Label();
Label l5 = new Label();
Label l6 = new Label();
Label l7 = new Label();
// --- Declaration of Variables ---
final int VAR_args_l0_l7 = 0; // Original Typ: [Ljava/lang/String;
final int VAR_hi_l1_l7 = 1; // Original Typ: Lexample/Hello;
final int VAR_i_l2_l6 = 2; // Original Typ: I
// --- Start of Method Code ---
mv.visitCode();
mv.visitLabel(l0);
{
/* 18 */mv.visitLineNumber(18, l0);/* 18 */
mv.visitTypeInsn (NEW, "example/Hello");
mv.visitInsn (DUP);
mv.visitLdcInsn ("YourName");
mv.visitMethodInsn (INVOKESPECIAL, "example/Hello", "<init>", "(Ljava/lang/String;)V");
mv.visitVarInsn (ASTORE, VAR_hi_l1_l7);
}
mv.visitLabel(l1);
{
/* 20 */mv.visitLineNumber(20, l1);/* 20 */
mv.visitInsn (ICONST_0);
mv.visitVarInsn (ISTORE, VAR_i_l2_l6);
}
mv.visitLabel(l2);
{
mv.visitJumpInsn (GOTO, l3);
}
mv.visitLabel(l4);
{
/* 21 */mv.visitLineNumber(21, l4);/* 21 */
mv.visitFrame(Opcodes.F_APPEND,2, new Object[] {"example/Hello", Opcodes.INTEGER}, 0, null);
mv.visitVarInsn (ALOAD, VAR_hi_l1_l7);
mv.visitMethodInsn (INVOKEVIRTUAL, "example/Hello", "sayHello", "()V");
}
mv.visitLabel(l5);
{
/* 20 */mv.visitLineNumber(20, l5);/* 20 */
mv.visitIincInsn (VAR_i_l2_l6, 1);
}
mv.visitLabel(l3);
{
mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
mv.visitVarInsn (ILOAD, VAR_i_l2_l6);
mv.visitIntInsn (BIPUSH, 10);
mv.visitJumpInsn (IF_ICMPLT, l4);
}
mv.visitLabel(l6);
{
/* 23 */mv.visitLineNumber(23, l6);/* 23 */
mv.visitInsn (RETURN);
}
mv.visitLabel(l7);
{
mv.visitLocalVariable("args", "[Ljava/lang/String;", null, l0, l7, 0);
mv.visitLocalVariable("hi", "Lexample/Hello;", null, l1, l7, 1);
mv.visitLocalVariable("i", "I", null, l2, l6, 2);
mv.visitMaxs(3, 3);
mv.visitEnd();
}
}
cw.visitEnd();
return cw.toByteArray();
}
}
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