Search in sources :

Example 11 with BytecodeExpression

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

the class StaticTypesUnaryExpressionHelper method writeUnaryMinus.

@Override
public void writeUnaryMinus(final UnaryMinusExpression expression) {
    expression.getExpression().visit(controller.getAcg());
    if (isPrimitiveOnTop()) {
        final ClassNode top = getTopOperand();
        if (top != boolean_TYPE) {
            BytecodeExpression bytecodeExpression = new BytecodeExpression() {

                @Override
                public void visit(final MethodVisitor mv) {
                    if (int_TYPE == top || short_TYPE == top || byte_TYPE == top || char_TYPE == top) {
                        mv.visitInsn(INEG);
                        if (byte_TYPE == top) {
                            mv.visitInsn(I2B);
                        } else if (char_TYPE == top) {
                            mv.visitInsn(I2C);
                        } else if (short_TYPE == top) {
                            mv.visitInsn(I2S);
                        }
                    } else if (long_TYPE == top) {
                        mv.visitInsn(LNEG);
                    } else if (float_TYPE == top) {
                        mv.visitInsn(FNEG);
                    } else if (double_TYPE == top) {
                        mv.visitInsn(DNEG);
                    }
                }
            };
            bytecodeExpression.visit(controller.getAcg());
            controller.getOperandStack().remove(1);
            return;
        }
    }
    // we already visited the sub expression
    super.writeUnaryMinus(EMPTY_UNARY_MINUS);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) BytecodeExpression(org.codehaus.groovy.classgen.BytecodeExpression) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 12 with BytecodeExpression

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

the class StaticTypesUnaryExpressionHelper method writeNotExpression.

@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
            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);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) TypeChooser(org.codehaus.groovy.classgen.asm.TypeChooser) BytecodeExpression(org.codehaus.groovy.classgen.BytecodeExpression) Label(org.objectweb.asm.Label) BytecodeExpression(org.codehaus.groovy.classgen.BytecodeExpression) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 13 with BytecodeExpression

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

the class StaticTypesCallSiteWriter method makeGroovyObjectGetPropertySite.

@Override
public void makeGroovyObjectGetPropertySite(final Expression receiver, final String methodName, final boolean safe, final boolean implicitThis) {
    TypeChooser typeChooser = controller.getTypeChooser();
    ClassNode classNode = controller.getClassNode();
    ClassNode receiverType = typeChooser.resolveType(receiver, classNode);
    if (receiver instanceof VariableExpression && ((VariableExpression) receiver).isThisExpression() && !controller.isInClosure()) {
        receiverType = classNode;
    }
    String property = methodName;
    if (implicitThis) {
        if (controller.getInvocationWriter() instanceof StaticInvocationWriter) {
            MethodCallExpression currentCall = ((StaticInvocationWriter) controller.getInvocationWriter()).getCurrentCall();
            if (currentCall != null && currentCall.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER) != null) {
                property = (String) currentCall.getNodeMetaData(StaticTypesMarker.IMPLICIT_RECEIVER);
                String[] props = property.split("\\.");
                BytecodeExpression thisLoader = new BytecodeExpression() {

                    @Override
                    public void visit(final MethodVisitor mv) {
                        // load this
                        mv.visitVarInsn(ALOAD, 0);
                    }
                };
                thisLoader.setType(CLOSURE_TYPE);
                Expression pexp = new PropertyExpression(thisLoader, new ConstantExpression(props[0]), safe);
                for (int i = 1, propsLength = props.length; i < propsLength; i++) {
                    final String prop = props[i];
                    pexp.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, CLOSURE_TYPE);
                    pexp = new PropertyExpression(pexp, prop);
                }
                pexp.visit(controller.getAcg());
                return;
            }
        }
    }
    if (makeGetPropertyWithGetter(receiver, receiverType, property, safe, implicitThis))
        return;
    if (makeGetPrivateFieldWithBridgeMethod(receiver, receiverType, property, safe, implicitThis))
        return;
    if (makeGetField(receiver, receiverType, property, safe, implicitThis, samePackages(receiverType.getPackageName(), classNode.getPackageName())))
        return;
    MethodCallExpression call = new MethodCallExpression(receiver, "getProperty", new ArgumentListExpression(new ConstantExpression(property)));
    call.setImplicitThis(implicitThis);
    call.setSafe(safe);
    call.setMethodTarget(GROOVYOBJECT_GETPROPERTY_METHOD);
    call.visit(controller.getAcg());
    return;
}
Also used : MethodVisitor(org.objectweb.asm.MethodVisitor) BytecodeExpression(org.codehaus.groovy.classgen.BytecodeExpression) BytecodeExpression(org.codehaus.groovy.classgen.BytecodeExpression)

Example 14 with BytecodeExpression

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

the class StaticTypesCallSiteWriter method writeListDotProperty.

private void writeListDotProperty(final Expression receiver, final String methodName, final MethodVisitor mv, final boolean safe) {
    ClassNode componentType = (ClassNode) receiver.getNodeMetaData(StaticCompilationMetadataKeys.COMPONENT_TYPE);
    if (componentType == null) {
        componentType = OBJECT_TYPE;
    }
    // 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", 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;
        }
    }, methodName);
    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(make(ArrayList.class));
    controller.getCompileStack().removeVar(next);
    controller.getCompileStack().removeVar(it);
    controller.getCompileStack().removeVar(var);
}
Also used : Label(org.objectweb.asm.Label) BytecodeExpression(org.codehaus.groovy.classgen.BytecodeExpression) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 15 with BytecodeExpression

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

