Beispiel #1
0
 /// <summary>
 /// Get's the namespace of the given type after conversion.
 /// </summary>
 public string GetConvertedNamespace(XTypeDefinition type)
 {
     if (type.IsNested)
     {
         return GetConvertedNamespace(type.DeclaringType);
     }
     var ns = type.Namespace;
     return ConvertNamespace(ns);
 }
Beispiel #2
0
 /// <summary>
 /// Create the current type as class definition.
 /// </summary>
 protected override void CreateClassDefinition(DexTargetPackage targetPackage, ClassDefinition parent, TypeDefinition parentType, XTypeDefinition parentXType)
 {
     base.CreateClassDefinition(targetPackage, parent, parentType, parentXType);
     Class.AccessFlags &= ~AccessFlags.Final;
     Class.IsAbstract = true;
     //Class.IsInterface = true;
     // Record in compiler
     Compiler.Record(new DelegateType(Compiler, XType, Class, targetPackage.DexFile, targetPackage.NameConverter));
 }
Beispiel #3
0
        /// <summary>
        /// Default ctor
        /// </summary>
        public DelegateType(AssemblyCompiler compiler, XTypeDefinition delegateType, ClassDefinition interfaceClass, Dex target, NameConverter nsConverter)
        {
            this.compiler = compiler;
            this.delegateType = delegateType;
            this.interfaceClass = interfaceClass;

            // Build invoke prototype
            invokeMethod = delegateType.Methods.First(x => x.EqualsName("Invoke"));
        }
Beispiel #4
0
 /// <summary>
 /// Is the given type a struct?
 /// </summary>
 public static bool IsStruct(this XTypeReference type, out XTypeDefinition typeDef)
 {
     typeDef = null;
     if (type == null)
     {
         return(false);
     }
     return(type.TryResolve(out typeDef) && typeDef.IsStruct);
 }
Beispiel #5
0
 /// <summary>
 /// .NET ctor
 /// </summary>
 public DecompilerContext(XMethodDefinition currentMethod)
 {
     if (currentMethod == null)
         throw new ArgumentNullException("currentMethod");
     name = currentMethod.Name;
     declaringTypeName = currentMethod.DeclaringType.Name;
     declaringType = currentMethod.DeclaringType;
     returnType = currentMethod.ReturnType;
     currentModule = currentMethod.Module;
 }
Beispiel #6
0
 /// <summary>
 /// Default ctor
 /// </summary>
 public AstBuilder(XModule module, MethodDefinition methodDef, XTypeDefinition declaringType, bool optimize)
 {
     this.module = module;
     typeSystem = module.TypeSystem;
     this.methodDef = methodDef;
     this.declaringType = declaringType;
     this.optimize = optimize;
     codeAttr = methodDef.Attributes.OfType<CodeAttribute>().FirstOrDefault();
     validExceptionHandlers = (codeAttr != null) ? codeAttr.ExceptionHandlers.Where(IsValid).ToList() : null;
 }
Beispiel #7
0
 /// <summary>
 /// Is the given type an enum?
 /// </summary>
 public static bool IsEnum(this XTypeReference type, out XTypeDefinition typeDef)
 {
     typeDef = null;
     if (type == null)
     {
         return(false);
     }
     type = type.GetWithoutModifiers();
     return(type.TryResolve(out typeDef) && typeDef.IsEnum);
 }
        public override void Create(ClassDefinition declaringClass, XTypeDefinition declaringType, DexTargetPackage targetPackage)
        {
            if (_baseFieldBuilder.dfield == null)
                return;

            // can't create udater for static fields.
            if (field.IsStatic)
                return;

            var updaterType = GetAtomicFieldUpdaterType(field.FieldType);
            if (updaterType == null)
                return;

            var fullUpdateTypeName = "Java.Util.Concurrent.Atomic." + updaterType;

            // create matching xField. Note: this seems to be a hack. what to do?

            var objType = new ObjectTypeReference(fullUpdateTypeName, new TypeArgument[0]);
            var javaTypeReference = new XBuilder.JavaTypeReference(Compiler.Module, objType, objType.ClassName);

            var basexField = _baseFieldBuilder.xField;
            var basedField = _baseFieldBuilder.dfield;
            var fieldName = basedField.Name + NameConstants.Atomic.FieldUpdaterPostfix;

            var xflags = XSyntheticFieldFlags.Static | XSyntheticFieldFlags.ReadOnly;

            if (basedField.IsProtected)
                xflags |= XSyntheticFieldFlags.Protected;
            if (basedField.IsPrivate)
                xflags |= XSyntheticFieldFlags.Private;


            var xAtomicField = XSyntheticFieldDefinition.Create(basexField.DeclaringType, xflags, fieldName, javaTypeReference);
            xField = xAtomicField;

            // create dfield.
            
            dfield = new DexLib.FieldDefinition
            {
                Name = fieldName,
                IsStatic = true,
                IsFinal = true,
                IsSynthetic = true,
                // same access as the original field.
                IsPublic = basedField.IsPublic,
                IsPrivate = basedField.IsPrivate,
                IsProtected = basedField.IsProtected,
            };
            
            AddFieldToDeclaringClass(declaringClass, dfield, targetPackage);

            targetPackage.NameConverter.Record(xField, dfield);
        }
