Esempio n. 1
0
 /// <summary>
 /// Add the given field to its declaring class.
 /// </summary>
 protected override void AddFieldToDeclaringClass(ClassDefinition declaringClass, DexLib.FieldDefinition dfield, DexTargetPackage targetPackage)
 {
     var generatedCodeClass = targetPackage.GetOrCreateGeneratedCodeClass();
     UpdateName(dfield, generatedCodeClass);
     dfield.Owner = generatedCodeClass;
     generatedCodeClass.Fields.Add(dfield);
 }
Esempio n. 2
0
        /// <summary>
        /// Add the given method to its declaring class.
        /// </summary>
        protected virtual void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method)
        {
            if (method.IsPrivate)
            {
                if (method.DeclaringType.HasNestedTypes)
                    dmethod.IsProtected = true;
                else
                    dmethod.IsPrivate = true;
            }
            else if (method.IsFamily) dmethod.IsProtected = true;
            else dmethod.IsPublic = true;

            if (method.DeclaringType.IsInterface)
            {
                dmethod.IsAbstract = true;
                //dmethod.
            }
            else
            {
                if (method.IsConstructor) dmethod.IsConstructor = true;
                else if (method.IsAbstract) dmethod.IsAbstract = true;
                else if (method.IsVirtual) dmethod.IsVirtual = true;
                else if (method.IsStatic) dmethod.IsStatic = true;
                else dmethod.IsFinal = true;
                //if (method.IsInitOnly) dmethod.IsFinal = true;
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Add the given method to its declaring class.
        /// </summary>
        protected override void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method)
        {
            dmethod.IsStatic = true;
            dmethod.IsPublic = true;

            
            if (method.IsAbstract || method.IsVirtual)
            {
                // generate a warning, since these methods will never be called 
                // as virtual. Do not generate a warning if we know the compiler
                // will handle the call.

                if (method.DeclaringType.FullName == "System.Array")
                {
                    // all array methods should be redirected by the compiler.
                    return;
                }
                var intfMethod = method.GetBaseInterfaceMethod();
                if (intfMethod != null && intfMethod.DeclaringType.FullName == "System.IFormattable")
                {
                    // this is handled by the compiler.
                    return;
                }

                DLog.Warning(DContext.CompilerCodeGenerator, "Abstract or virtual .NET method '{0}' in DexImport class '{1}'. Unless specially handled by the compiler, this will never be called virtually.", method.Name, method.DeclaringType.FullName);
            }
        }
Esempio n. 4
0
 /// <summary>
 /// Add the given method to its declaring class.
 /// </summary>
 protected override void AddMethodToDeclaringClass(ClassDefinition declaringClass, DexLib.MethodDefinition dmethod, DexTargetPackage targetPackage)
 {
     var generatedCodeClass = targetPackage.GetOrCreateGeneratedCodeClass();
     UpdateName(dmethod, generatedCodeClass);
     dmethod.Owner = generatedCodeClass;
     generatedCodeClass.Methods.Add(dmethod);
 }
Esempio n. 5
0
        /// <summary>
        /// Set the access flags of the created field.
        /// </summary>
        protected virtual void SetAccessFlags(DexLib.FieldDefinition dfield, FieldDefinition field)
        {
            if (field.IsPrivate) dfield.IsPrivate = true;
            if (field.IsProtected) dfield.IsProtected = true;
            if (field.IsPublic) dfield.IsPublic = true;

            if (field.IsFinal) dfield.IsFinal = true;
            if (field.IsStatic) dfield.IsStatic = true;
            if (field.IsTransient) dfield.IsTransient = true;
            if (field.IsVolatile) dfield.IsVolatile = true;
            if (field.IsSynthetic) dfield.IsSynthetic = true;
            if (field.IsEnum) dfield.IsEnum = true;
        }
Esempio n. 6
0
 /// <summary>
 /// Ensure that the name of the field is unique.
 /// </summary>
 private static void UpdateName(DexLib.FieldDefinition field, ClassDefinition declaringClass)
 {
     var baseName = field.Name;
     var name = field.Name;
     var postfix = 0;
     while (true)
     {
         if (declaringClass.Fields.All(x => x.Name != name))
         {
             field.Name = name;
             return;
         }
         name = baseName + ++postfix;
     }
 }
Esempio n. 7
0
        /// <summary>
        /// Set the access flags of the created field.
        /// </summary>
        protected virtual void SetAccessFlags(DexLib.FieldDefinition dfield, FieldDefinition field)
        {
            if (field.IsPrivate)
            {
                if (field.DeclaringType.HasNestedTypes)
                    dfield.IsProtected = true;
                else
                    dfield.IsPrivate = true;
            }
            else if (field.IsFamily) dfield.IsProtected = true;
            else dfield.IsPublic = true;

            if (field.IsInitOnly) dfield.IsFinal = true;
            if (field.IsStatic) dfield.IsStatic = true;
        }
Esempio n. 8
0
 /// <summary>
 /// Ensure that the name of the field is unique.
 /// </summary>
 private static void UpdateName(DexLib.MethodDefinition method, ClassDefinition declaringClass)
 {
     var baseName = method.Name;
     if (baseName == "<init>") baseName = "NetCtor";
     var name = baseName;
     var postfix = 0;
     while (true)
     {
         if (declaringClass.Methods.All(x => x.Name != name))
         {
             method.Name = name;
             return;
         }
         name = baseName + ++postfix;
     }
 }
Esempio n. 9
0
        /// <summary>
        /// Add the given method to its declaring class.
        /// </summary>
        protected virtual void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method)
        {
            if (method.IsPrivate) dmethod.IsPrivate = true;
            if (method.IsProtected) dmethod.IsProtected = true;
            if (method.IsPublic) dmethod.IsPublic = true;

            if (method.DeclaringClass.IsInterface)
            {
                dmethod.IsAbstract = true;
            }
            else
            {
                if (method.IsConstructor) dmethod.IsConstructor = true;
                if (method.IsAbstract) dmethod.IsAbstract = true;
                if (method.IsStatic) dmethod.IsStatic = true;
                if (!method.IsStatic && !method.IsFinal && !method.IsConstructor && !method.IsPrivate) dmethod.IsVirtual = true;
                if (method.IsFinal || method.IsPrivate) dmethod.IsFinal = true;
            }
        }
