Exemple #1
0
        void ProtoBuf.Serializers.IProtoSerializer.EmitWrite(CompilerContext ctx, Local valueFrom)
        {
            ProtoTypeCode typeCode = this.GetTypeCode();

            if (this.map == null)
            {
                ctx.LoadValue(valueFrom);
                ctx.ConvertToInt32(typeCode, false);
                ctx.EmitBasicWrite("WriteInt32", null);
                return;
            }
            using (Local localWithValue = ctx.GetLocalWithValue(this.ExpectedType, valueFrom))
            {
                CodeLabel codeLabel = ctx.DefineLabel();
                for (int i = 0; i < (int)this.map.Length; i++)
                {
                    CodeLabel codeLabel1 = ctx.DefineLabel();
                    CodeLabel codeLabel2 = ctx.DefineLabel();
                    ctx.LoadValue(localWithValue);
                    EnumSerializer.WriteEnumValue(ctx, typeCode, this.map[i].RawValue);
                    ctx.BranchIfEqual(codeLabel2, true);
                    ctx.Branch(codeLabel1, true);
                    ctx.MarkLabel(codeLabel2);
                    ctx.LoadValue(this.map[i].WireValue);
                    ctx.EmitBasicWrite("WriteInt32", null);
                    ctx.Branch(codeLabel, false);
                    ctx.MarkLabel(codeLabel1);
                }
                ctx.LoadReaderWriter();
                ctx.LoadValue(localWithValue);
                ctx.CastToObject(this.ExpectedType);
                ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("ThrowEnumException"));
                ctx.MarkLabel(codeLabel);
            }
        }
Exemple #2
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);
             }
         }
     }
 }
Exemple #3
0
        void IProtoTypeSerializer.EmitCallback(CompilerContext ctx, Local valueFrom, TypeModel.CallbackType callbackType)
        {
            bool copyValue = false;

            if (this.CanHaveInheritance)
            {
                for (int i = 0; i < this.serializers.Length; i++)
                {
                    IProtoSerializer serializer = this.serializers[i];
                    if ((serializer.ExpectedType != this.forType) && ((IProtoTypeSerializer)serializer).HasCallbacks(callbackType))
                    {
                        copyValue = true;
                    }
                }
            }
            MethodInfo method = (this.callbacks == null) ? null : this.callbacks[callbackType];

            if ((method != null) || copyValue)
            {
                ctx.LoadAddress(valueFrom, this.ExpectedType);
                EmitInvokeCallback(ctx, method, copyValue, null, this.forType);
                if (copyValue)
                {
                    CodeLabel label = ctx.DefineLabel();
                    for (int j = 0; j < this.serializers.Length; j++)
                    {
                        IProtoTypeSerializer serializer3;
                        IProtoSerializer     serializer2 = this.serializers[j];
                        Type expectedType = serializer2.ExpectedType;
                        if ((expectedType != this.forType) && (serializer3 = (IProtoTypeSerializer)serializer2).HasCallbacks(callbackType))
                        {
                            CodeLabel label2 = ctx.DefineLabel();
                            CodeLabel label3 = ctx.DefineLabel();
                            ctx.CopyValue();
                            ctx.TryCast(expectedType);
                            ctx.CopyValue();
                            ctx.BranchIfTrue(label2, true);
                            ctx.DiscardValue();
                            ctx.Branch(label3, false);
                            ctx.MarkLabel(label2);
                            serializer3.EmitCallback(ctx, null, callbackType);
                            ctx.Branch(label, false);
                            ctx.MarkLabel(label3);
                        }
                    }
                    ctx.MarkLabel(label);
                    ctx.DiscardValue();
                }
            }
        }
