Example usage for org.objectweb.asm Opcodes IFNE

List of usage examples for org.objectweb.asm Opcodes IFNE

Introduction

In this page you can find the example usage for org.objectweb.asm Opcodes IFNE.

Prototype

int IFNE

To view the source code for org.objectweb.asm Opcodes IFNE.

Click Source Link

Usage

From source file:com.github.malamut2.low.AllocationMethodAdapter.java

License:Apache License

void calculateArrayLengthAndDispatch(String typeName, int dimCount) {
    // Since the dimensions of the array are not known at instrumentation
    // time, we take the created multi-dimensional array and peel off nesting
    // levels from the left.  For each nesting layer we probe the array length
    // and accumulate a partial product which we can then feed the recording
    // function./*  w  w w. j  a v a  2  s  .c  o m*/

    // below we note the partial product of dimensions 1 to X-1 as productToX
    // (so productTo1 == 1 == no dimensions yet).  We denote by aref0 the
    // array reference at the current nesting level (the containing aref's [0]
    // element).  If we hit a level whose arraylength is 0 there's no point
    // continuing so we shortcut out.
    Label zeroDimension = new Label();
    super.visitInsn(Opcodes.DUP); // -> stack: ... origaref aref0
    super.visitLdcInsn(1); // -> stack: ... origaref aref0 productTo1
    for (int i = 0; i < dimCount; ++i) {
        // pre: stack: ... origaref aref0 productToI
        super.visitInsn(Opcodes.SWAP); // -> stack: ... origaref productToI aref
        super.visitInsn(Opcodes.DUP_X1);
        // -> stack: ... origaref aref0 productToI aref
        super.visitInsn(Opcodes.ARRAYLENGTH);
        // -> stack: ... origaref aref0 productToI dimI

        Label nonZeroDimension = new Label();
        super.visitInsn(Opcodes.DUP);
        // -> stack: ... origaref aref0 productToI dimI dimI
        super.visitJumpInsn(Opcodes.IFNE, nonZeroDimension);
        // -> stack: ... origaref aref0 productToI dimI
        super.visitInsn(Opcodes.POP);
        // -> stack: ... origaref aref0 productToI
        super.visitJumpInsn(Opcodes.GOTO, zeroDimension);
        super.visitLabel(nonZeroDimension);
        // -> stack: ... origaref aref0 productToI max(dimI,1)

        super.visitInsn(Opcodes.IMUL);
        // -> stack: ... origaref aref0 productTo{I+1}
        if (i < dimCount - 1) {
            super.visitInsn(Opcodes.SWAP);
            // -> stack: ... origaref productTo{I+1} aref0
            super.visitInsn(Opcodes.ICONST_0);
            // -> stack: ... origaref productTo{I+1} aref0 0
            super.visitInsn(Opcodes.AALOAD);
            // -> stack: ... origaref productTo{I+1} aref0'
            super.visitInsn(Opcodes.SWAP);
        }
        // post: stack: ... origaref aref0 productTo{I+1}
    }
    super.visitLabel(zeroDimension);

    super.visitInsn(Opcodes.SWAP); // -> stack: ... origaref product aref0
    super.visitInsn(Opcodes.POP); // -> stack: ... origaref product
    super.visitInsn(Opcodes.SWAP); // -> stack: ... product origaref
    invokeRecordAllocation(typeName);
}

From source file:com.google.devtools.build.android.desugar.BytecodeTypeInference.java

License:Open Source License

@Override
public void visitJumpInsn(int opcode, Label label) {
    switch (opcode) {
    case Opcodes.IFEQ:
    case Opcodes.IFNE:
    case Opcodes.IFLT:
    case Opcodes.IFGE:
    case Opcodes.IFGT:
    case Opcodes.IFLE:
        pop();//from   w  w  w . ja va 2 s  . com
        break;
    case Opcodes.IF_ICMPEQ:
    case Opcodes.IF_ICMPNE:
    case Opcodes.IF_ICMPLT:
    case Opcodes.IF_ICMPGE:
    case Opcodes.IF_ICMPGT:
    case Opcodes.IF_ICMPLE:
    case Opcodes.IF_ACMPEQ:
    case Opcodes.IF_ACMPNE:
        pop(2);
        break;
    case Opcodes.GOTO:
        break;
    case Opcodes.JSR:
        throw new RuntimeException("The JSR instruction is not supported.");
    case Opcodes.IFNULL:
    case Opcodes.IFNONNULL:
        pop(1);
        break;
    default:
        throw new RuntimeException("Unhandled opcode " + opcode);
    }
    super.visitJumpInsn(opcode, label);
}

