コード例 #1
0
        void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using (ctx.StartDebugBlockAuto(this))
            {
                var g = ctx.G;
                using (var value = ctx.GetLocalWithValueForEmitRead(this, valueFrom)) // overwriteList ? null : value
                    using (var result = ctx.Local(ExpectedType))
                    {
                        g.Assign(result, g.ReaderFunc.AppendBytes(value));
                        if (!value.IsNullRef())
                        {
                            g.If(value.AsOperand == null);
                        }
                        {
                            //if (overwriteList || value == null)
                            g.Reader.NoteObject(result);
                        }
                        if (!value.IsNullRef())
                        {
                            g.End();
                        }

                        ctx.LoadValue(result);
                    }
            }
        }
コード例 #2
0
        public void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using (ctx.StartDebugBlockAuto(this))
            {
                var g = ctx.G;

                g.Writer.ExpectRoot();
                if (_protoCompatibility)
                {
                    _serializer.EmitWrite(ctx, valueFrom);
                    return;
                }

                using (var rootToken = ctx.Local(typeof(SubItemToken)))
                    using (var typeKey = ctx.Local(typeof(int)))
                        using (var obj = ctx.Local(typeof(object)))
                            using (var refKey = ctx.Local(typeof(int)))
                            {
                                g.Assign(rootToken, g.WriterFunc.StartSubItem(null, false));
                                g.Writer.WriteFieldHeaderBegin(CurrentFormatVersion);
                                _serializer.EmitWrite(ctx, valueFrom);
                                g.While(g.StaticFactory.Invoke(typeof(ProtoWriter), nameof(ProtoWriter.TryGetNextLateReference), typeKey, obj, refKey, g.ArgReaderWriter()));
                                {
                                    g.Writer.WriteFieldHeaderBegin(refKey.AsOperand + 1);
                                    g.Writer.WriteRecursionSafeObject(obj, typeKey);
                                }
                                g.End();
                                g.Writer.EndSubItem(rootToken);
                            }
            }
        }
コード例 #3
0
 void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         ctx.EmitWrite(ctx.MapType(typeof(BclHelpers)), "WriteGuid", valueFrom);
     }
 }
コード例 #4
0
 protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this, _getSpecified?.Name))
     {
         if (_getSpecified == null)
         {
             Tail.EmitWrite(ctx, valueFrom);
             return;
         }
         using (Compiler.Local loc = ctx.GetLocalWithValue(ExpectedType, valueFrom))
         {
             ctx.LoadAddress(loc, ExpectedType);
             ctx.EmitCall(_getSpecified);
             Compiler.CodeLabel done         = ctx.DefineLabel();
             Compiler.CodeLabel notSpecified = ctx.DefineLabel();
             ctx.BranchIfFalse(notSpecified, false);
             {
                 Tail.EmitWrite(ctx, loc);
             }
             ctx.Branch(done, true);
             ctx.MarkLabel(notSpecified);
             {
                 ctx.G.Writer.WriteFieldHeaderCancelBegin();
             }
             ctx.MarkLabel(done);
         }
     }
 }
コード例 #5
0
 public void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         ctx.G.ThrowNotSupportedException();
     }
 }
コード例 #6
0
 void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         ctx.EmitBasicRead(ctx.MapType(typeof(BclHelpers)), "ReadGuid", ExpectedType);
     }
 }
コード例 #7
0
 void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         ctx.EmitBasicRead("ReadUInt16", ctx.MapType(typeof(ushort)));
     }
 }
コード例 #8
0
 void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         _head.EmitRead(ctx, valueFrom);
     }
 }
コード例 #9
0
        public void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using (ctx.StartDebugBlockAuto(this))
            {
                var g = ctx.G;
                using (Compiler.Local value = ctx.GetLocalWithValue(_ctor.DeclaringType, valueFrom))
                    using (Compiler.Local token = ctx.Local(typeof(SubItemToken)))
                    {
                        g.Assign(token, g.WriterFunc.StartSubItem(value, _prefixLength));
                        for (int i = 0; i < _tails.Length; i++)
                        {
                            Type type = GetMemberType(i);
                            ctx.LoadAddress(value, ExpectedType);
                            switch (_members[i].Member.MemberType)
                            {
                            case MemberTypes.Field:
                                ctx.LoadValue((FieldInfo)_members[i].Member);
                                break;

                            case MemberTypes.Property:
                                ctx.LoadValue((PropertyInfo)_members[i].Member);
                                break;
                            }
                            ctx.LoadValue(i + 1);
                            ctx.LoadReaderWriter();
                            ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod(nameof(ProtoWriter.WriteFieldHeaderBegin)));
                            ctx.WriteNullCheckedTail(type, _tails[i], null, true);
                        }
                        g.Writer.EndSubItem(token);
                    }
            }
        }
