public void GenerateLoad(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen> pushCtx, Action <IILGen> pushDescriptor, Type targetType)
        {
            var localResult  = ilGenerator.DeclareLocal(targetType);
            var finish       = ilGenerator.DefineLabel();
            var noValue      = ilGenerator.DefineLabel();
            var itemType     = targetType.GetGenericArguments()[0];
            var nullableType = typeof(Nullable <>).MakeGenericType(itemType);

            if (!targetType.IsAssignableFrom(nullableType))
            {
                throw new NotSupportedException();
            }
            ilGenerator
            .Do(pushReader)
            .Callvirt(() => default(AbstractBufferedReader).ReadBool())
            .Brfalse(noValue);
            _itemDescriptor.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor).LdcI4(0).Callvirt(() => default(ITypeDescriptor).NestedType(0)), itemType, _convertorGenerator);
            ilGenerator
            .Newobj(nullableType.GetConstructor(new[] { itemType }))
            .Stloc(localResult)
            .BrS(finish)
            .Mark(noValue)
            .Ldloca(localResult)
            .InitObj(nullableType)
            .Mark(finish)
            .Ldloc(localResult);
        }
Beispiel #2
0
        public void Skip(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen> pushCtx)
        {
            var localCount = ilGenerator.DeclareLocal(typeof(uint));
            var finish     = ilGenerator.DefineLabel();
            var next       = ilGenerator.DefineLabel();

            ilGenerator
            .Do(pushCtx)
            .Do(pushReader)
            .Callvirt(typeof(IReaderCtx).GetMethod(nameof(IReaderCtx.SkipObject)) !)
            .Brfalse(finish)
            .Do(pushReader)
            .Call(typeof(SpanReader).GetMethod(nameof(SpanReader.ReadVUInt32)) !)
            .Stloc(localCount)
            .Mark(next)
            .Ldloc(localCount)
            .Brfalse(finish)
            .Ldloc(localCount)
            .LdcI4(1)
            .Sub()
            .ConvU4()
            .Stloc(localCount)
            .GenerateSkip(_keysHandler, pushReader, pushCtx)
            .GenerateSkip(_valuesHandler, pushReader, pushCtx)
            .Br(next)
            .Mark(finish);
        }
Beispiel #3
0
 public bool FreeContent(IILGen ilGenerator, Action<IILGen> pushReaderOrCtx)
 {
     var needsFreeContent = false;
     var localCount = ilGenerator.DeclareLocal(typeof(uint));
     var finish = ilGenerator.DefineLabel();
     var next = ilGenerator.DefineLabel();
     ilGenerator
         .Do(pushReaderOrCtx)
         .Callvirt(() => ((IReaderCtx)null).SkipObject())
         .Brfalse(finish)
         .Do(Extensions.PushReaderFromCtx(pushReaderOrCtx))
         .Callvirt(() => ((AbstractBufferedReader)null).ReadVUInt32())
         .Stloc(localCount)
         .Mark(next)
         .Ldloc(localCount)
         .Brfalse(finish)
         .Ldloc(localCount)
         .LdcI4(1)
         .Sub()
         .ConvU4()
         .Stloc(localCount)
         .GenerateFreeContent(_keysHandler, pushReaderOrCtx, ref needsFreeContent)
         .GenerateFreeContent(_valuesHandler, pushReaderOrCtx, ref needsFreeContent)
         .Br(next)
         .Mark(finish);
     return needsFreeContent;
 }
Beispiel #4
0
        internal static void FillBufferWhenNotIgnoredKeyPropositionIl(ushort advEnumParamOrder, TableFieldInfo field, IILLocal emptyBufferLoc,
                                                                      FieldInfo instField, IILGen ilGenerator)
        {
            //stack contains KeyProposition
            var ignoreLabel = ilGenerator.DefineLabel(instField + "_ignore");
            var doneLabel   = ilGenerator.DefineLabel(instField + "_done");
            var writerLoc   = ilGenerator.DeclareLocal(typeof(AbstractBufferedWriter));

            ilGenerator
            .Dup()
            .LdcI4((int)KeyProposition.Ignored)
            .BeqS(ignoreLabel)
            .Newobj(() => new ByteBufferWriter())
            .Stloc(writerLoc);
            field.Handler.Save(ilGenerator,
                               il => il.Ldloc(writerLoc),
                               il => il.Ldarg(advEnumParamOrder).Ldfld(instField));
            var dataGetter = typeof(ByteBufferWriter).GetProperty("Data").GetGetMethod(true);

            ilGenerator.Ldloc(writerLoc).Callvirt(dataGetter);
            ilGenerator
            .Br(doneLabel)
            .Mark(ignoreLabel)
            .Ldloc(emptyBufferLoc)
            .Mark(doneLabel);
        }
Beispiel #5
0
            public void GenerateTypeIterator(IILGen ilGenerator, Action <IILGen> pushObj, Action <IILGen> pushCtx, Type type)
            {
                var finish     = ilGenerator.DefineLabel();
                var next       = ilGenerator.DefineLabel();
                var itemType   = _listTypeDescriptor._typeSerializers.LoadAsType(_listTypeDescriptor._itemDescriptor);
                var localList  = ilGenerator.DeclareLocal(typeof(IList <>).MakeGenericType(itemType));
                var localIndex = ilGenerator.DeclareLocal(typeof(int));
                var localCount = ilGenerator.DeclareLocal(typeof(int));

                ilGenerator
                .Do(pushObj)
                .Castclass(localList.LocalType)
                .Stloc(localList)
                .Ldloc(localList)
                .Callvirt(localList.LocalType.GetInterface("ICollection`1").GetProperty("Count").GetGetMethod())
                .Stloc(localCount)
                .LdcI4(0)
                .Stloc(localIndex)
                .Mark(next)
                .Ldloc(localIndex)
                .Ldloc(localCount)
                .BgeUn(finish)
                .Do(pushCtx)
                .Ldloc(localList)
                .Ldloc(localIndex)
                .Callvirt(localList.LocalType.GetMethod("get_Item"))
                .Callvirt(() => default(IDescriptorSerializerLiteContext).StoreNewDescriptors(null))
                .Ldloc(localIndex)
                .LdcI4(1)
                .Add()
                .Stloc(localIndex)
                .Br(next)
                .Mark(finish);
            }
Beispiel #6
0
        public NeedsFreeContent FreeContent(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen> pushCtx)
        {
            var localCount       = ilGenerator.DeclareLocal(typeof(uint));
            var finish           = ilGenerator.DefineLabel();
            var next             = ilGenerator.DefineLabel();
            var needsFreeContent = NeedsFreeContent.No;

            ilGenerator
            .Do(pushCtx)
            .Do(pushReader)
            .Callvirt(typeof(IReaderCtx).GetMethod(nameof(IReaderCtx.SkipObject)) !)
            .Brfalse(finish)
            .Do(pushReader)
            .Call(typeof(SpanReader).GetMethod(nameof(SpanReader.ReadVUInt32)) !)
            .Stloc(localCount)
            .Mark(next)
            .Ldloc(localCount)
            .Brfalse(finish)
            .Ldloc(localCount)
            .LdcI4(1)
            .Sub()
            .ConvU4()
            .Stloc(localCount)
            .GenerateFreeContent(_itemsHandler, pushReader, pushCtx, ref needsFreeContent)
            .Br(next)
            .Mark(finish);
            return(needsFreeContent);
        }
Beispiel #7
0
        public void Skip(IILGen ilGenerator, Action <IILGen> pushReaderOrCtx)
        {
            var localCount = ilGenerator.DeclareLocal(typeof(uint));
            var finish     = ilGenerator.DefineLabel();
            var next       = ilGenerator.DefineLabel();

            ilGenerator
            .Do(pushReaderOrCtx)
            .Callvirt(() => ((IReaderCtx)null).SkipObject())
            .Brfalse(finish)
            .Do(Extensions.PushReaderFromCtx(pushReaderOrCtx))
            .Callvirt(() => ((AbstractBufferedReader)null).ReadVUInt32())
            .Stloc(localCount)
            .Mark(next)
            .Ldloc(localCount)
            .Brfalse(finish)
            .Ldloc(localCount)
            .LdcI4(1)
            .Sub()
            .ConvU4()
            .Stloc(localCount)
            .GenerateSkip(_keysHandler, pushReaderOrCtx)
            .GenerateSkip(_valuesHandler, pushReaderOrCtx)
            .Br(next)
            .Mark(finish);
        }
        public void GenerateSkip(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen> pushCtx)
        {
            var localCount   = ilGenerator.DeclareLocal(typeof(uint));
            var skipFinished = ilGenerator.DefineLabel();
            var next         = ilGenerator.DefineLabel();

            ilGenerator
            .Do(pushReader)
            .Callvirt(() => default(AbstractBufferedReader).ReadVUInt32())
            .Stloc(localCount)
            .Ldloc(localCount)
            .Brfalse(skipFinished)
            .Mark(next)
            .Ldloc(localCount)
            .LdcI4(1)
            .Sub()
            .Stloc(localCount)
            .Ldloc(localCount)
            .Brfalse(skipFinished);
            _keyDescriptor.GenerateSkipEx(ilGenerator, pushReader, pushCtx);
            _valueDescriptor.GenerateSkipEx(ilGenerator, pushReader, pushCtx);
            ilGenerator
            .Br(next)
            .Mark(skipFinished);
        }
Beispiel #9
0
        public bool FreeContent(IILGen ilGenerator, Action <IILGen> pushReaderOrCtx)
        {
            var localCount       = ilGenerator.DeclareLocal(typeof(uint));
            var finish           = ilGenerator.DefineLabel();
            var next             = ilGenerator.DefineLabel();
            var needsFreeContent = false;

            ilGenerator
            .Do(pushReaderOrCtx)
            .Callvirt(() => default(IReaderCtx).SkipObject())
            .Brfalse(finish)
            .Do(Extensions.PushReaderFromCtx(pushReaderOrCtx))
            .Callvirt(() => default(AbstractBufferedReader).ReadVUInt32())
            .Stloc(localCount)
            .Mark(next)
            .Ldloc(localCount)
            .Brfalse(finish)
            .Ldloc(localCount)
            .LdcI4(1)
            .Sub()
            .ConvU4()
            .Stloc(localCount)
            .GenerateFreeContent(_itemsHandler, pushReaderOrCtx, ref needsFreeContent)
            .Br(next)
            .Mark(finish);
            return(needsFreeContent);
        }
