List of usage examples for org.objectweb.asm Opcodes DUP
int DUP
To view the source code for org.objectweb.asm Opcodes DUP.
Click Source Link
From source file:org.mbte.groovypp.compiler.bytecode.BytecodeExpr.java
License:Apache License
public static void dup(ClassNode type, MethodVisitor mv) { if (type == double_TYPE || type == long_TYPE) mv.visitInsn(Opcodes.DUP2);// w ww . j a v a 2 s .co m else mv.visitInsn(Opcodes.DUP); }
From source file:org.mbte.groovypp.compiler.ClosureUtil.java
License:Apache License
public static void instantiateClass(ClassNode type, CompilerTransformer compiler, Parameter[] constrParams, Expression superArgs, MethodVisitor mv) { TraitASTTransformFinal.improveAbstractMethods(type); type.getModule().addClass(type);//from w ww . j a va 2 s .c o m final String classInternalName = BytecodeHelper.getClassInternalName(type); mv.visitTypeInsn(Opcodes.NEW, classInternalName); mv.visitInsn(Opcodes.DUP); final ConstructorNode constructorNode = type.getDeclaredConstructors().get(0); for (int i = 0; i != constrParams.length; i++) { String name = constrParams[i].getName(); if ("this$0".equals(name)) { mv.visitVarInsn(Opcodes.ALOAD, 0); } else { final Register var = compiler.compileStack.getRegister(name, false); if (var != null) { FieldNode field = type.getDeclaredField(name); BytecodeExpr.load(field.getType(), var.getIndex(), mv); if (!constrParams[i].getType().equals(var.getType()) && !ClassHelper.isPrimitiveType(field.getType())) { BytecodeExpr.checkCast(constrParams[i].getType(), mv); } } else { FieldNode field = compiler.methodNode.getDeclaringClass().getDeclaredField(name); mv.visitVarInsn(Opcodes.ALOAD, 0); if (field == null) // @Field name = compiler.methodNode.getName() + "$" + name; mv.visitFieldInsn(Opcodes.GETFIELD, BytecodeHelper.getClassInternalName(compiler.methodNode.getDeclaringClass()), name, BytecodeHelper.getTypeDescription(constrParams[i].getType())); } } } if (superArgs != null) { final List<Expression> list = ((ArgumentListExpression) superArgs).getExpressions(); for (int i = 0; i != list.size(); ++i) ((BytecodeExpr) list.get(i)).visit(mv); } mv.visitMethodInsn(Opcodes.INVOKESPECIAL, classInternalName, "<init>", BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, constructorNode.getParameters())); }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
/** * Encode a method invocation that is wrapped in a synchronized block. * See Sun bug id #4414101 for a discussion of this generated code. * //from ww w. j av a 2s . com * @param smi - the SynchronizedMethodInvocation object. * @param context - the context of the code generation. * @return - true if the SynchronizedMethodInvocation is terminating. * @throws JavaGenerationException */ private static boolean encodeSynchronizedMethodInvocation(JavaStatement.SynchronizedMethodInvocation smi, GenerationContext context) throws JavaGenerationException { MethodVisitor mv = context.getMethodVisitor(); // Get the JavaExpression for the object to synchronize on and generate the bytecode. JavaExpression objectToSynchOn = smi.getSynchronizingObject(); encodeExpr(objectToSynchOn, context); // The object to synchronize on is now on the stack. Duplicate it, // move one to storage as a local variable, and to MONITORENTER on the other. mv.visitInsn(Opcodes.DUP); int mutexIndex = context.addLocalVar("$mutex", JavaTypeName.OBJECT); mv.visitVarInsn(Opcodes.ASTORE, mutexIndex); mv.visitInsn(Opcodes.MONITORENTER); // We need to wrap the method invocation in a try/catch block so // the monitor can be exited properly if the method invocation throws // an exception. Label tryCatchStart = new Label(); mv.visitLabel(tryCatchStart); // Note: if this is generalized to handle any synchronized statement (for example, a synchronized block), // then the scope of entries in the exception table here will have to be modified to exclude return instructions. // See encodeTryCatchStatement() for how to do this. // Here, the only statement in the try block is a single expressionStatement, which has no return instructions, // so we don't have to worry about handling this case. // Get the method invocation and generate the corresponding bytecode. MethodInvocation methodInvocation = smi.getMethodInvocation(); encodeExpr(methodInvocation, context); // Load the mutex object back onto the stack and do MonitorExit. mv.visitVarInsn(Opcodes.ALOAD, mutexIndex); mv.visitInsn(Opcodes.MONITOREXIT); // Label the end of the try block around the method invocation. Label tryEnd = new Label(); mv.visitLabel(tryEnd); // At this point we want to code an instruction to jump past the exception handling // code. Label tryCatchEnd = new Label(); mv.visitJumpInsn(Opcodes.GOTO, tryCatchEnd); // Label the start of the exception handling code. Label catchStart = new Label(); mv.visitLabel(catchStart); // The exception is on the stack. Store it as a local. int exceptionIndex = context.addLocalVar("exception", JavaTypeName.OBJECT); mv.visitVarInsn(Opcodes.ASTORE, exceptionIndex); // Retrieve the mutex object and do MONITOREXIT. mv.visitVarInsn(Opcodes.ALOAD, mutexIndex); mv.visitInsn(Opcodes.MONITOREXIT); // Label the end of the exception handling code that deals with the monitor. Label exceptionMonitorExitEnd = new Label(); mv.visitLabel(exceptionMonitorExitEnd); // Retrieve the exception and throw it. mv.visitVarInsn(Opcodes.ALOAD, exceptionIndex); mv.visitInsn(Opcodes.ATHROW); // Vist the label to mark the end of the try/catch. mv.visitLabel(tryCatchEnd); // Set up the try/catch block to catch exceptions thrown by the method invocation // and handle exiting the monitor. mv.visitTryCatchBlock(tryCatchStart, tryEnd, catchStart, null); // Set up a try catch block so that if an exception is thrown by trying to exit // the monitor in the case of an exception from the method invocation we will keep trying to // exit the monitor. mv.visitTryCatchBlock(catchStart, exceptionMonitorExitEnd, catchStart, null); return false; }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
/** * @param type/*from w ww . j a va2s . co m*/ * @return the DUP or DUP2 instruction, depending on type. */ private static int getDupOpCode(JavaTypeName type) { switch (type.getTag()) { case JavaTypeName.BOOLEAN_TAG: case JavaTypeName.BYTE_TAG: case JavaTypeName.SHORT_TAG: case JavaTypeName.CHAR_TAG: case JavaTypeName.INT_TAG: case JavaTypeName.FLOAT_TAG: case JavaTypeName.ARRAY_TAG: case JavaTypeName.OBJECT_TAG: return Opcodes.DUP; case JavaTypeName.LONG_TAG: case JavaTypeName.DOUBLE_TAG: return Opcodes.DUP2; case JavaTypeName.VOID_TAG: default: { throw new IllegalArgumentException("invalid type: " + type); } } }
From source file:org.openquark.cal.internal.javamodel.AsmJavaBytecodeGenerator.java
License:Open Source License
/** * Encodes the Java code for a given Java operator expression. * //from ww w. j av a 2 s . co m * @param operatorExpr the java operator expression * @param context * @return JavaTypeName * @throws JavaGenerationException */ private static JavaTypeName encodeOperatorExpr(JavaExpression.OperatorExpression operatorExpr, GenerationContext context) throws JavaGenerationException { MethodVisitor mv = context.getMethodVisitor(); JavaOperator operator = operatorExpr.getJavaOperator(); String symbol = operator.getSymbol(); JavaTypeName valueType = operator.getValueType(); // Now carry out the operation according to its type. if (operator.isArithmeticOp()) { // Add the instructions to evaluate the first argument. JavaTypeName arg1Type = encodeExpr(operatorExpr.getArgument(0), context); if (operatorExpr instanceof OperatorExpression.Unary) { if (symbol.equals("-")) { // number negation mv.visitInsn(getNegateOpCode(arg1Type)); return arg1Type; } throw new JavaGenerationException("Unknown unary arithmetic operator " + symbol + "."); } // Add an instruction to widen the argument if necessary. int wideningOpCode = getWideningOpCode(arg1Type, valueType); if (wideningOpCode != Opcodes.NOP) { mv.visitInsn(wideningOpCode); } // Add the instructions to evaluate the second argument. JavaTypeName arg2Type = encodeExpr(operatorExpr.getArgument(1), context); // Add an instruction to widen the argument if necessary. wideningOpCode = getWideningOpCode(arg2Type, valueType); if (wideningOpCode != Opcodes.NOP) { mv.visitInsn(wideningOpCode); } // Evaluate. mv.visitInsn(getArithmeticBinaryOpCode(symbol, valueType)); return valueType; } if (operator.isBitOp()) { // Add the instructions to evaluate the first argument. JavaTypeName arg1Type = encodeExpr(operatorExpr.getArgument(0), context); // Add an instruction to widen the argument if necessary. int wideningOpCode = getWideningOpCode(arg1Type, valueType); if (wideningOpCode != Opcodes.NOP) { mv.visitInsn(wideningOpCode); } if (operatorExpr instanceof OperatorExpression.Unary) { if (symbol.equals("~")) { // number negation if (valueType == JavaTypeName.INT) { mv.visitInsn(Opcodes.ICONST_M1); mv.visitInsn(Opcodes.IXOR); return valueType; } else if (valueType == JavaTypeName.LONG) { encodePushLongValue(new Long(-1), context); mv.visitInsn(Opcodes.LXOR); return valueType; } } throw new JavaGenerationException("Unknown unary arithmetic operator " + symbol + "."); } // Add the instructions to evaluate the second argument. JavaTypeName arg2Type = encodeExpr(operatorExpr.getArgument(1), context); // If this is >>, >>>, or << we may need to narrow the second argument to an int if (symbol.equals(">>") || symbol.equals(">>>") || symbol.equals("<<")) { if (arg2Type == JavaTypeName.LONG) { mv.visitInsn(Opcodes.L2I); } } else { // Add an instruction to widen the argument if necessary. wideningOpCode = getWideningOpCode(arg2Type, valueType); if (wideningOpCode != Opcodes.NOP) { mv.visitInsn(wideningOpCode); } } // Evaluate. mv.visitInsn(getArithmeticBinaryOpCode(symbol, valueType)); return valueType; } if (operator.isLogicalOp() || operator.isRelationalOp()) { // Logical op: {"!", "&&", "||"} // Relational op: {">", ">=", "<", "<=", "==", "!="} Label trueContinuation = new Label(); Label falseContinuation = new Label(); encodeBooleanValuedOperatorHelper(operatorExpr, context, trueContinuation, falseContinuation); return encodeThenTrueElseFalse(trueContinuation, falseContinuation, context); } if (operator == JavaOperator.STRING_CONCATENATION) { // Create an uninitialized StringBuilder, duplicate the reference (so we can invoke the initializer). mv.visitTypeInsn(Opcodes.NEW, "java/lang/StringBuilder"); mv.visitInsn(Opcodes.DUP); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V"); // append the first arg. JavaTypeName firstArgType = encodeExpr(operatorExpr.getArgument(0), context); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", getAppendJVMDescriptor(firstArgType)); // Append the results of evaluation of the second arg. // Note that, conveniently, StringBuilder has an append() method for all the different types. JavaTypeName secondArgType = encodeExpr(operatorExpr.getArgument(1), context); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "append", getAppendJVMDescriptor(secondArgType)); // Call toString() on the result. mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;"); return JavaTypeName.STRING; } return encodeTernaryOperatorExpr((OperatorExpression.Ternary) operatorExpr, context); }
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 va 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(); }
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. /*from w w w .j a va2 s. co 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.parboiled.compiler.notNullVerification.MyMethodAdapter.java
License:Apache License
@Override public void visitInsn(int opcode) { if (opcode == Opcodes.ARETURN && myIsNotNull) { mv.visitInsn(Opcodes.DUP); if (myThrowLabel == null) { Label skipLabel = new Label(); mv.visitJumpInsn(Opcodes.IFNONNULL, skipLabel); myThrowLabel = new Label(); mv.visitLabel(myThrowLabel); generateThrow("java/lang/IllegalStateException", "@NotNull method " + getFullMethodName() + " must not return null", skipLabel); } else {/*from w ww .j a v a 2s . co m*/ mv.visitJumpInsn(Opcodes.IFNULL, myThrowLabel); } } mv.visitInsn(opcode); }
From source file:org.parboiled.compiler.notNullVerification.MyMethodAdapter.java
License:Apache License
private void generateThrow(String exceptionClass, String descr, Label end) { String exceptionParamClass = "(Ljava/lang/String;)V"; mv.visitTypeInsn(Opcodes.NEW, exceptionClass); mv.visitInsn(Opcodes.DUP); mv.visitLdcInsn(descr);// w w w . j ava2s. co m mv.visitMethodInsn(Opcodes.INVOKESPECIAL, exceptionClass, NotNullVerifyingInstrumenter.CONSTRUCTOR_NAME, exceptionParamClass); mv.visitInsn(Opcodes.ATHROW); mv.visitLabel(end); instrumenter.myIsModification = true; }
From source file:org.pitest.mutationtest.engine.gregor.mutators.experimental.extended.UOIMutator1.java
License:Apache License
@Override public void visitVarInsn(int opcode, int var) { mv.visitVarInsn(opcode, var); switch (opcode) { case Opcodes.ILOAD: if (this.shouldMutate("Incremented (a++) integer local variable number " + var)) { mv.visitIincInsn(var, 1); }//from w w w . j av a 2s .c o m break; case Opcodes.FLOAD: if (this.shouldMutate("Incremented (a++) float local variable number " + var)) { mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.FCONST_1); mv.visitInsn(Opcodes.FADD); mv.visitVarInsn(Opcodes.FSTORE, var); } break; case Opcodes.LLOAD: if (this.shouldMutate("Incremented (a++) long local variable number " + var)) { mv.visitInsn(Opcodes.DUP2); mv.visitInsn(Opcodes.LCONST_1); mv.visitInsn(Opcodes.LADD); mv.visitVarInsn(Opcodes.LSTORE, var); } break; case Opcodes.DLOAD: if (this.shouldMutate("Incremented (a++) double local variable number " + var)) { mv.visitInsn(Opcodes.DUP2); mv.visitInsn(Opcodes.DCONST_1); mv.visitInsn(Opcodes.DADD); mv.visitVarInsn(Opcodes.DSTORE, var); } break; default: break; } }