コード例 #10
0
        void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using (ctx.StartDebugBlockAuto(this))
            {
                Type type = ExpectedType;
                if (type.IsValueType)
                { // note that for structs, we've already asserted that a custom ToString
                  // exists; no need to handle the box/callvirt scenario

                    // force it to a variable if needed, so we can take the address
                    using (Compiler.Local loc = ctx.GetLocalWithValue(type, valueFrom))
                    {
                        ctx.LoadAddress(loc, type);
                        ctx.EmitCall(GetCustomToString(type));
                    }
                }
                else
                {
                    ctx.LoadValue(valueFrom);
                    if (valueFrom.Type != ctx.MapType(typeof(string)))
                    {
                        ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("ToString"));
                    }
                }
                ctx.EmitBasicWrite("WriteString", null);
            }
        }
コード例 #11
0
 void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         ctx.EmitBasicWrite("WriteType", valueFrom);
     }
 }
コード例 #12
0
 void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         ctx.EmitBasicRead("ReadType", ExpectedType);
     }
 }
コード例 #13
0
 void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         ctx.EmitWrite(ctx.MapType(typeof(BclHelpers)), _includeKind ? "WriteDateTimeWithKind" : "WriteDateTime", valueFrom);
     }
 }
コード例 #14
0
 protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         Tail.EmitRead(ctx, valueFrom);
     }
 }
コード例 #15
0
        private void EmitBranchIfDefaultValue(Compiler.CompilerContext ctx, Compiler.CodeLabel label)
        {
            using (ctx.StartDebugBlockAuto(this))
            {
                var  g = ctx.G;
                Type nullableUnderlying = Helpers.GetNullableUnderlyingType(ExpectedType);

                if (nullableUnderlying != null)
                {
                    using (var loc = ctx.Local(ExpectedType))
                    {
                        // we another for null check
                        ctx.G.Assign(loc, g.GetStackValueOperand(ExpectedType));
                        g.If(loc.AsOperand.Property("HasValue"));

                        // unwrap value
                        g.LeaveNextReturnOnStack();
                        g.Eval(loc.AsOperand.Property("Value"));
                    }
                }

                EmitBranchIfDefaultValue_Switch(ctx, label);

                if (nullableUnderlying != null)
                {
                    g.End();
                }
            }
        }
コード例 #16
0
 protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         ctx.LoadValue(valueFrom);
         ctx.LoadValue(absoluteUriProperty);
         Tail.EmitWrite(ctx, null);
     }
コード例 #17
0
 public void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         var g = ctx.G;
         g.Writer.WriteFieldHeaderBegin(_number);
         _serializer.EmitWrite(ctx, valueFrom);
     }
 }
コード例 #18
0
 void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         ctx.LoadValue(valueFrom);
         ctx.EmitCall(_toTail);
         _rootTail.EmitWrite(ctx, null);
     }
 }
コード例 #19
0
 protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this, _property.Name))
     {
         ctx.LoadAddress(valueFrom, ExpectedType);
         ctx.LoadValue(_property);
         Tail.EmitWrite(ctx, null);
     }
 }
コード例 #20
0
 protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         ctx.LoadValue((int)_wireType);
         ctx.LoadReaderWriter();
         ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("WriteFieldHeaderCompleteAnyType"));
         Tail.EmitWrite(ctx, valueFrom);
     }
 }
