Example usage for org.objectweb.asm Opcodes SWAP

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

Introduction

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

Prototype

int SWAP

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

Click Source Link

Usage

From source file:org.jboss.byteman.rule.expression.FieldExpression.java

License:Open Source License

@Override
public void compileAssign(MethodVisitor mv, CompileContext compileContext) throws CompileException {
    if (indirectStatic != null) {
        // this is just wrapping a static field expression so compile it
        indirectStatic.compileAssign(mv, compileContext);
    } else {/* ww  w .  ja  v  a  2s . c om*/
        // make sure we are at the right source line
        compileContext.notifySourceLine(line);

        int currentStack = compileContext.getStackCount();
        int size = (type.getNBytes() > 4 ? 2 : 1);

        // copy the value so we leave it as a result
        if (size == 1) {
            // this means at the maximum we add 1 to the current stack
            // [.. val] ==> [.. val val]
            mv.visitInsn(Opcodes.DUP);
        } else {
            // [.. val1 val2] ==> [.. val1 val2 val1 val2]
            mv.visitInsn(Opcodes.DUP2);
        }
        compileContext.addStackCount(size);
        // compile the owner expression and swap with the value
        owner.compile(mv, compileContext);
        if (size == 1) {
            // [.. val val owner] ==> [.. val owner val]
            mv.visitInsn(Opcodes.SWAP);
        } else {
            // we have to use a DUP_X2 and a POP to insert the owner below the two word value
            // i.e. [.. val1 val2 val1 val2] ==> [.. val1 val2 val1 val2 owner] ==>
            //              [.. val1 val2 owner val1 val2 owner] ==> [.. val1 val2 owner val1 val2]
            mv.visitInsn(Opcodes.DUP_X2);
            compileContext.addStackCount(1);
            mv.visitInsn(Opcodes.POP);
            compileContext.addStackCount(-1);
        }
        if (isPublicField) {
            // now compile a field update
            String ownerType = Type.internalName(field.getDeclaringClass());
            String fieldName = field.getName();
            String fieldType = Type.internalName(field.getType(), true);
            mv.visitFieldInsn(Opcodes.PUTFIELD, ownerType, fieldName, fieldType);
            // we removed the owner and the value
            compileContext.addStackCount(-(1 + size));
        } else {
            // since this is a private field we need to do the update using reflection
            // box the value to an object if necessary
            if (type.isPrimitive()) {
                compileBox(Type.boxType(type), mv, compileContext);
            }
            // stack the helper and then dupx2 it so it goes under the owner and value
            // [.. val(s) owner  valObj ==> val(s) owner valObj helper ]
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            // [.. val(s) owner  valObj helper ==> val(s) helper owner valObj helper ]
            mv.visitInsn(Opcodes.DUP_X2);
            // stack now has 2 more words so count them
            compileContext.addStackCount(2);
            // now pop the redundant top word and stack the field index instead
            // [.. val(s) helper owner valObj helper ==> val(s) helper owner valObj index ]
            mv.visitInsn(Opcodes.POP);
            mv.visitLdcInsn(fieldIndex);
            // use the HelperAdapter method setAccessibleField to set the field value
            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.internalName(HelperAdapter.class),
                    "setAccessibleField", "(Ljava/lang/Object;Ljava/lang/Object;I)V");
            // we popped four args
            compileContext.addStackCount(-4);
        }

        // check the stack height is ok
        if (compileContext.getStackCount() != currentStack) {
            throw new CompileException("FieldExpression.compileAssign : invalid stack height "
                    + compileContext.getStackCount() + " expecting " + (currentStack));
        }
    }
}

From source file:org.jboss.byteman.rule.expression.StaticExpression.java

License:Open Source License

