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:org.moe.natj.processor.cxx.BCGen.java

License:Apache License

/**
 * Generates code which pops the top CxxObject on the stack and replaces it with its _cxx_rt_peer.
 *
 * @param mv        Method visitor//from  w w w.j  a  v a2  s  .  co  m
 * @param checkNull Handle null object case
 */
public static void swapCxxObjectWithItsPeer(MethodVisitor mv, final boolean checkNull) {
    final Label then;
    final Label join;
    if (checkNull) {
        then = new Label();
        join = new Label();

        // if
        mv.visitInsn(DUP);
        mv.visitJumpInsn(IFNONNULL, then);

        // else
        mv.visitInsn(POP);
        mv.visitInsn(LCONST_0);
        mv.visitJumpInsn(GOTO, join);

        // then
        mv.visitLabel(then);
    } else {
        join = null;
    }

    mv.visitTypeInsn(CHECKCAST, CxxSupport.CXX_OBJECT_ITF.getInternalName());
    mv.visitMethodInsn(INVOKEINTERFACE, CxxSupport.CXX_OBJECT_ITF.getInternalName(), "_cxx_rt_peer",
            Type.getMethodDescriptor(Type.LONG_TYPE), true);

    if (checkNull) {
        // join
        mv.visitLabel(join);
    }
}

From source file:org.moe.natj.processor.cxx.BCGen.java

License:Apache License

private static void CxxRuntime_getOrConstruct_dynamicType(MethodVisitor mv, CxxType type,
        CxxUtils.LocalManager localManager, CxxClassInfo itf, ITypeResolverPlugin plugin) {
    final int nextIndex = localManager.getNextIndex();
    final CxxUtils.Local peer = localManager.getNext("__cxx_GOC" + nextIndex, Type.LONG_TYPE, 2);
    final CxxUtils.Local rslt = localManager.getNext("__cxx_GOC" + nextIndex + "_R", itf.mapperType, 1);
    final Label endL = new Label();

    // Local variable start labels
    mv.visitLabel(peer.start);// ww  w  .j  av  a 2 s  . com
    mv.visitLabel(rslt.start);

    // Save peer
    mv.visitVarInsn(LSTORE, peer.index);

    // CxxRuntime.get(peer)
    mv.visitVarInsn(LLOAD, peer.index);
    mv.visitMethodInsn(INVOKESTATIC, CxxSupport.CXX_RUNTIME.getInternalName(), "get",
            Type.getMethodDescriptor(CxxSupport.CXX_OBJECT_ITF, Type.LONG_TYPE), false);
    mv.visitInsn(DUP);
    mv.visitTypeInsn(INSTANCEOF, itf.mapperType.getInternalName());
    mv.visitJumpInsn(IFNE, endL);

    // Construct
    mv.visitInsn(POP);
    mv.visitVarInsn(LLOAD, peer.index);
    mv.visitVarInsn(LLOAD, peer.index);
    final String getterMethod;
    if (type.isConstCxxObjectKind()) {
        getterMethod = "getConstClassForType";
    } else {
        getterMethod = "getClassForType";
    }
    mv.visitMethodInsn(INVOKESTATIC, plugin.getImplementingClass() + "$__cxx_TypeRes", getterMethod,
            Type.getMethodDescriptor(Type.getObjectType("java/lang/Class"), Type.LONG_TYPE), false);
    mv.visitMethodInsn(INVOKESTATIC, CxxSupport.CXX_RUNTIME.getInternalName(), "construct",
            Type.getMethodDescriptor(CxxSupport.CXX_OBJECT_ITF, Type.LONG_TYPE,
                    Type.getObjectType("java/lang/Class")),
            false);

    // Join
    mv.visitLabel(endL);
    mv.visitTypeInsn(CHECKCAST, itf.mapperType.getInternalName());
    mv.visitVarInsn(ASTORE, rslt.index);
    mv.visitVarInsn(ALOAD, rslt.index);

    // Local variable end labels
    mv.visitLabel(peer.end);
    mv.visitLabel(rslt.end);
}