Esempio n. 10
0
        /// <summary>
        /// Create a method body for the given method.
        /// </summary>
        internal static MethodBody TranslateToRL(AssemblyCompiler compiler, DexTargetPackage targetPackage, MethodSource source, DexLib.MethodDefinition dmethod, out CompiledMethod compiledMethod)
        {
            try
            {
#if DEBUG
                //Debugger.Launch();
                if ((source.Method != null) && (source.Method.Name == "test6"))
                {
                    //Debugger.Launch();
                }
#endif

                // Create Ast
                var optimizedAst = CreateOptimizedAst(compiler, source);

                // Generate RL code
                var rlBody = new MethodBody(source);
                var rlGenerator = new AstCompilerVisitor(compiler, source, targetPackage, dmethod, rlBody);
                optimizedAst.Accept(rlGenerator, null);

                // Should we add return_void?
                if (source.ReturnsVoid)
                {
                    var instructions = rlBody.Instructions;
                    if ((instructions.Count == 0) || (instructions.Last().Code != RCode.Return_void))
                    {
                        instructions.Add(new RL.Instruction(RCode.Return_void) { SequencePoint = source.GetLastSourceLine() });
                    }
                }

                // Record results
                compiledMethod = targetPackage.Record(source, rlBody, rlGenerator.Frame);

                return rlBody;
            }
            catch (Exception ex)
            {
                // Forward exception with more information
                var msg = string.Format("Error while compiling {0} in {1}: {2}", source.FullName, source.DeclaringTypeFullName, ex.Message);
                throw new CompilerException(msg, ex);
            }
        }
