Example usage for org.objectweb.asm Opcodes AASTORE

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

Introduction

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

Prototype

int AASTORE

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

Click Source Link

Usage

From source file:org.evosuite.instrumentation.error.ArrayInstrumentation.java

License:Open Source License

@Override
public void visitInsn(int opcode) {
    // Check array accesses
    if (opcode == Opcodes.IALOAD || opcode == Opcodes.BALOAD || opcode == Opcodes.CALOAD
            || opcode == Opcodes.SALOAD || opcode == Opcodes.LALOAD || opcode == Opcodes.FALOAD
            || opcode == Opcodes.DALOAD || opcode == Opcodes.AALOAD) {

        mv.visitInsn(Opcodes.DUP);/*from  w  w w. ja v a 2s  . c  o  m*/
        insertBranch(Opcodes.IFGE, "java/lang/ArrayIndexOutOfBoundsException");

        mv.visitInsn(Opcodes.DUP2);
        mv.visitInsn(Opcodes.SWAP);
        //mv.visitInsn(Opcodes.POP);
        mv.visitInsn(Opcodes.ARRAYLENGTH);
        insertBranch(Opcodes.IF_ICMPLT, "java/lang/ArrayIndexOutOfBoundsException");

    } else if (opcode == Opcodes.IASTORE || opcode == Opcodes.BASTORE || opcode == Opcodes.CASTORE
            || opcode == Opcodes.SASTORE || opcode == Opcodes.AASTORE || opcode == Opcodes.LASTORE
            || opcode == Opcodes.FASTORE || opcode == Opcodes.DASTORE) {

        int loc = 0;
        if (opcode == Opcodes.IASTORE)
            loc = mv.newLocal(Type.INT_TYPE);
        else if (opcode == Opcodes.BASTORE)
            loc = mv.newLocal(Type.BYTE_TYPE);
        else if (opcode == Opcodes.CASTORE)
            loc = mv.newLocal(Type.CHAR_TYPE);
        else if (opcode == Opcodes.SASTORE)
            loc = mv.newLocal(Type.SHORT_TYPE);
        else if (opcode == Opcodes.AASTORE)
            loc = mv.newLocal(Type.getType(Object.class));
        else if (opcode == Opcodes.LASTORE)
            loc = mv.newLocal(Type.LONG_TYPE);
        else if (opcode == Opcodes.FASTORE)
            loc = mv.newLocal(Type.FLOAT_TYPE);
        else if (opcode == Opcodes.DASTORE)
            loc = mv.newLocal(Type.DOUBLE_TYPE);
        else
            throw new RuntimeException("Unknown type");
        mv.storeLocal(loc);

        mv.visitInsn(Opcodes.DUP);
        insertBranch(Opcodes.IFGE, "java/lang/ArrayIndexOutOfBoundsException");

        mv.visitInsn(Opcodes.DUP2);
        mv.visitInsn(Opcodes.SWAP);
        //mv.visitInsn(Opcodes.POP);
        mv.visitInsn(Opcodes.ARRAYLENGTH);
        insertBranch(Opcodes.IF_ICMPLT, "java/lang/ArrayIndexOutOfBoundsException");

        mv.loadLocal(loc);
    }
}

From source file:org.evosuite.instrumentation.error.NullPointerExceptionInstrumentation.java

License:Open Source License

@Override
public void visitInsn(int opcode) {
    switch (opcode) {
    case Opcodes.ARRAYLENGTH:
        // TODO/*from   w ww. j  a  v  a2s . c  om*/
        break;
    case Opcodes.BALOAD:
    case Opcodes.CALOAD:
    case Opcodes.SALOAD:
    case Opcodes.IALOAD:
    case Opcodes.LALOAD:
    case Opcodes.FALOAD:
    case Opcodes.DALOAD:
    case Opcodes.AALOAD:
        // TODO
        break;

    case Opcodes.BASTORE:
    case Opcodes.CASTORE:
    case Opcodes.SASTORE:
    case Opcodes.IASTORE:
    case Opcodes.LASTORE:
    case Opcodes.FASTORE:
    case Opcodes.DASTORE:
    case Opcodes.AASTORE:
        // TODO
        break;
    default:
        // Ignore everything else
    }
    super.visitInsn(opcode);
}

From source file:org.evosuite.instrumentation.mutation.ReplaceArithmeticOperator.java

License:Open Source License

@SuppressWarnings("rawtypes")
private static int getNextIndexFromLoad(MethodNode mn) {
    Iterator it = mn.instructions.iterator();
    int index = 0;
    while (it.hasNext()) {
        AbstractInsnNode node = (AbstractInsnNode) it.next();
        if (node instanceof VarInsnNode) {
            VarInsnNode varNode = (VarInsnNode) node;
            int varIndex = varNode.var;
            switch (varNode.getOpcode()) {
            case Opcodes.ALOAD:
            case Opcodes.ILOAD:
            case Opcodes.FLOAD:
            case Opcodes.IALOAD:
            case Opcodes.BALOAD:
            case Opcodes.CALOAD:
            case Opcodes.AALOAD:
            case Opcodes.ASTORE:
            case Opcodes.ISTORE:
            case Opcodes.FSTORE:
            case Opcodes.IASTORE:
            case Opcodes.BASTORE:
            case Opcodes.CASTORE:
            case Opcodes.AASTORE:
                index = Math.max(index, varIndex + 1);
                break;
            case Opcodes.DLOAD:
            case Opcodes.DSTORE:
            case Opcodes.LLOAD:
            case Opcodes.LSTORE:
            case Opcodes.DALOAD:
            case Opcodes.DASTORE:
            case Opcodes.LALOAD:
            case Opcodes.LASTORE:
                index = Math.max(index, varIndex + 2);
                break;
            }/*from  ww  w.  ja  v  a 2 s.  c  om*/
        }
    }

    return index;
}

