Example usage for org.objectweb.asm MethodVisitor visitEnd

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

Introduction

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

Prototype

public void visitEnd() 

Source Link

Document

Visits the end of the method.

Usage

From source file:io.syncframework.optimizer.OControllerClassVisitor.java

License:Apache License

/**
 * Generates the _asUrl() method with using a constant string
 * public String _asUrl() { return "/*"; }
 *//* w w w.j  av  a  2s . c o  m*/
public void createUrlMethod() {
    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "_asUrl", "()Ljava/lang/String;", null, null);
    mv.visitCode();
    Label l0 = new Label();
    mv.visitLabel(l0);
    mv.visitLdcInsn(reflector.getUrl());
    mv.visitInsn(Opcodes.ARETURN);
    Label l1 = new Label();
    mv.visitLocalVariable("this", Type.getDescriptor(reflector.getClazz()), null, l0, l1, 0);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}

From source file:io.syncframework.optimizer.OInitializerClassVisitor.java

License:Apache License

/**
 * Generates the code://from   w w w . jav a 2 s . c  o m
 * 
 * public void _asDestroy() {
 *    return destroy();
 * }
 */
public void createDestroyMethod() {
    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "_asDestroy", "()V", null, null);
    Label l0 = new Label();
    if (reflector.getInit() != null) {
        mv.visitLabel(l0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, reflector.getClazzInternalName(), "destroy", "()V", false);
        mv.visitInsn(Opcodes.RETURN);
    } else {
        mv.visitLabel(l0);
        mv.visitInsn(Opcodes.RETURN);
    }

    Label l1 = new Label();
    mv.visitLocalVariable("this", reflector.getClazzDescriptor(), null, l0, l1, 0);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}

From source file:io.syncframework.optimizer.OInitializerClassVisitor.java

License:Apache License

/**
 * Generates the code:/*from   ww w.j  ava 2  s  .c  o m*/
 * 
 * public void _asInit() {
 *    return init();
 * }
 */
public void createInitMethod() {
    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "_asInit", "()V", null, null);
    Label l0 = new Label();
    if (reflector.getInit() != null) {
        mv.visitLabel(l0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, reflector.getClazzInternalName(), "init", "()V", false);
        mv.visitInsn(Opcodes.RETURN);
    } else {
        mv.visitLabel(l0);
        mv.visitInsn(Opcodes.RETURN);
    }
    Label l1 = new Label();
    mv.visitLocalVariable("this", reflector.getClazzDescriptor(), null, l0, l1, 0);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}

From source file:io.syncframework.optimizer.OInterceptorClassVisitor.java

License:Apache License

/**
 * Add code to the end of the class. We are adding the IController methods
 * @see org.objectweb.asm.ClassVisitor#visitEnd()
 *//*from   www .  j a  va 2 s  . c om*/