Beispiel #10
0
        public void Save(IILGen ilGenerator, Action <IILGen> pushWriter, Action <IILGen> pushCtx,
                         Action <IILGen> pushValue)
        {
            var realFinish          = ilGenerator.DefineLabel();
            var finish              = ilGenerator.DefineLabel();
            var next                = ilGenerator.DefineLabel();
            var localValue          = ilGenerator.DeclareLocal(_type !);
            var typeAsICollection   = _type.GetInterface("ICollection`1");
            var typeAsIEnumerable   = _type.GetInterface("IEnumerable`1");
            var getEnumeratorMethod = typeAsIEnumerable !.GetMethod("GetEnumerator");
            var typeAsIEnumerator   = getEnumeratorMethod !.ReturnType;
            var typeKeyValuePair    = typeAsICollection !.GetGenericArguments()[0];
            var localEnumerator     = ilGenerator.DeclareLocal(typeAsIEnumerator);
            var localPair           = ilGenerator.DeclareLocal(typeKeyValuePair);

            ilGenerator
            .Do(pushValue)
            .Stloc(localValue)
            .Do(pushCtx)
            .Do(pushWriter)
            .Ldloc(localValue)
            .Castclass(typeof(object))
            .Callvirt(typeof(IWriterCtx).GetMethod(nameof(IWriterCtx.WriteObject)) !)
            .Brfalse(realFinish)
            .Do(pushWriter)
            .Ldloc(localValue)
            .Callvirt(typeAsICollection.GetProperty("Count") !.GetGetMethod() !)
            .ConvU4()
            .Call(typeof(SpanWriter).GetMethod(nameof(SpanWriter.WriteVUInt32)) !)
            .Ldloc(localValue)
            .Callvirt(getEnumeratorMethod)
            .Stloc(localEnumerator)
            .Try()
            .Mark(next)
            .Ldloc(localEnumerator)
            .Callvirt(() => default(IEnumerator).MoveNext())
            .Brfalse(finish)
            .Ldloc(localEnumerator)
            .Callvirt(typeAsIEnumerator.GetProperty("Current") !.GetGetMethod() !)
            .Stloc(localPair);
            var keyAndValueTypes = _type.GetGenericArguments();

            _keysHandler.Save(ilGenerator, pushWriter, pushCtx, il => il
                              .Ldloca(localPair)
                              .Call(typeKeyValuePair.GetProperty("Key") !.GetGetMethod() !)
                              .Do(_typeConvertGenerator.GenerateConversion(keyAndValueTypes[0], _keysHandler.HandledType()) !));
            _valuesHandler.Save(ilGenerator, pushWriter, pushCtx, il => il
                                .Ldloca(localPair)
                                .Call(typeKeyValuePair.GetProperty("Value") !.GetGetMethod() !)
                                .Do(_typeConvertGenerator.GenerateConversion(keyAndValueTypes[1], _valuesHandler.HandledType()) !));
            ilGenerator
            .Br(next)
            .Mark(finish)
            .Finally()
            .Ldloc(localEnumerator)
            .Callvirt(() => default(IDisposable).Dispose())
            .EndTry()
            .Mark(realFinish);
        }
Beispiel #11
0
        public void Save(IILGen ilGenerator, Action <IILGen> pushWriterOrCtx, Action <IILGen> pushValue)
        {
            var realfinish          = ilGenerator.DefineLabel();
            var finish              = ilGenerator.DefineLabel();
            var next                = ilGenerator.DefineLabel();
            var localValue          = ilGenerator.DeclareLocal(_type);
            var typeAsICollection   = _type.GetInterface("ICollection`1");
            var typeAsIEnumerable   = _type.GetInterface("IEnumerable`1");
            var getEnumeratorMethod = typeAsIEnumerable.GetMethod("GetEnumerator");
            var typeAsIEnumerator   = getEnumeratorMethod.ReturnType;
            var typeKeyValuePair    = typeAsICollection.GetGenericArguments()[0];
            var localEnumerator     = ilGenerator.DeclareLocal(typeAsIEnumerator);
            var localPair           = ilGenerator.DeclareLocal(typeKeyValuePair);

            ilGenerator
            .Do(pushValue)
            .Stloc(localValue)
            .Do(pushWriterOrCtx)
            .Ldloc(localValue)
            .Castclass(typeof(object))
            .Callvirt(() => default(IWriterCtx).WriteObject(null))
            .Brfalse(realfinish)
            .Do(Extensions.PushWriterFromCtx(pushWriterOrCtx))
            .Ldloc(localValue)
            .Callvirt(typeAsICollection.GetProperty("Count").GetGetMethod())
            .ConvU4()
            .Callvirt(() => default(AbstractBufferedWriter).WriteVUInt32(0))
            .Ldloc(localValue)
            .Callvirt(getEnumeratorMethod)
            .Stloc(localEnumerator)
            .Try()
            .Mark(next)
            .Ldloc(localEnumerator)
            .Callvirt(() => default(IEnumerator).MoveNext())
            .Brfalse(finish)
            .Ldloc(localEnumerator)
            .Callvirt(typeAsIEnumerator.GetProperty("Current").GetGetMethod())
            .Stloc(localPair);
            _keysHandler.Save(ilGenerator, Extensions.PushWriterOrCtxAsNeeded(pushWriterOrCtx, _keysHandler.NeedsCtx()), il => il
                              .Ldloca(localPair)
                              .Call(typeKeyValuePair.GetProperty("Key").GetGetMethod())
                              .Do(_typeConvertorGenerator.GenerateConversion(_type.GetGenericArguments()[0], _keysHandler.HandledType())));
            _valuesHandler.Save(ilGenerator, Extensions.PushWriterOrCtxAsNeeded(pushWriterOrCtx, _valuesHandler.NeedsCtx()), il => il
                                .Ldloca(localPair)
                                .Call(typeKeyValuePair.GetProperty("Value").GetGetMethod())
                                .Do(_typeConvertorGenerator.GenerateConversion(_type.GetGenericArguments()[1], _valuesHandler.HandledType())));
            ilGenerator
            .Br(next)
            .Mark(finish)
            .Finally()
            .Ldloc(localEnumerator)
            .Callvirt(() => default(IDisposable).Dispose())
            .EndTry()
            .Mark(realfinish);
        }
Beispiel #12
0
        public void Load(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen> pushCtx)
        {
            var localCount          = ilGenerator.DeclareLocal(typeof(uint));
            var localResultOfObject = ilGenerator.DeclareLocal(typeof(object));
            var localResult         = ilGenerator.DeclareLocal(HandledType());
            var loadSkipped         = ilGenerator.DefineLabel();
            var loadFinished        = ilGenerator.DefineLabel();
            var finish = ilGenerator.DefineLabel();
            var next   = ilGenerator.DefineLabel();
            var collectionInterface = _type !.SpecializationOf(typeof(ICollection <>));
            var itemType            = collectionInterface !.GetGenericArguments()[0];

            ilGenerator
            .Do(pushCtx)
            .Do(pushReader)
            .Ldloca(localResultOfObject)
            .Callvirt(typeof(IReaderCtx).GetMethod(nameof(IReaderCtx.ReadObject)) !)
            .Brfalse(loadSkipped)
            .Do(pushReader)
            .Call(typeof(SpanReader).GetMethod(nameof(SpanReader.ReadVUInt32)) !)
            .Stloc(localCount)
            .Ldloc(localCount)
            .Newobj((_isSet ? typeof(HashSet <>) : typeof(List <>)).MakeGenericType(itemType).GetConstructor(new[] { typeof(int) }) !)
            .Stloc(localResult)
            .Do(pushCtx)
            .Ldloc(localResult)
            .Castclass(typeof(object))
            .Callvirt(() => default(IReaderCtx).RegisterObject(null))
            .Mark(next)
            .Ldloc(localCount)
            .Brfalse(loadFinished)
            .Ldloc(localCount)
            .LdcI4(1)
            .Sub()
            .ConvU4()
            .Stloc(localCount)
            .Ldloc(localResult)
            .GenerateLoad(_itemsHandler, itemType, pushReader, pushCtx, _typeConvertGenerator)
            .Callvirt(collectionInterface !.GetMethod("Add") !)
            .Br(next)
            .Mark(loadFinished)
            .Do(pushCtx)
            .Do(pushReader)
            .Callvirt(typeof(IReaderCtx).GetMethod(nameof(IReaderCtx.ReadObjectDone)) !)
            .Br(finish)
            .Mark(loadSkipped)
            .Ldloc(localResultOfObject)
            .Isinst(_type)
            .Stloc(localResult)
            .Mark(finish)
            .Ldloc(localResult);
        }
Beispiel #13
0
        public void GenerateLoad(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen> pushCtx, Action <IILGen> pushDescriptor, Type targetType)
        {
            if (targetType == typeof(object))
            {
                targetType = GetPreferedType();
            }
            var localCount                      = ilGenerator.DeclareLocal(typeof(int));
            var targetIDictionary               = GetInterface(targetType);
            var targetTypeArguments             = targetIDictionary.GetGenericArguments();
            var keyType                         = _typeSerializers.LoadAsType(_keyDescriptor, targetTypeArguments[0]);
            var valueType                       = _typeSerializers.LoadAsType(_valueDescriptor, targetTypeArguments[1]);
            var dictionaryTypeGenericDefinition = targetType.InheritsOrImplements(typeof(IOrderedDictionary <,>)) ? typeof(OrderedDictionaryWithDescriptor <,>) : typeof(DictionaryWithDescriptor <,>);
            var dictionaryType                  = dictionaryTypeGenericDefinition.MakeGenericType(keyType, valueType);

            if (!targetType.IsAssignableFrom(dictionaryType))
            {
                throw new InvalidOperationException();
            }
            var localDict    = ilGenerator.DeclareLocal(dictionaryType);
            var loadFinished = ilGenerator.DefineLabel();
            var next         = ilGenerator.DefineLabel();

            ilGenerator
            .Do(pushReader)
            .Callvirt(() => default(AbstractBufferedReader).ReadVUInt32())
            .ConvI4()
            .Dup()
            .LdcI4(1)
            .Sub()
            .Stloc(localCount)
            .Brfalse(loadFinished)
            .Ldloc(localCount)
            .Do(pushDescriptor)
            .Newobj(dictionaryType.GetConstructor(new[] { typeof(int), typeof(ITypeDescriptor) }))
            .Stloc(localDict)
            .Mark(next)
            .Ldloc(localCount)
            .Brfalse(loadFinished)
            .Ldloc(localCount)
            .LdcI4(1)
            .Sub()
            .Stloc(localCount)
            .Ldloc(localDict);
            _keyDescriptor.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor).LdcI4(0).Callvirt(() => default(ITypeDescriptor).NestedType(0)), keyType, _convertorGenerator);
            _valueDescriptor.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor).LdcI4(1).Callvirt(() => default(ITypeDescriptor).NestedType(0)), valueType, _convertorGenerator);
            ilGenerator
            .Callvirt(dictionaryType.GetMethod(nameof(IDictionary.Add)))
            .Br(next)
            .Mark(loadFinished)
            .Ldloc(localDict)
            .Castclass(targetType);
        }
