List of usage examples for org.objectweb.asm MethodVisitor visitLabel
public void visitLabel(final Label label)
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); }