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.hua.ast.visitors.BytecodeGeneratorASTVisitor.java

/**
 * Assumes top of stack contains two strings
 *//* www.ja v  a2 s .c  o m*/
private void handleStringOperator(ASTNode node, Operator op) throws ASTVisitorException {
    if (op.equals(Operator.PLUS)) {
        mn.instructions.add(new TypeInsnNode(Opcodes.NEW, "java/lang/StringBuilder"));
        mn.instructions.add(new InsnNode(Opcodes.DUP));
        mn.instructions.add(
                new MethodInsnNode(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V", false));
        mn.instructions.add(new InsnNode(Opcodes.SWAP));
        mn.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false));
        mn.instructions.add(new InsnNode(Opcodes.SWAP));
        mn.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append",
                "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false));
        mn.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString",
                "()Ljava/lang/String;", false));
    } else if (op.isRelational()) {
        LabelNode trueLabelNode = new LabelNode();
        switch (op) {
        case EQUAL:
            mn.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals",
                    "(Ljava/lang/Object;)Z", false));
            mn.instructions.add(new JumpInsnNode(Opcodes.IFNE, trueLabelNode));
            break;
        case NOT_EQUAL:
            mn.instructions.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, "java/lang/String", "equals",
                    "(Ljava/lang/Object;)Z", false));
            mn.instructions.add(new JumpInsnNode(Opcodes.IFEQ, trueLabelNode));
            break;
        default:
            ASTUtils.error(node, "Operator not supported on strings");
            break;
        }
        mn.instructions.add(new InsnNode(Opcodes.ICONST_0));
        LabelNode endLabelNode = new LabelNode();
        mn.instructions.add(new JumpInsnNode(Opcodes.GOTO, endLabelNode));
        mn.instructions.add(trueLabelNode);
        mn.instructions.add(new InsnNode(Opcodes.ICONST_1));
        mn.instructions.add(endLabelNode);
    } else {
        ASTUtils.error(node, "Operator not recognized");
    }
}

From source file:org.hua.ast.visitors.BytecodeGeneratorASTVisitor.java

@Override
public void visit(BinaryExpression node) throws ASTVisitorException {
    node.getExpression1().accept(this);
    Type expr1Type = ASTUtils.getSafeType(node.getExpression1());

    node.getExpression2().accept(this);
    Type expr2Type = ASTUtils.getSafeType(node.getExpression2());

    Type maxType = TypeUtils.maxType(expr1Type, expr2Type);

    // cast top of stack to max
    if (!maxType.equals(expr2Type)) {
        widen(maxType, expr2Type);
    }/*from w  ww .ja v  a 2s.  co  m*/
    System.out.println("^^^^^^^^^^^^^^^^^^^ binary op: " + node.getOperator());
    System.out.println("             type1: " + expr1Type + " type2: " + expr2Type);
    System.out.println("                max type: " + !maxType.equals(expr1Type));
    // cast second from top to max
    if (!maxType.equals(expr1Type)) {
        System.out.println("not to be dispalyed");
        LocalIndexPool lip = ASTUtils.getSafeLocalIndexPool(node);
        int localIndex = -1;
        if (expr2Type.equals(Type.DOUBLE_TYPE) || expr1Type.equals(Type.DOUBLE_TYPE)) {
            localIndex = lip.getLocalIndex(expr2Type);
            mn.instructions.add(new VarInsnNode(expr2Type.getOpcode(Opcodes.ISTORE), localIndex));
        } else {
            mn.instructions.add(new InsnNode(Opcodes.SWAP));
        }
        widen(maxType, expr1Type);
        if (expr2Type.equals(Type.DOUBLE_TYPE) || expr1Type.equals(Type.DOUBLE_TYPE)) {
            mn.instructions.add(new VarInsnNode(expr2Type.getOpcode(Opcodes.ILOAD), localIndex));
            lip.freeLocalIndex(localIndex, expr2Type);
        } else {
            mn.instructions.add(new InsnNode(Opcodes.SWAP));
        }
    }

    // 
    if (ASTUtils.isBooleanExpression(node)) {
        handleBooleanOperator(node, node.getOperator(), maxType);
    } else if (maxType.equals(TypeUtils.STRING_TYPE)) {
        mn.instructions.add(new InsnNode(Opcodes.SWAP));
        handleStringOperator(node, node.getOperator());
    } else {
        handleNumberOperator(node, node.getOperator(), maxType);
    }
}