From source file:org.moe.natj.processor.cxx.BCGen.java

License:Apache License

private static void CxxRuntime_getOrConstruct_binding(MethodVisitor mv, CxxUtils.LocalManager localManager,
        CxxClassInfo itf, Type implClass, boolean isConst) {
    final int nextIndex = localManager.getNextIndex();
    final CxxUtils.Local peer = localManager.getNext("__cxx_GOC" + nextIndex, Type.LONG_TYPE, 2);
    final CxxUtils.Local rslt = localManager.getNext("__cxx_GOC" + nextIndex + "_R", itf.mapperType, 1);
    final Label endL = new Label();
    final Label constructL = new Label();

    // Local variable start labels
    mv.visitLabel(peer.start);//from  www  . ja  v  a 2s.  com
    mv.visitLabel(rslt.start);

    // Save peer
    mv.visitVarInsn(LSTORE, peer.index);

    // CxxRuntime.get(peer)
    mv.visitVarInsn(LLOAD, peer.index);
    mv.visitMethodInsn(INVOKESTATIC, CxxSupport.CXX_RUNTIME.getInternalName(), "get",
            Type.getMethodDescriptor(CxxSupport.CXX_OBJECT_ITF, Type.LONG_TYPE), false);
    mv.visitInsn(DUP);
    mv.visitTypeInsn(INSTANCEOF, itf.mapperType.getInternalName());
    mv.visitJumpInsn(IFEQ, constructL);

    // Check const-nes
    mv.visitInsn(DUP);
    mv.visitTypeInsn(INSTANCEOF, CxxSupport.CXX_CONST_IMPL_ITF.getInternalName());
    mv.visitJumpInsn(isConst ? IFEQ : IFNE, constructL);

    // Store
    mv.visitTypeInsn(CHECKCAST, itf.mapperType.getInternalName());
    mv.visitVarInsn(ASTORE, rslt.index);
    mv.visitJumpInsn(GOTO, endL);

    // Construct
    mv.visitLabel(constructL);
    mv.visitInsn(POP);
    mv.visitTypeInsn(NEW, implClass.getInternalName());
    mv.visitInsn(DUP);
    mv.visitVarInsn(LLOAD, peer.index);
    mv.visitMethodInsn(INVOKESPECIAL, implClass.getInternalName(), "<init>", "(J)V", false);
    mv.visitVarInsn(ASTORE, rslt.index);

    // Join
    mv.visitLabel(endL);
    mv.visitVarInsn(ALOAD, rslt.index);

    // Local variable end labels
    mv.visitLabel(peer.end);
    mv.visitLabel(rslt.end);
}

From source file:org.nuclos.server.customcode.codegenerator.ClassDebugAdapter.java

License:Open Source License

private void insertDebugResolveMethod() {
    /*/*from   w w  w .  j a  v  a2  s  . c o m*/
      private String __resolve(String methodAndIndex) {
         if(methodAndIndex.equals("method1"))
      return "var1";
         if(methodAndIndex.equals("method2"))
      return "var2";
         [ ... ]
         if(methodAndIndex.equals("methodX"))
      return "varX";
         return "-";
      }
     */
    MethodVisitor mv = cv.visitMethod(ACC_PRIVATE + ACC_STATIC, "__resolve",
            "(Ljava/lang/String;)Ljava/lang/String;", null, null);
    mv.visitCode();
    Label l0 = new Label();
    mv.visitLabel(l0);
    for (String mapKey : varLookup.keySet()) {
        mv.visitVarInsn(ALOAD, 0);
        mv.visitLdcInsn(mapKey);
        mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z");
        Label l1 = new Label();
        mv.visitJumpInsn(IFEQ, l1);
        Label l2 = new Label();
        mv.visitLabel(l2);
        mv.visitLdcInsn(varLookup.get(mapKey));
        mv.visitInsn(ARETURN);
        mv.visitLabel(l1);
        mv.visitFrame(F_SAME, 0, null, 0, null);
    }
    mv.visitLdcInsn("-");
    mv.visitInsn(ARETURN);
    mv.visitMaxs(2, 2);
    mv.visitEnd();
}

