List of usage examples for org.objectweb.asm MethodVisitor visitLabel
public void visitLabel(final Label label)
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 w w .j av a 2 s. 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);/*from w ww .j a v a 2 s .com*/ 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.CompileStack.java
License:Apache License
public BytecodeVariable defineVariable(Variable v, ClassNode variableType, boolean initFromStack) { String name = v.getName();//from www . j a v a 2s. c o m BytecodeVariable answer = defineVar(name, variableType, v.isClosureSharedVariable(), v.isClosureSharedVariable()); stackVariables.put(name, answer); MethodVisitor mv = controller.getMethodVisitor(); Label startLabel = new Label(); answer.setStartLabel(startLabel); ClassNode type = answer.getType().redirect(); OperandStack operandStack = controller.getOperandStack(); if (!initFromStack) { if (ClassHelper.isPrimitiveType(v.getOriginType()) && ClassHelper.getWrapper(v.getOriginType()) == variableType) { pushInitValue(v.getOriginType(), mv); operandStack.push(v.getOriginType()); operandStack.box(); operandStack.remove(1); } else { pushInitValue(type, mv); } } operandStack.push(answer.getType()); if (answer.isHolder()) { operandStack.box(); operandStack.remove(1); createReference(answer); } else { operandStack.storeVar(answer); } mv.visitLabel(startLabel); return answer; }
From source file:org.codehaus.groovy.classgen.asm.CompileStack.java
License:Apache License
private void applyBlockRecorder(List<BlockRecorder> blocks) { if (blocks.isEmpty() || blocks.size() == visitedBlocks.size()) return;/*from w w w. j av a2s. c o m*/ MethodVisitor mv = controller.getMethodVisitor(); Label newStart = new Label(); for (BlockRecorder fb : blocks) { if (visitedBlocks.contains(fb)) continue; Label end = new Label(); mv.visitInsn(NOP); mv.visitLabel(end); fb.closeRange(end); // we exclude the finally block from the exception table // here to avoid double visiting of finally statements fb.excludedStatement.run(); fb.startRange(newStart); } mv.visitInsn(NOP); mv.visitLabel(newStart); }
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);/*from w w w. j av a 2 s .co m*/ // 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);/*from ww w . j ava2 s .c om*/ 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); controller.switchToFastPath();//from www . j av a2s . c o m }
From source file:org.codehaus.groovy.classgen.asm.OptimizingStatementWriter.java
License:Apache License
private void writeFastPathEpilogue(final FastPathData meta) { MethodVisitor mv = controller.getMethodVisitor(); mv.visitLabel(meta.afterPath); controller.switchToSlowPath();//w ww . jav a2 s.c o m }
From source file:org.codehaus.groovy.classgen.asm.sc.StaticInvocationWriter.java
License:Apache License
@Override public void makeCall(final Expression origin, final Expression receiver, final Expression message, final Expression arguments, final MethodCallerMultiAdapter adapter, final boolean safe, final boolean spreadSafe, final boolean implicitThis) { ClassNode dynamicCallReturnType = origin.getNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION); if (dynamicCallReturnType != null) { StaticTypesWriterController staticController = (StaticTypesWriterController) controller; if (origin instanceof MethodCallExpression) { ((MethodCallExpression) origin).setMethodTarget(null); }// w w w . j a v a 2s . c om InvocationWriter dynamicInvocationWriter = staticController.getRegularInvocationWriter(); dynamicInvocationWriter.makeCall(origin, receiver, message, arguments, adapter, safe, spreadSafe, implicitThis); return; } if (tryImplicitReceiver(origin, message, arguments, adapter, safe, spreadSafe, implicitThis)) { return; } // if call is spread safe, replace it with a for in loop if (spreadSafe && origin instanceof MethodCallExpression) { // receiver expressions with side effects should not be visited twice, avoid by using a temporary variable Expression tmpReceiver = receiver; if (!(receiver instanceof VariableExpression) && !(receiver instanceof ConstantExpression)) { tmpReceiver = new TemporaryVariableExpression(receiver); } MethodVisitor mv = controller.getMethodVisitor(); CompileStack compileStack = controller.getCompileStack(); TypeChooser typeChooser = controller.getTypeChooser(); OperandStack operandStack = controller.getOperandStack(); ClassNode classNode = controller.getClassNode(); int counter = labelCounter.incrementAndGet(); // use a temporary variable for the arraylist in which the results of the spread call will be stored ConstructorCallExpression cce = new ConstructorCallExpression( StaticCompilationVisitor.ARRAYLIST_CLASSNODE, ArgumentListExpression.EMPTY_ARGUMENTS); cce.setNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET, StaticCompilationVisitor.ARRAYLIST_CONSTRUCTOR); TemporaryVariableExpression result = new TemporaryVariableExpression(cce); result.visit(controller.getAcg()); operandStack.pop(); // if (receiver != null) tmpReceiver.visit(controller.getAcg()); Label ifnull = compileStack.createLocalLabel("ifnull_" + counter); mv.visitJumpInsn(IFNULL, ifnull); operandStack.remove(1); // receiver consumed by if() Label nonull = compileStack.createLocalLabel("nonull_" + counter); mv.visitLabel(nonull); ClassNode componentType = StaticTypeCheckingVisitor .inferLoopElementType(typeChooser.resolveType(tmpReceiver, classNode)); Parameter iterator = new Parameter(componentType, "for$it$" + counter); VariableExpression iteratorAsVar = new VariableExpression(iterator); MethodCallExpression origMCE = (MethodCallExpression) origin; MethodCallExpression newMCE = new MethodCallExpression(iteratorAsVar, origMCE.getMethodAsString(), origMCE.getArguments()); newMCE.setImplicitThis(false); newMCE.setMethodTarget(origMCE.getMethodTarget()); newMCE.setSafe(true); MethodCallExpression add = new MethodCallExpression(result, "add", newMCE); add.setImplicitThis(false); add.setMethodTarget(StaticCompilationVisitor.ARRAYLIST_ADD_METHOD); // for (e in receiver) { result.add(e?.method(arguments) } ForStatement stmt = new ForStatement(iterator, tmpReceiver, new ExpressionStatement(add)); stmt.visit(controller.getAcg()); // else { empty list } mv.visitLabel(ifnull); // end of if/else // return result list result.visit(controller.getAcg()); // cleanup temporary variables if (tmpReceiver instanceof TemporaryVariableExpression) { ((TemporaryVariableExpression) tmpReceiver).remove(controller); } result.remove(controller); } else if (safe && origin instanceof MethodCallExpression) { // wrap call in an IFNULL check MethodVisitor mv = controller.getMethodVisitor(); CompileStack compileStack = controller.getCompileStack(); OperandStack operandStack = controller.getOperandStack(); int counter = labelCounter.incrementAndGet(); // if (receiver != null) ExpressionAsVariableSlot slot = new ExpressionAsVariableSlot(controller, receiver); slot.visit(controller.getAcg()); operandStack.box(); Label ifnull = compileStack.createLocalLabel("ifnull_" + counter); mv.visitJumpInsn(IFNULL, ifnull); operandStack.remove(1); // receiver consumed by if() Label nonull = compileStack.createLocalLabel("nonull_" + counter); mv.visitLabel(nonull); MethodCallExpression origMCE = (MethodCallExpression) origin; MethodCallExpression newMCE = new MethodCallExpression( new VariableSlotLoader(slot.getType(), slot.getIndex(), controller.getOperandStack()), origMCE.getMethodAsString(), origMCE.getArguments()); MethodNode methodTarget = origMCE.getMethodTarget(); newMCE.setMethodTarget(methodTarget); newMCE.setSafe(false); newMCE.setImplicitThis(origMCE.isImplicitThis()); newMCE.setSourcePosition(origMCE); newMCE.visit(controller.getAcg()); compileStack.removeVar(slot.getIndex()); ClassNode returnType = operandStack.getTopOperand(); if (ClassHelper.isPrimitiveType(returnType) && !ClassHelper.VOID_TYPE.equals(returnType)) { operandStack.box(); } Label endof = compileStack.createLocalLabel("endof_" + counter); mv.visitJumpInsn(GOTO, endof); mv.visitLabel(ifnull); // else { null } mv.visitInsn(ACONST_NULL); mv.visitLabel(endof); } else { if (origin instanceof AttributeExpression && (adapter == AsmClassGenerator.getField || adapter == AsmClassGenerator.getGroovyObjectField)) { CallSiteWriter callSiteWriter = controller.getCallSiteWriter(); String fieldName = ((AttributeExpression) origin).getPropertyAsString(); if (fieldName != null && callSiteWriter instanceof StaticTypesCallSiteWriter) { ClassNode receiverType = controller.getTypeChooser().resolveType(receiver, controller.getClassNode()); if (((StaticTypesCallSiteWriter) callSiteWriter).makeGetField(receiver, receiverType, fieldName, safe, false)) { return; } } } super.makeCall(origin, receiver, message, arguments, adapter, safe, spreadSafe, implicitThis); } }
From source file:org.codehaus.groovy.classgen.asm.sc.StaticTypesBinaryExpressionMultiTypeDispatcher.java
License:Apache License
private void transformSpreadOnLHS(BinaryExpression origin) { PropertyExpression spreadExpression = (PropertyExpression) origin.getLeftExpression(); Expression value = origin.getRightExpression(); WriterController controller = getController(); MethodVisitor mv = controller.getMethodVisitor(); CompileStack compileStack = controller.getCompileStack(); TypeChooser typeChooser = controller.getTypeChooser(); OperandStack operandStack = controller.getOperandStack(); ClassNode classNode = controller.getClassNode(); int counter = labelCounter.incrementAndGet(); Expression receiver = spreadExpression.getObjectExpression(); // create an empty arraylist VariableExpression result = new VariableExpression( this.getClass().getSimpleName() + "$spreadresult" + counter, ARRAYLIST_CLASSNODE); ConstructorCallExpression cce = new ConstructorCallExpression(ARRAYLIST_CLASSNODE, ArgumentListExpression.EMPTY_ARGUMENTS); cce.setNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET, ARRAYLIST_CONSTRUCTOR); DeclarationExpression declr = new DeclarationExpression(result, Token.newSymbol("=", spreadExpression.getLineNumber(), spreadExpression.getColumnNumber()), cce); declr.visit(controller.getAcg());/*from ww w .ja va 2 s .c om*/ // if (receiver != null) receiver.visit(controller.getAcg()); Label ifnull = compileStack.createLocalLabel("ifnull_" + counter); mv.visitJumpInsn(IFNULL, ifnull); operandStack.remove(1); // receiver consumed by if() Label nonull = compileStack.createLocalLabel("nonull_" + counter); mv.visitLabel(nonull); ClassNode componentType = StaticTypeCheckingVisitor .inferLoopElementType(typeChooser.resolveType(receiver, classNode)); Parameter iterator = new Parameter(componentType, "for$it$" + counter); VariableExpression iteratorAsVar = new VariableExpression(iterator); PropertyExpression pexp = spreadExpression instanceof AttributeExpression ? new AttributeExpression(iteratorAsVar, spreadExpression.getProperty(), true) : new PropertyExpression(iteratorAsVar, spreadExpression.getProperty(), true); pexp.setImplicitThis(spreadExpression.isImplicitThis()); pexp.setSourcePosition(spreadExpression); BinaryExpression assignment = new BinaryExpression(pexp, origin.getOperation(), value); MethodCallExpression add = new MethodCallExpression(result, "add", assignment); add.setMethodTarget(ARRAYLIST_ADD_METHOD); // for (e in receiver) { result.add(e?.method(arguments) } ForStatement stmt = new ForStatement(iterator, receiver, new ExpressionStatement(add)); stmt.visit(controller.getAcg()); // else { empty list } mv.visitLabel(ifnull); // end of if/else // return result list result.visit(controller.getAcg()); }