Example usage for org.objectweb.asm Label Label

List of usage examples for org.objectweb.asm Label Label

Introduction

In this page you can find the example usage for org.objectweb.asm Label Label.

Prototype

public Label() 

Source Link

Document

Constructs a new label.

Usage

From source file:com.mulberry.athena.asm.ASMTest.java

License:Open Source License

@Test
public void generateClass() throws Exception {
    ClassWriter classWriter = new ClassWriter(0);
    ClassVisitor cv = new TraceClassVisitor(classWriter, new PrintWriter(System.out));
    //FieldVisitor fv;
    MethodVisitor mv;//from w  ww .  ja  va  2  s  .co m
    //AnnotationVisitor av0;

    cv.visit(V1_6, ACC_PUBLIC + ACC_SUPER, "Testing", null, "java/lang/Object", null);
    cv.visitSource("Testing.java", null);
    {
        mv = cv.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitLineNumber(1, l0);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
        mv.visitInsn(RETURN);
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLocalVariable("this", "LTesting;", null, l0, l1, 0);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }
    {
        mv = cv.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
        mv.visitCode();
        Label l0 = new Label();
        mv.visitLabel(l0);
        mv.visitLineNumber(3, l0);
        mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
        mv.visitLdcInsn("Works!");
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
        Label l1 = new Label();
        mv.visitLabel(l1);
        mv.visitLineNumber(4, l1);
        mv.visitInsn(RETURN);
        Label l2 = new Label();
        mv.visitLabel(l2);
        mv.visitLocalVariable("args", "[Ljava/lang/String;", null, l0, l2, 0);
        mv.visitMaxs(2, 1);
        mv.visitEnd();
    }
    cv.visitEnd();

    Class<?> clazz = new DynamicClassLoader().defineClass("Testing", classWriter.toByteArray());
    java.lang.reflect.Method method = clazz.getMethod("main", String[].class);
    final String[] arguments = new String[] { "hello", "world" };
    method.invoke(clazz, (Object) arguments);
}

From source file:com.nginious.http.serialize.JsonSerializerCreator.java

License:Apache License

/**
 * Creates bytecode which implements the {@link JsonSerializer#serializeProperties(org.json.JSONObject, Object)}
 * method for the serializer class being created.
 * /*w  ww  .j a va2  s .co  m*/
 * @param writer class byte code writer
 * @param intBeanClazzName binary name of serializer class being generated
 * @return a method visitor for writing bytecode inside the generated method
 */
private MethodVisitor createSerializeMethod(ClassWriter writer, String intBeanClazzName) {
    String[] exceptions = { "com/nginious/serialize/SerializerException" };
    MethodVisitor visitor = writer.visitMethod(Opcodes.ACC_PUBLIC, "serializeProperties",
            "(Lorg/json/JSONObject;Ljava/lang/Object;)V", null, exceptions);
    visitor.visitCode();

    Label label = new Label();
    visitor.visitVarInsn(Opcodes.ALOAD, 2);
    visitor.visitJumpInsn(Opcodes.IFNONNULL, label);
    visitor.visitInsn(Opcodes.RETURN);
    visitor.visitLabel(label);
    visitor.visitVarInsn(Opcodes.ALOAD, 2);
    visitor.visitTypeInsn(Opcodes.CHECKCAST, intBeanClazzName);
    visitor.visitIntInsn(Opcodes.ASTORE, 3);

    return visitor;
}

From source file:com.nginious.http.serialize.XmlSerializerCreator.java

License:Apache License

/**
 * Creates bytecode which implements the {@link XmlSerializer#serializeProperties(javax.xml.transform.sax.TransformerHandler, Object)}
 * method for the serializer class being created.
 * // w  w w  .  ja v  a2  s  .c o m
 * @param writer class byte code writer
 * @param intBeanClazzName binary name of serializer class being generated
 * @return a method visitor for writing bytecode inside the generated method
 */