From source file:com.google.monitoring.runtime.instrumentation.adapters.AllocationMethodAdapter.java

License:Apache License

private void pushProductOfIntArrayOnStack() {
    final Label beginScopeLabel = new Label();
    final Label endScopeLabel = new Label();

    final int dimsArrayIndex = newLocal("[I", beginScopeLabel, endScopeLabel);
    final int counterIndex = newLocal("I", beginScopeLabel, endScopeLabel);
    final int productIndex = newLocal("I", beginScopeLabel, endScopeLabel);
    final Label loopLabel = new Label();
    final Label endLabel = new Label();

    super.visitLabel(beginScopeLabel);

    // stack: ... intArray
    super.visitVarInsn(Opcodes.ASTORE, dimsArrayIndex);
    // -> stack: ...

    // counter = 0
    super.visitInsn(Opcodes.ICONST_0);
    super.visitVarInsn(Opcodes.ISTORE, counterIndex);
    // product = 1
    super.visitInsn(Opcodes.ICONST_1);
    super.visitVarInsn(Opcodes.ISTORE, productIndex);
    // loop:/* w  ww  .  ja  va2s .  com*/
    super.visitLabel(loopLabel);
    // if index >= arraylength goto end:
    super.visitVarInsn(Opcodes.ILOAD, counterIndex);
    super.visitVarInsn(Opcodes.ALOAD, dimsArrayIndex);
    super.visitInsn(Opcodes.ARRAYLENGTH);
    super.visitJumpInsn(Opcodes.IF_ICMPGE, endLabel);
    // product = product * max(array[counter],1)
    super.visitVarInsn(Opcodes.ALOAD, dimsArrayIndex);
    super.visitVarInsn(Opcodes.ILOAD, counterIndex);
    super.visitInsn(Opcodes.IALOAD);
    super.visitInsn(Opcodes.DUP);
    final Label nonZeroDimension = new Label();
    super.visitJumpInsn(Opcodes.IFNE, nonZeroDimension);
    super.visitInsn(Opcodes.POP);
    super.visitInsn(Opcodes.ICONST_1);
    super.visitLabel(nonZeroDimension);
    super.visitVarInsn(Opcodes.ILOAD, productIndex);
    super.visitInsn(Opcodes.IMUL); // if overflow happens it happens.
    super.visitVarInsn(Opcodes.ISTORE, productIndex);
    // iinc counter 1
    super.visitIincInsn(counterIndex, 1);
    // goto loop
    super.visitJumpInsn(Opcodes.GOTO, loopLabel);
    // end:
    super.visitLabel(endLabel);
    // re-push dimensions array
    super.visitVarInsn(Opcodes.ALOAD, dimsArrayIndex);
    // push product
    super.visitVarInsn(Opcodes.ILOAD, productIndex);

    super.visitLabel(endScopeLabel);
}

From source file:com.google.monitoring.runtime.instrumentation.adapters.AllocationMethodAdapter.java

License:Apache License

