internal override void ProcessOperand(TypeService service, MethodDef method, IList <Instruction> body, ref int index, MethodSpec operand) { Debug.Assert(service != null, $"{nameof(service)} != null"); Debug.Assert(method != null, $"{nameof(method)} != null"); Debug.Assert(body != null, $"{nameof(body)} != null"); Debug.Assert(operand != null, $"{nameof(operand)} != null"); Debug.Assert(index >= 0, $"{nameof(index)} >= 0"); Debug.Assert(index < body.Count, $"{nameof(index)} < {nameof(body)}.Count"); var current = service.GetItem(method); if (operand.Method is MethodDef operandDef) { var operandScanned = service.GetItem(operandDef); if (operandScanned?.IsScambled == true) { operand.GenericInstMethodSig = operandScanned.CreateGenericMethodSig(current, service, operand.GenericInstMethodSig); } } else if (current?.IsScambled == true) { var generics = operand.GenericInstMethodSig.GenericArguments.Select(x => current.ConvertToGenericIfAvalible(x)); operand.GenericInstMethodSig = new GenericInstMethodSig(generics.ToArray()); } }
public override void ProcessOperand(TypeService service, MethodDef method, IList <Instruction> body, ref int index, TypeDef operand) { ScannedItem t = service.GetItem(operand.MDToken); if (t == null) { return; } body[index].Operand = new TypeSpecUser(t.CreateGenericTypeSig(service.GetItem(method.DeclaringType.MDToken))); }
public override void ProcessOperand(TypeService service, MethodDef method, IList <Instruction> body, ref int index, MethodDef operand) { ScannedMethod tMethod = service.GetItem(operand.MDToken) as ScannedMethod; ScannedItem currentMethod = service.GetItem(method.MDToken) as ScannedMethod; if (tMethod != null) { var newspec = new MethodSpecUser(tMethod.TargetMethod, tMethod.CreateGenericMethodSig(currentMethod)); body[index].Operand = newspec; } }
internal override void ProcessOperand(TypeService service, MethodDef method, IList <Instruction> body, ref int index, MemberRef operand) { Debug.Assert(service != null, $"{nameof(service)} != null"); Debug.Assert(method != null, $"{nameof(method)} != null"); Debug.Assert(body != null, $"{nameof(body)} != null"); Debug.Assert(operand != null, $"{nameof(operand)} != null"); Debug.Assert(index >= 0, $"{nameof(index)} >= 0"); Debug.Assert(index < body.Count, $"{nameof(index)} < {nameof(body)}.Count"); var current = service.GetItem(method); if (operand.MethodSig == null) { return; } if (operand.MethodSig.Params.Count > 0 || body[index].OpCode != OpCodes.Newobj) { return; } ModuleDef mod = method.Module; var corlibType = mod.CorLibTypes.GetTypeRef("System", "Type").ResolveThrow(); var gettype = corlibType.FindMethod("GetTypeFromHandle"); var createInstance = mod.CorLibTypes.GetTypeRef("System", "Activator").ResolveThrow() .FindMethod("CreateInstance", MethodSig.CreateStatic(mod.CorLibTypes.Object, corlibType.ToTypeSig())); TypeSig sig = null; if (operand.Class is TypeRef typeRef) { sig = typeRef.ToTypeSig(); } if (operand.Class is TypeSpec typeSpec) { sig = typeSpec.ToTypeSig(); } if (sig != null) { body[index].OpCode = OpCodes.Ldtoken; var gen = current?.GetGeneric(sig); TypeSpecUser newTypeSpec = null; if (gen != null) { newTypeSpec = new TypeSpecUser(new GenericMVar(gen.Number)); } else { newTypeSpec = new TypeSpecUser(sig); } body[index].Operand = newTypeSpec; body.Insert(++index, Instruction.Create(OpCodes.Call, mod.Import(gettype))); body.Insert(++index, Instruction.Create(OpCodes.Call, mod.Import(createInstance))); } }
internal override void ProcessOperand(TypeService service, MethodDef method, IList <Instruction> body, ref int index, TypeDef operand) { Debug.Assert(service != null, $"{nameof(service)} != null"); Debug.Assert(method != null, $"{nameof(method)} != null"); Debug.Assert(body != null, $"{nameof(body)} != null"); Debug.Assert(operand != null, $"{nameof(operand)} != null"); Debug.Assert(index >= 0, $"{nameof(index)} >= 0"); Debug.Assert(index < body.Count, $"{nameof(index)} < {nameof(body)}.Count"); var current = service.GetItem(operand); if (current?.IsScambled == true) { body[index].Operand = new TypeSpecUser(current.CreateGenericTypeSig(service.GetItem(method.DeclaringType))); } }
internal GenericInstMethodSig CreateGenericMethodSig(ScannedMethod from, TypeService srv, GenericInstMethodSig original = null) { var types = new List <TypeSig>(TrueTypes.Count); foreach (var trueType in TrueTypes) { if (trueType.IsGenericMethodParameter) { Debug.Assert(original != null, $"{nameof(original)} != null"); var number = ((GenericSig)trueType).Number; Debug.Assert(number < original.GenericArguments.Count, $"{nameof(number)} < {nameof(original)}.GenericArguments.Count"); var originalArgument = original.GenericArguments[(int)number]; types.Add(originalArgument); } else if (from?.IsScambled == true) { types.Add(from.ConvertToGenericIfAvalible(trueType)); } else if (trueType.ToTypeDefOrRef() is TypeDef def) { // I am sure there are cleaner and better ways to do this. var item = srv.GetItem(def); types.Add(item?.IsScambled == true ? item.CreateGenericTypeSig(null) : trueType); } else { types.Add(trueType); } } return(new GenericInstMethodSig(types)); }
public override void ProcessOperand(TypeService service, MethodDef method, IList <Instruction> body, ref int index, MethodSpec operand) { ScannedMethod t = service.GetItem(method.MDToken) as ScannedMethod; if (t != null) { var generics = operand.GenericInstMethodSig.GenericArguments.Select(x => t.ConvertToGenericIfAvalible(x)); operand.GenericInstMethodSig = new GenericInstMethodSig(generics.ToArray()); } }
public override void ProcessOperand(TypeService service, MethodDef method, IList <Instruction> body, ref int index, TypeRef operand) { ScannedItem current = service.GetItem(method.MDToken); if (current == null) { return; } body[index].Operand = new TypeSpecUser(current.ConvertToGenericIfAvalible(operand.ToTypeSig())); }
internal override void ProcessOperand(TypeService service, MethodDef method, IList <Instruction> body, ref int index, MethodDef operand) { Debug.Assert(service != null, $"{nameof(service)} != null"); Debug.Assert(method != null, $"{nameof(method)} != null"); Debug.Assert(body != null, $"{nameof(body)} != null"); Debug.Assert(operand != null, $"{nameof(operand)} != null"); Debug.Assert(index >= 0, $"{nameof(index)} >= 0"); Debug.Assert(index < body.Count, $"{nameof(index)} < {nameof(body)}.Count"); var declType = service.GetItem(operand.DeclaringType); var targetMethod = service.GetItem(operand); if (declType?.IsScambled == true) { var methodD = new MemberRefUser(operand.Module, operand.Name, operand.MethodSig, declType.CreateGenericTypeSig(service.GetItem(method.DeclaringType)).ToTypeDefOrRef()); if (targetMethod?.IsScambled == true) { var newSpec = new MethodSpecUser(methodD, targetMethod.CreateGenericMethodSig(service.GetItem(method), service)); Debug.Assert(newSpec.GenericInstMethodSig.GenericArguments.Count == targetMethod.TargetMethod.GenericParameters.Count, $"{nameof(newSpec)}.GenericInstMethodSig.GenericArguments.Count == {nameof(targetMethod)}.TargetMethod.GenericParameters.Count"); body[index].Operand = newSpec; } else { body[index].Operand = methodD; } } else if (targetMethod?.IsScambled == true) { var newSpec = new MethodSpecUser(targetMethod.TargetMethod, targetMethod.CreateGenericMethodSig(service.GetItem(method), service)); Debug.Assert(newSpec.GenericInstMethodSig.GenericArguments.Count == targetMethod.TargetMethod.GenericParameters.Count, $"{nameof(newSpec)}.GenericInstMethodSig.GenericArguments.Count == {nameof(targetMethod)}.TargetMethod.GenericParameters.Count"); body[index].Operand = newSpec; } }
public override void Process(ScannedMethod m, MethodDef o) { var sc = service.GetItem(o.MDToken) as ScannedMethod; if (sc != null) { foreach (var regTypes in sc.TrueTypes) { m.RegisterGeneric(regTypes); } } }
internal override void ProcessOperand(TypeService service, MethodDef method, IList <Instruction> body, ref int index, FieldDef operand) { Debug.Assert(service != null, $"{nameof(service)} != null"); Debug.Assert(method != null, $"{nameof(method)} != null"); Debug.Assert(body != null, $"{nameof(body)} != null"); Debug.Assert(operand != null, $"{nameof(operand)} != null"); Debug.Assert(index >= 0, $"{nameof(index)} >= 0"); Debug.Assert(index < body.Count, $"{nameof(index)} < {nameof(body)}.Count"); if (method.Module.IsClr40 && body[index].OpCode != OpCodes.Ldsfld && body[index].OpCode != OpCodes.Ldsflda && body[index].OpCode != OpCodes.Stsfld) { return; } var declType = service.GetItem(operand.DeclaringType); if (declType?.IsScambled == true) { body[index].Operand = new MemberRefUser(operand.Module, operand.Name, operand.FieldSig, declType.CreateGenericTypeSig(service.GetItem(method.DeclaringType)).ToTypeDefOrRef()); } }
public override void ProcessOperand(TypeService service, MethodDef method, IList <Instruction> body, ref int index, MemberRef operand) { ScannedMethod current = service.GetItem(method.MDToken) as ScannedMethod; if (operand.MethodSig.Params.Count > 0 || current == null || body[index].OpCode != OpCodes.Newobj) { return; } ModuleDef mod = method.Module; var gettype = typeof(Type).GetMethod("GetTypeFromHandle"); var createInstance = typeof(Activator).GetMethod("CreateInstance", new Type[] { typeof(Type) }); var createInstanceArgs = typeof(Activator).GetMethod("CreateInstance", new Type[] { typeof(Type), typeof(object[]) }); TypeSig sig = null; if (operand.Class is TypeRef) { sig = (operand.Class as TypeRef)?.ToTypeSig(); } if (operand.Class is TypeSpec) { sig = (operand.Class as TypeSpec)?.ToTypeSig(); } if (sig != null) { //ScannedItem t = service.GetItem(operand.MDToken); //if (t != null) { // sig = t.CreateGenericTypeSig(service.GetItem(method.DeclaringType.MDToken)); // } var paramCount = operand.MethodSig.Params.Count; var gen = current.GetGeneric(sig); body[index].OpCode = OpCodes.Ldtoken; TypeSpecUser newTypeSpec = null; if (gen != null) { newTypeSpec = new TypeSpecUser(new GenericMVar(gen.Number)); } else { newTypeSpec = new TypeSpecUser(sig); } body[index].Operand = newTypeSpec; /* * var genericCallSig = new GenericInstMethodSig( new TypeSig[] { current.ConvertToGenericIfAvalible(sig) }); * foreach(var param in operand.MethodSig.Params.Select(x => current.ConvertToGenericIfAvalible(x))) { * genericCallSig.GenericArguments.Add(param); * } * * // tgtMethod.GenericInstMethodSig = genericCallSig; * var spec = new MethodSpecUser(tgtMethod, genericCallSig); * * body[index].OpCode = OpCodes.Call; * body[index].Operand = tgtMethod; */ body.Insert(++index, Instruction.Create(OpCodes.Call, mod.Import(gettype))); body.Insert(++index, Instruction.Create(OpCodes.Call, mod.Import(createInstance))); } }