private MethodVisitor createSerializeMethod(ClassWriter writer, String intBeanClazzName) {
    String[] exceptions = { "com/nginious/serialize/SerializerException" };
    MethodVisitor visitor = writer.visitMethod(Opcodes.ACC_PUBLIC, "serializeProperties",
            "(Ljavax/xml/transform/sax/TransformerHandler;Ljava/lang/Object;)V", null, exceptions);
    visitor.visitCode();

    Label label = new Label();
    visitor.visitVarInsn(Opcodes.ALOAD, 2);
    visitor.visitJumpInsn(Opcodes.IFNONNULL, label);
    visitor.visitInsn(Opcodes.RETURN);
    visitor.visitLabel(label);
    visitor.visitVarInsn(Opcodes.ALOAD, 0);
    visitor.visitVarInsn(Opcodes.ALOAD, 2);
    visitor.visitTypeInsn(Opcodes.CHECKCAST, intBeanClazzName);
    visitor.visitIntInsn(Opcodes.ASTORE, 3);
    return visitor;
}

From source file:com.nginious.http.xsp.expr.AndOperator.java

License:Apache License

/**
 * Creates bytecode for evaluating this and operator. The bytecode is generated using
 * the specified method visitor. The result of the evaluation produces the specified
 * type./*from ww  w.  jav a2  s  .  c o  m*/
 * 
 * @param visitor the method visitor
 * @param type the type
 */
void compile(MethodVisitor visitor, Type type) {
    Label labelFalse = new Label();
    Label labelEnd = new Label();

    // Test first value
    value1.compile(visitor, type);
    visitor.visitInsn(Opcodes.ICONST_1);
    visitor.visitJumpInsn(Opcodes.IF_ICMPNE, labelFalse);

    // Test second value
    value2.compile(visitor, type);
    visitor.visitInsn(Opcodes.ICONST_1);
    visitor.visitJumpInsn(Opcodes.IF_ICMPNE, labelFalse);

    // True
    visitor.visitLdcInsn(true);
    visitor.visitJumpInsn(Opcodes.GOTO, labelEnd);

    // False
    visitor.visitLabel(labelFalse);
    visitor.visitLdcInsn(false);

    visitor.visitLabel(labelEnd);
}

From source file:com.nginious.http.xsp.expr.AttributeValue.java

License:Apache License

/**
 * Creates bytecode for evaluating this attribute value. The bytecode is created using the
 * specified method visitor and creates a result of specified type.
 * /* w ww. j  av  a 2s  . c  om*/
 * @param visitor the method visitor
 * @param type the type
 */
void compile(MethodVisitor visitor, Type type) {
    visitor.visitLdcInsn(this.name);
    visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "com/nginious/http/xsp/expr/Expression", "getVariable",
            "(Ljava/lang/String;)Ljava/lang/Object;");

    if (type != Type.ANY) {
        visitor.visitInsn(Opcodes.DUP);
    }

    if (type == Type.STRING) {
        Label nullLabel = new Label();
        Label notNullLabel = new Label();

        visitor.visitJumpInsn(Opcodes.IFNULL, nullLabel);

        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;");
        visitor.visitJumpInsn(Opcodes.GOTO, notNullLabel);

        visitor.visitLabel(nullLabel);
        visitor.visitInsn(Opcodes.POP);
        visitor.visitInsn(Opcodes.ACONST_NULL);

        visitor.visitLabel(notNullLabel);
    } else if (type == Type.INT) {
        Label nullLabel = new Label();
        Label notNullLabel = new Label();

        visitor.visitJumpInsn(Opcodes.IFNULL, nullLabel);

        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;");
        visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "parseInt", "(Ljava/lang/String;)I");
        visitor.visitJumpInsn(Opcodes.GOTO, notNullLabel);

        visitor.visitLabel(nullLabel);
        visitor.visitInsn(Opcodes.POP);
        visitor.visitLdcInsn(0);

        visitor.visitLabel(notNullLabel);
    } else if (type == Type.DOUBLE) {
        Label nullLabel = new Label();
        Label notNullLabel = new Label();

        visitor.visitJumpInsn(Opcodes.IFNULL, nullLabel);

        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;");
        visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "parseDouble",
                "(Ljava/lang/String;)D");
        visitor.visitJumpInsn(Opcodes.GOTO, notNullLabel);

        visitor.visitLabel(nullLabel);
        visitor.visitInsn(Opcodes.POP);
        visitor.visitLdcInsn(0.0d);

        visitor.visitLabel(notNullLabel);
    }
}