void calculateArrayLengthAndDispatch(final String typeName, final int dimCount) {
    // Since the dimensions of the array are not known at instrumentation
    // time, we take the created multi-dimensional array and peel off nesting
    // levels from the left.  For each nesting layer we probe the array length
    // and accumulate a partial product which we can then feed the recording
    // function./*  w ww  .j a v a2s .  c  om*/

    // below we note the partial product of dimensions 1 to X-1 as productToX
    // (so productTo1 == 1 == no dimensions yet).  We denote by aref0 the
    // array reference at the current nesting level (the containing aref's [0]
    // element).  If we hit a level whose arraylength is 0 there's no point
    // continuing so we shortcut out.
    final Label zeroDimension = new Label();
    super.visitInsn(Opcodes.DUP); // -> stack: ... origaref aref0
    super.visitLdcInsn(1); // -> stack: ... origaref aref0 productTo1
    for (int i = 0; i < dimCount; ++i) {
        // pre: stack: ... origaref aref0 productToI
        super.visitInsn(Opcodes.SWAP); // -> stack: ... origaref productToI aref
        super.visitInsn(Opcodes.DUP_X1);
        // -> stack: ... origaref aref0 productToI aref
        super.visitInsn(Opcodes.ARRAYLENGTH);
        // -> stack: ... origaref aref0 productToI dimI

        final Label nonZeroDimension = new Label();
        super.visitInsn(Opcodes.DUP);
        // -> stack: ... origaref aref0 productToI dimI dimI
        super.visitJumpInsn(Opcodes.IFNE, nonZeroDimension);
        // -> stack: ... origaref aref0 productToI dimI
        super.visitInsn(Opcodes.POP);
        // -> stack: ... origaref aref0 productToI
        super.visitJumpInsn(Opcodes.GOTO, zeroDimension);
        super.visitLabel(nonZeroDimension);
        // -> stack: ... origaref aref0 productToI max(dimI,1)

        super.visitInsn(Opcodes.IMUL);
        // -> stack: ... origaref aref0 productTo{I+1}
        if (i < dimCount - 1) {
            super.visitInsn(Opcodes.SWAP);
            // -> stack: ... origaref productTo{I+1} aref0
            super.visitInsn(Opcodes.ICONST_0);
            // -> stack: ... origaref productTo{I+1} aref0 0
            super.visitInsn(Opcodes.AALOAD);
            // -> stack: ... origaref productTo{I+1} aref0'
            super.visitInsn(Opcodes.SWAP);
        }
        // post: stack: ... origaref aref0 productTo{I+1}
    }
    super.visitLabel(zeroDimension);

    super.visitInsn(Opcodes.SWAP); // -> stack: ... origaref product aref0
    super.visitInsn(Opcodes.POP); // -> stack: ... origaref product
    super.visitInsn(Opcodes.SWAP); // -> stack: ... product origaref
    invokeRecordAllocation(typeName);
}

From source file:com.google.template.soy.jbcsrc.BytecodeUtils.java

License:Apache License

private static void checkIntComparisonOpcode(Type comparisonType, int opcode) {
    switch (opcode) {
    case Opcodes.IFEQ:
    case Opcodes.IFNE:
        return;//from  w  ww .  j  av  a2 s  . c om
    case Opcodes.IFGT:
    case Opcodes.IFGE:
    case Opcodes.IFLT:
    case Opcodes.IFLE:
        if (comparisonType.getSort() == Type.ARRAY || comparisonType.getSort() == Type.OBJECT) {
            throw new IllegalArgumentException(
                    "Type: " + comparisonType + " cannot be compared via " + Printer.OPCODES[opcode]);
        }
        return;
    }
    throw new IllegalArgumentException("Unsupported opcode for comparison operation: " + opcode);
}

From source file:com.google.template.soy.jbcsrc.BytecodeUtils.java

License:Apache License

/**
 * Returns an expression that evaluates to the logical negation of the given boolean valued 
 * expression.//w  w w . j a v  a  2 s .co m
 */
static Expression logicalNot(final Expression baseExpr) {
    baseExpr.checkAssignableTo(Type.BOOLEAN_TYPE);
    checkArgument(baseExpr.resultType().equals(Type.BOOLEAN_TYPE), "not a boolean expression");
    return new Expression(Type.BOOLEAN_TYPE, baseExpr.features()) {
        @Override
        void doGen(CodeBuilder mv) {
            baseExpr.gen(mv);
            // Surprisingly, java bytecode uses a branch (instead of 'xor 1' or something) to implement
            // this. This is most likely useful for allowing true to be represented by any non-zero
            // number.
            Label ifTrue = mv.newLabel();
            Label end = mv.newLabel();
            mv.ifZCmp(Opcodes.IFNE, ifTrue); // if not 0 goto ifTrue
            mv.pushBoolean(true);
            mv.goTo(end);
            mv.mark(ifTrue);
            mv.pushBoolean(false);
            mv.mark(end);
        }
    };
}

