protected override void EmitRead(CompilerContext ctx, Local valueFrom)
 {
     using (Local localWithValue = ctx.GetLocalWithValue(this.ExpectedType, valueFrom))
     {
         if (this.Tail.RequiresOldValue)
         {
             ctx.LoadAddress(localWithValue, this.ExpectedType);
             ctx.LoadValue(this.field);
         }
         ctx.ReadNullCheckedTail(this.field.FieldType, this.Tail, null);
         if (this.Tail.ReturnsValue)
         {
             using (Local local = new Local(ctx, this.field.FieldType))
             {
                 ctx.StoreValue(local);
                 if (!this.field.FieldType.IsValueType)
                 {
                     CodeLabel codeLabel = ctx.DefineLabel();
                     ctx.LoadValue(local);
                     ctx.BranchIfFalse(codeLabel, true);
                     ctx.LoadAddress(localWithValue, this.ExpectedType);
                     ctx.LoadValue(local);
                     ctx.StoreValue(this.field);
                     ctx.MarkLabel(codeLabel);
                 }
                 else
                 {
                     ctx.LoadAddress(localWithValue, this.ExpectedType);
                     ctx.LoadValue(local);
                     ctx.StoreValue(this.field);
                 }
             }
         }
     }
 }
Example #2
0
        protected override void EmitRead(CompilerContext ctx, Local valueFrom)
        {
            bool flag;

            SanityCheck(ctx.Model, this.property, base.Tail, out flag, ctx.NonPublic, ctx.AllowInternal(this.property));
            if (this.ExpectedType.IsValueType && (valueFrom == null))
            {
                throw new InvalidOperationException("Attempt to mutate struct on the head of the stack; changes would be lost");
            }
            ctx.LoadAddress(valueFrom, this.ExpectedType);
            if (flag && base.Tail.RequiresOldValue)
            {
                ctx.CopyValue();
            }
            if (base.Tail.RequiresOldValue)
            {
                ctx.LoadValue(this.property);
            }
            Type propertyType = this.property.PropertyType;

            ctx.ReadNullCheckedTail(propertyType, base.Tail, null);
            if (flag)
            {
                CodeLabel label  = new CodeLabel();
                CodeLabel label2 = new CodeLabel();
                if (!propertyType.IsValueType)
                {
                    ctx.CopyValue();
                    label  = ctx.DefineLabel();
                    label2 = ctx.DefineLabel();
                    ctx.BranchIfFalse(label, true);
                }
                if (this.shadowSetter == null)
                {
                    ctx.StoreValue(this.property);
                }
                else
                {
                    ctx.EmitCall(this.shadowSetter);
                }
                if (!propertyType.IsValueType)
                {
                    ctx.Branch(label2, true);
                    ctx.MarkLabel(label);
                    ctx.DiscardValue();
                    ctx.DiscardValue();
                    ctx.MarkLabel(label2);
                }
            }
            else if (base.Tail.ReturnsValue)
            {
                ctx.DiscardValue();
            }
        }
Example #3
0
        protected override void EmitRead(CompilerContext ctx, Local valueFrom)
        {
            bool flag;

            PropertyDecorator.SanityCheck(ctx.Model, this.property, this.Tail, out flag, ctx.NonPublic, ctx.AllowInternal(this.property));
            if (this.ExpectedType.IsValueType && valueFrom == null)
            {
                throw new InvalidOperationException("Attempt to mutate struct on the head of the stack; changes would be lost");
            }
            using (Local localWithValue = ctx.GetLocalWithValue(this.ExpectedType, valueFrom))
            {
                if (this.Tail.RequiresOldValue)
                {
                    ctx.LoadAddress(localWithValue, this.ExpectedType);
                    ctx.LoadValue(this.property);
                }
                Type propertyType = this.property.PropertyType;
                ctx.ReadNullCheckedTail(propertyType, this.Tail, null);
                if (flag)
                {
                    using (Local local = new Local(ctx, this.property.PropertyType))
                    {
                        ctx.StoreValue(local);
                        CodeLabel codeLabel = new CodeLabel();
                        if (!propertyType.IsValueType)
                        {
                            codeLabel = ctx.DefineLabel();
                            ctx.LoadValue(local);
                            ctx.BranchIfFalse(codeLabel, true);
                        }
                        ctx.LoadAddress(localWithValue, this.ExpectedType);
                        ctx.LoadValue(local);
                        if (this.shadowSetter != null)
                        {
                            ctx.EmitCall(this.shadowSetter);
                        }
                        else
                        {
                            ctx.StoreValue(this.property);
                        }
                        if (!propertyType.IsValueType)
                        {
                            ctx.MarkLabel(codeLabel);
                        }
                    }
                }
                else if (this.Tail.ReturnsValue)
                {
                    ctx.DiscardValue();
                }
            }
        }
 protected override void EmitWrite(CompilerContext ctx, Local valueFrom)
 {
     if (this.getSpecified == null)
     {
         this.Tail.EmitWrite(ctx, valueFrom);
         return;
     }
     using (Local localWithValue = ctx.GetLocalWithValue(this.ExpectedType, valueFrom))
     {
         ctx.LoadAddress(localWithValue, this.ExpectedType);
         ctx.EmitCall(this.getSpecified);
         CodeLabel codeLabel = ctx.DefineLabel();
         ctx.BranchIfFalse(codeLabel, false);
         this.Tail.EmitWrite(ctx, localWithValue);
         ctx.MarkLabel(codeLabel);
     }
 }
