示例#1
0
 protected override void EmitRead(CompilerContext ctx, Local valueFrom)
 {
     using (Local localWithValue = ctx.GetLocalWithValue(this.expectedType, valueFrom))
     {
         using (Local local = new Local(ctx, ctx.MapType(typeof(SubItemToken))))
         {
             using (Local local1 = new Local(ctx, ctx.MapType(typeof(int))))
             {
                 ctx.LoadReaderWriter();
                 ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("StartSubItem"));
                 ctx.StoreValue(local);
                 CodeLabel codeLabel  = ctx.DefineLabel();
                 CodeLabel codeLabel1 = ctx.DefineLabel();
                 CodeLabel codeLabel2 = ctx.DefineLabel();
                 ctx.MarkLabel(codeLabel);
                 ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int)));
                 ctx.CopyValue();
                 ctx.StoreValue(local1);
                 ctx.LoadValue(1);
                 ctx.BranchIfEqual(codeLabel1, true);
                 ctx.LoadValue(local1);
                 ctx.LoadValue(1);
                 ctx.BranchIfLess(codeLabel2, false);
                 ctx.LoadReaderWriter();
                 ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField"));
                 ctx.Branch(codeLabel, true);
                 ctx.MarkLabel(codeLabel1);
                 if (this.Tail.RequiresOldValue)
                 {
                     if (!this.expectedType.IsValueType)
                     {
                         ctx.LoadValue(localWithValue);
                     }
                     else
                     {
                         ctx.LoadAddress(localWithValue, this.expectedType);
                         ctx.EmitCall(this.expectedType.GetMethod("GetValueOrDefault", Helpers.EmptyTypes));
                     }
                 }
                 this.Tail.EmitRead(ctx, null);
                 if (this.expectedType.IsValueType)
                 {
                     Type   type         = this.expectedType;
                     Type[] expectedType = new Type[] { this.Tail.ExpectedType };
                     ctx.EmitCtor(type, expectedType);
                 }
                 ctx.StoreValue(localWithValue);
                 ctx.Branch(codeLabel, false);
                 ctx.MarkLabel(codeLabel2);
                 ctx.LoadValue(local);
                 ctx.LoadReaderWriter();
                 ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("EndSubItem"));
                 ctx.LoadValue(localWithValue);
             }
         }
     }
 }
示例#2
0
 void ProtoBuf.Serializers.IProtoSerializer.EmitRead(CompilerContext ctx, Local valueFrom)
 {
     ctx.EmitBasicRead("ReadBoolean", this.ExpectedType);
 }
示例#3
0
 void IProtoSerializer.EmitRead(CompilerContext ctx, Local valueFrom)
 {
     ctx.EmitBasicRead("ReadSByte", this.ExpectedType);
 }
 void ProtoBuf.Serializers.IProtoSerializer.EmitRead(CompilerContext ctx, Local valueFrom)
 {
     ctx.EmitBasicRead(ctx.MapType(typeof(BclHelpers)), "ReadGuid", this.ExpectedType);
 }
