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
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.