示例#1
0
        private static void CreateSerializeMethod(TypeDefinition wrapper, ModuleDefinition module, PropertyDefinition valuesField, IReadOnlyList <IExposedProperty> properties)
        {
            MethodDefinition m = wrapper.AddMethod("Serialize",
                                                   MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual);

            ParameterDefinition paraId      = m.AddParameter <int>("id");
            ParameterDefinition paraWriter  = m.AddParameter(module.GetTypeReference(typeof(MessagePackWriter).MakeByRefType()), "writer");
            ParameterDefinition paraOptions = m.AddParameter <MessagePackSerializerOptions>("options");

            ILProcessor il = m.BeginEdit();

            MethodReference getItem = module.GetMethod <Dictionary <int, object> >("get_Item").MakeHostInstanceGeneric(module.GetTypeReference(typeof(Dictionary <,>)).MakeGenericInstanceType(module.GetTypeReference <int>(), module.GetTypeReference <object>()));

            il.EmitIfElse(properties, (property, index, next, body, fill) =>
            {
                // if (id == <id>)
                fill.Add(ILHelper.Ldarg(il, paraId));
                if (property.Id == 0)
                {
                    fill.Add(Instruction.Create(OpCodes.Brtrue, next));
                }
                else
                {
                    fill.Add(ILHelper.Int(property.Id));
                    fill.Add(Instruction.Create(OpCodes.Bne_Un, next));
                }
            }, (property, index, next, fill) =>
            {
                // writer.Write((Type) values[id])
                // options.Resolver.GetFormatterWithVerify<Type>().Serialize(ref writer, (Type) values[id], options)
                fill.AddRange(FormatterHelper.GetWriteValue(property.FieldTypeComponentAware, module, il, paraWriter, paraOptions, list =>
                {
                    list.Add(Instruction.Create(OpCodes.Call, valuesField.GetMethod));
                    list.Add(ILHelper.Int(property.Id));
                    list.Add(Instruction.Create(OpCodes.Callvirt, getItem));
                    if (property.IsValueType)
                    {
                        list.Add(Instruction.Create(OpCodes.Unbox_Any, property.FieldTypeComponentAware));
                    }
                }));

                if (index <= properties.Count - 1)
                {
                    fill.Add(Instruction.Create(OpCodes.Ret));
                }
            }, fill => { fill.Add(Instruction.Create(OpCodes.Ret)); });

            m.EndEdit();
        }
示例#2
0
        private static void CreateDeserializeMethod(TypeDefinition wrapper, ModuleDefinition module, IReadOnlyList <IExposedProperty> properties)
        {
            MethodDefinition m = wrapper.AddMethod <object>("Deserialize",
                                                            MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual);

            ParameterDefinition paraId      = m.AddParameter <int>("id");
            ParameterDefinition paraReader  = m.AddParameter(module.GetTypeReference(typeof(MessagePackReader).MakeByRefType()), "reader");
            ParameterDefinition paraOptions = m.AddParameter <MessagePackSerializerOptions>("options");

            ILProcessor il = m.BeginEdit();

            il.EmitIfElse(properties, (property, index, next, body, fill) =>
            {
                // if (id == <id>)
                fill.Add(ILHelper.Ldarg(il, paraId));
                if (property.Id == 0)
                {
                    fill.Add(Instruction.Create(OpCodes.Brtrue, next));
                }
                else
                {
                    fill.Add(ILHelper.Int(property.Id));
                    fill.Add(Instruction.Create(OpCodes.Bne_Un, next));
                }
            }, (property, index, next, fill) =>
            {
                // return reader.Read()
                // return options.Resolver.GetFormatterWithVerify<Type>().Deserialize(ref reader, options)

                fill.AddRange(FormatterHelper.GetReadValue(property.FieldTypeComponentAware, module, il, paraReader, paraOptions));
                if (property.IsValueType)
                {
                    fill.Add(Instruction.Create(OpCodes.Box, property.FieldTypeComponentAware));
                }

                fill.Add(Instruction.Create(OpCodes.Ret));
            }, fill =>
            {
                // return null
                fill.Add(Instruction.Create(OpCodes.Ldnull));
                fill.Add(Instruction.Create(OpCodes.Ret));
            });

            m.EndEdit();
        }
        public static ParameterDefinition AddParameter(this MethodDefinition m, TypeReference type, string name = null)
        {
            if (m.Module == null)
            {
                throw new NullReferenceException($"This method has yet to be added to the assembly and doesn't have a module. Please provide a module.");
            }

            return(m.AddParameter(m.Module, type, name));
        }
 public static ParameterDefinition AddParameter <T>(this MethodDefinition m, ModuleDefinition module, string name = null)
 {
     return(m.AddParameter(module, module.ImportReference(typeof(T)), name));
 }