From source file:org.evosuite.testcarver.instrument.Instrumenter.java

License:Open Source License

private InsnList addCaptureCall(final boolean isStatic, final String internalClassName, final String methodName,
        final String methodDesc, final Type[] argTypes) {
    // construction of  
    //   Capturer.capture(final Object receiver, final String methodName, final Object[] methodParams)
    // call//  www . j  av  a2  s.c  o m
    final InsnList il = new InsnList();

    il.add(new LdcInsnNode(this.captureId));

    // --- load receiver argument
    int varIndex;
    if (isStatic) {
        // static method invocation
        il.add(new LdcInsnNode(internalClassName));
        il.add(new MethodInsnNode(Opcodes.INVOKESTATIC, PackageInfo.getNameWithSlash(CaptureUtil.class),
                "loadClass", "(Ljava/lang/String;)Ljava/lang/Class;"));

        varIndex = 0;
    } else {
        // non-static method call
        il.add(new VarInsnNode(Opcodes.ALOAD, 0));
        varIndex = 1;
    }

    // --- load method name argument

    il.add(new LdcInsnNode(methodName));

    // --- load method description argument

    il.add(new LdcInsnNode(methodDesc));

    // --- load methodParams arguments

    // load methodParams length
    // TODO ICONST_1 to ICONST_5 would be more efficient
    il.add(new IntInsnNode(Opcodes.BIPUSH, argTypes.length));

    // create array object
    il.add(new TypeInsnNode(Opcodes.ANEWARRAY, "java/lang/Object"));

    // fill the array

    for (int i = 0; i < argTypes.length; i++) {
        il.add(new InsnNode(Opcodes.DUP));

        // TODO ICONST_1 to ICONST_5 would be more efficient
        il.add(new IntInsnNode(Opcodes.BIPUSH, i));

        //check for primitives
        this.loadAndConvertToObject(il, argTypes[i], varIndex++);
        il.add(new InsnNode(Opcodes.AASTORE));

        // long/double take two registers
        if (argTypes[i].equals(Type.LONG_TYPE) || argTypes[i].equals(Type.DOUBLE_TYPE)) {
            varIndex++;
        }
    }

    // --- construct Capture.capture() call

    il.add(new MethodInsnNode(Opcodes.INVOKESTATIC,
            PackageInfo.getNameWithSlash(org.evosuite.testcarver.capture.Capturer.class), "capture",
            "(ILjava/lang/Object;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V"));

    return il;
}

From source file:org.glassfish.pfl.tf.spi.Util.java

License:Open Source License

public void wrapArgs(MethodVisitor mv, int access, String desc) {
    info(2, "Wrapping args for descriptor " + desc);

    Type[] atypes = Type.getArgumentTypes(desc);
    emitIntConstant(mv, atypes.length);/*from   ww w .  jav  a2 s.c  o m*/
    mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");

    int argIndex;
    if ((access & Opcodes.ACC_STATIC) == Opcodes.ACC_STATIC) {
        argIndex = 0;
    } else {
        argIndex = 1;
    }

    for (int ctr = 0; ctr < atypes.length; ctr++) {
        mv.visitInsn(Opcodes.DUP);
        emitIntConstant(mv, ctr);
        argIndex = wrapArg(mv, argIndex, atypes[ctr]);
        mv.visitInsn(Opcodes.AASTORE);
    }
}

From source file:org.gradle.model.internal.manage.schema.extract.ManagedProxyClassGenerator.java

License:Apache License

