예제 #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
 public virtual void EmitCreateInstance(CompilerContext ctx)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         ctx.EmitCtor(_concreteTypeDefault);
         ctx.CopyValue();
         // we can use stack value here because note object on reader is static (backwards API)
         ctx.G.Reader.NoteObject(ctx.G.GetStackValueOperand(ExpectedType));
     }
 }
예제 #3
0
        protected override void EmitRead(CompilerContext ctx, Local valueFrom)
        {
            bool returnList     = this.ReturnList;
            bool castListForAdd = !this.add.DeclaringType.IsAssignableFrom(this.declaredType);

            using (Local local = this.AppendToCollection ? ctx.GetLocalWithValue(this.ExpectedType, valueFrom) : new Local(ctx, this.declaredType))
            {
                using (Local local2 = (returnList && this.AppendToCollection) ? new Local(ctx, this.ExpectedType) : null)
                {
                    if (!this.AppendToCollection)
                    {
                        ctx.LoadNullRef();
                        ctx.StoreValue(local);
                    }
                    else if (returnList)
                    {
                        ctx.LoadValue(local);
                        ctx.StoreValue(local2);
                    }
                    if (this.concreteType != null)
                    {
                        ctx.LoadValue(local);
                        CodeLabel label = ctx.DefineLabel();
                        ctx.BranchIfTrue(label, true);
                        ctx.EmitCtor(this.concreteType);
                        ctx.StoreValue(local);
                        ctx.MarkLabel(label);
                    }
                    EmitReadList(ctx, local, base.Tail, this.add, this.packedWireType, castListForAdd);
                    if (returnList)
                    {
                        if (this.AppendToCollection)
                        {
                            ctx.LoadValue(local2);
                            ctx.LoadValue(local);
                            CodeLabel label2 = ctx.DefineLabel();
                            CodeLabel label3 = ctx.DefineLabel();
                            ctx.BranchIfEqual(label2, true);
                            ctx.LoadValue(local);
                            ctx.Branch(label3, true);
                            ctx.MarkLabel(label2);
                            ctx.LoadNullRef();
                            ctx.MarkLabel(label3);
                        }
                        else
                        {
                            ctx.LoadValue(local);
                        }
                    }
                }
            }
        }
예제 #4
0
        protected override void EmitRead(CompilerContext ctx, Local valueFrom)
        {
            base.Tail.EmitRead(ctx, valueFrom);
            ctx.CopyValue();
            CodeLabel label  = ctx.DefineLabel();
            CodeLabel label2 = ctx.DefineLabel();

            ctx.LoadValue(typeof(string).GetProperty("Length"));
            ctx.BranchIfTrue(label, true);
            ctx.DiscardValue();
            ctx.LoadNullRef();
            ctx.Branch(label2, true);
            ctx.MarkLabel(label);
            ctx.EmitCtor(ctx.MapType(typeof(Uri)), new Type[] { ctx.MapType(typeof(string)) });
            ctx.MarkLabel(label2);
        }
예제 #5
0
        protected override void EmitRead(CompilerContext ctx, Local valueFrom)
        {
            this.Tail.EmitRead(ctx, valueFrom);
            ctx.CopyValue();
            CodeLabel codeLabel  = ctx.DefineLabel();
            CodeLabel codeLabel1 = ctx.DefineLabel();

            ctx.LoadValue(typeof(string).GetProperty("Length"));
            ctx.BranchIfTrue(codeLabel, true);
            ctx.DiscardValue();
            ctx.LoadNullRef();
            ctx.Branch(codeLabel1, true);
            ctx.MarkLabel(codeLabel);
            Type type = ctx.MapType(typeof(Uri));

            Type[] typeArray = new Type[] { ctx.MapType(typeof(string)) };
            ctx.EmitCtor(type, typeArray);
            ctx.MarkLabel(codeLabel1);
        }
예제 #6
0
        void IProtoTypeSerializer.EmitCreateInstance(CompilerContext ctx)
        {
            bool flag = true;

            if (this.factory != null)
            {
                EmitInvokeCallback(ctx, this.factory, false, this.constructType, this.forType);
            }
            else if (!this.useConstructor)
            {
                ctx.LoadValue(this.constructType);
                ctx.EmitCall(ctx.MapType(typeof(BclHelpers)).GetMethod("GetUninitializedObject"));
                ctx.Cast(this.forType);
            }
            else if (this.constructType.IsClass && this.hasConstructor)
            {
                ctx.EmitCtor(this.constructType);
            }
            else
            {
                ctx.LoadValue(this.ExpectedType);
                ctx.EmitCall(ctx.MapType(typeof(TypeModel)).GetMethod("ThrowCannotCreateInstance", BindingFlags.Public | BindingFlags.Static));
                ctx.LoadNullRef();
                flag = false;
            }
            if (flag)
            {
                ctx.CopyValue();
                ctx.LoadReaderWriter();
                ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("NoteObject", BindingFlags.Public | BindingFlags.Static));
            }
            if (this.baseCtorCallbacks != null)
            {
                for (int i = 0; i < this.baseCtorCallbacks.Length; i++)
                {
                    EmitInvokeCallback(ctx, this.baseCtorCallbacks[i], true, null, this.forType);
                }
            }
        }