Example #5
0
 internal static void EmitReadList(CompilerContext ctx, Local list, IProtoSerializer tail, MethodInfo add, WireType packedWireType, bool castListForAdd)
 {
     using (Local local = new Local(ctx, ctx.MapType(typeof(int))))
     {
         CodeLabel codeLabel = (packedWireType == WireType.None ? new CodeLabel() : ctx.DefineLabel());
         if (packedWireType != WireType.None)
         {
             ctx.LoadReaderWriter();
             ctx.LoadValue(typeof(ProtoReader).GetProperty("WireType"));
             ctx.LoadValue(2);
             ctx.BranchIfEqual(codeLabel, false);
         }
         ctx.LoadReaderWriter();
         ctx.LoadValue(typeof(ProtoReader).GetProperty("FieldNumber"));
         ctx.StoreValue(local);
         CodeLabel codeLabel1 = ctx.DefineLabel();
         ctx.MarkLabel(codeLabel1);
         ListDecorator.EmitReadAndAddItem(ctx, list, tail, add, castListForAdd);
         ctx.LoadReaderWriter();
         ctx.LoadValue(local);
         ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("TryReadFieldHeader"));
         ctx.BranchIfTrue(codeLabel1, false);
         if (packedWireType != WireType.None)
         {
             CodeLabel codeLabel2 = ctx.DefineLabel();
             ctx.Branch(codeLabel2, false);
             ctx.MarkLabel(codeLabel);
             ctx.LoadReaderWriter();
             ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("StartSubItem"));
             CodeLabel codeLabel3 = ctx.DefineLabel();
             CodeLabel codeLabel4 = ctx.DefineLabel();
             ctx.MarkLabel(codeLabel3);
             ctx.LoadValue((int)packedWireType);
             ctx.LoadReaderWriter();
             ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("HasSubValue"));
             ctx.BranchIfFalse(codeLabel4, false);
             ListDecorator.EmitReadAndAddItem(ctx, list, tail, add, castListForAdd);
             ctx.Branch(codeLabel3, false);
             ctx.MarkLabel(codeLabel4);
             ctx.LoadReaderWriter();
             ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("EndSubItem"));
             ctx.MarkLabel(codeLabel2);
         }
     }
 }
Example #6
0
        private void WriteFieldHandler(CompilerContext ctx, Type expected, Local loc, CodeLabel handler, CodeLabel @continue, IProtoSerializer serializer)
        {
            ctx.MarkLabel(handler);
            Type expectedType = serializer.ExpectedType;

            if (expectedType == this.forType)
            {
                this.EmitCreateIfNull(ctx, loc);
                serializer.EmitRead(ctx, loc);
            }
            else
            {
                RuntimeTypeModel model = (RuntimeTypeModel)ctx.Model;
                if (((IProtoTypeSerializer)serializer).CanCreateInstance())
                {
                    CodeLabel label = ctx.DefineLabel();
                    ctx.LoadValue(loc);
                    ctx.BranchIfFalse(label, false);
                    ctx.LoadValue(loc);
                    ctx.TryCast(expectedType);
                    ctx.BranchIfTrue(label, false);
                    ctx.LoadReaderWriter();
                    ctx.LoadValue(loc);
                    ((IProtoTypeSerializer)serializer).EmitCreateInstance(ctx);
                    ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("Merge"));
                    ctx.Cast(expected);
                    ctx.StoreValue(loc);
                    ctx.MarkLabel(label);
                }
                ctx.LoadValue(loc);
                ctx.Cast(expectedType);
                serializer.EmitRead(ctx, null);
            }
            if (serializer.ReturnsValue)
            {
                ctx.StoreValue(loc);
            }
            ctx.Branch(@continue, false);
        }
Example #7
0
 protected override void EmitWrite(CompilerContext ctx, Local valueFrom)
 {
     using (Local localWithValue = ctx.GetLocalWithValue(this.expectedType, valueFrom))
     {
         using (Local local = new Local(ctx, ctx.MapType(typeof(SubItemToken))))
         {
             ctx.LoadNullRef();
             ctx.LoadReaderWriter();
             ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("StartSubItem"));
             ctx.StoreValue(local);
             if (!this.expectedType.IsValueType)
             {
                 ctx.LoadValue(localWithValue);
             }
             else
             {
                 ctx.LoadAddress(localWithValue, this.expectedType);
                 ctx.LoadValue(this.expectedType.GetProperty("HasValue"));
             }
             CodeLabel codeLabel = ctx.DefineLabel();
             ctx.BranchIfFalse(codeLabel, false);
             if (!this.expectedType.IsValueType)
             {
                 ctx.LoadValue(localWithValue);
             }
             else
             {
                 ctx.LoadAddress(localWithValue, this.expectedType);
                 ctx.EmitCall(this.expectedType.GetMethod("GetValueOrDefault", Helpers.EmptyTypes));
             }
             this.Tail.EmitWrite(ctx, null);
             ctx.MarkLabel(codeLabel);
             ctx.LoadValue(local);
             ctx.LoadReaderWriter();
             ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("EndSubItem"));
         }
     }
 }
