/***
 * ASM examples: examples showing how ASM can be used
 * Copyright (c) 2000-2011 INRIA, France Telecom
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
import java.io.FileOutputStream;

import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

/**
 * @author Eric Bruneton
 */
public class Compile extends ClassLoader {

    public static void main(final String[] args) throws Exception {
        // creates the expression tree corresponding to
        // exp(i) = i > 3 && 6 > i
        Exp exp = new And(new GT(new Var(0), new Cst(3)), new GT(new Cst(6),
                new Var(0)));
        // compiles this expression into an Expression class
        Compile main = new Compile();
        byte[] b = exp.compile("Example");
        FileOutputStream fos = new FileOutputStream("Example.class");
        fos.write(b);
        fos.close();
        Class<?> expClass = main.defineClass("Example", b, 0, b.length);
        // instantiates this compiled expression class...
        Expression iexp = (Expression) expClass.newInstance();
        // ... and uses it to evaluate exp(0) to exp(9)
        for (int i = 0; i < 10; ++i) {
            boolean val = iexp.eval(i, 0) == 1;
            System.out.println(i + " > 3 && " + i + " < 6 = " + val);
        }
    }
}

/**
 * An abstract expression.
 * 
 * @author Eric Bruneton
 */
abstract class Exp implements Opcodes {

    /*
     * Returns the byte code of an Expression class corresponding to this
     * expression.
     */
    byte[] compile(final String name) {
        // class header
        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
        cw.visit(V1_1, ACC_PUBLIC, name, null, "java/lang/Object",
                new String[] { Expression.class.getName() });

        // default public constructor
        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null,
                null);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        mv.visitInsn(RETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();

        // eval method
        mv = cw.visitMethod(ACC_PUBLIC, "eval", "(II)I", null, null);
        compile(mv);
        mv.visitInsn(IRETURN);
        // max stack and max locals automatically computed
        mv.visitMaxs(0, 0);
        mv.visitEnd();

        return cw.toByteArray();
    }

    /*
     * Compile this expression. This method must append to the given code writer
     * the byte code that evaluates and pushes on the stack the value of this
     * expression.
     */
    abstract void compile(MethodVisitor mv);
}

/**
 * A constant expression.
 */
class Cst extends Exp {

    int value;

    Cst(final int value) {
        this.value = value;
    }

    @Override
    void compile(final MethodVisitor mv) {
        // pushes the constant's value onto the stack
        mv.visitLdcInsn(new Integer(value));
    }
}

/**
 * A variable reference expression.
 */
class Var extends Exp {

    int index;

    Var(final int index) {
        this.index = index + 1;
    }

    @Override
    void compile(final MethodVisitor mv) {
        // pushes the 'index' local variable onto the stack
        mv.visitVarInsn(ILOAD, index);
    }
}

/**
 * An abstract binary expression.
 */
abstract class BinaryExp extends Exp {

    Exp e1;

    Exp e2;

    BinaryExp(final Exp e1, final Exp e2) {
        this.e1 = e1;
        this.e2 = e2;
    }
}

/**
 * An addition expression.
 */
class Add extends BinaryExp {

    Add(final Exp e1, final Exp e2) {
        super(e1, e2);
    }

    @Override
    void compile(final MethodVisitor mv) {
        // compiles e1, e2, and adds an instruction to add the two values
        e1.compile(mv);
        e2.compile(mv);
        mv.visitInsn(IADD);
    }
}

/**
 * A multiplication expression.
 */
class Mul extends BinaryExp {

    Mul(final Exp e1, final Exp e2) {
        super(e1, e2);
    }

    @Override
    void compile(final MethodVisitor mv) {
        // compiles e1, e2, and adds an instruction to multiply the two values
        e1.compile(mv);
        e2.compile(mv);
        mv.visitInsn(IMUL);
    }
}

/**
 * A "greater than" expression.
 */
class GT extends BinaryExp {

    GT(final Exp e1, final Exp e2) {
        super(e1, e2);
    }

    @Override
    void compile(final MethodVisitor mv) {
        // compiles e1, e2, and adds the instructions to compare the two values
        e1.compile(mv);
        e2.compile(mv);
        Label iftrue = new Label();
        Label end = new Label();
        mv.visitJumpInsn(IF_ICMPGT, iftrue);
        // case where e1 <= e2 : pushes false and jump to "end"
        mv.visitLdcInsn(new Integer(0));
        mv.visitJumpInsn(GOTO, end);
        // case where e1 > e2 : pushes true
        mv.visitLabel(iftrue);
        mv.visitLdcInsn(new Integer(1));
        mv.visitLabel(end);
    }
}

/**
 * A logical "and" expression.
 */
class And extends BinaryExp {

    And(final Exp e1, final Exp e2) {
        super(e1, e2);
    }

    @Override
    void compile(final MethodVisitor mv) {
        // compiles e1
        e1.compile(mv);
        // tests if e1 is false
        mv.visitInsn(DUP);
        Label end = new Label();
        mv.visitJumpInsn(IFEQ, end);
        // case where e1 is true : e1 && e2 is equal to e2
        mv.visitInsn(POP);
        e2.compile(mv);
        // if e1 is false, e1 && e2 is equal to e1:
        // we jump directly to this label, without evaluating e2
        mv.visitLabel(end);
    }
}

/**
 * A logical "or" expression.
 */
class Or extends BinaryExp {

    Or(final Exp e1, final Exp e2) {
        super(e1, e2);
    }

    @Override
    void compile(final MethodVisitor mv) {
        // compiles e1
        e1.compile(mv);
        // tests if e1 is true
        mv.visitInsn(DUP);
        Label end = new Label();
        mv.visitJumpInsn(IFNE, end);
        // case where e1 is false : e1 || e2 is equal to e2
        mv.visitInsn(POP);
        e2.compile(mv);
        // if e1 is true, e1 || e2 is equal to e1:
        // we jump directly to this label, without evaluating e2
        mv.visitLabel(end);
    }
}

/**
 * A logical "not" expression.
 */
class Not extends Exp {

    Exp e;

    Not(final Exp e) {
        this.e = e;
    }

    @Override
    void compile(final MethodVisitor mv) {
        // computes !e1 by evaluating 1 - e1
        mv.visitLdcInsn(new Integer(1));
        e.compile(mv);
        mv.visitInsn(ISUB);
    }
}