From source file:com.google.template.soy.jbcsrc.BytecodeUtils.java

License:Apache License

private static Expression doShortCircuitingLogicalOperator(
        final ImmutableList<? extends Expression> expressions, final boolean isOrOperator) {
    checkArgument(!expressions.isEmpty());
    for (Expression expr : expressions) {
        expr.checkAssignableTo(Type.BOOLEAN_TYPE);
    }/*from w ww .j ava  2  s .co  m*/
    if (expressions.size() == 1) {
        return expressions.get(0);
    }

    return new Expression(Type.BOOLEAN_TYPE,
            Expression.areAllCheap(expressions) ? Features.of(Feature.CHEAP) : Features.of()) {
        @Override
        void doGen(CodeBuilder adapter) {
            Label end = new Label();
            Label shortCircuit = new Label();
            for (int i = 0; i < expressions.size(); i++) {
                Expression expr = expressions.get(i);
                expr.gen(adapter);
                if (i == expressions.size() - 1) {
                    // if we are the last one, just goto end. Whatever the result of the last expression is
                    // determines the result of the whole expression (when all prior tests fail).
                    adapter.goTo(end);
                } else {
                    adapter.ifZCmp(isOrOperator ? Opcodes.IFNE : Opcodes.IFEQ, shortCircuit);
                }
            }
            adapter.mark(shortCircuit);
            adapter.pushBoolean(isOrOperator); // default for || is true && is false
            adapter.mark(end);
        }
    };
}

From source file:com.google.template.soy.jbcsrc.BytecodeUtilsTest.java

License:Apache License

public void testCompareLongs() {
    Expression one = constant(1L);
    Expression two = constant(2L);
    assertThatExpression(compare(Opcodes.IFNE, one, two)).evaluatesTo(true);
    assertThatExpression(compare(Opcodes.IFLT, one, two)).evaluatesTo(true);
    assertThatExpression(compare(Opcodes.IFLE, one, two)).evaluatesTo(true);
    assertThatExpression(compare(Opcodes.IFGT, one, two)).evaluatesTo(false);
    assertThatExpression(compare(Opcodes.IFGE, one, two)).evaluatesTo(false);
    assertThatExpression(compare(Opcodes.IFEQ, one, two)).evaluatesTo(false);

    assertThatExpression(compare(Opcodes.IFLE, two, two)).evaluatesTo(true);
    assertThatExpression(compare(Opcodes.IFGE, two, two)).evaluatesTo(true);
}

From source file:com.google.template.soy.jbcsrc.BytecodeUtilsTest.java

License:Apache License

public void testCompareDoubles() {
    Expression one = constant(1D);
    Expression two = constant(2D);
    Expression nan = constant(Double.NaN);

    assertThatExpression(compare(Opcodes.IFNE, one, two)).evaluatesTo(true);
    assertThatExpression(compare(Opcodes.IFLT, one, two)).evaluatesTo(true);
    assertThatExpression(compare(Opcodes.IFLE, one, two)).evaluatesTo(true);
    assertThatExpression(compare(Opcodes.IFGT, one, two)).evaluatesTo(false);
    assertThatExpression(compare(Opcodes.IFGE, one, two)).evaluatesTo(false);
    assertThatExpression(compare(Opcodes.IFEQ, one, two)).evaluatesTo(false);

    assertThatExpression(compare(Opcodes.IFLE, two, two)).evaluatesTo(true);
    assertThatExpression(compare(Opcodes.IFGE, two, two)).evaluatesTo(true);

    // There are special cases for NaN that we need to test, basically every expression involving
    // NaN should evaluate to false with the exception of NaN != * which always == true
    assertThatExpression(compare(Opcodes.IFNE, nan, two)).evaluatesTo(true);
    assertThatExpression(compare(Opcodes.IFNE, two, nan)).evaluatesTo(true);
    assertThatExpression(compare(Opcodes.IFNE, nan, nan)).evaluatesTo(true);

    assertThatExpression(compare(Opcodes.IFEQ, nan, two)).evaluatesTo(false);
    assertThatExpression(compare(Opcodes.IFEQ, two, nan)).evaluatesTo(false);
    assertThatExpression(compare(Opcodes.IFEQ, nan, nan)).evaluatesTo(false);

    assertThatExpression(compare(Opcodes.IFLE, nan, two)).evaluatesTo(false);
    assertThatExpression(compare(Opcodes.IFLE, two, nan)).evaluatesTo(false);
    assertThatExpression(compare(Opcodes.IFLT, nan, two)).evaluatesTo(false);
    assertThatExpression(compare(Opcodes.IFLT, two, nan)).evaluatesTo(false);
    assertThatExpression(compare(Opcodes.IFGE, nan, two)).evaluatesTo(false);
    assertThatExpression(compare(Opcodes.IFGE, two, nan)).evaluatesTo(false);
    assertThatExpression(compare(Opcodes.IFGT, nan, two)).evaluatesTo(false);
    assertThatExpression(compare(Opcodes.IFGT, two, nan)).evaluatesTo(false);
}