Beispiel #14
0
        public void Load(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen> pushCtx)
        {
            var localCount          = ilGenerator.DeclareLocal(typeof(uint));
            var localResultOfObject = ilGenerator.DeclareLocal(typeof(object));
            var localResult         = ilGenerator.DeclareLocal(HandledType());
            var loadSkipped         = ilGenerator.DefineLabel();
            var finish           = ilGenerator.DefineLabel();
            var readFinish       = ilGenerator.DefineLabel();
            var next             = ilGenerator.DefineLabel();
            var genericArguments = _type !.GetGenericArguments();

            ilGenerator
            .Do(pushCtx)
            .Do(pushReader)
            .Ldloca(localResultOfObject)
            .Callvirt(typeof(IReaderCtx).GetMethod(nameof(IReaderCtx.ReadObject)) !)
            .Brfalse(loadSkipped)
            .Do(pushReader)
            .Call(typeof(SpanReader).GetMethod(nameof(SpanReader.ReadVUInt32)) !)
            .Stloc(localCount)
            .Ldloc(localCount)
            .Newobj(typeof(Dictionary <,>).MakeGenericType(genericArguments).GetConstructor(new[] { typeof(int) }) !)
            .Stloc(localResult)
            .Do(pushCtx)
            .Ldloc(localResult)
            .Castclass(typeof(object))
            .Callvirt(() => default(IReaderCtx).RegisterObject(null))
            .Mark(next)
            .Ldloc(localCount)
            .Brfalse(readFinish)
            .Ldloc(localCount)
            .LdcI4(1)
            .Sub()
            .ConvU4()
            .Stloc(localCount)
            .Ldloc(localResult)
            .GenerateLoad(_keysHandler, genericArguments[0], pushReader, pushCtx, _typeConvertGenerator)
            .GenerateLoad(_valuesHandler, genericArguments[1], pushReader, pushCtx, _typeConvertGenerator)
            .Callvirt(_type.GetMethod("Add") !)
            .Br(next)
            .Mark(readFinish)
            .Do(pushCtx)
            .Do(pushReader)
            .Callvirt(typeof(IReaderCtx).GetMethod(nameof(IReaderCtx.ReadObjectDone)) !)
            .Br(finish)
            .Mark(loadSkipped)
            .Ldloc(localResultOfObject)
            .Isinst(_type)
            .Stloc(localResult)
            .Mark(finish)
            .Ldloc(localResult);
        }
Beispiel #15
0
 public void Load(IILGen ilGenerator, Action<IILGen> pushReaderOrCtx)
 {
     var localCount = ilGenerator.DeclareLocal(typeof(uint));
     var localResultOfObject = ilGenerator.DeclareLocal(typeof(object));
     var localResult = ilGenerator.DeclareLocal(HandledType());
     var loadSkipped = ilGenerator.DefineLabel();
     var finish = ilGenerator.DefineLabel();
     var readfinish = ilGenerator.DefineLabel();
     var next = ilGenerator.DefineLabel();
     var genericArguments = _type.GetGenericArguments();
     object fake;
     ilGenerator
         .Do(pushReaderOrCtx)
         .Ldloca(localResultOfObject)
         .Callvirt(() => default(IReaderCtx).ReadObject(out fake))
         .Brfalse(loadSkipped)
         .Do(Extensions.PushReaderFromCtx(pushReaderOrCtx))
         .Callvirt(() => default(AbstractBufferedReader).ReadVUInt32())
         .Stloc(localCount)
         .Ldloc(localCount)
         .Newobj(typeof(Dictionary<,>).MakeGenericType(genericArguments).GetConstructor(new[] { typeof(int) }))
         .Stloc(localResult)
         .Do(pushReaderOrCtx)
         .Ldloc(localResult)
         .Castclass(typeof(object))
         .Callvirt(() => default(IReaderCtx).RegisterObject(null))
         .Mark(next)
         .Ldloc(localCount)
         .Brfalse(readfinish)
         .Ldloc(localCount)
         .LdcI4(1)
         .Sub()
         .ConvU4()
         .Stloc(localCount)
         .Ldloc(localResult)
         .GenerateLoad(_keysHandler, genericArguments[0], pushReaderOrCtx, _typeConvertorGenerator)
         .GenerateLoad(_valuesHandler, genericArguments[1], pushReaderOrCtx, _typeConvertorGenerator)
         .Callvirt(_type.GetMethod("Add"))
         .Br(next)
         .Mark(readfinish)
         .Do(pushReaderOrCtx)
         .Callvirt(() => default(IReaderCtx).ReadObjectDone())
         .Br(finish)
         .Mark(loadSkipped)
         .Ldloc(localResultOfObject)
         .Isinst(_type)
         .Stloc(localResult)
         .Mark(finish)
         .Ldloc(localResult);
 }
Beispiel #16
0
        public void Load(IILGen ilGenerator, Action <IILGen> pushReaderOrCtx)
        {
            var    localCount          = ilGenerator.DeclareLocal(typeof(uint));
            var    localResultOfObject = ilGenerator.DeclareLocal(typeof(object));
            var    localResult         = ilGenerator.DeclareLocal(HandledType());
            var    loadSkipped         = ilGenerator.DefineLabel();
            var    loadFinished        = ilGenerator.DefineLabel();
            var    finish = ilGenerator.DefineLabel();
            var    next   = ilGenerator.DefineLabel();
            object fake;

            ilGenerator
            .Do(pushReaderOrCtx)
            .Ldloca(localResultOfObject)
            .Callvirt(() => default(IReaderCtx).ReadObject(out fake))
            .Brfalse(loadSkipped)
            .Do(Extensions.PushReaderFromCtx(pushReaderOrCtx))
            .Callvirt(() => default(AbstractBufferedReader).ReadVUInt32())
            .Stloc(localCount)
            .Ldloc(localCount)
            .Newobj(typeof(List <>).MakeGenericType(_type.GetGenericArguments()[0]).GetConstructor(new[] { typeof(int) }))
            .Stloc(localResult)
            .Do(pushReaderOrCtx)
            .Ldloc(localResult)
            .Castclass(typeof(object))
            .Callvirt(() => default(IReaderCtx).RegisterObject(null))
            .Mark(next)
            .Ldloc(localCount)
            .Brfalse(loadFinished)
            .Ldloc(localCount)
            .LdcI4(1)
            .Sub()
            .ConvU4()
            .Stloc(localCount)
            .Ldloc(localResult)
            .GenerateLoad(_itemsHandler, _type.GetGenericArguments()[0], pushReaderOrCtx, _typeConvertorGenerator)
            .Callvirt(_type.GetInterface("ICollection`1").GetMethod("Add"))
            .Br(next)
            .Mark(loadFinished)
            .Do(pushReaderOrCtx)
            .Callvirt(() => default(IReaderCtx).ReadObjectDone())
            .Br(finish)
            .Mark(loadSkipped)
            .Ldloc(localResultOfObject)
            .Isinst(_type)
            .Stloc(localResult)
            .Mark(finish)
            .Ldloc(localResult);
        }
Beispiel #17
0
        public void GenerateSave(IILGen ilGenerator, Action <IILGen> pushWriter, Action <IILGen> pushCtx, Action <IILGen> pushValue, Type valueType)
        {
            var finish    = ilGenerator.DefineLabel();
            var next      = ilGenerator.DefineLabel();
            var notnull   = ilGenerator.DefineLabel();
            var itemType  = GetItemType(valueType);
            var localList = ilGenerator.DeclareLocal(
                typeof(IList <>).MakeGenericType(itemType));
            var localIndex = ilGenerator.DeclareLocal(typeof(int));
            var localCount = ilGenerator.DeclareLocal(typeof(int));

            ilGenerator
            .Do(pushValue)
            .Castclass(localList.LocalType)
            .Stloc(localList)
            .Ldloc(localList)
            .BrtrueS(notnull)
            .Do(pushWriter)
            .Callvirt(() => default(AbstractBufferedWriter).WriteByteZero())
            .Br(finish)
            .Mark(notnull)
            .Ldloc(localList)
            .Callvirt(localList.LocalType.GetInterface("ICollection`1").GetProperty("Count").GetGetMethod())
            .Stloc(localCount)
            .Do(pushWriter)
            .Ldloc(localCount)
            .LdcI4(1)
            .Add()
            .Callvirt(() => default(AbstractBufferedWriter).WriteVUInt32(0))
            .LdcI4(0)
            .Stloc(localIndex)
            .Mark(next)
            .Ldloc(localIndex)
            .Ldloc(localCount)
            .BgeUn(finish);
            _itemDescriptor.GenerateSaveEx(ilGenerator, pushWriter, pushCtx,
                                           il => il.Ldloc(localList)
                                           .Ldloc(localIndex)
                                           .Callvirt(localList.LocalType.GetMethod("get_Item")), itemType);
            ilGenerator
            .Ldloc(localIndex)
            .LdcI4(1)
            .Add()
            .Stloc(localIndex)
            .Br(next)
            .Mark(finish);
        }
Beispiel #18
0
        public void GenerateLoad(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen> pushCtx, Action <IILGen> pushDescriptor, Type targetType)
        {
            var localCount          = ilGenerator.DeclareLocal(typeof(int));
            var targetIList         = targetType.GetInterface("IList`1") ?? targetType;
            var targetTypeArguments = targetIList.GetGenericArguments();
            var itemType            = _typeSerializers.LoadAsType(_itemDescriptor, targetTypeArguments[0]);
            var listType            = typeof(ListWithDescriptor <>).MakeGenericType(itemType);

            if (!targetType.IsAssignableFrom(listType))
            {
                throw new NotSupportedException();
            }
            var localList    = ilGenerator.DeclareLocal(listType);
            var loadFinished = ilGenerator.DefineLabel();
            var next         = ilGenerator.DefineLabel();

            ilGenerator
            .Do(pushReader)
            .Callvirt(() => default(AbstractBufferedReader).ReadVUInt32())
            .ConvI4()
            .Dup()
            .Stloc(localCount)
            .Brfalse(loadFinished)
            .Ldloc(localCount)
            .LdcI4(1)
            .Sub()
            .Dup()
            .Stloc(localCount)
            .Do(pushDescriptor)
            .Newobj(listType.GetConstructor(new[] { typeof(int), typeof(ITypeDescriptor) }))
            .Stloc(localList)
            .Mark(next)
            .Ldloc(localCount)
            .Brfalse(loadFinished)
            .Ldloc(localCount)
            .LdcI4(1)
            .Sub()
            .Stloc(localCount)
            .Ldloc(localList);
            _itemDescriptor.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor).LdcI4(0).Callvirt(() => default(ITypeDescriptor).NestedType(0)), itemType, _convertorGenerator);
            ilGenerator
            .Callvirt(listType.GetInterface("ICollection`1").GetMethod("Add"))
            .Br(next)
            .Mark(loadFinished)
            .Ldloc(localList)
            .Castclass(targetType);
        }