Beispiel #9
0
        /// <summary>
        /// Gets the type with the given namespace and name.
        /// </summary>
        public bool TryGetType(string fullName, out XTypeDefinition type)
        {
            FullNameCacheEntry e;

            if (fullNameCache.TryGetValue(fullName, out e))
            {
                type = e.Type;
                return(true);
            }

            type = null;
            return(false);
        }
Beispiel #10
0
        /// <summary>
        /// Create the current type as class definition.
        /// </summary>
        public virtual void Create(ClassDefinition declaringClass, XTypeDefinition declaringType, DexTargetPackage targetPackage)
        {
            // Find xfield
            xField = XBuilder.AsFieldDefinition(compiler.Module, field);

            // Create field definition
            dfield = new Dot42.DexLib.FieldDefinition();
            dfield.Name = NameConverter.GetConvertedName(field);
            AddFieldToDeclaringClass(declaringClass, dfield, targetPackage);
            targetPackage.NameConverter.Record(xField, dfield);

            // Set access flags
            SetAccessFlags(dfield, field);

            // Give warning if static in generic class.
            // This could of cause also be handled automagically be the compiler,
            // with mixture of whats done in the Interlocked converter and whats
            // done in the GenericInstanceConverter.
            if (field.IsStatic && declaringType.IsGenericClass)
            {
                if (!field.HasSuppressMessageAttribute("StaticFieldInGenericType")
                 && !field.DeclaringType.HasSuppressMessageAttribute("StaticFieldInGenericType"))
                {
                    string msg;
                    if (field.Name.Contains("CachedAnonymousMethodDelegate"))
                        msg = "The compiler generated a static field '{0}' in generic type '{1}'. This is not supported " +
                              "in Dot42 if the anonymous delegate accesses a generic class parameter. A workaround " +
                              "is to convert the anonymous static delegate to a normal method.\n";
                    else
                        msg = "Static field '{0}' in generic type {1}: All generic instances will share " +
                              "the same static field, contrary on how CLR operates. A workaround is to " +
                              "use ConcurrentDictionaries to access the values dependent on the type.\n";
                    
                    msg += "You can suppress this warning with a [SuppressMessage(\"dot42\"," +
                           " \"StaticFieldInGenericType\")] attribute, either on the field or on the class.";

                    var body = field.DeclaringType.Methods.Select(m => m.Body)
                                                          .FirstOrDefault(m => m != null 
                                                                            && m.Instructions.Any(i => i.SequencePoint != null));
                    if (body != null)
                    {
                        var seqPoint = body.Instructions.Select(i=>i.SequencePoint).First(i => i != null);
                        DLog.Warning(DContext.CompilerILConverter, seqPoint.Document.Url, seqPoint.StartColumn, seqPoint.StartLine, msg, field.Name, declaringType.FullName);
                    }
                    else
                    {
                        DLog.Warning(DContext.CompilerILConverter, msg, field.Name, declaringType.FullName);
                    }
                }
            }
        }
        protected override XTypeDefinition CreateXType(XTypeDefinition parentXType)
        {
            var typeDef = (XBuilder.ILTypeDefinition)XBuilder.AsTypeReference(Compiler.Module, Type)
                                                             .Resolve();

            string name = NameConverter.GetNullableClassName(typeDef.Name);

            XSyntheticTypeFlags xflags = default(XSyntheticTypeFlags);

            return XSyntheticTypeDefinition.Create(Compiler.Module, parentXType, xflags,
                                                   typeDef.Namespace, name,
                                                  Compiler.Module.TypeSystem.Object,
                                                  string.Join(":", Type.Scope.Name, Type.MetadataToken.ToScopeId(), "Nullable"));
        }
        protected override void CreateClassDefinition(DexTargetPackage targetPackage, ClassDefinition parent,
            TypeDefinition parentType,
            XTypeDefinition parentXType)
        {
            base.CreateClassDefinition(targetPackage, parent, parentType, parentXType);

            if (IsDot42InternalApplication())
            {
                // FixUp Visiblility.
                Class.IsPublic = true;
                Class.IsProtected = false;
                Class.IsPrivate = false;
            }
        }