From source file:org.jacoco.core.internal.instr.FrameTracker.java

License:Open Source License

@Override
public void visitInsn(final int opcode) {
    final Object t1, t2, t3, t4;
    switch (opcode) {
    case Opcodes.NOP:
    case Opcodes.RETURN:
        break;//from   ww  w  . j a  v  a2  s.c om
    case Opcodes.ARETURN:
    case Opcodes.ATHROW:
    case Opcodes.FRETURN:
    case Opcodes.IRETURN:
    case Opcodes.MONITORENTER:
    case Opcodes.MONITOREXIT:
    case Opcodes.POP:
        pop(1);
        break;
    case Opcodes.DRETURN:
    case Opcodes.LRETURN:
    case Opcodes.POP2:
        pop(2);
        break;
    case Opcodes.AASTORE:
    case Opcodes.BASTORE:
    case Opcodes.CASTORE:
    case Opcodes.FASTORE:
    case Opcodes.IASTORE:
    case Opcodes.SASTORE:
        pop(3);
        break;
    case Opcodes.LASTORE:
    case Opcodes.DASTORE:
        pop(4);
        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:
        push(Opcodes.INTEGER);
        break;
    case Opcodes.ARRAYLENGTH:
    case Opcodes.F2I:
    case Opcodes.I2B:
    case Opcodes.I2C:
    case Opcodes.I2S:
    case Opcodes.INEG:
        pop(1);
        push(Opcodes.INTEGER);
        break;
    case Opcodes.BALOAD:
    case Opcodes.CALOAD:
    case Opcodes.D2I:
    case Opcodes.FCMPG:
    case Opcodes.FCMPL:
    case Opcodes.IADD:
    case Opcodes.IALOAD:
    case Opcodes.IAND:
    case Opcodes.IDIV:
    case Opcodes.IMUL:
    case Opcodes.IOR:
    case Opcodes.IREM:
    case Opcodes.ISHL:
    case Opcodes.ISHR:
    case Opcodes.ISUB:
    case Opcodes.IUSHR:
    case Opcodes.IXOR:
    case Opcodes.L2I:
    case Opcodes.SALOAD:
        pop(2);
        push(Opcodes.INTEGER);
        break;
    case Opcodes.DCMPG:
    case Opcodes.DCMPL:
    case Opcodes.LCMP:
        pop(4);
        push(Opcodes.INTEGER);
        break;
    case Opcodes.FCONST_0:
    case Opcodes.FCONST_1:
    case Opcodes.FCONST_2:
        push(Opcodes.FLOAT);
        break;
    case Opcodes.FNEG:
    case Opcodes.I2F:
        pop(1);
        push(Opcodes.FLOAT);
        break;
    case Opcodes.D2F:
    case Opcodes.FADD:
    case Opcodes.FALOAD:
    case Opcodes.FDIV:
    case Opcodes.FMUL:
    case Opcodes.FREM:
    case Opcodes.FSUB:
    case Opcodes.L2F:
        pop(2);
        push(Opcodes.FLOAT);
        break;
    case Opcodes.LCONST_0:
    case Opcodes.LCONST_1:
        push(Opcodes.LONG);
        push(Opcodes.TOP);
        break;
    case Opcodes.F2L:
    case Opcodes.I2L:
        pop(1);
        push(Opcodes.LONG);
        push(Opcodes.TOP);
        break;
    case Opcodes.D2L:
    case Opcodes.LALOAD:
    case Opcodes.LNEG:
        pop(2);
        push(Opcodes.LONG);
        push(Opcodes.TOP);
        break;
    case Opcodes.LSHL:
    case Opcodes.LSHR:
    case Opcodes.LUSHR:
        pop(3);
        push(Opcodes.LONG);
        push(Opcodes.TOP);
        break;
    case Opcodes.LADD:
    case Opcodes.LAND:
    case Opcodes.LDIV:
    case Opcodes.LMUL:
    case Opcodes.LOR:
    case Opcodes.LREM:
    case Opcodes.LSUB:
    case Opcodes.LXOR:
        pop(4);
        push(Opcodes.LONG);
        push(Opcodes.TOP);
        break;
    case Opcodes.DCONST_0:
    case Opcodes.DCONST_1:
        push(Opcodes.DOUBLE);
        push(Opcodes.TOP);
        break;
    case Opcodes.F2D:
    case Opcodes.I2D:
        pop(1);
        push(Opcodes.DOUBLE);
        push(Opcodes.TOP);
        break;
    case Opcodes.DALOAD:
    case Opcodes.DNEG:
    case Opcodes.L2D:
        pop(2);
        push(Opcodes.DOUBLE);
        push(Opcodes.TOP);
        break;
    case Opcodes.DADD:
    case Opcodes.DDIV:
    case Opcodes.DMUL:
    case Opcodes.DREM:
    case Opcodes.DSUB:
        pop(4);
        push(Opcodes.DOUBLE);
        push(Opcodes.TOP);
        break;
    case Opcodes.ACONST_NULL:
        push(Opcodes.NULL);
        break;
    case Opcodes.AALOAD:
        pop(1);
        t1 = pop();
        push(Type.getType(((String) t1).substring(1)));
        break;
    case Opcodes.DUP:
        t1 = pop();
        push(t1);
        push(t1);
        break;
    case Opcodes.DUP_X1:
        t1 = pop();
        t2 = pop();
        push(t1);
        push(t2);
        push(t1);
        break;
    case Opcodes.DUP_X2:
        t1 = pop();
        t2 = pop();
        t3 = pop();
        push(t1);
        push(t3);
        push(t2);
        push(t1);
        break;
    case Opcodes.DUP2:
        t1 = pop();
        t2 = pop();
        push(t2);
        push(t1);
        push(t2);
        push(t1);
        break;
    case Opcodes.DUP2_X1:
        t1 = pop();
        t2 = pop();
        t3 = pop();
        push(t2);
        push(t1);
        push(t3);
        push(t2);
        push(t1);
        break;
    case Opcodes.DUP2_X2:
        t1 = pop();
        t2 = pop();
        t3 = pop();
        t4 = pop();
        push(t2);
        push(t1);
        push(t4);
        push(t3);
        push(t2);
        push(t1);
        break;
    case Opcodes.SWAP:
        t1 = pop();
        t2 = pop();
        push(t1);
        push(t2);
        break;
    default:
        throw new IllegalArgumentException();
    }
    mv.visitInsn(opcode);
}