Beispiel #19
0
        public void GenerateLoad(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen> pushCtx, Action <IILGen> pushDescriptor, Type targetType)
        {
            var localCount     = ilGenerator.DeclareLocal(typeof(int));
            var keyType        = _typeSerializers.LoadAsType(_keyDescriptor);
            var valueType      = _typeSerializers.LoadAsType(_valueDescriptor);
            var dictionaryType = typeof(DictionaryWithDescriptor <,>).MakeGenericType(keyType, valueType);

            if (!targetType.IsAssignableFrom(dictionaryType))
            {
                throw new InvalidOperationException();
            }
            var localDict    = ilGenerator.DeclareLocal(dictionaryType);
            var loadFinished = ilGenerator.DefineLabel();
            var next         = ilGenerator.DefineLabel();

            ilGenerator
            .Do(pushReader)
            .Callvirt(() => default(AbstractBufferedReader).ReadVUInt32())
            .ConvI4()
            .Dup()
            .LdcI4(1)
            .Sub()
            .Stloc(localCount)
            .Brfalse(loadFinished)
            .Ldloc(localCount)
            .Do(pushDescriptor)
            .Newobj(dictionaryType.GetConstructor(new[] { typeof(int), typeof(ITypeDescriptor) }))
            .Stloc(localDict)
            .Mark(next)
            .Ldloc(localCount)
            .Brfalse(loadFinished)
            .Ldloc(localCount)
            .LdcI4(1)
            .Sub()
            .Stloc(localCount)
            .Ldloc(localDict);
            _keyDescriptor.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor).LdcI4(0).Callvirt(() => default(ITypeDescriptor).NestedType(0)), keyType, _convertorGenerator);
            _valueDescriptor.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor).LdcI4(1).Callvirt(() => default(ITypeDescriptor).NestedType(0)), valueType, _convertorGenerator);
            ilGenerator
            .Callvirt(dictionaryType.GetMethod("Add"))
            .Br(next)
            .Mark(loadFinished)
            .Ldloc(localDict)
            .Castclass(targetType);
        }
Beispiel #20
0
        public void Save(IILGen ilGenerator, Action <IILGen> pushWriterOrCtx, Action <IILGen> pushValue)
        {
            var finish     = ilGenerator.DefineLabel();
            var next       = ilGenerator.DefineLabel();
            var localValue = ilGenerator.DeclareLocal(_type);
            var localIndex = ilGenerator.DeclareLocal(typeof(int));
            var localCount = ilGenerator.DeclareLocal(typeof(int));

            ilGenerator
            .LdcI4(0)
            .Stloc(localIndex)
            .Do(pushValue)
            .Stloc(localValue)
            .Do(pushWriterOrCtx)
            .Ldloc(localValue)
            .Castclass(typeof(object))
            .Callvirt(() => default(IWriterCtx).WriteObject(null))
            .Brfalse(finish)
            .Ldloc(localValue)
            .Callvirt(_type.GetInterface("ICollection`1").GetProperty("Count").GetGetMethod())
            .Stloc(localCount)
            .Do(Extensions.PushWriterFromCtx(pushWriterOrCtx))
            .Ldloc(localCount)
            .ConvU4()
            .Callvirt(() => default(AbstractBufferedWriter).WriteVUInt32(0))
            .Mark(next)
            .Ldloc(localIndex)
            .Ldloc(localCount)
            .BgeUn(finish);
            _itemsHandler.Save(ilGenerator, Extensions.PushWriterOrCtxAsNeeded(pushWriterOrCtx, _itemsHandler.NeedsCtx()), il => il
                               .Ldloc(localValue)
                               .Ldloc(localIndex)
                               .Callvirt(_type.GetMethod("get_Item"))
                               .Do(_typeConvertorGenerator.GenerateConversion(_type.GetGenericArguments()[0], _itemsHandler.HandledType())));
            ilGenerator
            .Ldloc(localIndex)
            .LdcI4(1)
            .Add()
            .Stloc(localIndex)
            .Br(next)
            .Mark(finish);
        }
Beispiel #21
0
        public void Skip(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen>?pushCtx)
        {
            var finish = ilGenerator.DefineLabel();

            ilGenerator
            .Do(pushReader)
            .Call(typeof(SpanReader).GetMethod(nameof(SpanReader.ReadBool)) !)
            .Brfalse(finish)
            .GenerateSkip(_itemHandler, pushReader, pushCtx)
            .Mark(finish);
        }
Beispiel #22
0
        public void Skip(IILGen ilGenerator, Action <IILGen> pushReaderOrCtx)
        {
            var finish = ilGenerator.DefineLabel();

            ilGenerator
            .Do(pushReaderOrCtx)
            .Callvirt(() => default(AbstractBufferedReader).ReadBool())
            .Brfalse(finish);
            _itemHandler.Skip(ilGenerator, pushReaderOrCtx);
            ilGenerator
            .Mark(finish);
        }
Beispiel #23
0
        public void GenerateSkip(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen> pushCtx)
        {
            var finish = ilGenerator.DefineLabel();

            ilGenerator
            .Do(pushReader)
            .Callvirt(() => default(AbstractBufferedReader).ReadBool())
            .Brfalse(finish);
            _itemDescriptor.GenerateSkipEx(ilGenerator, pushReader, pushCtx);
            ilGenerator
            .Mark(finish);
        }
Beispiel #24
0
        public void Load(IILGen ilGenerator, Action <IILGen> pushReaderOrCtx)
        {
            var localResult  = ilGenerator.DeclareLocal(HandledType());
            var finish       = ilGenerator.DefineLabel();
            var noValue      = ilGenerator.DefineLabel();
            var itemType     = _type.GetGenericArguments()[0];
            var nullableType = typeof(Nullable <>).MakeGenericType(itemType);

            ilGenerator
            .Do(pushReaderOrCtx)
            .Callvirt(() => default(AbstractBufferedReader).ReadBool())
            .Brfalse(noValue);
            _itemHandler.Load(ilGenerator, pushReaderOrCtx);
            _typeConvertorGenerator.GenerateConversion(_itemHandler.HandledType(), itemType)(ilGenerator);
            ilGenerator
            .Newobj(nullableType.GetConstructor(new[] { itemType }))
            .Stloc(localResult)
            .BrS(finish)
            .Mark(noValue)
            .Ldloca(localResult)
            .InitObj(nullableType)
            .Mark(finish)
            .Ldloc(localResult);
        }
Beispiel #25
0
        public void Load(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen>?pushCtx)
        {
            var localResult  = ilGenerator.DeclareLocal(HandledType());
            var finish       = ilGenerator.DefineLabel();
            var noValue      = ilGenerator.DefineLabel();
            var itemType     = _type !.GetGenericArguments()[0];
            var nullableType = typeof(Nullable <>).MakeGenericType(itemType);

            ilGenerator
            .Do(pushReader)
            .Call(typeof(SpanReader).GetMethod(nameof(SpanReader.ReadBool)) !)
            .Brfalse(noValue);
            _itemHandler.Load(ilGenerator, pushReader, pushCtx);
            _typeConvertorGenerator.GenerateConversion(_itemHandler.HandledType(), itemType) !(ilGenerator);
            ilGenerator
            .Newobj(nullableType.GetConstructor(new[] { itemType }) !)
            .Stloc(localResult)
            .BrS(finish)
            .Mark(noValue)
            .Ldloca(localResult)
            .InitObj(nullableType)
            .Mark(finish)
            .Ldloc(localResult);
        }
Beispiel #26
0
            public void GenerateTypeIterator(IILGen ilGenerator, Action <IILGen> pushObj, Action <IILGen> pushCtx, Type type)
            {
                var finish       = ilGenerator.DefineLabel();
                var itemType     = _nullableTypeDescriptor.GetPreferredType(type).GetGenericArguments()[0];
                var nullableType = typeof(Nullable <>).MakeGenericType(itemType);
                var localValue   = ilGenerator.DeclareLocal(nullableType);

                ilGenerator
                .Do(pushObj)
                .Stloc(localValue)
                .Ldloca(localValue)
                .Call(nullableType.GetMethod("get_HasValue"))
                .Brfalse(finish)
                .Ldloca(localValue)
                .Call(nullableType.GetMethod("get_Value"))
                .Callvirt(() => default(IDescriptorSerializerLiteContext).StoreNewDescriptors(null))
                .Mark(finish);
            }
Beispiel #27
0
        public void GenerateSave(IILGen ilGenerator, Action <IILGen> pushWriter, Action <IILGen> pushCtx, Action <IILGen> pushValue, Type valueType)
        {
            var itemType      = GetItemType(valueType);
            var localValue    = ilGenerator.DeclareLocal(valueType);
            var localHasValue = ilGenerator.DeclareLocal(typeof(bool));

            var finish = ilGenerator.DefineLabel();

            ilGenerator
            .Do(pushValue)
            .Stloc(localValue)
            .Do(pushWriter)
            .Ldloca(localValue)
            .Call(valueType.GetMethod("get_HasValue"))
            .Dup()
            .Stloc(localHasValue)
            .Callvirt(() => default(AbstractBufferedWriter).WriteBool(false))
            .Ldloc(localHasValue)
            .Brfalse(finish);
            _itemDescriptor.GenerateSaveEx(ilGenerator, pushWriter, pushCtx,
                                           il => il.Ldloca(localValue).Call(valueType.GetMethod("get_Value")), itemType);
            ilGenerator
            .Mark(finish);
        }
Beispiel #28
0
        public void Save(IILGen ilGenerator, Action <IILGen> pushWriterOrCtx, Action <IILGen> pushValue)
        {
            var nullableType  = typeof(Nullable <>).MakeGenericType(_type.GetGenericArguments()[0]);
            var localValue    = ilGenerator.DeclareLocal(nullableType);
            var localHasValue = ilGenerator.DeclareLocal(typeof(bool));
            var finish        = ilGenerator.DefineLabel();

            ilGenerator
            .Do(pushValue)
            .Stloc(localValue)
            .Do(pushWriterOrCtx)
            .Ldloca(localValue)     //Ldloca for struct!
            .Call(nullableType.GetMethod("get_HasValue"))
            .Dup()
            .Stloc(localHasValue)
            .Callvirt(() => default(AbstractBufferedWriter).WriteBool(false))
            .Ldloc(localHasValue)
            .Brfalse(finish);
            _itemHandler.Save(ilGenerator, pushWriterOrCtx,
                              il => il
                              .Ldloca(localValue).Call(_type.GetMethod("get_Value"))
                              .Do(_typeConvertorGenerator.GenerateConversion(_type.GetGenericArguments()[0], _itemHandler.HandledType())));
            ilGenerator.Mark(finish);
        }