示例#5
0
        protected override void EmitRead(CompilerContext ctx, Local valueFrom)
        {
            using (Compiler.Local list = AppendToCollection ? ctx.GetLocalWithValue(ExpectedType, valueFrom)
                : new Compiler.Local(ctx, typeof(TDictionary)))
                using (Compiler.Local token = new Compiler.Local(ctx, typeof(SubItemToken)))
                    using (Compiler.Local key = new Compiler.Local(ctx, typeof(TKey)))
                        using (Compiler.Local @value = new Compiler.Local(ctx, typeof(TValue)))
                            using (Compiler.Local fieldNumber = new Compiler.Local(ctx, typeof(int)))
                            {
                                if (!AppendToCollection)
                                { // always new
                                    ctx.LoadNullRef();
                                    ctx.StoreValue(list);
                                }
                                if (concreteType != null)
                                {
                                    ctx.LoadValue(list);
                                    Compiler.CodeLabel notNull = ctx.DefineLabel();
                                    ctx.BranchIfTrue(notNull, true);
                                    ctx.EmitCtor(concreteType);
                                    ctx.StoreValue(list);
                                    ctx.MarkLabel(notNull);
                                }

                                var redoFromStart = ctx.DefineLabel();
                                ctx.MarkLabel(redoFromStart);

                                // key = default(TKey); value = default(TValue);
                                if (typeof(TKey) == typeof(string))
                                {
                                    ctx.LoadValue("");
                                    ctx.StoreValue(key);
                                }
                                else
                                {
                                    ctx.InitLocal(typeof(TKey), key);
                                }
                                if (typeof(TValue) == typeof(string))
                                {
                                    ctx.LoadValue("");
                                    ctx.StoreValue(value);
                                }
                                else
                                {
                                    ctx.InitLocal(typeof(TValue), @value);
                                }

                                // token = ProtoReader.StartSubItem(reader);
                                ctx.LoadReader(true);
                                ctx.EmitCall(typeof(ProtoReader).GetMethod("StartSubItem", ProtoReader.State.ReaderStateTypeArray));
                                ctx.StoreValue(token);

                                Compiler.CodeLabel @continue = ctx.DefineLabel(), processField = ctx.DefineLabel();
                                // while ...
                                ctx.Branch(@continue, false);

                                // switch(fieldNumber)
                                ctx.MarkLabel(processField);
                                ctx.LoadValue(fieldNumber);
                                CodeLabel @default = ctx.DefineLabel(), one = ctx.DefineLabel(), two = ctx.DefineLabel();
                                ctx.Switch(new[] { @default, one, two }); // zero based, hence explicit 0

                                // case 0: default: reader.SkipField();
                                ctx.MarkLabel(@default);
                                ctx.LoadReader(true);
                                ctx.EmitCall(typeof(ProtoReader).GetMethod("SkipField", ProtoReader.State.StateTypeArray));
                                ctx.Branch(@continue, false);

                                // case 1: key = ...
                                ctx.MarkLabel(one);
                                keyTail.EmitRead(ctx, null);
                                ctx.StoreValue(key);
                                ctx.Branch(@continue, false);

                                // case 2: value = ...
                                ctx.MarkLabel(two);
                                Tail.EmitRead(ctx, Tail.RequiresOldValue ? @value : null);
                                ctx.StoreValue(value);

                                // (fieldNumber = reader.ReadFieldHeader()) > 0
                                ctx.MarkLabel(@continue);
                                ctx.EmitBasicRead("ReadFieldHeader", typeof(int));
                                ctx.CopyValue();
                                ctx.StoreValue(fieldNumber);
                                ctx.LoadValue(0);
                                ctx.BranchIfGreater(processField, false);

                                // ProtoReader.EndSubItem(token, reader);
                                ctx.LoadValue(token);
                                ctx.LoadReader(true);
                                ctx.EmitCall(typeof(ProtoReader).GetMethod("EndSubItem",
                                                                           new[] { typeof(SubItemToken), typeof(ProtoReader), ProtoReader.State.ByRefStateType }));

                                // list[key] = value;
                                ctx.LoadAddress(list, ExpectedType);
                                ctx.LoadValue(key);
                                ctx.LoadValue(@value);
                                ctx.EmitCall(indexerSet);

                                // while reader.TryReadFieldReader(fieldNumber)
                                ctx.LoadReader(true);
                                ctx.LoadValue(this.fieldNumber);
                                ctx.EmitCall(typeof(ProtoReader).GetMethod("TryReadFieldHeader",
                                                                           new[] { ProtoReader.State.ByRefStateType, typeof(int) }));
                                ctx.BranchIfTrue(redoFromStart, false);

                                if (ReturnsValue)
                                {
                                    ctx.LoadValue(list);
                                }
                            }
        }
示例#6
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();
                        }
                    }
                }
            }
        }
示例#7
0
        void IProtoSerializer.EmitRead(CompilerContext ctx, Local valueFrom)
        {
            ProtoTypeCode typeCode = this.GetTypeCode();

            if (this.map == null)
            {
                ctx.EmitBasicRead("ReadInt32", ctx.MapType(typeof(int)));
                ctx.ConvertFromInt32(typeCode, false);
            }
            else
            {
                int[]    keys   = new int[this.map.Length];
                object[] values = new object[this.map.Length];
                for (int i = 0; i < this.map.Length; i++)
                {
                    keys[i]   = this.map[i].WireValue;
                    values[i] = this.map[i].RawValue;
                }
                using (Local local = new Local(ctx, this.ExpectedType))
                {
                    using (Local local2 = new Local(ctx, ctx.MapType(typeof(int))))
                    {
                        ctx.EmitBasicRead("ReadInt32", ctx.MapType(typeof(int)));
                        ctx.StoreValue(local2);
                        CodeLabel label = ctx.DefineLabel();
                        BasicList.NodeEnumerator enumerator = BasicList.GetContiguousGroups(keys, values).GetEnumerator();
                        while (enumerator.MoveNext())
                        {
                            BasicList.Group current = (BasicList.Group)enumerator.Current;
                            CodeLabel       label2  = ctx.DefineLabel();
                            int             count   = current.Items.Count;
                            if (count == 1)
                            {
                                ctx.LoadValue(local2);
                                ctx.LoadValue(current.First);
                                CodeLabel label3 = ctx.DefineLabel();
                                ctx.BranchIfEqual(label3, true);
                                ctx.Branch(label2, false);
                                WriteEnumValue(ctx, typeCode, label3, label, current.Items[0], local);
                            }
                            else
                            {
                                ctx.LoadValue(local2);
                                ctx.LoadValue(current.First);
                                ctx.Subtract();
                                CodeLabel[] jumpTable = new CodeLabel[count];
                                for (int j = 0; j < count; j++)
                                {
                                    jumpTable[j] = ctx.DefineLabel();
                                }
                                ctx.Switch(jumpTable);
                                ctx.Branch(label2, false);
                                for (int k = 0; k < count; k++)
                                {
                                    WriteEnumValue(ctx, typeCode, jumpTable[k], label, current.Items[k], local);
                                }
                            }
                            ctx.MarkLabel(label2);
                        }
                        ctx.LoadReaderWriter();
                        ctx.LoadValue(this.ExpectedType);
                        ctx.LoadValue(local2);
                        ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("ThrowEnumException"));
                        ctx.MarkLabel(label);
                        ctx.LoadValue(local);
                    }
                }
            }
        }
