Example usage for org.objectweb.asm MethodVisitor visitLabel

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

Introduction

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

Prototype

public void visitLabel(final Label label) 

Source Link

Document

Visits a label.

Usage

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

License:Apache License

private void evaluateLogicalOrExpression(BinaryExpression expression) {
    MethodVisitor mv = controller.getMethodVisitor();
    AsmClassGenerator acg = controller.getAcg();
    OperandStack operandStack = controller.getOperandStack();

    Label end = new Label();

    expression.getLeftExpression().visit(acg);
    operandStack.doGroovyCast(ClassHelper.boolean_TYPE);
    Label trueCase = operandStack.jump(IFNE);

    expression.getRightExpression().visit(acg);
    operandStack.doGroovyCast(ClassHelper.boolean_TYPE);
    Label falseCase = operandStack.jump(IFEQ);

    mv.visitLabel(trueCase);
    ConstantExpression.PRIM_TRUE.visit(acg);
    operandStack.jump(GOTO, end);/*  w w  w  . j a v a 2s  .com*/

    mv.visitLabel(falseCase);
    ConstantExpression.PRIM_FALSE.visit(acg);

    mv.visitLabel(end);
}

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

License:Apache License

private void evaluateElvisOperatorExpression(ElvisOperatorExpression expression) {
    MethodVisitor mv = controller.getMethodVisitor();
    CompileStack compileStack = controller.getCompileStack();
    OperandStack operandStack = controller.getOperandStack();
    TypeChooser typeChooser = controller.getTypeChooser();

    Expression boolPart = expression.getBooleanExpression().getExpression();
    Expression falsePart = expression.getFalseExpression();

    ClassNode truePartType = typeChooser.resolveType(boolPart, controller.getClassNode());
    ClassNode falsePartType = typeChooser.resolveType(falsePart, controller.getClassNode());
    ClassNode common = WideningCategories.lowestUpperBound(truePartType, falsePartType);

    // x?:y is equal to x?x:y, which evals to 
    //      var t=x; boolean(t)?t:y
    // first we load x, dup it, convert the dupped to boolean, then 
    // jump depending on the value. For true we are done, for false we
    // have to load y, thus we first remove x and then load y. 
    // But since x and y may have different stack lengths, this cannot work
    // Thus we have to have to do the following:
    // Be X the type of x, Y the type of y and S the common supertype of 
    // X and Y, then we have to see x?:y as  
    //      var t=x;boolean(t)?S(t):S(y)
    // so we load x, dup it, store the value in a local variable (t), then 
    // do boolean conversion. In the true part load t and cast it to S, 
    // in the false part load y and cast y to S 

    // load x, dup it, store one in $t and cast the remaining one to boolean
    int mark = operandStack.getStackLength();
    boolPart.visit(controller.getAcg());
    operandStack.dup();//from w w w  .  j  av a2s .c om
    if (ClassHelper.isPrimitiveType(truePartType)
            && !ClassHelper.isPrimitiveType(operandStack.getTopOperand())) {
        truePartType = ClassHelper.getWrapper(truePartType);
    }
    int retValueId = compileStack.defineTemporaryVariable("$t", truePartType, true);
    operandStack.castToBool(mark, true);

    Label l0 = operandStack.jump(IFEQ);
    // true part: load $t and cast to S
    operandStack.load(truePartType, retValueId);
    operandStack.doGroovyCast(common);
    Label l1 = new Label();
    mv.visitJumpInsn(GOTO, l1);

    // false part: load false expression and cast to S
    mv.visitLabel(l0);
    falsePart.visit(controller.getAcg());
    operandStack.doGroovyCast(common);

    // finish and cleanup
    mv.visitLabel(l1);
    compileStack.removeVar(retValueId);
    controller.getOperandStack().replace(common, 2);

}

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

License:Apache License

private void evaluateNormalTernary(TernaryExpression expression) {
    MethodVisitor mv = controller.getMethodVisitor();
    OperandStack operandStack = controller.getOperandStack();
    TypeChooser typeChooser = controller.getTypeChooser();

    Expression boolPart = expression.getBooleanExpression();
    Expression truePart = expression.getTrueExpression();
    Expression falsePart = expression.getFalseExpression();

    ClassNode truePartType = typeChooser.resolveType(truePart, controller.getClassNode());
    ClassNode falsePartType = typeChooser.resolveType(falsePart, controller.getClassNode());
    ClassNode common = WideningCategories.lowestUpperBound(truePartType, falsePartType);

    // we compile b?x:y as 
    //      boolean(b)?S(x):S(y), S = common super type of x,y
    // so we load b, do boolean conversion. 
    // In the true part load x and cast it to S, 
    // in the false part load y and cast y to S 

    // load b and convert to boolean
    int mark = operandStack.getStackLength();
    boolPart.visit(controller.getAcg());
    operandStack.castToBool(mark, true);

    Label l0 = operandStack.jump(IFEQ);
    // true part: load x and cast to S
    truePart.visit(controller.getAcg());
    operandStack.doGroovyCast(common);/*ww w . ja  v a  2 s .  c om*/
    Label l1 = new Label();
    mv.visitJumpInsn(GOTO, l1);

    // false part: load y and cast to S
    mv.visitLabel(l0);
    falsePart.visit(controller.getAcg());
    operandStack.doGroovyCast(common);

    // finish and cleanup
    mv.visitLabel(l1);
    controller.getOperandStack().replace(common, 2);

}

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

