private static void EmitUnpackMembersFromMap(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder)
        {
            Label label  = unpackerIL.DefineLabel("BEGIN_LOOP");
            Label target = unpackerIL.DefineLabel("END_LOOP");

            unpackerIL.MarkLabel(label);
            LocalBuilder memberName = localHolder.MemberName;

            unpackerIL.EmitAnyLdarg(1);
            unpackerIL.EmitAnyLdloca(memberName);
            unpackerIL.EmitAnyCall(_Unpacker.ReadString);
            unpackerIL.EmitBrfalse(target);
            LocalBuilder unpackedData      = localHolder.UnpackedData;
            LocalBuilder unpackedDataValue = localHolder.UnpackedDataValue;

            for (int i = 0; i < entries.Length; i++)
            {
                if (entries[i].Contract.Name != null)
                {
                    unpackerIL.EmitAnyLdloc(memberName);
                    unpackerIL.EmitLdstr(entries[i].Contract.Name);
                    unpackerIL.EmitAnyCall(_String.op_Equality);
                    Label label3 = unpackerIL.DefineLabel("END_IF_MEMBER_" + i);
                    unpackerIL.EmitBrfalse(label3);
                    if (entries[i].Member == null)
                    {
                        Emittion.EmitGeneralRead(unpackerIL, 1);
                    }
                    else if (UnpackHelpers.IsReadOnlyAppendableCollectionMember(entries[i].Member))
                    {
                        Emittion.EmitDeserializeCollectionValue(emitter, unpackerIL, 1, result, entries[i].Member, entries[i].Member.GetMemberValueType(), entries[i].Contract.NilImplication, localHolder);
                    }
                    else
                    {
                        Emittion.EmitDeserializeValue(emitter, unpackerIL, 1, result, entries[i], localHolder);
                    }
                    unpackerIL.EmitBr(label);
                    unpackerIL.MarkLabel(label3);
                }
            }
            unpackerIL.EmitAnyLdarg(1);
            unpackerIL.EmitCallvirt(_Unpacker.Read);
            unpackerIL.EmitPop();
            unpackerIL.EmitBr(label);
            unpackerIL.MarkLabel(target);
        }
        private static void EmitUnpackMembersFromArray(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder)
        {
            LocalBuilder itemsCount = localHolder.ItemsCount;
            LocalBuilder local      = unpackerIL.DeclareLocal(typeof(int), "unpacked");

            Emittion.EmitGetUnpackerItemsCountAsInt32(unpackerIL, 1, localHolder);
            unpackerIL.EmitAnyStloc(itemsCount);
            for (int i = 0; i < entries.Length; i++)
            {
                Label endOfDeserialization = unpackerIL.DefineLabel("END_IF");
                Label target = unpackerIL.DefineLabel("ELSE");
                unpackerIL.EmitAnyLdloc(local);
                unpackerIL.EmitAnyLdloc(itemsCount);
                unpackerIL.EmitBlt(target);
                if (entries[i].Member != null)
                {
                    Emittion.EmitNilImplication(unpackerIL, 1, entries[i].Contract.Name, entries[i].Contract.NilImplication, endOfDeserialization, localHolder);
                }
                unpackerIL.EmitBr(endOfDeserialization);
                unpackerIL.MarkLabel(target);
                if (entries[i].Member == null)
                {
                    Emittion.EmitGeneralRead(unpackerIL, 1);
                }
                else if (UnpackHelpers.IsReadOnlyAppendableCollectionMember(entries[i].Member))
                {
                    Emittion.EmitDeserializeCollectionValue(emitter, unpackerIL, 1, result, entries[i].Member, entries[i].Member.GetMemberValueType(), entries[i].Contract.NilImplication, localHolder);
                }
                else
                {
                    Emittion.EmitDeserializeValue(emitter, unpackerIL, 1, result, entries[i], localHolder);
                }
                unpackerIL.EmitAnyLdloc(local);
                unpackerIL.EmitLdc_I4_1();
                unpackerIL.EmitAdd();
                unpackerIL.EmitAnyStloc(local);
                unpackerIL.MarkLabel(endOfDeserialization);
            }
        }
