Example usage for org.objectweb.asm Opcodes ANEWARRAY

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

Introduction

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

Prototype

int ANEWARRAY

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

Click Source Link

Usage

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;/*from w  w w.j  av  a2  s .  c o  m*/
    }
    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 visitTypeInsn(final int opcode, final String type) {
    switch (opcode) {
    case Opcodes.NEW:
        final Label label = new Label();
        mv.visitLabel(label);//w  w  w. ja  v a 2  s  .  c o  m
        push(label);
        break;
    case Opcodes.ANEWARRAY:
        pop(1);
        push('[' + Type.getObjectType(type).getDescriptor());
        break;
    case Opcodes.CHECKCAST:
        pop(1);
        push(type);
        break;
    case Opcodes.INSTANCEOF:
        pop(1);
        push(Opcodes.INTEGER);
        break;
    default:
        throw new IllegalArgumentException();
    }
    mv.visitTypeInsn(opcode, type);
}

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.
 * //  w  ww.  j  ava2 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.
 * //www  .ja v a  2 s.  c  om
 * @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.agent.adapter.RuleGeneratorAdapter.java

License:Open Source License

/**
 * Generates the instruction to create a new array.
 *
 * @param type the type of the array elements.
 *///from w w  w.ja v  a2  s. c  om
public void newArray(final Type type) {
    int typ;
    switch (type.getSort()) {
    case Type.BOOLEAN:
        typ = Opcodes.T_BOOLEAN;
        break;
    case Type.CHAR:
        typ = Opcodes.T_CHAR;
        break;
    case Type.BYTE:
        typ = Opcodes.T_BYTE;
        break;
    case Type.SHORT:
        typ = Opcodes.T_SHORT;
        break;
    case Type.INT:
        typ = Opcodes.T_INT;
        break;
    case Type.FLOAT:
        typ = Opcodes.T_FLOAT;
        break;
    case Type.LONG:
        typ = Opcodes.T_LONG;
        break;
    case Type.DOUBLE:
        typ = Opcodes.T_DOUBLE;
        break;
    default:
        typeInsn(Opcodes.ANEWARRAY, type);
        return;
    }
    visitIntInsn(Opcodes.NEWARRAY, typ);
}

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

    Type baseType = getType().getBaseType();
    int currentStack = compileContext.getStackCount();
    int expected = 1;
    int length = elements.size();

    // stack array size and then create the array
    mv.visitLdcInsn(length);/*w ww .j  a v  a 2 s .c om*/
    compileContext.addStackCount(1);
    // new array pops count and pushes array so no change to stack size
    if (baseType.isArray()) {
        mv.visitMultiANewArrayInsn(getType().getInternalName(), 1);
    } else if (baseType.isObject()) {
        mv.visitTypeInsn(Opcodes.ANEWARRAY, baseType.getInternalName());
    } else {
        int operand = 0;
        if (baseType.equals(Type.Z)) {
            operand = Opcodes.T_BOOLEAN;
        } else if (baseType.equals(Type.B)) {
            operand = Opcodes.T_BYTE;
        } else if (baseType.equals(Type.S)) {
            operand = Opcodes.T_SHORT;
        } else if (baseType.equals(Type.C)) {
            operand = Opcodes.T_CHAR;
        } else if (baseType.equals(Type.I)) {
            operand = Opcodes.T_INT;
        } else if (baseType.equals(Type.J)) {
            operand = Opcodes.T_LONG;
        } else if (baseType.equals(Type.F)) {
            operand = Opcodes.T_FLOAT;
        } else if (baseType.equals(Type.D)) {
            operand = Opcodes.T_DOUBLE;
        }
        mv.visitIntInsn(Opcodes.NEWARRAY, operand);
    }

    int idx = 0;
    boolean isTwoWords = (baseType.getNBytes() > 4);

    for (Expression element : elements) {
        int toPop = 0;
        // copy array so we can assign it -- adds one to height
        mv.visitInsn(Opcodes.DUP);
        // compile expression index -- adds 1 to height
        mv.visitLdcInsn(idx++);
        compileContext.addStackCount(2);
        // compile value -- adds one or two words to height
        element.compile(mv, compileContext);
        // ensure we have the correct value type
        compileContext.compileTypeConversion(element.type, baseType);
        // now we can do the array store
        if (baseType.isObject() || baseType.isArray()) {
            // compile load object - pops 3
            mv.visitInsn(Opcodes.AASTORE);
            toPop = -3;
        } else if (baseType == Type.Z || baseType == Type.B) {
            // compile load byte - pops 3
            mv.visitInsn(Opcodes.BASTORE);
            toPop = -3;
        } else if (baseType == Type.S) {
            // compile load short - pops 3
            mv.visitInsn(Opcodes.SASTORE);
            toPop = -3;
        } else if (baseType == Type.C) {
            // compile load char - pops 3
            mv.visitInsn(Opcodes.CASTORE);
            toPop = -3;
        } else if (baseType == Type.I) {
            // compile load int - pops 3
            mv.visitInsn(Opcodes.IASTORE);
            toPop = -3;
        } else if (baseType == Type.J) {
            // compile load long - pops 4
            mv.visitInsn(Opcodes.LASTORE);
            toPop = -4;
        } else if (baseType == Type.F) {
            // compile load float - pops 3
            mv.visitInsn(Opcodes.FASTORE);
            toPop = -3;
        } else if (baseType == Type.D) {
            // compile load double - pops 4
            mv.visitInsn(Opcodes.DASTORE);
            toPop = -4;
        }
        // pop the appropriate number of elements off the stack
        compileContext.addStackCount(toPop);
    }

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

    // no need to update stack max
}