@Override
public void compileAssign(MethodVisitor mv, CompileContext compileContext) throws CompileException {
    // make sure we are at the right source line
    compileContext.notifySourceLine(line);

    int currentStack = compileContext.getStackCount();
    int size = (type.getNBytes() > 4 ? 2 : 1);

    // copy the value so we leave a result
    // increases stack height by size words
    if (size == 1) {
        mv.visitInsn(Opcodes.DUP);//from  w w w . j a va 2 s .c  om
    } else {
        mv.visitInsn(Opcodes.DUP2);
    }
    compileContext.addStackCount(size);
    // compile a static field update

    if (isPublicField) {
        String ownerType = Type.internalName(field.getDeclaringClass());
        String fieldName = field.getName();
        String fieldType = Type.internalName(field.getType(), true);
        compileContext.addStackCount(-size);
        mv.visitFieldInsn(Opcodes.PUTSTATIC, ownerType, fieldName, fieldType);
    } else {
        // since this is a private field we need to do the update using reflection
        // box the value to an object if necessary
        // [.. val(s) val(s) ==> val(s) valObj]
        if (type.isPrimitive()) {
            compileBox(Type.boxType(type), mv, compileContext);
        }
        // stack the helper and then swap it so it goes under the value
        // [.. val(s) valObj ==> val(s) valObj helper ==> val(s) helper valObj]
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitInsn(Opcodes.SWAP);
        // stack a null owner then swap it so it goes under the value
        // [val(s) helper valObj ==> val(s) helper valObj null ==> val(s) helper null valObj]
        mv.visitInsn(Opcodes.ACONST_NULL);
        mv.visitInsn(Opcodes.SWAP);
        // now stack the field index
        // [.. val(s) helper null valObj ==> val(s) helper null valObj index ]
        mv.visitLdcInsn(fieldIndex);
        // we added three more words
        compileContext.addStackCount(3);
        // use the HelperAdapter method setAccessibleField to set the field value
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.internalName(HelperAdapter.class),
                "setAccessibleField", "(Ljava/lang/Object;Ljava/lang/Object;I)V");
        // we popped four args
        compileContext.addStackCount(-4);
    }

    if (compileContext.getStackCount() != currentStack) {
        throw new CompileException("StaticExpression.compileAssign : invalid stack height "
                + compileContext.getStackCount() + " expecting " + currentStack);
    }
}

From source file:org.jboss.byteman.rule.expression.ThrowExpression.java

License:Open Source License

public void compile(MethodVisitor mv, CompileContext compileContext) throws CompileException {
    // make sure we are at the right source line
    compileContext.notifySourceLine(line);

    int currentStack = compileContext.getStackCount();
    int expected = 1;
    int extraParams = 0;

    // ok, we need to create the thrown exception instance and then
    // initialise it.

    // create the thrown exception instance -- adds 1 to stack
    String exceptionClassName = type.getInternalName();
    mv.visitTypeInsn(Opcodes.NEW, exceptionClassName);
    compileContext.addStackCount(1);/*  w w  w  .  j a  va 2  s . c  om*/
    // copy the exception so we can init it
    mv.visitInsn(Opcodes.DUP);
    compileContext.addStackCount(1);

    int argCount = arguments.size();

    // stack each of the arguments to the constructor
    for (int i = 0; i < argCount; i++) {
        Type argType = argumentTypes.get(i);
        Type paramType = paramTypes.get(i);
        int paramCount = (paramType.getNBytes() > 4 ? 2 : 1);

        // track extra storage used after type conversion
        extraParams += (paramCount);
        arguments.get(i).compile(mv, compileContext);
        compileTypeConversion(argType, paramType, mv, compileContext);
    }

    // construct the exception
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, exceptionClassName, "<init>", getDescriptor());

    // modify the stack height to account for the removed exception and params
    compileContext.addStackCount(-(extraParams + 1));

    if (compileContext.getStackCount() != currentStack + expected) {
        throw new CompileException("ThrowExpression.compile : invalid stack height "
                + compileContext.getStackCount() + " expecting " + (currentStack + expected));
    }
    // now create a ThrowException to wrap the user exception
    // create the thrown exception instance -- adds 1 to stack [UE] --> [UE, THE]
    exceptionClassName = "org/jboss/byteman/rule/exception/ThrowException";
    mv.visitTypeInsn(Opcodes.NEW, exceptionClassName);
    compileContext.addStackCount(1);
    // copy the ThrowException so we can init it [UE, THE] --> [THE, UE, THE]
    mv.visitInsn(Opcodes.DUP_X1);
    compileContext.addStackCount(1);
    // reverse the order of the top two words  [THE, UE, THE] --> [THE, THE, UE]
    mv.visitInsn(Opcodes.SWAP);
    // construct the exception [THE, THE, UE] --> [UE]
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, exceptionClassName, "<init>", "(Ljava/lang/Throwable;)V");
    // we should now have just the ThrowException on the stack
    compileContext.addStackCount(-2);
    if (compileContext.getStackCount() != currentStack + expected) {
        throw new CompileException("ThrowExpression.compile : invalid stack height "
                + compileContext.getStackCount() + " expecting " + (currentStack + expected));
    }

    // now throw the exception and decrement the stack height

    mv.visitInsn(Opcodes.ATHROW);
    compileContext.addStackCount(-1);
}

