Search in sources :

Example 16 with MethodVisitor

use of org.objectweb.asm.MethodVisitor in project groovy-core by groovy.

the class AsmClassGenerator method storeThisInstanceField.

private void storeThisInstanceField(FieldExpression expression) {
    MethodVisitor mv = controller.getMethodVisitor();
    FieldNode field = expression.getField();
    boolean setReferenceFromReference = field.isHolder() && expression.isUseReferenceDirectly();
    String ownerName = (field.getOwner().equals(controller.getClassNode())) ? controller.getInternalClassName() : BytecodeHelper.getClassInternalName(field.getOwner());
    OperandStack operandStack = controller.getOperandStack();
    if (setReferenceFromReference) {
        // rhs is ready to use reference, just put it in the field
        mv.visitVarInsn(ALOAD, 0);
        operandStack.push(controller.getClassNode());
        operandStack.swap();
        mv.visitFieldInsn(PUTFIELD, ownerName, field.getName(), BytecodeHelper.getTypeDescription(field.getType()));
    } else if (field.isHolder()) {
        // rhs is normal value, set the value in the Reference
        operandStack.doGroovyCast(field.getOriginType());
        operandStack.box();
        mv.visitVarInsn(ALOAD, 0);
        mv.visitFieldInsn(GETFIELD, ownerName, expression.getFieldName(), BytecodeHelper.getTypeDescription(field.getType()));
        mv.visitInsn(SWAP);
        mv.visitMethodInsn(INVOKEVIRTUAL, "groovy/lang/Reference", "set", "(Ljava/lang/Object;)V", false);
    } else {
        // rhs is normal value, set normal value
        operandStack.doGroovyCast(field.getOriginType());
        mv.visitVarInsn(ALOAD, 0);
        operandStack.push(controller.getClassNode());
        operandStack.swap();
        mv.visitFieldInsn(PUTFIELD, ownerName, field.getName(), BytecodeHelper.getTypeDescription(field.getType()));
    }
}
Also used : OperandStack(org.codehaus.groovy.classgen.asm.OperandStack) FieldNode(org.codehaus.groovy.ast.FieldNode) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 17 with MethodVisitor

use of org.objectweb.asm.MethodVisitor in project groovy-core by groovy.

the class AsmClassGenerator method visitArrayExpression.

public void visitArrayExpression(ArrayExpression expression) {
    MethodVisitor mv = controller.getMethodVisitor();
    ClassNode elementType = expression.getElementType();
    String arrayTypeName = BytecodeHelper.getClassInternalName(elementType);
    List sizeExpression = expression.getSizeExpression();
    int size = 0;
    int dimensions = 0;
    if (sizeExpression != null) {
        for (Iterator iter = sizeExpression.iterator(); iter.hasNext(); ) {
            Expression element = (Expression) iter.next();
            if (element == ConstantExpression.EMPTY_EXPRESSION)
                break;
            dimensions++;
            // let's convert to an int
            element.visit(this);
            controller.getOperandStack().doGroovyCast(ClassHelper.int_TYPE);
        }
        controller.getOperandStack().remove(dimensions);
    } else {
        size = expression.getExpressions().size();
        BytecodeHelper.pushConstant(mv, size);
    }
    int storeIns = AASTORE;
    if (sizeExpression != null) {
        arrayTypeName = BytecodeHelper.getTypeDescription(expression.getType());
        mv.visitMultiANewArrayInsn(arrayTypeName, dimensions);
    } else if (ClassHelper.isPrimitiveType(elementType)) {
        int primType = 0;
        if (elementType == ClassHelper.boolean_TYPE) {
            primType = T_BOOLEAN;
            storeIns = BASTORE;
        } else if (elementType == ClassHelper.char_TYPE) {
            primType = T_CHAR;
            storeIns = CASTORE;
        } else if (elementType == ClassHelper.float_TYPE) {
            primType = T_FLOAT;
            storeIns = FASTORE;
        } else if (elementType == ClassHelper.double_TYPE) {
            primType = T_DOUBLE;
            storeIns = DASTORE;
        } else if (elementType == ClassHelper.byte_TYPE) {
            primType = T_BYTE;
            storeIns = BASTORE;
        } else if (elementType == ClassHelper.short_TYPE) {
            primType = T_SHORT;
            storeIns = SASTORE;
        } else if (elementType == ClassHelper.int_TYPE) {
            primType = T_INT;
            storeIns = IASTORE;
        } else if (elementType == ClassHelper.long_TYPE) {
            primType = T_LONG;
            storeIns = LASTORE;
        }
        mv.visitIntInsn(NEWARRAY, primType);
    } else {
        mv.visitTypeInsn(ANEWARRAY, arrayTypeName);
    }
    for (int i = 0; i < size; i++) {
        mv.visitInsn(DUP);
        BytecodeHelper.pushConstant(mv, i);
        Expression elementExpression = expression.getExpression(i);
        if (elementExpression == null) {
            ConstantExpression.NULL.visit(this);
        } else {
            elementExpression.visit(this);
            controller.getOperandStack().doGroovyCast(elementType);
        }
        mv.visitInsn(storeIns);
        controller.getOperandStack().remove(1);
    }
    controller.getOperandStack().push(expression.getType());
}
Also used : InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) InterfaceHelperClassNode(org.codehaus.groovy.ast.InterfaceHelperClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) Iterator(java.util.Iterator) List(java.util.List) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 18 with MethodVisitor

