Search in sources :

Example 1 with AnnotationDefaultTag

use of soot.tagkit.AnnotationDefaultTag in project robovm by robovm.

the class AttributesEncoder method encodeAttributes.

private Constant encodeAttributes(Host host) {
    List<Value> attributes = new ArrayList<Value>();
    for (Tag tag : host.getTags()) {
        if (tag instanceof SourceFileTag) {
            // Skip. We don't need this at this time.
            Value sourceFile = getString(((SourceFileTag) tag).getSourceFile());
            attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR), new IntegerConstant(SOURCE_FILE), sourceFile));
        } else if (tag instanceof EnclosingMethodTag) {
            EnclosingMethodTag emt = (EnclosingMethodTag) tag;
            Value eClass = getString(emt.getEnclosingClass());
            Value eMethod = getStringOrNull(emt.getEnclosingMethod());
            Value eDesc = getStringOrNull(emt.getEnclosingMethodSig());
            attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR, I8_PTR, I8_PTR), new IntegerConstant(ENCLOSING_METHOD), eClass, eMethod, eDesc));
        } else if (tag instanceof SignatureTag) {
            Value signature = getString(((SignatureTag) tag).getSignature());
            attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR), new IntegerConstant(SIGNATURE), signature));
        } else if (tag instanceof InnerClassTag) {
            InnerClassTag ict = (InnerClassTag) tag;
            Value innerClass = getStringOrNull(ict.getInnerClass());
            Value outerClass = getStringOrNull(ict.getOuterClass());
            Value innerName = getStringOrNull(ict.getShortName());
            Value innerClassAccess = new IntegerConstant(ict.getAccessFlags());
            attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I8_PTR, I8_PTR, I8_PTR, I32), new IntegerConstant(INNER_CLASS), innerClass, outerClass, innerName, innerClassAccess));
        } else if (tag instanceof AnnotationDefaultTag) {
            StructureConstant value = encodeAnnotationElementValue(((AnnotationDefaultTag) tag).getDefaultVal());
            attributes.add(new PackedStructureConstant(new PackedStructureType(I8, value.getType()), new IntegerConstant(ANNOTATION_DEFAULT), value));
        } else if (tag instanceof VisibilityAnnotationTag) {
            VisibilityAnnotationTag vat = (VisibilityAnnotationTag) tag;
            if (vat.getVisibility() == AnnotationConstants.RUNTIME_VISIBLE) {
                Type[] types = new Type[vat.getAnnotations().size()];
                Value[] values = new Value[vat.getAnnotations().size()];
                int i = 0;
                for (AnnotationTag at : vat.getAnnotations()) {
                    values[i] = encodeAnnotationTagValue(at);
                    types[i] = values[i].getType();
                    i++;
                }
                attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I32, new PackedStructureType(types)), new IntegerConstant(RUNTIME_VISIBLE_ANNOTATIONS), new IntegerConstant(vat.getAnnotations().size()), new PackedStructureConstant(new PackedStructureType(types), values)));
            }
        } else if (tag instanceof VisibilityParameterAnnotationTag) {
            VisibilityParameterAnnotationTag vpat = (VisibilityParameterAnnotationTag) tag;
            List<Type> typesList = new ArrayList<Type>();
            List<Value> valuesList = new ArrayList<Value>();
            boolean hasRuntimeVisible = false;
            for (VisibilityAnnotationTag vat : vpat.getVisibilityAnnotations()) {
                typesList.add(I32);
                if (vat.getVisibility() == AnnotationConstants.RUNTIME_VISIBLE && vat.getAnnotations() != null && !vat.getAnnotations().isEmpty()) {
                    hasRuntimeVisible = true;
                    valuesList.add(new IntegerConstant(vat.getAnnotations().size()));
                    for (AnnotationTag at : vat.getAnnotations()) {
                        valuesList.add(encodeAnnotationTagValue(at));
                        typesList.add(valuesList.get(valuesList.size() - 1).getType());
                    }
                } else {
                    valuesList.add(new IntegerConstant(0));
                }
            }
            if (hasRuntimeVisible) {
                Type[] types = typesList.toArray(new Type[typesList.size()]);
                Value[] values = valuesList.toArray(new Value[valuesList.size()]);
                attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I32, new PackedStructureType(types)), new IntegerConstant(RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS), new IntegerConstant(vpat.getVisibilityAnnotations().size()), new PackedStructureConstant(new PackedStructureType(types), values)));
            }
        }
    }
    if (host instanceof SootMethod) {
        List<SootClass> exceptions = ((SootMethod) host).getExceptions();
        if (!exceptions.isEmpty()) {
            Value[] values = new Value[exceptions.size()];
            for (int i = 0; i < exceptions.size(); i++) {
                String exName = getInternalName(exceptions.get(i));
                values[i] = getString(exName);
                addDependency(exName);
            }
            attributes.add(new PackedStructureConstant(new PackedStructureType(I8, I32, new ArrayType(exceptions.size(), I8_PTR)), new IntegerConstant(EXCEPTIONS), new IntegerConstant(exceptions.size()), new ArrayConstant(new ArrayType(exceptions.size(), I8_PTR), values)));
        }
    }
    if (attributes.isEmpty()) {
        return null;
    }
    attributes.add(0, new IntegerConstant(attributes.size()));
    Type[] types = new Type[attributes.size()];
    for (int i = 0; i < types.length; i++) {
        types[i] = attributes.get(i).getType();
    }
    return new PackedStructureConstant(new PackedStructureType(types), attributes.toArray(new Value[0]));
}
Also used : ArrayList(java.util.ArrayList) SourceFileTag(soot.tagkit.SourceFileTag) ArrayType(org.robovm.compiler.llvm.ArrayType) InnerClassTag(soot.tagkit.InnerClassTag) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) AnnotationTag(soot.tagkit.AnnotationTag) VisibilityParameterAnnotationTag(soot.tagkit.VisibilityParameterAnnotationTag) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) ArrayConstant(org.robovm.compiler.llvm.ArrayConstant) VisibilityParameterAnnotationTag(soot.tagkit.VisibilityParameterAnnotationTag) AnnotationDefaultTag(soot.tagkit.AnnotationDefaultTag) SootClass(soot.SootClass) PackedStructureType(org.robovm.compiler.llvm.PackedStructureType) IntegerConstant(org.robovm.compiler.llvm.IntegerConstant) PackedStructureConstant(org.robovm.compiler.llvm.PackedStructureConstant) EnclosingMethodTag(soot.tagkit.EnclosingMethodTag) PackedStructureType(org.robovm.compiler.llvm.PackedStructureType) ArrayType(org.robovm.compiler.llvm.ArrayType) Type(org.robovm.compiler.llvm.Type) StructureConstant(org.robovm.compiler.llvm.StructureConstant) PackedStructureConstant(org.robovm.compiler.llvm.PackedStructureConstant) Value(org.robovm.compiler.llvm.Value) SignatureTag(soot.tagkit.SignatureTag) SootMethod(soot.SootMethod) Tag(soot.tagkit.Tag) AnnotationDefaultTag(soot.tagkit.AnnotationDefaultTag) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) InnerClassTag(soot.tagkit.InnerClassTag) SignatureTag(soot.tagkit.SignatureTag) AnnotationTag(soot.tagkit.AnnotationTag) SourceFileTag(soot.tagkit.SourceFileTag) EnclosingMethodTag(soot.tagkit.EnclosingMethodTag) VisibilityParameterAnnotationTag(soot.tagkit.VisibilityParameterAnnotationTag)