Exemple #4
0
        private void ResolveInlineFragment(
            CompilerContext context,
            InlineFragmentNode inlineFragment,
            SelectionIncludeCondition?includeCondition)
        {
            if (inlineFragment.SelectionSet.Selections.Count == 0)
            {
                throw OperationCompiler_FragmentNoSelections(inlineFragment);
            }

            if (_fragments.GetFragment(context.Type, inlineFragment) is { } fragmentInfo&&
                DoesTypeApply(fragmentInfo.TypeCondition, context.Type))
            {
                if (inlineFragment.IsDeferrable() &&
                    AllowFragmentDeferral(context, inlineFragment))
                {
                    CompilerContext deferContext = context.Branch(fragmentInfo);
                    CompileSelectionSet(deferContext);

                    context.RegisterFragment(new Fragment(
                                                 context.Type,
                                                 inlineFragment,
                                                 deferContext.GetSelectionSet(),
                                                 context.IsInternalSelection,
                                                 includeCondition));
                }
                else
                {
                    CollectFields(
                        context,
                        fragmentInfo.SelectionSet,
                        includeCondition);
                }
            }
        }
        private void ResolveFragmentSpread(
            CompilerContext context,
            FragmentSpreadNode fragmentSpread,
            SelectionIncludeCondition?includeCondition)
        {
            if (_fragments.GetFragment(fragmentSpread.Name.Value) is { } fragmentInfo&&
                DoesTypeApply(fragmentInfo.TypeCondition, context.Type))
            {
                FragmentDefinitionNode fragmentDefinition = fragmentInfo.FragmentDefinition !;

                if (fragmentSpread.IsDeferrable() &&
                    AllowFragmentDeferral(context, fragmentSpread, fragmentDefinition))
                {
                    CompilerContext deferContext = context.Branch(fragmentInfo);
                    CompileSelectionSet(deferContext);

                    context.RegisterFragment(new Fragment(
                                                 context.Type,
                                                 fragmentSpread,
                                                 fragmentDefinition,
                                                 deferContext.GetSelectionSet(),
                                                 context.IsInternalSelection,
                                                 includeCondition));
                }
                else
                {
                    CollectFields(
                        context,
                        fragmentInfo.SelectionSet,
                        includeCondition);
                }
            }
        }
Exemple #6
0
 private static void WriteEnumValue(CompilerContext ctx, ProtoTypeCode typeCode, CodeLabel handler, CodeLabel @continue, object value, Local local)
 {
     ctx.MarkLabel(handler);
     WriteEnumValue(ctx, typeCode, value);
     ctx.StoreValue(local);
     ctx.Branch(@continue, false);
 }
Exemple #7
0
        private void EmitWriteArrayLoop(CompilerContext ctx, Local i, Local arr)
        {
            ctx.LoadValue(0);
            ctx.StoreValue(i);
            CodeLabel label  = ctx.DefineLabel();
            CodeLabel label2 = ctx.DefineLabel();

            ctx.Branch(label, false);
            ctx.MarkLabel(label2);
            ctx.LoadArrayValue(arr, i);
            if (this.SupportNull)
            {
                base.Tail.EmitWrite(ctx, null);
            }
            else
            {
                ctx.WriteNullCheckedTail(this.itemType, base.Tail, null);
            }
            ctx.LoadValue(i);
            ctx.LoadValue(1);
            ctx.Add();
            ctx.StoreValue(i);
            ctx.MarkLabel(label);
            ctx.LoadValue(i);
            ctx.LoadLength(arr, false);
            ctx.BranchIfLess(label2, false);
        }
