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.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); }// ww w. ja va 2 s . 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());//w w w. jav a2 s. c o m // 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()); }
From source file:org.codehaus.groovy.classgen.asm.sc.StaticTypesCallSiteWriter.java
License:Apache License
private void writeMapDotProperty(final Expression receiver, final String propertyName, final MethodVisitor mv, final boolean safe) { receiver.visit(controller.getAcg()); // load receiver Label exit = new Label(); if (safe) {//from w w w. j a va 2s . c om Label doGet = new Label(); mv.visitJumpInsn(IFNONNULL, doGet); controller.getOperandStack().remove(1); mv.visitInsn(ACONST_NULL); mv.visitJumpInsn(GOTO, exit); mv.visitLabel(doGet); receiver.visit(controller.getAcg()); } mv.visitLdcInsn(propertyName); // load property name mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Map", "get", "(Ljava/lang/Object;)Ljava/lang/Object;", true); if (safe) { mv.visitLabel(exit); } controller.getOperandStack().replace(OBJECT_TYPE); }
From source file:org.codehaus.groovy.classgen.asm.sc.StaticTypesCallSiteWriter.java
License:Apache License
private void writeListDotProperty(final Expression receiver, final String propertyName, final MethodVisitor mv, final boolean safe) { ClassNode componentType = receiver.getNodeMetaData(StaticCompilationMetadataKeys.COMPONENT_TYPE); if (componentType == null) { componentType = OBJECT_TYPE;/*ww w.j av a2s . co m*/ } // for lists, replace list.foo with: // def result = new ArrayList(list.size()) // for (e in list) { result.add (e.foo) } // result CompileStack compileStack = controller.getCompileStack(); Label exit = new Label(); if (safe) { receiver.visit(controller.getAcg()); Label doGet = new Label(); mv.visitJumpInsn(IFNONNULL, doGet); controller.getOperandStack().remove(1); mv.visitInsn(ACONST_NULL); mv.visitJumpInsn(GOTO, exit); mv.visitLabel(doGet); } Variable tmpList = new VariableExpression("tmpList", ClassHelper.make(ArrayList.class)); int var = compileStack.defineTemporaryVariable(tmpList, false); Variable iterator = new VariableExpression("iterator", Iterator_TYPE); int it = compileStack.defineTemporaryVariable(iterator, false); Variable nextVar = new VariableExpression("next", componentType); final int next = compileStack.defineTemporaryVariable(nextVar, false); mv.visitTypeInsn(NEW, "java/util/ArrayList"); mv.visitInsn(DUP); receiver.visit(controller.getAcg()); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()I", true); controller.getOperandStack().remove(1); mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "<init>", "(I)V", false); mv.visitVarInsn(ASTORE, var); Label l1 = new Label(); mv.visitLabel(l1); receiver.visit(controller.getAcg()); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "iterator", "()Ljava/util/Iterator;", true); controller.getOperandStack().remove(1); mv.visitVarInsn(ASTORE, it); Label l2 = new Label(); mv.visitLabel(l2); mv.visitVarInsn(ALOAD, it); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true); Label l3 = new Label(); mv.visitJumpInsn(IFEQ, l3); mv.visitVarInsn(ALOAD, it); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true); mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(componentType)); mv.visitVarInsn(ASTORE, next); Label l4 = new Label(); mv.visitLabel(l4); mv.visitVarInsn(ALOAD, var); final ClassNode finalComponentType = componentType; PropertyExpression pexp = new PropertyExpression(new BytecodeExpression() { @Override public void visit(final MethodVisitor mv) { mv.visitVarInsn(ALOAD, next); } @Override public ClassNode getType() { return finalComponentType; } }, propertyName); pexp.visit(controller.getAcg()); controller.getOperandStack().box(); controller.getOperandStack().remove(1); mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z", true); mv.visitInsn(POP); Label l5 = new Label(); mv.visitLabel(l5); mv.visitJumpInsn(GOTO, l2); mv.visitLabel(l3); mv.visitVarInsn(ALOAD, var); if (safe) { mv.visitLabel(exit); } controller.getOperandStack().push(ClassHelper.make(ArrayList.class)); controller.getCompileStack().removeVar(next); controller.getCompileStack().removeVar(it); controller.getCompileStack().removeVar(var); }
From source file:org.codehaus.groovy.classgen.asm.sc.StaticTypesCallSiteWriter.java
License:Apache License
boolean makeGetField(final Expression receiver, final ClassNode receiverType, final String fieldName, final boolean safe, final boolean implicitThis) { FieldNode field = receiverType.getField(fieldName); if (field != null && isDirectAccessAllowed(field, controller.getClassNode())) { CompileStack compileStack = controller.getCompileStack(); MethodVisitor mv = controller.getMethodVisitor(); ClassNode replacementType = field.getOriginType(); OperandStack operandStack = controller.getOperandStack(); if (field.isStatic()) { mv.visitFieldInsn(GETSTATIC, BytecodeHelper.getClassInternalName(field.getOwner()), fieldName, BytecodeHelper.getTypeDescription(replacementType)); operandStack.push(replacementType); } else {//from w ww .j a v a 2s . co m if (implicitThis) { compileStack.pushImplicitThis(implicitThis); receiver.visit(controller.getAcg()); compileStack.popImplicitThis(); } else { receiver.visit(controller.getAcg()); } Label exit = new Label(); if (safe) { mv.visitInsn(DUP); Label doGet = new Label(); mv.visitJumpInsn(IFNONNULL, doGet); mv.visitInsn(POP); mv.visitInsn(ACONST_NULL); mv.visitJumpInsn(GOTO, exit); mv.visitLabel(doGet); } if (!operandStack.getTopOperand().isDerivedFrom(field.getOwner())) { mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(field.getOwner())); } mv.visitFieldInsn(GETFIELD, BytecodeHelper.getClassInternalName(field.getOwner()), fieldName, BytecodeHelper.getTypeDescription(replacementType)); if (safe) { if (ClassHelper.isPrimitiveType(replacementType)) { operandStack.replace(replacementType); operandStack.box(); replacementType = operandStack.getTopOperand(); } mv.visitLabel(exit); } } operandStack.replace(replacementType); return true; } for (ClassNode face : receiverType.getInterfaces()) { // GROOVY-7039 if (face != receiverType && makeGetField(receiver, face, fieldName, safe, implicitThis)) { return true; } } ClassNode superClass = receiverType.getSuperClass(); if (superClass != null && !OBJECT_TYPE.equals(superClass)) { return makeGetField(receiver, superClass, fieldName, safe, implicitThis); } return false; }
From source file:org.codehaus.groovy.classgen.asm.sc.StaticTypesStatementWriter.java
License:Apache License
private void writeOptimizedForEachLoop(CompileStack compileStack, OperandStack operandStack, MethodVisitor mv, ForStatement loop, Expression collectionExpression, ClassNode collectionType, Parameter loopVariable) { BytecodeVariable variable = compileStack.defineVariable(loopVariable, false); Label continueLabel = compileStack.getContinueLabel(); Label breakLabel = compileStack.getBreakLabel(); AsmClassGenerator acg = controller.getAcg(); // load array on stack collectionExpression.visit(acg);/*from w w w .j a v a2 s.com*/ mv.visitInsn(DUP); int array = compileStack.defineTemporaryVariable("$arr", collectionType, true); mv.visitJumpInsn(IFNULL, breakLabel); // $len = array.length mv.visitVarInsn(ALOAD, array); mv.visitInsn(ARRAYLENGTH); operandStack.push(ClassHelper.int_TYPE); int arrayLen = compileStack.defineTemporaryVariable("$len", ClassHelper.int_TYPE, true); // $idx = 0 mv.visitInsn(ICONST_0); operandStack.push(ClassHelper.int_TYPE); int loopIdx = compileStack.defineTemporaryVariable("$idx", ClassHelper.int_TYPE, true); mv.visitLabel(continueLabel); // $idx<$len? mv.visitVarInsn(ILOAD, loopIdx); mv.visitVarInsn(ILOAD, arrayLen); mv.visitJumpInsn(IF_ICMPGE, breakLabel); // get array element loadFromArray(mv, variable, array, loopIdx); // $idx++ mv.visitIincInsn(loopIdx, 1); // loop body loop.getLoopBlock().visit(acg); mv.visitJumpInsn(GOTO, continueLabel); mv.visitLabel(breakLabel); compileStack.removeVar(loopIdx); compileStack.removeVar(arrayLen); compileStack.removeVar(array); }
From source file:org.codehaus.groovy.classgen.asm.sc.StaticTypesStatementWriter.java
License:Apache License
private void writeIteratorBasedForEachLoop(CompileStack compileStack, OperandStack operandStack, MethodVisitor mv, ForStatement loop, Expression collectionExpression, ClassNode collectionType, Parameter loopVariable) { // Declare the loop counter. BytecodeVariable variable = compileStack.defineVariable(loopVariable, false); if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(collectionType, ITERABLE_CLASSNODE)) { MethodCallExpression iterator = new MethodCallExpression(collectionExpression, "iterator", new ArgumentListExpression()); iterator.setMethodTarget(collectionType.getMethod("iterator", Parameter.EMPTY_ARRAY)); iterator.setImplicitThis(false); iterator.visit(controller.getAcg()); } else {//from w w w .j a v a 2 s .c o m collectionExpression.visit(controller.getAcg()); mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "iterator", "(Ljava/lang/Object;)Ljava/util/Iterator;", false); operandStack.replace(ClassHelper.Iterator_TYPE); } // Then get the iterator and generate the loop control int iteratorIdx = compileStack.defineTemporaryVariable("iterator", ClassHelper.Iterator_TYPE, true); Label continueLabel = compileStack.getContinueLabel(); Label breakLabel = compileStack.getBreakLabel(); mv.visitLabel(continueLabel); mv.visitVarInsn(ALOAD, iteratorIdx); writeIteratorHasNext(mv); // note: ifeq tests for ==0, a boolean is 0 if it is false mv.visitJumpInsn(IFEQ, breakLabel); mv.visitVarInsn(ALOAD, iteratorIdx); writeIteratorNext(mv); operandStack.push(ClassHelper.OBJECT_TYPE); operandStack.storeVar(variable); // Generate the loop body loop.getLoopBlock().visit(controller.getAcg()); mv.visitJumpInsn(GOTO, continueLabel); mv.visitLabel(breakLabel); compileStack.removeVar(iteratorIdx); }
From source file:org.codehaus.groovy.classgen.asm.sc.StaticTypesStatementWriter.java
License:Apache License
private void writeEnumerationBasedForEachLoop(CompileStack compileStack, OperandStack operandStack, MethodVisitor mv, ForStatement loop, Expression collectionExpression, ClassNode collectionType, Parameter loopVariable) { // Declare the loop counter. BytecodeVariable variable = compileStack.defineVariable(loopVariable, false); collectionExpression.visit(controller.getAcg()); // Then get the iterator and generate the loop control int enumIdx = compileStack.defineTemporaryVariable("$enum", ENUMERATION_CLASSNODE, true); Label continueLabel = compileStack.getContinueLabel(); Label breakLabel = compileStack.getBreakLabel(); mv.visitLabel(continueLabel);/*ww w.j a v a 2 s. c o m*/ mv.visitVarInsn(ALOAD, enumIdx); ENUMERATION_HASMORE_METHOD.call(mv); // note: ifeq tests for ==0, a boolean is 0 if it is false mv.visitJumpInsn(IFEQ, breakLabel); mv.visitVarInsn(ALOAD, enumIdx); ENUMERATION_NEXT_METHOD.call(mv); operandStack.push(ClassHelper.OBJECT_TYPE); operandStack.storeVar(variable); // Generate the loop body loop.getLoopBlock().visit(controller.getAcg()); mv.visitJumpInsn(GOTO, continueLabel); mv.visitLabel(breakLabel); }
From source file:org.codehaus.groovy.classgen.asm.sc.StaticTypesUnaryExpressionHelper.java
License:Apache License
@Override public void writeNotExpression(final NotExpression expression) { TypeChooser typeChooser = controller.getTypeChooser(); Expression subExpression = expression.getExpression(); ClassNode classNode = controller.getClassNode(); if (typeChooser.resolveType(subExpression, classNode) == boolean_TYPE) { subExpression.visit(controller.getAcg()); controller.getOperandStack().doGroovyCast(boolean_TYPE); BytecodeExpression bytecodeExpression = new BytecodeExpression() { @Override//from w ww . j a va 2s. co m public void visit(final MethodVisitor mv) { Label ne = new Label(); mv.visitJumpInsn(IFNE, ne); mv.visitInsn(ICONST_1); Label out = new Label(); mv.visitJumpInsn(GOTO, out); mv.visitLabel(ne); mv.visitInsn(ICONST_0); mv.visitLabel(out); } }; bytecodeExpression.visit(controller.getAcg()); controller.getOperandStack().remove(1); return; } super.writeNotExpression(expression); }
From source file:org.codehaus.groovy.classgen.asm.StatementWriter.java
License:Apache License
protected void writeForInLoop(ForStatement loop) { controller.getAcg().onLineNumber(loop, "visitForLoop"); writeStatementLabel(loop);//from w ww .j a va2 s . co m CompileStack compileStack = controller.getCompileStack(); MethodVisitor mv = controller.getMethodVisitor(); OperandStack operandStack = controller.getOperandStack(); compileStack.pushLoop(loop.getVariableScope(), loop.getStatementLabels()); // Declare the loop counter. BytecodeVariable variable = compileStack.defineVariable(loop.getVariable(), false); // Then get the iterator and generate the loop control MethodCallExpression iterator = new MethodCallExpression(loop.getCollectionExpression(), "iterator", new ArgumentListExpression()); iterator.visit(controller.getAcg()); operandStack.doGroovyCast(ClassHelper.Iterator_TYPE); final int iteratorIdx = compileStack.defineTemporaryVariable("iterator", ClassHelper.Iterator_TYPE, true); Label continueLabel = compileStack.getContinueLabel(); Label breakLabel = compileStack.getBreakLabel(); mv.visitLabel(continueLabel); mv.visitVarInsn(ALOAD, iteratorIdx); writeIteratorHasNext(mv); // note: ifeq tests for ==0, a boolean is 0 if it is false mv.visitJumpInsn(IFEQ, breakLabel); mv.visitVarInsn(ALOAD, iteratorIdx); writeIteratorNext(mv); operandStack.push(ClassHelper.OBJECT_TYPE); operandStack.storeVar(variable); // Generate the loop body loop.getLoopBlock().visit(controller.getAcg()); mv.visitJumpInsn(GOTO, continueLabel); mv.visitLabel(breakLabel); compileStack.removeVar(iteratorIdx); compileStack.pop(); }