예제 #7
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);
                                }
                            }
        }
예제 #8
0
        private static void EmitReadAndAddItem(CompilerContext ctx, Local list, IProtoSerializer tail, MethodInfo add, bool castListForAdd)
        {
            ctx.LoadAddress(list, list.Type);
            if (castListForAdd)
            {
                ctx.Cast(add.DeclaringType);
            }
            Type expectedType = tail.ExpectedType;
            bool returnsValue = tail.ReturnsValue;

            if (!tail.RequiresOldValue)
            {
                if (!returnsValue)
                {
                    throw new InvalidOperationException();
                }
                tail.EmitRead(ctx, null);
            }
            else if (expectedType.IsValueType || !returnsValue)
            {
                using (Local local = new Local(ctx, expectedType))
                {
                    if (!expectedType.IsValueType)
                    {
                        ctx.LoadNullRef();
                        ctx.StoreValue(local);
                    }
                    else
                    {
                        ctx.LoadAddress(local, expectedType);
                        ctx.EmitCtor(expectedType);
                    }
                    tail.EmitRead(ctx, local);
                    if (!returnsValue)
                    {
                        ctx.LoadValue(local);
                    }
                }
            }
            else
            {
                ctx.LoadNullRef();
                tail.EmitRead(ctx, null);
            }
            Type parameterType = add.GetParameters()[0].ParameterType;

            if (parameterType != expectedType)
            {
                if (parameterType != ctx.MapType(typeof(object)))
                {
                    if (Helpers.GetUnderlyingType(parameterType) != expectedType)
                    {
                        throw new InvalidOperationException("Conflicting item/add type");
                    }
                    Type[] typeArray = new Type[] { expectedType };
                    ctx.EmitCtor(Helpers.GetConstructor(parameterType, typeArray, false));
                }
                else
                {
                    ctx.CastToObject(expectedType);
                }
            }
            ctx.EmitCall(add);
            if (add.ReturnType != ctx.MapType(typeof(void)))
            {
                ctx.DiscardValue();
            }
        }
예제 #9
0
        protected override void EmitRead(CompilerContext ctx, Local valueFrom)
        {
            Local local;
            bool  returnList = this.ReturnList;

            using (Local local1 = (this.AppendToCollection ? ctx.GetLocalWithValue(this.ExpectedType, valueFrom) : new Local(ctx, this.declaredType)))
            {
                if (!returnList || !this.AppendToCollection)
                {
                    local = null;
                }
                else
                {
                    local = new Local(ctx, this.ExpectedType);
                }
                using (Local local2 = local)
                {
                    if (!this.AppendToCollection)
                    {
                        ctx.LoadNullRef();
                        ctx.StoreValue(local1);
                    }
                    else if (returnList)
                    {
                        ctx.LoadValue(local1);
                        ctx.StoreValue(local2);
                    }
                    if (this.concreteType != null)
                    {
                        ctx.LoadValue(local1);
                        CodeLabel codeLabel = ctx.DefineLabel();
                        ctx.BranchIfTrue(codeLabel, true);
                        ctx.EmitCtor(this.concreteType);
                        ctx.StoreValue(local1);
                        ctx.MarkLabel(codeLabel);
                    }
                    bool flag = [email protected](this.declaredType);
                    ListDecorator.EmitReadList(ctx, local1, this.Tail, this.@add, this.packedWireType, flag);
                    if (returnList)
                    {
                        if (!this.AppendToCollection)
                        {
                            ctx.LoadValue(local1);
                        }
                        else
                        {
                            ctx.LoadValue(local2);
                            ctx.LoadValue(local1);
                            CodeLabel codeLabel1 = ctx.DefineLabel();
                            CodeLabel codeLabel2 = ctx.DefineLabel();
                            ctx.BranchIfEqual(codeLabel1, true);
                            ctx.LoadValue(local1);
                            ctx.Branch(codeLabel2, true);
                            ctx.MarkLabel(codeLabel1);
                            ctx.LoadNullRef();
                            ctx.MarkLabel(codeLabel2);
                        }
                    }
                }
            }
        }
예제 #10
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();
                        }
                    }
                }
            }
        }
예제 #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);
                    }
                }
            }
        }
        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();
                        }
                    }
                }
            }
        }