Exemple #8
0
 protected override void EmitWrite(CompilerContext ctx, Local valueFrom)
 {
     using (Local local = ctx.GetLocalWithValue(this.ExpectedType, valueFrom))
     {
         MethodInfo info;
         MethodInfo info2;
         MethodInfo method      = this.GetEnumeratorInfo(ctx.Model, out info, out info2);
         Type       returnType  = method.ReturnType;
         bool       writePacked = this.WritePacked;
         using (Local local2 = new Local(ctx, returnType))
         {
             using (Local local3 = writePacked ? new Local(ctx, ctx.MapType(typeof(SubItemToken))) : null)
             {
                 if (writePacked)
                 {
                     ctx.LoadValue(this.fieldNumber);
                     ctx.LoadValue(2);
                     ctx.LoadReaderWriter();
                     ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("WriteFieldHeader"));
                     ctx.LoadValue(local);
                     ctx.LoadReaderWriter();
                     ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("StartSubItem"));
                     ctx.StoreValue(local3);
                     ctx.LoadValue(this.fieldNumber);
                     ctx.LoadReaderWriter();
                     ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("SetPackedField"));
                 }
                 ctx.LoadAddress(local, this.ExpectedType);
                 ctx.EmitCall(method);
                 ctx.StoreValue(local2);
                 using (ctx.Using(local2))
                 {
                     CodeLabel label  = ctx.DefineLabel();
                     CodeLabel label2 = ctx.DefineLabel();
                     ctx.Branch(label2, false);
                     ctx.MarkLabel(label);
                     ctx.LoadAddress(local2, returnType);
                     ctx.EmitCall(info2);
                     Type expectedType = base.Tail.ExpectedType;
                     if ((expectedType != ctx.MapType(typeof(object))) && (info2.ReturnType == ctx.MapType(typeof(object))))
                     {
                         ctx.CastFromObject(expectedType);
                     }
                     base.Tail.EmitWrite(ctx, null);
                     ctx.MarkLabel(label2);
                     ctx.LoadAddress(local2, returnType);
                     ctx.EmitCall(info);
                     ctx.BranchIfTrue(label, false);
                 }
                 if (writePacked)
                 {
                     ctx.LoadValue(local3);
                     ctx.LoadReaderWriter();
                     ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("EndSubItem"));
                 }
             }
         }
     }
 }
Exemple #9
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);
         }
     }
 }
Exemple #10
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();
            }
        }
Exemple #11
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);
                        }
                    }
                }
            }
        }
Exemple #12
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);
        }
Exemple #13
0
        private void ResolveInlineFragment(
            CompilerContext context,
            InlineFragmentNode inlineFragment,
            SelectionIncludeCondition?includeCondition)
        {
            if (inlineFragment.SelectionSet.Selections.Count == 0)
            {
                throw OperationCompiler_FragmentNoSelections(inlineFragment);
            }

            if (_fragments.GetFragment(context.Type, inlineFragment) is { } fragmentInfo&&
                DoesTypeApply(fragmentInfo.TypeCondition, context.Type))
            {
                var reference = new SpreadReference(context.SelectionPath, inlineFragment);

                if (!context.Spreads.TryGetValue(reference, out var selectionSet))
                {
                    selectionSet = inlineFragment.SelectionSet.WithSelections(
                        inlineFragment.SelectionSet.Selections);
                    context.Spreads.Add(reference, selectionSet);
                }

                if (inlineFragment.IsDeferrable() &&
                    AllowFragmentDeferral(context, inlineFragment))
                {
                    CompilerContext deferContext = context.Branch(selectionSet);
                    CompileSelectionSet(deferContext);

                    context.RegisterFragment(new Fragment(
                                                 _nextFragmentId++,
                                                 context.Type,
                                                 inlineFragment,
                                                 deferContext.GetSelectionSet(),
                                                 context.IsInternalSelection,
                                                 includeCondition));
                }
                else
                {
                    CollectFields(
                        context,
                        selectionSet,
                        includeCondition);
                }
            }
        }
Exemple #14
0
    private void ResolveFragmentSpread(
        CompilerContext context,
        FragmentSpreadNode fragmentSpread,
        SelectionIncludeCondition?includeCondition)
    {
        if (_fragments.GetFragment(fragmentSpread.Name.Value) is { } fragmentInfo&&
            DoesTypeApply(fragmentInfo.TypeCondition, context.Type))
        {
            FragmentDefinitionNode fragmentDefinition = fragmentInfo.FragmentDefinition !;

            if (fragmentDefinition.SelectionSet.Selections.Count == 0)
            {
                throw OperationCompiler_FragmentNoSelections(fragmentDefinition);
            }

            var reference = new SpreadReference(context.SelectionPath, fragmentSpread);

            if (!context.Spreads.TryGetValue(reference, out SelectionSetNode? selectionSet))
            {
                selectionSet = fragmentDefinition.SelectionSet.WithSelections(
                    fragmentDefinition.SelectionSet.Selections);
                context.Spreads.Add(reference, selectionSet);
            }

            if (fragmentSpread.IsDeferrable() &&
                AllowFragmentDeferral(context, fragmentSpread, fragmentDefinition))
            {
                CompilerContext deferContext = context.Branch(selectionSet);
                CompileSelectionSet(deferContext);

                context.RegisterFragment(new Fragment(
                                             _nextFragmentId++,
                                             context.Type,
                                             fragmentSpread,
                                             fragmentDefinition,
                                             deferContext.GetSelectionSet(),
                                             context.IsInternalSelection,
                                             includeCondition));
            }
            else
            {
                CollectFields(context, selectionSet, includeCondition);
            }
        }
    }