From source file:org.jacoco.core.runtime.LoggerRuntime.java

License:Open Source License

public int generateDataAccessor(final long classid, final String classname, final int probecount,
        final MethodVisitor mv) {

    // The data accessor performs the following steps:
    ////from   www. j av  a  2  s.  c om
    // final Object[] args = new Object[3];
    // args[0] = Long.valueOf(classid);
    // args[1] = classname;
    // args[2] = Integer.valueOf(probecount);
    // Logger.getLogger(CHANNEL).log(Level.INFO, key, args);
    // final byte[] probedata = (byte[]) args[0];
    //
    // Note that local variable 'args' is used at two places. As were not
    // allowed to allocate local variables we have to keep this value with
    // DUP and SWAP operations on the operand stack.

    // 1. Create parameter array:

    RuntimeData.generateArgumentArray(classid, classname, probecount, mv);

    // Stack[0]: [Ljava/lang/Object;

    mv.visitInsn(Opcodes.DUP);

    // Stack[1]: [Ljava/lang/Object;
    // Stack[0]: [Ljava/lang/Object;

    // 2. Call Logger:

    mv.visitLdcInsn(CHANNEL);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/util/logging/Logger", "getLogger",
            "(Ljava/lang/String;)Ljava/util/logging/Logger;");

    // Stack[2]: Ljava/util/logging/Logger;
    // Stack[1]: [Ljava/lang/Object;
    // Stack[0]: [Ljava/lang/Object;

    mv.visitInsn(Opcodes.SWAP);

    // Stack[2]: [Ljava/lang/Object;
    // Stack[1]: Ljava/util/logging/Logger;
    // Stack[0]: [Ljava/lang/Object;

    mv.visitFieldInsn(Opcodes.GETSTATIC, "java/util/logging/Level", "INFO", "Ljava/util/logging/Level;");

    // Stack[3]: Ljava/util/logging/Level;
    // Stack[2]: [Ljava/lang/Object;
    // Stack[1]: Ljava/util/logging/Logger;
    // Stack[0]: [Ljava/lang/Object;

    mv.visitInsn(Opcodes.SWAP);

    // Stack[3]: [Ljava/lang/Object;
    // Stack[2]: Ljava/util/logging/Level;
    // Stack[1]: Ljava/util/logging/Logger;
    // Stack[0]: [Ljava/lang/Object;

    mv.visitLdcInsn(key);

    // Stack[4]: Ljava/lang/String;
    // Stack[3]: [Ljava/lang/Object;
    // Stack[2]: Ljava/util/logging/Level;
    // Stack[1]: Ljava/util/logging/Logger;
    // Stack[0]: [Ljava/lang/Object;

    mv.visitInsn(Opcodes.SWAP);

    // Stack[4]: [Ljava/lang/Object;
    // Stack[3]: Ljava/lang/String;
    // Stack[2]: Ljava/util/logging/Level;
    // Stack[1]: Ljava/util/logging/Logger;
    // Stack[0]: [Ljava/lang/Object;

    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/util/logging/Logger", "log",
            "(Ljava/util/logging/Level;Ljava/lang/String;[Ljava/lang/Object;)V");

    // Stack[0]: [Ljava/lang/Object;

    // 3. Load data structure from parameter array:

    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitInsn(Opcodes.AALOAD);
    mv.visitTypeInsn(Opcodes.CHECKCAST, InstrSupport.DATAFIELD_DESC);

    // Stack[0]: [Z

    return 5; // Maximum local stack size is 5
}