コード例 #21
0
        void IProtoTypeSerializer.EmitCallback(Compiler.CompilerContext ctx, Compiler.Local valueFrom, TypeModel.CallbackType callbackType)
        {
            using (ctx.StartDebugBlockAuto(this))
            {
                bool actuallyHasInheritance = false;
                if (CanHaveInheritance)
                {
                    for (int i = 0; i < _serializers.Length; i++)
                    {
                        IProtoSerializer ser = _serializers[i];
                        if (ser.ExpectedType != ExpectedType && ((ser as IProtoTypeSerializer)?.HasCallbacks(callbackType) ?? false))
                        {
                            actuallyHasInheritance = true;
                        }
                    }
                }

                Helpers.DebugAssert(((IProtoTypeSerializer)this).HasCallbacks(callbackType), "Shouldn't be calling this if there is nothing to do");
                MethodInfo method = _callbacks?[callbackType];
                if (method == null && !actuallyHasInheritance)
                {
                    return;
                }
                ctx.LoadAddress(valueFrom, ExpectedType);
                EmitInvokeCallback(ctx, method, actuallyHasInheritance, null, ExpectedType);

                if (actuallyHasInheritance)
                {
                    Compiler.CodeLabel @break = ctx.DefineLabel();
                    for (int i = 0; i < _serializers.Length; i++)
                    {
                        IProtoSerializer     ser = _serializers[i];
                        IProtoTypeSerializer typeser;
                        Type serType = ser.ExpectedType;
                        if (serType != ExpectedType &&
                            (typeser = (IProtoTypeSerializer)ser).HasCallbacks(callbackType))
                        {
                            Compiler.CodeLabel ifMatch = ctx.DefineLabel(), nextTest = ctx.DefineLabel();
                            ctx.CopyValue();
                            ctx.TryCast(serType);
                            ctx.CopyValue();
                            ctx.BranchIfTrue(ifMatch, true);
                            ctx.DiscardValue();
                            ctx.Branch(nextTest, false);
                            ctx.MarkLabel(ifMatch);
                            typeser.EmitCallback(ctx, null, callbackType);
                            ctx.Branch(@break, false);
                            ctx.MarkLabel(nextTest);
                        }
                    }
                    ctx.MarkLabel(@break);
                    ctx.DiscardValue();
                }
            }
        }
コード例 #22
0
 void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         ctx.EmitBasicRead("ReadString", ctx.MapType(typeof(string)));
         ctx.EmitCall(_parse);
         ctx.CopyValue();
         ctx.CastToObject(_parse.ReturnType);
         ctx.EmitCallNoteObject();
     }
 }
コード例 #23
0
 public void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         using (var value = ctx.GetLocalWithValue(ExpectedType, valueFrom))
         {
             _subTypeHelpers.EmitWrite(ctx.G, _model[_typeKey], value);
             ctx.G.Writer.NoteLateReference(ctx.MapMetaKeyToCompiledKey(_baseTypeKey), value);
         }
     }
 }
コード例 #24
0
        public void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using (ctx.StartDebugBlockAuto(this))
            {
                var g = ctx.G;
                using (var value = ctx.GetLocalWithValueForEmitRead(this, valueFrom))
                {
                    _subTypeHelpers.EmitTryRead(
                        g,
                        value,
                        _model[_typeKey],
                        r =>
                    {
                        using (ctx.StartDebugBlockAuto(this, "returnGen"))
                        {
                            if (r == null)
                            {
                                g.If(value.AsOperand == null);
                                {
                                    g.ThrowProtoException(CantCreateInstanceMessage);
                                }
                                g.End();
                                g.Reader.NoteObject(value);
                            }
                            else
                            {
                                r.Serializer.EmitCreateInstance(ctx);
                                ctx.StoreValue(value);
                            }
                            g.Reader.NoteLateReference(ctx.MapMetaKeyToCompiledKey(_baseTypeKey), value);
                        }
                    });

                    if (EmitReadReturnsValue)
                    {
                        ctx.LoadValue(value);
                    }
                }
            }
        }
コード例 #25
0
 public void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         var g = ctx.G;
         g.If(g.ReaderFunc.ReadFieldHeader_int() != _number);
         {
             g.ThrowProtoException("Expected tag " + _number);
         }
         g.End();
         _serializer.EmitRead(ctx, valueFrom);
     }
 }
コード例 #26
0
        protected override void EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using (ctx.StartDebugBlockAuto(this))
            {
                using (Compiler.Local valOrNull = ctx.GetLocalWithValue(_expectedType, valueFrom))
                {
                    if (_expectedType.IsValueType)
                    {
                        ctx.LoadAddress(valOrNull, _expectedType);
                        ctx.LoadValue(_expectedType.GetProperty("HasValue"));
                    }
                    else
                    {
                        ctx.LoadValue(valOrNull);
                    }
                    Compiler.CodeLabel done   = ctx.DefineLabel();
                    Compiler.CodeLabel onNull = ctx.DefineLabel();

                    ctx.BranchIfFalse(onNull, false);
                    // if !=null
                    {
                        if (_expectedType.IsValueType)
                        {
                            ctx.LoadAddress(valOrNull, _expectedType);
                            ctx.EmitCall(_expectedType.GetMethod("GetValueOrDefault", Helpers.EmptyTypes));
                        }
                        else
                        {
                            ctx.LoadValue(valOrNull);
                        }
                        Tail.EmitWrite(ctx, null);

                        ctx.Branch(done, true);
                    }
                    // else
                    {
                        ctx.MarkLabel(onNull);
                        if (_throwIfNull)
                        {
                            ctx.G.ThrowNullReferenceException();
                            ctx.G.ForceResetUnreachableState();
                        }
                        else
                        {
                            ctx.G.Writer.WriteFieldHeaderCancelBegin();
                        }
                    }
                    ctx.MarkLabel(done);
                }
            }
        }