From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java

License:Open Source License

/**
 * Add the <clinit> method. This initializes the static fields that have initializers.
 * @param classRep// ww  w .j av a  2s.c om
 * @param cv
 * @param initializeForAsserts
 * @throws JavaGenerationException
 */
private static void encodeClassInitializer(JavaClassRep classRep, ClassVisitor cv, boolean initializeForAsserts)
        throws JavaGenerationException {

    // Add initializers for the statically-initialized fields.
    final int nFields = classRep.getNFieldDeclarations();

    if (!classRep.hasInitializedStaticField() && !initializeForAsserts) {
        //we don't need to bother adding a static initializer if there are no static fields to initialize.
        //note that javac also has this optimization.
        return;
    }

    MethodVisitor mv = cv.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);

    // Start the method's code.
    mv.visitCode();

    final JavaTypeName classRepTypeName = classRep.getClassName();

    /*
     * If this class contains assert statements we need to initialize the static final synthetic boolean field
     * '$assertionsDisabled'.
     * This is done by loading the Class constant for the top level class. The method 'desiredAssertionStatus()'
     * is then invoked on this Class object and the returned value is used to initialize $assertionsDisabled. 
     */
    if (initializeForAsserts) {
        // Get the fully-qualified internal class  name.    
        final String className = classRepTypeName.getJVMInternalName();

        // Get the top level class name.
        String topLevelClassName = getTopLevelClassJVMInternalName(className);

        // Load the Class constant for the top level class
        mv.visitLdcInsn(Type.getType("L" + topLevelClassName + ";"));

        // Now that we have the Class constant for the top level class we invoke the method
        // desiredAssertionStatus on it and use the resulting value to initialize the static field $assertionsDisabled in this class.
        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Class", "desiredAssertionStatus", "()Z");
        Label l0 = new Label();
        mv.visitJumpInsn(Opcodes.IFNE, l0);
        mv.visitInsn(Opcodes.ICONST_1);
        Label l1 = new Label();
        mv.visitJumpInsn(Opcodes.GOTO, l1);
        mv.visitLabel(l0);
        mv.visitInsn(Opcodes.ICONST_0);
        mv.visitLabel(l1);
        mv.visitFieldInsn(Opcodes.PUTSTATIC, className, "$assertionsDisabled", "Z");
    }

    for (int i = 0; i < nFields; ++i) {

        JavaFieldDeclaration fieldDecl = classRep.getFieldDeclaration(i);
        JavaExpression initializer = fieldDecl.getInitializer();

        if (initializer != null && Modifier.isStatic(fieldDecl.getModifiers())) {

            GenerationContext context = new GenerationContext(new HashMap<String, JavaTypeName>(),
                    new HashMap<String, Integer>(), 0, mv, classRepTypeName);

            //evaluate the initializer
            encodeExpr(initializer, context);

            //do the assignment
            mv.visitFieldInsn(Opcodes.PUTSTATIC, classRep.getClassName().getJVMInternalName(),
                    fieldDecl.getFieldName(), fieldDecl.getFieldType().getJVMDescriptor());
        }
    }

    // return.
    mv.visitInsn(Opcodes.RETURN);

    //mark the end of the method with a call to visitMaxs
    mv.visitMaxs(0, 0);

    // End the method.
    mv.visitEnd();
}

From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java

License:Open Source License