Beispiel #29
0
        public void Save(IILGen ilGenerator, Action <IILGen> pushWriter, Action <IILGen>?pushCtx, Action <IILGen> pushValue)
        {
            var nullableType  = typeof(Nullable <>).MakeGenericType(_type !.GetGenericArguments()[0]);
            var localValue    = ilGenerator.DeclareLocal(nullableType);
            var localHasValue = ilGenerator.DeclareLocal(typeof(bool));
            var finish        = ilGenerator.DefineLabel();

            ilGenerator
            .Do(pushValue)
            .Stloc(localValue)
            .Do(pushWriter)
            .Ldloca(localValue)     //ref for struct!
            .Call(nullableType.GetMethod("get_HasValue") !)
            .Dup()
            .Stloc(localHasValue)
            .Call(typeof(SpanWriter).GetMethod(nameof(SpanWriter.WriteBool)) !)
            .Ldloc(localHasValue)
            .Brfalse(finish);
            _itemHandler.Save(ilGenerator, pushWriter, pushCtx,
                              il => il
                              .Ldloca(localValue).Call(_type.GetMethod("get_Value") !)
                              .Do(_typeConvertorGenerator.GenerateConversion(_type.GetGenericArguments()[0], _itemHandler.HandledType()) !));
            ilGenerator.Mark(finish);
        }
Beispiel #30
0
 public void GenerateLoad(IILGen ilGenerator, Action<IILGen> pushReader, Action<IILGen> pushCtx, Action<IILGen> pushDescriptor, Type targetType)
 {
     var localCount = ilGenerator.DeclareLocal(typeof(int));
     var targetIDictionary = targetType.GetInterface("IDictionary`2") ?? targetType;
     var targetTypeArguments = targetIDictionary.GetGenericArguments();
     var keyType = _typeSerializers.LoadAsType(_keyDescriptor, targetTypeArguments[0]);
     var valueType = _typeSerializers.LoadAsType(_valueDescriptor, targetTypeArguments[1]);
     var dictionaryType = typeof(DictionaryWithDescriptor<,>).MakeGenericType(keyType, valueType);
     if (!targetType.IsAssignableFrom(dictionaryType)) throw new InvalidOperationException();
     var localDict = ilGenerator.DeclareLocal(dictionaryType);
     var loadFinished = ilGenerator.DefineLabel();
     var next = ilGenerator.DefineLabel();
     ilGenerator
         .Do(pushReader)
         .Callvirt(() => default(AbstractBufferedReader).ReadVUInt32())
         .ConvI4()
         .Dup()
         .LdcI4(1)
         .Sub()
         .Stloc(localCount)
         .Brfalse(loadFinished)
         .Ldloc(localCount)
         .Do(pushDescriptor)
         .Newobj(dictionaryType.GetConstructor(new[] { typeof(int), typeof(ITypeDescriptor) }))
         .Stloc(localDict)
         .Mark(next)
         .Ldloc(localCount)
         .Brfalse(loadFinished)
         .Ldloc(localCount)
         .LdcI4(1)
         .Sub()
         .Stloc(localCount)
         .Ldloc(localDict);
     _keyDescriptor.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor).LdcI4(0).Callvirt(() => default(ITypeDescriptor).NestedType(0)), keyType, _convertorGenerator);
     _valueDescriptor.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor).LdcI4(1).Callvirt(() => default(ITypeDescriptor).NestedType(0)), valueType, _convertorGenerator);
     ilGenerator
         .Callvirt(dictionaryType.GetMethod("Add"))
         .Br(next)
         .Mark(loadFinished)
         .Ldloc(localDict)
         .Castclass(targetType);
 }
Beispiel #31
0
 public void GenerateLoad(IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen> pushCtx, Action <IILGen> pushDescriptor, Type targetType)
 {
     if (targetType == typeof(object))
     {
         var resultLoc  = ilGenerator.DeclareLocal(typeof(DynamicObject), "result");
         var labelNoCtx = ilGenerator.DefineLabel();
         ilGenerator
         .Do(pushDescriptor)
         .Castclass(typeof(ObjectTypeDescriptor))
         .Newobj(typeof(DynamicObject).GetConstructor(new[] { typeof(ObjectTypeDescriptor) }))
         .Stloc(resultLoc)
         .Do(pushCtx)
         .BrfalseS(labelNoCtx)
         .Do(pushCtx)
         .Ldloc(resultLoc)
         .Callvirt(() => default(ITypeBinaryDeserializerContext).AddBackRef(null))
         .Mark(labelNoCtx);
         var idx = 0;
         foreach (var pair in _fields)
         {
             var idxForCapture = idx;
             ilGenerator.Ldloc(resultLoc);
             ilGenerator.LdcI4(idx);
             pair.Value.GenerateLoadEx(ilGenerator, pushReader, pushCtx,
                                       il =>
                                       il.Do(pushDescriptor)
                                       .LdcI4(idxForCapture)
                                       .Callvirt(() => default(ITypeDescriptor).NestedType(0)), typeof(object), _typeSerializers.ConvertorGenerator);
             ilGenerator.Callvirt(() => default(DynamicObject).SetFieldByIdxFast(0, null));
             idx++;
         }
         ilGenerator
         .Ldloc(resultLoc)
         .Castclass(typeof(object));
     }
     else
     {
         var resultLoc  = ilGenerator.DeclareLocal(targetType, "result");
         var labelNoCtx = ilGenerator.DefineLabel();
         ilGenerator
         .Newobj(targetType.GetConstructor(Type.EmptyTypes))
         .Stloc(resultLoc)
         .Do(pushCtx)
         .BrfalseS(labelNoCtx)
         .Do(pushCtx)
         .Ldloc(resultLoc)
         .Callvirt(() => default(ITypeBinaryDeserializerContext).AddBackRef(null))
         .Mark(labelNoCtx);
         var props = targetType.GetProperties();
         for (var idx = 0; idx < _fields.Count; idx++)
         {
             var idxForCapture = idx;
             var pair          = _fields[idx];
             var prop          = props.FirstOrDefault(p => GetPersitentName(p) == pair.Key);
             if (prop == null || !_typeSerializers.IsSafeToLoad(prop.PropertyType))
             {
                 pair.Value.GenerateSkipEx(ilGenerator, pushReader, pushCtx);
                 continue;
             }
             ilGenerator.Ldloc(resultLoc);
             pair.Value.GenerateLoadEx(ilGenerator, pushReader, pushCtx,
                                       il => il.Do(pushDescriptor).LdcI4(idxForCapture).Callvirt(() => default(ITypeDescriptor).NestedType(0)),
                                       prop.PropertyType, _typeSerializers.ConvertorGenerator);
             ilGenerator.Callvirt(prop.GetSetMethod());
         }
         ilGenerator.Ldloc(resultLoc);
     }
 }
Beispiel #32
0
 public void GenerateTypeIterator(IILGen ilGenerator, Action<IILGen> pushObj, Action<IILGen> pushCtx)
 {
     var finish = ilGenerator.DefineLabel();
     var next = ilGenerator.DefineLabel();
     var itemType = _listTypeDescriptor._typeSerializers.LoadAsType(_listTypeDescriptor._itemDescriptor);
     var localList = ilGenerator.DeclareLocal(typeof(IList<>).MakeGenericType(itemType));
     var localIndex = ilGenerator.DeclareLocal(typeof(int));
     var localCount = ilGenerator.DeclareLocal(typeof(int));
     ilGenerator
         .Do(pushObj)
         .Castclass(localList.LocalType)
         .Dup()
         .Stloc(localList)
         .Callvirt(localList.LocalType.GetInterface("ICollection`1").GetProperty("Count").GetGetMethod())
         .Stloc(localCount)
         .LdcI4(0)
         .Stloc(localIndex)
         .Mark(next)
         .Ldloc(localIndex)
         .Ldloc(localCount)
         .BgeUn(finish)
         .Do(pushCtx)
         .Ldloc(localList)
         .Ldloc(localIndex)
         .Callvirt(localList.LocalType.GetMethod("get_Item"))
         .Callvirt(() => default(IDescriptorSerializerLiteContext).StoreNewDescriptors(null))
         .Ldloc(localIndex)
         .LdcI4(1)
         .Add()
         .Stloc(localIndex)
         .Br(next)
         .Mark(finish);
 }
Beispiel #33
0
 public void GenerateSave(IILGen ilGenerator, Action<IILGen> pushWriter, Action<IILGen> pushCtx, Action<IILGen> pushValue, Type valueType)
 {
     var finish = ilGenerator.DefineLabel();
     var next = ilGenerator.DefineLabel();
     var notnull = ilGenerator.DefineLabel();
     var itemType = GetItemType(valueType);
     var localList = ilGenerator.DeclareLocal(
         typeof(IList<>).MakeGenericType(itemType));
     var localIndex = ilGenerator.DeclareLocal(typeof(int));
     var localCount = ilGenerator.DeclareLocal(typeof(int));
     ilGenerator
         .Do(pushValue)
         .Castclass(localList.LocalType)
         .Dup()
         .Stloc(localList)
         .BrtrueS(notnull)
         .Do(pushWriter)
         .LdcI4(0)
         .Callvirt(() => default(AbstractBufferedWriter).WriteVUInt32(0))
         .Br(finish)
         .Mark(notnull)
         .Ldloc(localList)
         .Callvirt(localList.LocalType.GetInterface("ICollection`1").GetProperty("Count").GetGetMethod())
         .Stloc(localCount)
         .Do(pushWriter)
         .Ldloc(localCount)
         .LdcI4(1)
         .Add()
         .ConvU4()
         .Callvirt(() => default(AbstractBufferedWriter).WriteVUInt32(0))
         .LdcI4(0)
         .Stloc(localIndex)
         .Mark(next)
         .Ldloc(localIndex)
         .Ldloc(localCount)
         .BgeUn(finish);
     _itemDescriptor.GenerateSaveEx(ilGenerator, pushWriter, pushCtx,
         il => il.Ldloc(localList)
                 .Ldloc(localIndex)
                 .Callvirt(localList.LocalType.GetMethod("get_Item")), itemType);
     ilGenerator
         .Ldloc(localIndex)
         .LdcI4(1)
         .Add()
         .Stloc(localIndex)
         .Br(next)
         .Mark(finish);
 }