From source file:org.jacoco.core.runtime.URLStreamHandlerRuntime.java

License:Open Source License

public int generateDataAccessor(final long classid, final String classname, final int probecount,
        final MethodVisitor mv) {

    // The data accessor performs the following steps:
    ///* w  w w .  jav a 2 s.  c o  m*/
    // final URL url = new URL(protocol, null, "");
    // final URLConnection connection = url.openConnection();
    // final Object[] args = new Object[3];
    // args[0] = Long.valueOf(classid);
    // args[1] = classname;
    // args[2] = Integer.valueOf(probecount);
    // connection.equals(args);
    // final byte[] probedata = (byte[]) args[0];

    RuntimeData.generateArgumentArray(classid, classname, probecount, mv);
    mv.visitInsn(Opcodes.DUP);

    // Stack[1]: [Ljava/lang/Object;
    // Stack[0]: [Ljava/lang/Object;

    mv.visitTypeInsn(Opcodes.NEW, "java/net/URL");
    mv.visitInsn(Opcodes.DUP);
    mv.visitLdcInsn(protocol);
    mv.visitInsn(Opcodes.ACONST_NULL);
    mv.visitLdcInsn("");
    mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/net/URL", "<init>",
            "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");

    // Stack[2]: [Ljava/net/URL;
    // Stack[1]: [Ljava/lang/Object;
    // Stack[0]: [Ljava/lang/Object;

    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/net/URL", "openConnection", "()Ljava/net/URLConnection;");

    // Stack[2]: [Ljava/net/URLConnection;
    // Stack[1]: [Ljava/lang/Object;
    // Stack[0]: [Ljava/lang/Object;

    mv.visitInsn(Opcodes.SWAP);

    // Stack[2]: [Ljava/lang/Object;
    // Stack[1]: [Ljava/net/URLConnection;
    // Stack[0]: [Ljava/lang/Object;

    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z");

    // Stack[1]: Z;
    // Stack[0]: [Ljava/lang/Object;

    mv.visitInsn(Opcodes.POP);

    // Stack[0]: [Ljava/lang/Object;

    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitInsn(Opcodes.AALOAD);
    mv.visitTypeInsn(Opcodes.CHECKCAST, InstrSupport.DATAFIELD_DESC);

    return 7;
}

