private static void CreateTuplePack(SerializerEmitter emiter, Type tupleType, IList <Type> itemTypes, Action <TracingILGenerator, LocalBuilder> loadTupleEmitter) { var il = emiter.GetPackToMethodILGenerator(); var localHolder = new LocalVariableHolder(il); try { /* * packer.PackArrayHeader( cardinarity ); * _serializer0.PackTo( packer, tuple.Item1 ); * : * _serializer6.PackTo( packer, tuple.item7 ); * _serializer7.PackTo( packer, tuple.Rest.Item1 ); */ var tuple = il.DeclareLocal(tupleType, "tuple"); loadTupleEmitter(il, tuple); il.EmitAnyLdarg(1); il.EmitAnyLdc_I4(itemTypes.Count); il.EmitAnyCall(Metadata._Packer.PackArrayHeader); il.EmitPop(); var tupleTypeList = TupleItems.CreateTupleTypeList(itemTypes); int depth = -1; for (int i = 0; i < itemTypes.Count; i++) { if (i % 7 == 0) { depth++; } Emittion.EmitSerializeValue( emiter, il, 1, itemTypes[i], null, NilImplication.MemberDefault, il0 => { il0.EmitAnyLdloc(tuple); for (int j = 0; j < depth; j++) { // .TRest.TRest ... var rest = tupleTypeList[j].GetProperty("Rest"); il0.EmitGetProperty(rest); } var itemn = tupleTypeList[depth].GetProperty("Item" + ((i % 7) + 1)); #if DEBUG Contract.Assert(itemn != null, tupleTypeList[depth].GetFullName() + "::Item" + ((i % 7) + 1) + " [ " + depth + " ] @ " + i); #endif il0.EmitGetProperty(itemn); }, localHolder ); } il.EmitRet(); } finally { il.FlushTrace(); } }
private static void CreateMapPack(Type targetType, SerializerEmitter emiter, CollectionTraits traits) { var il = emiter.GetPackToMethodILGenerator(); var localHolder = new LocalVariableHolder(il); try { /* * int count = ((ICollection<KeyValuePair<string, DateTime>>)dictionary).Count; * packer.PackMapHeader(count); * foreach (KeyValuePair<string, DateTime> current in dictionary) * { * this._serializer0.PackTo(packer, current.Key); * this._serializer1.PackTo(packer, current.Value); * } */ var collection = localHolder.GetSerializingCollection(targetType); var item = localHolder.GetSerializingCollectionItem(traits.ElementType); var keyProperty = traits.ElementType.GetProperty("Key"); var valueProperty = traits.ElementType.GetProperty("Value"); // This instruction is always ldarg, not to be ldarga. il.EmitAnyLdarg(2); il.EmitAnyStloc(collection); var count = localHolder.PackingCollectionCount; EmitLoadTarget(targetType, il, collection); il.EmitGetProperty(traits.CountProperty); il.EmitAnyStloc(count); il.EmitAnyLdarg(1); il.EmitAnyLdloc(count); il.EmitAnyCall(Metadata._Packer.PackMapHeader); il.EmitPop(); Emittion.EmitForEach( il, traits, collection, (il0, getCurrentEmitter) => { if (traits.ElementType.IsGenericType) { Contract.Assert(traits.ElementType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>)); getCurrentEmitter(); il0.EmitAnyStloc(item); Emittion.EmitSerializeValue( emiter, il0, 1, traits.ElementType.GetGenericArguments()[0], null, NilImplication.MemberDefault, il1 => { il1.EmitAnyLdloca(item); il1.EmitGetProperty(keyProperty); }, localHolder ); Emittion.EmitSerializeValue( emiter, il0, 1, traits.ElementType.GetGenericArguments()[1], null, NilImplication.MemberDefault, il1 => { il1.EmitAnyLdloca(item); il1.EmitGetProperty(valueProperty); }, localHolder ); } else { Contract.Assert(traits.ElementType == typeof(DictionaryEntry)); getCurrentEmitter(); il0.EmitAnyStloc(item); Emittion.EmitSerializeValue( emiter, il0, 1, typeof(MessagePackObject), null, NilImplication.MemberDefault, il1 => { il0.EmitAnyLdloca(item); il0.EmitGetProperty(Metadata._DictionaryEntry.Key); il0.EmitUnbox_Any(typeof(MessagePackObject)); }, localHolder ); Emittion.EmitSerializeValue( emiter, il0, 1, typeof(MessagePackObject), null, NilImplication.MemberDefault, il1 => { il0.EmitAnyLdloca(item); il0.EmitGetProperty(Metadata._DictionaryEntry.Value); il0.EmitUnbox_Any(typeof(MessagePackObject)); }, localHolder ); } } ); il.EmitRet(); } finally { il.FlushTrace(); } }
private static void CreatePackArrayProceduresCore(Type targetType, SerializerEmitter emitter, CollectionTraits traits) { var il = emitter.GetPackToMethodILGenerator(); var localHolder = new LocalVariableHolder(il); try { // Array if (targetType.IsArray) { /* * // array * packer.PackArrayHeader( length ); * for( int i = 0; i < length; i++ ) * { * this._serializer.PackTo( packer, collection[ i ] ); * } */ var length = localHolder.PackingCollectionCount; il.EmitAnyLdarg(2); il.EmitLdlen(); il.EmitAnyStloc(length); il.EmitAnyLdarg(1); il.EmitAnyLdloc(length); il.EmitAnyCall(Metadata._Packer.PackArrayHeader); il.EmitPop(); Emittion.EmitFor( il, length, (il0, i) => Emittion.EmitSerializeValue( emitter, il0, 1, traits.ElementType, null, NilImplication.MemberDefault, il1 => { il1.EmitAnyLdarg(2); il1.EmitAnyLdloc(i); il1.EmitLdelem(traits.ElementType); }, localHolder ) ); } else if (traits.CountProperty == null) { /* * array = collection.ToArray(); * packer.PackArrayHeader( length ); * for( int i = 0; i < length; i++ ) * { * this._serializer.PackTo( packer, array[ i ] ); * } */ var array = localHolder.GetSerializingCollection(traits.ElementType.MakeArrayType()); EmitLoadTarget(targetType, il, 2); il.EmitAnyCall(Metadata._Enumerable.ToArray1Method.MakeGenericMethod(traits.ElementType)); il.EmitAnyStloc(array); var length = localHolder.PackingCollectionCount; il.EmitAnyLdloc(array); il.EmitLdlen(); il.EmitAnyStloc(length); il.EmitAnyLdarg(1); il.EmitAnyLdloc(length); il.EmitAnyCall(Metadata._Packer.PackArrayHeader); il.EmitPop(); Emittion.EmitFor( il, length, (il0, i) => Emittion.EmitSerializeValue( emitter, il0, 1, traits.ElementType, null, NilImplication.MemberDefault, il1 => { il1.EmitAnyLdloc(array); il1.EmitAnyLdloc(i); il1.EmitLdelem(traits.ElementType); }, localHolder ) ); } else { /* * // Enumerable * packer.PackArrayHeader( collection.Count ); * foreach( var item in list ) * { * this._serializer.PackTo( packer, array[ i ] ); * } */ var collection = localHolder.GetSerializingCollection(targetType); // This instruction always ldarg, not to be ldarga il.EmitAnyLdarg(2); il.EmitAnyStloc(collection); var count = localHolder.PackingCollectionCount; EmitLoadTarget(targetType, il, 2); il.EmitGetProperty(traits.CountProperty); il.EmitAnyStloc(count); il.EmitAnyLdarg(1); il.EmitAnyLdloc(count); il.EmitAnyCall(Metadata._Packer.PackArrayHeader); il.EmitPop(); Emittion.EmitForEach( il, traits, collection, (il0, getCurrentEmitter) => Emittion.EmitSerializeValue( emitter, il0, 1, traits.ElementType, null, NilImplication.MemberDefault, _ => getCurrentEmitter(), localHolder ) ); } il.EmitRet(); } finally { il.FlushTrace(); } }
private static void CreateTuplePack( SerializerEmitter emiter, Type tupleType, IList<Type> itemTypes, Action<TracingILGenerator, LocalBuilder> loadTupleEmitter ) { var il = emiter.GetPackToMethodILGenerator(); try { /* * packer.PackArrayHeader( cardinarity ); * _serializer0.PackTo( packer, tuple.Item1 ); * : * _serializer6.PackTo( packer, tuple.item7 ); * _serializer7.PackTo( packer, tuple.Rest.Item1 ); */ var tuple = il.DeclareLocal( tupleType, "tuple" ); loadTupleEmitter( il, tuple ); il.EmitAnyLdarg( 1 ); il.EmitAnyLdc_I4( itemTypes.Count ); il.EmitAnyCall( Metadata._Packer.PackArrayHeader ); il.EmitPop(); var tupleTypeList = TupleItems.CreateTupleTypeList( itemTypes ); int depth = -1; for ( int i = 0; i < itemTypes.Count; i++ ) { if ( i % 7 == 0 ) { depth++; } Emittion.EmitSerializeValue( emiter, il, 1, itemTypes[ i ], null, NilImplication.MemberDefault, il0 => { il0.EmitAnyLdloc( tuple ); for ( int j = 0; j < depth; j++ ) { // .TRest.TRest ... var rest = tupleTypeList[ j ].GetProperty( "Rest" ); il0.EmitGetProperty( rest ); } var itemn = tupleTypeList[ depth ].GetProperty( "Item" + ( ( i % 7 ) + 1 ) ); #if DEBUG Contract.Assert( itemn != null, tupleTypeList[ depth ].GetFullName() + "::Item" + ( ( i % 7 ) + 1 ) + " [ " + depth + " ] @ " + i ); #endif il0.EmitGetProperty( itemn ); } ); } il.EmitRet(); } finally { il.FlushTrace(); } }
private static void CreatePackArrayProceduresCore( Type targetType, SerializerEmitter emitter, CollectionTraits traits ) { var il = emitter.GetPackToMethodILGenerator(); try { // Array if ( targetType.IsArray ) { /* * // array * packer.PackArrayHeader( length ); * for( int i = 0; i < length; i++ ) * { * this._serializer.PackTo( packer, collection[ i ] ); * } */ var length = il.DeclareLocal( typeof( int ), "length" ); il.EmitAnyLdarg( 2 ); il.EmitLdlen(); il.EmitAnyStloc( length ); il.EmitAnyLdarg( 1 ); il.EmitAnyLdloc( length ); il.EmitAnyCall( Metadata._Packer.PackArrayHeader ); il.EmitPop(); Emittion.EmitFor( il, length, ( il0, i ) => { Emittion.EmitSerializeValue( emitter, il0, 1, traits.ElementType, null, NilImplication.MemberDefault, il1 => { il1.EmitAnyLdarg( 2 ); il1.EmitAnyLdloc( i ); il1.EmitLdelem( traits.ElementType ); } ); } ); } else if ( traits.CountProperty == null ) { /* * array = collection.ToArray(); * packer.PackArrayHeader( length ); * for( int i = 0; i < length; i++ ) * { * this._serializer.PackTo( packer, array[ i ] ); * } */ var array = il.DeclareLocal( traits.ElementType.MakeArrayType(), "array" ); EmitLoadTarget( targetType, il, 2 ); il.EmitAnyCall( Metadata._Enumerable.ToArray1Method.MakeGenericMethod( traits.ElementType ) ); il.EmitAnyStloc( array ); var length = il.DeclareLocal( typeof( int ), "length" ); il.EmitAnyLdloc( array ); il.EmitLdlen(); il.EmitAnyStloc( length ); il.EmitAnyLdarg( 1 ); il.EmitAnyLdloc( length ); il.EmitAnyCall( Metadata._Packer.PackArrayHeader ); il.EmitPop(); Emittion.EmitFor( il, length, ( il0, i ) => { Emittion.EmitSerializeValue( emitter, il0, 1, traits.ElementType, null, NilImplication.MemberDefault, il1 => { il1.EmitAnyLdloc( array ); il1.EmitAnyLdloc( i ); il1.EmitLdelem( traits.ElementType ); } ); } ); } else { /* * // Enumerable * packer.PackArrayHeader( collection.Count ); * foreach( var item in list ) * { * this._serializer.PackTo( packer, array[ i ] ); * } */ var collection = il.DeclareLocal( targetType, "collection" ); // This instruction always ldarg, not to be ldarga il.EmitAnyLdarg( 2 ); il.EmitAnyStloc( collection ); var count = il.DeclareLocal( typeof( int ), "count" ); EmitLoadTarget( targetType, il, 2 ); il.EmitGetProperty( traits.CountProperty ); il.EmitAnyStloc( count ); il.EmitAnyLdarg( 1 ); il.EmitAnyLdloc( count ); il.EmitAnyCall( Metadata._Packer.PackArrayHeader ); il.EmitPop(); Emittion.EmitForEach( il, traits, collection, ( il0, getCurrentEmitter ) => { Emittion.EmitSerializeValue( emitter, il0, 1, traits.ElementType, null, NilImplication.MemberDefault, _ => getCurrentEmitter() ); } ); } il.EmitRet(); } finally { il.FlushTrace(); } }
private static void CreateMapPack( Type targetType, SerializerEmitter emiter, CollectionTraits traits ) { var il = emiter.GetPackToMethodILGenerator(); try { /* * int count = ((ICollection<KeyValuePair<string, DateTime>>)dictionary).Count; * packer.PackMapHeader(count); * foreach (KeyValuePair<string, DateTime> current in dictionary) * { * this._serializer0.PackTo(packer, current.Key); * this._serializer1.PackTo(packer, current.Value); * } */ var collection = il.DeclareLocal( targetType, "collection" ); var item = il.DeclareLocal( traits.ElementType, "item" ); var keyProperty = traits.ElementType.GetProperty( "Key" ); var valueProperty = traits.ElementType.GetProperty( "Value" ); // This instruction is always ldarg, not to be ldarga. il.EmitAnyLdarg( 2 ); il.EmitAnyStloc( collection ); var count = il.DeclareLocal( typeof( int ), "count" ); EmitLoadTarget( targetType, il, collection ); il.EmitGetProperty( traits.CountProperty ); il.EmitAnyStloc( count ); il.EmitAnyLdarg( 1 ); il.EmitAnyLdloc( count ); il.EmitAnyCall( Metadata._Packer.PackMapHeader ); il.EmitPop(); Emittion.EmitForEach( il, traits, collection, ( il0, getCurrentEmitter ) => { if ( traits.ElementType.IsGenericType ) { Contract.Assert( traits.ElementType.GetGenericTypeDefinition() == typeof( KeyValuePair<,> ) ); getCurrentEmitter(); il0.EmitAnyStloc( item ); Emittion.EmitSerializeValue( emiter, il0, 1, traits.ElementType.GetGenericArguments()[ 0 ], null, NilImplication.MemberDefault, il1 => { il1.EmitAnyLdloca( item ); il1.EmitGetProperty( keyProperty ); } ); Emittion.EmitSerializeValue( emiter, il0, 1, traits.ElementType.GetGenericArguments()[ 1 ], null, NilImplication.MemberDefault, il1 => { il1.EmitAnyLdloca( item ); il1.EmitGetProperty( valueProperty ); } ); } else { Contract.Assert( traits.ElementType == typeof( DictionaryEntry ) ); getCurrentEmitter(); il0.EmitAnyStloc( item ); Emittion.EmitSerializeValue( emiter, il0, 1, typeof( MessagePackObject ), null, NilImplication.MemberDefault, il1 => { il0.EmitAnyLdloca( item ); il0.EmitGetProperty( Metadata._DictionaryEntry.Key ); il0.EmitUnbox_Any( typeof( MessagePackObject ) ); } ); Emittion.EmitSerializeValue( emiter, il0, 1, typeof( MessagePackObject ), null, NilImplication.MemberDefault, il1 => { il0.EmitAnyLdloca( item ); il0.EmitGetProperty( Metadata._DictionaryEntry.Value ); il0.EmitUnbox_Any( typeof( MessagePackObject ) ); } ); } } ); il.EmitRet(); } finally { il.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); }
private static void CreateMapPack(Type targetType, SerializerEmitter emiter, CollectionTraits traits) { TracingILGenerator packToMethodILGenerator = emiter.GetPackToMethodILGenerator(); LocalVariableHolder localHolder = new LocalVariableHolder(packToMethodILGenerator); try { < > c__DisplayClass20 class3; LocalBuilder serializingCollection = localHolder.GetSerializingCollection(targetType); LocalBuilder item = localHolder.GetSerializingCollectionItem(traits.ElementType); PropertyInfo keyProperty = traits.ElementType.GetProperty("Key"); PropertyInfo valueProperty = traits.ElementType.GetProperty("Value"); packToMethodILGenerator.EmitAnyLdarg(2); packToMethodILGenerator.EmitAnyStloc(serializingCollection); LocalBuilder packingCollectionCount = localHolder.PackingCollectionCount; EmitLoadTarget(targetType, packToMethodILGenerator, serializingCollection); packToMethodILGenerator.EmitGetProperty(traits.CountProperty); packToMethodILGenerator.EmitAnyStloc(packingCollectionCount); packToMethodILGenerator.EmitAnyLdarg(1); packToMethodILGenerator.EmitAnyLdloc(packingCollectionCount); packToMethodILGenerator.EmitAnyCall(_Packer.PackMapHeader); packToMethodILGenerator.EmitPop(); Emittion.EmitForEach(packToMethodILGenerator, traits, serializingCollection, delegate(TracingILGenerator il0, Action getCurrentEmitter) { Action <TracingILGenerator> loadValueEmitter = null; Action <TracingILGenerator> action2 = null; Action <TracingILGenerator> action3 = null; Action <TracingILGenerator> action4 = null; < > c__DisplayClass20 class1 = class3; if (traits.ElementType.IsGenericType) { Contract.Assert(traits.ElementType.GetGenericTypeDefinition() == typeof(KeyValuePair <,>)); getCurrentEmitter(); il0.EmitAnyStloc(item); if (loadValueEmitter == null) { loadValueEmitter = delegate(TracingILGenerator il1) { il1.EmitAnyLdloca(item); il1.EmitGetProperty(keyProperty); }; } Emittion.EmitSerializeValue(emiter, il0, 1, traits.ElementType.GetGenericArguments()[0], null, NilImplication.MemberDefault, loadValueEmitter, localHolder); if (action2 == null) { action2 = delegate(TracingILGenerator il1) { il1.EmitAnyLdloca(item); il1.EmitGetProperty(valueProperty); }; } Emittion.EmitSerializeValue(emiter, il0, 1, traits.ElementType.GetGenericArguments()[1], null, NilImplication.MemberDefault, action2, localHolder); } else { Contract.Assert(traits.ElementType == typeof(DictionaryEntry)); getCurrentEmitter(); il0.EmitAnyStloc(item); if (action3 == null) { action3 = delegate(TracingILGenerator il1) { il0.EmitAnyLdloca(item); il0.EmitGetProperty(_DictionaryEntry.Key); il0.EmitUnbox_Any(typeof(MessagePackObject)); }; } Emittion.EmitSerializeValue(emiter, il0, 1, typeof(MessagePackObject), null, NilImplication.MemberDefault, action3, localHolder); if (action4 == null) { action4 = delegate(TracingILGenerator il1) { il0.EmitAnyLdloca(item); il0.EmitGetProperty(_DictionaryEntry.Value); il0.EmitUnbox_Any(typeof(MessagePackObject)); }; } Emittion.EmitSerializeValue(emiter, il0, 1, typeof(MessagePackObject), null, NilImplication.MemberDefault, action4, localHolder); } });