Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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;
        }