From source file:com.google.template.soy.jbcsrc.DetachState.java

License:Apache License

/**
 * Generate detach logic for calls./* w w  w  . j  av  a  2 s.  c o  m*/
 * 
 * <p>Calls are a little different due to a desire to minimize the cost of detaches. We assume 
 * that if a given call site detaches once, it is more likely to detach multiple times. So we
 * generate code that looks like:   <pre>{@code
 * 
 * RenderResult initialResult = template.render(appendable, renderContext);
 * if (!initialResult.isDone()) {
 *   // save all fields
 *   state = REATTACH_RENDER;
 *   return initialResult;
 * } else {
 *   goto END;
 * }
 * REATTACH_RENDER:
 * // restore nothing!
 * RenderResult secondResult = template.render(appendable, renderContext);
 * if (!secondResult.isDone()) {
 *   // saveFields
 *   state = REATTACH_RENDER;
 *   return secondResult;
 * } else {
 *   // restore all fields
 *   goto END;
 * }
 * END:
 * }</pre>
 * 
 * <p>With this technique we save re-running the save-restore logic for multiple detaches from
 * the same call site.  This should be especially useful for top level templates.
 * 
 * @param callRender an Expression that can generate code to call the render method, should be
 *     safe to generate more than once. 
 */
Statement detachForRender(final Expression callRender) {
    checkArgument(callRender.resultType().equals(RENDER_RESULT_TYPE));
    final Label reattachRender = new Label();
    final SaveRestoreState saveRestoreState = variables.saveRestoreState();
    // We pass NULL statement for the restore logic since we handle that ourselves below
    int state = addState(reattachRender, Statement.NULL_STATEMENT);
    final Statement saveState = stateField.putInstanceField(thisExpr, BytecodeUtils.constant(state));
    return new Statement() {
        @Override
        void doGen(CodeBuilder adapter) {
            // Legend: RR = RenderResult, Z = boolean
            callRender.gen(adapter); // Stack: RR
            adapter.dup(); // Stack: RR, RR
            MethodRef.RENDER_RESULT_IS_DONE.invokeUnchecked(adapter); // Stack: RR, Z
            // if isDone goto Done
            Label end = new Label();
            adapter.ifZCmp(Opcodes.IFNE, end); // Stack: RR

            saveRestoreState.save().gen(adapter);
            saveState.gen(adapter);
            adapter.returnValue();

            adapter.mark(reattachRender);
            callRender.gen(adapter); // Stack: RR
            adapter.dup(); // Stack: RR, RR
            MethodRef.RENDER_RESULT_IS_DONE.invokeUnchecked(adapter); // Stack: RR, Z
            // if isDone goto restore
            Label restore = new Label();
            adapter.ifZCmp(Opcodes.IFNE, restore); // Stack: RR
            // no need to save or restore anything
            adapter.returnValue();
            adapter.mark(restore); // Stack: RR
            saveRestoreState.restore().gen(adapter);
            adapter.mark(end); // Stack: RR
            adapter.pop(); // Stack:
        }
    };
}