Esempio n. 11
0
 /// <summary>
 /// Set the value of the given dex field.
 /// </summary>
 protected virtual void SetFieldValue(DexLib.FieldDefinition dfield, FieldDefinition field)
 {
     var constant = field.Constant;
     if (constant != null)
     {
         var fieldType = field.FieldType;
         if (fieldType.IsByte())
         {
             constant = XConvert.ToByte(constant);
         }
         else if (fieldType.IsUInt16())
         {
             constant = XConvert.ToShort(constant);
         }
         else if (fieldType.IsUInt32())
         {
             constant = XConvert.ToInt(constant);
         }
         else if (fieldType.IsUInt64())
         {
             constant = XConvert.ToLong(constant);
         }
     }
     dfield.Value = constant;
 }
Esempio n. 12
0
 /// <summary>
 /// Generate method code
 /// </summary>
 public override void GenerateCode(DexLib.ClassDefinition declaringClass, DexTargetPackage targetPackage)
 {
     // Do nothing
 }
Esempio n. 13
0
 /// <summary>
 /// Add the given method to its declaring class.
 /// </summary>
 protected override void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method)
 {
     base.SetAccessFlags(dmethod, method);
     dmethod.IsNative = true;
 }
Esempio n. 14
0
 /// <summary>
 /// Set relation to dex class.
 /// </summary>
 internal void SetDexClass(DexLib.ClassDefinition @class, DexTargetPackage targetPackage)
 {
     if (@class == null)
         throw new ArgumentNullException("@class");
     if (dexType != null)
         throw new InvalidOperationException("Cannot set dex class twice");
     dexType = @class;
 }
Esempio n. 15
0
 /// <summary>
 /// Set the value of the given dex field.
 /// </summary>
 protected virtual void SetFieldValue(DexLib.FieldDefinition dfield, FieldDefinition field)
 {
     dfield.Value = field.ConstantValue;
 }
Esempio n. 16
0
 /// <summary>
 /// Create a dex field definition from this field.
 /// </summary>
 public DexLib.FieldDefinition GetDexField(DexLib.ClassDefinition owner, DexTargetPackage targetPackage)
 {
     if (dexField == null)
     {
         var fdef = new DexLib.FieldDefinition(owner, name, fieldType.GetReference(targetPackage));
         if (IsStatic) fdef.IsStatic = true;
         if (IsPrivate) fdef.IsPrivate = true;
         else if (IsProtected) fdef.IsProtected = true;
         else fdef.IsPublic = true;
         if (IsReadOnly) fdef.IsFinal = true;
         dexField = fdef;
         targetPackage.NameConverter.Record(this, dexField);
     }
     return dexField;
 }
Esempio n. 17
0
 /// <summary>
 /// Gets the type of the value in the given register.
 /// </summary>
 public RType GetType(DexLib.Instructions.Register register)
 {
     return dRegisterTypes[register];
 }
Esempio n. 18
0
 /// <summary>
 /// Set the value of the given dex field.
 /// </summary>
 protected override void SetFieldValue(DexLib.FieldDefinition dfield, FieldDefinition field)
 {
     // Do nothing
 }
Esempio n. 19
0
        /// <summary>
        /// Add the given method to its declaring class.
        /// </summary>
        protected virtual void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method)
        {
            // subclass accesses have already been fixed on an actual use basis.
            if (method.IsPrivate)
                dmethod.IsPrivate = true;
            else if (method.IsFamily || method.IsFamilyOrAssembly) 
                dmethod.IsProtected = true;
            else
                dmethod.IsPublic = true;

            if (method.DeclaringType.IsInterface)
            {
                dmethod.IsAbstract = true;
                //dmethod.
            }
            else
            {
                if (method.IsConstructor)
                {
                    dmethod.IsConstructor = true;
                    dmethod.IsStatic = method.IsStatic;
                    if (method.IsStatic)
                    {
                        // reset access modifiers for static constructors.
                        dmethod.IsPrivate = false;
                        dmethod.IsProtected = false;
                    }
                }
                else if (method.IsAbstract) dmethod.IsAbstract = true;
                else if (method.IsVirtual) dmethod.IsVirtual = true;
                else if (method.IsStatic) dmethod.IsStatic = true;
                else dmethod.IsFinal = true;
                //if (method.IsInitOnly) dmethod.IsFinal = true;
            }

            if (method.IsCompilerGenerated())
                dmethod.IsSynthetic = true;
        }