コード例 #27
0
 void IProtoTypeSerializer.EmitCreateInstance(Compiler.CompilerContext ctx)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         // different ways of creating a new instance
         bool callNoteObject = true;
         if (_factory != null)
         {
             EmitInvokeCallback(ctx, _factory, false, _constructType, ExpectedType);
         }
         else if (!_useConstructor || (_useConstructor && !_hasConstructor))
         { // DataContractSerializer style
             ctx.LoadValue(_constructType);
             ctx.EmitCall(ctx.MapType(typeof(BclHelpers)).GetMethod("GetUninitializedObject"));
             ctx.Cast(ExpectedType);
         }
         else if (_constructType.IsClass && _hasConstructor)
         { // XmlSerializer style
             ctx.EmitCtor(_constructType);
         }
         else
         {
             ctx.LoadValue(ExpectedType);
             ctx.EmitCall(
                 ctx.MapType(typeof(TypeModel)).GetMethod(
                     "ThrowCannotCreateInstance",
                     BindingFlags.Static | BindingFlags.Public));
             ctx.LoadNullRef();
             callNoteObject = false;
         }
         if (callNoteObject)
         {
             // track root object creation
             ctx.CopyValue();
             ctx.LoadReaderWriter();
             ctx.EmitCall(
                 ctx.MapType(typeof(ProtoReader)).GetMethod(
                     "NoteObject",
                     BindingFlags.Static | BindingFlags.Public));
         }
         if (_baseCtorCallbacks != null)
         {
             for (int i = 0; i < _baseCtorCallbacks.Length; i++)
             {
                 EmitInvokeCallback(ctx, _baseCtorCallbacks[i], true, null, ExpectedType);
             }
         }
     }
 }
コード例 #28
0
 protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         Tail.EmitRead(ctx, valueFrom);
         ctx.CopyValue();
         Compiler.CodeLabel @nonEmpty = ctx.DefineLabel(), @end = ctx.DefineLabel();
         ctx.LoadValue(typeof(string).GetProperty("Length"));
         ctx.BranchIfTrue(@nonEmpty, true);
         ctx.DiscardValue();
         ctx.LoadNullRef();
         ctx.Branch(@end, true);
         ctx.MarkLabel(@nonEmpty);
         ctx.EmitCtor(ctx.MapType(typeof(Uri)), ctx.MapType(typeof(string)));
         ctx.MarkLabel(@end);
     }
 }
コード例 #29
0
 void IProtoSerializer.EmitWrite(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         if (!EmitDedicatedMethod(ctx, valueFrom, false))
         {
             ctx.LoadValue(valueFrom);
             if (ExpectedType.IsValueType)
             {
                 ctx.CastToObject(ExpectedType);
             }
             ctx.LoadValue(ctx.MapMetaKeyToCompiledKey(_baseKey)); // re-map for formality, but would expect identical, else dedicated method
             ctx.LoadReaderWriter();
             ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("WriteRecursionSafeObject"));
         }
     }
 }
コード例 #30
0
        protected override void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using (ctx.StartDebugBlockAuto(this, _field.Name))
            {
                using (Compiler.Local loc = ctx.GetLocalWithValueForEmitRead(this, valueFrom))
                    using (Compiler.Local newVal = new Compiler.Local(ctx, _field.FieldType))
                    {
                        Compiler.Local valueForTail;
                        if (Tail.RequiresOldValue)
                        {
                            ctx.LoadAddress(loc, ExpectedType);
                            ctx.LoadValue(_field);
                            if (!Tail.EmitReadReturnsValue)
                            {
                                ctx.StoreValue(newVal);
                                valueForTail = newVal;
                            }
                            else
                            {
                                valueForTail = null; // on stack
                            }
                        }
                        else
                        {
                            valueForTail = null;
                        }

                        Tail.EmitRead(ctx, valueForTail);

                        if (Tail.EmitReadReturnsValue)
                        {
                            ctx.StoreValue(newVal);
                        }

                        ctx.LoadAddress(loc, ExpectedType);
                        ctx.LoadValue(newVal);
                        ctx.StoreValue(_field);

                        if (EmitReadReturnsValue)
                        {
                            ctx.LoadValue(loc);
                        }
                    }
            }
        }