From source file:org.jboss.byteman.rule.expression.MethodExpression.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 extraParams = 0; // space used by stacked args after conversion
    int expected = 0;

    // no need for type conversion as return type was derived from method
    if (type.getNBytes() > 4) {
        expected = 2;/*from w  w  w .  j a  va2 s. com*/
    } else if (type != Type.VOID) {
        expected = 1;
    } else {
        expected = 0;
    }

    int argCount = arguments.size();

    if (isPublicMethod) {
        // we can just do this as a direct call
        // stack the recipient if necessary then stack the args and then invoke the method
        if (recipient != null) {
            // compile code for recipient
            recipient.compile(mv, compileContext);

            extraParams += 1;
        }

        for (int i = 0; i < argCount; i++) {
            Expression argument = arguments.get(i);
            Type argType = argumentTypes.get(i);
            Type paramType = paramTypes.get(i);
            // compile code to stack argument and type convert if necessary
            argument.compile(mv, compileContext);
            compileTypeConversion(argType, paramType, mv, compileContext);
            // allow for stacked paramType value
            extraParams += (paramType.getNBytes() > 4 ? 2 : 1);
        }

        // enable triggering before we call the method
        // this adds an extra value to the stack so modify the compile context to ensure
        // we increase the maximum height if necessary
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/jboss/byteman/rule/Rule", "enableTriggersInternal",
                "()Z");
        compileContext.addStackCount(1);
        mv.visitInsn(Opcodes.POP);
        compileContext.addStackCount(-1);

        // ok, now just call the method -- removes extraParams words

        String ownerName = Type.internalName(method.getDeclaringClass());

        if (recipient == null) {
            mv.visitMethodInsn(Opcodes.INVOKESTATIC, ownerName, method.getName(), getDescriptor());
        } else if (method.getDeclaringClass().isInterface()) {
            mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, ownerName, method.getName(), getDescriptor());
        } else {
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, ownerName, method.getName(), getDescriptor());
        }
        // decrement the stack height to account for stacked param values (removed) and return value (added)
        compileContext.addStackCount(expected - extraParams);

        // now disable triggering again
        // this temporarily adds an extra value to the stack -- n.b. we *must* increment and
        // then decrement the stack height even though we bumped the max before the call. in
        // some cases the stack may be larger after the method call than before e.g. calling
        // a static which returns a value or calling a non-static which returns a long/double

        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/jboss/byteman/rule/Rule", "disableTriggersInternal",
                "()Z");
        compileContext.addStackCount(1);
        mv.visitInsn(Opcodes.POP);
        compileContext.addStackCount(-1);
    } else {
        // if we are calling a method by reflection then we need to stack the current helper then
        // the recipient or null if there is none and then build an object array on the stack
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        compileContext.addStackCount(1);
        if (recipient != null) {
            // compile code for recipient
            recipient.compile(mv, compileContext);
        } else {
            mv.visitInsn(Opcodes.ACONST_NULL);
            compileContext.addStackCount(1);
        }

        // stack arg count then create a new array
        mv.visitLdcInsn(argCount);
        compileContext.addStackCount(1);
        // this just swaps one word for another
        mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");

        // duplicate the array, stack the index, compile code to generate the arg and the do an array put
        for (int i = 0; i < argCount; i++) {
            mv.visitInsn(Opcodes.DUP);
            mv.visitLdcInsn(i);
            // that was two extra words
            compileContext.addStackCount(2);
            Expression argument = arguments.get(i);
            Type argType = argumentTypes.get(i);
            Type paramType = paramTypes.get(i);
            // compile code to stack argument and type convert/box if necessary
            argument.compile(mv, compileContext);
            compileTypeConversion(argType, paramType, mv, compileContext);
            compileBox(paramType, mv, compileContext);
            // that's 3 extra words which now get removed
            mv.visitInsn(Opcodes.AASTORE);
            compileContext.addStackCount(-3);
        }
        // now stack the method object index
        mv.visitLdcInsn(methodIndex);
        compileContext.addStackCount(1);

        // enable triggering before we call the method
        // this adds an extra value to the stack so modify the compile context to ensure
        // we increase the maximum height if necessary
        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/jboss/byteman/rule/Rule", "enableTriggersInternal",
                "()Z");
        compileContext.addStackCount(1);
        mv.visitInsn(Opcodes.POP);
        compileContext.addStackCount(-1);

        // ok, we  now have the recipient, args array and method index on the stack
        // so we can call the HelperAdapter method  to do the actual reflective invocation
        mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, Type.internalName(HelperAdapter.class),
                "invokeAccessibleMethod", "(Ljava/lang/Object;[Ljava/lang/Object;I)Ljava/lang/Object;");
        // we popped 4 words and left one in its place
        compileContext.addStackCount(-3);
        if (type == Type.VOID) {
            mv.visitInsn(Opcodes.POP);
            compileContext.addStackCount(-1);
        } else {
            // do any necessary casting and/or unboxing
            compileTypeConversion(Type.OBJECT, type, mv, compileContext);
        }

        // now disable triggering again
        // this temporarily adds an extra value to the stack -- n.b. no need to increment and
        // then decrement the stack height here because the previous enable call will already have
        // bumped the max when we had 4 slots on the stack and any return value on the stack will
        // occupy at most 2 slots

        mv.visitMethodInsn(Opcodes.INVOKESTATIC, "org/jboss/byteman/rule/Rule", "disableTriggersInternal",
                "()Z");
        compileContext.addStackCount(1);
        mv.visitInsn(Opcodes.POP);
        compileContext.addStackCount(-1);
    }

    // ensure we have only increased the stack by the return value size
    if (compileContext.getStackCount() != currentStack + expected) {
        throw new CompileException("MethodExpression.compile : invalid stack height "
                + compileContext.getStackCount() + " expecting " + (currentStack + expected));
    }

    // no need to update max stack since compiling the  recipient or arguments will
    // have done so (and there will be no change if there was no such compile call)
}

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

    if (arrayDimCount == 0) {
        // ok, we need to create the new instance and then initialise it.

        // create the new instance -- adds 1 to stack
        String instantiatedClassName = type.getInternalName();
        mv.visitTypeInsn(Opcodes.NEW, instantiatedClassName);
        compileContext.addStackCount(1);
        // copy the exception so we can init it
        mv.visitInsn(Opcodes.DUP);/*www .  j a va  2 s.  c  o m*/
        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, instantiatedClassName, "<init>", getDescriptor());

        // modify the stack height to account for the removed exception and params
        compileContext.addStackCount(-(extraParams + 1));
    } else {
        // TODO !!! implement compilation for array types !!!
        if (arrayDimCount == 1) {
            // we can use a NEWARRAY or ANEWARRAY
            Type baseType = type.getBaseType();
            // compile first array dimension adds 1 to stack
            arrayDims.get(0).compile(mv, compileContext);
            // compile new array op -- pops 1 and adds 1 to stack
            if (baseType.isObject()) {
                mv.visitTypeInsn(Opcodes.ANEWARRAY, baseType.getInternalName());
                // } else if (baseType.isArray()) {  // cannot happen!!!
            } else {
                int operand = 0;
                if (baseType.equals(Type.Z)) {
                    operand = Opcodes.T_BOOLEAN;
                } else if (baseType.equals(Type.B)) {
                    operand = Opcodes.T_BYTE;
                } else if (baseType.equals(Type.S)) {
                    operand = Opcodes.T_SHORT;
                } else if (baseType.equals(Type.C)) {
                    operand = Opcodes.T_CHAR;
                } else if (baseType.equals(Type.I)) {
                    operand = Opcodes.T_INT;
                } else if (baseType.equals(Type.J)) {
                    operand = Opcodes.T_LONG;
                } else if (baseType.equals(Type.F)) {
                    operand = Opcodes.T_FLOAT;
                } else if (baseType.equals(Type.D)) {
                    operand = Opcodes.T_DOUBLE;
                }
                mv.visitIntInsn(Opcodes.NEWARRAY, operand);
            }
        } else {
            // we need to use MULTIANEWARRAY

            for (int i = 0; i < arrayDimDefinedCount; i++) {
                // compile next array dimension adds 1 to stack
                arrayDims.get(i).compile(mv, compileContext);
            }
            // execute the MULTIANEWARRAY operation -- pops arrayDims operands and pushes 1
            mv.visitMultiANewArrayInsn(type.getInternalName(), arrayDimDefinedCount);
            compileContext.addStackCount(1 - arrayDimDefinedCount);
        }
    }

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

