Example usage for org.objectweb.asm MethodVisitor visitLocalVariable

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

Introduction

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

Prototype

public void visitLocalVariable(final String name, final String descriptor, final String signature,
        final Label start, final Label end, final int index) 

Source Link

Document

Visits a local variable declaration.

Usage

From source file:org.boretti.drools.integration.drools5.DroolsClassVisitor.java

License:Open Source License

@Override
public void visitEnd() {
    FieldVisitor fv = null;//w  w  w .  j  ava  2 s.com
    if (isNeedChangeForBoth()) {
        fv = super.visitField(Opcodes.ACC_PRIVATE, DROOLS_FIELD_NAME, Type.BOOLEAN_TYPE.getDescriptor(), null,
                null);
        if (fv != null) {
            AnnotationVisitor av = fv.visitAnnotation(Type.getType(Generated.class).getDescriptor(), true);
            AnnotationVisitor value = av.visitArray("value");
            value.visit("", "Generated by Drools5IntegrationHelper Maven plugin");
            value.visitEnd();
            av.visit("date", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz").format(current));
            av.visitEnd();
            fv.visitEnd();
        }
    }
    if (isNeedChangeForField()) {
        fv = super.visitField(Opcodes.ACC_PRIVATE, DROOLS_FIELD_RULE,
                Type.getType(RuleBase.class).getDescriptor(), null, null);
        if (fv != null) {
            AnnotationVisitor av = fv.visitAnnotation(Type.getType(Generated.class).getDescriptor(), true);
            AnnotationVisitor value = av.visitArray("value");
            value.visit("", "Generated by Drools5IntegrationHelper Maven plugin");
            value.visitEnd();
            av.visit("date", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz").format(current));
            av.visitEnd();
            fv.visitEnd();
        }
        MethodVisitor mv = super.visitMethod(Opcodes.ACC_PRIVATE, DROOLS_METHOD_RUN, "()V", null, null);
        AnnotationVisitor av = mv.visitAnnotation(Type.getType(Generated.class).getDescriptor(), true);
        AnnotationVisitor value = av.visitArray("value");
        value.visit("", "Generated by Drools5IntegrationHelper Maven plugin");
        value.visitEnd();
        av.visit("date", new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssz").format(current));
        av.visitEnd();
        mv.visitCode();
        Label start = new Label();
        mv.visitLabel(start);
        Label doIt = new Label();
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, Type.getObjectType(me).getInternalName(), DROOLS_FIELD_NAME,
                Type.BOOLEAN_TYPE.getDescriptor());
        mv.visitJumpInsn(Opcodes.IFEQ, doIt);
        mv.visitInsn(Opcodes.RETURN);
        mv.visitLabel(doIt);
        mv.visitFrame(Opcodes.F_SAME, 1, new Object[] { Type.getObjectType(me).getInternalName() }, 0,
                new Object[] {});
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitFieldInsn(Opcodes.GETFIELD, Type.getObjectType(me).getInternalName(), DROOLS_FIELD_RULE,
                Type.getType(RuleBase.class).getDescriptor());
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getType(RuleBase.class).getInternalName(),
                "newStatelessSession", "()Lorg/drools/StatelessSession;");
        mv.visitInsn(Opcodes.DUP);
        mv.visitLdcInsn(FIELD_NAME_LOGGER);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getType(Object.class).getInternalName(), "getClass",
                "()Ljava/lang/Class;");
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getType(org.apache.log4j.Logger.class).getInternalName(),
                "getLogger", "(Ljava/lang/Class;)Lorg/apache/log4j/Logger;");
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getType(StatelessSession.class).getInternalName(),
                "setGlobal", "(Ljava/lang/String;Ljava/lang/Object;)V");
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.getType(StatelessSession.class).getInternalName(),
                "execute", "(Ljava/lang/Object;)V");
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitInsn(Opcodes.ICONST_1);
        mv.visitFieldInsn(Opcodes.PUTFIELD, Type.getObjectType(me).getInternalName(), DROOLS_FIELD_NAME,
                Type.BOOLEAN_TYPE.getDescriptor());
        mv.visitInsn(Opcodes.RETURN);
        Label end = new Label();
        mv.visitLabel(end);
        mv.visitLocalVariable("this", Type.getObjectType(me).getDescriptor(), null, start, end, 0);
        mv.visitMaxs(4, 1);
        mv.visitEnd();
    }
    super.visitEnd();
}

