public TypeSig ToGenericIfAvalible(TypeSig t) { if (t.ContainsGenericParameter || t.ScopeType == null) { return(t); } GenericParam gp; if (!Generics.TryGetValue(t.ScopeType.MDToken.Raw, out gp)) { return(t); } TypeSig newSig = new GenericMVar(gp.Number); if (t.IsSingleOrMultiDimensionalArray) { var arraySig = t as SZArraySig; if (arraySig == null || arraySig.IsMultiDimensional) { return(t); } else { return(new ArraySig(newSig, arraySig.Rank)); } } return(newSig); }
public TypeSig Replace(GenericMVar genMVarSig) { if (genMVarSig.OwnerMethod == OwnerMethod.Def) { return(OwnerMethod.GenArgs[(int)genMVarSig.Number]); } return(null); }
public TypeSig Replace(GenericMVar genMVar) { if (MethodEqualityComparer.DontCompareDeclaringTypes.Equals(genMVar.OwnerMethod, OwnerMethod)) { return(MethodGenArgs[(int)genMVar.Number]); } return(genMVar); }
private MethodDef CreateFactoryMethodNoParameters(ITypeService service, ModuleDef module) { var instancevar = new GenericParamUser(0, GenericParamAttributes.NoSpecialConstraint, "t"); var mvar = new GenericMVar(0); var typeSpec = new TypeSpecUser(mvar); var local = new Local(mvar); var rtHandle = new Local(module.Import(typeof(RuntimeTypeHandle)).ToTypeSig()); var method = new MethodDefUser("create", new MethodSig(CallingConvention.Default, 1, mvar), MethodAttributes.Static); method.GenericParameters.Add(instancevar); var gettype = typeof(Type).GetMethod("GetTypeFromHandle"); var comparetypes = typeof(Type).GetMethod("op_Equality"); var i = new List <Instruction>(); i.Add(Instruction.Create(OpCodes.Ldtoken, typeSpec)); i.Add(Instruction.Create(OpCodes.Call, module.Import(gettype))); i.Add(Instruction.Create(OpCodes.Stloc, rtHandle)); foreach (var mr in ObjectCreationRef) { Instruction endjump = Instruction.Create(OpCodes.Nop); i.Add(Instruction.Create(OpCodes.Ldloc, rtHandle)); i.Add(Instruction.Create(OpCodes.Ldtoken, mr.DeclaringType)); i.Add(Instruction.Create(OpCodes.Call, module.Import(gettype))); i.Add(Instruction.Create(OpCodes.Call, module.Import(comparetypes))); i.Add(Instruction.Create(OpCodes.Brfalse_S, endjump)); i.Add(Instruction.Create(OpCodes.Newobj, mr)); i.Add(Instruction.Create(OpCodes.Ret)); i.Add(endjump); } i.Add(Instruction.Create(OpCodes.Ldloca_S, local)); i.Add(Instruction.Create(OpCodes.Initobj, typeSpec)); i.Add(Instruction.Create(OpCodes.Ldloc, local)); i.Add(Instruction.Create(OpCodes.Ret)); method.Body = new CilBody(true, i, new ExceptionHandler[0], new Local[] { local, rtHandle }); return(method); }
TypeSig ResolveGenericArgs(TypeSig typeSig) { if (!recursionCounter.Increment()) { return(null); } if (ReplaceGenericArg(ref typeSig)) { recursionCounter.Decrement(); return(typeSig); } TypeSig result; switch (typeSig.ElementType) { case ElementType.Ptr: result = new PtrSig(ResolveGenericArgs(typeSig.Next)); break; case ElementType.ByRef: result = new ByRefSig(ResolveGenericArgs(typeSig.Next)); break; case ElementType.Var: result = new GenericVar((typeSig as GenericVar).Number); break; case ElementType.ValueArray: result = new ValueArraySig(ResolveGenericArgs(typeSig.Next), (typeSig as ValueArraySig).Size); break; case ElementType.SZArray: result = new SZArraySig(ResolveGenericArgs(typeSig.Next)); break; case ElementType.MVar: result = new GenericMVar((typeSig as GenericMVar).Number); break; case ElementType.CModReqd: result = new CModReqdSig((typeSig as ModifierSig).Modifier, ResolveGenericArgs(typeSig.Next)); break; case ElementType.CModOpt: result = new CModOptSig((typeSig as ModifierSig).Modifier, ResolveGenericArgs(typeSig.Next)); break; case ElementType.Module: result = new ModuleSig((typeSig as ModuleSig).Index, ResolveGenericArgs(typeSig.Next)); break; case ElementType.Pinned: result = new PinnedSig(ResolveGenericArgs(typeSig.Next)); break; case ElementType.FnPtr: throw new NotSupportedException("FnPtr is not supported."); case ElementType.Array: ArraySig arraySig = (ArraySig)typeSig; List <uint> sizes = new List <uint>(arraySig.Sizes); List <int> lbounds = new List <int>(arraySig.LowerBounds); result = new ArraySig(ResolveGenericArgs(typeSig.Next), arraySig.Rank, sizes, lbounds); break; case ElementType.GenericInst: GenericInstSig gis = (GenericInstSig)typeSig; List <TypeSig> genArgs = new List <TypeSig>(gis.GenericArguments.Count); foreach (TypeSig ga in gis.GenericArguments) { genArgs.Add(ResolveGenericArgs(ga)); } result = new GenericInstSig(ResolveGenericArgs((TypeSig)gis.GenericType) as ClassOrValueTypeSig, genArgs); break; default: result = typeSig; break; } recursionCounter.Decrement(); return(result); }
void AddGenericMVar() => TypeSig = new GenericMVar(GenericVariableNumber.Value, options.OwnerMethod);
/// <summary> /// Reads the next type /// </summary> /// <returns>A new <see cref="TypeSig"/> instance or <c>null</c> if invalid element type</returns> TypeSig ReadType() { if (!recursionCounter.Increment()) { return(null); } uint num, i; TypeSig nextType, result = null; switch ((ElementType)reader.ReadByte()) { case ElementType.Void: result = corLibTypes.Void; break; case ElementType.Boolean: result = corLibTypes.Boolean; break; case ElementType.Char: result = corLibTypes.Char; break; case ElementType.I1: result = corLibTypes.SByte; break; case ElementType.U1: result = corLibTypes.Byte; break; case ElementType.I2: result = corLibTypes.Int16; break; case ElementType.U2: result = corLibTypes.UInt16; break; case ElementType.I4: result = corLibTypes.Int32; break; case ElementType.U4: result = corLibTypes.UInt32; break; case ElementType.I8: result = corLibTypes.Int64; break; case ElementType.U8: result = corLibTypes.UInt64; break; case ElementType.R4: result = corLibTypes.Single; break; case ElementType.R8: result = corLibTypes.Double; break; case ElementType.String: result = corLibTypes.String; break; case ElementType.TypedByRef: result = corLibTypes.TypedReference; break; case ElementType.I: result = corLibTypes.IntPtr; break; case ElementType.U: result = corLibTypes.UIntPtr; break; case ElementType.Object: result = corLibTypes.Object; break; case ElementType.Ptr: result = new PtrSig(ReadType()); break; case ElementType.ByRef: result = new ByRefSig(ReadType()); break; case ElementType.ValueType: result = new ValueTypeSig(ReadTypeDefOrRef()); break; case ElementType.Class: result = new ClassSig(ReadTypeDefOrRef()); break; case ElementType.FnPtr: result = new FnPtrSig(ReadSig()); break; case ElementType.SZArray: result = new SZArraySig(ReadType()); break; case ElementType.CModReqd: result = new CModReqdSig(ReadTypeDefOrRef(), ReadType()); break; case ElementType.CModOpt: result = new CModOptSig(ReadTypeDefOrRef(), ReadType()); break; case ElementType.Sentinel: result = new SentinelSig(); break; case ElementType.Pinned: result = new PinnedSig(ReadType()); break; case ElementType.Var: if (!reader.TryReadCompressedUInt32(out num)) { break; } result = new GenericVar(num, gpContext.Type); break; case ElementType.MVar: if (!reader.TryReadCompressedUInt32(out num)) { break; } result = new GenericMVar(num, gpContext.Method); break; case ElementType.ValueArray: nextType = ReadType(); if (!reader.TryReadCompressedUInt32(out num)) { break; } result = new ValueArraySig(nextType, num); break; case ElementType.Module: if (!reader.TryReadCompressedUInt32(out num)) { break; } result = new ModuleSig(num, ReadType()); break; case ElementType.GenericInst: nextType = ReadType(); if (!reader.TryReadCompressedUInt32(out num)) { break; } var genericInstSig = new GenericInstSig(nextType as ClassOrValueTypeSig, num); var args = genericInstSig.GenericArguments; for (i = 0; i < num; i++) { args.Add(ReadType()); } result = genericInstSig; break; case ElementType.Array: nextType = ReadType(); uint rank; if (!reader.TryReadCompressedUInt32(out rank)) { break; } if (rank > MaxArrayRank) { break; } if (rank == 0) { result = new ArraySig(nextType, rank); break; } if (!reader.TryReadCompressedUInt32(out num)) { break; } if (num > MaxArrayRank) { break; } var sizes = new List <uint>((int)num); for (i = 0; i < num; i++) { if (!reader.TryReadCompressedUInt32(out uint size)) { goto exit; } sizes.Add(size); } if (!reader.TryReadCompressedUInt32(out num)) { break; } if (num > MaxArrayRank) { break; } var lowerBounds = new List <int>((int)num); for (i = 0; i < num; i++) { if (!reader.TryReadCompressedInt32(out int size)) { goto exit; } lowerBounds.Add(size); } result = new ArraySig(nextType, rank, sizes, lowerBounds); break; case ElementType.Internal: IntPtr address; if (IntPtr.Size == 4) { address = new IntPtr(reader.ReadInt32()); } else { address = new IntPtr(reader.ReadInt64()); } result = helper.ConvertRTInternalAddress(address); break; case ElementType.End: case ElementType.R: default: result = null; break; } exit: recursionCounter.Decrement(); return(result); }
public TypeSig Replace(GenericMVar genMVarSig) { return(null); }
private static TypeSig ReplaceGenericSigImpl(TypeSig tySig, IGenericReplacer replacer) { if (tySig == null) { return(null); } switch (tySig.ElementType) { case ElementType.Class: case ElementType.ValueType: case ElementType.TypedByRef: return(tySig); case ElementType.Ptr: return(new PtrSig(ReplaceGenericSigImpl(tySig.Next, replacer))); case ElementType.ByRef: return(new ByRefSig(ReplaceGenericSigImpl(tySig.Next, replacer))); case ElementType.Pinned: return(new PinnedSig(ReplaceGenericSigImpl(tySig.Next, replacer))); case ElementType.SZArray: return(new SZArraySig(ReplaceGenericSigImpl(tySig.Next, replacer))); case ElementType.Array: { ArraySig arySig = (ArraySig)tySig; return(new ArraySig(ReplaceGenericSigImpl(arySig.Next, replacer), arySig.Rank, arySig.Sizes, arySig.LowerBounds)); } case ElementType.CModReqd: { CModReqdSig modreqdSig = (CModReqdSig)tySig; return(new CModReqdSig(modreqdSig.Modifier, ReplaceGenericSigImpl(modreqdSig.Next, replacer))); } case ElementType.CModOpt: { CModOptSig modoptSig = (CModOptSig)tySig; return(new CModOptSig(modoptSig.Modifier, ReplaceGenericSigImpl(modoptSig.Next, replacer))); } case ElementType.GenericInst: { GenericInstSig genInstSig = (GenericInstSig)tySig; return(new GenericInstSig(genInstSig.GenericType, ReplaceGenericSigListImpl(genInstSig.GenericArguments, replacer))); } case ElementType.Var: { GenericVar genVarSig = (GenericVar)tySig; TypeSig result = replacer.Replace(genVarSig); if (result != null) { return(result); } return(genVarSig); } case ElementType.MVar: { GenericMVar genMVarSig = (GenericMVar)tySig; TypeSig result = replacer.Replace(genMVarSig); if (result != null) { return(result); } return(genMVarSig); } default: if (tySig is CorLibTypeSig) { return(tySig); } throw new NotSupportedException(); } }
// Token: 0x06000231 RID: 561 RVA: 0x0001F4AC File Offset: 0x0001D6AC private TypeSig ResolveGenericArgs(TypeSig typeSig) { if (!this.recursionCounter.Increment()) { return(null); } if (this.ReplaceGenericArg(ref typeSig)) { this.recursionCounter.Decrement(); return(typeSig); } ElementType elementType = typeSig.ElementType; TypeSig result; switch (elementType) { case ElementType.Ptr: result = new PtrSig(this.ResolveGenericArgs(typeSig.Next)); goto IL_265; case ElementType.ByRef: result = new ByRefSig(this.ResolveGenericArgs(typeSig.Next)); goto IL_265; case ElementType.ValueType: case ElementType.Class: case ElementType.TypedByRef: case ElementType.I: case ElementType.U: case ElementType.R: case ElementType.Object: break; case ElementType.Var: result = new GenericVar((typeSig as GenericVar).Number); goto IL_265; case ElementType.Array: { ArraySig arraySig = (ArraySig)typeSig; List <uint> sizes = new List <uint>(arraySig.Sizes); List <int> lbounds = new List <int>(arraySig.LowerBounds); result = new ArraySig(this.ResolveGenericArgs(typeSig.Next), arraySig.Rank, sizes, lbounds); goto IL_265; } case ElementType.GenericInst: { GenericInstSig gis = (GenericInstSig)typeSig; List <TypeSig> genArgs = new List <TypeSig>(gis.GenericArguments.Count); foreach (TypeSig ga in gis.GenericArguments) { genArgs.Add(this.ResolveGenericArgs(ga)); } result = new GenericInstSig(this.ResolveGenericArgs(gis.GenericType) as ClassOrValueTypeSig, genArgs); goto IL_265; } case ElementType.ValueArray: result = new ValueArraySig(this.ResolveGenericArgs(typeSig.Next), (typeSig as ValueArraySig).Size); goto IL_265; case ElementType.FnPtr: throw new NotSupportedException("FnPtr is not supported."); case ElementType.SZArray: result = new SZArraySig(this.ResolveGenericArgs(typeSig.Next)); goto IL_265; case ElementType.MVar: result = new GenericMVar((typeSig as GenericMVar).Number); goto IL_265; case ElementType.CModReqd: result = new CModReqdSig((typeSig as ModifierSig).Modifier, this.ResolveGenericArgs(typeSig.Next)); goto IL_265; case ElementType.CModOpt: result = new CModOptSig((typeSig as ModifierSig).Modifier, this.ResolveGenericArgs(typeSig.Next)); goto IL_265; default: if (elementType == ElementType.Module) { result = new ModuleSig((typeSig as ModuleSig).Index, this.ResolveGenericArgs(typeSig.Next)); goto IL_265; } if (elementType == ElementType.Pinned) { result = new PinnedSig(this.ResolveGenericArgs(typeSig.Next)); goto IL_265; } break; } result = typeSig; IL_265: this.recursionCounter.Decrement(); return(result); }
public TypeSig Duplicate(TypeSig typeSig) { if (!IsDuplicateNeeded(typeSig)) { return(typeSig); } switch (typeSig.ElementType) { case ElementType.Class: case ElementType.ValueType: return(typeSig); case ElementType.Ptr: return(new PtrSig(Duplicate(typeSig.Next))); case ElementType.ByRef: return(new ByRefSig(Duplicate(typeSig.Next))); case ElementType.SZArray: return(new SZArraySig(Duplicate(typeSig.Next))); case ElementType.Pinned: return(new PinnedSig(Duplicate(typeSig.Next))); case ElementType.Array: { ArraySig arySig = (ArraySig)typeSig; return(new ArraySig(Duplicate(arySig.Next), arySig.Rank, Duplicate(arySig.Sizes), Duplicate(arySig.LowerBounds))); } case ElementType.Var: { GenericVar genVar = (GenericVar)typeSig; TypeSig result = GenReplacer.Replace(genVar); if (result != null) { return(result); } return(new GenericVar(genVar.Number, genVar.OwnerType)); } case ElementType.MVar: { GenericMVar genMVar = (GenericMVar)typeSig; TypeSig result = GenReplacer.Replace(genMVar); if (result != null) { return(result); } return(new GenericMVar(genMVar.Number, genMVar.OwnerMethod)); } case ElementType.GenericInst: { GenericInstSig genSig = (GenericInstSig)typeSig; return(new GenericInstSig(genSig.GenericType, Duplicate(genSig.GenericArguments))); } case ElementType.CModReqd: { CModReqdSig modreq = (CModReqdSig)typeSig; return(new CModReqdSig(modreq.Modifier, Duplicate(modreq.Next))); } case ElementType.CModOpt: { CModOptSig modopt = (CModOptSig)typeSig; return(new CModOptSig(modopt.Modifier, Duplicate(modopt.Next))); } default: if (typeSig is CorLibTypeSig) { return(typeSig); } throw new ArgumentOutOfRangeException("Duplicate TypeSig " + typeSig.GetType().Name); } }
private MethodDef CreateFactory(ITypeService service, ModuleDef module, int paramNumber, IList <IMethodDefOrRef> methods) { var declaringTypeGeneric = new GenericParamUser(0, GenericParamAttributes.NoSpecialConstraint, "t"); var declaringTypeGenericMVar = new GenericMVar(0); var pGenericTypeSpecs = Enumerable.Range(1, paramNumber).Select((x) => new TypeSpecUser(new GenericMVar(x))).ToArray(); var returnGeneric = new GenericMVar(paramNumber + 1);//last generic is return type var typeSpec = new TypeSpecUser(declaringTypeGenericMVar); var local = new Local(declaringTypeGenericMVar); var rtHandle = new Local(module.Import(typeof(RuntimeTypeHandle)).ToTypeSig()); var methodSig = new MethodSig(CallingConvention.Default, 1, returnGeneric, //Method index Enumerable.Range(1, paramNumber) .Select(x => new GenericMVar(x)) .Concat(new TypeSig[] { module.CorLibTypes.UInt32 }) //Index .ToArray()); var method = new MethodDefUser("call", methodSig, MethodAttributes.Static); method.GenericParameters.Add(declaringTypeGeneric); for (ushort genericNum = 1; genericNum < paramNumber + 2 /*declare type / return type */; genericNum++) { method.GenericParameters.Add(new GenericParamUser(genericNum, GenericParamAttributes.NoSpecialConstraint, "p" + genericNum.ToString())); } var gettype = typeof(Type).GetMethod("GetTypeFromHandle"); var comparetypes = typeof(Type).GetMethod("op_Equality"); var i = new List <Instruction>(); i.Add(Instruction.Create(OpCodes.Ldtoken, typeSpec)); i.Add(Instruction.Create(OpCodes.Call, module.Import(gettype))); i.Add(Instruction.Create(OpCodes.Stloc, rtHandle)); var retDef = new Instruction[] { Instruction.Create(OpCodes.Ldloca_S, local), Instruction.Create(OpCodes.Initobj, new TypeSpecUser(returnGeneric)), Instruction.Create(OpCodes.Ldloc, local), Instruction.Create(OpCodes.Ret), }; foreach (var mr in methods) { Instruction endjump = Instruction.Create(OpCodes.Nop); //Calling type i.Add(Instruction.Create(OpCodes.Ldloc, rtHandle)); i.Add(Instruction.Create(OpCodes.Ldtoken, mr.DeclaringType)); i.Add(Instruction.Create(OpCodes.Call, module.Import(gettype))); i.Add(Instruction.Create(OpCodes.Call, module.Import(comparetypes))); i.Add(Instruction.Create(OpCodes.Brfalse_S, endjump)); //method index i.Add(Instruction.Create(OpCodes.Ldarg, new Parameter(paramNumber))); i.Add(Instruction.Create(OpCodes.Ldc_I4, GetIndexOfMethodInDeclaringType(mr))); i.Add(Instruction.Create(OpCodes.Ceq)); i.Add(Instruction.Create(OpCodes.Brfalse_S, endjump)); //params for (int index = 0; index < mr.MethodSig.Params.Count; index++) { i.Add(Instruction.Create(OpCodes.Ldtoken, pGenericTypeSpecs[index])); i.Add(Instruction.Create(OpCodes.Call, module.Import(gettype))); i.Add(Instruction.Create(OpCodes.Ldtoken, new TypeSpecUser(mr.MethodSig.Params[index]))); i.Add(Instruction.Create(OpCodes.Call, module.Import(gettype))); i.Add(Instruction.Create(OpCodes.Call, module.Import(comparetypes))); i.Add(Instruction.Create(OpCodes.Brfalse_S, endjump)); } for (int index = 0; index < paramNumber; index++) { i.Add(Instruction.Create(OpCodes.Ldarg, new Parameter(index))); } i.Add(Instruction.Create(OpCodes.Call, mr)); if (mr.MethodSig.RetType != module.CorLibTypes.Void) { i.Add(Instruction.Create(OpCodes.Ret)); } else { // i.AddRange(retDef); } i.Add(endjump); } i.AddRange(retDef); method.Body = new CilBody(true, i, new ExceptionHandler[0], new Local[] { local, rtHandle }); // method.Body.KeepOldMaxStack = true; return(method); }
/// <summary> /// Create a list of all possible combinations of types/generic types that would make /// sense as parameters. This is necessary because the serialized method data does not /// contain information about which parameters map to which generic types (indices), /// neither GenericVars (declaring type) or GenericMVars (method itself). /// /// TODO: Factor in context generics (generics from virtualized method itself and /// declaring type?) /// </summary> /// <param name="parameters">Parameters (with no generic type information)</param> /// <param name="generics">Generics visible to the method</param> /// <returns>Combinations with at least one item (original parameters)</returns> public static IList <IList <TypeSig> > CreateGenericParameterCombinations_(IList <TypeSig> parameters, IList <TypeSig> typeGenerics, IList <TypeSig> methodGenerics) { IList <IList <TypeSig> > list = new List <IList <TypeSig> >(); list.Add(parameters); for (UInt16 p = 0; p < parameters.Count; p++) { TypeSig paramtype = parameters[p]; IList <TypeSig> ptypes = new TypeSig[] { paramtype }; // Might be something like: DoSomething(IList<!0> someList) if (paramtype.IsGenericInstanceType) { ptypes = PossibleTypeSigs(paramtype, typeGenerics, methodGenerics); } for (UInt16 g = 0; g < typeGenerics.Count; g++) { var gtype = typeGenerics[g]; foreach (var ptype in ptypes) { // Better comparison? //if (ptype.FullName.Equals(gtype.FullName)) //{ Int32 length = list.Count; for (Int32 i = 0; i < length; i++) { // Copy param list List <TypeSig> newParams = new List <TypeSig>(); newParams.AddRange(list[i]); GenericVar gvar = new GenericVar(g); newParams[p] = gvar; list.Add(newParams); } //} } } for (UInt16 g = 0; g < methodGenerics.Count; g++) { var gtype = methodGenerics[g]; foreach (var ptype in ptypes) { //if (ptype.FullName.Equals(gtype.FullName)) //{ Int32 length = list.Count; for (Int32 i = 0; i < length; i++) { List <TypeSig> newParams = new List <TypeSig>(); newParams.AddRange(list[i]); GenericMVar gmvar = new GenericMVar(g); newParams[p] = gmvar; list.Add(newParams); } //} } } } return(list); }