Exemple #15
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);
        }
Exemple #16
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);
        }
        protected override void EmitWrite(CompilerContext ctx, Local valueFrom)
        {
            CodeLabel label = ctx.DefineLabel();

            if (valueFrom == null)
            {
                ctx.CopyValue();
                CodeLabel label2 = ctx.DefineLabel();
                this.EmitBranchIfDefaultValue(ctx, label2);
                base.Tail.EmitWrite(ctx, null);
                ctx.Branch(label, true);
                ctx.MarkLabel(label2);
                ctx.DiscardValue();
            }
            else
            {
                ctx.LoadValue(valueFrom);
                this.EmitBranchIfDefaultValue(ctx, label);
                base.Tail.EmitWrite(ctx, valueFrom);
            }
            ctx.MarkLabel(label);
        }
Exemple #18
0
 protected override void EmitRead(CompilerContext ctx, Local valueFrom)
 {
     using (Local local = ctx.GetLocalWithValue(this.ExpectedType, valueFrom))
     {
         ctx.LoadAddress(local, this.ExpectedType);
         if (base.Tail.RequiresOldValue)
         {
             ctx.CopyValue();
             ctx.LoadValue(this.field);
         }
         ctx.ReadNullCheckedTail(this.field.FieldType, base.Tail, null);
         if (base.Tail.ReturnsValue)
         {
             if (this.field.FieldType.IsValueType)
             {
                 ctx.StoreValue(this.field);
             }
             else
             {
                 CodeLabel label  = ctx.DefineLabel();
                 CodeLabel label2 = ctx.DefineLabel();
                 ctx.CopyValue();
                 ctx.BranchIfTrue(label, true);
                 ctx.DiscardValue();
                 ctx.DiscardValue();
                 ctx.Branch(label2, true);
                 ctx.MarkLabel(label);
                 ctx.StoreValue(this.field);
                 ctx.MarkLabel(label2);
             }
         }
         else
         {
             ctx.DiscardValue();
         }
     }
 }
Exemple #19
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);
                        }
                    }
                }
            }
        }
        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);
                                }
                            }
        }
Exemple #21
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);
                    }
                }
            }
        }
