Search in sources :

Example 6 with MethodVisitor

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

the class StaticTypesCallSiteWriter method writeOperatorCall.

private void writeOperatorCall(Expression receiver, Expression arguments, String operator) {
    prepareSiteAndReceiver(receiver, operator, false, controller.getCompileStack().isLHS());
    controller.getOperandStack().doGroovyCast(Number_TYPE);
    visitBoxedArgument(arguments);
    controller.getOperandStack().doGroovyCast(Number_TYPE);
    MethodVisitor mv = controller.getMethodVisitor();
    mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/typehandling/NumberMath", operator, "(Ljava/lang/Number;Ljava/lang/Number;)Ljava/lang/Number;", false);
    controller.getOperandStack().replace(Number_TYPE, 2);
}
Also used : MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 7 with MethodVisitor

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

the class StaticTypesCallSiteWriter method writePowerCall.

private void writePowerCall(Expression receiver, Expression arguments, final ClassNode rType, ClassNode aType) {
    OperandStack operandStack = controller.getOperandStack();
    int m1 = operandStack.getStackLength();
    //slow Path
    prepareSiteAndReceiver(receiver, "power", false, controller.getCompileStack().isLHS());
    operandStack.doGroovyCast(getWrapper(rType));
    visitBoxedArgument(arguments);
    operandStack.doGroovyCast(getWrapper(aType));
    int m2 = operandStack.getStackLength();
    MethodVisitor mv = controller.getMethodVisitor();
    if (BigDecimal_TYPE.equals(rType) && Integer_TYPE.equals(getWrapper(aType))) {
        mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "power", "(Ljava/math/BigDecimal;Ljava/lang/Integer;)Ljava/lang/Number;", false);
    } else if (BigInteger_TYPE.equals(rType) && Integer_TYPE.equals(getWrapper(aType))) {
        mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "power", "(Ljava/math/BigInteger;Ljava/lang/Integer;)Ljava/lang/Number;", false);
    } else if (Long_TYPE.equals(getWrapper(rType)) && Integer_TYPE.equals(getWrapper(aType))) {
        mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "power", "(Ljava/lang/Long;Ljava/lang/Integer;)Ljava/lang/Number;", false);
    } else if (Integer_TYPE.equals(getWrapper(rType)) && Integer_TYPE.equals(getWrapper(aType))) {
        mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "power", "(Ljava/lang/Integer;Ljava/lang/Integer;)Ljava/lang/Number;", false);
    } else {
        mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/DefaultGroovyMethods", "power", "(Ljava/lang/Number;Ljava/lang/Number;)Ljava/lang/Number;", false);
    }
    controller.getOperandStack().replace(Number_TYPE, m2 - m1);
}
Also used : MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 8 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 9 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 10 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)

Aggregations

MethodVisitor (org.objectweb.asm.MethodVisitor)403 Label (org.objectweb.asm.Label)114 ClassNode (org.codehaus.groovy.ast.ClassNode)57 ClassWriter (org.objectweb.asm.ClassWriter)33 Type (org.objectweb.asm.Type)33 InnerClassNode (org.codehaus.groovy.ast.InnerClassNode)30 ArrayList (java.util.ArrayList)27 Test (org.junit.Test)23 ClassVisitor (org.objectweb.asm.ClassVisitor)23 Parameter (org.codehaus.groovy.ast.Parameter)22 LinkedList (java.util.LinkedList)19 InterfaceHelperClassNode (org.codehaus.groovy.ast.InterfaceHelperClassNode)18 AsmClassGenerator (org.codehaus.groovy.classgen.AsmClassGenerator)18 BytecodeExpression (org.codehaus.groovy.classgen.BytecodeExpression)18 FieldVisitor (org.objectweb.asm.FieldVisitor)18 ArgumentListExpression (org.codehaus.groovy.ast.expr.ArgumentListExpression)17 ClassReader (org.objectweb.asm.ClassReader)17 List (java.util.List)16 ExpressionStatement (org.codehaus.groovy.ast.stmt.ExpressionStatement)16 MethodDescription (net.bytebuddy.description.method.MethodDescription)15