From source file:org.jboss.arquillian.extension.jacoco.container.ArquillianRuntime.java

License:Apache License

public int generateDataAccessor(long classid, String classname, int probecount, MethodVisitor mv) {
    // 1. Create parameter array:
    generateArgumentArray(classid, classname, probecount, mv);
    // stack[0]: [Ljava/lang/Object;

    mv.visitInsn(Opcodes.DUP);/*from  w  ww.j  a v  a2 s  . c o  m*/

    // stack[1]: [Ljava/lang/Object;
    // stack[0]: [Ljava/lang/Object;

    // 2. Invoke ArquillianRuntime:
    mv.visitMethodInsn(Opcodes.INVOKESTATIC,
            "org/jboss/arquillian/extension/jacoco/container/ArquillianRuntime", "getInstance",
            "()Lorg/jboss/arquillian/extension/jacoco/container/ArquillianRuntime;");

    // stack[2]: LArquillianRuntime;
    // stack[1]: [Ljava/lang/Object;
    // stack[0]: [Ljava/lang/Object;

    mv.visitInsn(Opcodes.SWAP);

    // stack[2]: [Ljava/lang/Object;
    // stack[1]: LArquillianRuntime;
    // stack[0]: [Ljava/lang/Object;

    // 3. Invoke ArquillianRuntime swapExecutionData, gets the boolean[] in Object[0]:
    mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL,
            "org/jboss/arquillian/extension/jacoco/container/ArquillianRuntime", "swapExecutionData",
            "([Ljava/lang/Object;)V");

    // Stack[0]: [Ljava/lang/Object;

    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitInsn(Opcodes.AALOAD);
    mv.visitTypeInsn(Opcodes.CHECKCAST, InstrSupport.DATAFIELD_DESC);

    // Stack[0]: [Z;

    return 5;
}

From source file:org.jboss.byteman.agent.adapter.RuleGeneratorAdapter.java

License:Open Source License

/**
 * Generates a SWAP instruction.
 */
public void swap() {
    visitInsn(Opcodes.SWAP);
}

From source file:org.jboss.byteman.agent.adapter.RuleTriggerMethodAdapter.java

License:Open Source License

/**
 * plant code to copy back any updated values from the argument array to the relevant local variable slots
 *///from   w w  w  .  ja  va2  s  .c o m
