Search in sources :

Example 66 with MethodVisitor

use of org.objectweb.asm.MethodVisitor in project groovy by apache.

the class StaticTypesCallSiteWriter method makeGetField.

boolean makeGetField(final Expression receiver, final ClassNode receiverType, final String fieldName, final boolean safe, final boolean implicitThis, final boolean samePackage) {
    FieldNode field = receiverType.getField(fieldName);
    // or we are in an inner class
    if (field != null && isDirectAccessAllowed(field, controller.getClassNode(), samePackage)) {
        CompileStack compileStack = controller.getCompileStack();
        MethodVisitor mv = controller.getMethodVisitor();
        ClassNode replacementType = field.getOriginType();
        OperandStack operandStack = controller.getOperandStack();
        if (field.isStatic()) {
            mv.visitFieldInsn(GETSTATIC, BytecodeHelper.getClassInternalName(field.getOwner()), fieldName, BytecodeHelper.getTypeDescription(replacementType));
            operandStack.push(replacementType);
        } else {
            if (implicitThis) {
                compileStack.pushImplicitThis(implicitThis);
            }
            receiver.visit(controller.getAcg());
            if (implicitThis)
                compileStack.popImplicitThis();
            Label exit = new Label();
            if (safe) {
                mv.visitInsn(DUP);
                Label doGet = new Label();
                mv.visitJumpInsn(IFNONNULL, doGet);
                mv.visitInsn(POP);
                mv.visitInsn(ACONST_NULL);
                mv.visitJumpInsn(GOTO, exit);
                mv.visitLabel(doGet);
            }
            if (!operandStack.getTopOperand().isDerivedFrom(field.getOwner())) {
                mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(field.getOwner()));
            }
            mv.visitFieldInsn(GETFIELD, BytecodeHelper.getClassInternalName(field.getOwner()), fieldName, BytecodeHelper.getTypeDescription(replacementType));
            if (safe) {
                if (ClassHelper.isPrimitiveType(replacementType)) {
                    operandStack.replace(replacementType);
                    operandStack.box();
                    replacementType = operandStack.getTopOperand();
                }
                mv.visitLabel(exit);
            }
        }
        operandStack.replace(replacementType);
        return true;
    }
    for (ClassNode intf : receiverType.getInterfaces()) {
        // GROOVY-7039
        if (intf != receiverType && makeGetField(receiver, intf, fieldName, safe, implicitThis, false)) {
            return true;
        }
    }
    ClassNode superClass = receiverType.getSuperClass();
    if (superClass != null) {
        return makeGetField(receiver, superClass, fieldName, safe, implicitThis, false);
    }
    return false;
}
Also used : Label(org.objectweb.asm.Label) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 67 with MethodVisitor

use of org.objectweb.asm.MethodVisitor in project groovy by apache.

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 68 with MethodVisitor

use of org.objectweb.asm.MethodVisitor in project groovy by apache.

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 69 with MethodVisitor

use of org.objectweb.asm.MethodVisitor in project groovy by apache.

the class StaticTypesUnaryExpressionHelper method writeBitwiseNegate.

@Override
public void writeBitwiseNegate(final BitwiseNegationExpression expression) {
    expression.getExpression().visit(controller.getAcg());
    if (isPrimitiveOnTop()) {
        final ClassNode top = getTopOperand();
        if (top == int_TYPE || top == short_TYPE || top == byte_TYPE || top == char_TYPE || top == long_TYPE) {
            BytecodeExpression bytecodeExpression = new BytecodeExpression() {

                @Override
                public void visit(final MethodVisitor mv) {
                    if (long_TYPE == top) {
                        mv.visitLdcInsn(-1);
                        mv.visitInsn(LXOR);
                    } else {
                        mv.visitInsn(ICONST_M1);
                        mv.visitInsn(IXOR);
                        if (byte_TYPE == top) {
                            mv.visitInsn(I2B);
                        } else if (char_TYPE == top) {
                            mv.visitInsn(I2C);
                        } else if (short_TYPE == top) {
                            mv.visitInsn(I2S);
                        }
                    }
                }
            };
            bytecodeExpression.visit(controller.getAcg());
            controller.getOperandStack().remove(1);
            return;
        }
    }
    super.writeBitwiseNegate(EMPTY_BITWISE_NEGATE);
}
Also used : ClassNode(org.codehaus.groovy.ast.ClassNode) BytecodeExpression(org.codehaus.groovy.classgen.BytecodeExpression) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 70 with MethodVisitor

use of org.objectweb.asm.MethodVisitor in project groovy by apache.

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)

Aggregations

MethodVisitor (org.objectweb.asm.MethodVisitor)630 Label (org.objectweb.asm.Label)186 ClassWriter (org.objectweb.asm.ClassWriter)116 Type (org.objectweb.asm.Type)59 ClassNode (org.codehaus.groovy.ast.ClassNode)57 FieldVisitor (org.objectweb.asm.FieldVisitor)56 ClassVisitor (org.objectweb.asm.ClassVisitor)47 ClassReader (org.objectweb.asm.ClassReader)43 ArrayList (java.util.ArrayList)32 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)30 Test (org.junit.Test)29 AnnotationVisitor (org.objectweb.asm.AnnotationVisitor)29 List (java.util.List)23 LinkedList (java.util.LinkedList)22 Parameter (org.codehaus.groovy.ast.Parameter)22 InterfaceHelperClassNode (org.codehaus.groovy.ast.InterfaceHelperClassNode)18 AsmClassGenerator (org.codehaus.groovy.classgen.AsmClassGenerator)18 BytecodeExpression (org.codehaus.groovy.classgen.BytecodeExpression)18 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)17 Method (java.lang.reflect.Method)16