private static void CreateMapUnpackFrom(SerializationContext context, Type targetType, SerializerEmitter emitter, CollectionTraits traits) { var il = emitter.GetUnpackFromMethodILGenerator(); var localHolder = new LocalVariableHolder(il); var instanceType = targetType; try { /* * if (!unpacker.IsMapHeader) * { * throw SerializationExceptions.NewIsNotMapHeader(); * } * * TDictionary<TKey, TValue> dictionary = new ...; * this.UnpackToCore(unpacker, dictionary); * return dictionary; */ if (targetType.IsInterface || targetType.IsAbstract) { instanceType = context.DefaultCollectionTypes.GetConcreteType(targetType); if (instanceType == null) { il.EmitTypeOf(targetType); il.EmitAnyCall(SerializationExceptions.NewNotSupportedBecauseCannotInstanciateAbstractTypeMethod); il.EmitThrow(); return; } } il.EmitAnyLdarg(1); il.EmitGetProperty(Metadata._Unpacker.IsMapHeader); var endIf = il.DefineLabel("END_IF"); il.EmitBrtrue_S(endIf); il.EmitAnyCall(SerializationExceptions.NewIsNotMapHeaderMethod); il.EmitThrow(); il.MarkLabel(endIf); var collection = localHolder.GetDeserializingCollection(instanceType); Emittion.EmitConstruction( il, collection, il0 => Emittion.EmitGetUnpackerItemsCountAsInt32(il0, 1, localHolder) ); EmitInvokeMapUnpackToHelper(targetType, emitter, traits, il, 1, il0 => il0.EmitAnyLdloc(collection)); il.EmitAnyLdloc(collection); il.EmitRet(); } finally { il.FlushTrace(); } }
private static void CreateArrayUnpackFrom(Type targetType, SerializerEmitter emitter, CollectionTraits traits) { var il = emitter.GetUnpackFromMethodILGenerator(); var localHolder = new LocalVariableHolder(il); try { if (targetType.IsInterface || targetType.IsAbstract) { il.EmitTypeOf(targetType); il.EmitAnyCall(SerializationExceptions.NewNotSupportedBecauseCannotInstanciateAbstractTypeMethod); il.EmitThrow(); return; } /* * if (!unpacker.IsArrayHeader) * { * throw SerializationExceptions.NewIsNotArrayHeader(); * } * * TCollection collection = new ...; * this.UnpackToCore(unpacker, array); * return collection; */ il.EmitAnyLdarg(1); il.EmitGetProperty(Metadata._Unpacker.IsArrayHeader); var endIf = il.DefineLabel("END_IF"); il.EmitBrtrue_S(endIf); il.EmitAnyCall(SerializationExceptions.NewIsNotArrayHeaderMethod); il.EmitThrow(); il.MarkLabel(endIf); var collection = localHolder.GetDeserializingCollection(targetType); // Emit newobj, newarr, or call ValueType..ctor() Emittion.EmitConstruction( il, collection, il0 => Emittion.EmitGetUnpackerItemsCountAsInt32(il0, 1, localHolder) ); EmitInvokeArrayUnpackToHelper(targetType, emitter, traits, il, 1, il0 => il0.EmitAnyLdloc(collection)); il.EmitAnyLdloc(collection); il.EmitRet(); } finally { il.FlushTrace(); } }
private static void CreateArrayUnpackFrom(Type targetType, SerializerEmitter emitter, CollectionTraits traits) { Action <TracingILGenerator> initialCountLoadingEmitter = null; TracingILGenerator unpackFromMethodILGenerator = emitter.GetUnpackFromMethodILGenerator(); LocalVariableHolder localHolder = new LocalVariableHolder(unpackFromMethodILGenerator); try { LocalBuilder collection; if (targetType.IsInterface || targetType.IsAbstract) { unpackFromMethodILGenerator.EmitTypeOf(targetType); unpackFromMethodILGenerator.EmitAnyCall(SerializationExceptions.NewNotSupportedBecauseCannotInstanciateAbstractTypeMethod); unpackFromMethodILGenerator.EmitThrow(); } else { unpackFromMethodILGenerator.EmitAnyLdarg(1); unpackFromMethodILGenerator.EmitGetProperty(_Unpacker.IsArrayHeader); Label target = unpackFromMethodILGenerator.DefineLabel("END_IF"); unpackFromMethodILGenerator.EmitBrtrue_S(target); unpackFromMethodILGenerator.EmitAnyCall(SerializationExceptions.NewIsNotArrayHeaderMethod); unpackFromMethodILGenerator.EmitThrow(); unpackFromMethodILGenerator.MarkLabel(target); collection = localHolder.GetDeserializingCollection(targetType); if (initialCountLoadingEmitter == null) { initialCountLoadingEmitter = il0 => Emittion.EmitGetUnpackerItemsCountAsInt32(il0, 1, localHolder); } Emittion.EmitConstruction(unpackFromMethodILGenerator, collection, initialCountLoadingEmitter); EmitInvokeArrayUnpackToHelper(targetType, emitter, traits, unpackFromMethodILGenerator, 1, il0 => il0.EmitAnyLdloc(collection)); unpackFromMethodILGenerator.EmitAnyLdloc(collection); unpackFromMethodILGenerator.EmitRet(); } } finally { unpackFromMethodILGenerator.FlushTrace(); } }
/// <summary> /// Creates serializer for <typeparamref name="TObject"/>. /// </summary> /// <param name="entries">Serialization target members. This will not be <c>null</c> nor empty.</param> /// <returns> /// <see cref="MessagePackSerializer{T}"/>. This value will not be <c>null</c>. /// </returns> protected sealed override MessagePackSerializer <TObject> CreateSerializer(SerializingMember[] entries) { using (var emitter = this._generatorManager.CreateEmitter(typeof(TObject), this._emitterFlavor)) { try { var packerIL = emitter.GetPackToMethodILGenerator(); try { if (typeof(IPackable).IsAssignableFrom(typeof(TObject))) { if (typeof(TObject).IsValueType) { packerIL.EmitAnyLdarga(2); } else { packerIL.EmitAnyLdarg(2); } packerIL.EmitAnyLdarg(1); packerIL.EmitLdnull(); packerIL.EmitCall(typeof(TObject).GetInterfaceMap(typeof(IPackable)).TargetMethods.Single()); packerIL.EmitRet(); } else { this.EmitPackMembers(emitter, packerIL, entries); } } finally { packerIL.FlushTrace(); } var unpackerIL = emitter.GetUnpackFromMethodILGenerator(); try { // TODO: For big struct, use Dictionary<String,SM> var result = unpackerIL.DeclareLocal(typeof(TObject), "result"); Emittion.EmitConstruction(unpackerIL, result, null); if (typeof(IUnpackable).IsAssignableFrom(typeof(TObject))) { if (typeof(TObject).GetIsValueType()) { unpackerIL.EmitAnyLdloca(result); } else { unpackerIL.EmitAnyLdloc(result); } unpackerIL.EmitAnyLdarg(1); unpackerIL.EmitCall(typeof(TObject).GetInterfaceMap(typeof(IUnpackable)).TargetMethods.Single()); } else { EmitUnpackMembers(emitter, unpackerIL, entries, result); } unpackerIL.EmitAnyLdloc(result); unpackerIL.EmitRet(); } finally { unpackerIL.FlushTrace(); } return(emitter.CreateInstance <TObject>(this.Context)); } finally { emitter.FlushTrace(); } } }
protected sealed override MessagePackSerializer <TObject> CreateSerializer(SerializingMember[] entries) { MessagePackSerializer <TObject> serializer; using (SerializerEmitter emitter = this._generatorManager.CreateEmitter(typeof(TObject), this._emitterFlavor)) { try { TracingILGenerator packToMethodILGenerator = emitter.GetPackToMethodILGenerator(); try { if (typeof(IPackable).IsAssignableFrom(typeof(TObject))) { if (typeof(TObject).IsValueType) { packToMethodILGenerator.EmitAnyLdarga(2); } else { packToMethodILGenerator.EmitAnyLdarg(2); } packToMethodILGenerator.EmitAnyLdarg(1); packToMethodILGenerator.EmitLdnull(); packToMethodILGenerator.EmitCall(typeof(TObject).GetInterfaceMap(typeof(IPackable)).TargetMethods.Single <MethodInfo>()); packToMethodILGenerator.EmitRet(); } else { this.EmitPackMembers(emitter, packToMethodILGenerator, entries); } } finally { packToMethodILGenerator.FlushTrace(); } TracingILGenerator unpackFromMethodILGenerator = emitter.GetUnpackFromMethodILGenerator(); try { LocalBuilder target = unpackFromMethodILGenerator.DeclareLocal(typeof(TObject), "result"); Emittion.EmitConstruction(unpackFromMethodILGenerator, target, null); if (typeof(IUnpackable).IsAssignableFrom(typeof(TObject))) { if (typeof(TObject).GetIsValueType()) { unpackFromMethodILGenerator.EmitAnyLdloca(target); } else { unpackFromMethodILGenerator.EmitAnyLdloc(target); } unpackFromMethodILGenerator.EmitAnyLdarg(1); unpackFromMethodILGenerator.EmitCall(typeof(TObject).GetInterfaceMap(typeof(IUnpackable)).TargetMethods.Single <MethodInfo>()); } else { EmittingSerializerBuilder <TObject> .EmitUnpackMembers(emitter, unpackFromMethodILGenerator, entries, target); } unpackFromMethodILGenerator.EmitAnyLdloc(target); unpackFromMethodILGenerator.EmitRet(); } finally { unpackFromMethodILGenerator.FlushTrace(); } serializer = emitter.CreateInstance <TObject>(base.Context); } finally { emitter.FlushTrace(); } } return(serializer); }