Esempio n. 20
0
 /// <summary>
 /// Record the given field mapping
 /// </summary>
 internal void Record(XFieldDefinition xField, DexLib.FieldDefinition dField)
 {
     xFieldMap.Add(xField, dField);
 }
Esempio n. 21
0
 /// <summary>
 /// Add the given method to its declaring class.
 /// </summary>
 protected override void SetAccessFlags(DexLib.MethodDefinition dmethod, MethodDefinition method)
 {
     dmethod.IsStatic = true;
     dmethod.IsPublic = true;
 }
Esempio n. 22
0
 /// <summary>
 /// Set the field type of the given dex field.
 /// </summary>
 protected virtual void SetFieldType(DexLib.FieldDefinition dfield, FieldDefinition field, DexTargetPackage targetPackage)
 {
     dfield.Type = field.FieldType.GetReference(targetPackage, compiler.Module);            
 }
Esempio n. 23
0
        /// <summary>
        /// Set the access flags of the created field.
        /// </summary>
        protected virtual void SetAccessFlags(DexLib.FieldDefinition dfield, FieldDefinition field)
        {
            // subclass accesses have already been fixed on an actual use basis.
            if (field.IsPrivate)
                dfield.IsPrivate = true;
            else if (field.IsFamily || field.IsFamilyOrAssembly) 
                dfield.IsProtected = true;
            else
                dfield.IsPublic = true;

            if (field.IsInitOnly) dfield.IsFinal = true;
            if (field.IsStatic) dfield.IsStatic = true;

            if (field.IsCompilerGenerated())
                dfield.IsSynthetic = true;

            dfield.IsVolatile = field.IsUsedInInterlocked || IsVolatile(field); ;
        }
Esempio n. 24
0
 /// <summary>
 /// Add the given method to its declaring class.
 /// </summary>
 protected virtual void AddFieldToDeclaringClass(ClassDefinition declaringClass, DexLib.FieldDefinition dmethod, DexTargetPackage targetPackage)
 {
     dmethod.Owner = declaringClass;
     declaringClass.Fields.Add(dmethod);
 }
Esempio n. 25
0
 /// <summary>
 /// Set the access flags of the created field.
 /// </summary>
 protected override void SetAccessFlags(DexLib.FieldDefinition dfield, FieldDefinition field)
 {
     base.SetAccessFlags(dfield, field);
     dfield.IsFinal = true;
 }
Esempio n. 26
0
 /// <summary>
 /// Set the field type of the given dex field.
 /// </summary>
 protected override void SetFieldType(DexLib.FieldDefinition dfield, FieldDefinition field, DexTargetPackage targetPackage)
 {
     dfield.Type = dfield.Owner;
 }
Esempio n. 27
0
 /// <summary>
 /// Record the given method mapping
 /// </summary>
 internal void Record(XMethodDefinition xMethod, DexLib.MethodDefinition dMethod)
 {
     xMethodMap.Add(xMethod, dMethod);
 }
Esempio n. 28
0
        public static MethodEntry RecordMapping(TypeEntry typeEntry, XMethodDefinition xMethod, MethodDefinition method, DexLib.MethodDefinition dmethod, CompiledMethod compiledMethod)
        {
            var scopeId = xMethod.ScopeId;

            StringBuilder netSignature = new StringBuilder();
            method.MethodSignatureFullName(netSignature);

            var entry = new MethodEntry(method.OriginalName, netSignature.ToString(), dmethod.Name, dmethod.Prototype.ToSignature(), dmethod.MapFileId,
                                        scopeId);

            typeEntry.Methods.Add(entry);

            if (compiledMethod != null)
            {
                compiledMethod.RecordMapping(entry);
            }

            return entry;
        }