Exemple #22
0
        void IProtoSerializer.EmitWrite(CompilerContext ctx, Local valueFrom)
        {
            Type expectedType = this.ExpectedType;

            using (Local local = ctx.GetLocalWithValue(expectedType, valueFrom))
            {
                this.EmitCallbackIfNeeded(ctx, local, TypeModel.CallbackType.BeforeSerialize);
                CodeLabel label = ctx.DefineLabel();
                if (!this.CanHaveInheritance)
                {
                    goto Label_0206;
                }
                for (int i = 0; i < this.serializers.Length; i++)
                {
                    IProtoSerializer serializer = this.serializers[i];
                    Type             type       = serializer.ExpectedType;
                    if (type != this.forType)
                    {
                        CodeLabel label2 = ctx.DefineLabel();
                        CodeLabel label3 = ctx.DefineLabel();
                        ctx.LoadValue(local);
                        ctx.TryCast(type);
                        ctx.CopyValue();
                        ctx.BranchIfTrue(label2, true);
                        ctx.DiscardValue();
                        ctx.Branch(label3, true);
                        ctx.MarkLabel(label2);
                        serializer.EmitWrite(ctx, null);
                        ctx.Branch(label, false);
                        ctx.MarkLabel(label3);
                    }
                }
                if ((this.constructType != null) && (this.constructType != this.forType))
                {
                    using (Local local2 = new Local(ctx, ctx.MapType(typeof(Type))))
                    {
                        ctx.LoadValue(local);
                        ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType"));
                        ctx.CopyValue();
                        ctx.StoreValue(local2);
                        ctx.LoadValue(this.forType);
                        ctx.BranchIfEqual(label, true);
                        ctx.LoadValue(local2);
                        ctx.LoadValue(this.constructType);
                        ctx.BranchIfEqual(label, true);
                        goto Label_01B1;
                    }
                }
                ctx.LoadValue(local);
                ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType"));
                ctx.LoadValue(this.forType);
                ctx.BranchIfEqual(label, true);
Label_01B1:
                ctx.LoadValue(this.forType);
                ctx.LoadValue(local);
                ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType"));
                ctx.EmitCall(ctx.MapType(typeof(TypeModel)).GetMethod("ThrowUnexpectedSubtype", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static));
Label_0206:
                ctx.MarkLabel(label);
                for (int j = 0; j < this.serializers.Length; j++)
                {
                    IProtoSerializer serializer2 = this.serializers[j];
                    if (serializer2.ExpectedType == this.forType)
                    {
                        serializer2.EmitWrite(ctx, local);
                    }
                }
                if (this.isExtensible)
                {
                    ctx.LoadValue(local);
                    ctx.LoadReaderWriter();
                    ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("AppendExtensionData"));
                }
                this.EmitCallbackIfNeeded(ctx, local, TypeModel.CallbackType.AfterSerialize);
            }
        }
        protected override void EmitWrite(CompilerContext ctx, Local valueFrom)
        {
            Type       itemType = typeof(KeyValuePair <TKey, TValue>);
            MethodInfo moveNext, current, getEnumerator = ListDecorator.GetEnumeratorInfo(
                ExpectedType, itemType, out moveNext, out current);
            Type enumeratorType = getEnumerator.ReturnType;

            MethodInfo key    = itemType.GetProperty(nameof(KeyValuePair <TKey, TValue> .Key)).GetGetMethod(),
                       @value = itemType.GetProperty(nameof(KeyValuePair <TKey, TValue> .Value)).GetGetMethod();

            using (Compiler.Local list = ctx.GetLocalWithValue(ExpectedType, valueFrom))
                using (Compiler.Local iter = new Compiler.Local(ctx, enumeratorType))
                    using (Compiler.Local token = new Compiler.Local(ctx, typeof(SubItemToken)))
                        using (Compiler.Local kvp = new Compiler.Local(ctx, itemType))
                        {
                            ctx.LoadAddress(list, ExpectedType);
                            ctx.EmitCall(getEnumerator, ExpectedType);
                            ctx.StoreValue(iter);
                            using (ctx.Using(iter))
                            {
                                Compiler.CodeLabel body = ctx.DefineLabel(), next = ctx.DefineLabel();
                                ctx.Branch(next, false);

                                ctx.MarkLabel(body);

                                ctx.LoadAddress(iter, enumeratorType);
                                ctx.EmitCall(current, enumeratorType);

                                if (itemType != typeof(object) && current.ReturnType == typeof(object))
                                {
                                    ctx.CastFromObject(itemType);
                                }
                                ctx.StoreValue(kvp);

                                ctx.LoadValue(fieldNumber);
                                ctx.LoadValue((int)wireType);
                                ctx.LoadWriter(true);
                                ctx.EmitCall(ProtoWriter.GetStaticMethod("WriteFieldHeader"));

                                ctx.LoadNullRef();
                                ctx.LoadWriter(true);
                                ctx.EmitCall(ProtoWriter.GetStaticMethod("StartSubItem"));
                                ctx.StoreValue(token);

                                ctx.LoadAddress(kvp, itemType);
                                ctx.EmitCall(key, itemType);
                                ctx.WriteNullCheckedTail(typeof(TKey), keyTail, null);

                                ctx.LoadAddress(kvp, itemType);
                                ctx.EmitCall(value, itemType);
                                ctx.WriteNullCheckedTail(typeof(TValue), Tail, null);

                                ctx.LoadValue(token);
                                ctx.LoadWriter(true);
                                ctx.EmitCall(ProtoWriter.GetStaticMethod("EndSubItem"));

                                ctx.MarkLabel(@next);
                                ctx.LoadAddress(iter, enumeratorType);
                                ctx.EmitCall(moveNext, enumeratorType);
                                ctx.BranchIfTrue(body, false);
                            }
                        }
        }