@Override
public void visitEnd() {
    //
    // private static Map<String,Class<?>> _asConverters;
    //
    {
        FieldVisitor fv = cv.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC, "_asConverters",
                "Ljava/util/Map;", "Ljava/util/Map<Ljava/lang/String;Ljava/lang/Class<*>;>;", null);
        fv.visitEnd();
    }
    //
    // private static Map<String,Class<?>> _asParameters;
    //
    {
        FieldVisitor fv = cv.visitField(Opcodes.ACC_PRIVATE + Opcodes.ACC_STATIC, "_asParameters",
                "Ljava/util/Map;", "Ljava/util/Map<Ljava/lang/String;Ljava/lang/Class<*>;>;", null);
        fv.visitEnd();
    }

    createStaticMethod();

    if (!createdStaticMethod) {
        MethodVisitor mv = cv.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
        mv.visitCode();
        mv = new OInterceptorStaticMethodVisitor(mv, reflector);
        mv.visitInsn(Opcodes.RETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    createContextMethod("_asApplicationContext", Type.getDescriptor(ApplicationContext.class),
            reflector.getApplicationContext());
    createContextMethod("_asErrorContext", Type.getDescriptor(ErrorContext.class), reflector.getErrorContext());
    createContextMethod("_asCookieContext", Type.getDescriptor(CookieContext.class),
            reflector.getCookieContext());
    createContextMethod("_asMessageContext", Type.getDescriptor(MessageContext.class),
            reflector.getMessageContext());
    createContextMethod("_asRequestContext", Type.getDescriptor(RequestContext.class),
            reflector.getRequestContext());
    createContextMethod("_asSessionContext", Type.getDescriptor(SessionContext.class),
            reflector.getSessionContext());

    createParametersMethod();
    createParametersSetterMethod();
    createParametersGetterMethod();
    createParameterConverterMethod();

    createBeforeMethod();
    createAfterMethod();
}

From source file:io.syncframework.optimizer.OInterceptorClassVisitor.java

License:Apache License

/**
 * Generates the code:// w  w w .j av  a2s.c  om
 * 
 * public Result _asAfter() {
 *    return after();
 * }
 */
public void createAfterMethod() {
    String signature = "()" + Type.getDescriptor(Result.class);
    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "_asAfter", signature, null, null);
    Label l0 = new Label();

    if (reflector.getAfter() != null) {
        mv.visitLabel(l0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, reflector.getClazzInternalName(), "after", signature, false);
        mv.visitInsn(Opcodes.ARETURN);
    } else {
        mv.visitLabel(l0);
        mv.visitInsn(Opcodes.ACONST_NULL);
        mv.visitInsn(Opcodes.ARETURN);
    }

    Label l1 = new Label();
    mv.visitLocalVariable("this", reflector.getClazzDescriptor(), null, l0, l1, 0);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}

From source file:io.syncframework.optimizer.OInterceptorClassVisitor.java

License:Apache License

/**
 * Generates the code://from ww w.ja  v  a 2s  . c  o  m
 * 
 * public Result _asBefore() {
 *    return before();
 * }
 */
public void createBeforeMethod() {
    String signature = "()" + Type.getDescriptor(Result.class);
    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "_asBefore", signature, null, null);
    Label l0 = new Label();

    if (reflector.getAfter() != null) {
        mv.visitLabel(l0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, reflector.getClazzInternalName(), "before", signature, false);
        mv.visitInsn(Opcodes.ARETURN);
    } else {
        mv.visitLabel(l0);
        mv.visitInsn(Opcodes.ACONST_NULL);
        mv.visitInsn(Opcodes.ARETURN);
    }

    Label l1 = new Label();
    mv.visitLocalVariable("this", reflector.getClazzDescriptor(), null, l0, l1, 0);
    mv.visitMaxs(1, 1);
    mv.visitEnd();
}

From source file:jaspex.speculation.InjectDetectLocalClassVisitor.java

License:Open Source License

@Override
public void visitEnd() {
    if (_active) {
        cv.visitField(ACC_PUBLIC, "$owner", Type.OBJECT.bytecodeName(), null, null);

        {/*from   w  w  w.j  a v a2 s. c om*/
            MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "$setOwner", "(Ljava/lang/Object;)V", null, null);
            mv.visitCode();
            mv.visitVarInsn(ALOAD, 0);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitFieldInsn(PUTFIELD, _name, "$owner", Type.OBJECT.bytecodeName());
            mv.visitInsn(RETURN);
            mv.visitMaxs(0, 0);
            mv.visitEnd();
        }
        {
            MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "$getOwner", "()Ljava/lang/Object;", null, null);
            mv.visitCode();
            mv.visitVarInsn(ALOAD, 0);
            mv.visitFieldInsn(GETFIELD, _name, "$owner", Type.OBJECT.bytecodeName());
            mv.visitInsn(ARETURN);
            mv.visitMaxs(1, 1);
            mv.visitEnd();
        }
    }

    cv.visitEnd();
}

From source file:jaspex.speculation.InjectOverloadsClassVisitor.java