From source file:com.nginious.http.xsp.expr.BeanValue.java

License:Apache License

/**
 * Creates bytecode for evaluating this bean value. The bytecode is generated using the
 * specified method visitor and produces a value of the specified type.
 * //  w  w w.  jav  a2  s  .  c o  m
 * @param visitor the method visitor
 * @param type the type
 */
void compile(MethodVisitor visitor, Type type) {
    visitor.visitLdcInsn(this.beanName);
    visitor.visitLdcInsn(this.propertyName);
    visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "com/nginious/http/xsp/expr/BeanValue", "getValue",
            "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");

    if (type != Type.ANY) {
        visitor.visitInsn(Opcodes.DUP);
    }

    // visitor.visitJumpInsn(Opcodes.IFNONNULL, null);

    if (type == Type.DOUBLE) {
        Label nullLabel = new Label();
        Label notNullLabel = new Label();

        visitor.visitJumpInsn(Opcodes.IFNULL, nullLabel);

        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;");
        visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "parseDouble",
                "(Ljava/lang/String;)D");
        visitor.visitJumpInsn(Opcodes.GOTO, notNullLabel);

        visitor.visitLabel(nullLabel);
        visitor.visitInsn(Opcodes.POP);
        visitor.visitLdcInsn(0.0d);

        visitor.visitLabel(notNullLabel);
    } else if (type == Type.INT) {
        Label nullLabel = new Label();
        Label notNullLabel = new Label();

        visitor.visitJumpInsn(Opcodes.IFNULL, nullLabel);

        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;");
        visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "parseInt", "(Ljava/lang/String;)I");
        visitor.visitJumpInsn(Opcodes.GOTO, notNullLabel);

        visitor.visitLabel(nullLabel);
        visitor.visitInsn(Opcodes.POP);
        visitor.visitLdcInsn(0);

        visitor.visitLabel(notNullLabel);
    } else if (type == Type.STRING) {
        Label nullLabel = new Label();
        Label notNullLabel = new Label();

        visitor.visitJumpInsn(Opcodes.IFNULL, nullLabel);

        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;");
        visitor.visitJumpInsn(Opcodes.GOTO, notNullLabel);

        visitor.visitLabel(nullLabel);
        visitor.visitInsn(Opcodes.POP);
        visitor.visitInsn(Opcodes.ACONST_NULL);

        visitor.visitLabel(notNullLabel);
    }
}

From source file:com.nginious.http.xsp.expr.EqualsOperator.java

License:Apache License

/**
 * Compiles bytecode for evaluating this equals operator producing
 * a string as result. The specified method visitor is used for generating
 * bytecode./*  w  w w  . j  av a2  s . c  o  m*/
 * 
 * @param visitor the method visitor
 */
private void compileString(MethodVisitor visitor) {
    value1.compile(visitor, Type.STRING);
    visitor.visitVarInsn(Opcodes.ASTORE, 1);
    value2.compile(visitor, Type.STRING);
    visitor.visitVarInsn(Opcodes.ASTORE, 2);
    Label nullLabel = new Label();
    Label notNullLabel = new Label();

    visitor.visitVarInsn(Opcodes.ALOAD, 1);
    visitor.visitJumpInsn(Opcodes.IFNULL, nullLabel);
    visitor.visitVarInsn(Opcodes.ALOAD, 2);
    visitor.visitJumpInsn(Opcodes.IFNULL, nullLabel);

    visitor.visitVarInsn(Opcodes.ALOAD, 1);
    visitor.visitVarInsn(Opcodes.ALOAD, 2);
    visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z");
    visitor.visitJumpInsn(Opcodes.GOTO, notNullLabel);

    visitor.visitLabel(nullLabel);
    visitor.visitLdcInsn(false);

    visitor.visitLabel(notNullLabel);
}