From source file:org.jboss.byteman.rule.expression.Variable.java

License:Open Source License

@Override
public void compileAssign(MethodVisitor mv, CompileContext compileContext) throws CompileException {
    // make sure we are at the right source line
    compileContext.notifySourceLine(line);

    int currentStack = compileContext.getStackCount();
    int size = ((type.getNBytes() > 4) ? 2 : 1);
    int max;/*from   w w  w.  j  a  v  a2 s.c  om*/

    // value to be assigned is TOS and will already be coerced to the correct value type
    // copy it so we leave it as a a return value on the stack
    if (size == 2) {
        // [... val1 val2 ==> ... val1 val2 val1 val2]
        mv.visitInsn(Opcodes.DUP2);
    } else {
        // [... val ==> ... val val]
        mv.visitInsn(Opcodes.DUP);
    }
    // stack the current helper then insert it below the value
    mv.visitVarInsn(Opcodes.ALOAD, 0);
    if (size == 2) {
        // use a DUP_X2 to push a copy below the value then pop the redundant value
        // [... val1 val2 val1 val2 helper ==> ... val1 val2 helper val1 val2 helper]
        mv.visitInsn(Opcodes.DUP_X2);
        // [... val1 val2 helper val1 val2 helper ==> ... val1 val2 helper val1 val2]
        mv.visitInsn(Opcodes.POP);
    } else {
        // we can just swap the two values
        // [... val val helper ==> ... val helper val]
        mv.visitInsn(Opcodes.SWAP);
    }
    // stack the name for the variable and swap below the value
    mv.visitLdcInsn(name);
    if (size == 2) {
        // use a DUP_X2 to push a copy below the value then pop the redundant value
        // [... val1 val2 helper val1 val2 name ==> [... val1 val2 helper name val1 val2 name]
        mv.visitInsn(Opcodes.DUP_X2);
        // this is the high water mark
        compileContext.addStackCount(5);
        // [... val1 val2 helper name val1 val2 name ==> [... val1 val2 helper name val1 val2]
        mv.visitInsn(Opcodes.POP);
        compileContext.addStackCount(-1);
        // and now we have the desired arrangement for the call[.. val1 val2 helper name val1 val2]
    } else {
        // this is the high water mark
        // at this point the stack has gone from [ .. val]  to [.. val helper val name]
        compileContext.addStackCount(3);
        // we can just swap the two values
        // [... val helper val name ==> ... val helper name val]
        mv.visitInsn(Opcodes.SWAP);
        // and now we have the desired arrangement for the call[.. val helper name val]
    }

    // ensure we have an object
    compileObjectConversion(type, Type.OBJECT, mv, compileContext);

    // call the setBinding method
    mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.internalName(HelperAdapter.class), "setBinding",
            "(Ljava/lang/String;Ljava/lang/Object;)V");

    // the call will remove 3 from the stack height
    compileContext.addStackCount(-3);

    // ok, the stack height should be as it was
    if (compileContext.getStackCount() != currentStack) {
        throw new CompileException("variable.compileAssignment : invalid stack height "
                + compileContext.getStackCount() + " expecting " + currentStack);
    }
}

From source file:org.mbte.groovypp.compiler.bytecode.BytecodeExpr.java

License:Apache License

public void swapObjectWith(ClassNode type, MethodVisitor mv) {
    if (type == long_TYPE || type == double_TYPE) {
        mv.visitInsn(Opcodes.DUP_X2);//from ww  w  . j av a 2s . c o  m
        mv.visitInsn(Opcodes.POP);
    } else {
        mv.visitInsn(Opcodes.SWAP);
    }
}

From source file:org.mbte.groovypp.compiler.bytecode.BytecodeExpr.java

License:Apache License

public void swapWithObject(ClassNode type, MethodVisitor mv) {
    if (type == long_TYPE || type == double_TYPE) {
        mv.visitInsn(Opcodes.DUP2_X1);//  ww  w .  j  a  v a  2s  . com
        mv.visitInsn(Opcodes.POP2);
    } else {
        mv.visitInsn(Opcodes.SWAP);
    }
}

From source file:org.sonar.java.bytecode.se.BytecodeEGWalkerExecuteTest.java

License:Open Source License

