Search in sources :

Example 31 with AsmClassGenerator

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

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);
    }
    // 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 32 with AsmClassGenerator

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

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)

Example 33 with AsmClassGenerator

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

the class StaticTypesStatementWriter method writeOptimizedForEachLoop.

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);
    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);
}
Also used : Label(org.objectweb.asm.Label) AsmClassGenerator(org.codehaus.groovy.classgen.AsmClassGenerator)

Example 34 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)

Example 35 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)

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