void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)

        {
            Helpers.DebugAssert(valueFrom != null);                                  // don't support stack-head for this

            using (Compiler.Local converted = new Compiler.Local(ctx, declaredType)) // declare/re-use local

            {
                ctx.LoadValue(valueFrom);  // load primary onto stack

                ctx.EmitCall(toTail);      // static convert op, primary-to-surrogate

                ctx.StoreValue(converted); // store into surrogate local



                rootTail.EmitRead(ctx, converted); // downstream processing against surrogate local



                ctx.LoadValue(converted);  // load from surrogate local

                ctx.EmitCall(fromTail);    // static convert op, surrogate-to-primary

                ctx.StoreValue(valueFrom); // store back into primary
            }
        }
예제 #2
0
 void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     using (ctx.StartDebugBlockAuto(this))
     {
         _head.EmitRead(ctx, valueFrom);
     }
 }
 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);
     }
 }
예제 #4
0
        void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using (ctx.StartDebugBlockAuto(this))
            {
                using (Compiler.Local value = ctx.GetLocalWithValueForEmitRead(this, valueFrom))
                    using (Compiler.Local converted = new Compiler.Local(ctx, _declaredType)) // declare/re-use local
                        using (Compiler.Local reservedTrap = new Compiler.Local(ctx, typeof(int)))
                        {
                            var g = ctx.G;

                            if (!ExpectedType.IsValueType)
                            {
                                g.Assign(reservedTrap, g.ReaderFunc.ReserveNoteObject_int());
                            }

                            ctx.LoadValue(value);                                                   // load primary onto stack
                            ctx.EmitCall(_toTail);                                                  // static convert op, primary-to-surrogate

                            ctx.StoreValue(converted);                                              // store into surrogate local

                            _rootTail.EmitRead(ctx, _rootTail.RequiresOldValue ? converted : null); // downstream processing against surrogate local

                            if (_rootTail.EmitReadReturnsValue)
                            {
                                ctx.StoreValue(converted);
                            }

                            ctx.LoadValue(converted); // load from surrogate local
                            ctx.EmitCall(_fromTail);  // static convert op, surrogate-to-primary
                            ctx.StoreValue(value);    // store back into primary

                            if (!ExpectedType.IsValueType)
                            {
                                g.Reader.NoteReservedTrappedObject(reservedTrap, value);
                            }

                            if (EmitReadReturnsValue)
                            {
                                ctx.LoadValue(value);
                            }
                        }
            }
        }
예제 #5
0
 void IProtoSerializer.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 {
     head.EmitRead(ctx, valueFrom);
 }
예제 #6
0
        public void EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
        {
            using (ctx.StartDebugBlockAuto(this))
            {
                var g = ctx.G;

                g.Reader.ExpectRoot();
                if (_protoCompatibility)
                {
                    _serializer.EmitRead(ctx, _serializer.RequiresOldValue ? valueFrom : null);
                    return;
                }

                using (var rootToken = ctx.Local(typeof(SubItemToken)))
                    using (var typeKey = ctx.Local(typeof(int)))
                        using (var obj = ctx.Local(typeof(object)))
                            using (var formatVersion = ctx.Local(typeof(int)))
                                using (var expectedRefKey = ctx.Local(typeof(int)))
                                    using (var actualRefKey = ctx.Local(typeof(int)))
                                        using (var value = ctx.GetLocalWithValueForEmitRead(this, valueFrom))
                                        {
                                            g.Assign(rootToken, g.ReaderFunc.StartSubItem());
                                            g.Assign(formatVersion, g.ReaderFunc.ReadFieldHeader_int());
                                            g.If(formatVersion.AsOperand != CurrentFormatVersion);
                                            {
                                                g.ThrowProtoException("Wrong format version, required " + CurrentFormatVersion + " but actual " + formatVersion.AsOperand);
                                            }
                                            g.End();
                                            _serializer.EmitRead(ctx, _serializer.RequiresOldValue ? value : null);
                                            if (_serializer.EmitReadReturnsValue)
                                            {
                                                g.Assign(value, g.GetStackValueOperand(ExpectedType));
                                            }

                                            g.While(g.StaticFactory.Invoke(typeof(ProtoReader), nameof(ProtoReader.TryGetNextLateReference), typeKey, obj, expectedRefKey, g.ArgReaderWriter()));
                                            {
                                                g.DoWhile();
                                                {
                                                    g.Assign(actualRefKey, g.ReaderFunc.ReadFieldHeader_int() - 1);
                                                    g.If(actualRefKey.AsOperand != expectedRefKey.AsOperand);
                                                    {
                                                        g.If(actualRefKey.AsOperand <= -1);
                                                        {
                                                            g.ThrowProtoException("Expected field for late reference");
                                                        }
                                                        g.End();
                                                        g.If(actualRefKey.AsOperand > expectedRefKey.AsOperand);
                                                        {
                                                            g.ThrowProtoException("Mismatched order of late reference objects");
                                                        }
                                                        g.End();
                                                        g.Reader.SkipField();
                                                    }
                                                    g.End();
                                                }
                                                g.EndDoWhile(actualRefKey.AsOperand < expectedRefKey.AsOperand);
                                                g.If(!g.StaticFactory.InvokeReferenceEquals(g.ReaderFunc.ReadObject(obj, typeKey), obj));
                                                {
                                                    g.ThrowProtoException("Late reference changed during deserializing");
                                                }
                                                g.End();
                                            }
                                            g.End();
                                            g.Reader.EndSubItem(rootToken);

                                            if (EmitReadReturnsValue)
                                            {
                                                ctx.LoadValue(value);
                                            }
                                        }
            }
        }
예제 #7
0
 void IRuntimeProtoSerializerNode.EmitRead(Compiler.CompilerContext ctx, Compiler.Local valueFrom)
 => head.EmitRead(ctx, valueFrom);