private void CloneLocalVariables(MemberCloneContext context, CilMethodBody body, CilMethodBody clonedBody) { foreach (var variable in body.LocalVariables) { var clonedVariable = new CilLocalVariable(context.Importer.ImportTypeSignature(variable.VariableType)); clonedBody.LocalVariables.Add(clonedVariable); } }
public void Process(TypeDefinition type) { // On first execution, grab fields from global constructor if (FieldsInModule.Count == 0) { var globalType = type.Module.GetOrCreateModuleType(); foreach (var field in globalType.Fields) { // This assumes that the fields have no default value (which the forks Ive checked didnt have) if (!field.IsStatic || field.IsPrivate || field.HasDefault) { continue; } CheckUsage(field, type.Module); } } foreach (var method in type.Methods.Where(m => m.CilMethodBody != null)) { var instr = method.CilMethodBody.Instructions; for (int i = 0; i < instr.Count; i++) { if (instr[i].OpCode.OperandType != CilOperandType.InlineField) { continue; } if (!(instr[i].Operand is FieldDefinition field) || !FieldsInModule.Contains(field)) { continue; } // Check if dictionary already contains a local for the field, if not create a new one and add it to the dictionary if (!CreatedLocals.TryGetValue(field, out var createdLocal)) { createdLocal = new CilLocalVariable(field.Signature.FieldType); method.CilMethodBody.LocalVariables.Add(createdLocal); CreatedLocals.Add(field, createdLocal); } // Get local from dictionary instr[i].OpCode = GetOpCode(instr[i].OpCode.Code); instr[i].Operand = createdLocal; _count++; } instr.OptimizeMacros(); } }
public override void Execute(Context context, IEnumerable <MetadataMember> targets) { foreach (var Pairs in L2FieldProtection.L2FKey) { var Cache = new Dictionary <IFieldDescriptor, CilLocalVariable>(); var IL = Pairs.Key.CilMethodBody.Instructions; for (int x = 0; x < IL.Count; x++) { CilInstruction Instr = IL[x]; if ((Instr.IsCode(CilCode.Ldsfld) || Instr.IsCode(CilCode.Stsfld) || Instr.IsCode(CilCode.Ldsflda)) && Pairs.Value.Contains(Instr.Operand as IFieldDescriptor)) { IFieldDescriptor Field = Pairs.Value.SingleOrDefault(q => q == Instr.Operand as IFieldDescriptor); /* Thanks Linq :^) */ if (Field == null) { continue; } var NewLocal = new CilLocalVariable(context.Importer.ImportTypeSignature(Field.Signature.FieldType)); Instr.OpCode = Instr.OpCode.Code switch { CilCode.Ldsfld => CilOpCodes.Ldloc, CilCode.Stsfld => CilOpCodes.Stloc, CilCode.Ldsflda => CilOpCodes.Ldloca, _ => throw new ArgumentOutOfRangeException(nameof(Instr.OpCode)) }; if (!Cache.ContainsKey(Field)) { Pairs.Key.CilMethodBody.LocalVariables.Add(NewLocal); Cache.Add(Field, NewLocal); } else { NewLocal = Cache[Field]; } Instr.Operand = NewLocal; } } Pairs.Value.ToArray().ToList().ForEach(x => ((TypeDefinition)x.DeclaringType)?.Fields?.Remove(x.Resolve() ?? (FieldDefinition)x)); /* Performance Is Meh. */ } } }
public void NoIndex() { var variable = new CilLocalVariable(_module.CorLibTypeFactory.Object); Assert.Equal(-1, variable.Index); }
/// <summary> /// Creates a new CIL variable. /// </summary> /// <param name="variable">The underlying variable object.</param> public CilVariable(CilLocalVariable variable) { Variable = variable ?? throw new ArgumentNullException(nameof(variable)); }