Exemple #3
0
        private static void EmitUnpackMembersFromMap(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder)
        {
            /*
             *		var memberName = unpacker.Data.AsString();
             *		if( memberName == "A" )
             *		{
             *			if( !unpacker.Read() )
             *			{
             *				throw SerializationExceptions.NewUnexpectedStreamEndsException();
             *			}
             *
             *			isAFound = true;
             *		}
             *		:
             */

            var beginLoop = unpackerIL.DefineLabel("BEGIN_LOOP");
            var endLoop   = unpackerIL.DefineLabel("END_LOOP");

            unpackerIL.MarkLabel(beginLoop);
            var memberName = localHolder.MemberName;

            unpackerIL.EmitAnyLdarg(1);
            unpackerIL.EmitAnyLdloca(memberName);
            unpackerIL.EmitAnyCall(Metadata._Unpacker.ReadString);
            unpackerIL.EmitBrfalse(endLoop);

            for (int i = 0; i < entries.Length; i++)
            {
                if (entries[i].Contract.Name == null)
                {
                    // skip undefined member
                    continue;
                }

                // TODO: binary comparison

                // Is it current member?
                unpackerIL.EmitAnyLdloc(memberName);
                unpackerIL.EmitLdstr(entries[i].Contract.Name);
                unpackerIL.EmitAnyCall(Metadata._String.op_Equality);
                var endIfCurrentMember = unpackerIL.DefineLabel("END_IF_MEMBER_" + i);
                unpackerIL.EmitBrfalse(endIfCurrentMember);

                // Deserialize value
                if (entries[i].Member == null)
                {
                    Emittion.EmitGeneralRead(unpackerIL, 1);
                    // Ignore undefined member -- Nop.
                }
                else if (UnpackHelpers.IsReadOnlyAppendableCollectionMember(entries[i].Member))
                {
                    Emittion.EmitDeserializeCollectionValue(
                        emitter,
                        unpackerIL,
                        1,
                        result,
                        entries[i].Member,
                        entries[i].Member.GetMemberValueType(),
                        entries[i].Contract.NilImplication,
                        localHolder
                        );
                }
                else
                {
                    Emittion.EmitDeserializeValue(
                        emitter,
                        unpackerIL,
                        1,
                        result,
                        entries[i],
                        localHolder
                        );
                }

                // TOOD: Record for missing check

                unpackerIL.EmitBr(beginLoop);
                unpackerIL.MarkLabel(endIfCurrentMember);
            }

            // Drain next value with unpacker.Read()
            unpackerIL.EmitAnyLdarg(1);
            unpackerIL.EmitCallvirt(Metadata._Unpacker.Read);
            unpackerIL.EmitPop();
            unpackerIL.EmitBr(beginLoop);
            unpackerIL.MarkLabel(endLoop);
        }
Exemple #4
0
        private static void EmitUnpackMembersFromArray(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder, Label endOfDeserialization)
        {
            /*
             *  int unpacked = 0;
             *  int itemsCount = unpacker.ItemsCount;
             *
             *  :
             *  if( unpacked >= itemsCount )
             *  {
             *		HandleNilImplication(...);
             *  }
             *  else
             *  {
             *  #if PRIMITIVE
             *		if( !unpacker.ReadT( out local1 ) )
             *		{
             *			throw SerializationExceptions.NewUnexpectedEndOfStreamMethod();
             *		}
             *  #else
             *		if( !unpacker.Read() )
             *		{
             *			throw SerializationExceptions.NewUnexpectedEndOfStreamMethod();
             *		}
             *
             *		local1 = this._serializer1.Unpack
             *	#endif
             *		unpacked++;
             *	}
             *	:
             */

            // TODO: Supports ExtensionObject like round-tripping.

            var itemsCount = localHolder.ItemsCount;
            var unpacked   = unpackerIL.DeclareLocal(typeof(int), "unpacked");

            Emittion.EmitGetUnpackerItemsCountAsInt32(unpackerIL, 1, localHolder);
            unpackerIL.EmitAnyStloc(itemsCount);

            for (int i = 0; i < entries.Length; i++)
            {
                var endIf0 = unpackerIL.DefineLabel("END_IF");
                var else0  = unpackerIL.DefineLabel("ELSE");

                unpackerIL.EmitAnyLdloc(unpacked);
                unpackerIL.EmitAnyLdloc(itemsCount);
                unpackerIL.EmitBge(else0);

                if (entries[i].Member == null)
                {
                    Emittion.EmitGeneralRead(unpackerIL, 1);
                    // Ignore undefined member -- Nop.
                }
                else if (UnpackHelpers.IsReadOnlyAppendableCollectionMember(entries[i].Member))
                {
                    Emittion.EmitDeserializeCollectionValue(
                        emitter,
                        unpackerIL,
                        1,
                        result,
                        entries[i].Member,
                        entries[i].Member.GetMemberValueType(),
                        entries[i].Contract.NilImplication,
                        localHolder
                        );
                }
                else
                {
                    Emittion.EmitDeserializeValue(
                        emitter,
                        unpackerIL,
                        1,
                        result,
                        entries[i],
                        localHolder
                        );
                }

                unpackerIL.EmitAnyLdloc(unpacked);
                unpackerIL.EmitLdc_I4_1();
                unpackerIL.EmitAdd();
                unpackerIL.EmitAnyStloc(unpacked);

                unpackerIL.EmitBr(endIf0);

                unpackerIL.MarkLabel(else0);

                if (entries[i].Member != null)
                {
                    // Respect nil implication.
                    switch (entries[i].Contract.NilImplication)
                    {
                    case NilImplication.MemberDefault:
                    {
                        unpackerIL.EmitBr(endOfDeserialization);
                        break;
                    }

                    case NilImplication.Null:
                    {
                        if (entries[i].Member.GetMemberValueType().GetIsValueType())
                        {
                            if (Nullable.GetUnderlyingType(entries[i].Member.GetMemberValueType()) == null)
                            {
                                // val type

                                /*
                                 * if( value == null )
                                 * {
                                 *		throw SerializationEceptions.NewValueTypeCannotBeNull( "...", typeof( MEMBER ), typeof( TYPE ) );
                                 * }
                                 */
                                unpackerIL.EmitLdstr(entries[i].Contract.Name);
                                unpackerIL.EmitLdtoken(entries[i].Member.GetMemberValueType());
                                unpackerIL.EmitAnyCall(Metadata._Type.GetTypeFromHandle);
                                unpackerIL.EmitLdtoken(entries[i].Member.DeclaringType);
                                unpackerIL.EmitAnyCall(Metadata._Type.GetTypeFromHandle);
                                unpackerIL.EmitAnyCall(SerializationExceptions.NewValueTypeCannotBeNull3Method);
                                unpackerIL.EmitThrow();
                            }
                            else
                            {
                                // nullable
                                unpackerIL.EmitAnyLdloca(localHolder.GetDeserializedValue(entries[i].Member.GetMemberValueType()));
                                unpackerIL.EmitInitobj(entries[i].Member.GetMemberValueType());
                                unpackerIL.EmitAnyLdloc(result);
                                unpackerIL.EmitAnyLdloc(localHolder.GetDeserializedValue(entries[i].Member.GetMemberValueType()));
                                Emittion.EmitStoreValue(unpackerIL, entries[i].Member);
                            }
                        }
                        else
                        {
                            // ref type
                            unpackerIL.EmitAnyLdloc(result);
                            unpackerIL.EmitLdnull();
                            Emittion.EmitStoreValue(unpackerIL, entries[i].Member);
                        }

                        break;
                    }

                    case NilImplication.Prohibit:
                    {
                        unpackerIL.EmitLdstr(entries[i].Contract.Name);
                        unpackerIL.EmitAnyCall(SerializationExceptions.NewNullIsProhibitedMethod);
                        unpackerIL.EmitThrow();
                        break;
                    }
                    }
                }

                unpackerIL.MarkLabel(endIf0);
            }
        }