Exemple #24
0
        void ProtoBuf.Serializers.IProtoTypeSerializer.EmitCallback(CompilerContext ctx, Local valueFrom, TypeModel.CallbackType callbackType)
        {
            MethodInfo item;
            bool       flag = false;

            if (this.CanHaveInheritance)
            {
                for (int i = 0; i < (int)this.serializers.Length; i++)
                {
                    IProtoSerializer protoSerializer = this.serializers[i];
                    if (protoSerializer.ExpectedType != this.forType && ((IProtoTypeSerializer)protoSerializer).HasCallbacks(callbackType))
                    {
                        flag = true;
                    }
                }
            }
            if (this.callbacks == null)
            {
                item = null;
            }
            else
            {
                item = this.callbacks[callbackType];
            }
            MethodInfo methodInfo = item;

            if (methodInfo == null && !flag)
            {
                return;
            }
            ctx.LoadAddress(valueFrom, this.ExpectedType);
            TypeSerializer.EmitInvokeCallback(ctx, methodInfo, flag, null, this.forType);
            if (flag)
            {
                CodeLabel codeLabel = ctx.DefineLabel();
                for (int j = 0; j < (int)this.serializers.Length; j++)
                {
                    IProtoSerializer protoSerializer1 = this.serializers[j];
                    Type             expectedType     = protoSerializer1.ExpectedType;
                    if (expectedType != this.forType)
                    {
                        IProtoTypeSerializer protoTypeSerializer  = (IProtoTypeSerializer)protoSerializer1;
                        IProtoTypeSerializer protoTypeSerializer1 = protoTypeSerializer;
                        if (protoTypeSerializer.HasCallbacks(callbackType))
                        {
                            CodeLabel codeLabel1 = ctx.DefineLabel();
                            CodeLabel codeLabel2 = ctx.DefineLabel();
                            ctx.CopyValue();
                            ctx.TryCast(expectedType);
                            ctx.CopyValue();
                            ctx.BranchIfTrue(codeLabel1, true);
                            ctx.DiscardValue();
                            ctx.Branch(codeLabel2, false);
                            ctx.MarkLabel(codeLabel1);
                            protoTypeSerializer1.EmitCallback(ctx, null, callbackType);
                            ctx.Branch(codeLabel, false);
                            ctx.MarkLabel(codeLabel2);
                        }
                    }
                }
                ctx.MarkLabel(codeLabel);
                ctx.DiscardValue();
            }
        }
        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);
                    }
                }
            }
        }
Exemple #26
0
        protected override void EmitWrite(CompilerContext ctx, Local valueFrom)
        {
            MethodInfo methodInfo;
            MethodInfo methodInfo1;
            Local      local;

            using (Local localWithValue = ctx.GetLocalWithValue(this.ExpectedType, valueFrom))
            {
                MethodInfo enumeratorInfo = this.GetEnumeratorInfo(ctx.Model, out methodInfo, out methodInfo1);
                Type       returnType     = enumeratorInfo.ReturnType;
                bool       writePacked    = this.WritePacked;
                using (Local local1 = new Local(ctx, returnType))
                {
                    if (writePacked)
                    {
                        local = new Local(ctx, ctx.MapType(typeof(SubItemToken)));
                    }
                    else
                    {
                        local = null;
                    }
                    using (Local local2 = local)
                    {
                        if (writePacked)
                        {
                            ctx.LoadValue(this.fieldNumber);
                            ctx.LoadValue(2);
                            ctx.LoadReaderWriter();
                            ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("WriteFieldHeader"));
                            ctx.LoadValue(localWithValue);
                            ctx.LoadReaderWriter();
                            ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("StartSubItem"));
                            ctx.StoreValue(local2);
                            ctx.LoadValue(this.fieldNumber);
                            ctx.LoadReaderWriter();
                            ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("SetPackedField"));
                        }
                        ctx.LoadAddress(localWithValue, this.ExpectedType);
                        ctx.EmitCall(enumeratorInfo);
                        ctx.StoreValue(local1);
                        using (IDisposable disposable = ctx.Using(local1))
                        {
                            CodeLabel codeLabel  = ctx.DefineLabel();
                            CodeLabel codeLabel1 = ctx.DefineLabel();
                            ctx.Branch(codeLabel1, false);
                            ctx.MarkLabel(codeLabel);
                            ctx.LoadAddress(local1, returnType);
                            ctx.EmitCall(methodInfo1);
                            Type expectedType = this.Tail.ExpectedType;
                            if (expectedType != ctx.MapType(typeof(object)) && methodInfo1.ReturnType == ctx.MapType(typeof(object)))
                            {
                                ctx.CastFromObject(expectedType);
                            }
                            this.Tail.EmitWrite(ctx, null);
                            ctx.MarkLabel(codeLabel1);
                            ctx.LoadAddress(local1, returnType);
                            ctx.EmitCall(methodInfo);
                            ctx.BranchIfTrue(codeLabel, false);
                        }
                        if (writePacked)
                        {
                            ctx.LoadValue(local2);
                            ctx.LoadReaderWriter();
                            ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("EndSubItem"));
                        }
                    }
                }
            }
        }