private void doArgUpdate() {
    // at entry the top of the stack contains the object array
    // for an AT EXIT rule the entry below this is the return value

    Type objectType = Type.getType(Object.class);
    int arraySize = callArrayBindings.size();
    int lastUpdated = -1;
    int returnIdx = -1;

    // identify which is the last index we will need to update. n.b. if we find a return value we will
    // update that last

    for (int i = 0; i < arraySize; i++) {
        Binding binding = callArrayBindings.get(i);
        if (binding.isUpdated()) {
            lastUpdated = i;
            if (binding.isReturn()) {
                returnIdx = i;
            }
        }
    }

    // if the return value is updated it gets done last
    if (returnIdx >= 0) {
        lastUpdated = returnIdx;
    }

    // write back all other args then stack new return value and drop old one
    for (int i = 0; i < arraySize; i++) {
        Binding binding = callArrayBindings.get(i);
        if (binding.isUpdated() && !binding.isReturn()) {
            // if this is the last update then we consume the arguments array
            // otherwise we need to copy it
            if (i != lastUpdated) {
                dup();
            }
            push(i);
            arrayLoad(objectType);
            if (binding.isParam()) {
                int idx = binding.getIndex() - 1;
                unbox(argumentTypes[idx]);
                storeArg(idx);
            } else if (binding.isLocalVar()) {
                int idx = binding.getLocalIndex();
                unbox(getLocalType(idx));
                storeLocal(idx);
            }
        }
    }

    // if we had a return value to process then the args array will still be on top of the stack above
    // the old return value

    if (returnIdx >= 0) {
        // get rid of old return value remembering to use the correct type for $!
        // which varies depending if this is an AT EXIT or AFTER CALL rule
        if (saveValueType.getSize() == 2) {
            mv.visitInsn(Opcodes.DUP_X2);
            mv.visitInsn(Opcodes.POP);
            mv.visitInsn(Opcodes.POP2);
        } else {
            mv.visitInsn(Opcodes.SWAP);
            mv.visitInsn(Opcodes.POP);
        }

        push(returnIdx);
        arrayLoad(objectType);
        // use the correct type for $! which varies depending if this is an AT EXIT or AFTER CALL rule
        unbox(saveValueType);
    }
}

