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); }
/// <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); }
public static TextTokenKind GetTextTokenType(GenericSig sig) { if (sig == null) { return(TextTokenKind.Text); } return(sig.IsMethodVar ? TextTokenKind.MethodGenericParameter : TextTokenKind.TypeGenericParameter); }
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); }
internal static int GetGenericSigToken(GenericSig field) { return(Writer.Module == field.Module ? Writer.Metadata.GetToken(field).ToInt32() : field.MDToken.ToInt32()); }
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); } } }
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); }