Search in sources :

Example 21 with AsmClassGenerator

use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy-core by groovy.

the class StaticInvocationWriter method loadArguments.

protected void loadArguments(List<Expression> argumentList, Parameter[] para) {
    if (para.length == 0)
        return;
    ClassNode lastParaType = para[para.length - 1].getOriginType();
    AsmClassGenerator acg = controller.getAcg();
    TypeChooser typeChooser = controller.getTypeChooser();
    OperandStack operandStack = controller.getOperandStack();
    ClassNode lastArgType = argumentList.size() > 0 ? typeChooser.resolveType(argumentList.get(argumentList.size() - 1), controller.getClassNode()) : null;
    if (lastParaType.isArray() && ((argumentList.size() > para.length) || ((argumentList.size() == (para.length - 1)) && !lastParaType.equals(lastArgType)) || ((argumentList.size() == para.length && lastArgType != null && !lastArgType.isArray()) && (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(lastArgType, lastParaType.getComponentType()))) || ClassHelper.GSTRING_TYPE.equals(lastArgType) && ClassHelper.STRING_TYPE.equals(lastParaType.getComponentType()))) {
        int stackLen = operandStack.getStackLength() + argumentList.size();
        MethodVisitor mv = controller.getMethodVisitor();
        MethodVisitor orig = mv;
        //mv = new org.objectweb.asm.util.TraceMethodVisitor(mv);
        controller.setMethodVisitor(mv);
        // first parameters as usual
        for (int i = 0; i < para.length - 1; i++) {
            Expression expression = argumentList.get(i);
            expression.visit(acg);
            if (!isNullConstant(expression)) {
                operandStack.doGroovyCast(para[i].getType());
            }
        }
        // last parameters wrapped in an array
        List<Expression> lastParams = new LinkedList<Expression>();
        for (int i = para.length - 1; i < argumentList.size(); i++) {
            lastParams.add(argumentList.get(i));
        }
        ArrayExpression array = new ArrayExpression(lastParaType.getComponentType(), lastParams);
        array.visit(acg);
        // adjust stack length
        while (operandStack.getStackLength() < stackLen) {
            operandStack.push(ClassHelper.OBJECT_TYPE);
        }
        if (argumentList.size() == para.length - 1) {
            operandStack.remove(1);
        }
    } else if (argumentList.size() == para.length) {
        for (int i = 0; i < argumentList.size(); i++) {
            Expression expression = argumentList.get(i);
            expression.visit(acg);
            if (!isNullConstant(expression)) {
                operandStack.doGroovyCast(para[i].getType());
            }
        }
    } else {
        // method call with default arguments
        ClassNode classNode = controller.getClassNode();
        Expression[] arguments = new Expression[para.length];
        for (int i = 0, j = 0; i < para.length; i++) {
            Parameter curParam = para[i];
            ClassNode curParamType = curParam.getType();
            Expression curArg = j < argumentList.size() ? argumentList.get(j) : null;
            Expression initialExpression = (Expression) curParam.getNodeMetaData(StaticTypesMarker.INITIAL_EXPRESSION);
            if (initialExpression == null && curParam.hasInitialExpression())
                initialExpression = curParam.getInitialExpression();
            if (initialExpression == null && curParam.getNodeMetaData(Verifier.INITIAL_EXPRESSION) != null) {
                initialExpression = (Expression) curParam.getNodeMetaData(Verifier.INITIAL_EXPRESSION);
            }
            ClassNode curArgType = curArg == null ? null : typeChooser.resolveType(curArg, classNode);
            if (initialExpression != null && !compatibleArgumentType(curArgType, curParamType)) {
                // use default expression
                arguments[i] = initialExpression;
            } else {
                arguments[i] = curArg;
                j++;
            }
        }
        for (int i = 0; i < arguments.length; i++) {
            Expression expression = arguments[i];
            expression.visit(acg);
            if (!isNullConstant(expression)) {
                operandStack.doGroovyCast(para[i].getType());
            }
        }
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) Parameter(org.codehaus.groovy.ast.Parameter) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator) LinkedList(java.util.LinkedList) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 22 with AsmClassGenerator

use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy-core by groovy.

the class StaticTypesBinaryExpressionMultiTypeDispatcher method assignToArray.

protected void assignToArray(Expression parent, Expression receiver, Expression index, Expression rhsValueLoader) {
    ClassNode current = getController().getClassNode();
    ClassNode arrayType = getController().getTypeChooser().resolveType(receiver, current);
    ClassNode arrayComponentType = arrayType.getComponentType();
    int operationType = getOperandType(arrayComponentType);
    BinaryExpressionWriter bew = binExpWriter[operationType];
    AsmClassGenerator acg = getController().getAcg();
    if (bew.arraySet(true) && arrayType.isArray()) {
        super.assignToArray(parent, receiver, index, rhsValueLoader);
    } else {
        /******
            / This code path is needed because ACG creates array access expressions
            *******/
        WriterController controller = getController();
        StaticTypeCheckingVisitor visitor = new StaticCompilationVisitor(controller.getSourceUnit(), controller.getClassNode());
        // let's replace this assignment to a subscript operator with a
        // method call
        // e.g. x[5] = 10
        // -> (x, [], 5), =, 10
        // -> methodCall(x, "putAt", [5, 10])
        ArgumentListExpression ae = new ArgumentListExpression(index, rhsValueLoader);
        if (rhsValueLoader instanceof VariableSlotLoader && parent instanceof BinaryExpression) {
            // GROOVY-6061
            Expression right = ((BinaryExpression) parent).getRightExpression();
            rhsValueLoader.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, controller.getTypeChooser().resolveType(parent, controller.getClassNode()));
        }
        MethodCallExpression mce = new MethodCallExpression(receiver, "putAt", ae);
        mce.setSourcePosition(parent);
        visitor.visitMethodCallExpression(mce);
        OperandStack operandStack = controller.getOperandStack();
        int height = operandStack.getStackLength();
        mce.visit(controller.getAcg());
        operandStack.pop();
        operandStack.remove(operandStack.getStackLength() - height);
        // return value of assignment
        rhsValueLoader.visit(controller.getAcg());
    }
}
Also used : StaticCompilationVisitor(org.codehaus.groovy.transform.sc.StaticCompilationVisitor) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator) StaticTypeCheckingVisitor(org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor)