the class BinaryExpressionHelper method writePostOrPrefixMethod.

protected void writePostOrPrefixMethod(int op, String method, Expression expression, Expression orig) {
    final OperandStack operandStack = controller.getOperandStack();
    // at this point the receiver will be already on the stack.
    // in a[1]++ the method will be "++" aka "next" and the receiver a[1]
    ClassNode BEType = controller.getTypeChooser().resolveType(expression, controller.getClassNode());
    Expression callSiteReceiverSwap = new BytecodeExpression(BEType) {

        @Override
        public void visit(MethodVisitor mv) {
            // CallSite is normally not showing up on the 
            // operandStack, so we place a dummy here with same
            // slot length.
            operandStack.push(ClassHelper.OBJECT_TYPE);
            // change (receiver,callsite) to (callsite,receiver)
            operandStack.swap();
            setType(operandStack.getTopOperand());
            // no need to keep any of those on the operand stack
            // after this expression is processed, the operand stack
            // will contain callSiteReceiverSwap.getType()
            operandStack.remove(2);
        }
    };
    // execute method
    // this will load the callsite and the receiver normally in the wrong
    // order since the receiver is already present, but before the callsite
    // Therefore we use callSiteReceiverSwap to correct the order. 
    // After this call the JVM operand stack will contain the the result of
    // the method call... usually simply Object in operandStack
    controller.getCallSiteWriter().makeCallSite(callSiteReceiverSwap, method, MethodCallExpression.NO_ARGUMENTS, false, false, false, false);
// now rhs is completely done and we need only to store. In a[1]++ this 
// would be a.getAt(1).next() for the rhs, "lhs" code is a.putAt(1, rhs)
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) ListExpression(org.codehaus.groovy.ast.expr.ListExpression) PropertyExpression(org.codehaus.groovy.ast.expr.PropertyExpression) ElvisOperatorExpression(org.codehaus.groovy.ast.expr.ElvisOperatorExpression) ConstantExpression(org.codehaus.groovy.ast.expr.ConstantExpression) PrefixExpression(org.codehaus.groovy.ast.expr.PrefixExpression) PostfixExpression(org.codehaus.groovy.ast.expr.PostfixExpression) MethodCallExpression(org.codehaus.groovy.ast.expr.MethodCallExpression) BytecodeExpression(org.codehaus.groovy.classgen.BytecodeExpression) EmptyExpression(org.codehaus.groovy.ast.expr.EmptyExpression) Expression(org.codehaus.groovy.ast.expr.Expression) VariableExpression(org.codehaus.groovy.ast.expr.VariableExpression) ArrayExpression(org.codehaus.groovy.ast.expr.ArrayExpression) ArgumentListExpression(org.codehaus.groovy.ast.expr.ArgumentListExpression) ClassExpression(org.codehaus.groovy.ast.expr.ClassExpression) TupleExpression(org.codehaus.groovy.ast.expr.TupleExpression) BinaryExpression(org.codehaus.groovy.ast.expr.BinaryExpression) FieldExpression(org.codehaus.groovy.ast.expr.FieldExpression) TernaryExpression(org.codehaus.groovy.ast.expr.TernaryExpression) BytecodeExpression(org.codehaus.groovy.classgen.BytecodeExpression) MethodVisitor(org.objectweb.asm.MethodVisitor)

Aggregations

BytecodeExpression (org.codehaus.groovy.classgen.BytecodeExpression)16 ClassNode (org.codehaus.groovy.ast.ClassNode)12 MethodVisitor (org.objectweb.asm.MethodVisitor)12 BinaryExpression (org.codehaus.groovy.ast.expr.BinaryExpression)6 FieldExpression (org.codehaus.groovy.ast.expr.FieldExpression)6 PropertyExpression (org.codehaus.groovy.ast.expr.PropertyExpression)6 VariableExpression (org.codehaus.groovy.ast.expr.VariableExpression)6 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)4 ArrayExpression (org.codehaus.groovy.ast.expr.ArrayExpression)4 ClassExpression (org.codehaus.groovy.ast.expr.ClassExpression)4 ConstantExpression (org.codehaus.groovy.ast.expr.ConstantExpression)4 ElvisOperatorExpression (org.codehaus.groovy.ast.expr.ElvisOperatorExpression)4 EmptyExpression (org.codehaus.groovy.ast.expr.EmptyExpression)4 Expression (org.codehaus.groovy.ast.expr.Expression)4 ListExpression (org.codehaus.groovy.ast.expr.ListExpression)4 MethodCallExpression (org.codehaus.groovy.ast.expr.MethodCallExpression)4 PostfixExpression (org.codehaus.groovy.ast.expr.PostfixExpression)4 PrefixExpression (org.codehaus.groovy.ast.expr.PrefixExpression)4 TernaryExpression (org.codehaus.groovy.ast.expr.TernaryExpression)4 TupleExpression (org.codehaus.groovy.ast.expr.TupleExpression)4