From source file:org.codehaus.groovy.classgen.asm.CompileStack.java

License:Apache License

/**
 * Clears the state of the class. This method should be called
 * after a MethodNode is visited. Note that a call to init will
 * fail if clear is not called before//from  w ww.j a va2  s . c o m
 */
public void clear() {
    if (stateStack.size() > 1) {
        int size = stateStack.size() - 1;
        throw new GroovyBugError("the compile stack contains " + size + " more push instruction"
                + (size == 1 ? "" : "s") + " than pops.");
    }
    if (lhsStack.size() > 1) {
        int size = lhsStack.size() - 1;
        throw new GroovyBugError("lhs stack is supposed to be empty, but has " + size + " elements left.");
    }
    if (implicitThisStack.size() > 1) {
        int size = implicitThisStack.size() - 1;
        throw new GroovyBugError(
                "implicit 'this' stack is supposed to be empty, but has " + size + " elements left.");
    }
    clear = true;
    MethodVisitor mv = controller.getMethodVisitor();
    // br experiment with local var table so debuggers can retrieve variable names
    if (true) {//AsmClassGenerator.CREATE_DEBUG_INFO) {
        if (thisEndLabel == null)
            setEndLabels();

        if (!scope.isInStaticContext()) {
            // write "this"
            mv.visitLocalVariable("this", className, null, thisStartLabel, thisEndLabel, 0);
        }

        for (Object usedVariable : usedVariables) {
            BytecodeVariable v = (BytecodeVariable) usedVariable;
            ClassNode t = v.getType();
            if (v.isHolder())
                t = ClassHelper.REFERENCE_TYPE;
            String type = BytecodeHelper.getTypeDescription(t);
            Label start = v.getStartLabel();
            Label end = v.getEndLabel();
            mv.visitLocalVariable(v.getName(), type, null, start, end, v.getIndex());
        }
    }

    //exception table writing
    for (ExceptionTableEntry ep : typedExceptions) {
        mv.visitTryCatchBlock(ep.start, ep.end, ep.goal, ep.sig);
    }
    //exception table writing
    for (ExceptionTableEntry ep : untypedExceptions) {
        mv.visitTryCatchBlock(ep.start, ep.end, ep.goal, ep.sig);
    }

    pop();
    typedExceptions.clear();
    untypedExceptions.clear();
    stackVariables.clear();
    usedVariables.clear();
    scope = null;
    finallyBlocks.clear();
    resetVariableIndex(false);
    superBlockNamedLabels.clear();
    currentBlockNamedLabels.clear();
    namedLoopBreakLabel.clear();
    namedLoopContinueLabel.clear();
    continueLabel = null;
    breakLabel = null;
    thisStartLabel = null;
    thisEndLabel = null;
    mv = null;
}

From source file:org.eclipse.m2m.atl.emftvm.jit.CodeBlockJIT.java

License:Open Source License

/**
 * Generates a constructor for the {@link JITCodeBlock}.
 * @param init the constructor visitor/*from   w w w  .  j  a  va 2s  . co m*/
 * @param className the name of the generated class
 */
protected static void generateConstructor(final MethodVisitor init, final String className) {
    init.visitCode();
    // Generate labels
    final Label start = new Label();
    final Label end = new Label();
    // Generate bytecode
    init.visitLabel(start);
    init.visitVarInsn(ALOAD, 0); // this
    init.visitVarInsn(ALOAD, 1); // cb
    init.visitMethodInsn(INVOKESPECIAL, // super(cb) 
            Type.getInternalName(JITCodeBlock.class), "<init>",
            Type.getMethodDescriptor(Type.VOID_TYPE, new Type[] { Type.getType(CodeBlock.class) }));
    init.visitInsn(RETURN);
    init.visitLabel(end);
    // Create local variable table
    init.visitLocalVariable("this", "L" + className + ";", null, start, end, 0);
    init.visitLocalVariable("cb", Type.getDescriptor(CodeBlock.class), null, start, end, 1);
    // Finalise
    init.visitMaxs(2, 2);
    init.visitEnd();
}

From source file:org.eclipse.m2m.atl.emftvm.jit.CodeBlockJIT.java

License:Open Source License