Beispiel #34
0
 public void GenerateLoad(IILGen ilGenerator, Action<IILGen> pushReader, Action<IILGen> pushCtx, Action<IILGen> pushDescriptor, Type targetType)
 {
     var localCount = ilGenerator.DeclareLocal(typeof(int));
     var itemType = _typeSerializers.LoadAsType(_itemDescriptor);
     var listType = typeof(ListWithDescriptor<>).MakeGenericType(itemType);
     if (!targetType.IsAssignableFrom(listType)) throw new NotSupportedException();
     var localList = ilGenerator.DeclareLocal(listType);
     var loadFinished = ilGenerator.DefineLabel();
     var next = ilGenerator.DefineLabel();
     ilGenerator
         .Do(pushReader)
         .Callvirt(() => default(AbstractBufferedReader).ReadVUInt32())
         .ConvI4()
         .Dup()
         .Stloc(localCount)
         .Brfalse(loadFinished)
         .Ldloc(localCount)
         .LdcI4(1)
         .Sub()
         .Dup()
         .Stloc(localCount)
         .Do(pushDescriptor)
         .Newobj(listType.GetConstructor(new[] { typeof(int), typeof(ITypeDescriptor) }))
         .Stloc(localList)
         .Mark(next)
         .Ldloc(localCount)
         .Brfalse(loadFinished)
         .Ldloc(localCount)
         .LdcI4(1)
         .Sub()
         .Stloc(localCount)
         .Ldloc(localList);
     _itemDescriptor.GenerateLoadEx(ilGenerator, pushReader, pushCtx, il => il.Do(pushDescriptor).LdcI4(0).Callvirt(() => default(ITypeDescriptor).NestedType(0)), itemType);
     ilGenerator
         .Callvirt(listType.GetInterface("ICollection`1").GetMethod("Add"))
         .Br(next)
         .Mark(loadFinished)
         .Ldloc(localList)
         .Castclass(targetType);
 }
Beispiel #35
0
 public void Save(IILGen ilGenerator, Action<IILGen> pushWriterOrCtx, Action<IILGen> pushValue)
 {
     var finish = ilGenerator.DefineLabel();
     var next = ilGenerator.DefineLabel();
     var localValue = ilGenerator.DeclareLocal(_type);
     var localIndex = ilGenerator.DeclareLocal(typeof(int));
     var localCount = ilGenerator.DeclareLocal(typeof(int));
     ilGenerator
         .Do(pushValue)
         .Stloc(localValue)
         .Do(pushWriterOrCtx)
         .Ldloc(localValue)
         .Castclass(typeof(object))
         .Callvirt(() => default(IWriterCtx).WriteObject(null))
         .Brfalse(finish)
         .Ldloc(localValue)
         .Callvirt(_type.GetInterface("ICollection`1").GetProperty("Count").GetGetMethod())
         .Stloc(localCount)
         .Do(Extensions.PushWriterFromCtx(pushWriterOrCtx))
         .Ldloc(localCount)
         .ConvU4()
         .Callvirt(() => default(AbstractBufferedWriter).WriteVUInt32(0))
         .Mark(next)
         .Ldloc(localIndex)
         .Ldloc(localCount)
         .BgeUn(finish);
     _itemsHandler.Save(ilGenerator, Extensions.PushWriterOrCtxAsNeeded(pushWriterOrCtx, _itemsHandler.NeedsCtx()), il => il
         .Ldloc(localValue)
         .Ldloc(localIndex)
         .Callvirt(_type.GetMethod("get_Item"))
         .Do(_typeConvertorGenerator.GenerateConversion(_type.GetGenericArguments()[0], _itemsHandler.HandledType())));
     ilGenerator
         .Ldloc(localIndex)
         .LdcI4(1)
         .Add()
         .Stloc(localIndex)
         .Br(next)
         .Mark(finish);
 }
Beispiel #36
0
        public void GenerateSave(IILGen ilGenerator, Action <IILGen> pushWriter, Action <IILGen> pushCtx,
                                 Action <IILGen> pushValue, Type saveType)
        {
            var notnull           = ilGenerator.DefineLabel();
            var completeFinish    = ilGenerator.DefineLabel();
            var notDictionary     = ilGenerator.DefineLabel();
            var keyType           = saveType.GetGenericArguments()[0];
            var valueType         = saveType.GetGenericArguments()[1];
            var typeAsIDictionary = typeof(IDictionary <,>).MakeGenericType(keyType, valueType);
            var typeAsICollection = typeAsIDictionary.GetInterface("ICollection`1");
            var localDict         = ilGenerator.DeclareLocal(typeAsIDictionary);

            ilGenerator
            .Do(pushValue)
            .Castclass(typeAsIDictionary)
            .Stloc(localDict)
            .Ldloc(localDict)
            .Brtrue(notnull)
            .Do(pushWriter)
            .Callvirt(() => default(AbstractBufferedWriter).WriteByteZero())
            .Br(completeFinish)
            .Mark(notnull)
            .Do(pushWriter)
            .Ldloc(localDict)
            .Callvirt(typeAsICollection.GetProperty(nameof(ICollection.Count)).GetGetMethod())
            .LdcI4(1)
            .Add()
            .Callvirt(() => default(AbstractBufferedWriter).WriteVUInt32(0));
            {
                var typeAsDictionary    = typeof(Dictionary <,>).MakeGenericType(keyType, valueType);
                var getEnumeratorMethod = typeAsDictionary.GetMethods()
                                          .Single(m => m.Name == nameof(IEnumerable.GetEnumerator) && m.ReturnType.IsValueType && m.GetParameters().Length == 0);
                var typeAsIEnumerator = getEnumeratorMethod.ReturnType;
                var currentGetter     = typeAsIEnumerator.GetProperty(nameof(IEnumerator.Current)).GetGetMethod();
                var typeKeyValuePair  = currentGetter.ReturnType;
                var localEnumerator   = ilGenerator.DeclareLocal(typeAsIEnumerator);
                var localPair         = ilGenerator.DeclareLocal(typeKeyValuePair);
                var finish            = ilGenerator.DefineLabel();
                var next = ilGenerator.DefineLabel();
                ilGenerator
                .Ldloc(localDict)
                .Isinst(typeAsDictionary)
                .Brfalse(notDictionary)
                .Ldloc(localDict)
                .Castclass(typeAsDictionary)
                .Callvirt(getEnumeratorMethod)
                .Stloc(localEnumerator)
                .Try()
                .Mark(next)
                .Ldloca(localEnumerator)
                .Call(typeAsIEnumerator.GetMethod(nameof(IEnumerator.MoveNext)))
                .Brfalse(finish)
                .Ldloca(localEnumerator)
                .Call(currentGetter)
                .Stloc(localPair);
                _keyDescriptor.GenerateSaveEx(ilGenerator, pushWriter, pushCtx,
                                              il => il.Ldloca(localPair).Call(typeKeyValuePair.GetProperty("Key").GetGetMethod()), keyType);
                _valueDescriptor.GenerateSaveEx(ilGenerator, pushWriter, pushCtx,
                                                il => il.Ldloca(localPair).Call(typeKeyValuePair.GetProperty("Value").GetGetMethod()), valueType);
                ilGenerator
                .Br(next)
                .Mark(finish)
                .Finally()
                .Ldloca(localEnumerator)
                .Constrained(typeAsIEnumerator)
                .Callvirt(() => default(IDisposable).Dispose())
                .EndTry()
                .Br(completeFinish);
            }
            {
                var getEnumeratorMethod = typeAsIDictionary.GetInterface("IEnumerable`1").GetMethod(nameof(IEnumerable.GetEnumerator));
                var typeAsIEnumerator   = getEnumeratorMethod.ReturnType;
                var currentGetter       = typeAsIEnumerator.GetProperty(nameof(IEnumerator.Current)).GetGetMethod();
                var typeKeyValuePair    = currentGetter.ReturnType;
                var localEnumerator     = ilGenerator.DeclareLocal(typeAsIEnumerator);
                var localPair           = ilGenerator.DeclareLocal(typeKeyValuePair);
                var finish = ilGenerator.DefineLabel();
                var next   = ilGenerator.DefineLabel();
                ilGenerator
                .Mark(notDictionary)
                .Ldloc(localDict)
                .Callvirt(getEnumeratorMethod)
                .Stloc(localEnumerator)
                .Try()
                .Mark(next)
                .Ldloc(localEnumerator)
                .Callvirt(() => default(IEnumerator).MoveNext())
                .Brfalse(finish)
                .Ldloc(localEnumerator)
                .Callvirt(currentGetter)
                .Stloc(localPair);
                _keyDescriptor.GenerateSaveEx(ilGenerator, pushWriter, pushCtx, il => il.Ldloca(localPair).Call(typeKeyValuePair.GetProperty("Key").GetGetMethod()), keyType);
                _valueDescriptor.GenerateSaveEx(ilGenerator, pushWriter, pushCtx, il => il.Ldloca(localPair).Call(typeKeyValuePair.GetProperty("Value").GetGetMethod()), valueType);
                ilGenerator
                .Br(next)
                .Mark(finish)
                .Finally()
                .Ldloc(localEnumerator)
                .Callvirt(() => default(IDisposable).Dispose())
                .EndTry()
                .Mark(completeFinish);
            }
        }