@Test
public void test_swap() throws Exception {
    SymbolicValue sv1 = new SymbolicValue();
    SymbolicValue sv2 = new SymbolicValue();
    ProgramState programState = execute(new Instruction(Opcodes.SWAP),
            ProgramState.EMPTY_STATE.stackValue(sv1).stackValue(sv2));
    ProgramState.Pop pop = programState.unstackValue(2);
    assertThat(pop.values).containsExactly(sv1, sv2);
    assertThat(pop.state).isEqualTo(ProgramState.EMPTY_STATE);

    assertThatThrownBy(() -> execute(new Instruction(Opcodes.SWAP), ProgramState.EMPTY_STATE.stackValue(sv1)))
            .hasMessage("SWAP needs 2 values on stack");
}

From source file:serianalyzer.JVMImpl.java

License:Open Source License

/**
 * @param opcode/*from  w  ww .  jav  a 2 s . c  o  m*/
 * @param s
 */
static void handleJVMInsn(int opcode, JVMStackState s) {
    BaseType o1;
    BaseType o2;
    BaseType o3;
    List<BaseType> l1;
    List<BaseType> l2;
    switch (opcode) {
    case Opcodes.NOP:
        break;

    case Opcodes.ARRAYLENGTH:
        o1 = s.pop();
        s.push(new BasicConstant(Type.INT_TYPE, 0, !(o1 != null && !o1.isTainted())));
        break;
    case Opcodes.ACONST_NULL:
        s.push(new BasicConstant(Type.VOID_TYPE, "<null>")); //$NON-NLS-1$
        break;
    case Opcodes.ICONST_M1:
    case Opcodes.ICONST_0:
    case Opcodes.ICONST_1:
    case Opcodes.ICONST_2:
    case Opcodes.ICONST_3:
    case Opcodes.ICONST_4:
    case Opcodes.ICONST_5:
        s.push(new BasicConstant(Type.INT_TYPE, opcode - 3));
        break;
    case Opcodes.LCONST_0:
    case Opcodes.LCONST_1:
        s.push(new BasicConstant(Type.LONG_TYPE, opcode - 9L));
        break;
    case Opcodes.FCONST_0:
    case Opcodes.FCONST_1:
    case Opcodes.FCONST_2:
        s.push(new BasicConstant(Type.FLOAT_TYPE, opcode - 11f));
        break;
    case Opcodes.DCONST_0:
    case Opcodes.DCONST_1:
        s.push(new BasicConstant(Type.DOUBLE_TYPE, opcode - 14d));
        break;
    case Opcodes.IALOAD:
    case Opcodes.LALOAD:
    case Opcodes.FALOAD:
    case Opcodes.DALOAD:
    case Opcodes.BALOAD:
    case Opcodes.CALOAD:
    case Opcodes.SALOAD:
        o1 = s.pop();
        o2 = s.pop();
        s.push(new BasicVariable(toType(opcode), "primitive array elem", //$NON-NLS-1$
                (o1 == null || o1.isTainted()) | (o2 == null || o2.isTainted())));
        break;

    case Opcodes.AALOAD:
        o1 = s.pop();
        o2 = s.pop();
        if (o1 != null && o2 instanceof SimpleType && ((SimpleType) o2).getType().toString().startsWith("[")) { //$NON-NLS-1$
            Type atype = Type.getType(((SimpleType) o2).getType().toString().substring(1));
            if (o2.getAlternativeTypes() != null && !o2.getAlternativeTypes().isEmpty()) {
                s.clear();
                break;
            }
            s.push(new BasicVariable(atype, "array elem " + atype, o1.isTainted() | o2.isTainted())); //$NON-NLS-1$
        } else {
            s.clear();
        }
        break;

    case Opcodes.IASTORE:
    case Opcodes.LASTORE:
    case Opcodes.FASTORE:
    case Opcodes.DASTORE:
    case Opcodes.AASTORE:
    case Opcodes.BASTORE:
    case Opcodes.CASTORE:
    case Opcodes.SASTORE:
        s.pop(3);
        break;

    case Opcodes.POP2:
        s.pop();
    case Opcodes.MONITORENTER:
    case Opcodes.MONITOREXIT:
    case Opcodes.POP:
        s.pop();
        break;

    case Opcodes.DUP:
        if (!s.isEmpty()) {
            o1 = s.pop();
            s.push(o1);
            s.push(o1);
        }
        break;
    case Opcodes.DUP_X1:
        o1 = s.pop();
        o2 = s.pop();
        s.push(o1);
        s.push(o2);
        s.push(o1);
        break;
    case Opcodes.DUP_X2:
        o1 = s.pop();
        o2 = s.pop();
        o3 = s.pop();
        s.push(o1);
        s.push(o3);
        s.push(o2);
        s.push(o1);
        break;
    case Opcodes.DUP2:
        l1 = s.popWord();
        if (l1.isEmpty()) {
            log.trace("DUP2 with unknown operand"); //$NON-NLS-1$
            s.clear();
        } else {
            s.pushWord(l1);
            s.pushWord(l1);
        }
        break;
    case Opcodes.DUP2_X1:
        l1 = s.popWord();
        o1 = s.pop();
        if (l1.isEmpty()) {
            log.trace("DUP2 with unknown operand"); //$NON-NLS-1$
            s.clear();
        } else {
            s.pushWord(l1);
            s.push(o1);
            s.pushWord(l1);
        }
        break;
    case Opcodes.DUP2_X2:
        l1 = s.popWord();
        l2 = s.popWord();
        if (l1.isEmpty() || l2.isEmpty()) {
            log.trace("DUP2 with unknown operand"); //$NON-NLS-1$
            s.clear();
        } else {
            s.pushWord(l1);
            s.pushWord(l2);
            s.pushWord(l1);
        }
        break;

    case Opcodes.SWAP:
        o1 = s.pop();
        o2 = s.pop();
        s.push(o1);
        s.push(o2);
        break;

    case Opcodes.IADD:
    case Opcodes.LADD:
    case Opcodes.FADD:
    case Opcodes.DADD:
    case Opcodes.ISUB:
    case Opcodes.LSUB:
    case Opcodes.FSUB:
    case Opcodes.DSUB:
    case Opcodes.IMUL:
    case Opcodes.LMUL:
    case Opcodes.FMUL:
    case Opcodes.DMUL:
    case Opcodes.IDIV:
    case Opcodes.LDIV:
    case Opcodes.FDIV:
    case Opcodes.DDIV:
    case Opcodes.IREM:
    case Opcodes.LREM:
    case Opcodes.FREM:
    case Opcodes.DREM:
    case Opcodes.IAND:
    case Opcodes.LAND:
    case Opcodes.IOR:
    case Opcodes.LOR:
    case Opcodes.IXOR:
    case Opcodes.LXOR:
    case Opcodes.LCMP:
    case Opcodes.FCMPL:
    case Opcodes.FCMPG:
    case Opcodes.DCMPL:
    case Opcodes.DCMPG:
        s.merge(2);
        break;

    case Opcodes.ISHL:
    case Opcodes.LSHL:
    case Opcodes.ISHR:
    case Opcodes.LSHR:
    case Opcodes.IUSHR:
    case Opcodes.LUSHR:
        s.pop(); // amount
        // ignore value
        break;

    case Opcodes.INEG:
    case Opcodes.F2I:
    case Opcodes.D2I:
    case Opcodes.L2I:
        s.push(cast(s.pop(), Type.INT_TYPE));
        break;

    case Opcodes.LNEG:
    case Opcodes.I2L:
    case Opcodes.F2L:
    case Opcodes.D2L:
        s.push(cast(s.pop(), Type.LONG_TYPE));
        break;

    case Opcodes.FNEG:
    case Opcodes.I2F:
    case Opcodes.L2F:
    case Opcodes.D2F:
        s.push(cast(s.pop(), Type.FLOAT_TYPE));

    case Opcodes.DNEG:
    case Opcodes.I2D:
    case Opcodes.L2D:
    case Opcodes.F2D:
        s.push(cast(s.pop(), Type.DOUBLE_TYPE));

    case Opcodes.I2B:
        s.push(cast(s.pop(), Type.BYTE_TYPE));
        break;
    case Opcodes.I2C:
        s.push(cast(s.pop(), Type.CHAR_TYPE));
        break;
    case Opcodes.I2S:
        s.push(cast(s.pop(), Type.SHORT_TYPE));
        break;

    case Opcodes.ARETURN:
        s.clear();
        break;

    case Opcodes.IRETURN:
    case Opcodes.LRETURN:
    case Opcodes.FRETURN:
    case Opcodes.DRETURN:
    case Opcodes.RETURN:
        if (log.isTraceEnabled()) {
            log.trace("Found return " + s.pop()); //$NON-NLS-1$
        }
        s.clear();
        break;

    case Opcodes.ATHROW:
        Object thrw = s.pop();
        log.trace("Found throw " + thrw); //$NON-NLS-1$
        s.clear();
        break;

    default:
        log.warn("Unsupported instruction code " + opcode); //$NON-NLS-1$
    }
}