예제 #1
0
        private MosaType LoadGenericParam(GenericSig sig)
        {
            //Debug.Assert(false, sig.FullName);
            MosaType[] pars = sig.IsTypeVar ? var : mvar;
            MosaType   type = pars[sig.Number];

            if (type == null)
            {
                type = metadata.Controller.CreateType();
                using (var genericParam = metadata.Controller.MutateType(type))
                {
                    genericParam.Module               = metadata.TypeSystem.LinkerModule;
                    genericParam.Namespace            = "";
                    genericParam.Name                 = (sig.IsTypeVar ? "!" : "!!") + sig.Number;
                    genericParam.TypeCode             = (MosaTypeCode)sig.ElementType;
                    genericParam.GenericParamIndex    = (int)sig.Number;
                    genericParam.HasOpenGenericParams = true;
                    genericParam.UnderlyingObject     = new UnitDesc <TypeDef, TypeSig>(null, null, sig);
                }
                pars[sig.Number] = type;
                metadata.Controller.AddType(type);
            }

            return(type);
        }
예제 #2
0
        /// <summary>
        /// Gets a generic signature color
        /// </summary>
        /// <param name="genericSig">Generic signature</param>
        /// <returns></returns>
        public virtual object GetColor(GenericSig genericSig)
        {
            if (genericSig == null)
            {
                return(BoxedTextColor.Text);
            }

            return(genericSig.IsMethodVar ? BoxedTextColor.MethodGenericParameter : BoxedTextColor.TypeGenericParameter);
        }
예제 #3
0
        public static TextTokenKind GetTextTokenType(GenericSig sig)
        {
            if (sig == null)
            {
                return(TextTokenKind.Text);
            }

            return(sig.IsMethodVar ? TextTokenKind.MethodGenericParameter : TextTokenKind.TypeGenericParameter);
        }
예제 #4
0
        internal GenericSig GetGeneric(TypeSig t)
        {
            Debug.Assert(t != null, $"{nameof(t)} != null");

            t = SignatureUtils.GetLeaf(t);

            GenericSig result = null;

            if (Generics.TryGetValue(t, out var gp))
            {
                result = this is ScannedType ? (GenericSig) new GenericVar(gp.Number) : new GenericMVar(gp.Number);
            }

            return(result);
        }
예제 #5
0
 internal static int GetGenericSigToken(GenericSig field)
 {
     return(Writer.Module == field.Module ? Writer.Metadata.GetToken(field).ToInt32() : field.MDToken.ToInt32());
 }
예제 #6
0
        static void AppendTypeName(StringBuilder b, TypeSig type)
        {
            if (type == null)
            {
                // could happen when a TypeSpecification has no ElementType; e.g. function pointers in C++/CLI assemblies
                return;
            }
            if (type is GenericInstSig)
            {
                GenericInstSig giType = (GenericInstSig)type;
                AppendTypeNameWithArguments(b, giType.GenericType == null ? null : giType.GenericType.TypeDefOrRef, giType.GenericArguments);
                return;
            }
            ArraySigBase arrayType = type as ArraySigBase;

            if (arrayType != null)
            {
                AppendTypeName(b, arrayType.Next);
                b.Append('[');
                var lowerBounds = arrayType.GetLowerBounds();
                var sizes       = arrayType.GetSizes();
                for (int i = 0; i < arrayType.Rank; i++)
                {
                    if (i > 0)
                    {
                        b.Append(',');
                    }
                    if (i < lowerBounds.Count && i < sizes.Count)
                    {
                        b.Append(lowerBounds[i]);
                        b.Append(':');
                        b.Append(sizes[i] + lowerBounds[i] - 1);
                    }
                }
                b.Append(']');
                return;
            }
            ByRefSig refType = type as ByRefSig;

            if (refType != null)
            {
                AppendTypeName(b, refType.Next);
                b.Append('@');
                return;
            }
            PtrSig ptrType = type as PtrSig;

            if (ptrType != null)
            {
                AppendTypeName(b, ptrType.Next);
                b.Append('*');
                return;
            }
            GenericSig gp = type as GenericSig;

            if (gp != null)
            {
                b.Append('`');
                if (gp.IsMethodVar)
                {
                    b.Append('`');
                }
                b.Append(gp.Number);
            }
            else
            {
                var typeRef = type.ToTypeDefOrRef();
                if (typeRef.DeclaringType != null)
                {
                    AppendTypeName(b, typeRef.DeclaringType.ToTypeSig());
                    b.Append('.');
                    b.Append(typeRef.Name);
                }
                else
                {
                    b.Append(type.FullName);
                }
            }
        }
