Example usage for org.objectweb.asm Opcodes NEWARRAY

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

Introduction

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

Prototype

int NEWARRAY

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

Click Source Link

Usage

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);//from   w w w .ja  v a  2 s.co  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.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 w  w  w  . j  a  v  a2s.c  om
 * 
 * @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();
}

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

License:Open Source License

/**
 * Create the Java code for a given class instance creation expression. The new object reference will be pushed onto
 * the operand stack. /*ww w .  j a  va  2  s  . c  o m*/
 * 
 * @param cice the class instance creation expression
 * @param context 
 * @return JavaTypeName    
 * @throws JavaGenerationException
 */
private static JavaTypeName encodeClassInstanceCreationExpr(
        final JavaExpression.ClassInstanceCreationExpression cice, final GenerationContext context)
        throws JavaGenerationException {

    final MethodVisitor mv = context.getMethodVisitor();
    final JavaTypeName classType = cice.getClassName();
    if (classType instanceof JavaTypeName.Reference.Array) {

        final JavaTypeName.Reference.Array arrayType = (JavaTypeName.Reference.Array) classType;
        final int nSizedDims = cice.getNArgs();
        if (nSizedDims == 1) {

            //for example, new String[10][][] will hit this case since it has 1 sized dimension (even though a multi-dimensional array is 
            //being created

            //push the size of the dimension
            encodeExpr(cice.getArg(0), context);

            final JavaTypeName arrayElementType = arrayType.getIncrementalElementType();
            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:
            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();
            }
            }

            return arrayType;

        } else {
            //the case of multi-dimensional arrays where more than 1 sizing dimension is supplied.

            // push args onto the stack
            for (int i = 0; i < nSizedDims; i++) {
                encodeExpr(cice.getArg(i), context);
            }

            mv.visitMultiANewArrayInsn(arrayType.getJVMInternalName(), nSizedDims);

            return arrayType;
        }

    } else if (classType instanceof JavaTypeName.Reference.Object) {

        String internalClassName = classType.getJVMInternalName();

        // create uninitialized object, duplicate the ref.
        mv.visitTypeInsn(Opcodes.NEW, internalClassName);
        mv.visitInsn(Opcodes.DUP);

        // push args onto the stack
        for (int i = 0, nArgs = cice.getNArgs(); i < nArgs; i++) {
            encodeExpr(cice.getArg(i), context);
        }

        //descriptor for the constructor
        StringBuilder descriptor = new StringBuilder("(");
        for (int i = 0, nArgs = cice.getNArgs(); i < nArgs; ++i) {
            descriptor.append(cice.getParamType(i).getJVMDescriptor());
        }
        descriptor.append(")V");

        // initialize - consumes the args and the duplicate reference.
        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, internalClassName, "<init>", descriptor.toString());

        return classType;

    } else {
        throw new JavaGenerationException("cannot create a new instance of a primitive type.");
    }
}

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

License:Open Source License

@Test
public void test_newarray() throws Exception {
    SymbolicValue size = new SymbolicValue();
    int[] opcodes = { Opcodes.NEWARRAY, Opcodes.ANEWARRAY };
    for (int opcode : opcodes) {
        ProgramState programState = execute(new Instruction(opcode), ProgramState.EMPTY_STATE.stackValue(size));
        assertThat(programState.peekValue()).isNotEqualTo(size);
        assertStack(programState, ObjectConstraint.NOT_NULL);

        assertThatThrownBy(() -> execute(new Instruction(opcode), ProgramState.EMPTY_STATE))
                .hasMessage(Printer.OPCODES[opcode] + " needs 1 values on stack");
    }/*w  ww .j a va2 s.  c  o  m*/
}

From source file:org.testeoa.estatica.AdapterDUG.java

License:Open Source License

@Override
public void visitIntInsn(int opcode, int operand) {
    String instrucao = getInstrucao(opcode);
    if (opcode == Opcodes.NEWARRAY) {
        instrucao += " " + getTipo(operand);
    } else {/*  w w  w. j  av  a  2s.c o m*/
        instrucao += " " + operand;
    }
    addInstrucao(instrucao);
    super.visitIntInsn(opcode, operand);
}

From source file:serianalyzer.JVMImpl.java

License:Open Source License

/**
 * @param opcode//from  w  ww  . ja va 2s .  co  m
 * @param operand
 * @param s
 */
static void handleJVMIntInsn(int opcode, int operand, JVMStackState s) {
    switch (opcode) {
    case Opcodes.BIPUSH:
        s.push(new BasicConstant(Type.BYTE_TYPE, operand));
        break;
    case Opcodes.SIPUSH:
        s.push(new BasicConstant(Type.SHORT_TYPE, operand));
        break;
    case Opcodes.NEWARRAY:
        s.pop();
        s.push(new BasicVariable(makeBasicArrayType(operand), "array", false)); //$NON-NLS-1$
    }
}

From source file:uk.ac.cam.cl.dtg.teaching.programmingtest.java.bytecode.InstructionCounterMethodAdapter.java

License:Open Source License

/** Deal with: NEWARRAY, BIPUSH, SIPUSH. */
@Override/*from   w w  w. j  a  va  2s.  c  om*/
public void visitIntInsn(int opcode, int operand) {
    mv.visitIntInsn(opcode, operand);
    switch (opcode) {
    case Opcodes.NEWARRAY:
        increment(INCREMENT_ALLOCATION);
        break;
    default:
        increment(INCREMENT_INSTRUCTION);
    }
}

From source file:v6.java.preverifier.PreverifierMethodNode.java

License:Open Source License

/**
 * @see org.objectweb.asm.MethodVisitor#visitIntInsn(int, int)
 *///from  w w  w  .j ava  2  s .  c o m
public void visitIntInsn(int opcode, int operand) {
    if (opcode == Opcodes.NEWARRAY) {
        if ((operand == Opcodes.T_DOUBLE) || (operand == Opcodes.T_FLOAT)) {
            ClassNodeErrorInformation classInfo = new ClassNodeErrorInformation(classNode);
            MethodNodeErrorInformation methodInfo = new MethodNodeErrorInformation(classInfo, this);

            PreverificationErrorLocation location = new PreverificationErrorLocation(
                    PreverificationErrorLocationType.METHOD_INSTRUCTION, classInfo, methodInfo, null,
                    lineNumber);
            PreverificationError error = new PreverificationError(PreverificationErrorType.FLOATING_POINT,
                    location, null);
            addError(error);
        }
    }

    super.visitIntInsn(opcode, operand);
}