use of org.objectweb.asm.MethodVisitor in project groovy-core by groovy.

the class AsmClassGenerator method visitStdMethod.

private void visitStdMethod(MethodNode node, boolean isConstructor, Parameter[] parameters, Statement code) {
    MethodVisitor mv = controller.getMethodVisitor();
    final ClassNode superClass = controller.getClassNode().getSuperClass();
    if (isConstructor && (code == null || !((ConstructorNode) node).firstStatementIsSpecialConstructorCall())) {
        boolean hasCallToSuper = false;
        if (code != null && controller.getClassNode() instanceof InnerClassNode) {
            // so we must ensure not to add it twice (see GROOVY-4471)
            if (code instanceof BlockStatement) {
                for (Statement statement : ((BlockStatement) code).getStatements()) {
                    if (statement instanceof ExpressionStatement) {
                        final Expression expression = ((ExpressionStatement) statement).getExpression();
                        if (expression instanceof ConstructorCallExpression) {
                            ConstructorCallExpression call = (ConstructorCallExpression) expression;
                            if (call.isSuperCall()) {
                                hasCallToSuper = true;
                                break;
                            }
                        }
                    }
                }
            }
        }
        if (!hasCallToSuper) {
            // invokes the super class constructor
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(superClass), "<init>", "()V", false);
        }
    }
    controller.getCompileStack().init(node.getVariableScope(), parameters);
    controller.getCallSiteWriter().makeSiteEntry();
    // handle body
    super.visitConstructorOrMethod(node, isConstructor);
    controller.getCompileStack().clear();
    if (node.isVoidMethod()) {
        mv.visitInsn(RETURN);
    } else {
        // we make a dummy return for label ranges that reach here
        ClassNode type = node.getReturnType().redirect();
        if (ClassHelper.isPrimitiveType(type)) {
            mv.visitLdcInsn(0);
            controller.getOperandStack().push(ClassHelper.int_TYPE);
            controller.getOperandStack().doGroovyCast(type);
            BytecodeHelper.doReturn(mv, type);
            controller.getOperandStack().remove(1);
        } else {
            mv.visitInsn(ACONST_NULL);
            BytecodeHelper.doReturn(mv, type);
        }
    }
}
Also used : InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) InterfaceHelperClassNode(org.codehaus.groovy.ast.InterfaceHelperClassNode) ClassNode(org.codehaus.groovy.ast.ClassNode) ConstructorNode(org.codehaus.groovy.ast.ConstructorNode) CaseStatement(org.codehaus.groovy.ast.stmt.CaseStatement) ForStatement(org.codehaus.groovy.ast.stmt.ForStatement) CatchStatement(org.codehaus.groovy.ast.stmt.CatchStatement) IfStatement(org.codehaus.groovy.ast.stmt.IfStatement) AssertStatement(org.codehaus.groovy.ast.stmt.AssertStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) Statement(org.codehaus.groovy.ast.stmt.Statement) WhileStatement(org.codehaus.groovy.ast.stmt.WhileStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) ThrowStatement(org.codehaus.groovy.ast.stmt.ThrowStatement) DoWhileStatement(org.codehaus.groovy.ast.stmt.DoWhileStatement) ContinueStatement(org.codehaus.groovy.ast.stmt.ContinueStatement) BreakStatement(org.codehaus.groovy.ast.stmt.BreakStatement) ReturnStatement(org.codehaus.groovy.ast.stmt.ReturnStatement) SynchronizedStatement(org.codehaus.groovy.ast.stmt.SynchronizedStatement) SwitchStatement(org.codehaus.groovy.ast.stmt.SwitchStatement) TryCatchStatement(org.codehaus.groovy.ast.stmt.TryCatchStatement) ExpressionStatement(org.codehaus.groovy.ast.stmt.ExpressionStatement) BlockStatement(org.codehaus.groovy.ast.stmt.BlockStatement) InnerClassNode(org.codehaus.groovy.ast.InnerClassNode) MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 19 with MethodVisitor