From source file:com.nginious.http.xsp.expr.EqualsOperator.java

License:Apache License

/**
 * Compiles bytecode for evaluating this equals operator producing
 * an integer as result. The specified method visitor is used for generating
 * bytecode./*from ww w.ja  v  a 2 s  .c  o  m*/
 * 
 * @param visitor the method visitor
 */
private void compileInt(MethodVisitor visitor) {
    Label trueLabel = new Label();
    Label falseLabel = new Label();

    value1.compile(visitor, Type.INT);
    value2.compile(visitor, Type.INT);
    visitor.visitJumpInsn(Opcodes.IF_ICMPEQ, trueLabel);

    visitor.visitLdcInsn(false);
    visitor.visitJumpInsn(Opcodes.GOTO, falseLabel);

    visitor.visitLabel(trueLabel);
    visitor.visitLdcInsn(true);

    visitor.visitLabel(falseLabel);
}

From source file:com.nginious.http.xsp.expr.EqualsOperator.java

License:Apache License

/**
 * Compiles bytecode for evaluating this equals operator producing
 * a double as result. The specified method visitor is used for generating
 * bytecode.//ww w . j a v a  2  s.  c  om
 * 
 * @param visitor the method visitor
 */
private void compileDouble(MethodVisitor visitor) {
    Label trueLabel = new Label();
    Label falseLabel = new Label();

    value1.compile(visitor, Type.DOUBLE);
    value2.compile(visitor, Type.DOUBLE);
    visitor.visitInsn(Opcodes.DCMPL);
    visitor.visitJumpInsn(Opcodes.IFEQ, trueLabel);

    visitor.visitLdcInsn(false);
    visitor.visitJumpInsn(Opcodes.GOTO, falseLabel);

    visitor.visitLabel(trueLabel);
    visitor.visitLdcInsn(true);

    visitor.visitLabel(falseLabel);
}

From source file:com.nginious.http.xsp.expr.ExpressionCompiler.java

License:Apache License

/**
 * Creates a compiled expression from the specified tree value node expression. The class bytecode for the 
 * compiled expression is generated at runtime.
 * //  w  ww  .  ja  v  a2 s  .com
 * @param uncompiled the uncompiled tree value node expression
 * @return the compiled expression
 * @throws ExpressionException if unable to compile expression
 */