private static boolean encodeIfThenElseStatement(JavaStatement.IfThenElseStatement iteStatement,
        GenerationContext context) throws JavaGenerationException {

    MethodVisitor mv = context.getMethodVisitor();

    JavaExpression conditionExpr = iteStatement.getCondition();
    JavaStatement thenStatement = iteStatement.getThenStatement();
    JavaStatement elseStatement = iteStatement.getElseStatement();

    if (conditionExpr instanceof JavaExpression.OperatorExpression) {

        //generate more efficient code in the case of if (boolean-valued-operator)...

        //This case exists to handle the special case where an operator occurs as the child of an if-then-else (or ternary operator)
        //conditional. For example, in the situation:
        ///*from w  w w  .j a v a2  s . com*/
        //if (x != null) {...} else {...}
        // 
        // we do not want to evaluate x != null to a boolean value, push that value on the stack,
        // and then test it prior to selecting the correct branch. Rather, we can combine the evaluation
        // and jump operations into a single step.

        JavaExpression.OperatorExpression operatorExpr = (JavaExpression.OperatorExpression) conditionExpr;
        JavaOperator operator = operatorExpr.getJavaOperator();

        if (operator.isLogicalOp() || operator.isRelationalOp()) {

            Label trueContinuation = new Label();
            context.addStatementJumpLabel(trueContinuation);

            Label falseContinuation = new Label();
            context.addStatementJumpLabel(falseContinuation);

            encodeBooleanValuedOperatorHelper(operatorExpr, context, trueContinuation, falseContinuation);
            return encodeThenStatementElseStatement(trueContinuation, falseContinuation, thenStatement,
                    elseStatement, context);
        }

        throw new JavaGenerationException(
                "Unrecognized boolean-valued conditional operator " + operator.getSymbol() + ".");
    }

    //encode the condition. It will be boolean valued.
    encodeExpr(iteStatement.getCondition(), context);

    //if false, jump to falseContinuation
    Label falseContinuation = new Label();
    mv.visitJumpInsn(Opcodes.IFEQ, falseContinuation);

    return encodeThenStatementElseStatement(null, falseContinuation, thenStatement, elseStatement, context);
}

From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java

License:Open Source License

private static boolean encodeThenStatementElseStatement(Label trueContinuation, Label falseContinuation,
        JavaStatement thenStatement, JavaStatement elseStatement, GenerationContext context)
        throws JavaGenerationException {

    MethodVisitor mv = context.getMethodVisitor();

    if (trueContinuation != null) {
        mv.visitLabel(trueContinuation);
    }/*from  w ww. j  a  v  a  2  s. c  o m*/

    //in general the "then" part will have its own inner scope, but we optimize this out in the case of ExpressionStatements which
    //can't introduce new variables.
    GenerationContext thenContext = (thenStatement instanceof JavaStatement.ExpressionStatement) ? context
            : new GenerationContext(context);

    boolean thenIsTerminating = encodeStatement(thenStatement, thenContext);
    context.addJumpReturnLabelInfo(thenContext);

    if (elseStatement.emptyStatement()) {
        //don't bother to encode the goto skipping over the else part if there is not else part.

        mv.visitLabel(falseContinuation);

        //the if-then-else is not terminating, because the else part, which is just {}, is not terminating
        return false;
    }

    Label label2 = null;
    if (!thenIsTerminating) {
        label2 = new Label();
        context.addStatementJumpLabel(label2);

        mv.visitJumpInsn(Opcodes.GOTO, label2);
    }

    mv.visitLabel(falseContinuation);

    //in general the "else" part will have its own inner scope, but we optimize this out in the case of ExpressionStatements which
    //can't introduce new variables.
    GenerationContext elseContext = (elseStatement instanceof JavaStatement.ExpressionStatement) ? context
            : new GenerationContext(context);
    boolean elseIsTerminating = encodeStatement(elseStatement, elseContext);
    context.addJumpReturnLabelInfo(elseContext);

    if (!thenIsTerminating) {
        mv.visitLabel(label2);
    }

    return thenIsTerminating && elseIsTerminating;
}

From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java

License:Open Source License

