Search in sources :

Example 41 with AsmClassGenerator

use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy by apache.

the class BinaryExpressionMultiTypeDispatcher method evaluateBinaryExpression.

@Override
protected void evaluateBinaryExpression(final String message, BinaryExpression binExp) {
    int operation = removeAssignment(binExp.getOperation().getType());
    ClassNode current = getController().getClassNode();
    Expression leftExp = binExp.getLeftExpression();
    ClassNode leftTypeOrig = getController().getTypeChooser().resolveType(leftExp, current);
    ClassNode leftType = leftTypeOrig;
    Expression rightExp = binExp.getRightExpression();
    ClassNode rightType = getController().getTypeChooser().resolveType(rightExp, current);
    AsmClassGenerator acg = getController().getAcg();
    OperandStack os = getController().getOperandStack();
    if (operation == LEFT_SQUARE_BRACKET) {
        leftType = leftTypeOrig.getComponentType();
        int operationType = getOperandType(leftType);
        BinaryExpressionWriter bew = binExpWriter[operationType];
        if (leftTypeOrig.isArray() && isIntCastableType(rightExp) && bew.arrayGet(operation, true)) {
            leftExp.visit(acg);
            os.doGroovyCast(leftTypeOrig);
            rightExp.visit(acg);
            os.doGroovyCast(int_TYPE);
            bew.arrayGet(operation, false);
            os.replace(bew.getArrayGetResultType(), 2);
        } else {
            super.evaluateBinaryExpression(message, binExp);
        }
    } else if (operation == DIVIDE) {
        int operationType = getOperandType(getController().getTypeChooser().resolveType(binExp, current));
        BinaryExpressionWriter bew = binExpWriter[operationType];
        if (bew.writeDivision(true)) {
            leftExp.visit(acg);
            os.doGroovyCast(bew.getDevisionOpResultType());
            rightExp.visit(acg);
            os.doGroovyCast(bew.getDevisionOpResultType());
            bew.writeDivision(false);
        } else {
            super.evaluateBinaryExpression(message, binExp);
        }
    } else {
        int operationType = getOperandConversionType(leftType, rightType);
        BinaryExpressionWriter bew = binExpWriter[operationType];
        if (isShiftOperation(operation) && isIntCastableType(rightExp) && bew.write(operation, true)) {
            leftExp.visit(acg);
            os.doGroovyCast(bew.getNormalOpResultType());
            rightExp.visit(acg);
            os.doGroovyCast(int_TYPE);
            bew.write(operation, false);
        } else if (bew.write(operation, true)) {
            leftExp.visit(acg);
            os.doGroovyCast(bew.getNormalOpResultType());
            rightExp.visit(acg);
            os.doGroovyCast(bew.getNormalOpResultType());
            bew.write(operation, false);
        } else {
            super.evaluateBinaryExpression(message, binExp);
        }
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) Expression(org.codehaus.groovy.ast.expr.Expression) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator)

Example 42 with AsmClassGenerator

use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy by apache.

the class BinaryExpressionMultiTypeDispatcher method assignToArray.

@Override
protected void assignToArray(Expression orig, 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()) {
        OperandStack operandStack = getController().getOperandStack();
        // load the array
        receiver.visit(acg);
        operandStack.doGroovyCast(arrayType);
        // load index
        index.visit(acg);
        operandStack.doGroovyCast(int_TYPE);
        // load rhs
        rhsValueLoader.visit(acg);
        operandStack.doGroovyCast(arrayComponentType);
        // store value in array
        bew.arraySet(false);
        // load return value && correct operand stack stack
        operandStack.remove(3);
        rhsValueLoader.visit(acg);
    } else {
        super.assignToArray(orig, receiver, index, rhsValueLoader);
    }
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator)

Example 43 with AsmClassGenerator

use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy by apache.

the class BinaryExpressionMultiTypeDispatcher method doPrimitiveCompare.