Example #8
0
        private void EmitBranchIfDefaultValue(CompilerContext ctx, CodeLabel label)
        {
            Type expectedType = this.ExpectedType;

            switch (Helpers.GetTypeCode(expectedType))
            {
            case ProtoTypeCode.Boolean:
                if (!((bool)this.defaultValue))
                {
                    ctx.BranchIfFalse(label, false);
                    return;
                }
                ctx.BranchIfTrue(label, false);
                return;

            case ProtoTypeCode.Char:
                if (((char)this.defaultValue) != '\0')
                {
                    ctx.LoadValue((int)((char)this.defaultValue));
                    this.EmitBeq(ctx, label, expectedType);
                    return;
                }
                ctx.BranchIfFalse(label, false);
                return;

            case ProtoTypeCode.SByte:
                if (((sbyte)this.defaultValue) != 0)
                {
                    ctx.LoadValue((int)((sbyte)this.defaultValue));
                    this.EmitBeq(ctx, label, expectedType);
                    return;
                }
                ctx.BranchIfFalse(label, false);
                return;

            case ProtoTypeCode.Byte:
                if (((byte)this.defaultValue) != 0)
                {
                    ctx.LoadValue((int)((byte)this.defaultValue));
                    this.EmitBeq(ctx, label, expectedType);
                    return;
                }
                ctx.BranchIfFalse(label, false);
                return;

            case ProtoTypeCode.Int16:
                if (((short)this.defaultValue) != 0)
                {
                    ctx.LoadValue((int)((short)this.defaultValue));
                    this.EmitBeq(ctx, label, expectedType);
                    return;
                }
                ctx.BranchIfFalse(label, false);
                return;

            case ProtoTypeCode.UInt16:
                if (((ushort)this.defaultValue) != 0)
                {
                    ctx.LoadValue((int)((ushort)this.defaultValue));
                    this.EmitBeq(ctx, label, expectedType);
                    return;
                }
                ctx.BranchIfFalse(label, false);
                return;

            case ProtoTypeCode.Int32:
                if (((int)this.defaultValue) != 0)
                {
                    ctx.LoadValue((int)this.defaultValue);
                    this.EmitBeq(ctx, label, expectedType);
                    return;
                }
                ctx.BranchIfFalse(label, false);
                return;

            case ProtoTypeCode.UInt32:
                if (((uint)this.defaultValue) != 0)
                {
                    ctx.LoadValue((int)((uint)this.defaultValue));
                    this.EmitBeq(ctx, label, expectedType);
                    return;
                }
                ctx.BranchIfFalse(label, false);
                return;

            case ProtoTypeCode.Int64:
                ctx.LoadValue((long)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;

            case ProtoTypeCode.UInt64:
                ctx.LoadValue((long)((ulong)this.defaultValue));
                this.EmitBeq(ctx, label, expectedType);
                return;

            case ProtoTypeCode.Single:
                ctx.LoadValue((float)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;

            case ProtoTypeCode.Double:
                ctx.LoadValue((double)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;

            case ProtoTypeCode.Decimal:
            {
                decimal defaultValue = (decimal)this.defaultValue;
                ctx.LoadValue(defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;
            }

            case ProtoTypeCode.DateTime:
                ctx.LoadValue(((DateTime)this.defaultValue).ToBinary());
                ctx.EmitCall(ctx.MapType(typeof(DateTime)).GetMethod("FromBinary"));
                this.EmitBeq(ctx, label, expectedType);
                return;

            case ProtoTypeCode.String:
                ctx.LoadValue((string)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;

            case ProtoTypeCode.TimeSpan:
            {
                TimeSpan span = (TimeSpan)this.defaultValue;
                if (!(span == TimeSpan.Zero))
                {
                    ctx.LoadValue(span.Ticks);
                    ctx.EmitCall(ctx.MapType(typeof(TimeSpan)).GetMethod("FromTicks"));
                    break;
                }
                ctx.LoadValue(typeof(TimeSpan).GetField("Zero"));
                break;
            }

            case ProtoTypeCode.Guid:
                ctx.LoadValue((Guid)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;

            default:
                throw new NotSupportedException("Type cannot be represented as a default value: " + expectedType.FullName);
            }
            this.EmitBeq(ctx, label, expectedType);
        }
Example #9
0
        public void EmitRead(CompilerContext ctx, Local incoming)
        {
            using (Local local = ctx.GetLocalWithValue(this.ExpectedType, incoming))
            {
                Local[] localArray = new Local[this.members.Length];
                try
                {
                    for (int i = 0; i < localArray.Length; i++)
                    {
                        Type memberType = this.GetMemberType(i);
                        bool flag       = true;
                        localArray[i] = new Local(ctx, memberType);
                        if (this.ExpectedType.IsValueType)
                        {
                            continue;
                        }
                        if (memberType.IsValueType)
                        {
                            switch (Helpers.GetTypeCode(memberType))
                            {
                            case ProtoTypeCode.Boolean:
                            case ProtoTypeCode.SByte:
                            case ProtoTypeCode.Byte:
                            case ProtoTypeCode.Int16:
                            case ProtoTypeCode.UInt16:
                            case ProtoTypeCode.Int32:
                            case ProtoTypeCode.UInt32:
                                ctx.LoadValue(0);
                                goto Label_0108;

                            case ProtoTypeCode.Int64:
                            case ProtoTypeCode.UInt64:
                                ctx.LoadValue((long)0L);
                                goto Label_0108;

                            case ProtoTypeCode.Single:
                                ctx.LoadValue((float)0f);
                                goto Label_0108;

                            case ProtoTypeCode.Double:
                                ctx.LoadValue((double)0.0);
                                goto Label_0108;

                            case ProtoTypeCode.Decimal:
                                ctx.LoadValue((decimal)0M);
                                goto Label_0108;

                            case ProtoTypeCode.Guid:
                                ctx.LoadValue(Guid.Empty);
                                goto Label_0108;
                            }
                            ctx.LoadAddress(localArray[i], memberType);
                            ctx.EmitCtor(memberType);
                            flag = false;
                        }
                        else
                        {
                            ctx.LoadNullRef();
                        }
Label_0108:
                        if (flag)
                        {
                            ctx.StoreValue(localArray[i]);
                        }
                    }
                    CodeLabel label = this.ExpectedType.IsValueType ? new CodeLabel() : ctx.DefineLabel();
                    if (!this.ExpectedType.IsValueType)
                    {
                        ctx.LoadAddress(local, this.ExpectedType);
                        ctx.BranchIfFalse(label, false);
                    }
                    for (int j = 0; j < this.members.Length; j++)
                    {
                        ctx.LoadAddress(local, this.ExpectedType);
                        switch (this.members[j].MemberType)
                        {
                        case MemberTypes.Field:
                            ctx.LoadValue((FieldInfo)this.members[j]);
                            break;

                        case MemberTypes.Property:
                            ctx.LoadValue((PropertyInfo)this.members[j]);
                            break;
                        }
                        ctx.StoreValue(localArray[j]);
                    }
                    if (!this.ExpectedType.IsValueType)
                    {
                        ctx.MarkLabel(label);
                    }
                    using (Local local2 = new Local(ctx, ctx.MapType(typeof(int))))
                    {
                        CodeLabel label2 = ctx.DefineLabel();
                        CodeLabel label3 = ctx.DefineLabel();
                        CodeLabel label4 = ctx.DefineLabel();
                        ctx.Branch(label2, false);
                        CodeLabel[] jumpTable = new CodeLabel[this.members.Length];
                        for (int m = 0; m < this.members.Length; m++)
                        {
                            jumpTable[m] = ctx.DefineLabel();
                        }
                        ctx.MarkLabel(label3);
                        ctx.LoadValue(local2);
                        ctx.LoadValue(1);
                        ctx.Subtract();
                        ctx.Switch(jumpTable);
                        ctx.Branch(label4, false);
                        for (int n = 0; n < jumpTable.Length; n++)
                        {
                            ctx.MarkLabel(jumpTable[n]);
                            IProtoSerializer tail      = this.tails[n];
                            Local            valueFrom = tail.RequiresOldValue ? localArray[n] : null;
                            ctx.ReadNullCheckedTail(localArray[n].Type, tail, valueFrom);
                            if (tail.ReturnsValue)
                            {
                                if (localArray[n].Type.IsValueType)
                                {
                                    ctx.StoreValue(localArray[n]);
                                }
                                else
                                {
                                    CodeLabel label5 = ctx.DefineLabel();
                                    CodeLabel label6 = ctx.DefineLabel();
                                    ctx.CopyValue();
                                    ctx.BranchIfTrue(label5, true);
                                    ctx.DiscardValue();
                                    ctx.Branch(label6, true);
                                    ctx.MarkLabel(label5);
                                    ctx.StoreValue(localArray[n]);
                                    ctx.MarkLabel(label6);
                                }
                            }
                            ctx.Branch(label2, false);
                        }
                        ctx.MarkLabel(label4);
                        ctx.LoadReaderWriter();
                        ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField"));
                        ctx.MarkLabel(label2);
                        ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int)));
                        ctx.CopyValue();
                        ctx.StoreValue(local2);
                        ctx.LoadValue(0);
                        ctx.BranchIfGreater(label3, false);
                    }
                    for (int k = 0; k < localArray.Length; k++)
                    {
                        ctx.LoadValue(localArray[k]);
                    }
                    ctx.EmitCtor(this.ctor);
                    ctx.StoreValue(local);
                }
                finally
                {
                    for (int num6 = 0; num6 < localArray.Length; num6++)
                    {
                        if (localArray[num6] != null)
                        {
                            localArray[num6].Dispose();
                        }
                    }
                }
            }
        }
Example #10
0
        void IProtoSerializer.EmitRead(CompilerContext ctx, Local valueFrom)
        {
            Type expectedType = this.ExpectedType;

            using (Local local = ctx.GetLocalWithValue(expectedType, valueFrom))
            {
                using (Local local2 = new Local(ctx, ctx.MapType(typeof(int))))
                {
                    if (this.HasCallbacks(TypeModel.CallbackType.BeforeDeserialize))
                    {
                        if (this.ExpectedType.IsValueType)
                        {
                            this.EmitCallbackIfNeeded(ctx, local, TypeModel.CallbackType.BeforeDeserialize);
                        }
                        else
                        {
                            CodeLabel label = ctx.DefineLabel();
                            ctx.LoadValue(local);
                            ctx.BranchIfFalse(label, false);
                            this.EmitCallbackIfNeeded(ctx, local, TypeModel.CallbackType.BeforeDeserialize);
                            ctx.MarkLabel(label);
                        }
                    }
                    CodeLabel label2 = ctx.DefineLabel();
                    CodeLabel label3 = ctx.DefineLabel();
                    ctx.Branch(label2, false);
                    ctx.MarkLabel(label3);
                    BasicList.NodeEnumerator enumerator = BasicList.GetContiguousGroups(this.fieldNumbers, this.serializers).GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        BasicList.Group current = (BasicList.Group)enumerator.Current;
                        CodeLabel       label4  = ctx.DefineLabel();
                        int             count   = current.Items.Count;
                        if (count == 1)
                        {
                            ctx.LoadValue(local2);
                            ctx.LoadValue(current.First);
                            CodeLabel label5 = ctx.DefineLabel();
                            ctx.BranchIfEqual(label5, true);
                            ctx.Branch(label4, false);
                            this.WriteFieldHandler(ctx, expectedType, local, label5, label2, (IProtoSerializer)current.Items[0]);
                        }
                        else
                        {
                            ctx.LoadValue(local2);
                            ctx.LoadValue(current.First);
                            ctx.Subtract();
                            CodeLabel[] jumpTable = new CodeLabel[count];
                            for (int i = 0; i < count; i++)
                            {
                                jumpTable[i] = ctx.DefineLabel();
                            }
                            ctx.Switch(jumpTable);
                            ctx.Branch(label4, false);
                            for (int j = 0; j < count; j++)
                            {
                                this.WriteFieldHandler(ctx, expectedType, local, jumpTable[j], label2, (IProtoSerializer)current.Items[j]);
                            }
                        }
                        ctx.MarkLabel(label4);
                    }
                    this.EmitCreateIfNull(ctx, local);
                    ctx.LoadReaderWriter();
                    if (this.isExtensible)
                    {
                        ctx.LoadValue(local);
                        ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("AppendExtensionData"));
                    }
                    else
                    {
                        ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField"));
                    }
                    ctx.MarkLabel(label2);
                    ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int)));
                    ctx.CopyValue();
                    ctx.StoreValue(local2);
                    ctx.LoadValue(0);
                    ctx.BranchIfGreater(label3, false);
                    this.EmitCreateIfNull(ctx, local);
                    this.EmitCallbackIfNeeded(ctx, local, TypeModel.CallbackType.AfterDeserialize);
                    if ((valueFrom != null) && !local.IsSame(valueFrom))
                    {
                        ctx.LoadValue(local);
                        ctx.Cast(valueFrom.Type);
                        ctx.StoreValue(valueFrom);
                    }
                }
            }
        }