public Expression compile(TreeExpression uncompiled) throws ExpressionException {
    ClassWriter writer = new ClassWriter(0);

    // Create class
    String className = classBaseName + classNameCounter.getAndIncrement();
    String classIdentifier = className.replace('.', '/');
    writer.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, classIdentifier, "L" + classIdentifier + ";",
            "com/nginious/http/xsp/expr/Expression", null);

    // Create constructor
    MethodVisitor visitor = writer.visitMethod(Opcodes.ACC_PROTECTED, "<init>", "()V", null, null);
    visitor.visitCode();
    visitor.visitVarInsn(Opcodes.ALOAD, 0);
    visitor.visitMethodInsn(Opcodes.INVOKESPECIAL, "com/nginious/http/xsp/expr/Expression", "<init>", "()V");
    visitor.visitInsn(Opcodes.RETURN);
    visitor.visitMaxs(1, 1);
    visitor.visitEnd();

    // protected abstract boolean evaluateBoolean();
    visitor = writer.visitMethod(Opcodes.ACC_PROTECTED, "evaluateBoolean", "()Z", null, null);

    if (uncompiled.getType() == Type.BOOLEAN) {
        uncompiled.compile(visitor);
    } else if (uncompiled.getType() == Type.DOUBLE) {
        visitor.visitVarInsn(Opcodes.ALOAD, 0); // this
        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classIdentifier, "evaluateDouble", "()D");

        Label endLabel = new Label();
        Label falseLabel = new Label();
        visitor.visitLdcInsn(0.0d);
        visitor.visitInsn(Opcodes.DCMPL);
        visitor.visitJumpInsn(Opcodes.IFEQ, falseLabel);
        visitor.visitLdcInsn(true);
        visitor.visitJumpInsn(Opcodes.GOTO, endLabel);
        visitor.visitLabel(falseLabel);
        visitor.visitLdcInsn(false);
        visitor.visitLabel(endLabel);
    } else if (uncompiled.getType() == Type.INT) {
        visitor.visitVarInsn(Opcodes.ALOAD, 0); // this
        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classIdentifier, "evaluateInt", "()I");

        Label endLabel = new Label();
        Label falseLabel = new Label();
        visitor.visitLdcInsn(0);
        visitor.visitJumpInsn(Opcodes.IFNE, falseLabel);
        visitor.visitLdcInsn(true);
        visitor.visitJumpInsn(Opcodes.GOTO, endLabel);
        visitor.visitLabel(falseLabel);
        visitor.visitLdcInsn(false);
        visitor.visitLabel(endLabel);
    } else if (uncompiled.getType() == Type.STRING) {
        visitor.visitVarInsn(Opcodes.ALOAD, 0); // this
        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classIdentifier, "evaluateString",
                "()Ljava/lang/String;");
        visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "parseBoolean",
                "(Ljava/lang/String;)Z");
    }

    visitor.visitInsn(Opcodes.IRETURN);
    visitor.visitMaxs(5, 5);
    visitor.visitEnd();

    // protected abstract int evaluateInt();
    visitor = writer.visitMethod(Opcodes.ACC_PROTECTED, "evaluateInt", "()I", null, null);

    if (uncompiled.getType() == Type.BOOLEAN) {
        visitor.visitVarInsn(Opcodes.ALOAD, 0); // this
        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classIdentifier, "evaluateBoolean", "()Z");

        Label endLabel = new Label();
        Label falseLabel = new Label();
        visitor.visitJumpInsn(Opcodes.IFEQ, falseLabel);
        visitor.visitLdcInsn(1);
        visitor.visitJumpInsn(Opcodes.GOTO, endLabel);
        visitor.visitLabel(falseLabel);
        visitor.visitLdcInsn(0);
        visitor.visitLabel(endLabel);
    } else if (uncompiled.getType() == Type.DOUBLE) {
        visitor.visitVarInsn(Opcodes.ALOAD, 0); // this
        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classIdentifier, "evaluateDouble", "()D");
        visitor.visitInsn(Opcodes.D2I);
    } else if (uncompiled.getType() == Type.INT) {
        uncompiled.compile(visitor);
    } else if (uncompiled.getType() == Type.STRING) {
        visitor.visitVarInsn(Opcodes.ALOAD, 0); // this
        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classIdentifier, "evaluateString",
                "()Ljava/lang/String;");
        visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "parseInt", "(Ljava/lang/String;)I");
    }

    visitor.visitInsn(Opcodes.IRETURN);
    visitor.visitMaxs(5, 5);
    visitor.visitEnd();

    // protected abstract double evaluateDouble();
    visitor = writer.visitMethod(Opcodes.ACC_PROTECTED, "evaluateDouble", "()D", null, null);

    if (uncompiled.getType() == Type.BOOLEAN) {
        visitor.visitVarInsn(Opcodes.ALOAD, 0); // this
        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classIdentifier, "evaluateBoolean", "()Z");

        Label endLabel = new Label();
        Label falseLabel = new Label();
        visitor.visitJumpInsn(Opcodes.IFEQ, falseLabel);
        visitor.visitLdcInsn(1.0d);
        visitor.visitJumpInsn(Opcodes.GOTO, endLabel);
        visitor.visitLabel(falseLabel);
        visitor.visitLdcInsn(0.0d);
        visitor.visitLabel(endLabel);
    } else if (uncompiled.getType() == Type.DOUBLE) {
        uncompiled.compile(visitor);
    } else if (uncompiled.getType() == Type.INT) {
        visitor.visitVarInsn(Opcodes.ALOAD, 0); // this
        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classIdentifier, "evaluateInt", "()I");
        visitor.visitInsn(Opcodes.I2D);
    } else if (uncompiled.getType() == Type.STRING) {
        visitor.visitVarInsn(Opcodes.ALOAD, 0); // this
        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classIdentifier, "evaluateString",
                "()Ljava/lang/String;");
        visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "parseDouble",
                "(Ljava/lang/String;)D");
    }

    visitor.visitInsn(Opcodes.DRETURN);
    visitor.visitMaxs(5, 5);
    visitor.visitEnd();

    // protected abstract String evaluateString();
    visitor = writer.visitMethod(Opcodes.ACC_PROTECTED, "evaluateString", "()Ljava/lang/String;", null, null);

    if (uncompiled.getType() == Type.BOOLEAN) {
        visitor.visitVarInsn(Opcodes.ALOAD, 0); // this
        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classIdentifier, "evaluateBoolean", "()Z");
        visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "toString", "(Z)Ljava/lang/String;");
    } else if (uncompiled.getType() == Type.DOUBLE) {
        visitor.visitVarInsn(Opcodes.ALOAD, 0); // this
        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classIdentifier, "evaluateDouble", "()D");
        visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "toString", "(D)Ljava/lang/String;");
    } else if (uncompiled.getType() == Type.INT) {
        visitor.visitVarInsn(Opcodes.ALOAD, 0); // this
        visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, classIdentifier, "evaluateInt", "()I");
        visitor.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "toString", "(I)Ljava/lang/String;");
    } else if (uncompiled.getType() == Type.STRING) {
        uncompiled.compile(visitor);
    }

    visitor.visitInsn(Opcodes.ARETURN);
    visitor.visitMaxs(6, 6);
    visitor.visitEnd();

    // public abstract Type getType();        
    visitor = writer.visitMethod(Opcodes.ACC_PUBLIC, "getType", "()Lcom/nginious/http/xsp/expr/Type;", null,
            null);

    if (uncompiled.getType() == Type.BOOLEAN) {
        visitor.visitFieldInsn(Opcodes.GETSTATIC, "com/nginious/http/xsp/expr/Type", "BOOLEAN",
                "Lcom/nginious/http/xsp/expr/Type;");
        visitor.visitInsn(Opcodes.ARETURN);
    } else if (uncompiled.getType() == Type.DOUBLE) {
        visitor.visitFieldInsn(Opcodes.GETSTATIC, "com/nginious/http/xsp/expr/Type", "DOUBLE",
                "Lcom/nginious/http/xsp/expr/Type;");
        visitor.visitInsn(Opcodes.ARETURN);
    } else if (uncompiled.getType() == Type.INT) {
        visitor.visitFieldInsn(Opcodes.GETSTATIC, "com/nginious/http/xsp/expr/Type", "INT",
                "Lcom/nginious/http/xsp/expr/Type;");
        visitor.visitInsn(Opcodes.ARETURN);
    } else if (uncompiled.getType() == Type.STRING) {
        visitor.visitFieldInsn(Opcodes.GETSTATIC, "com/nginious/http/xsp/expr/Type", "STRING",
                "Lcom/nginious/http/xsp/expr/Type;");
        visitor.visitInsn(Opcodes.ARETURN);
    }

    visitor.visitMaxs(1, 1);
    visitor.visitEnd();

    try {
        writer.visitEnd();
        byte[] clazzBytes = writer.toByteArray();
        Class<?> clazz = loadClass(className, clazzBytes);
        return (Expression) clazz.newInstance();
    } catch (Exception e) {
        throw new ExpressionException("Can't instantiate compiled expression", e);
    }
}