Beispiel #13
0
        /// <summary>
        /// Create the current type as class definition.
        /// </summary>
        public void Create(ClassDefinition declaringClass, XTypeDefinition declaringType, DexTargetPackage targetPackage)
        {
            // Find xfield
            xField = XBuilder.AsFieldDefinition(compiler.Module, field);

            // Create field definition
            dfield = new Dot42.DexLib.FieldDefinition();
            dfield.Name = NameConverter.GetConvertedName(field);
            AddFieldToDeclaringClass(declaringClass, dfield, targetPackage);
            targetPackage.NameConverter.Record(xField, dfield);

            // Set access flags
            SetAccessFlags(dfield, field);
        }
Beispiel #14
0
        private XMethodDefinition FindMethod(XTypeDefinition delegateType, string methodName)
        {
            while (true)
            {
                var ret = delegateType.Methods.FirstOrDefault(x => x.EqualsName(methodName));
                if (ret != null)
                    return ret;

                var baseType = delegateType.BaseType;
                if (baseType == null)
                    return null;

                delegateType = baseType.Resolve();
            }
        }
Beispiel #15
0
 /// <summary>
 /// Resolve this reference to it's definition.
 /// </summary>
 public virtual bool TryResolve(out XTypeDefinition type)
 {
     if (resolvedType != null)
     {
         type = resolvedType;
         return(true);
     }
     if (!Module.TryGetType(FullName, out type))
     {
         return(false);
     }
     // Cache for later
     resolvedType = type;
     type.AddFlushAction(() => resolvedType = null);
     return(true);
 }
Beispiel #16
0
 /// <summary>
 /// Try to get a type definition (me or one of my nested typed) by the given full name.
 /// </summary>
 public virtual bool TryGet(string fullName, bool noImports, out XTypeDefinition type)
 {
     if (FullName == fullName)
     {
         type = this;
         return(true);
     }
     foreach (var nested in NestedTypes)
     {
         if (nested.TryGet(fullName, noImports, out type))
         {
             return(true);
         }
     }
     type = null;
     return(false);
 }
Beispiel #17
0
        /// <summary>
        /// Default ctor
        /// </summary>
        public DelegateType(AssemblyCompiler compiler, XTypeDefinition delegateType, ClassDefinition interfaceClass, Dex target, NameConverter nsConverter)
        {
            this.compiler = compiler;
            this.delegateType = delegateType;
            this.interfaceClass = interfaceClass;

            // Build invoke prototype
            invokeMethod = delegateType.Methods.First(x => x.EqualsName("Invoke"));
            XTypeDefinition baseType = delegateType;
            while ((null != baseType) && !baseType.Methods.Any(x => x.EqualsName("Equals")))
            {
                baseType = baseType.BaseType as XTypeDefinition;
            }
            if (null != baseType)
            {
                equalsMethod = baseType.Methods.First(x => x.EqualsName("Equals"));
            }
        }
Beispiel #18
0
        /// <summary>
        /// Add the given type to my list.
        /// </summary>
        internal void Register(XTypeDefinition type, string overrideFullName = null)
        {
            Register(type, overrideFullName, false);

            string className;

            if (type.TryGetDexImportNames(out className))
            {
                var typeRef = Java.XBuilder.AsTypeReference(this, className, XTypeUsageFlags.DeclaringType);
                Register(type, typeRef.FullName, true);
            }

            if (type.TryGetJavaImportNames(out className))
            {
                var typeRef = Java.XBuilder.AsTypeReference(this, className, XTypeUsageFlags.DeclaringType);
                Register(type, typeRef.FullName, true);
            }
        }