Beispiel #37
0
 public void GenerateSave(IILGen ilGenerator, Action<IILGen> pushWriter, Action<IILGen> pushCtx,
     Action<IILGen> pushValue, Type saveType)
 {
     var notnull = ilGenerator.DefineLabel();
     var completeFinish = ilGenerator.DefineLabel();
     var notDictionary = ilGenerator.DefineLabel();
     var keyType = saveType.GetGenericArguments()[0];
     var valueType = saveType.GetGenericArguments()[1];
     var typeAsIDictionary = typeof(IDictionary<,>).MakeGenericType(keyType, valueType);
     var typeAsICollection = typeAsIDictionary.GetInterface("ICollection`1");
     var localDict = ilGenerator.DeclareLocal(typeAsIDictionary);
     ilGenerator
         .Do(pushValue)
         .Castclass(typeAsIDictionary)
         .Stloc(localDict)
         .Ldloc(localDict)
         .Brtrue(notnull)
         .Do(pushWriter)
         .Callvirt(() => default(AbstractBufferedWriter).WriteByteZero())
         .Br(completeFinish)
         .Mark(notnull)
         .Do(pushWriter)
         .Ldloc(localDict)
         .Callvirt(typeAsICollection.GetProperty("Count").GetGetMethod())
         .LdcI4(1)
         .Add()
         .Callvirt(() => default(AbstractBufferedWriter).WriteVUInt32(0));
     {
         var typeAsDictionary = typeof(Dictionary<,>).MakeGenericType(keyType, valueType);
         var getEnumeratorMethod = typeAsDictionary.GetMethods()
                 .Single(m => m.Name == "GetEnumerator" && m.ReturnType.IsValueType && m.GetParameters().Length == 0);
         var typeAsIEnumerator = getEnumeratorMethod.ReturnType;
         var currentGetter = typeAsIEnumerator.GetProperty("Current").GetGetMethod();
         var typeKeyValuePair = currentGetter.ReturnType;
         var localEnumerator = ilGenerator.DeclareLocal(typeAsIEnumerator);
         var localPair = ilGenerator.DeclareLocal(typeKeyValuePair);
         var finish = ilGenerator.DefineLabel();
         var next = ilGenerator.DefineLabel();
         ilGenerator
             .Ldloc(localDict)
             .Castclass(typeAsDictionary)
             .Brfalse(notDictionary)
             .Ldloc(localDict)
             .Castclass(typeAsDictionary)
             .Callvirt(getEnumeratorMethod)
             .Stloc(localEnumerator)
             .Try()
             .Mark(next)
             .Ldloca(localEnumerator)
             .Call(typeAsIEnumerator.GetMethod("MoveNext"))
             .Brfalse(finish)
             .Ldloca(localEnumerator)
             .Call(currentGetter)
             .Stloc(localPair);
         _keyDescriptor.GenerateSaveEx(ilGenerator, pushWriter, pushCtx,
             il => il.Ldloca(localPair).Call(typeKeyValuePair.GetProperty("Key").GetGetMethod()), keyType);
         _valueDescriptor.GenerateSaveEx(ilGenerator, pushWriter, pushCtx,
             il => il.Ldloca(localPair).Call(typeKeyValuePair.GetProperty("Value").GetGetMethod()), valueType);
         ilGenerator
             .Br(next)
             .Mark(finish)
             .Finally()
             .Ldloca(localEnumerator)
             .Constrained(typeAsIEnumerator)
             .Callvirt(() => default(IDisposable).Dispose())
             .EndTry()
             .Br(completeFinish);
     }
     {
         var getEnumeratorMethod = typeAsIDictionary.GetInterface("IEnumerable`1").GetMethod("GetEnumerator");
         var typeAsIEnumerator = getEnumeratorMethod.ReturnType;
         var currentGetter = typeAsIEnumerator.GetProperty("Current").GetGetMethod();
         var typeKeyValuePair = currentGetter.ReturnType;
         var localEnumerator = ilGenerator.DeclareLocal(typeAsIEnumerator);
         var localPair = ilGenerator.DeclareLocal(typeKeyValuePair);
         var finish = ilGenerator.DefineLabel();
         var next = ilGenerator.DefineLabel();
         ilGenerator
             .Mark(notDictionary)
             .Ldloc(localDict)
             .Callvirt(getEnumeratorMethod)
             .Stloc(localEnumerator)
             .Try()
             .Mark(next)
             .Ldloc(localEnumerator)
             .Callvirt(() => default(IEnumerator).MoveNext())
             .Brfalse(finish)
             .Ldloc(localEnumerator)
             .Callvirt(currentGetter)
             .Stloc(localPair);
         _keyDescriptor.GenerateSaveEx(ilGenerator, pushWriter, pushCtx, il => il.Ldloca(localPair).Call(typeKeyValuePair.GetProperty("Key").GetGetMethod()), keyType);
         _valueDescriptor.GenerateSaveEx(ilGenerator, pushWriter, pushCtx, il => il.Ldloca(localPair).Call(typeKeyValuePair.GetProperty("Value").GetGetMethod()), valueType);
         ilGenerator
             .Br(next)
             .Mark(finish)
             .Finally()
             .Ldloc(localEnumerator)
             .Callvirt(() => default(IDisposable).Dispose())
             .EndTry()
             .Mark(completeFinish);
     }
 }
Beispiel #38
0
 public void GenerateTypeIterator(IILGen ilGenerator, Action<IILGen> pushObj, Action<IILGen> pushCtx, Type type)
 {
     var finish = ilGenerator.DefineLabel();
     var next = ilGenerator.DefineLabel();
     var keyType = _owner._typeSerializers.LoadAsType(_owner._keyDescriptor);
     var valueType = _owner._typeSerializers.LoadAsType(_owner._valueDescriptor);
     if (_owner._type == null) _owner._type = type;
     var isDict = _owner._type != null && _owner._type.GetGenericTypeDefinition() == typeof(Dictionary<,>);
     var typeAsIDictionary = isDict ? _owner._type : typeof(IDictionary<,>).MakeGenericType(keyType, valueType);
     var getEnumeratorMethod = isDict
         ? typeAsIDictionary.GetMethods()
             .Single(
                 m => m.Name == "GetEnumerator" && m.ReturnType.IsValueType && m.GetParameters().Length == 0)
         : typeAsIDictionary.GetInterface("IEnumerable`1").GetMethod("GetEnumerator");
     var typeAsIEnumerator = getEnumeratorMethod.ReturnType;
     var currentGetter = typeAsIEnumerator.GetProperty("Current").GetGetMethod();
     var typeKeyValuePair = currentGetter.ReturnType;
     var localEnumerator = ilGenerator.DeclareLocal(typeAsIEnumerator);
     var localPair = ilGenerator.DeclareLocal(typeKeyValuePair);
     ilGenerator
         .Do(pushObj)
         .Castclass(typeAsIDictionary)
         .Callvirt(getEnumeratorMethod)
         .Stloc(localEnumerator)
         .Try()
         .Mark(next)
         .Do(il =>
         {
             if (isDict)
             {
                 il
                     .Ldloca(localEnumerator)
                     .Call(typeAsIEnumerator.GetMethod("MoveNext"));
             }
             else
             {
                 il
                     .Ldloc(localEnumerator)
                     .Callvirt(() => default(IEnumerator).MoveNext());
             }
         })
         .Brfalse(finish)
         .Do(il =>
         {
             if (isDict)
             {
                 il
                     .Ldloca(localEnumerator)
                     .Call(currentGetter);
             }
             else
             {
                 il
                     .Ldloc(localEnumerator)
                     .Callvirt(currentGetter);
             }
         })
         .Stloc(localPair);
     if (!_owner._keyDescriptor.Sealed)
     {
         ilGenerator
             .Do(pushCtx)
             .Ldloca(localPair)
             .Call(typeKeyValuePair.GetProperty("Key").GetGetMethod())
             .Callvirt(() => default(IDescriptorSerializerLiteContext).StoreNewDescriptors(null));
     }
     if (!_owner._valueDescriptor.Sealed)
     {
         ilGenerator
             .Do(pushCtx)
             .Ldloca(localPair)
             .Call(typeKeyValuePair.GetProperty("Value").GetGetMethod())
             .Callvirt(() => default(IDescriptorSerializerLiteContext).StoreNewDescriptors(null));
     }
     ilGenerator
         .Br(next)
         .Mark(finish)
         .Finally()
         .Do(il =>
         {
             if (isDict)
             {
                 il
                     .Ldloca(localEnumerator)
                     .Constrained(typeAsIEnumerator);
             }
             else
             {
                 il.Ldloc(localEnumerator);
             }
         })
         .Callvirt(() => default(IDisposable).Dispose())
         .EndTry();
 }
Beispiel #39
0
 public void Save(IILGen ilGenerator, Action<IILGen> pushWriterOrCtx, Action<IILGen> pushValue)
 {
     var realfinish = ilGenerator.DefineLabel();
     var finish = ilGenerator.DefineLabel();
     var next = ilGenerator.DefineLabel();
     var localValue = ilGenerator.DeclareLocal(_type);
     var typeAsICollection = _type.GetInterface("ICollection`1");
     var typeAsIEnumerable = _type.GetInterface("IEnumerable`1");
     var getEnumeratorMethod = typeAsIEnumerable.GetMethod("GetEnumerator");
     var typeAsIEnumerator = getEnumeratorMethod.ReturnType;
     var typeKeyValuePair = typeAsICollection.GetGenericArguments()[0];
     var localEnumerator = ilGenerator.DeclareLocal(typeAsIEnumerator);
     var localPair = ilGenerator.DeclareLocal(typeKeyValuePair);
     ilGenerator
         .Do(pushValue)
         .Stloc(localValue)
         .Do(pushWriterOrCtx)
         .Ldloc(localValue)
         .Castclass(typeof(object))
         .Callvirt(() => default(IWriterCtx).WriteObject(null))
         .Brfalse(realfinish)
         .Do(Extensions.PushWriterFromCtx(pushWriterOrCtx))
         .Ldloc(localValue)
         .Callvirt(typeAsICollection.GetProperty("Count").GetGetMethod())
         .ConvU4()
         .Callvirt(() => default(AbstractBufferedWriter).WriteVUInt32(0))
         .Ldloc(localValue)
         .Callvirt(getEnumeratorMethod)
         .Stloc(localEnumerator)
         .Try()
         .Mark(next)
         .Ldloc(localEnumerator)
         .Callvirt(() => default(IEnumerator).MoveNext())
         .Brfalse(finish)
         .Ldloc(localEnumerator)
         .Callvirt(typeAsIEnumerator.GetProperty("Current").GetGetMethod())
         .Stloc(localPair);
     _keysHandler.Save(ilGenerator, Extensions.PushWriterOrCtxAsNeeded(pushWriterOrCtx, _keysHandler.NeedsCtx()), il => il
         .Ldloca(localPair)
         .Call(typeKeyValuePair.GetProperty("Key").GetGetMethod())
         .Do(_typeConvertorGenerator.GenerateConversion(_type.GetGenericArguments()[0], _keysHandler.HandledType())));
     _valuesHandler.Save(ilGenerator, Extensions.PushWriterOrCtxAsNeeded(pushWriterOrCtx, _valuesHandler.NeedsCtx()), il => il
         .Ldloca(localPair)
         .Call(typeKeyValuePair.GetProperty("Value").GetGetMethod())
         .Do(_typeConvertorGenerator.GenerateConversion(_type.GetGenericArguments()[1], _valuesHandler.HandledType())));
     ilGenerator
         .Br(next)
         .Mark(finish)
         .Finally()
         .Ldloc(localEnumerator)
         .Callvirt(() => default(IDisposable).Dispose())
         .EndTry()
         .Mark(realfinish);
 }
 public void GenerateTypeIterator(IILGen ilGenerator, Action<IILGen> pushObj, Action<IILGen> pushCtx)
 {
     var finish = ilGenerator.DefineLabel();
     var next = ilGenerator.DefineLabel();
     var keyType = _owner._typeSerializers.LoadAsType(_owner._keyDescriptor);
     var valueType = _owner._typeSerializers.LoadAsType(_owner._valueDescriptor);
     var typeAsIDictionary = typeof(IDictionary<,>).MakeGenericType(keyType, valueType);
     var typeAsICollection = typeAsIDictionary.GetInterface("ICollection`1");
     var typeAsIEnumerable = typeAsIDictionary.GetInterface("IEnumerable`1");
     var getEnumeratorMethod = typeAsIEnumerable.GetMethod("GetEnumerator");
     var typeAsIEnumerator = getEnumeratorMethod.ReturnType;
     var typeKeyValuePair = typeAsICollection.GetGenericArguments()[0];
     var localEnumerator = ilGenerator.DeclareLocal(typeAsIEnumerator);
     var localPair = ilGenerator.DeclareLocal(typeKeyValuePair);
     ilGenerator
         .Do(pushObj)
         .Castclass(typeAsIDictionary)
         .Callvirt(getEnumeratorMethod)
         .Stloc(localEnumerator)
         .Try()
         .Mark(next)
         .Ldloc(localEnumerator)
         .Callvirt(() => default(IEnumerator).MoveNext())
         .Brfalse(finish)
         .Ldloc(localEnumerator)
         .Callvirt(typeAsIEnumerator.GetProperty("Current").GetGetMethod())
         .Stloc(localPair);
     if (!_owner._keyDescriptor.Sealed)
     {
         ilGenerator
             .Do(pushCtx)
             .Ldloca(localPair)
             .Call(typeKeyValuePair.GetProperty("Key").GetGetMethod())
             .Callvirt(() => default(IDescriptorSerializerLiteContext).StoreNewDescriptors(null));
     }
     if (!_owner._valueDescriptor.Sealed)
     {
         ilGenerator
             .Do(pushCtx)
             .Ldloca(localPair)
             .Call(typeKeyValuePair.GetProperty("Value").GetGetMethod())
             .Callvirt(() => default(IDescriptorSerializerLiteContext).StoreNewDescriptors(null));
     }
     ilGenerator
         .Br(next)
         .Mark(finish)
         .Finally()
         .Ldloc(localEnumerator)
         .Callvirt(() => default(IDisposable).Dispose())
         .EndTry();
 }