private void writeConfigureMethod(ClassVisitor visitor, Type generatedType, ModelProperty<?> property,
        boolean writable) {
    if (!writable && property.getSchema() instanceof CompositeSchema) {
        // Adds a void $propName(Closure<?> cl) method that delegates to model state

        MethodVisitor methodVisitor = declareMethod(visitor, property.getName(),
                Type.getMethodDescriptor(Type.VOID_TYPE, CLOSURE_TYPE), null);
        putNodeStateFieldValueOnStack(methodVisitor, generatedType);
        putConstantOnStack(methodVisitor, property.getName());
        putFirstMethodArgumentOnStack(methodVisitor);
        methodVisitor.visitMethodInsn(INVOKEINTERFACE, MODEL_ELEMENT_STATE_TYPE_INTERNAL_NAME, "apply",
                STATE_APPLY_METHOD_DESCRIPTOR, true);
        finishVisitingMethod(methodVisitor);
        return;//  ww w .java2s. com
    }
    if (!writable && property.getSchema() instanceof UnmanagedImplStructSchema) {
        UnmanagedImplStructSchema<?> structSchema = (UnmanagedImplStructSchema<?>) property.getSchema();
        if (!structSchema.isAnnotated()) {
            return;
        }

        // Adds a void $propName(Closure<?> cl) method that executes the closure
        MethodVisitor methodVisitor = declareMethod(visitor, property.getName(),
                Type.getMethodDescriptor(Type.VOID_TYPE, CLOSURE_TYPE), null);
        putThisOnStack(methodVisitor);
        methodVisitor.visitMethodInsn(INVOKEVIRTUAL, generatedType.getInternalName(),
                property.getGetter().getName(),
                Type.getMethodDescriptor(Type.getType(property.getType().getConcreteClass())), false);
        putFirstMethodArgumentOnStack(methodVisitor);
        methodVisitor.visitMethodInsn(INVOKESTATIC, Type.getInternalName(ClosureBackedAction.class), "execute",
                Type.getMethodDescriptor(Type.VOID_TYPE, OBJECT_TYPE, CLOSURE_TYPE), false);
        finishVisitingMethod(methodVisitor);
        return;
    }

    // Adds a void $propName(Closure<?> cl) method that throws MME, to avoid attempts to convert closure to something else
    MethodVisitor methodVisitor = declareMethod(visitor, property.getName(),
            Type.getMethodDescriptor(Type.VOID_TYPE, CLOSURE_TYPE), null);
    putThisOnStack(methodVisitor);
    putConstantOnStack(methodVisitor, property.getName());
    methodVisitor.visitInsn(Opcodes.ICONST_1);
    methodVisitor.visitTypeInsn(Opcodes.ANEWARRAY, OBJECT_TYPE.getInternalName());
    methodVisitor.visitInsn(Opcodes.DUP);
    methodVisitor.visitInsn(Opcodes.ICONST_0);
    putFirstMethodArgumentOnStack(methodVisitor);
    methodVisitor.visitInsn(Opcodes.AASTORE);
    methodVisitor.visitMethodInsn(INVOKEVIRTUAL, generatedType.getInternalName(), "methodMissing",
            METHOD_MISSING_METHOD_DESCRIPTOR, false);
    finishVisitingMethod(methodVisitor);
}

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  w w  w  .  ja v a  2 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.AbstractRuntimeData.java

License:Open Source License

/**
 * Generates code that creates the argument array for the
 * {@link #getProbes(Object[])} method. The array instance is left on the
 * operand stack. The generated code requires a stack size of 5.
 * /*from  ww  w.  j av  a2 s  .  c o m*/
 * @param classid
 *            class identifier
 * @param classname
 *            VM class name
 * @param probecount
 *            probe count for this class
 * @param mv
 *            visitor to emit generated code
 */
public static void generateArgumentArray(final long classid, final String classname, final int probecount,
        final MethodVisitor mv) {
    mv.visitInsn(Opcodes.ICONST_3);
    mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");

    // Class Id:
    mv.visitInsn(Opcodes.DUP);
    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitLdcInsn(Long.valueOf(classid));
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false);
    mv.visitInsn(Opcodes.AASTORE);

    // Class Name:
    mv.visitInsn(Opcodes.DUP);
    mv.visitInsn(Opcodes.ICONST_1);
    mv.visitLdcInsn(classname);
    mv.visitInsn(Opcodes.AASTORE);

    // Probe Count:
    mv.visitInsn(Opcodes.DUP);
    mv.visitInsn(Opcodes.ICONST_2);
    InstrSupport.push(mv, probecount);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
    mv.visitInsn(Opcodes.AASTORE);
}

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

License:Open Source License

/**
 * Generates code that creates the argument array for the
 * <code>getExecutionData()</code> method. The array instance is left on the
 * operand stack. The generated code requires a stack size of 5.
 * //from   ww  w .  ja  v a  2 s . c o  m
 * @param classid
 *            class identifier
 * @param classname
 *            VM class name
 * @param probecount
 *            probe count for this class
 * @param mv
 *            visitor to emit generated code
 */
public static void generateArgumentArray(final long classid, final String classname, final int probecount,
        final MethodVisitor mv) {
    mv.visitInsn(Opcodes.ICONST_3);
    mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");

    // Class Id:
    mv.visitInsn(Opcodes.DUP);
    mv.visitInsn(Opcodes.ICONST_0);
    mv.visitLdcInsn(Long.valueOf(classid));
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;");
    mv.visitInsn(Opcodes.AASTORE);

    // Class Name:
    mv.visitInsn(Opcodes.DUP);
    mv.visitInsn(Opcodes.ICONST_1);
    mv.visitLdcInsn(classname);
    mv.visitInsn(Opcodes.AASTORE);

    // Probe Count:
    mv.visitInsn(Opcodes.DUP);
    mv.visitInsn(Opcodes.ICONST_2);
    InstrSupport.push(mv, probecount);
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;");
    mv.visitInsn(Opcodes.AASTORE);
}

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);//from  w  w w .  j  a  v a 2 s .  co  m
    } 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
}