License:Open Source License

private void injectOverload(InfoMethod method) {
    MethodVisitor mv = cv.visitMethod(method.access() & ~ACC_SYNCHRONIZED & ~ACC_NATIVE,
            method.name() + "$transactional", method.desc(), method.signature(), method.exceptions());
    mv.visitCode();//from   w  w w  .java  2 s.co m
    // Contador de posies de argumentos
    int pos = 0;
    if (!method.isStatic())
        mv.visitVarInsn(ALOAD, pos++);
    for (Type argType : method.argumentTypes()) {
        mv.visitVarInsn(argType.getLoadInsn(), pos);
        pos += argType.getNumberSlots();
    }
    mv.visitMethodInsn(method.isStatic() ? INVOKESTATIC : INVOKESPECIAL, method.infoClass().type().asmName(),
            method.name(), method.desc());
    mv.visitInsn(method.returnType().getReturnInsn());
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:jaspex.speculation.runtime.CodegenHelper.java

License:Open Source License

public static byte[] generateClass(Type codegenType) {
    // Obter id a partir do tipo
    String name = codegenType.commonName();
    name = name.replaceFirst(Matcher.quoteReplacement(CODEGEN_CLASS_PREFIX), "");
    int id = Integer.parseInt(name.substring(0, name.indexOf("$")));

    // Obter InvokedMethod
    InvokedMethod method = _idToMethodMap.get(id);

    Log.trace(color("[ CodeGen ]", "31") + " Generating wrapper for {}.{}{}", method.owner(), method.name(),
            method.desc());//from  w  w  w  .  j a va 2  s.  c om

    UtilList<Type> arguments = method.argumentTypes();
    if (!method.isStatic())
        arguments.addFirst(method.owner());
    String argumentsDesc = "";
    for (Type type : arguments)
        argumentsDesc += type.bytecodeName();

    // Optimizao: Se mtodo for ()V e static, criamos um singleton apenas com o call,
    //      e tornamos o constructor private para que a classe no seja instanciada
    //      noutros locais
    boolean singletonMode = arguments.isEmpty();

    // Criar classe
    ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    cw.visit(V1_6, ACC_PUBLIC | ACC_FINAL, codegenType.asmName(), null, CommonTypes.CALLABLE.asmName(),
            (Options.RVP ? new String[] { CommonTypes.PREDICTABLECALLABLE.asmName() } : null));
    cw.visitSource(color("JaSPEx Generated Wrapper Class", "31"), null);

    // Criar fields para conter argumentos
    {
        int fieldPos = 0;
        for (Type t : arguments) {
            cw.visitField(ACC_PRIVATE + ACC_FINAL, "arg" + (fieldPos++), t.bytecodeName(), null, null);
        }
    }

    // Criar constructor
    {
        MethodVisitor mv = cw.visitMethod((singletonMode ? ACC_PRIVATE : ACC_PUBLIC), "<init>",
                "(" + argumentsDesc + ")V", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, Type.OBJECT.asmName(), "<init>", "()V");
        int localsPos = 0;
        int fieldPos = 0;
        for (Type t : arguments) {
            mv.visitVarInsn(ALOAD, 0);
            mv.visitVarInsn(t.getLoadInsn(), localsPos + 1);
            mv.visitFieldInsn(PUTFIELD, codegenType.asmName(), "arg" + fieldPos++, t.bytecodeName());
            localsPos += t.getNumberSlots();
        }
        mv.visitInsn(RETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    // Criar mtodo esttico como "bridge" para o constructor
    // A ideia deste mtodo  resolver o problema de j termos os argumentos para a invocao na stack
    // quando descobrimos que queremos criar uma instncia desta classe. Assim, em vez de andar a
    // fazer swaps at colocarmos a instncia desta classe por baixo dos argumentos para o seu
    // construtor, chamamos este mtodo esttico para fazer esse trabalho por ns.
    // O que este mtodo  basicamente:
    // public static codegenType newInstance(args) { return new codegenType(args); }
    if (!singletonMode) {
        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "newInstance",
                "(" + argumentsDesc + ")" + codegenType.bytecodeName(), null, null);
        mv.visitCode();
        mv.visitTypeInsn(NEW, codegenType.asmName());
        mv.visitInsn(DUP);
        int localsPos = 0;
        for (Type t : arguments) {
            mv.visitVarInsn(t.getLoadInsn(), localsPos);
            localsPos += t.getNumberSlots();
        }
        mv.visitMethodInsn(INVOKESPECIAL, codegenType.asmName(), "<init>", "(" + argumentsDesc + ")V");
        mv.visitInsn(ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    // Criar mtodos call e call_nonspeculative
    for (String[] target : new String[][] { { "call", method.name() },
            { "call_nonspeculative", method.name().replace("$speculative", "$non_speculative") } }) {
        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, target[0], "()" + Type.OBJECT.bytecodeName(), null, null);
        mv.visitCode();
        int fieldPos = 0;
        for (Type t : arguments) {
            mv.visitVarInsn(ALOAD, 0);
            mv.visitFieldInsn(GETFIELD, codegenType.asmName(), "arg" + fieldPos++, t.bytecodeName());
        }
        mv.visitMethodInsn(method.opcode() == INVOKESPECIAL ? INVOKEVIRTUAL : method.opcode(),
                method.owner().asmName(), target[1], method.desc());
        if (method.returnType().equals(Type.PRIM_VOID)) {
            if (!jaspex.Options.FASTMODE)
                mv.visitLdcInsn("JASPEX VOID RETURN VALUE");
            else
                mv.visitInsn(ACONST_NULL);
        } else if (method.returnType().isPrimitive())
            boxWrap(method.returnType(), mv);
        mv.visitInsn(ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    if (singletonMode) {
        // Criar field com singleton
        cw.visitField(ACC_STATIC | ACC_FINAL | ACC_PUBLIC, "INSTANCE", codegenType.bytecodeName(), null, null);
    }

    if (Options.RVP) {
        // Field com previso
        cw.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "PREDICTOR", CommonTypes.PREDICTOR.bytecodeName(),
                null, null);

        { // Mtodo de acesso  previso
            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "predict", "()" + Type.OBJECT.bytecodeName(), null,
                    null);
            mv.visitCode();
            if (method.returnType().equals(Type.PRIM_VOID)) {
                mv.visitTypeInsn(NEW, "java/lang/AssertionError");
                mv.visitInsn(DUP);
                mv.visitLdcInsn("Asked for prediction for Void method");
                mv.visitMethodInsn(INVOKESPECIAL, "java/lang/AssertionError", "<init>",
                        "(Ljava/lang/Object;)V");
                mv.visitInsn(ATHROW);
            } else {
                mv.visitFieldInsn(GETSTATIC, codegenType.asmName(), "PREDICTOR",
                        CommonTypes.PREDICTOR.bytecodeName());
                mv.visitMethodInsn(INVOKEVIRTUAL, CommonTypes.PREDICTOR.asmName(), "predict",
                        "()" + Type.OBJECT.bytecodeName());
                mv.visitInsn(ARETURN);
            }
            mv.visitMaxs(0, 0);
            mv.visitEnd();
        }
        { // Mtodo de actualizao da previso
            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "updatePrediction",
                    "(" + Type.OBJECT.bytecodeName() + ")V", null, null);
            mv.visitCode();
            if (!method.returnType().equals(Type.PRIM_VOID)) {
                mv.visitFieldInsn(GETSTATIC, codegenType.asmName(), "PREDICTOR",
                        CommonTypes.PREDICTOR.bytecodeName());
                mv.visitVarInsn(ALOAD, 1);
                mv.visitMethodInsn(INVOKEVIRTUAL, CommonTypes.PREDICTOR.asmName(), "updatePrediction",
                        "(" + Type.OBJECT.bytecodeName() + ")V");
            }
            mv.visitInsn(RETURN);
            mv.visitMaxs(0, 0);
            mv.visitEnd();
        }

    }

    // Gerar clinit caso existam fields para inicializar
    if (singletonMode || Options.RVP) {
        // Adicionar static initializer
        MethodVisitor mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
        mv.visitCode();
        if (singletonMode) {
            mv.visitTypeInsn(NEW, codegenType.asmName());
            mv.visitInsn(DUP);
            mv.visitMethodInsn(INVOKESPECIAL, codegenType.asmName(), "<init>", "()V");
            mv.visitFieldInsn(PUTSTATIC, codegenType.asmName(), "INSTANCE", codegenType.bytecodeName());
        }
        if (Options.RVP) {
            mv.visitLdcInsn(method.returnType().bytecodeName());
            mv.visitMethodInsn(INVOKESTATIC, CommonTypes.PREDICTORFACTORY.asmName(), "newPredictor",
                    "(" + Type.STRING.bytecodeName() + ")" + CommonTypes.PREDICTOR.bytecodeName());
            mv.visitFieldInsn(PUTSTATIC, codegenType.asmName(), "PREDICTOR",
                    CommonTypes.PREDICTOR.bytecodeName());
        }
        mv.visitInsn(RETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    // Criar toString
    {
        Type sb = Type.fromClass(StringBuilder.class);
        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "toString", "()" + Type.STRING.bytecodeName(), null,
                null);
        mv.visitCode();
        mv.visitTypeInsn(NEW, sb.asmName());
        mv.visitInsn(DUP);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESPECIAL, Type.OBJECT.asmName(), "toString", "()" + Type.STRING.bytecodeName());
        mv.visitMethodInsn(INVOKESPECIAL, sb.asmName(), "<init>", "(" + Type.STRING.bytecodeName() + ")V");
        mv.visitVarInsn(ASTORE, 1);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitLdcInsn("{");
        mv.visitMethodInsn(INVOKEVIRTUAL, sb.asmName(), "append",
                "(" + Type.STRING.bytecodeName() + ")" + sb.bytecodeName());
        int fieldPos = 0;
        boolean first = true;
        for (Type t : arguments) {
            mv.visitVarInsn(ALOAD, 1);
            mv.visitLdcInsn((first ? "" : ", ") + "arg" + fieldPos + ": ");
            first = false;
            mv.visitMethodInsn(INVOKEVIRTUAL, sb.asmName(), "append",
                    "(" + Type.STRING.bytecodeName() + ")" + sb.bytecodeName());
            mv.visitVarInsn(ALOAD, 1);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitFieldInsn(GETFIELD, codegenType.asmName(), "arg" + fieldPos++, t.bytecodeName());
            if (t.isPrimitive())
                boxWrap(t, mv);
            mv.visitMethodInsn(INVOKESTATIC, Type.STRING.asmName(), "valueOf",
                    "(" + Type.OBJECT.bytecodeName() + ")" + Type.STRING.bytecodeName());
            mv.visitMethodInsn(INVOKEVIRTUAL, sb.asmName(), "append",
                    "(" + Type.STRING.bytecodeName() + ")" + sb.bytecodeName());
        }
        mv.visitVarInsn(ALOAD, 1);
        mv.visitLdcInsn("} ");
        mv.visitMethodInsn(INVOKEVIRTUAL, sb.asmName(), "append",
                "(" + Type.STRING.bytecodeName() + ")" + sb.bytecodeName());
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKEVIRTUAL, Type.OBJECT.asmName(), "toString", "()" + Type.STRING.bytecodeName());
        mv.visitInsn(ARETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    if (Options.ALLOWDUMMYTX && SpeculationSkiplist.useDummyTransaction(method)) {
        Log.info("Setting isDummy transaction flag for " + method.owner().commonName() + "." + method.name());

        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "useDummyTransaction", "()Z", null, null);
        mv.visitCode();
        mv.visitInsn(ICONST_1);
        mv.visitInsn(IRETURN);
        mv.visitMaxs(0, 0);
        mv.visitEnd();
    }

    cw.visitEnd();

    byte[] newClass = cw.toByteArray();

    //if (speculation.SpeculativeClassLoader.PRINTCLASS) asmlib.Util.printClass(newClass);

    if (Options.WRITECLASS) {
        try {
            new java.io.File("output" + java.io.File.separatorChar).mkdir();
            java.io.FileOutputStream fos = new java.io.FileOutputStream(
                    "output" + java.io.File.separatorChar + codegenType.commonName() + ".class");
            fos.write(newClass);
            fos.close();
        } catch (java.io.FileNotFoundException e) {
            throw new Error(e);
        } catch (java.io.IOException e) {
            throw new Error(e);
        }
    }

    return newClass;
}

From source file:jaspex.transactifier.AddObjectMethodsClassVisitor.java

License:Open Source License

@Override
public void visitEnd() {
    if (_injectToString) {
        // toString completamente transaccional usando o jaspex.Builtin.StringBuilder_*
        // Funciona porque apenas o hashCode() pode causar especulaes, e portanto no
        // pode haver concorrncia no acesso ao StringBuilder, j que ser sempre a mesma
        // thread/task a executar o cdigo que se segue  chamada do hashCode
        /*//from  www  . j  ava2  s.c  o m
        @Override
        public String toString() {
           String hashCode = Integer.toHexString(hashCode());
           Object stringBuilder = jaspex.Builtin.StringBuilder_new();
           jaspex.Builtin.StringBuilder_append(stringBuilder, getClass().getName());
           jaspex.Builtin.StringBuilder_append(stringBuilder, '@');
           jaspex.Builtin.StringBuilder_append(stringBuilder, hashCode);
           return jaspex.Builtin.StringBuilder_toString(stringBuilder);
        }
         */
        MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "toString", "()Ljava/lang/String;", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        // Chamada depois  corrigida pelo ChangeObjectMethodsMethodVisitor
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I");
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", "toHexString", "(I)Ljava/lang/String;");
        mv.visitVarInsn(ASTORE, 1);
        mv.visitMethodInsn(INVOKESTATIC, "jaspex/Builtin", "StringBuilder_new", "()Ljava/lang/Object;");
        mv.visitVarInsn(ASTORE, 2);
        mv.visitVarInsn(ALOAD, 2);
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;");
        mv.visitMethodInsn(INVOKESTATIC, "jaspex/Builtin", "StringBuilder_append",
                "(Ljava/lang/Object;Ljava/lang/String;)V");
        mv.visitVarInsn(ALOAD, 2);
        mv.visitIntInsn(BIPUSH, '@');
        mv.visitMethodInsn(INVOKESTATIC, "jaspex/Builtin", "StringBuilder_append", "(Ljava/lang/Object;C)V");
        mv.visitVarInsn(ALOAD, 2);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKESTATIC, "jaspex/Builtin", "StringBuilder_append",
                "(Ljava/lang/Object;Ljava/lang/String;)V");
        mv.visitVarInsn(ALOAD, 2);
        mv.visitMethodInsn(INVOKESTATIC, "jaspex/Builtin", "StringBuilder_toString",
                "(Ljava/lang/Object;)Ljava/lang/String;");
        mv.visitInsn(ARETURN);
        mv.visitMaxs(2, 3);
        mv.visitEnd();
    }

    if (_injectHashCode) {
        MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "hashCode", "()I", null, null);
        mv.visitCode();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitMethodInsn(INVOKESTATIC, "java/lang/System", "identityHashCode", "(Ljava/lang/Object;)I");
        mv.visitInsn(IRETURN);
        mv.visitMaxs(1, 1);
        mv.visitEnd();
    }

    cv.visitEnd();
}