Beispiel #19
0
 /// <summary>
 /// Does the given type extend from System.MulticastDelegate?
 /// </summary>
 public static bool IsDelegate(this XTypeDefinition type)
 {
     while (true)
     {
         var baseType = type.BaseType;
         if (baseType == null)
         {
             break;
         }
         if (!baseType.TryResolve(out type))
         {
             break;
         }
         if (type.FullName == typeof(System.MulticastDelegate).FullName)
         {
             return(true);
         }
     }
     return(false);
 }
Beispiel #20
0
 /// <summary>
 /// Is the given type a base class of the given child?
 /// </summary>
 public static bool IsBaseOf(this XTypeDefinition type, XTypeDefinition child)
 {
     while (child != null)
     {
         if (child.BaseType == null)
         {
             return(false);
         }
         XTypeDefinition baseType;
         if (!child.BaseType.TryResolve(out baseType))
         {
             return(false);
         }
         if (baseType.IsSame(type))
         {
             return(true);
         }
         child = baseType;
     }
     return(false);
 }
Beispiel #21
0
        private void Register(XTypeDefinition type, string overridenName, bool isImport)
        {
            // scopeId must be unique
            if (scopeIdCache.ContainsKey(type.ScopeId) && scopeIdCache[type.ScopeId] != type)
            {
                if (type is XBuilder.JavaTypeDefinition)
                {
                    // FixMe. Java TypeDefinitions get created multiple times.
                    //Debugger.Break();
                }
                else
                {
                    throw new Exception("scopeId not unique for " + type.ScopeId);
                }
            }

            scopeIdCache[type.ScopeId] = type;

            var fullname = overridenName ?? type.FullName;

            FullNameCacheEntry e;

            if (fullNameCache.TryGetValue(fullname, out e))
            {
                if (e.Priority < type.Priority)
                {
                    return;
                }
                // new priority is higher or equal,
                // but we must not override a non-import type.
                if (isImport && !e.IsImport)
                {
                    return;
                }
            }

            fullNameCache[fullname] = new FullNameCacheEntry(type, type.Priority, isImport);
        }
Beispiel #22
0
        /// <summary>
        /// Gets the type with the given namespace and name.
        /// </summary>
        public bool TryGetType(string fullName, out XTypeDefinition type)
        {
            if (fullNameCache.TryGetValue(fullName, out type))
            {
                return(true);
            }

            for (var attempt = 0; attempt < 2; attempt++)
            {
                var noImports = (attempt == 0);
                sortedTypes = sortedTypes ?? types.OrderBy(x => x.Priority).ToList();
                foreach (var t in sortedTypes)
                {
                    if (t.TryGet(fullName, noImports, out type))
                    {
                        fullNameCache[fullName] = type;
                        return(true);
                    }
                }
            }

            type = null;
            return(false);
        }
Beispiel #23
0
 /// <summary>
 /// Create the classname for the Nullable base class for the given type.
 /// </summary>
 public static string GetNullableBaseClassName(XTypeDefinition type)
 {
     return type.Name + "__Nullable";
 }
Beispiel #24
0
 /// <summary>
 /// Resolve this reference to it's definition.
 /// </summary>
 public override bool TryResolve(out XTypeDefinition type)
 {
     type = null;
     return(false);
 }
Beispiel #25
0
 /// <summary>
 /// Create the classname for the Nullable base class for the given type.
 /// </summary>
 public static string GetNullableClassName(XTypeDefinition type)
 {
     return GetNullableClassName(type.Name);
 }
Beispiel #26
0
 public FullNameCacheEntry(XTypeDefinition type, int priority, bool isImport)
 {
     Type     = type;
     Priority = priority;
     IsImport = isImport;
 }
Beispiel #27
0
 /// <summary>
 /// Default ctor
 /// </summary>
 protected XTypeDefinition(XModule module, XTypeDefinition declaringType, bool isValueType, IEnumerable<string> genericParameterNames)
     : base(module, declaringType, isValueType, genericParameterNames)
 {
 }
 /// <summary>
 /// Create the current type as class definition.
 /// </summary>
 protected override void CreateClassDefinition(DexTargetPackage targetPackage, ClassDefinition parent, TypeDefinition parentType, XTypeDefinition parentXType)
 {
     base.CreateClassDefinition(targetPackage, parent, parentType, parentXType);
     XType.SetDexClass(Class, targetPackage);
 }