Example 2 with AnnotationDefaultTag

use of soot.tagkit.AnnotationDefaultTag in project robovm by robovm.

the class AnnotationImplPlugin method generateSetDefaultsMethod.

private void generateSetDefaultsMethod(Clazz clazz, ClassWriter cw) {
    String implName = clazz.getInternalName() + IMPL_CLASS_NAME_SUFFIX;
    SootClass sootClass = clazz.getSootClass();
    List<SootMethod> methods = sootClass.getMethods();
    // Generate the $setDefaults() method which is called from the constructor
    // to set any default values
    MethodVisitor mv = cw.visitMethod(ACC_PRIVATE, "$setDefaults", "()V", null, null);
    mv.visitCode();
    for (SootMethod method : methods) {
        AnnotationDefaultTag defTag = (AnnotationDefaultTag) method.getTag(AnnotationDefaultTag.class.getSimpleName());
        String fieldName = getFieldName(method);
        if (defTag == null) {
            // No default value. Set field to super.NO_VALUE.
            mv.visitVarInsn(ALOAD, 0);
            mv.visitFieldInsn(GETSTATIC, BASE_CLASS, "NO_VALUE", "Ljava/lang/Object;");
            mv.visitFieldInsn(PUTFIELD, implName, fieldName, "Ljava/lang/Object;");
        } else {
            soot.Type type = method.getReturnType();
            String typeDesc = Types.getDescriptor(type);
            Object v = null;
            if (type instanceof PrimType) {
                switch(typeDesc.charAt(0)) {
                    case 'Z':
                    case 'B':
                    case 'S':
                    case 'C':
                    case 'I':
                        v = ((AnnotationIntElem) defTag.getDefaultVal()).getValue();
                        break;
                    case 'J':
                        v = ((AnnotationLongElem) defTag.getDefaultVal()).getValue();
                        break;
                    case 'F':
                        v = ((AnnotationFloatElem) defTag.getDefaultVal()).getValue();
                        break;
                    case 'D':
                        v = ((AnnotationDoubleElem) defTag.getDefaultVal()).getValue();
                        break;
                }
            } else if ("Ljava/lang/Class;".equals(typeDesc)) {
                v = Type.getType(((AnnotationClassElem) defTag.getDefaultVal()).getDesc());
                if (((Type) v).getDescriptor().length() != 1) {
                    // Only use a simple LDC for primitive classes (e.g. byte.class).
                    // Other classes may not be available at runtime. By falling back
                    // to Method.getDefaultValue() below we will get the proper
                    // exception at runtime.
                    v = null;
                }
            } else if ("Ljava/lang/String;".equals(typeDesc)) {
                v = ((AnnotationStringElem) defTag.getDefaultVal()).getValue();
            }
            if (v != null) {
                mv.visitVarInsn(ALOAD, 0);
                if (v instanceof Type && ((Type) v).getDescriptor().length() == 1) {
                    // LDC of primitive type class such as byte.class
                    switch(((Type) v).getDescriptor().charAt(0)) {
                        case 'V':
                            mv.visitFieldInsn(GETSTATIC, "java/lang/Void", "TYPE", "Ljava/lang/Class;");
                            break;
                        case 'Z':
                            mv.visitFieldInsn(GETSTATIC, "java/lang/Boolean", "TYPE", "Ljava/lang/Class;");
                            break;
                        case 'B':
                            mv.visitFieldInsn(GETSTATIC, "java/lang/Byte", "TYPE", "Ljava/lang/Class;");
                            break;
                        case 'S':
                            mv.visitFieldInsn(GETSTATIC, "java/lang/Short", "TYPE", "Ljava/lang/Class;");
                            break;
                        case 'C':
                            mv.visitFieldInsn(GETSTATIC, "java/lang/Character", "TYPE", "Ljava/lang/Class;");
                            break;
                        case 'I':
                            mv.visitFieldInsn(GETSTATIC, "java/lang/Integer", "TYPE", "Ljava/lang/Class;");
                            break;
                        case 'J':
                            mv.visitFieldInsn(GETSTATIC, "java/lang/Long", "TYPE", "Ljava/lang/Class;");
                            break;
                        case 'F':
                            mv.visitFieldInsn(GETSTATIC, "java/lang/Float", "TYPE", "Ljava/lang/Class;");
                            break;
                        case 'D':
                            mv.visitFieldInsn(GETSTATIC, "java/lang/Double", "TYPE", "Ljava/lang/Class;");
                            break;
                    }
                } else {
                    mv.visitLdcInsn(v);
                }
                boxIfNeeded(mv, type);
                mv.visitFieldInsn(PUTFIELD, implName, fieldName, "Ljava/lang/Object;");
            } else {
                // Must be class, enum, array type or annotation. Fall back to super.getDefaultValue(<memberName>).
                mv.visitVarInsn(ALOAD, 0);
                mv.visitInsn(DUP);
                mv.visitLdcInsn(method.getName());
                mv.visitMethodInsn(INVOKESPECIAL, BASE_CLASS, "getDefaultValue", "(Ljava/lang/String;)Ljava/lang/Object;");
                mv.visitFieldInsn(PUTFIELD, implName, fieldName, "Ljava/lang/Object;");
            }
        }
    }
    mv.visitInsn(RETURN);
    mv.visitMaxs(0, 0);
    mv.visitEnd();
}
Also used : Type(org.objectweb.asm.Type) PrimType(soot.PrimType) AnnotationDefaultTag(soot.tagkit.AnnotationDefaultTag) SootMethod(soot.SootMethod) PrimType(soot.PrimType) SootClass(soot.SootClass) MethodVisitor(org.objectweb.asm.MethodVisitor)

