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()); }
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()); }
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); } }
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); } } }
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); }
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); }
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); }
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()); }
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); }
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); }
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); }