Beispiel #29
0
 /// <summary>
 /// Gets the default constructor of the given value type.
 /// Throws an exception if not found.
 /// </summary>
 internal static XMethodDefinition GetDefaultValueCtor(XTypeDefinition valueType)
 {
     var defaultCtor = valueType.Methods.FirstOrDefault(x => x.IsConstructor && !x.IsStatic && (x.Parameters.Count == 0));
     if (defaultCtor == null)
         throw new NotImplementedException(string.Format("Value type {0} has no default ctor", valueType.FullName));
     return defaultCtor;
 }
 /// <summary>
 /// Resolve this reference to it's definition.
 /// </summary>
 public override bool TryResolve(out XTypeDefinition type)
 {
     return ElementType.TryResolve(out type);
 }
Beispiel #31
0
 /// <summary>
 /// Convert an argument or a numeric operation to int/long.
 /// </summary>
 private static void ConvertNumericOpArgument(AstExpression node, int argumentIndex, XTypeDefinition enumType, bool isWide, XTypeReference enumNumericType)
 {
     var module = enumType.Module;
     var argument = node.Arguments[argumentIndex];
     switch (argument.Code)
     {
         case AstCode.Ldc_I4:
             // Keep numeric value
             argument.SetType(module.TypeSystem.Int);
             break;
         case AstCode.Ldc_I8:
             // Keep numeric value
             argument.SetType(module.TypeSystem.Long);
             break;
         default:
             // Convert enum to numeric
             var numericValue = new AstExpression(argument);
             argument.SetCode(isWide ? AstCode.Enum_to_long : AstCode.Enum_to_int)
                     .SetType(enumNumericType)
                     .SetArguments(numericValue);
             break;
     }
 }
Beispiel #32
0
 /// <summary>
 /// Convert the given node that holds a numeric value and convert it to it's enum instance.
 /// </summary>
 private static void ConvertNumericToEnum(AstExpression node, XTypeDefinition enumType, XTypeReference enumNumericType)
 {
     // Call Enum.GetValue(enumType, value)
     var enumValue = new AstExpression(node);
     node.SetCode(enumNumericType.IsWide() ? AstCode.Long_to_enum : AstCode.Int_to_enum).SetArguments(enumValue).SetType(enumType);
     node.Operand = null;
 }
Beispiel #33
0
        /// <summary>
        /// Convert a integer compare operation (bge, bgt, ble, blt) with enum argument.
        /// </summary>
        private static void ConvertICmpArgument(AstExpression node, int argIndex, XTypeDefinition enumType, AssemblyCompiler compiler)
        {
            Debug.Assert(node.Arguments.Count == 2);
            var isWide = enumType.GetEnumUnderlyingType().IsWide();
            var module = compiler.Module;
            var retType = isWide ? module.TypeSystem.Long : module.TypeSystem.Int;

            // Convert arguments
            ConvertNumericOpArgument(node, argIndex, enumType, isWide, retType);
        }
Beispiel #34
0
        /// <summary>
        /// Convert a binary operation (Add, Sub, Mul, Div, Rem, And, Or, Xor) resulting in an enum.
        /// </summary>
        private static void ConvertBinOp(AstExpression node, XTypeDefinition enumType, AssemblyCompiler compiler)
        {
            Debug.Assert(node.Arguments.Count == 2);
            var isWide = enumType.GetEnumUnderlyingType().IsWide();
            var module = compiler.Module;            
            var retType = isWide ? module.TypeSystem.Long : module.TypeSystem.Int;

            // Convert arguments
            ConvertNumericOpArgument(node, 0, enumType, isWide, retType);
            ConvertNumericOpArgument(node, 1, enumType, isWide, retType);

            // Convert return value
            if ((node.ExpectedType == null) || (!node.ExpectedType.IsPrimitive))
            {
                ConvertNumericToEnum(node, enumType, retType);
            }
            else
            {
                node.InferredType = retType;
            }
        }
Beispiel #35
0
 /// <summary>
 /// Add the given type to my list.
 /// </summary>
 private void Add(XTypeDefinition type)
 {
     types.Add(type);
     sortedTypes = null;
 }
