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