Example usage for org.objectweb.asm MethodVisitor visitJumpInsn

List of usage examples for org.objectweb.asm MethodVisitor visitJumpInsn

Introduction

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

Prototype

public void visitJumpInsn(final int opcode, final Label label) 

Source Link

Document

Visits a jump instruction.

Usage

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 w  w .j  a  va  2 s. c  om
 * @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.
 * /*from  w ww. j a  v a  2 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./* w  ww . java 2 s  .com*/
 * 
 * @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.
 * /*from  w  w w.  j av  a 2 s .  c  o m*/
 * @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.
 * //from w  w  w .  j  a  v  a 2  s .  c om
 * @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  a2s .  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   w w  w . ja  v  a 2  s .  co  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./*from   www .j av a2s .  c  o m*/
 * 
 * @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.
 * /*from   w  ww  .jav  a2 s .c om*/
 * @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);
    }
}

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

License:Apache License

/**
 * Creates bytecode for evaluating this left function. The specified method visitor
 * and type are used for generating bytecode.
 * /*  ww w  .j  a  va  2s  .  c  o m*/
 * @param visitor the method visitor
 * @param type the type
 */
void compile(MethodVisitor visitor, Type type) {
    value.compile(visitor, Type.STRING);
    visitor.visitVarInsn(Opcodes.ASTORE, 1);

    Label nullLabel = new Label();
    Label notNullLabel = new Label();

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

    visitor.visitVarInsn(Opcodes.ALOAD, 1);
    visitor.visitLdcInsn(0);
    value2.compile(visitor, Type.INT);
    visitor.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/String", "substring", "(II)Ljava/lang/String;");
    visitor.visitJumpInsn(Opcodes.GOTO, notNullLabel);

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

    visitor.visitLabel(notNullLabel);
}