/**
 * Generates an execute method for the {@link JITCodeBlock}.
 * @param execute the execute method visitor
 * @param cb the {@link CodeBlock} to JIT-compile
 * @param className the name of the generated class
 */// w w w.j  a v a 2  s .  c  o m
protected void generateExecute(final MethodVisitor execute, final CodeBlock cb, final String className) {
    execute.visitCode();
    // Generate labels
    final LabelSwitch ls = new LabelSwitch();
    for (Instruction instr : cb.getCode()) {
        ls.doSwitch(instr);
    }
    // Default labels
    final Label start = new Label();
    final Label end = new Label();
    final Label tryStart = new Label();
    final Label vmExceptionHandler = new Label();
    final Label exceptionHandler = new Label();
    final Label catchEnd = new Label();
    // Create exception table
    execute.visitTryCatchBlock(tryStart, vmExceptionHandler, vmExceptionHandler,
            Type.getInternalName(VMException.class));
    execute.visitTryCatchBlock(tryStart, vmExceptionHandler, exceptionHandler,
            Type.getInternalName(Exception.class));
    // Generate bytecode
    execute.visitLabel(start);
    execute.visitVarInsn(ALOAD, 1); // frame
    execute.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(StackFrame.class), "getEnv",
            Type.getMethodDescriptor(Type.getType(ExecEnv.class), new Type[0]));
    execute.visitVarInsn(ASTORE, 2);
    execute.visitVarInsn(ALOAD, 2); // env
    execute.visitMethodInsn(INVOKEINTERFACE, Type.getInternalName(ExecEnv.class), "getMonitor",
            Type.getMethodDescriptor(Type.getType(VMMonitor.class), new Type[0]));
    execute.visitVarInsn(ASTORE, 3); // monitor
    execute.visitLabel(tryStart);
    final ByteCodeSwitch bs = new ByteCodeSwitch(this, execute, ls);
    final EList<Instruction> code = cb.getCode();
    final boolean hasMonitor = getEnv().getMonitor() != null;
    for (Instruction instr : code) {
        if (hasMonitor) {
            // do checkMonitor() before each instruction
            generateCheckMonitor(execute, code.indexOf(instr) + 1); // pc
        }
        // generate instruction-specific code
        bs.doSwitch(instr);
    }
    execute.visitJumpInsn(GOTO, catchEnd);
    // catch (VMException e)
    execute.visitLabel(vmExceptionHandler);
    execute.visitVarInsn(ASTORE, 4); // e
    execute.visitVarInsn(ALOAD, 4); // e
    execute.visitInsn(ATHROW); // throw e
    // catch (Exception e)
    execute.visitLabel(exceptionHandler);
    execute.visitVarInsn(ASTORE, 4); // e
    execute.visitTypeInsn(NEW, Type.getInternalName(VMException.class)); // new VMException(): [vme, ...]
    execute.visitInsn(DUP); // [vme, vme, e, ...]
    execute.visitVarInsn(ALOAD, 1); // frame: [frame, vme, vme, ...]
    execute.visitVarInsn(ALOAD, 4); // e: [e, frame, vme, vme, ...]
    execute.visitMethodInsn(INVOKESPECIAL, // new VMException(frame, e): [vme, ...]
            Type.getInternalName(VMException.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE,
                    new Type[] { Type.getType(StackFrame.class), Type.getType(Throwable.class) }));
    execute.visitInsn(ATHROW); // throw vme
    // Regular method return
    execute.visitLabel(catchEnd);
    if (cb.getStackLevel() == 0) {
        execute.visitInsn(ACONST_NULL); // push null
    }
    execute.visitInsn(ARETURN); // return result
    execute.visitLabel(end);
    // Create local variable table
    execute.visitLocalVariable("this", "L" + className + ";", null, start, end, 0);
    execute.visitLocalVariable("frame", Type.getDescriptor(StackFrame.class), null, start, end, 1);
    execute.visitLocalVariable("env", Type.getDescriptor(ExecEnv.class), null, start, end, 2);
    execute.visitLocalVariable("monitor", Type.getDescriptor(VMMonitor.class), null, start, end, 3);
    execute.visitLocalVariable("e", Type.getDescriptor(VMException.class), null, vmExceptionHandler,
            exceptionHandler, 4);
    execute.visitLocalVariable("e", Type.getDescriptor(Exception.class), null, exceptionHandler, catchEnd, 4);
    // Finalise
    execute.visitMaxs(0, 0); // recalculate 
    execute.visitEnd();
}

