コード例 #1
0
        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();
            }
        }