Beispiel #36
0
 /// <summary>
 /// Gets a formatted full classname for the given type.
 /// </summary>
 private string FormatClassName(XTypeDefinition typeDef)
 {
     string className;
     if (typeDef.TryGetDexImportNames(out className))
         return FormatImportedClassName(className);
     if (typeDef.TryGetJavaImportNames(out className))
         return FormatImportedClassName(className);
     return nsConverter.GetConvertedFullName(typeDef);
 }
Beispiel #37
0
 /// <summary>
 /// Gets the struct $CopyFrom method of the given value type.
 /// Throws an exception if not found.
 /// </summary>
 private static XMethodDefinition GetCopyFromMethod(XTypeDefinition valueType)
 {
     var method = valueType.Methods.FirstOrDefault(x => !x.IsStatic && (x.Parameters.Count == 1) && (x.Name == NameConstants.Struct.CopyFromMethodName));
     if (method == null)
         throw new NotImplementedException(string.Format("Value type {0} has no struct copyFrom method", valueType.FullName));
     return method;
 }
 /// <summary>
 /// Resolve this reference to it's definition.
 /// </summary>
 public override bool TryResolve(out XTypeDefinition type)
 {
     return(ElementType.TryResolve(out type));
 }
 /// <summary>
 /// Mark is as an annotation
 /// </summary>
 protected override void CreateClassDefinition(DexTargetPackage targetPackage, ClassDefinition parent, TypeDefinition parentType, XTypeDefinition parentXType)
 {
     base.CreateClassDefinition(targetPackage, parent, parentType, parentXType);
     Class.AccessFlags |= AccessFlags.Annotation;
 }
Beispiel #40
0
 /// <summary>
 /// Resolve this reference to it's definition.
 /// </summary>
 public override bool TryResolve(out XTypeDefinition type)
 {
     type = this;
     return true;
 }
 /// <summary>
 /// Create the current type as class definition.
 /// </summary>
 protected override void CreateClassDefinition(DexTargetPackage targetPackage, ClassDefinition parent, TypeDefinition parentType, XTypeDefinition parentXType)
 {
     // Do not create a class.
     // It already exists in the framework.
 }
 /// <summary>
 /// Create the XType for this builder.
 /// </summary>
 protected override XTypeDefinition CreateXType(XTypeDefinition parentXType)
 {
     var baseType = Compiler.GetDot42InternalType("EnumInfo");
     return XSyntheticTypeDefinition.Create(Compiler.Module, parentXType, XSyntheticTypeFlags.Private, null, ClassName, 
                                            baseType, parentXType.ScopeId + ":Info");
 }
Beispiel #43
0
 /// <summary>
 /// Default ctor
 /// </summary>
 protected XMethodDefinition(XTypeDefinition declaringType)
     : base(declaringType)
 {
 }
Beispiel #44
0
        /// <summary>
        /// Get's the full name of the given type after conversion.
        /// </summary>
        public string GetConvertedFullName(XTypeDefinition type)
        {
            if (type.IsNested)
            {
                var declaringTypeName = GetConvertedFullName(type.DeclaringType);
                return declaringTypeName + Dex.NestedClassSeparator + GetConvertedName(type);
            }

            var ns = GetConvertedNamespace(type);
            return ns + '.' + GetConvertedName(type);
        }
Beispiel #45
0
 /// <summary>
 /// Default ctor
 /// </summary>
 protected XTypeDefinition(XModule module, XTypeDefinition declaringType, bool isValueType, IEnumerable <string> genericParameterNames)
     : base(module, declaringType, isValueType, genericParameterNames)
 {
 }
Beispiel #46
0
 /// <summary>
 /// Resolve this reference to it's definition.
 /// </summary>
 public override bool TryResolve(out XTypeDefinition type)
 {
     type = this;
     return(true);
 }
Beispiel #47
0
 /// <summary>
 /// Gets the recorded delegate type for the given .NET delegate type.
 /// </summary>
 internal DelegateType GetDelegateType(XTypeDefinition type)
 {
     DelegateType result;
     if (delegateTypes.TryGetValue(type, out result))
         return result;
     throw new ArgumentException(string.Format("No delegate type found for {0}", type.FullName));
 }