From source file:org.eclipse.objectteams.otredyn.bytecode.asm.AddThreadNotificationAdapter.java

License:Open Source License

@Override
public MethodVisitor visitMethod(int access, String methodName, String desc, String signature,
        String[] exceptions) {/*from ww w  .j  av a  2 s. c  o m*/
    if (INIT.equals(methodName)) {
        // into each constructor ...
        final MethodVisitor methodVisitor = cv.visitMethod(access, methodName, desc, null, null);
        return new AdviceAdapter(this.api, methodVisitor, access, methodName, desc) {
            @Override
            public void invokeConstructor(Type type, Method method) {
                super.invokeConstructor(type, method);
                // ... that contains a super(..) call (rather than this(..)):
                if (type.getInternalName().equals(clazz.getInternalSuperClassName())) {
                    // insert:
                    // this._OT$creationThread = Thread.currentThread();
                    methodVisitor.visitIntInsn(Opcodes.ALOAD, 0);
                    methodVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, ClassNames.THREAD_SLASH, CURRENT_THREAD,
                            CURRENT_THREAD_DESC, false);
                    methodVisitor.visitFieldInsn(Opcodes.PUTFIELD, clazz.getInternalName(), CREATION_THREAD,
                            THREAD_DESC);
                }
            }
        };
    } else if (RUN.equals(methodName) && RUN_DESC.equals(desc)) {
        final MethodVisitor methodVisitor = cv.visitMethod(access, methodName, desc, null, null);
        return new AdviceAdapter(this.api, methodVisitor, access, methodName, desc) {

            Label start = new Label(); // start of method (scope of new local)
            Label end = new Label(); // end of method
            int isThreadStartIdx; // new local: boolean _OT$isThreadStart

            @Override
            protected void onMethodEnter() {
                methodVisitor.visitLabel(start);
                isThreadStartIdx = newLocal(Type.BOOLEAN_TYPE);
                methodVisitor.visitLocalVariable("_OT$isThreadStart", "Z", null, start, end, isThreadStartIdx);
                // TeamThreadManager.newThreadStarted(false, this._OT$creationThread)
                methodVisitor.visitInsn(Opcodes.ICONST_0);
                methodVisitor.visitIntInsn(Opcodes.ALOAD, 0);
                methodVisitor.visitFieldInsn(Opcodes.GETFIELD, clazz.getInternalName(), CREATION_THREAD,
                        THREAD_DESC);
                methodVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, ClassNames.TEAM_THREAD_MANAGER_SLASH,
                        NEW_THREAD_STARTED, NEW_THREAD_STARTED_DESC, false);
                methodVisitor.visitIntInsn(Opcodes.ISTORE, isThreadStartIdx);
                // this._OT$creationThread = null; // avoid leak
                methodVisitor.visitIntInsn(Opcodes.ALOAD, 0);
                methodVisitor.visitInsn(Opcodes.ACONST_NULL);
                methodVisitor.visitFieldInsn(Opcodes.PUTFIELD, clazz.getInternalName(), CREATION_THREAD,
                        THREAD_DESC);
            }

            @Override
            protected void onMethodExit(int opcode) {
                insertThreadEndedNotification();
            }

            @Override
            public void endMethod() {
                methodVisitor.visitLabel(end);

                // insert another threadEnded notification as a handler for Throwable
                Label handler = new Label();
                methodVisitor.visitLabel(handler);
                insertThreadEndedNotification();
                methodVisitor.visitInsn(Opcodes.ATHROW); // rethrow caught exception

                methodVisitor.visitTryCatchBlock(start, end, handler, ClassNames.THROWABLE_SLASH);
                methodVisitor.visitMaxs(0, 0);
            }

            void insertThreadEndedNotification() {
                Label skip = new Label();
                // insert:
                // if (_OT$isThreadStart) TeamThreadManager.threadEnded();
                methodVisitor.visitIntInsn(Opcodes.ILOAD, isThreadStartIdx);
                methodVisitor.visitJumpInsn(Opcodes.IFEQ, skip);
                methodVisitor.visitMethodInsn(Opcodes.INVOKESTATIC, ClassNames.TEAM_THREAD_MANAGER_SLASH,
                        THREAD_ENDED, THREAD_ENDED_DESC, false);
                methodVisitor.visitLabel(skip);
            }
        };
    }
    return null;
}