Exemple #27
0
 void ProtoBuf.Serializers.IProtoSerializer.EmitWrite(CompilerContext ctx, Local valueFrom)
 {
     using (Local localWithValue = ctx.GetLocalWithValue(this.ExpectedType, valueFrom))
     {
         this.EmitCallbackIfNeeded(ctx, localWithValue, TypeModel.CallbackType.BeforeSerialize);
         CodeLabel codeLabel = ctx.DefineLabel();
         if (this.CanHaveInheritance)
         {
             for (int i = 0; i < (int)this.serializers.Length; i++)
             {
                 IProtoSerializer protoSerializer = this.serializers[i];
                 Type             expectedType    = protoSerializer.ExpectedType;
                 if (expectedType != this.forType)
                 {
                     CodeLabel codeLabel1 = ctx.DefineLabel();
                     CodeLabel codeLabel2 = ctx.DefineLabel();
                     ctx.LoadValue(localWithValue);
                     ctx.TryCast(expectedType);
                     ctx.CopyValue();
                     ctx.BranchIfTrue(codeLabel1, true);
                     ctx.DiscardValue();
                     ctx.Branch(codeLabel2, true);
                     ctx.MarkLabel(codeLabel1);
                     protoSerializer.EmitWrite(ctx, null);
                     ctx.Branch(codeLabel, false);
                     ctx.MarkLabel(codeLabel2);
                 }
             }
             if (this.constructType == null || this.constructType == this.forType)
             {
                 ctx.LoadValue(localWithValue);
                 ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType"));
                 ctx.LoadValue(this.forType);
                 ctx.BranchIfEqual(codeLabel, true);
             }
             else
             {
                 using (Local local = new Local(ctx, ctx.MapType(typeof(Type))))
                 {
                     ctx.LoadValue(localWithValue);
                     ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType"));
                     ctx.CopyValue();
                     ctx.StoreValue(local);
                     ctx.LoadValue(this.forType);
                     ctx.BranchIfEqual(codeLabel, true);
                     ctx.LoadValue(local);
                     ctx.LoadValue(this.constructType);
                     ctx.BranchIfEqual(codeLabel, true);
                 }
             }
             ctx.LoadValue(this.forType);
             ctx.LoadValue(localWithValue);
             ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType"));
             ctx.EmitCall(ctx.MapType(typeof(TypeModel)).GetMethod("ThrowUnexpectedSubtype", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic));
         }
         ctx.MarkLabel(codeLabel);
         for (int j = 0; j < (int)this.serializers.Length; j++)
         {
             IProtoSerializer protoSerializer1 = this.serializers[j];
             if (protoSerializer1.ExpectedType == this.forType)
             {
                 protoSerializer1.EmitWrite(ctx, localWithValue);
             }
         }
         if (this.isExtensible)
         {
             ctx.LoadValue(localWithValue);
             ctx.LoadReaderWriter();
             ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("AppendExtensionData"));
         }
         this.EmitCallbackIfNeeded(ctx, localWithValue, TypeModel.CallbackType.AfterSerialize);
     }
 }
Exemple #28
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);
                }
            }
        }
Exemple #29
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();
                        }
                    }
                }
            }
        }
Exemple #30
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);
                    }
                }
            }
        }