License:Apache License

/**
 * writes some int standard operations for compares
 * @param type the token type//  w  ww  .j av  a  2  s. c o  m
 * @return true if a successful std operator write
 */
protected boolean writeStdCompare(int type, boolean simulate) {
    type = type - COMPARE_NOT_EQUAL;
    // look if really compare
    if (type < 0 || type > 7)
        return false;

    if (!simulate) {
        MethodVisitor mv = controller.getMethodVisitor();
        OperandStack operandStack = controller.getOperandStack();
        // operands are on the stack already
        int bytecode = stdCompareCodes[type];
        mv.visitInsn(getCompareCode());
        Label l1 = new Label();
        mv.visitJumpInsn(bytecode, l1);
        mv.visitInsn(ICONST_1);
        Label l2 = new Label();
        mv.visitJumpInsn(GOTO, l2);
        mv.visitLabel(l1);
        mv.visitInsn(ICONST_0);
        mv.visitLabel(l2);
        operandStack.replace(ClassHelper.boolean_TYPE, 2);
    }
    return true;
}

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

License:Apache License

protected boolean writeSpaceship(int type, boolean simulate) {
    if (type != COMPARE_TO)
        return false;
    /*  //from w  w  w.  ja  v a 2  s.  com
       we will actually do
             
      (x < y) ? -1 : ((x == y) ? 0 : 1)
      which is the essence of what the call with Number would do
      this compiles to something along
              
      <x>
      <y>
      LCMP
      IFGE L1
      ICONST_M1
      GOTO L2
      L1
      <x>
      <y>
      LCMP
      IFNE L3
      ICONST_0
      GOTO L2
      L3
      ICONST_1
      L2
              
      since the operators are already on the stack and we don't want
      to load them again, we will instead duplicate them. This will
      require some pop actions in the branches!
              
      DUP4          (operands: L1L2L1L2)
      LCMP          
      IFGE L1       (operands: L1L2)
      ICONST_M1     (operands: L1L2I)
      GOTO L2
      L1
      -----         (operands: L1L2)
      LCMP
      IFNE L3       (operands: -)
      ICONST_0      (operands: I)
      GOTO L2
      L3
      - jump from L1 branch to here (operands: -)
      ICONST_1      (operands: I)
      L2  
      - if jump from GOTO L2 we have LLI, but need only I
      - if from L3 branch we get only I
              
      this means we have to pop of LL before loading -1
              
      since there is no DUP4 we have to do this:
    DUP2_X1
    POP2
    DUP2_X1
    DUP2_X1
    POP2
    DUP2_X1          
    */
    if (!simulate) {
        MethodVisitor mv = controller.getMethodVisitor();
        // duplicate arguments
        doubleTwoOperands(mv);

        Label l1 = new Label();
        mv.visitInsn(getCompareCode());
        mv.visitJumpInsn(IFGE, l1);
        // no jump, so -1, need to pop off surplus LL
        removeTwoOperands(mv);
        mv.visitInsn(ICONST_M1);
        Label l2 = new Label();
        mv.visitJumpInsn(GOTO, l2);

        mv.visitLabel(l1);
        Label l3 = new Label();
        mv.visitInsn(getCompareCode());
        mv.visitJumpInsn(IFNE, l3);
        mv.visitInsn(ICONST_0);
        mv.visitJumpInsn(GOTO, l2);

        mv.visitLabel(l3);
        mv.visitInsn(ICONST_1);

        controller.getOperandStack().replace(ClassHelper.int_TYPE, 2);
    }
    return true;
}

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

License:Apache License

/**
 * writes a std compare. This involves the tokens IF_ICMPEQ, IF_ICMPNE, 
 * IF_ICMPEQ, IF_ICMPNE, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE and IF_ICMPLT
 * @param type the token type/*from  w  w  w .j  a va2  s .c  om*/
 * @return true if a successful std compare write
 */
protected boolean writeStdCompare(int type, boolean simulate) {
    type = type - COMPARE_NOT_EQUAL;
    // look if really compare
    if (type < 0 || type > 7)
        return false;

    if (!simulate) {
        MethodVisitor mv = getController().getMethodVisitor();
        OperandStack operandStack = getController().getOperandStack();
        // operands are on the stack already
        int bytecode = stdCompareCodes[type];
        Label l1 = new Label();
        mv.visitJumpInsn(bytecode, l1);
        mv.visitInsn(ICONST_1);
        Label l2 = new Label();
        mv.visitJumpInsn(GOTO, l2);
        mv.visitLabel(l1);
        mv.visitInsn(ICONST_0);
        mv.visitLabel(l2);
        operandStack.replace(ClassHelper.boolean_TYPE, 2);
    }
    return true;
}

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