From source file:org.enerj.enhancer.ClassEnhancer.java

License:Open Source License

/**
 * Generate the getfield/putfield replacement methods (enerj_Get_* and enerj_Set_*)
 * for persistent fields.//from w  w  w . ja v a 2s  .co  m
 * Parameters to the generated methods conveniently match the stack frame of
 * getfield and putfield.
 *
 * @param aField a Field for which the methods will be generated.
 */
private void emitPersistentFieldMediationMethods(Field aField) {
    int fieldScope = aField.getAccessModifiers() & (ACC_PRIVATE | ACC_PUBLIC | ACC_PROTECTED);
    String fieldName = aField.getName();
    String methodNameSuffix = getFieldMethodNameSuffix(mClassName, fieldName);
    String fieldType = aField.getDescriptor();
    int opcodeOffset = getOpcodeOffsetForDescriptor(fieldType);
    // TODO do we need to worry about fields with parameterized types? 
    //String genericSignature = Type.getDescriptor( aField.getGenericType() );

    MethodVisitor mv = cv.visitMethod(fieldScope | ACC_STATIC, FIELD_ACCESSOR_PREFIX + methodNameSuffix,
            '(' + mThisClassDescr + ')' + fieldType, null, null);
    Label label0 = new Label();
    mv.visitLabel(label0);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, "enerj_mLoaded", "Z");
    Label label1 = new Label();
    mv.visitJumpInsn(IFNE, label1);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, "enerj_mNew", "Z");
    mv.visitJumpInsn(IFNE, label1);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitInsn(ICONST_0);
    mv.visitMethodInsn(INVOKESTATIC, sPersistableHelperClassSlashed, "checkLoaded",
            "(Lorg/enerj/core/Persistable;Z)V");
    mv.visitLabel(label1);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, fieldName, fieldType);
    mv.visitInsn(getReturnOpcodeForDescriptor(fieldType));
    Label label3 = new Label();
    mv.visitLabel(label3);
    mv.visitLocalVariable("anInstance", mThisClassDescr, null, label0, label3, 0);
    mv.visitMaxs(0, 0);

    ///--------------
    // Mutator (Setter). Because of the == comparison, the method is a little different
    // for primitives, Strings (final class that implements equals() properly), and regular objects.

    mv = cv.visitMethod(fieldScope | ACC_STATIC, FIELD_MUTATOR_PREFIX + methodNameSuffix,
            '(' + mThisClassDescr + fieldType + ")V", null, null);
    mv.visitCode();

    // Check if checkLoaded needs to be called. Call if (!enerj_mLoaded && !enerj_mNew)
    Label mutatorStartLabel = new Label();
    mv.visitLabel(mutatorStartLabel);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, "enerj_mLoaded", "Z");
    Label mutatorLabel1 = new Label();
    mv.visitJumpInsn(IFNE, mutatorLabel1);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, "enerj_mNew", "Z");
    mv.visitJumpInsn(IFNE, mutatorLabel1);

    // Call checkLoaded
    mv.visitVarInsn(ALOAD, 0);
    mv.visitInsn(ICONST_1);
    mv.visitMethodInsn(INVOKESTATIC, sPersistableHelperClassSlashed, "checkLoaded",
            "(Lorg/enerj/core/Persistable;Z)V");
    mv.visitLabel(mutatorLabel1);

    // Check if the field's value is actually changing. For primitives, we use ==;
    // for special classes declared final (e.g., String, Integer), we use equals(); 
    // and for other objects we use == (identity).

    Label notModifiedLabel = new Label();

    if (MetaData.isPrimitive(fieldType)) {
        // Push parameter 1 - the new value
        mv.visitVarInsn(ILOAD + opcodeOffset, 1);
        // This
        mv.visitVarInsn(ALOAD, 0);
        // Current value
        mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, fieldName, fieldType);

        char type = fieldType.charAt(0);
        switch (type) {
        case 'B':
        case 'Z':
        case 'C':
        case 'S':
        case 'I':
            mv.visitJumpInsn(IF_ICMPEQ, notModifiedLabel);
            break;

        case 'F':
            mv.visitInsn(FCMPL);
            mv.visitJumpInsn(IFEQ, notModifiedLabel);
            break;

        case 'J':
            mv.visitInsn(LCMP);
            mv.visitJumpInsn(IFEQ, notModifiedLabel);
            break;

        case 'D':
            mv.visitInsn(DCMPL);
            mv.visitJumpInsn(IFEQ, notModifiedLabel);
            break;

        default:
            throw new RuntimeException("Unknown primitive type: " + type);
        }
    } else if (fieldType.equals("Ljava/lang/String;") || fieldType.equals("Ljava/lang/Integer;")
            || fieldType.equals("Ljava/lang/Long;") || fieldType.equals("Ljava/lang/Byte;")
            || fieldType.equals("Ljava/lang/Boolean;") || fieldType.equals("Ljava/lang/Character;")
            || fieldType.equals("Ljava/lang/Short;") || fieldType.equals("Ljava/lang/Float;")
            || fieldType.equals("Ljava/lang/Double;")) {

        // One of the core final immutable types. Use equals() to compare values, like this:
        // "if ((aValue == null{1} && anInstance.mString != null{2}) || (aValue != null{3} && !aValue.equals(anInstance.mString){4})" ...

        // {1}: aValue == null
        mv.visitVarInsn(ALOAD, 1);
        Label imEqualsLabel = new Label();
        mv.visitJumpInsn(IFNONNULL, imEqualsLabel);

        // {2}: anInstance.mString != null
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, fieldName, fieldType);
        Label imStoreLabel = new Label();
        mv.visitJumpInsn(IFNONNULL, imStoreLabel);

        // {3}: aValue != null
        mv.visitLabel(imEqualsLabel);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitJumpInsn(IFNULL, notModifiedLabel);

        // {4}: equals()...
        // Push parameter 1 - the new value
        mv.visitVarInsn(ALOAD, 1);
        // Current Value
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, fieldName, fieldType);
        // Compare !equals()
        mv.visitMethodInsn(INVOKEVIRTUAL, aField.getInternalName(), "equals", "(Ljava/lang/Object;)Z");
        mv.visitJumpInsn(IFNE, notModifiedLabel);

        mv.visitLabel(imStoreLabel);
    } else {
        // Some other Object -- use identity ==
        // Push parameter 1 - the new value
        mv.visitVarInsn(ALOAD, 1);
        // This
        mv.visitVarInsn(ALOAD, 0);
        // Current value
        mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, fieldName, fieldType);
        mv.visitJumpInsn(IF_ACMPEQ, notModifiedLabel);
    }

    // Store the value
    // Mark owner object as modified - short circuit if already marked modified
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, "enerj_mModified", "Z");
    Label mutatorLabel2 = new Label();
    mv.visitJumpInsn(IFNE, mutatorLabel2);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESTATIC, sPersistableHelperClassSlashed, "addModified", sPersistableVoidSignature);
    mv.visitLabel(mutatorLabel2);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(ILOAD + opcodeOffset, 1);
    mv.visitFieldInsn(PUTFIELD, mThisClassNameSlashed, fieldName, fieldType);
    mv.visitLabel(notModifiedLabel);
    mv.visitInsn(RETURN);

    Label mutatorEndlabel = new Label();
    mv.visitLabel(mutatorEndlabel);
    mv.visitLocalVariable("anInstance", mThisClassDescr, null, mutatorStartLabel, mutatorEndlabel, 0);
    mv.visitLocalVariable("aValue", fieldType, null, mutatorStartLabel, mutatorEndlabel, 1);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:org.enerj.enhancer.ClassEnhancer.java