Example #11
0
        protected override void EmitRead(CompilerContext ctx, Local valueFrom)
        {
            Type type         = ctx.MapType(typeof(List <>)).MakeGenericType(new Type[] { this.itemType });
            Type expectedType = this.ExpectedType;

            using (Local local = this.AppendToCollection ? ctx.GetLocalWithValue(expectedType, valueFrom) : null)
            {
                using (Local local2 = new Local(ctx, expectedType))
                {
                    using (Local local3 = new Local(ctx, type))
                    {
                        ctx.EmitCtor(type);
                        ctx.StoreValue(local3);
                        ListDecorator.EmitReadList(ctx, local3, base.Tail, type.GetMethod("Add"), this.packedWireType, false);
                        using (Local local4 = this.AppendToCollection ? new Local(ctx, ctx.MapType(typeof(int))) : null)
                        {
                            Type[] types = new Type[] { ctx.MapType(typeof(Array)), ctx.MapType(typeof(int)) };
                            if (this.AppendToCollection)
                            {
                                ctx.LoadLength(local, true);
                                ctx.CopyValue();
                                ctx.StoreValue(local4);
                                ctx.LoadAddress(local3, type);
                                ctx.LoadValue(type.GetProperty("Count"));
                                ctx.Add();
                                ctx.CreateArray(this.itemType, null);
                                ctx.StoreValue(local2);
                                ctx.LoadValue(local4);
                                CodeLabel label = ctx.DefineLabel();
                                ctx.BranchIfFalse(label, true);
                                ctx.LoadValue(local);
                                ctx.LoadValue(local2);
                                ctx.LoadValue(0);
                                ctx.EmitCall(expectedType.GetMethod("CopyTo", types));
                                ctx.MarkLabel(label);
                                ctx.LoadValue(local3);
                                ctx.LoadValue(local2);
                                ctx.LoadValue(local4);
                            }
                            else
                            {
                                ctx.LoadAddress(local3, type);
                                ctx.LoadValue(type.GetProperty("Count"));
                                ctx.CreateArray(this.itemType, null);
                                ctx.StoreValue(local2);
                                ctx.LoadAddress(local3, type);
                                ctx.LoadValue(local2);
                                ctx.LoadValue(0);
                            }
                            types[0] = expectedType;
                            MethodInfo method = type.GetMethod("CopyTo", types);
                            if (method == null)
                            {
                                types[1] = ctx.MapType(typeof(Array));
                                method   = type.GetMethod("CopyTo", types);
                            }
                            ctx.EmitCall(method);
                        }
                        ctx.LoadValue(local2);
                    }
                }
            }
        }