use of org.objectweb.asm.MethodVisitor in project groovy-core by groovy.

the class AsmClassGenerator method visitTupleExpression.

void visitTupleExpression(TupleExpression expression, boolean useWrapper) {
    MethodVisitor mv = controller.getMethodVisitor();
    int size = expression.getExpressions().size();
    BytecodeHelper.pushConstant(mv, size);
    mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
    for (int i = 0; i < size; i++) {
        mv.visitInsn(DUP);
        BytecodeHelper.pushConstant(mv, i);
        Expression argument = expression.getExpression(i);
        argument.visit(this);
        controller.getOperandStack().box();
        if (useWrapper && argument instanceof CastExpression)
            loadWrapper(argument);
        mv.visitInsn(AASTORE);
        controller.getOperandStack().remove(1);
    }
}
Also used : MethodVisitor(org.objectweb.asm.MethodVisitor)

Example 20 with MethodVisitor

use of org.objectweb.asm.MethodVisitor in project groovy-core by groovy.

the class Verifier method addStaticMetaClassField.

private void addStaticMetaClassField(final ClassNode node, final String classInternalName) {
    String _staticClassInfoFieldName = "$staticClassInfo";
    while (node.getDeclaredField(_staticClassInfoFieldName) != null) _staticClassInfoFieldName = _staticClassInfoFieldName + "$";
    final String staticMetaClassFieldName = _staticClassInfoFieldName;
    FieldNode staticMetaClassField = node.addField(staticMetaClassFieldName, ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, ClassHelper.make(ClassInfo.class, false), null);
    staticMetaClassField.setSynthetic(true);
    node.addSyntheticMethod("$getStaticMetaClass", ACC_PROTECTED, ClassHelper.make(MetaClass.class), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BytecodeSequence(new BytecodeInstruction() {

        public void visit(MethodVisitor mv) {
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
            if (BytecodeHelper.isClassLiteralPossible(node) || BytecodeHelper.isSameCompilationUnit(classNode, node)) {
                BytecodeHelper.visitClassLiteral(mv, node);
            } else {
                mv.visitMethodInsn(INVOKESTATIC, classInternalName, "$get$$class$" + classInternalName.replaceAll("\\/", "\\$"), "()Ljava/lang/Class;", false);
            }
            Label l1 = new Label();
            mv.visitJumpInsn(IF_ACMPEQ, l1);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/runtime/ScriptBytecodeAdapter", "initMetaClass", "(Ljava/lang/Object;)Lgroovy/lang/MetaClass;", false);
            mv.visitInsn(ARETURN);
            mv.visitLabel(l1);
            mv.visitFieldInsn(GETSTATIC, classInternalName, staticMetaClassFieldName, "Lorg/codehaus/groovy/reflection/ClassInfo;");
            mv.visitVarInsn(ASTORE, 1);
            mv.visitVarInsn(ALOAD, 1);
            Label l0 = new Label();
            mv.visitJumpInsn(IFNONNULL, l0);
            mv.visitVarInsn(ALOAD, 0);
            mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;", false);
            mv.visitMethodInsn(INVOKESTATIC, "org/codehaus/groovy/reflection/ClassInfo", "getClassInfo", "(Ljava/lang/Class;)Lorg/codehaus/groovy/reflection/ClassInfo;", false);
            mv.visitInsn(DUP);
            mv.visitVarInsn(ASTORE, 1);
            mv.visitFieldInsn(PUTSTATIC, classInternalName, staticMetaClassFieldName, "Lorg/codehaus/groovy/reflection/ClassInfo;");
            mv.visitLabel(l0);
            mv.visitVarInsn(ALOAD, 1);
            mv.visitMethodInsn(INVOKEVIRTUAL, "org/codehaus/groovy/reflection/ClassInfo", "getMetaClass", "()Lgroovy/lang/MetaClass;", false);
            mv.visitInsn(ARETURN);
        }
    }));
}
Also used : MetaClass(groovy.lang.MetaClass) Label(org.objectweb.asm.Label) ClassInfo(org.codehaus.groovy.reflection.ClassInfo) MethodVisitor(org.objectweb.asm.MethodVisitor)

Aggregations

MethodVisitor (org.objectweb.asm.MethodVisitor)407 Label (org.objectweb.asm.Label)114 ClassNode (org.codehaus.groovy.ast.ClassNode)57 ClassWriter (org.objectweb.asm.ClassWriter)34 Type (org.objectweb.asm.Type)34 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