License:Open Source License

/**
 * Generate the getfield/putfield replacement methods (enerj_Get_* and enerj_Set_*)
 * for non-static transient fields./*from  w ww .  j a  v  a 2s. c  o m*/
 * Parameters to the generated methods conveniently match the stack frame of
 * getfield and putfield.
 *
 * @param aField a Field for which the methods will be generated.
 */
private void emitTransientFieldMediationMethods(Field aField) {
    int fieldScope = aField.getAccessModifiers() & (ACC_PRIVATE | ACC_PUBLIC | ACC_PROTECTED);
    String fieldName = aField.getName();
    String methodNameSuffix = getFieldMethodNameSuffix(mClassName, fieldName);
    String fieldType = aField.getDescriptor();

    // Accessor (Getter).
    MethodVisitor mv = cv.visitMethod(fieldScope | ACC_STATIC, FIELD_ACCESSOR_PREFIX + methodNameSuffix,
            '(' + mThisClassDescr + ')' + fieldType, null, null);
    mv.visitCode();
    Label startLabel = new Label();
    mv.visitLabel(startLabel);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitFieldInsn(GETFIELD, mThisClassNameSlashed, fieldName, fieldType);
    mv.visitInsn(getReturnOpcodeForDescriptor(fieldType));
    Label endLabel = new Label();
    mv.visitLabel(endLabel);
    mv.visitLocalVariable("anInstance", mThisClassDescr, null, startLabel, endLabel, 0);
    mv.visitMaxs(0, 0);
    mv.visitEnd();

    // Mutator (Setter).
    mv = cv.visitMethod(fieldScope | ACC_STATIC, FIELD_MUTATOR_PREFIX + methodNameSuffix,
            '(' + mThisClassDescr + fieldType + ")V", null, null);
    mv.visitCode();
    startLabel = new Label();
    mv.visitLabel(startLabel);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitVarInsn(getLoadOpcodeForDescriptor(fieldType), 1);
    mv.visitFieldInsn(PUTFIELD, mThisClassNameSlashed, fieldName, fieldType);
    mv.visitInsn(RETURN);
    endLabel = new Label();
    mv.visitLabel(endLabel);
    mv.visitLocalVariable("anInstance", mThisClassDescr, null, startLabel, endLabel, 0);
    mv.visitLocalVariable("aValue", fieldType, null, startLabel, endLabel, 1);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:org.enerj.enhancer.ClassEnhancer.java

License:Open Source License

/**
 * Generate the getstatic/putstatic replacement methods (enerj_Get_* and enerj_Set_*)
 * for static transient fields. //from   www .  j a  v a  2s.co  m
 * Parameters to the generated methods conveniently match the stack frame of
 * getstatic and putstatic.
 *
 * @param aField a Field for which the methods will be generated.
 */
private void emitStaticFieldMediationMethods(Field aField) {
    int fieldScope = aField.getAccessModifiers() & (ACC_PRIVATE | ACC_PUBLIC | ACC_PROTECTED);
    String fieldName = aField.getName();
    String methodNameSuffix = getFieldMethodNameSuffix(mClassName, fieldName);
    String fieldType = aField.getDescriptor();

    // Accessor (Getter).
    MethodVisitor mv = cv.visitMethod(fieldScope | ACC_STATIC, FIELD_ACCESSOR_PREFIX + methodNameSuffix,
            "()" + fieldType, null, null);
    mv.visitCode();
    mv.visitFieldInsn(GETSTATIC, mThisClassNameSlashed, fieldName, fieldType);
    mv.visitInsn(getReturnOpcodeForDescriptor(fieldType));
    mv.visitMaxs(0, 0);
    mv.visitEnd();

    // Mutator (Setter).
    mv = cv.visitMethod(fieldScope | ACC_STATIC, FIELD_MUTATOR_PREFIX + methodNameSuffix,
            '(' + fieldType + ")V", null, null);
    mv.visitCode();
    Label startLabel = new Label();
    mv.visitLabel(startLabel);
    mv.visitVarInsn(getLoadOpcodeForDescriptor(fieldType), 0);
    mv.visitFieldInsn(PUTSTATIC, mThisClassNameSlashed, fieldName, fieldType);
    mv.visitInsn(RETURN);
    Label endLabel = new Label();
    mv.visitLabel(endLabel);
    mv.visitLocalVariable("aValue", fieldType, null, startLabel, endLabel, 0);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:org.enerj.enhancer.ClassEnhancer.java

License:Open Source License

/**
 * Emit the special clone() method on a top-level persistable. This is
 * generated when a top-level Persistable doesn't have a clone method.
 * It ensures initPersistableClone is called if a sub-class implements clone().
 *///from   www  .j  a v a2 s. c  o  m
private void emitClone() {
    // TODO Only add this exception if superclass throws it. Object does, while java.util.Date does not.
    // TODO Either that or never throw it and wrap the super.clone() in a try/catch.
    // TODO catch part should never happen. If it does, return null.
    String[] exceptions = new String[] { "java/lang/CloneNotSupportedException" };
    MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "clone", "()Ljava/lang/Object;", null, exceptions);

    mv.visitCode();
    Label startLabel = new Label();
    mv.visitLabel(startLabel);
    mv.visitVarInsn(ALOAD, 0);
    mv.visitMethodInsn(INVOKESPECIAL, mSuperClassNameSlashed, "clone", "()Ljava/lang/Object;");
    mv.visitInsn(DUP);
    mv.visitTypeInsn(CHECKCAST, sPersistableClassSlashed);
    mv.visitMethodInsn(INVOKESTATIC, sPersistableHelperClassSlashed, "initPersistableClone",
            sPersistableVoidSignature);
    mv.visitInsn(ARETURN);
    Label endLabel = new Label();
    mv.visitLabel(endLabel);

    mv.visitLocalVariable("this", mThisClassDescr, null, startLabel, endLabel, 0);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}

From source file:org.enerj.enhancer.ClassEnhancer.java

License:Open Source License

/**
 * Emits the enerj_ReadObject method.// w ww  .  j  a va2  s  .  c o m
 *
 * @param someFields a list of the persistent fields for this class (not including
 *  super-class fields).
 */
private void emitReadObject(ArrayList<Field> someFields) {
    MethodVisitor mv = cv.visitMethod(ACC_PUBLIC, "enerj_ReadObject", sReadWriteObjectMethodSignature, null,
            new String[] { "java/io/IOException" });

    mv.visitCode();
    Label startLabel = new Label();
    mv.visitLabel(startLabel);

    mv.visitVarInsn(ALOAD, 1);
    mv.visitMethodInsn(INVOKEVIRTUAL, sObjectSerializerClassNameSlashed, "getDataInput",
            "()Ljava/io/DataInput;");
    mv.visitVarInsn(ASTORE, 2);

    if (!mIsTopLevelPersistable) {
        // Call super read if not a top-level persistable
        mv.visitVarInsn(ALOAD, 0);
        mv.visitVarInsn(ALOAD, 1);
        mv.visitMethodInsn(INVOKESPECIAL, mSuperClassNameSlashed, "enerj_ReadObject",
                sReadWriteObjectMethodSignature);
    }

    for (Field field : someFields) {
        String fieldName = field.getName();
        String fieldType = field.getDescriptor();

        // This will return null if the type is not a primitive.
        String dataInOutSuffix = MetaData.getPrimitiveDataInOutSuffix(fieldType);
        if (dataInOutSuffix != null) {
            // Read instructions for primitive...
            // this - For putfield
            mv.visitVarInsn(ALOAD, 0);
            // DataInput "stream"
            mv.visitVarInsn(ALOAD, 2);
            // Invoke read method on DataInput
            mv.visitMethodInsn(INVOKEINTERFACE, sDataInputClassNameSlashed, "read" + dataInOutSuffix,
                    "()" + fieldType);
            // Store the value
            mv.visitFieldInsn(PUTFIELD, mThisClassNameSlashed, fieldName, fieldType);
        } else {
            // Read instructions for a SCO or FCO...
            // this - For putfield
            mv.visitVarInsn(ALOAD, 0);
            // ReadContext - method param 1
            mv.visitVarInsn(ALOAD, 1);
            // this - method param 2
            mv.visitVarInsn(ALOAD, 0);
            // Invoke readObject - value to stack for putfield
            mv.visitMethodInsn(INVOKEVIRTUAL, sObjectSerializerClassNameSlashed, "readObject",
                    "(" + sPersistableClassDescr + ")Ljava/lang/Object;");
            // Cast Object result to proper type
            mv.visitTypeInsn(CHECKCAST, field.getInternalName());
            // Store the value
            mv.visitFieldInsn(PUTFIELD, mThisClassNameSlashed, fieldName, fieldType);
        }
    }

    // Invoke enerjPostLoad if it exists
    if (mHasPostLoad) {
        // this
        mv.visitVarInsn(ALOAD, 0);
        // See comments on call to enerjPreStore for reason why INVOKESPECIAL is used.
        mv.visitMethodInsn(INVOKESPECIAL, mThisClassNameSlashed, sPostLoadMethodName, sNoArgMethodSignature);
    }

    mv.visitInsn(RETURN);

    Label endLabel = new Label();
    mv.visitLabel(endLabel);

    mv.visitLocalVariable("this", mThisClassDescr, null, startLabel, endLabel, 0);
    mv.visitLocalVariable("aContext", "Lorg/enerj/core/ObjectSerializer;", null, startLabel, endLabel, 1);
    mv.visitLocalVariable("stream", "Ljava/io/DataInput;", null, startLabel, endLabel, 2);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}