private IEnumerable <Instruction> CopyArray(PropertyDefinition property) { var type = ((ArrayType)property.PropertyType).GetElementType(); var loopStart = Instruction.Create(OpCodes.Nop); var index = NewVariable(TypeSystem.Int32Definition); var conditionStart = Instruction.Create(OpCodes.Ldloc, index); var list = new List <Instruction> { // init empty array Instruction.Create(OpCodes.Ldarg_0), Instruction.Create(OpCodes.Ldarg_1), Instruction.Create(OpCodes.Callvirt, property.GetMethod), Instruction.Create(OpCodes.Ldlen), Instruction.Create(OpCodes.Conv_I4), Instruction.Create(OpCodes.Newarr, type), property.CreateSetInstruction(), Instruction.Create(OpCodes.Ldc_I4_0), // init index Instruction.Create(OpCodes.Stloc, index), Instruction.Create(OpCodes.Br_S, conditionStart), loopStart }; list.AddRange(CopyArrayItem(property, type.Resolve(), index)); // increment index list.Add(Instruction.Create(OpCodes.Ldloc, index)); list.Add(Instruction.Create(OpCodes.Ldc_I4_1)); list.Add(Instruction.Create(OpCodes.Add)); list.Add(Instruction.Create(OpCodes.Stloc, index)); // condition list.Add(conditionStart); list.Add(Instruction.Create(OpCodes.Ldarg_1)); list.Add(Instruction.Create(OpCodes.Callvirt, property.GetMethod)); list.Add(Instruction.Create(OpCodes.Ldlen)); list.Add(Instruction.Create(OpCodes.Conv_I4)); list.Add(Instruction.Create(OpCodes.Clt)); // loop end list.Add(Instruction.Create(OpCodes.Brtrue_S, loopStart)); return(list); }
private bool TryCopy(PropertyDefinition property, out IEnumerable <Instruction> instructions) { if (property.AnyAttribute(IgnoreDuringDeepCopyAttribute)) { property.CustomAttributes.Remove(property.SingleAttribute(IgnoreDuringDeepCopyAttribute)); instructions = null; return(false); } if (property.GetMethod == null || property.SetMethod == null && property.GetBackingField() == null) { instructions = null; return(false); } if (property.AnyAttribute(DeepCopyByReferenceAttribute)) { property.CustomAttributes.Remove(property.SingleAttribute(DeepCopyByReferenceAttribute)); instructions = new[] { Instruction.Create(OpCodes.Ldarg_0), Instruction.Create(OpCodes.Ldarg_1), Instruction.Create(OpCodes.Callvirt, property.GetMethod), property.CreateSetInstruction() }; return(true); } var source = ValueSource.New().Property(property); var target = ValueTarget.New().Property(property); var list = new List <Instruction>(); instructions = list; if (property.PropertyType.IsArray) { using (new IfNotNull(list, source)) list.AddRange(CopyArray(property)); return(true); } instructions = Copy(property.PropertyType, source, target); return(true); }
public void Dispose() { if (_instructions == null) { throw new InvalidOperationException(); } if (_next != null) { _instructions.Add(_next); } if (_index != null) { _instructions.Add(Instruction.Create(OpCodes.Stelem_Ref)); } else if (_property != null) { _instructions.Add(_property.CreateSetInstruction()); } else if (_call != null) { _instructions.Add(Instruction.Create(OpCodes.Call, _call)); } else if (_callvirt != null) { _instructions.Add(Instruction.Create(OpCodes.Callvirt, _callvirt)); } else if (_variable != null) { _instructions.Add(Instruction.Create(OpCodes.Stloc, _variable)); } foreach (var code in _added) { _instructions.Add(Instruction.Create(code)); } _instructions = null; _next = null; }