Ejemplo n.º 1
0
        public override void EmitRead(Type type)
        {
            // arg0: stream, arg1: ctx

            LocalBuilder instance;
            if (type.IsValueType)
                instance = EmitNewInstance(type);
            else
            {
                var id = EmitHelper.EmitDeserializeRef(type);
                instance = EmitNewInstance(type);
                EmitHelper.EmitMarkRef(instance, id);
            }

            //var instance = <get instance>;
            //instance.OnDeserializing();
            //<deserialize members if any>
            //instance.OnDeserialized();
            //return instance;

            //var instance = <get instance>;

            var onDeserializing = type.GetMethodMarkedWith(typeof(OnDeserializingAttribute));
            if (onDeserializing != null)
            {
                // instance.OnDeserializing(ctx)
                emit.ldloc_s(instance)
                    .ldarg_1()
                    .callvirt(onDeserializing);
            }

            Action<MetaMember, MethodInfo, bool> emitDeserializeMember = (member, deserialize, inheritance) =>
            {
                // push stream and ctx and call Deserialize
                emit.ldarg_0()
                    .ldarg_1()
                    .call(deserialize);

                // cast if we went through base (which returns 'object')
                if (inheritance)
                    emit.cast(member.Type);

                // store deserialize result in member
                member.emit_store();
            };

            var members = GetMembers(type);
            for (int i = 0; i < members.Length; i++)
            {
                var member = new MetaMember(members[i]);

                var inheritance = ctx.RequiresInheritance(member.Type);
                var deserialize = ctx.GetReadMethod(member.Type, inheritance);

                //<type|instance>.field|property = <cast if necessary>DeserializeT(stream, ctx);
                {
                    if (member.IsStatic)
                    {
                        var SKIP = emit.deflabel();

                        Statics.HandleMark(1, SKIP);

                        emitDeserializeMember(member, deserialize, inheritance);

                        emit.mark(SKIP);
                    }
                    else
                    {
                        // push value if not static
                        if (type.IsValueType)
                            emit.ldloca_s(instance);
                        else emit.ldloc_s(instance);

                        emitDeserializeMember(member, deserialize, inheritance);
                    }
                }
            }

            var onDeserialized = type.GetMethodMarkedWith(typeof(OnDeserializedAttribute));
            if (onDeserialized != null)
            {
                // instance.OnDeserialized(ctx)
                emit.ldloc_s(instance)
                    .ldarg_1()
                    .callvirt(onDeserialized);
            }

            // return instance;
            emit.ret_s(instance);
        }
Ejemplo n.º 2
0
        public override void EmitWrite(Type type)
        {
            // arg0: stream, arg1: value, arg2: ctx

            if (!type.IsValueType)
                EmitHelper.EmitSerializeRef();

            var onSerializing = type.GetMethodMarkedWith(typeof(OnSerializingAttribute));
            if (onSerializing != null)
            {
                // value.OnSerializing(ctx)
                emit.ldarg_1()
                    .ldarg_2()
                    .callvirt(onSerializing);
            }

            var members = GetMembers(type);
            for (int i = 0; i < members.Length; i++)
            {
                var member = new MetaMember(members[i]);
                var memberType = member.Type;

                // Serialize(stream, <type|value>.member, ctx)
                {
                    if (member.IsStatic)
                    {
                        var SKIP = emit.deflabel();

                        Statics.HandleMark(2, SKIP);

                        // push stream
                        emit.ldarg_0();

                        // push member
                        member.emit_load();

                        // push ctx and call serialize
                        var serialize = ctx.GetWriteMethod(memberType);
                        emit.ldarg_2()
                            .call(serialize);

                        emit.mark(SKIP);
                    }
                    else
                    {
                        // push stream
                        emit.ldarg_0();

                        // push value if member is not static
                        if (type.IsValueType)
                            emit.ldarga_s(1);
                        else emit.ldarg_s(1);

                        // push member
                        member.emit_load();

                        // push ctx and call serialize
                        var serialize = ctx.GetWriteMethod(memberType);
                        emit.ldarg_2()
                            .call(serialize);
                    }
                }
            }

            var onSerialized = type.GetMethodMarkedWith(typeof(OnSerializedAttribute));
            if (onSerialized != null)
            {
                // value.OnSerialized(ctx)
                emit.ldarg_1()
                    .ldarg_2()
                    .callvirt(onSerialized);
            }

            emit.ret();
        }