예제 #7
0
        static void AppendTypeName(StringBuilder b, TypeSig type)
        {
            if (type == null)
            {
                return;
            }
            if (type is GenericInstSig)
            {
                GenericInstSig giType = (GenericInstSig)type;
                AppendTypeNameWithArguments(b, giType.GenericType == null ? null : giType.GenericType.TypeDefOrRef, giType.GenericArguments);
                return;
            }
            ArraySigBase arrayType = type as ArraySigBase;

            if (arrayType != null)
            {
                AppendTypeName(b, arrayType.Next);
                b.Append('[');
                var lowerBounds = arrayType.GetLowerBounds();
                var sizes       = arrayType.GetSizes();
                for (int i = 0; i < arrayType.Rank; i++)
                {
                    if (i > 0)
                    {
                        b.Append(',');
                    }
                    if (i < lowerBounds.Count && i < sizes.Count)
                    {
                        b.Append(lowerBounds[i]);
                        b.Append(':');
                        b.Append(sizes[i] + lowerBounds[i] - 1);
                    }
                }
                b.Append(']');
                return;
            }
            ByRefSig refType = type as ByRefSig;

            if (refType != null)
            {
                AppendTypeName(b, refType.Next);
                b.Append('@');
                return;
            }
            PtrSig ptrType = type as PtrSig;

            if (ptrType != null)
            {
                AppendTypeName(b, ptrType.Next);
                b.Append('*');
                return;
            }
            GenericSig gp = type as GenericSig;

            if (gp != null)
            {
                b.Append('`');
                if (gp.IsMethodVar)
                {
                    b.Append('`');
                }
                b.Append(gp.Number);
            }
            else
            {
                var typeRef = type.ToTypeDefOrRef();
                if (typeRef.DeclaringType != null)
                {
                    AppendTypeName(b, typeRef.DeclaringType.ToTypeSig());
                    b.Append('.');
                    b.Append(typeRef.Name);
                }
                else
                {
                    FullNameCreator.FullNameSB(type, false, null, null, null, b);
                }
            }
        }
        static void AppendTypeName(StringBuilder b, TypeSig type)
        {
            if (type == null)
            {
                // could happen when a TypeSpecification has no ElementType; e.g. function pointers in C++/CLI assemblies
                return;
            }
            if (type is GenericInstSig)
            {
                GenericInstSig giType = (GenericInstSig)type;
                AppendTypeNameWithArguments(b, giType.GenericType.TypeDefOrRef, giType.GenericArguments);
                return;
            }
            SZArraySig arrayType = type as SZArraySig;              // TODO: multi-dimensional array

            if (arrayType != null)
            {
                AppendTypeName(b, arrayType.Next);
                b.Append("[]");
            }
            ByRefSig refType = type as ByRefSig;

            if (refType != null)
            {
                AppendTypeName(b, refType.Next);
                b.Append('@');
            }
            PtrSig ptrType = type as PtrSig;

            if (ptrType != null)
            {
                AppendTypeName(b, ptrType.Next);
                b.Append('*');
            }
            GenericSig gp = type as GenericSig;

            if (gp != null)
            {
                b.Append('`');
                if (gp.IsMethodVar)
                {
                    b.Append('`');
                }
                b.Append(gp.Number);
            }
            else
            {
                var typeRef  = type.ToTypeDefOrRef();
                var declType = Decompiler.DnlibExtensions.GetDeclaringType(typeRef);
                if (declType != null)
                {
                    AppendTypeName(b, declType.ToTypeSig());
                    b.Append('.');
                    b.Append(typeRef.Name);
                }
                else
                {
                    b.Append(type.FullName);
                }
            }
        }
        private int ProcessMethod(MethodDef md)
        {
            List <GenInfo> toPatch = new List <GenInfo>();

            if (!md.HasGenericParameters)
            {
                return(0);
            }

            List <MethodSpec> callers = FindCallingSpecs(md);

            if (callers.Count == 0)
            {
                return(0);
            }

            Dictionary <int, TypeSig> locals = new Dictionary <int, TypeSig>();

            for (int i = 0; i < callers.Count; i++)
            {
                MethodSpec spec = callers[i];

                for (int x = 0; x < md.Body.Variables.Count; x++)
                {
                    Local l = md.Body.Variables[x];

                    if (!l.Type.IsGenericMethodParameter)
                    {
                        continue;
                    }
                    if (!(l.Type is GenericSig))
                    {
                        continue;
                    }


                    GenericSig gSig = l.Type as GenericSig;

                    GenericParam gParam = md.GenericParameters.Where(y => y.Number == gSig.Number).FirstOrDefault();

                    int indexOf = md.GenericParameters.IndexOf(gParam);

                    if (gSig.Number > spec.GenericInstMethodSig.GenericArguments.Count - 1 || gSig.Number < 0)
                    {
                        continue;
                    }

                    TypeSig tSig = spec.GenericInstMethodSig.GenericArguments[(int)gSig.Number];



                    ITypeDefOrRef c**t = tSig.ToTypeDefOrRef();

                    ITypeDefOrRef tRef = c**t.ScopeType;

                    if (tSig.IsSZArray)
                    {
                    }
                    l.Type = tRef.ToTypeSig();

                    if (locals.ContainsKey(l.Index))
                    {
                        if (locals[l.Index] == tRef.ToTypeSig())
                        {
                            continue;
                        }
                        else
                        {
                            locals[l.Index] = tRef.ToTypeSig();
                        }
                    }
                    else
                    {
                        locals.Add(l.Index, tRef.ToTypeSig());
                    }

                    //md.GenericParameters.Remove(gParam);
                }
            }

            if (locals.Count == 0)
            {
                return(0);
            }


            Dictionary <int, Local> newLocals = new Dictionary <int, Local>();

            foreach (var pair in locals)
            {
                int     index = pair.Key;
                TypeSig tSig  = pair.Value;

                Local newLocal = new Local(tSig);
                //newLocal.Name = "TESTING!!!" + Guid.NewGuid().ToString();
                newLocal.Index = index;

                newLocals.Add(index, newLocal);
            }

            for (int i = 0; i < md.Body.Instructions.Count; i++)
            {
                Instruction inst = md.Body.Instructions[i];
                if (inst.OpCode == OpCodes.Stloc || inst.OpCode == OpCodes.Ldloc)
                {
                    Local l = inst.Operand as Local;
                    if (newLocals.ContainsKey(l.Index))
                    {
                        md.Body.Instructions[i].Operand = newLocals[l.Index];
                    }
                }
            }

            md.Body.Variables.Clear();
            foreach (var pair in newLocals)
            {
                md.Body.Variables.Add(pair.Value);
            }

            // New local is not added at all, it is simply f****d.

            if (md.Name == "")
            {
            }

            /*for (int i = 0; i < md.Body.Variables.Count; i++)
             * {
             *  Local l = md.Body.Variables[i];
             *
             *  if (!l.Type.IsGenericMethodParameter)
             *  {
             *      continue;
             *  }
             *  if (!(l.Type is GenericSig))
             *  {
             *      continue;
             *  }
             *
             *  if (locals.ContainsKey(l))
             *  {
             *      md.Body.Variables[i].Type = locals[l];
             *  }
             * }*/

            /*for (int i = 0; i < md.Body.Instructions.Count; i++)
             * {
             *  Instruction inst = md.Body.Instructions[i];
             *
             *  // If it is a generic method
             *  if (inst.Operand != null && inst.Operand is MethodSpec)
             *  {
             *      // Investigate the method body to see if all locals are outlined, use gen param count vs local count...?
             *      // If it is the same then we know that there are variables to outline. Next is trying to identify when a legitimate generic type is there...
             *      // We need to collate them into a list so we can link how many have the same generic sig types listed
             *      // (a generic should technically have several different types).
             *
             *
             *      MethodSpec mSpec = inst.Operand as MethodSpec;
             *      if (mSpec == null)
             *      {
             *          // Failsafe check
             *          continue;
             *      }
             *
             *      MethodDef mDef = mSpec.ResolveMethodDef();
             *      if (mDef == null)
             *      {
             *          Logger.Log(this, string.Format("Resolved MethodDef is null for {0}", mSpec));
             *          continue;
             *      }
             *
             *      if (mDef.Body == null)
             *      {
             *          continue;
             *      }
             *
             *      int lCount = mDef.Body.Variables.Count;
             *      int gpCount = mSpec.GenericInstMethodSig.GenericArguments.Count;
             *
             *
             *
             *      toPatch.Add(new GenInfo() { CallingInst = inst, GenCount = gpCount, LocalCount = lCount, RawMethod = mDef, TargetGeneric = mSpec,
             *          GenericArgs = mSpec.GenericInstMethodSig.GenericArguments.ToList(),
             *      CallIndex = i,
             *      ParentMethod = md});
             *
             *  }
             * }*/


            List <GenInfo> Completed = new List <GenInfo>();

            //Completed.AddRange(toPatch);

            foreach (GenInfo inf in toPatch)
            {
                // Get count of other similar generic instances
                // ... should put in a dictionary the link between the method, and numbers.
                // Let's get it working without that for now


                // get generic param from generic arg

                // Go to local, go to type, cast type to genericsig.
                // You can then get the 'number' which corresponds to the generic parameter on the raw method
                // Relate that back to the index on the locals maybe?
                bool comp = false;

                List <GenericParam> toDelete = new List <GenericParam>();
                List <Local>        toAdd    = new List <Local>();
                for (int i = 0; i < inf.RawMethod.Body.Variables.Count; i++)
                {
                    Local l = inf.RawMethod.Body.Variables[i];

                    if (!l.Type.IsGenericMethodParameter)
                    {
                        continue;
                    }
                    if (!(l.Type is GenericSig))
                    {
                        continue;
                    }

                    GenericSig gSig = l.Type as GenericSig;

                    if (gSig.Number > inf.TargetGeneric.GenericInstMethodSig.GenericArguments.Count - 1 || gSig.Number < 0)
                    {
                        continue;
                    }
                    TypeSig tSig = inf.TargetGeneric.GenericInstMethodSig.GenericArguments[(int)gSig.Number];

                    if (inf.RawMethod.Name == "method_1")
                    {
                    }
                    if (tSig.IsGenericParameter)
                    {
                    }
                    if (tSig == null)
                    {
                        continue;
                    }

                    ((MethodDef)inf.TargetGeneric.Method).Body.Variables[i].Type = tSig;
                    ((MethodDef)inf.TargetGeneric.Method).Body.Variables[i].Name = "CANCER_" + Guid.NewGuid().ToString();
                    //toAdd.Add(new Local(tSig));
                }

                //toAdd.ForEach(x => ((MethodDef)inf.TargetGeneric.Method).Body.Variables.Add(x));

                /*for (int i = 0; i < inf.RawMethod.Parameters.Count; i++)
                 * {
                 *  Parameter param = inf.RawMethod.Parameters[i];
                 *
                 *  if (!param.Type.IsGenericParameter)
                 *      continue;
                 *
                 *
                 *  GenericSig gSig = param.Type.ToGenericSig();
                 *
                 *  TypeSig tSig = inf.TargetGeneric.GenericInstMethodSig.GenericArguments[(int)gSig.Number];
                 *
                 *  if (tSig == null)
                 *      continue;
                 *
                 *  if (inf.RawMethod.Name == "method_4")
                 *  {
                 *
                 *  }
                 *  if (tSig.IsGenericParameter)
                 *      continue;
                 *  param.Type = tSig;
                 *
                 *  //toDelete.Add(inf.RawMethod.GenericParameters.Where(x => x.Number == gSig.Number).FirstOrDefault());
                 *
                 *
                 * }*/



                /*for (int i = 0; i < inf.RawMethod.GenericParameters.Count; i++)
                 * {
                 *  GenericParam gParam = inf.RawMethod.GenericParameters[i];
                 *
                 *
                 *  TypeSig tSig = inf.TargetGeneric.GenericInstMethodSig.GenericArguments[i];
                 *
                 *  if (tSig == null)
                 *      continue;
                 *
                 *  MethodDef mDef = inf.TargetGeneric.Method as MethodDef;
                 *
                 *  Parameter p = mDef.Parameters.Where(x => !x.IsHiddenThisParameter && x.Type.FullName == gParam.FullName).FirstOrDefault();
                 *
                 *
                 *  if (p == null)
                 *  {
                 *      continue;
                 *  }
                 *
                 *  p.Type = tSig;
                 *
                 *  toDelete.Add(gParam);
                 *
                 *
                 * }*/
                toDelete.ForEach(x => inf.RawMethod.GenericParameters.Remove(x));

                /*for (int i = 0; i < inf.RawMethod.Body.Variables.Count; i++)
                 * {
                 *  Local l = inf.RawMethod.Body.Variables[i];
                 *
                 *  if (!l.Type.IsGenericMethodParameter)
                 *  {
                 *      continue;
                 *  }
                 *  if (!(l.Type is GenericSig))
                 *  {
                 *      continue;
                 *  }
                 *
                 *  GenericSig gSig = l.Type as GenericSig;
                 *  //if (gSig.Number > inf.TargetGeneric.GenericInstMethodSig.GenericArguments.Count - 1)
                 *  //    continue;
                 *  TypeSig tSig = inf.TargetGeneric.GenericInstMethodSig.GenericArguments.Where(
                 *      (x) =>
                 *      {
                 *          if (!x.IsGenericMethodParameter)
                 *              return false;
                 *
                 *          GenericSig gSig2 = x.ToGenericSig();
                 *          if (gSig2 == null)
                 *              return false;
                 *
                 *          return gSig2.Number == gSig.Number;
                 *          //return true;
                 *      }
                 *      ).FirstOrDefault();
                 *
                 *  if (tSig == null)
                 *      continue;
                 *
                 *  inf.RawMethod.Body.Variables[i].Type = tSig;
                 *
                 *  comp = true;
                 * }
                 *
                 * if (comp)
                 *  Completed.Add(inf);*/
            }


            return(Completed.Count);
        }