示例#8
0
 void ProtoBuf.Serializers.IProtoSerializer.EmitRead(CompilerContext ctx, Local valueFrom)
 {
     ctx.EmitBasicRead("ReadUInt16", ctx.MapType(typeof(ushort)));
 }
示例#9
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);
                    }
                }
            }
        }
示例#10
0
 void IProtoSerializer.EmitRead(CompilerContext ctx, Local valueFrom)
 {
     ctx.EmitBasicRead("ReadUInt32", ctx.MapType(typeof(uint)));
 }
示例#11
0
        void ProtoBuf.Serializers.IProtoSerializer.EmitRead(CompilerContext ctx, Local valueFrom)
        {
            ProtoTypeCode typeCode = this.GetTypeCode();

            if (this.map == null)
            {
                ctx.EmitBasicRead("ReadInt32", ctx.MapType(typeof(int)));
                ctx.ConvertFromInt32(typeCode, false);
                return;
            }
            int[]    wireValue = new int[(int)this.map.Length];
            object[] rawValue  = new object[(int)this.map.Length];
            for (int i = 0; i < (int)this.map.Length; i++)
            {
                wireValue[i] = this.map[i].WireValue;
                rawValue[i]  = this.map[i].RawValue;
            }
            using (Local local = new Local(ctx, this.ExpectedType))
            {
                using (Local local1 = new Local(ctx, ctx.MapType(typeof(int))))
                {
                    ctx.EmitBasicRead("ReadInt32", ctx.MapType(typeof(int)));
                    ctx.StoreValue(local1);
                    CodeLabel codeLabel = ctx.DefineLabel();
                    BasicList.NodeEnumerator enumerator = BasicList.GetContiguousGroups(wireValue, rawValue).GetEnumerator();
                    while (enumerator.MoveNext())
                    {
                        BasicList.Group current    = (BasicList.Group)enumerator.Current;
                        CodeLabel       codeLabel1 = ctx.DefineLabel();
                        int             count      = current.Items.Count;
                        if (count != 1)
                        {
                            ctx.LoadValue(local1);
                            ctx.LoadValue(current.First);
                            ctx.Subtract();
                            CodeLabel[] codeLabelArray = new CodeLabel[count];
                            for (int j = 0; j < count; j++)
                            {
                                codeLabelArray[j] = ctx.DefineLabel();
                            }
                            ctx.Switch(codeLabelArray);
                            ctx.Branch(codeLabel1, false);
                            for (int k = 0; k < count; k++)
                            {
                                EnumSerializer.WriteEnumValue(ctx, typeCode, codeLabelArray[k], codeLabel, current.Items[k], local);
                            }
                        }
                        else
                        {
                            ctx.LoadValue(local1);
                            ctx.LoadValue(current.First);
                            CodeLabel codeLabel2 = ctx.DefineLabel();
                            ctx.BranchIfEqual(codeLabel2, true);
                            ctx.Branch(codeLabel1, false);
                            EnumSerializer.WriteEnumValue(ctx, typeCode, codeLabel2, codeLabel, current.Items[0], local);
                        }
                        ctx.MarkLabel(codeLabel1);
                    }
                    ctx.LoadReaderWriter();
                    ctx.LoadValue(this.ExpectedType);
                    ctx.LoadValue(local1);
                    ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("ThrowEnumException"));
                    ctx.MarkLabel(codeLabel);
                    ctx.LoadValue(local);
                }
            }
        }
        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();
                        }
                    }
                }
            }
        }
示例#13
0
 void ProtoBuf.Serializers.IProtoSerializer.EmitRead(CompilerContext ctx, Local valueFrom)
 {
     ctx.EmitBasicRead("ReadString", ctx.MapType(typeof(string)));
     ctx.EmitCall(this.parse);
 }