Example #12
0
        private void EmitBranchIfDefaultValue(CompilerContext ctx, CodeLabel label)
        {
            Type          expectedType = this.ExpectedType;
            ProtoTypeCode typeCode     = Helpers.GetTypeCode(expectedType);

            switch (typeCode)
            {
            case ProtoTypeCode.Boolean:
            {
                if ((bool)this.defaultValue)
                {
                    ctx.BranchIfTrue(label, false);
                    return;
                }
                ctx.BranchIfFalse(label, false);
                return;
            }

            case ProtoTypeCode.Char:
            {
                if ((char)this.defaultValue == 0)
                {
                    ctx.BranchIfFalse(label, false);
                    return;
                }
                ctx.LoadValue((char)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;
            }

            case ProtoTypeCode.SByte:
            {
                if ((sbyte)this.defaultValue == 0)
                {
                    ctx.BranchIfFalse(label, false);
                    return;
                }
                ctx.LoadValue((sbyte)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;
            }

            case ProtoTypeCode.Byte:
            {
                if ((byte)this.defaultValue == 0)
                {
                    ctx.BranchIfFalse(label, false);
                    return;
                }
                ctx.LoadValue((int)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;
            }

            case ProtoTypeCode.Int16:
            {
                if ((short)this.defaultValue == 0)
                {
                    ctx.BranchIfFalse(label, false);
                    return;
                }
                ctx.LoadValue((short)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;
            }

            case ProtoTypeCode.UInt16:
            {
                if ((ushort)this.defaultValue == 0)
                {
                    ctx.BranchIfFalse(label, false);
                    return;
                }
                ctx.LoadValue((int)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;
            }

            case ProtoTypeCode.Int32:
            {
                if ((int)this.defaultValue == 0)
                {
                    ctx.BranchIfFalse(label, false);
                    return;
                }
                ctx.LoadValue((int)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;
            }

            case ProtoTypeCode.UInt32:
            {
                if ((uint)this.defaultValue == 0)
                {
                    ctx.BranchIfFalse(label, false);
                    return;
                }
                ctx.LoadValue((int)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;
            }

            case ProtoTypeCode.Int64:
            {
                ctx.LoadValue((long)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;
            }

            case ProtoTypeCode.UInt64:
            {
                ctx.LoadValue((long)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;
            }

            case ProtoTypeCode.Single:
            {
                ctx.LoadValue((float)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;
            }

            case ProtoTypeCode.Double:
            {
                ctx.LoadValue((double)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;
            }

            case ProtoTypeCode.Decimal:
            {
                ctx.LoadValue((decimal)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;
            }

            case ProtoTypeCode.DateTime:
            {
                ctx.LoadValue(((DateTime)this.defaultValue).ToBinary());
                ctx.EmitCall(ctx.MapType(typeof(DateTime)).GetMethod("FromBinary"));
                this.EmitBeq(ctx, label, expectedType);
                return;
            }

            case ProtoTypeCode.Unknown | ProtoTypeCode.DateTime:
            {
                throw new NotSupportedException(string.Concat("Type cannot be represented as a default value: ", expectedType.FullName));
            }

            case ProtoTypeCode.String:
            {
                ctx.LoadValue((string)this.defaultValue);
                this.EmitBeq(ctx, label, expectedType);
                return;
            }

            default:
            {
                switch (typeCode)
                {
                case ProtoTypeCode.TimeSpan:
                {
                    TimeSpan timeSpan = (TimeSpan)this.defaultValue;
                    if (timeSpan != TimeSpan.Zero)
                    {
                        ctx.LoadValue(timeSpan.Ticks);
                        ctx.EmitCall(ctx.MapType(typeof(TimeSpan)).GetMethod("FromTicks"));
                    }
                    else
                    {
                        ctx.LoadValue(typeof(TimeSpan).GetField("Zero"));
                    }
                    this.EmitBeq(ctx, label, expectedType);
                    return;
                }

                case ProtoTypeCode.ByteArray:
                {
                    throw new NotSupportedException(string.Concat("Type cannot be represented as a default value: ", expectedType.FullName));
                }

                case ProtoTypeCode.Guid:
                {
                    ctx.LoadValue((Guid)this.defaultValue);
                    this.EmitBeq(ctx, label, expectedType);
                    return;
                }

                default:
                {
                    throw new NotSupportedException(string.Concat("Type cannot be represented as a default value: ", expectedType.FullName));
                }
                }
                break;
            }
            }
        }
        protected override void EmitRead(CompilerContext ctx, Local valueFrom)
        {
            MethodInfo methodInfo;
            MethodInfo methodInfo1;
            Local      localWithValue;

            if (base.AppendToCollection)
            {
                localWithValue = ctx.GetLocalWithValue(this.ExpectedType, valueFrom);
            }
            else
            {
                localWithValue = null;
            }
            using (Local local = localWithValue)
            {
                using (Local local1 = new Local(ctx, this.builderFactory.ReturnType))
                {
                    ctx.EmitCall(this.builderFactory);
                    ctx.StoreValue(local1);
                    if (base.AppendToCollection)
                    {
                        CodeLabel codeLabel = ctx.DefineLabel();
                        if (!this.ExpectedType.IsValueType)
                        {
                            ctx.LoadValue(local);
                            ctx.BranchIfFalse(codeLabel, false);
                        }
                        PropertyInfo property = Helpers.GetProperty(this.ExpectedType, "Length", false) ?? Helpers.GetProperty(this.ExpectedType, "Count", false) ?? Helpers.GetProperty(ImmutableCollectionDecorator.ResolveIReadOnlyCollection(this.ExpectedType, this.Tail.ExpectedType), "Count", false);
                        ctx.LoadAddress(local, local.Type);
                        ctx.EmitCall(Helpers.GetGetMethod(property, false, false));
                        ctx.BranchIfFalse(codeLabel, false);
                        Type type = ctx.MapType(typeof(void));
                        if (this.addRange == null)
                        {
                            MethodInfo enumeratorInfo = base.GetEnumeratorInfo(ctx.Model, out methodInfo, out methodInfo1);
                            Type       returnType     = enumeratorInfo.ReturnType;
                            using (Local local2 = new Local(ctx, returnType))
                            {
                                ctx.LoadAddress(local, this.ExpectedType);
                                ctx.EmitCall(enumeratorInfo);
                                ctx.StoreValue(local2);
                                using (IDisposable disposable = ctx.Using(local2))
                                {
                                    CodeLabel codeLabel1 = ctx.DefineLabel();
                                    CodeLabel codeLabel2 = ctx.DefineLabel();
                                    ctx.Branch(codeLabel2, false);
                                    ctx.MarkLabel(codeLabel1);
                                    ctx.LoadAddress(local1, local1.Type);
                                    ctx.LoadAddress(local2, returnType);
                                    ctx.EmitCall(methodInfo1);
                                    ctx.EmitCall(this.@add);
                                    if ([email protected] != null && [email protected] != type)
                                    {
                                        ctx.DiscardValue();
                                    }
                                    ctx.MarkLabel(codeLabel2);
                                    ctx.LoadAddress(local2, returnType);
                                    ctx.EmitCall(methodInfo);
                                    ctx.BranchIfTrue(codeLabel1, false);
                                }
                            }
                        }
                        else
                        {
                            ctx.LoadValue(local1);
                            ctx.LoadValue(local);
                            ctx.EmitCall(this.addRange);
                            if (this.addRange.ReturnType != null && [email protected] != type)
                            {
                                ctx.DiscardValue();
                            }
                        }
                        ctx.MarkLabel(codeLabel);
                    }
                    ListDecorator.EmitReadList(ctx, local1, this.Tail, this.@add, this.packedWireType, false);
                    ctx.LoadAddress(local1, local1.Type);
                    ctx.EmitCall(this.finish);
                    if (this.ExpectedType != this.finish.ReturnType)
                    {
                        ctx.Cast(this.ExpectedType);
                    }
                }
            }
        }
        public void EmitRead(CompilerContext ctx, Local incoming)
        {
            Local local;

            using (Local localWithValue = ctx.GetLocalWithValue(this.ExpectedType, incoming))
            {
                Local[] localArray = new Local[(int)this.members.Length];
                try
                {
                    for (int i = 0; i < (int)localArray.Length; i++)
                    {
                        Type memberType = this.GetMemberType(i);
                        bool flag       = true;
                        localArray[i] = new Local(ctx, memberType);
                        if (!this.ExpectedType.IsValueType)
                        {
                            if (!memberType.IsValueType)
                            {
                                ctx.LoadNullRef();
                            }
                            else
                            {
                                ProtoTypeCode typeCode = Helpers.GetTypeCode(memberType);
                                switch (typeCode)
                                {
                                case ProtoTypeCode.Boolean:
                                case ProtoTypeCode.SByte:
                                case ProtoTypeCode.Byte:
                                case ProtoTypeCode.Int16:
                                case ProtoTypeCode.UInt16:
                                case ProtoTypeCode.Int32:
                                case ProtoTypeCode.UInt32:
                                {
                                    ctx.LoadValue(0);
                                    break;
                                }

                                case ProtoTypeCode.Char:
                                {
                                    ctx.LoadAddress(localArray[i], memberType);
                                    ctx.EmitCtor(memberType);
                                    flag = false;
                                    break;
                                }

                                case ProtoTypeCode.Int64:
                                case ProtoTypeCode.UInt64:
                                {
                                    ctx.LoadValue((long)0);
                                    break;
                                }

                                case ProtoTypeCode.Single:
                                {
                                    ctx.LoadValue(0f);
                                    break;
                                }

                                case ProtoTypeCode.Double:
                                {
                                    ctx.LoadValue(0);
                                    break;
                                }

                                case ProtoTypeCode.Decimal:
                                {
                                    ctx.LoadValue(new decimal(0));
                                    break;
                                }

                                default:
                                {
                                    if (typeCode == ProtoTypeCode.Guid)
                                    {
                                        ctx.LoadValue(Guid.Empty);
                                        break;
                                    }
                                    else
                                    {
                                        goto case ProtoTypeCode.Char;
                                    }
                                }
                                }
                            }
                            if (flag)
                            {
                                ctx.StoreValue(localArray[i]);
                            }
                        }
                    }
                    CodeLabel codeLabel = (this.ExpectedType.IsValueType ? new CodeLabel() : ctx.DefineLabel());
                    if (!this.ExpectedType.IsValueType)
                    {
                        ctx.LoadAddress(localWithValue, this.ExpectedType);
                        ctx.BranchIfFalse(codeLabel, false);
                    }
                    for (int j = 0; j < (int)this.members.Length; j++)
                    {
                        ctx.LoadAddress(localWithValue, this.ExpectedType);
                        MemberTypes memberType1 = this.members[j].MemberType;
                        if (memberType1 == MemberTypes.Field)
                        {
                            ctx.LoadValue((FieldInfo)this.members[j]);
                        }
                        else if (memberType1 == MemberTypes.Property)
                        {
                            ctx.LoadValue((PropertyInfo)this.members[j]);
                        }
                        ctx.StoreValue(localArray[j]);
                    }
                    if (!this.ExpectedType.IsValueType)
                    {
                        ctx.MarkLabel(codeLabel);
                    }
                    using (Local local1 = new Local(ctx, ctx.MapType(typeof(int))))
                    {
                        CodeLabel codeLabel1 = ctx.DefineLabel();
                        CodeLabel codeLabel2 = ctx.DefineLabel();
                        CodeLabel codeLabel3 = ctx.DefineLabel();
                        ctx.Branch(codeLabel1, false);
                        CodeLabel[] codeLabelArray = new CodeLabel[(int)this.members.Length];
                        for (int k = 0; k < (int)this.members.Length; k++)
                        {
                            codeLabelArray[k] = ctx.DefineLabel();
                        }
                        ctx.MarkLabel(codeLabel2);
                        ctx.LoadValue(local1);
                        ctx.LoadValue(1);
                        ctx.Subtract();
                        ctx.Switch(codeLabelArray);
                        ctx.Branch(codeLabel3, false);
                        for (int l = 0; l < (int)codeLabelArray.Length; l++)
                        {
                            ctx.MarkLabel(codeLabelArray[l]);
                            IProtoSerializer protoSerializer = this.tails[l];
                            if (protoSerializer.RequiresOldValue)
                            {
                                local = localArray[l];
                            }
                            else
                            {
                                local = null;
                            }
                            ctx.ReadNullCheckedTail(localArray[l].Type, protoSerializer, local);
                            if (protoSerializer.ReturnsValue)
                            {
                                if (!localArray[l].Type.IsValueType)
                                {
                                    CodeLabel codeLabel4 = ctx.DefineLabel();
                                    CodeLabel codeLabel5 = ctx.DefineLabel();
                                    ctx.CopyValue();
                                    ctx.BranchIfTrue(codeLabel4, true);
                                    ctx.DiscardValue();
                                    ctx.Branch(codeLabel5, true);
                                    ctx.MarkLabel(codeLabel4);
                                    ctx.StoreValue(localArray[l]);
                                    ctx.MarkLabel(codeLabel5);
                                }
                                else
                                {
                                    ctx.StoreValue(localArray[l]);
                                }
                            }
                            ctx.Branch(codeLabel1, false);
                        }
                        ctx.MarkLabel(codeLabel3);
                        ctx.LoadReaderWriter();
                        ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField"));
                        ctx.MarkLabel(codeLabel1);
                        ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int)));
                        ctx.CopyValue();
                        ctx.StoreValue(local1);
                        ctx.LoadValue(0);
                        ctx.BranchIfGreater(codeLabel2, false);
                    }
                    for (int m = 0; m < (int)localArray.Length; m++)
                    {
                        ctx.LoadValue(localArray[m]);
                    }
                    ctx.EmitCtor(this.ctor);
                    ctx.StoreValue(localWithValue);
                }
                finally
                {
                    for (int n = 0; n < (int)localArray.Length; n++)
                    {
                        if (localArray[n] != null)
                        {
                            localArray[n].Dispose();
                        }
                    }
                }
            }
        }