Beispiel #41
0
 public void GenerateLoad(IILGen ilGenerator, Action<IILGen> pushReader, Action<IILGen> pushCtx, Action<IILGen> pushDescriptor, Type targetType)
 {
     if (targetType == typeof(object))
     {
         var resultLoc = ilGenerator.DeclareLocal(typeof(DynamicObject), "result");
         var labelNoCtx = ilGenerator.DefineLabel();
         ilGenerator
             .Do(pushDescriptor)
             .Castclass(typeof(ObjectTypeDescriptor))
             .Newobj(typeof(DynamicObject).GetConstructor(new[] { typeof(ObjectTypeDescriptor) }))
             .Stloc(resultLoc)
             .Do(pushCtx)
             .BrfalseS(labelNoCtx)
             .Do(pushCtx)
             .Ldloc(resultLoc)
             .Callvirt(() => default(ITypeBinaryDeserializerContext).AddBackRef(null))
             .Mark(labelNoCtx);
         var idx = 0;
         foreach (var pair in _fields)
         {
             var idxForCapture = idx;
             ilGenerator.Ldloc(resultLoc);
             ilGenerator.LdcI4(idx);
             pair.Value.GenerateLoadEx(ilGenerator, pushReader, pushCtx,
                 il =>
                     il.Do(pushDescriptor)
                         .LdcI4(idxForCapture)
                         .Callvirt(() => default(ITypeDescriptor).NestedType(0)), typeof(object), _typeSerializers.ConvertorGenerator);
             ilGenerator.Callvirt(() => default(DynamicObject).SetFieldByIdxFast(0, null));
             idx++;
         }
         ilGenerator
             .Ldloc(resultLoc)
             .Castclass(typeof(object));
     }
     else
     {
         var resultLoc = ilGenerator.DeclareLocal(targetType, "result");
         var labelNoCtx = ilGenerator.DefineLabel();
         ilGenerator
             .Newobj(targetType.GetConstructor(Type.EmptyTypes))
             .Stloc(resultLoc)
             .Do(pushCtx)
             .BrfalseS(labelNoCtx)
             .Do(pushCtx)
             .Ldloc(resultLoc)
             .Callvirt(() => default(ITypeBinaryDeserializerContext).AddBackRef(null))
             .Mark(labelNoCtx);
         var props = targetType.GetProperties();
         for (var idx = 0; idx < _fields.Count; idx++)
         {
             var idxForCapture = idx;
             var pair = _fields[idx];
             var prop = props.FirstOrDefault(p => GetPersitentName(p) == pair.Key);
             if (prop == null || !_typeSerializers.IsSafeToLoad(prop.PropertyType))
             {
                 pair.Value.GenerateSkipEx(ilGenerator, pushReader, pushCtx);
                 continue;
             }
             ilGenerator.Ldloc(resultLoc);
             pair.Value.GenerateLoadEx(ilGenerator, pushReader, pushCtx,
                                     il => il.Do(pushDescriptor).LdcI4(idxForCapture).Callvirt(() => default(ITypeDescriptor).NestedType(0)),
                                     prop.PropertyType, _typeSerializers.ConvertorGenerator);
             ilGenerator.Callvirt(prop.GetSetMethod());
         }
         ilGenerator.Ldloc(resultLoc);
     }
 }
Beispiel #42
0
 public void GenerateSkip(IILGen ilGenerator, Action<IILGen> pushReader, Action<IILGen> pushCtx)
 {
     var localCount = ilGenerator.DeclareLocal(typeof(uint));
     var skipFinished = ilGenerator.DefineLabel();
     var next = ilGenerator.DefineLabel();
     ilGenerator
         .Do(pushReader)
         .Callvirt(() => default(AbstractBufferedReader).ReadVUInt32())
         .Stloc(localCount)
         .Ldloc(localCount)
         .Brfalse(skipFinished)
         .Mark(next)
         .Ldloc(localCount)
         .LdcI4(1)
         .Sub()
         .Stloc(localCount)
         .Ldloc(localCount)
         .Brfalse(skipFinished);
     _keyDescriptor.GenerateSkipEx(ilGenerator, pushReader, pushCtx);
     _valueDescriptor.GenerateSkipEx(ilGenerator, pushReader, pushCtx);
     ilGenerator
         .Br(next)
         .Mark(skipFinished);
 }
Beispiel #43
0
            public void GenerateTypeIterator(IILGen ilGenerator, Action <IILGen> pushObj, Action <IILGen> pushCtx, Type type)
            {
                var finish = ilGenerator.DefineLabel();
                var next   = ilGenerator.DefineLabel();

                if (type == typeof(object))
                {
                    type = _owner.GetPreferedType();
                }
                var targetIDictionary   = _owner.GetInterface(type);
                var targetTypeArguments = targetIDictionary.GetGenericArguments();
                var keyType             = _owner._typeSerializers.LoadAsType(_owner._keyDescriptor, targetTypeArguments[0]);
                var valueType           = _owner._typeSerializers.LoadAsType(_owner._valueDescriptor, targetTypeArguments[1]);

                if (_owner._type == null)
                {
                    _owner._type = type;
                }
                var isDict              = type.GetGenericTypeDefinition() == typeof(Dictionary <,>);
                var typeAsIDictionary   = isDict ? type : typeof(IDictionary <,>).MakeGenericType(keyType, valueType);
                var getEnumeratorMethod = isDict
                    ? typeAsIDictionary.GetMethods()
                                          .Single(
                    m => m.Name == nameof(IEnumerable.GetEnumerator) && m.ReturnType.IsValueType && m.GetParameters().Length == 0)
                    : typeAsIDictionary.GetInterface("IEnumerable`1").GetMethod(nameof(IEnumerable.GetEnumerator));
                var typeAsIEnumerator = getEnumeratorMethod.ReturnType;
                var currentGetter     = typeAsIEnumerator.GetProperty(nameof(IEnumerator.Current)).GetGetMethod();
                var typeKeyValuePair  = currentGetter.ReturnType;
                var localEnumerator   = ilGenerator.DeclareLocal(typeAsIEnumerator);
                var localPair         = ilGenerator.DeclareLocal(typeKeyValuePair);

                ilGenerator
                .Do(pushObj)
                .Castclass(typeAsIDictionary)
                .Callvirt(getEnumeratorMethod)
                .Stloc(localEnumerator)
                .Try()
                .Mark(next)
                .Do(il =>
                {
                    if (isDict)
                    {
                        il
                        .Ldloca(localEnumerator)
                        .Call(typeAsIEnumerator.GetMethod(nameof(IEnumerator.MoveNext)));
                    }
                    else
                    {
                        il
                        .Ldloc(localEnumerator)
                        .Callvirt(() => default(IEnumerator).MoveNext());
                    }
                })
                .Brfalse(finish)
                .Do(il =>
                {
                    if (isDict)
                    {
                        il
                        .Ldloca(localEnumerator)
                        .Call(currentGetter);
                    }
                    else
                    {
                        il
                        .Ldloc(localEnumerator)
                        .Callvirt(currentGetter);
                    }
                })
                .Stloc(localPair);
                if (!_owner._keyDescriptor.Sealed)
                {
                    ilGenerator
                    .Do(pushCtx)
                    .Ldloca(localPair)
                    .Call(typeKeyValuePair.GetProperty("Key").GetGetMethod())
                    .Callvirt(() => default(IDescriptorSerializerLiteContext).StoreNewDescriptors(null));
                }
                if (!_owner._valueDescriptor.Sealed)
                {
                    ilGenerator
                    .Do(pushCtx)
                    .Ldloca(localPair)
                    .Call(typeKeyValuePair.GetProperty("Value").GetGetMethod())
                    .Callvirt(() => default(IDescriptorSerializerLiteContext).StoreNewDescriptors(null));
                }
                ilGenerator
                .Br(next)
                .Mark(finish)
                .Finally()
                .Do(il =>
                {
                    if (isDict)
                    {
                        il
                        .Ldloca(localEnumerator)
                        .Constrained(typeAsIEnumerator);
                    }
                    else
                    {
                        il.Ldloc(localEnumerator);
                    }
                })
                .Callvirt(() => default(IDisposable).Dispose())
                .EndTry();
            }
Beispiel #44
0
 public void ReplayTo(IILGen target)
 {
     Label = target.DefineLabel(_name);
 }
Beispiel #45
0
 public void Skip(IILGen ilGenerator, Action<IILGen> pushReaderOrCtx)
 {
     var localCount = ilGenerator.DeclareLocal(typeof(uint));
     var finish = ilGenerator.DefineLabel();
     var next = ilGenerator.DefineLabel();
     ilGenerator
         .Do(pushReaderOrCtx)
         .Callvirt(() => default(IReaderCtx).SkipObject())
         .Brfalse(finish)
         .Do(Extensions.PushReaderFromCtx(pushReaderOrCtx))
         .Callvirt(() => default(AbstractBufferedReader).ReadVUInt32())
         .Stloc(localCount)
         .Mark(next)
         .Ldloc(localCount)
         .Brfalse(finish)
         .Ldloc(localCount)
         .LdcI4(1)
         .Sub()
         .ConvU4()
         .Stloc(localCount)
         .GenerateSkip(_itemsHandler, pushReaderOrCtx)
         .Br(next)
         .Mark(finish);
 }