Example usage for org.objectweb.asm MethodVisitor visitLabel

List of usage examples for org.objectweb.asm MethodVisitor visitLabel

Introduction

In this page you can find the example usage for org.objectweb.asm MethodVisitor visitLabel.

Prototype

public void visitLabel(final Label label) 

Source Link

Document

Visits a label.

Usage

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());

}