Example 23 with AsmClassGenerator

use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy-core by groovy.

the class CompareIdentityExpression method visit.

@Override
public void visit(final GroovyCodeVisitor visitor) {
    if (visitor instanceof AsmClassGenerator) {
        AsmClassGenerator acg = (AsmClassGenerator) visitor;
        WriterController controller = acg.getController();
        ClassNode leftType = controller.getTypeChooser().resolveType(leftExpression, controller.getClassNode());
        ClassNode rightType = controller.getTypeChooser().resolveType(rightExpression, controller.getClassNode());
        MethodVisitor mv = controller.getMethodVisitor();
        leftExpression.visit(acg);
        controller.getOperandStack().box();
        rightExpression.visit(acg);
        controller.getOperandStack().box();
        Label l1 = new Label();
        mv.visitJumpInsn(IF_ACMPNE, l1);
        mv.visitInsn(ICONST_1);
        Label l2 = new Label();
        mv.visitJumpInsn(GOTO, l2);
        mv.visitLabel(l1);
        mv.visitInsn(ICONST_0);
        mv.visitLabel(l2);
        controller.getOperandStack().replace(ClassHelper.boolean_TYPE, 2);
    } else {
        super.visit(visitor);
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) WriterController(org.codehaus.groovy.classgen.asm.WriterController) Label(org.objectweb.asm.Label) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 24 with AsmClassGenerator

use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy-core by groovy.

the class TemporaryVariableExpression method visit.

@Override
public void visit(final GroovyCodeVisitor visitor) {
    if (visitor instanceof AsmClassGenerator) {
        if (variable == null) {
            AsmClassGenerator acg = (AsmClassGenerator) visitor;
            WriterController controller = acg.getController();
            variable = new ExpressionAsVariableSlot(controller, expression);
        }
        variable.visit(visitor);
    } else {
        expression.visit(visitor);
    }
}
Also used : WriterController(org.codehaus.groovy.classgen.asm.WriterController) ExpressionAsVariableSlot(org.codehaus.groovy.classgen.asm.ExpressionAsVariableSlot) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator)

Example 25 with AsmClassGenerator

use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy-core by groovy.

the class CompareToNullExpression method visit.

@Override
public void visit(final GroovyCodeVisitor visitor) {
    if (visitor instanceof AsmClassGenerator) {
        AsmClassGenerator acg = (AsmClassGenerator) visitor;
        WriterController controller = acg.getController();
        MethodVisitor mv = controller.getMethodVisitor();
        objectExpression.visit(acg);
        ClassNode top = controller.getOperandStack().getTopOperand();
        if (ClassHelper.isPrimitiveType(top)) {
            controller.getOperandStack().pop();
            mv.visitInsn(ICONST_0);
            controller.getOperandStack().push(ClassHelper.boolean_TYPE);
            return;
        }
        Label zero = new Label();
        mv.visitJumpInsn(equalsNull ? IFNONNULL : IFNULL, zero);
        mv.visitInsn(ICONST_1);
        Label end = new Label();
        mv.visitJumpInsn(GOTO, end);
        mv.visitLabel(zero);
        mv.visitInsn(ICONST_0);
        mv.visitLabel(end);
        controller.getOperandStack().replace(ClassHelper.boolean_TYPE);
    } else {
        super.visit(visitor);
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) WriterController(org.codehaus.groovy.classgen.asm.WriterController) Label(org.objectweb.asm.Label) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator) MethodVisitor(org.objectweb.asm.MethodVisitor)

Aggregations

AsmClassGenerator (org.codehaus.groovy.classgen.AsmClassGenerator)45 ClassNode (org.codehaus.groovy.ast.ClassNode)21 MethodVisitor (org.objectweb.asm.MethodVisitor)18 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)14 Expression (org.codehaus.groovy.ast.expr.Expression)14 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)14 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)14 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)10 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)10 FieldExpression (org.codehaus.groovy.ast.expr.FieldExpression)10 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)10 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)10 Label (org.objectweb.asm.Label)10 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)8 ArrayExpression (org.codehaus.groovy.ast.expr.ArrayExpression)8 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)8 ElvisOperatorExpression (org.codehaus.groovy.ast.expr.ElvisOperatorExpression)8 EmptyExpression (org.codehaus.groovy.ast.expr.EmptyExpression)8 ListExpression (org.codehaus.groovy.ast.expr.ListExpression)8 PostfixExpression (org.codehaus.groovy.ast.expr.PostfixExpression)8