Exemple #5
0
        private static void EmitUnpackMembersFromArray(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder)
        {
            /*
             *  int unpacked = 0;
             *  int itemsCount = unpacker.ItemsCount;
             *
             *  :
             *  if( unpacked == itemsCount )
             *  {
             *		HandleNilImplication(...);
             *  }
             *  else
             *  {
             *  #if PRIMITIVE
             *		if( !unpacker.ReadT( out local1 ) )
             *		{
             *			throw SerializationExceptions.NewUnexpectedEndOfStreamMethod();
             *		}
             *  #else
             *		if( !unpacker.Read() )
             *		{
             *			throw SerializationExceptions.NewUnexpectedEndOfStreamMethod();
             *		}
             *
             *		local1 = this._serializer1.Unpack
             *	#endif
             *		unpacked++;
             *	}
             *	:
             */

            // TODO: Supports ExtensionObject like round-tripping.

            var itemsCount = localHolder.ItemsCount;
            var unpacked   = unpackerIL.DeclareLocal(typeof(int), "unpacked");

            Emittion.EmitGetUnpackerItemsCountAsInt32(unpackerIL, 1, localHolder);
            unpackerIL.EmitAnyStloc(itemsCount);

            for (int i = 0; i < entries.Length; i++)
            {
                var endIf0 = unpackerIL.DefineLabel("END_IF");
                var else0  = unpackerIL.DefineLabel("ELSE");

                unpackerIL.EmitAnyLdloc(unpacked);
                unpackerIL.EmitAnyLdloc(itemsCount);
                unpackerIL.EmitBlt(else0);
                // Tail missing member handling.
                if (entries[i].Member != null)
                {
                    // Respect nil implication.
                    Emittion.EmitNilImplication(unpackerIL, 1, entries[i].Contract.Name, entries[i].Contract.NilImplication, endIf0, localHolder);
                }

                unpackerIL.EmitBr(endIf0);

                unpackerIL.MarkLabel(else0);

                if (entries[i].Member == null)
                {
                    Emittion.EmitGeneralRead(unpackerIL, 1);
                    // Ignore undefined member -- Nop.
                }
                else if (UnpackHelpers.IsReadOnlyAppendableCollectionMember(entries[i].Member))
                {
                    Emittion.EmitDeserializeCollectionValue(
                        emitter,
                        unpackerIL,
                        1,
                        result,
                        entries[i].Member,
                        entries[i].Member.GetMemberValueType(),
                        entries[i].Contract.NilImplication,
                        localHolder
                        );
                }
                else
                {
                    Emittion.EmitDeserializeValue(
                        emitter,
                        unpackerIL,
                        1,
                        result,
                        entries[i],
                        localHolder
                        );
                }

                unpackerIL.EmitAnyLdloc(unpacked);
                unpackerIL.EmitLdc_I4_1();
                unpackerIL.EmitAdd();
                unpackerIL.EmitAnyStloc(unpacked);

                unpackerIL.MarkLabel(endIf0);
            }
        }