List of usage examples for org.objectweb.asm MethodVisitor visitJumpInsn
public void visitJumpInsn(final int opcode, final Label label)
From source file:org.codehaus.groovy.classgen.asm.BinaryIntExpressionHelper.java
License:Apache License
/** * writes a std compare. This involves the tokens IF_ICMPEQ, IF_ICMPNE, * IF_ICMPEQ, IF_ICMPNE, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE and IF_ICMPLT * @param type the token type/*from ww w . j a v a2 s .c o m*/ * @return true if a successful std compare write */ protected boolean writeStdCompare(int type, boolean simulate) { type = type - COMPARE_NOT_EQUAL; // look if really compare if (type < 0 || type > 7) return false; if (!simulate) { MethodVisitor mv = getController().getMethodVisitor(); OperandStack operandStack = getController().getOperandStack(); // operands are on the stack already int bytecode = stdCompareCodes[type]; Label l1 = new Label(); mv.visitJumpInsn(bytecode, l1); mv.visitInsn(ICONST_1); Label l2 = new Label(); mv.visitJumpInsn(GOTO, l2); mv.visitLabel(l1); mv.visitInsn(ICONST_0); mv.visitLabel(l2); operandStack.replace(ClassHelper.boolean_TYPE, 2); } return true; }
From source file:org.codehaus.groovy.classgen.asm.BinaryIntExpressionHelper.java
License:Apache License
/** * writes the spaceship operator, type should be COMPARE_TO * @param type the token type//from w w w . j a v a2s. c o m * @return true if a successful spaceship operator write */ protected boolean writeSpaceship(int type, boolean simulate) { if (type != COMPARE_TO) return false; /* we will actually do (x < y) ? -1 : ((x == y) ? 0 : 1) which is the essence of what the call with Integers would do this compiles to something along <x> <y> IF_ICMPGE L1 ICONST_M1 GOTO L2 L1 <x> <y> IF_ICMPNE L3 ICONST_0 GOTO L2 L3 ICONST_1 L2 since the operators are already on the stack and we don't want to load them again, we will instead duplicate them. This will require some pop actions in the branches! DUP2 (operands: IIII) IF_ICMPGE L1 (operands: II) ICONST_M1 (operands: III) GOTO L2 L1 ----- (operands: II) IF_ICMPNE L3 (operands: -) ICONST_0 (operands: I) GOTO L2 L3 - jump from L1 branch to here (operands: -) ICONST_1 (operands: I) L2 - if jump from GOTO L2 we have III, but need only I - if from L3 branch we get only I this means we have to pop of II before loading -1 */ if (!simulate) { MethodVisitor mv = getController().getMethodVisitor(); // duplicate int arguments mv.visitInsn(DUP2); Label l1 = new Label(); mv.visitJumpInsn(IF_ICMPGE, l1); // no jump, so -1, need to pop off surplus II mv.visitInsn(POP2); mv.visitInsn(ICONST_M1); Label l2 = new Label(); mv.visitJumpInsn(GOTO, l2); mv.visitLabel(l1); Label l3 = new Label(); mv.visitJumpInsn(IF_ICMPNE, l3); mv.visitInsn(ICONST_0); mv.visitJumpInsn(GOTO, l2); mv.visitLabel(l3); mv.visitInsn(ICONST_1); getController().getOperandStack().replace(ClassHelper.int_TYPE, 2); } return true; }
From source file:org.codehaus.groovy.classgen.asm.BytecodeHelper.java
License:Apache License
/** * Negate a boolean on stack./*w w w . j a v a 2 s . c om*/ */ public static void negateBoolean(MethodVisitor mv) { // code to negate the primitive boolean Label endLabel = new Label(); Label falseLabel = new Label(); mv.visitJumpInsn(IFNE, falseLabel); mv.visitInsn(ICONST_1); mv.visitJumpInsn(GOTO, endLabel); mv.visitLabel(falseLabel); mv.visitInsn(ICONST_0); mv.visitLabel(endLabel); }
From source file:org.codehaus.groovy.classgen.asm.BytecodeHelper.java
License:Apache License
/** * Converts a primitive type to boolean. * * @param mv method visitor// w w w . j ava2 s . co m * @param type primitive type to convert */ public static void convertPrimitiveToBoolean(MethodVisitor mv, ClassNode type) { if (type == boolean_TYPE) { return; } // Special handling is done for floating point types in order to // handle checking for 0 or NaN values. if (type == double_TYPE) { convertDoubleToBoolean(mv); return; } else if (type == float_TYPE) { convertFloatToBoolean(mv); return; } Label trueLabel = new Label(); Label falseLabel = new Label(); // Convert long to int for IFEQ comparison using LCMP if (type == long_TYPE) { mv.visitInsn(LCONST_0); mv.visitInsn(LCMP); } // This handles byte, short, char and int mv.visitJumpInsn(IFEQ, falseLabel); mv.visitInsn(ICONST_1); mv.visitJumpInsn(GOTO, trueLabel); mv.visitLabel(falseLabel); mv.visitInsn(ICONST_0); mv.visitLabel(trueLabel); }
From source file:org.codehaus.groovy.classgen.asm.BytecodeHelper.java
License:Apache License
private static void convertDoubleToBoolean(MethodVisitor mv) { Label trueLabel = new Label(); Label falseLabel = new Label(); Label falseLabelWithPop = new Label(); mv.visitInsn(DUP2); // will need the extra for isNaN call if required mv.visitInsn(DCONST_0);//from w w w . j a v a 2 s.c o m mv.visitInsn(DCMPL); mv.visitJumpInsn(IFEQ, falseLabelWithPop); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", "isNaN", "(D)Z", false); mv.visitJumpInsn(IFNE, falseLabel); mv.visitInsn(ICONST_1); mv.visitJumpInsn(GOTO, trueLabel); mv.visitLabel(falseLabelWithPop); mv.visitInsn(POP2); mv.visitLabel(falseLabel); mv.visitInsn(ICONST_0); mv.visitLabel(trueLabel); }
From source file:org.codehaus.groovy.classgen.asm.BytecodeHelper.java
License:Apache License
private static void convertFloatToBoolean(MethodVisitor mv) { Label trueLabel = new Label(); Label falseLabel = new Label(); Label falseLabelWithPop = new Label(); mv.visitInsn(DUP); // will need the extra for isNaN call if required mv.visitInsn(FCONST_0);/*from w ww .j a va 2s . c o m*/ mv.visitInsn(FCMPL); mv.visitJumpInsn(IFEQ, falseLabelWithPop); mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", "isNaN", "(F)Z", false); mv.visitJumpInsn(IFNE, falseLabel); mv.visitInsn(ICONST_1); mv.visitJumpInsn(GOTO, trueLabel); mv.visitLabel(falseLabelWithPop); mv.visitInsn(POP); mv.visitLabel(falseLabel); mv.visitInsn(ICONST_0); mv.visitLabel(trueLabel); }
From source file:org.codehaus.groovy.classgen.asm.CallSiteWriter.java
License:Apache License
private void generateGetCallSiteArray() { int visibility = (controller.getClassNode() instanceof InterfaceHelperClassNode) ? MOD_PUBSS : MOD_PRIVSS; MethodVisitor mv = controller.getClassVisitor().visitMethod(visibility, GET_CALLSITE_METHOD, GET_CALLSITE_DESC, null, null); controller.setMethodVisitor(mv);// w w w . ja va 2s .c o m mv.visitCode(); mv.visitFieldInsn(GETSTATIC, controller.getInternalClassName(), "$callSiteArray", "Ljava/lang/ref/SoftReference;"); Label l0 = new Label(); mv.visitJumpInsn(IFNULL, l0); mv.visitFieldInsn(GETSTATIC, controller.getInternalClassName(), "$callSiteArray", "Ljava/lang/ref/SoftReference;"); mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/ref/SoftReference", "get", "()Ljava/lang/Object;", false); mv.visitTypeInsn(CHECKCAST, "org/codehaus/groovy/runtime/callsite/CallSiteArray"); mv.visitInsn(DUP); mv.visitVarInsn(ASTORE, 0); Label l1 = new Label(); mv.visitJumpInsn(IFNONNULL, l1); mv.visitLabel(l0); mv.visitMethodInsn(INVOKESTATIC, controller.getInternalClassName(), "$createCallSiteArray", "()Lorg/codehaus/groovy/runtime/callsite/CallSiteArray;", false); mv.visitVarInsn(ASTORE, 0); mv.visitTypeInsn(NEW, "java/lang/ref/SoftReference"); mv.visitInsn(DUP); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/ref/SoftReference", "<init>", "(Ljava/lang/Object;)V", false); mv.visitFieldInsn(PUTSTATIC, controller.getInternalClassName(), "$callSiteArray", "Ljava/lang/ref/SoftReference;"); mv.visitLabel(l1); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, "org/codehaus/groovy/runtime/callsite/CallSiteArray", "array", "[Lorg/codehaus/groovy/runtime/callsite/CallSite;"); mv.visitInsn(ARETURN); mv.visitMaxs(0, 0); mv.visitEnd(); }
From source file:org.codehaus.groovy.classgen.asm.InvocationWriter.java
License:Apache License
private void makeMOPBasedConstructorCall(final List<ConstructorNode> constructors, final ConstructorCallExpression call, final ClassNode callNode) { MethodVisitor mv = controller.getMethodVisitor(); OperandStack operandStack = controller.getOperandStack(); call.getArguments().visit(controller.getAcg()); // keep Object[] on stack mv.visitInsn(DUP);// w w w .j av a 2 s . com // to select the constructor we need also the number of // available constructors and the class we want to make // the call on BytecodeHelper.pushConstant(mv, -1); controller.getAcg().visitClassExpression(new ClassExpression(callNode)); operandStack.remove(1); // removes one Object[] leaves the int containing the // call flags and the constructor number selectConstructorAndTransformArguments.call(mv); //load "this" if (controller.isConstructor()) { mv.visitVarInsn(ALOAD, 0); } else { mv.visitTypeInsn(NEW, BytecodeHelper.getClassInternalName(callNode)); } mv.visitInsn(SWAP); TreeMap<Integer, ConstructorNode> sortedConstructors = new TreeMap<>(); for (ConstructorNode constructor : constructors) { String typeDescriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, constructor.getParameters()); int hash = BytecodeHelper.hashCode(typeDescriptor); ConstructorNode sameHashNode = sortedConstructors.put(hash, constructor); if (sameHashNode != null) { controller.getSourceUnit() .addError(new SyntaxException( "Unable to compile class " + controller.getClassNode().getName() + " due to hash collision in constructors", call.getLineNumber(), call.getColumnNumber())); } } Label[] targets = new Label[constructors.size()]; int[] indices = new int[constructors.size()]; Iterator<Integer> hashIt = sortedConstructors.keySet().iterator(); Iterator<ConstructorNode> constructorIt = sortedConstructors.values().iterator(); for (int i = 0, n = targets.length; i < n; i += 1) { targets[i] = new Label(); indices[i] = hashIt.next(); } // create switch targets Label defaultLabel = new Label(); Label afterSwitch = new Label(); mv.visitLookupSwitchInsn(defaultLabel, indices, targets); for (Label target : targets) { mv.visitLabel(target); // to keep the stack height, we need to leave // one Object[] on the stack as last element. At the // same time, we need the Object[] on top of the stack // to extract the parameters. if (controller.isConstructor()) { // in this case we need one "this", so a SWAP will exchange // "this" and Object[], a DUP_X1 will then copy the Object[] /// to the last place in the stack: // Object[],this -SWAP-> this,Object[] // this,Object[] -DUP_X1-> Object[],this,Object[] mv.visitInsn(SWAP); mv.visitInsn(DUP_X1); } else { // in this case we need two "this" in between and the Object[] // at the bottom of the stack as well as on top for our invokeSpecial // So we do DUP_X1, DUP2_X1, POP // Object[],this -DUP_X1-> this,Object[],this // this,Object[],this -DUP2_X1-> Object[],this,this,Object[],this // Object[],this,this,Object[],this -POP-> Object[],this,this,Object[] mv.visitInsn(DUP_X1); mv.visitInsn(DUP2_X1); mv.visitInsn(POP); } ConstructorNode cn = constructorIt.next(); String descriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, cn.getParameters()); // unwrap the Object[] and make transformations if needed // that means, to duplicate the Object[], make a cast with possible // unboxing and then swap it with the Object[] for each parameter // vargs need special attention and transformation though Parameter[] parameters = cn.getParameters(); int lengthWithoutVargs = parameters.length; if (parameters.length > 0 && parameters[parameters.length - 1].getType().isArray()) { lengthWithoutVargs -= 1; } for (int p = 0; p < lengthWithoutVargs; p += 1) { loadAndCastElement(operandStack, mv, parameters, p); } if (parameters.length > lengthWithoutVargs) { ClassNode type = parameters[lengthWithoutVargs].getType(); BytecodeHelper.pushConstant(mv, lengthWithoutVargs); controller.getAcg().visitClassExpression(new ClassExpression(type)); operandStack.remove(1); castToVargsArray.call(mv); BytecodeHelper.doCast(mv, type); } else { // at the end we remove the Object[] // the vargs case simply the last swap so no pop is needed mv.visitInsn(POP); } // make the constructor call mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(callNode), "<init>", descriptor, false); mv.visitJumpInsn(GOTO, afterSwitch); } mv.visitLabel(defaultLabel); // this part should never be reached! mv.visitTypeInsn(NEW, "java/lang/IllegalArgumentException"); mv.visitInsn(DUP); mv.visitLdcInsn( "This class has been compiled with a super class which is binary incompatible with the current super class found on classpath. You should recompile this class with the new version."); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/IllegalArgumentException", "<init>", "(Ljava/lang/String;)V", false); mv.visitInsn(ATHROW); mv.visitLabel(afterSwitch); // For a special constructor call inside a constructor we don't need // any result object on the stack, for outside the constructor we do. // to keep the stack height for the able we kept one object as dummy // result on the stack, which we can remove now if inside a constructor. if (!controller.isConstructor()) { // in case we are not in a constructor we have an additional // object on the stack, the result of our constructor call // which we want to keep, so we swap with the dummy object and // do normal removal of it. In the end, the call result will be // on the stack then mv.visitInsn(SWAP); operandStack.push(callNode); // for call result } mv.visitInsn(POP); }
From source file:org.codehaus.groovy.classgen.asm.OptimizingStatementWriter.java
License:Apache License
private FastPathData writeGuards(final StatementMeta meta, final Statement statement) { if (fastPathBlocked || controller.isFastPath() || meta == null || !meta.optimize) return null; controller.getAcg().onLineNumber(statement, null); MethodVisitor mv = controller.getMethodVisitor(); FastPathData fastPathData = new FastPathData(); Label slowPath = new Label(); for (int i = 0, n = guards.length; i < n; i += 1) { if (meta.involvedTypes[i]) { guards[i].call(mv);// w ww.j a v a 2 s .com mv.visitJumpInsn(IFEQ, slowPath); } } // meta class check with boolean holder String owner = BytecodeHelper.getClassInternalName(controller.getClassNode()); MethodNode mn = controller.getMethodNode(); if (mn != null) { mv.visitFieldInsn(GETSTATIC, owner, Verifier.STATIC_METACLASS_BOOL, "Z"); mv.visitJumpInsn(IFNE, slowPath); } // standard metaclass check disabledStandardMetaClass.call(mv); mv.visitJumpInsn(IFNE, slowPath); // other guards here mv.visitJumpInsn(GOTO, fastPathData.pathStart); mv.visitLabel(slowPath); return fastPathData; }
From source file:org.codehaus.groovy.classgen.asm.OptimizingStatementWriter.java
License:Apache License
private void writeFastPathPrelude(final FastPathData meta) { MethodVisitor mv = controller.getMethodVisitor(); mv.visitJumpInsn(GOTO, meta.afterPath); mv.visitLabel(meta.pathStart);/*from w w w. j av a 2 s . c o m*/ controller.switchToFastPath(); }