From source file:org.lambdamatic.analyzer.ast.LambdaExpressionReader.java

License:Open Source License

/**
 * Reads the given {@link TypeInsnNode} instruction.
 * /*from   ww  w.j  a va2 s. c  o m*/
 * @param typeInsnNode the instruction to read
 * @param expressionStack the expression stack to put on or pop from.
 * @param localVariables the local variables
 */
private static void readTypeInstruction(final TypeInsnNode typeInsnNode,
        final Stack<Expression> expressionStack, final LocalVariables localVariables) {
    switch (typeInsnNode.getOpcode()) {
    case Opcodes.NEW:
        final Type instanceType = Type.getObjectType(typeInsnNode.desc);
        final ObjectInstanciation objectVariable = new ObjectInstanciation(getType(instanceType));
        expressionStack.push(objectVariable);
        break;
    case Opcodes.ANEWARRAY:
        final Type parameterType = Type.getObjectType(typeInsnNode.desc);
        final NumberLiteral arrayLength = (NumberLiteral) expressionStack.pop();
        final ArrayVariable arrayVariable = new ArrayVariable(getArrayType(parameterType),
                arrayLength.getValue().intValue());
        expressionStack.push(arrayVariable);
        break;
    default:
        LOGGER.warn("TypeInsnNode with OpCode {} was ignored.", typeInsnNode.getOpcode());
    }
}

