Ejemplo n.º 1
0
        object CreateWriter(IFieldHandler fieldHandler, Type realType)
        {
            //Action<T, ref SpanWriter, IWriterCtx>
            var delegateType = typeof(WriterFun <>).MakeGenericType(realType);
            var dm           = ILBuilder.Instance.NewMethod(fieldHandler.Name + "Writer", delegateType);
            var ilGenerator  = dm.Generator;

            fieldHandler.Save(ilGenerator, il => il.Ldarg(1), il => il.Ldarg(2),
                              il => il.Ldarg(0).Do(_typeConvertGenerator.GenerateConversion(realType, fieldHandler.HandledType()) !));
            ilGenerator.Ret();
            return(dm.Create());
        }
Ejemplo n.º 2
0
        object CreateWriter(IFieldHandler fieldHandler, Type realType)
        {
            //Action<T, AbstractBufferedWriter, IWriterCtx>
            var             delegateType    = typeof(Action <, ,>).MakeGenericType(realType, typeof(AbstractBufferedWriter), typeof(IWriterCtx));
            var             dm              = ILBuilder.Instance.NewMethod(fieldHandler.Name + "Writer", delegateType);
            var             ilGenerator     = dm.Generator;
            Action <IILGen> pushWriterOrCtx = il => il.Ldarg((ushort)(1 + (fieldHandler.NeedsCtx() ? 1 : 0)));

            fieldHandler.Save(ilGenerator, pushWriterOrCtx,
                              il => il.Ldarg(0).Do(_typeConvertorGenerator.GenerateConversion(realType, fieldHandler.HandledType())));
            ilGenerator.Ret();
            return(dm.Create());
        }
Ejemplo n.º 3
0
 public static void GenerateLoadEx(this ITypeDescriptor descriptor, IILGen ilGenerator, Action<IILGen> pushReader, Action<IILGen> pushCtx, Action<IILGen> pushDescriptor, Type asType, ITypeConvertorGenerator convertorGenerator)
 {
     if (descriptor.StoredInline)
     {
         if (descriptor.LoadNeedsHelpWithConversion && asType!=typeof(object))
         {
             var origType = descriptor.GetPreferedType();
             descriptor.GenerateLoad(ilGenerator, pushReader, pushCtx, pushDescriptor, origType);
             if (origType != asType)
             {
                 var conv = convertorGenerator.GenerateConversion(origType, asType);
                 if (conv == null)
                     throw new BTDBException("Don't know how to convert " + descriptor.Name + " from " +
                                             origType.ToSimpleName() + " to " + asType.ToSimpleName());
                 conv(ilGenerator);
             }
         }
         else
         {
             descriptor.GenerateLoad(ilGenerator, pushReader, pushCtx, pushDescriptor, asType);
         }
     }
     else
     {
         ilGenerator
             .Do(pushCtx)
             .Callvirt(() => default(ITypeBinaryDeserializerContext).LoadObject());
         if (asType != typeof(object))
             ilGenerator.Castclass(asType);
     }
 }
Ejemplo n.º 4
0
 public static void GenerateLoadEx(this ITypeDescriptor descriptor, IILGen ilGenerator, Action <IILGen> pushReader, Action <IILGen> pushCtx, Action <IILGen> pushDescriptor, Type asType, ITypeConvertorGenerator convertorGenerator)
 {
     if (descriptor.StoredInline)
     {
         if (descriptor.LoadNeedsHelpWithConversion && asType != typeof(object))
         {
             var origType = descriptor.GetPreferedType();
             descriptor.GenerateLoad(ilGenerator, pushReader, pushCtx, pushDescriptor, origType);
             if (origType != asType)
             {
                 var conv = convertorGenerator.GenerateConversion(origType, asType);
                 if (conv == null)
                 {
                     throw new BTDBException("Don't know how to convert " + descriptor.Name + " from " +
                                             origType.ToSimpleName() + " to " + asType.ToSimpleName());
                 }
                 conv(ilGenerator);
             }
         }
         else
         {
             descriptor.GenerateLoad(ilGenerator, pushReader, pushCtx, pushDescriptor, asType);
         }
     }
     else
     {
         ilGenerator
         .Do(pushCtx)
         .Callvirt(() => default(ITypeBinaryDeserializerContext).LoadObject());
         if (asType != typeof(object))
         {
             ilGenerator.Castclass(asType);
         }
     }
 }
Ejemplo n.º 5
0
 public static IILGen GenerateLoad(this IILGen ilGenerator, IFieldHandler fieldHandler, Type typeWanted, Action <IILGen> pushReaderOrCtx, ITypeConvertorGenerator typeConvertorGenerator)
 {
     fieldHandler.Load(ilGenerator,
                       fieldHandler.NeedsCtx() ? pushReaderOrCtx : PushReaderFromCtx(pushReaderOrCtx));
     typeConvertorGenerator.GenerateConversion(fieldHandler.HandledType(), typeWanted)(ilGenerator);
     return(ilGenerator);
 }
Ejemplo n.º 6
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 localEnumerator     = ilGenerator.DeclareLocal(typeAsIEnumerator);

            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);
            _itemsHandler.Save(ilGenerator, pushWriter, pushCtx, il => il
                               .Ldloc(localEnumerator)
                               .Callvirt(typeAsIEnumerator.GetProperty("Current") !.GetGetMethod() !)
                               .Do(_typeConvertGenerator.GenerateConversion(_type.GetGenericArguments()[0], _itemsHandler.HandledType()) !));
            ilGenerator
            .Br(next)
            .Mark(finish)
            .Finally()
            .Ldloc(localEnumerator)
            .Callvirt(() => default(IDisposable).Dispose())
            .EndTry()
            .Mark(realFinish);
        }
Ejemplo n.º 7
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);
        }
Ejemplo n.º 8
0
        object CreateSimpleLoader(SimpleLoaderType loaderType)
        {
            var             delegateType    = typeof(Func <, ,>).MakeGenericType(typeof(AbstractBufferedReader), typeof(IReaderCtx), loaderType.RealType);
            var             dm              = ILBuilder.Instance.NewMethod(loaderType.FieldHandler.Name + "SimpleReader", delegateType);
            var             ilGenerator     = dm.Generator;
            Action <IILGen> pushReaderOrCtx = il => il.Ldarg((ushort)(loaderType.FieldHandler.NeedsCtx() ? 1 : 0));

            loaderType.FieldHandler.Load(ilGenerator, pushReaderOrCtx);
            ilGenerator
            .Do(_typeConvertorGenerator.GenerateConversion(loaderType.FieldHandler.HandledType(), loaderType.RealType))
            .Ret();
            return(dm.Create());
        }
Ejemplo n.º 9
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);
            var keyAndValueTypes = _type.GetGenericArguments();

            _keysHandler.Save(ilGenerator, Extensions.PushWriterOrCtxAsNeeded(pushWriterOrCtx, _keysHandler.NeedsCtx()), il => il
                              .Ldloca(localPair)
                              .Call(typeKeyValuePair.GetProperty("Key") !.GetGetMethod() !)
                              .Do(_typeConvertGenerator.GenerateConversion(keyAndValueTypes[0], _keysHandler.HandledType()) !));
            _valuesHandler.Save(ilGenerator, Extensions.PushWriterOrCtxAsNeeded(pushWriterOrCtx, _valuesHandler.NeedsCtx()), 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);
        }
Ejemplo n.º 10
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);
        }
Ejemplo n.º 11
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);
        }