From source file:org.jboss.byteman.rule.expression.ArrayExpression.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);

    Type valueType = arrayRef.getType().getBaseType();
    int currentStack = compileContext.getStackCount();
    boolean isTwoWords = (valueType.getNBytes() > 4);
    int toPop = 0;
    int size = (isTwoWords ? 2 : 1);

    // value to be assigned is TOS and will already be coerced to the correct value type
    // copy it so we can install the copy and leave the original as a a return value on the stack
    if (isTwoWords) {
        // [... val1 val2 ==> ... val1 val2 val1 val2]
        mv.visitInsn(Opcodes.DUP2);//  w w  w. j av  a2  s .  c  om
    } else {
        // [... val ==> ... val val]
        mv.visitInsn(Opcodes.DUP);
    }
    compileContext.addStackCount(size);

    // compile load of array reference -- adds 1 to stack height
    arrayRef.compile(mv, compileContext);
    // for each index expression compile the expression and the do an array load
    Iterator<Expression> iterator = idxList.iterator();

    while (iterator.hasNext()) {
        Expression idxExpr = iterator.next();
        if (iterator.hasNext()) {
            // dereference the array to get an embedded array
            // compile expression index -- adds 1 to height
            idxExpr.compile(mv, compileContext);
            // make sure the index is an integer
            compileTypeConversion(idxExpr.getType(), Type.I, mv, compileContext);
            // fetch embedded array pop 2 and add 1
            mv.visitInsn(Opcodes.AALOAD);
            compileContext.addStackCount(-1);
            valueType = valueType.getBaseType();
        } else {
            if (isTwoWords) {
                // stack is [..., val1, val2, val1, val2, aref ] and we want [..., val1, val2, aref, val1, val2 ]
                mv.visitInsn(Opcodes.DUP_X2); // ==>  [..., val1, val2, aref. val1, val2, aref ]
                compileContext.addStackCount(1);
                mv.visitInsn(Opcodes.POP); // ==> [..., val1, val2, aref. val1, val2 ]
                compileContext.addStackCount(-1);
            } else {
                // stack is [..., val, val, aref ] and we want [..., val, aref, val ]
                mv.visitInsn(Opcodes.SWAP);
            }
            // compile expression index -- adds 1 to height
            idxExpr.compile(mv, compileContext);
            // make sure the index is an integer
            compileTypeConversion(idxExpr.getType(), Type.I, mv, compileContext);
            if (isTwoWords) {
                // stack is [..., val1, val2, aref, val1, val2, idx] and we want [..., val1, val2, aref, idx, val1, val2 ]
                mv.visitInsn(Opcodes.DUP_X2); // ==> [..., val1, val2, aref, idx, val1, val2, idx]
                compileContext.addStackCount(1);
                mv.visitInsn(Opcodes.POP); // ==> [..., val1, val2, aref, idx, val1, val2 ]
                compileContext.addStackCount(-1);
            } else {
                // stack is [..., val, aref, val, idx] and we want [..., val, aref, idx, val ]
                mv.visitInsn(Opcodes.SWAP);
            }
            // now we can do the array store
            if (valueType.isObject() || valueType.isArray()) {
                // compile load object - pops 3
                mv.visitInsn(Opcodes.AASTORE);
                toPop = -3;
            } else if (valueType == Type.Z || valueType == Type.B) {
                // compile load byte - pops 3
                mv.visitInsn(Opcodes.BASTORE);
                toPop = -3;
            } else if (valueType == Type.S) {
                // compile load short - pops 3
                mv.visitInsn(Opcodes.SASTORE);
                toPop = -3;
            } else if (valueType == Type.C) {
                // compile load char - pops 3
                mv.visitInsn(Opcodes.CASTORE);
                toPop = -3;
            } else if (valueType == Type.I) {
                // compile load int - pops 3
                mv.visitInsn(Opcodes.IASTORE);
                toPop = -3;
            } else if (valueType == Type.J) {
                // compile load long - pops 4
                mv.visitInsn(Opcodes.LASTORE);
                toPop = -4;
            } else if (valueType == Type.F) {
                // compile load float - pops 3
                mv.visitInsn(Opcodes.FASTORE);
                toPop = -3;
            } else if (valueType == Type.D) {
                // compile load double - pops 4
                mv.visitInsn(Opcodes.DASTORE);
                toPop = -4;
            }
            compileContext.addStackCount(toPop);
            if (iterator.hasNext()) {
                assert valueType.isArray();
                valueType = valueType.getBaseType();
            }
        }
    }

    // check stack height
    if (compileContext.getStackCount() != currentStack) {
        throw new CompileException("ArrayExpression.compile : invalid stack height "
                + compileContext.getStackCount() + " expecting " + currentStack);
    }

    // we needed room for an aray and an index or for a one or two word result
    // but the recursive evaluations will have made sure the max stack is big enough
    // so there is no need to update the maximum stack height
}

From source file:org.jboss.byteman.rule.expression.DollarExpression.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);

    String targetName = binding.getName();

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

    if (index == HELPER_IDX) {
        // not allowed to reassign the helper binding
        throw new CompileException("DollarExpression.compileAssign : invalid assignment to helper binding $$");
    } else {//w  ww  .  j  a  v  a 2s .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) {
            mv.visitInsn(Opcodes.DUP2);
        } else {
            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
            mv.visitInsn(Opcodes.DUP_X2);
            mv.visitInsn(Opcodes.POP);
        } else {
            // we can just swap the two values
            mv.visitInsn(Opcodes.SWAP);
        }
        // stack the name for the variable and swap below the value
        mv.visitLdcInsn(targetName);
        if (size == 2) {
            // use a DUP_X2 to push a copy below the value then pop the redundant value
            mv.visitInsn(Opcodes.DUP_X2);
            // this is the high water mark
            // at this point the stack has gone from [ .. val1 val2]  to [.. val1 val2 helper name val1 val2 name]
            compileContext.addStackCount(5);
            mv.visitInsn(Opcodes.POP);
            compileContext.addStackCount(-1);
        } 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
            mv.visitInsn(Opcodes.SWAP);
        }
        // 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);
        }
    }
}