private static boolean encodeTryCatchStatement(JavaStatement.Block block, GenerationContext context)
        throws JavaGenerationException {

    MethodVisitor mv = context.getMethodVisitor();

    List<JavaExceptionHandler> exceptionHandlers = block.getExceptionHandlers();

    if (exceptionHandlers.isEmpty()) {
        throw new IllegalStateException();
    }//from  w  w w .  j av a  2 s  .c o  m

    // Spawn a child context for the try block.
    GenerationContext tryBlockContext = new GenerationContext(context);

    boolean isTerminating = false; // starts out false (for the case with no statements..)

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

    // Append the instructions comprising the block's component statements.
    int nStatements = block.getNBlockStatements();
    for (int i = 0; i < nStatements; i++) {
        JavaStatement blockStatement = block.getNthBlockStatement(i);

        // skip comments.
        if (blockStatement instanceof Comment) {
            continue;
        }

        // is terminating if the last statement is terminating. 
        isTerminating = encodeStatement(blockStatement, tryBlockContext);
        context.addJumpReturnLabelInfo(tryBlockContext);
    }

    // Add an instruction to jump to after the exception handlers, if the statement block isn't terminating.
    Label tryCatchEndLabel = new Label();
    context.addStatementJumpLabel(tryCatchEndLabel);
    if (!isTerminating) {
        mv.visitJumpInsn(Opcodes.GOTO, tryCatchEndLabel);
    }

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

    // Add exception handlers as necessary.      

    // Now set handlers to handle any exceptions.
    for (int i = 0, nExceptionHandlers = exceptionHandlers.size(); i < nExceptionHandlers; ++i) {

        JavaExceptionHandler eh = exceptionHandlers.get(i);

        JavaTypeName exceptionType = JavaTypeName.make(eh.getExceptionClass()); // exception class is a non-array reference type.  

        //encode the start of the catch block.
        Label catchLabel = new Label();
        mv.visitLabel(catchLabel);

        // Create a child context for the catch block.
        GenerationContext catchContext = new GenerationContext(context);

        // The thrown exception object will be the only item on the stack.  
        // Store it into a new local variable.
        String exceptionVarName = eh.getExceptionVarName();
        int exceptionVarIndex = catchContext.addLocalVar(exceptionVarName, exceptionType);
        mv.visitVarInsn(Opcodes.ASTORE, exceptionVarIndex);

        boolean catchIsTerminating = encodeStatement(eh.getHandlerCode(), catchContext);
        context.addJumpReturnLabelInfo(catchContext);

        if (!catchIsTerminating) {
            mv.visitJumpInsn(Opcodes.GOTO, tryCatchEndLabel);
        }

        // In the end, we're only terminating if all the catch blocks are terminating.
        isTerminating &= catchIsTerminating;

        //encode the try/catch block. This can be done in any order, any time after all labels passed as arguments have been visited,
        //  between visitCode() and visitMaxs().
        encodeTryCatchBlock(tryStartLabel, tryEndLabel, catchLabel, exceptionType, tryBlockContext);
    }

    //mark the end of the whole try/catch code
    mv.visitLabel(tryCatchEndLabel);

    return isTerminating;
}

From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java

License:Open Source License

private static boolean encodeUnconditionalLoop(JavaStatement.UnconditionalLoop ul, GenerationContext context)
        throws JavaGenerationException {

    //implemented as:
    //label label1:
    //{ body statements}
    //goto label1

    MethodVisitor mv = context.getMethodVisitor();
    Label label1 = new Label();
    mv.visitLabel(label1);/*w  w w.  ja va2s .  co  m*/

    context.addStatementJumpLabel(ul.getLabel(), label1);

    //the body defines a new scope.
    GenerationContext bodyContext = new GenerationContext(context);

    boolean bodyIsTerminating = encodeStatement(ul.getBody(), bodyContext);
    context.addJumpReturnLabelInfo(bodyContext);

    if (!bodyIsTerminating) {
        mv.visitJumpInsn(Opcodes.GOTO, label1);
    }

    return true;
}

From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java

License:Open Source License