License:Apache License

/**
 * writes the spaceship operator, type should be COMPARE_TO
 * @param type the token type//from ww w  .  j av a  2s.  co  m
 * @return true if a successful spaceship operator write
 */
protected boolean writeSpaceship(int type, boolean simulate) {
    if (type != COMPARE_TO)
        return false;
    /*  
       we will actually do
             
      (x < y) ? -1 : ((x == y) ? 0 : 1)
      which is the essence of what the call with Integers would do
      this compiles to something along
              
      <x>
      <y>
      IF_ICMPGE L1
      ICONST_M1
      GOTO L2
      L1
      <x>
      <y>
      IF_ICMPNE L3
      ICONST_0
      GOTO L2
      L3
      ICONST_1
      L2
              
      since the operators are already on the stack and we don't want
      to load them again, we will instead duplicate them. This will
      require some pop actions in the branches!
              
      DUP2          (operands: IIII) 
      IF_ICMPGE L1  (operands: II)
      ICONST_M1     (operands: III)
      GOTO L2
      L1
      -----         (operands: II)
      IF_ICMPNE L3  (operands: -)
      ICONST_0      (operands: I)
      GOTO L2
      L3
      - jump from L1 branch to here (operands: -)
      ICONST_1      (operands: I)
      L2  
      - if jump from GOTO L2 we have III, but need only I
      - if from L3 branch we get only I
              
      this means we have to pop of II before loading -1
              
    */
    if (!simulate) {
        MethodVisitor mv = getController().getMethodVisitor();
        // duplicate int arguments
        mv.visitInsn(DUP2);

        Label l1 = new Label();
        mv.visitJumpInsn(IF_ICMPGE, l1);
        // no jump, so -1, need to pop off surplus II
        mv.visitInsn(POP2);
        mv.visitInsn(ICONST_M1);
        Label l2 = new Label();
        mv.visitJumpInsn(GOTO, l2);

        mv.visitLabel(l1);
        Label l3 = new Label();
        mv.visitJumpInsn(IF_ICMPNE, l3);
        mv.visitInsn(ICONST_0);
        mv.visitJumpInsn(GOTO, l2);

        mv.visitLabel(l3);
        mv.visitInsn(ICONST_1);

        getController().getOperandStack().replace(ClassHelper.int_TYPE, 2);
    }
    return true;
}

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

License:Apache License

/**
 * Negate a boolean on stack./*from   w  w w.  ja  va 2s . c om*/
 */
public static void negateBoolean(MethodVisitor mv) {
    // code to negate the primitive boolean
    Label endLabel = new Label();
    Label falseLabel = new Label();
    mv.visitJumpInsn(IFNE, falseLabel);
    mv.visitInsn(ICONST_1);
    mv.visitJumpInsn(GOTO, endLabel);
    mv.visitLabel(falseLabel);
    mv.visitInsn(ICONST_0);
    mv.visitLabel(endLabel);
}

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

License:Apache License

/**
 * Converts a primitive type to boolean.
 *
 * @param mv method visitor//  w  w  w .ja  v a2s .c o m
 * @param type primitive type to convert
 */
public static void convertPrimitiveToBoolean(MethodVisitor mv, ClassNode type) {
    if (type == boolean_TYPE) {
        return;
    }
    // Special handling is done for floating point types in order to
    // handle checking for 0 or NaN values.
    if (type == double_TYPE) {
        convertDoubleToBoolean(mv);
        return;
    } else if (type == float_TYPE) {
        convertFloatToBoolean(mv);
        return;
    }
    Label trueLabel = new Label();
    Label falseLabel = new Label();
    // Convert long to int for IFEQ comparison using LCMP
    if (type == long_TYPE) {
        mv.visitInsn(LCONST_0);
        mv.visitInsn(LCMP);
    }
    // This handles byte, short, char and int
    mv.visitJumpInsn(IFEQ, falseLabel);
    mv.visitInsn(ICONST_1);
    mv.visitJumpInsn(GOTO, trueLabel);
    mv.visitLabel(falseLabel);
    mv.visitInsn(ICONST_0);
    mv.visitLabel(trueLabel);
}

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

License:Apache License

private static void convertDoubleToBoolean(MethodVisitor mv) {
    Label trueLabel = new Label();
    Label falseLabel = new Label();
    Label falseLabelWithPop = new Label();
    mv.visitInsn(DUP2); // will need the extra for isNaN call if required
    mv.visitInsn(DCONST_0);// w w  w.j ava 2 s  . co m
    mv.visitInsn(DCMPL);
    mv.visitJumpInsn(IFEQ, falseLabelWithPop);
    mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "isNaN", "(D)Z", false);
    mv.visitJumpInsn(IFNE, falseLabel);
    mv.visitInsn(ICONST_1);
    mv.visitJumpInsn(GOTO, trueLabel);
    mv.visitLabel(falseLabelWithPop);
    mv.visitInsn(POP2);
    mv.visitLabel(falseLabel);
    mv.visitInsn(ICONST_0);
    mv.visitLabel(trueLabel);
}