Aggregations

SootClass (soot.SootClass)2 SootMethod (soot.SootMethod)2 AnnotationDefaultTag (soot.tagkit.AnnotationDefaultTag)2 ArrayList (java.util.ArrayList)1 MethodVisitor (org.objectweb.asm.MethodVisitor)1 Type (org.objectweb.asm.Type)1 ArrayConstant (org.robovm.compiler.llvm.ArrayConstant)1 ArrayType (org.robovm.compiler.llvm.ArrayType)1 IntegerConstant (org.robovm.compiler.llvm.IntegerConstant)1 PackedStructureConstant (org.robovm.compiler.llvm.PackedStructureConstant)1 PackedStructureType (org.robovm.compiler.llvm.PackedStructureType)1 StructureConstant (org.robovm.compiler.llvm.StructureConstant)1 Type (org.robovm.compiler.llvm.Type)1 Value (org.robovm.compiler.llvm.Value)1 PrimType (soot.PrimType)1 AnnotationTag (soot.tagkit.AnnotationTag)1 EnclosingMethodTag (soot.tagkit.EnclosingMethodTag)1 InnerClassTag (soot.tagkit.InnerClassTag)1 SignatureTag (soot.tagkit.SignatureTag)1 SourceFileTag (soot.tagkit.SourceFileTag)1