/**
 * Encode a method invocation that is wrapped in a synchronized block.
 *   See Sun bug id #4414101 for a discussion of this generated code.
 * //from   ww  w  . j  a  v  a 2  s .c o m
 * @param smi - the SynchronizedMethodInvocation object.
 * @param context - the context of the code generation.
 * @return - true if the SynchronizedMethodInvocation is terminating.
 * @throws JavaGenerationException
 */
private static boolean encodeSynchronizedMethodInvocation(JavaStatement.SynchronizedMethodInvocation smi,
        GenerationContext context) throws JavaGenerationException {

    MethodVisitor mv = context.getMethodVisitor();

    // Get the JavaExpression for the object to synchronize on and generate the bytecode. 
    JavaExpression objectToSynchOn = smi.getSynchronizingObject();
    encodeExpr(objectToSynchOn, context);

    // The object to synchronize on is now on the stack.  Duplicate it, 
    // move one to storage as a local variable, and to MONITORENTER on the other. 
    mv.visitInsn(Opcodes.DUP);

    int mutexIndex = context.addLocalVar("$mutex", JavaTypeName.OBJECT);
    mv.visitVarInsn(Opcodes.ASTORE, mutexIndex);

    mv.visitInsn(Opcodes.MONITORENTER);

    // We need to wrap the method invocation in a try/catch block so 
    // the monitor can be exited properly if the method invocation throws
    // an exception.
    Label tryCatchStart = new Label();
    mv.visitLabel(tryCatchStart);

    // Note: if this is generalized to handle any synchronized statement (for example, a synchronized block), 
    //   then the scope of entries in the exception table here will have to be modified to exclude return instructions.
    //   See encodeTryCatchStatement() for how to do this.
    //   Here, the only statement in the try block is a single expressionStatement, which has no return instructions, 
    //     so we don't have to worry about handling this case.

    // Get the method invocation and generate the corresponding bytecode.
    MethodInvocation methodInvocation = smi.getMethodInvocation();
    encodeExpr(methodInvocation, context);

    // Load the mutex object back onto the stack and do MonitorExit.
    mv.visitVarInsn(Opcodes.ALOAD, mutexIndex);
    mv.visitInsn(Opcodes.MONITOREXIT);

    // Label the end of the try block around the method invocation.
    Label tryEnd = new Label();
    mv.visitLabel(tryEnd);

    // At this point we want to code an instruction to jump past the exception handling
    // code.
    Label tryCatchEnd = new Label();
    mv.visitJumpInsn(Opcodes.GOTO, tryCatchEnd);

    // Label the start of the exception handling code.
    Label catchStart = new Label();
    mv.visitLabel(catchStart);

    // The exception is on the stack.  Store it as a local.
    int exceptionIndex = context.addLocalVar("exception", JavaTypeName.OBJECT);
    mv.visitVarInsn(Opcodes.ASTORE, exceptionIndex);

    // Retrieve the mutex object and do MONITOREXIT.
    mv.visitVarInsn(Opcodes.ALOAD, mutexIndex);
    mv.visitInsn(Opcodes.MONITOREXIT);

    // Label the end of the exception handling code that deals with the monitor.
    Label exceptionMonitorExitEnd = new Label();
    mv.visitLabel(exceptionMonitorExitEnd);

    // Retrieve the exception and throw it.
    mv.visitVarInsn(Opcodes.ALOAD, exceptionIndex);
    mv.visitInsn(Opcodes.ATHROW);

    // Vist the label to mark the end of the try/catch.
    mv.visitLabel(tryCatchEnd);

    // Set up the try/catch block to catch exceptions thrown by the method invocation
    // and handle exiting the monitor.
    mv.visitTryCatchBlock(tryCatchStart, tryEnd, catchStart, null);

    // Set up a try catch block so that if an exception is thrown by trying to exit 
    // the monitor in the case of an exception from the method invocation we will keep trying to 
    // exit the monitor.
    mv.visitTryCatchBlock(catchStart, exceptionMonitorExitEnd, catchStart, null);

    return false;
}