From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java

License:Open Source License

/**
 * Creates and initializes a 1-dimensional array (as specified by arrayCreationExpr) and then pushes a reference
 * to the array onto the stack./*from   ww  w  .j  ava  2 s  .  co  m*/
 * 
 * @param arrayCreationExpr
 * @param context
 * @return JavaTypeName the type of the result on the operand stack. 
 * @throws JavaGenerationException
 */
private static JavaTypeName encodeArrayCreationExpr(JavaExpression.ArrayCreationExpression arrayCreationExpr,
        GenerationContext context) throws JavaGenerationException {

    MethodVisitor mv = context.getMethodVisitor();
    final int nArrayElements = arrayCreationExpr.getNElementValues();

    //push the n of elements of the array onto the stack.       
    encodePushIntValue(nArrayElements, context);

    JavaTypeName arrayElementType = arrayCreationExpr.getArrayElementTypeName();
    switch (arrayElementType.getTag()) {

    case JavaTypeName.VOID_TAG:
        throw new JavaGenerationException("Cannot have an array of with void element types.");

    case JavaTypeName.BOOLEAN_TAG:
    case JavaTypeName.BYTE_TAG:
    case JavaTypeName.SHORT_TAG:
    case JavaTypeName.CHAR_TAG:
    case JavaTypeName.INT_TAG:
    case JavaTypeName.LONG_TAG:
    case JavaTypeName.DOUBLE_TAG:
    case JavaTypeName.FLOAT_TAG: {
        //push the instruction to create a 1-dimensonal array of primitive values
        mv.visitIntInsn(Opcodes.NEWARRAY, getNewArrayArgCode(arrayElementType));
        break;
    }

    case JavaTypeName.ARRAY_TAG: {
        throw new JavaGenerationException(
                "JavaExpression.ArrayCreationExpression supports only 1 dimensional arrays.");
    }

    case JavaTypeName.OBJECT_TAG: {
        //push the instruction to create a 1-dimensonal array of reference values
        mv.visitTypeInsn(Opcodes.ANEWARRAY, arrayElementType.getJVMInternalName());
        break;
    }

    default: {
        throw new IllegalArgumentException();
    }
    }

    final int arrayElemStoreCode = getArrayStoreOpCode(arrayElementType);

    //now initialize the elements of the array
    for (int i = 0; i < nArrayElements; ++i) {
        //duplicate the array reference on the stack
        mv.visitInsn(Opcodes.DUP);

        //push i
        encodePushIntValue(i, context);

        //push the code to evalaute the ith element expression
        encodeExpr(arrayCreationExpr.getElementValue(i), context);

        //array[i] = elementExpr           
        mv.visitInsn(arrayElemStoreCode);
    }

    return arrayElementType.makeArrayType();
}