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