protected boolean doPrimitiveCompare(ClassNode leftType, ClassNode rightType, BinaryExpression binExp) {
    Expression leftExp = binExp.getLeftExpression();
    Expression rightExp = binExp.getRightExpression();
    int operation = binExp.getOperation().getType();
    int operationType = getOperandConversionType(leftType, rightType);
    BinaryExpressionWriter bew = binExpWriter[operationType];
    if (!bew.write(operation, true))
        return false;
    AsmClassGenerator acg = getController().getAcg();
    OperandStack os = getController().getOperandStack();
    leftExp.visit(acg);
    os.doGroovyCast(bew.getNormalOpResultType());
    rightExp.visit(acg);
    os.doGroovyCast(bew.getNormalOpResultType());
    bew.write(operation, false);
    return true;
}
Also used : PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) Expression(org.codehaus.groovy.ast.expr.Expression) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator)

Example 44 with AsmClassGenerator

use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy by apache.

the class InvocationWriter method makeUncachedCall.

protected void makeUncachedCall(Expression origin, ClassExpression sender, Expression receiver, Expression message, Expression arguments, MethodCallerMultiAdapter adapter, boolean safe, boolean spreadSafe, boolean implicitThis, boolean containsSpreadExpression) {
    OperandStack operandStack = controller.getOperandStack();
    CompileStack compileStack = controller.getCompileStack();
    AsmClassGenerator acg = controller.getAcg();
    // ensure VariableArguments are read, not stored
    compileStack.pushLHS(false);
    // sender only for call sites
    if (adapter == AsmClassGenerator.setProperty) {
        ConstantExpression.NULL.visit(acg);
    } else {
        sender.visit(acg);
    }
    String methodName = getMethodName(message);
    if (adapter == invokeMethodOnSuper && methodName != null) {
        controller.getSuperMethodNames().add(methodName);
    }
    // receiver
    compileStack.pushImplicitThis(implicitThis);
    receiver.visit(acg);
    operandStack.box();
    compileStack.popImplicitThis();
    int operandsToRemove = 2;
    // message
    if (message != null) {
        message.visit(acg);
        operandStack.box();
        operandsToRemove++;
    }
    // arguments
    int numberOfArguments = containsSpreadExpression ? -1 : AsmClassGenerator.argumentSize(arguments);
    if (numberOfArguments > MethodCallerMultiAdapter.MAX_ARGS || containsSpreadExpression) {
        ArgumentListExpression ae = makeArgumentList(arguments);
        if (containsSpreadExpression) {
            acg.despreadList(ae.getExpressions(), true);
        } else {
            ae.visit(acg);
        }
    } else if (numberOfArguments > 0) {
        operandsToRemove += numberOfArguments;
        TupleExpression te = (TupleExpression) arguments;
        for (int i = 0; i < numberOfArguments; i++) {
            Expression argument = te.getExpression(i);
            argument.visit(acg);
            operandStack.box();
            if (argument instanceof CastExpression)
                acg.loadWrapper(argument);
        }
    }
    if (adapter == null)
        adapter = invokeMethod;
    adapter.call(controller.getMethodVisitor(), numberOfArguments, safe, spreadSafe);
    compileStack.popLHS();
    operandStack.replace(ClassHelper.OBJECT_TYPE, operandsToRemove);
}
Also used : AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator)

Example 45 with AsmClassGenerator

use of org.codehaus.groovy.classgen.AsmClassGenerator in project groovy by apache.

the class InvocationWriter method loadArguments.

// load arguments
protected void loadArguments(List<Expression> argumentList, Parameter[] para) {
    if (para.length == 0)
        return;
    ClassNode lastParaType = para[para.length - 1].getOriginType();
    AsmClassGenerator acg = controller.getAcg();
    OperandStack operandStack = controller.getOperandStack();
    if (lastParaType.isArray() && (argumentList.size() > para.length || argumentList.size() == para.length - 1 || !lastIsArray(argumentList, para.length - 1))) {
        int stackLen = operandStack.getStackLength() + argumentList.size();
        MethodVisitor mv = controller.getMethodVisitor();
        //mv = new org.objectweb.asm.util.TraceMethodVisitor(mv);
        controller.setMethodVisitor(mv);
        // first parameters as usual
        for (int i = 0; i < para.length - 1; i++) {
            argumentList.get(i).visit(acg);
            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 {
        for (int i = 0; i < argumentList.size(); i++) {
            argumentList.get(i).visit(acg);
            operandStack.doGroovyCast(para[i].getType());
        }
    }
}
Also used : AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator) LinkedList(java.util.LinkedList) 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