public static bool CheckMethodFirstParams(string module, MethodDefinition method) { Collection <ParameterDefinition> parms = method.Parameters; for (int i = 0; i < parms.Count; ++i) { ParameterDefinition parm = parms[i]; TypeDefinition parmType = parm.ParameterType.Resolve(); if (i == 0) { if (parmType.FullName != typeof(IConnection).FullName) { Debug.LogError(module + ": 方法[" + method.FullName + "]中第一个参数只能为[" + typeof(IConnection).FullName + "]"); return(false); } } else if (!BaseTypeFactory.IsBaseType(parmType) && !parmType.IsValueType) { if (parmType.FullName == typeof(byte[]).FullName) { continue; } if (parmType.FullName == typeof(ByteBuffer).FullName) { continue; } Debug.LogError(module + ": 方法[" + method.FullName + "]中的参数只能为[基本类型,字符串,枚举,结构体,基本类型数组,字符串数组,枚举数组,结构体数组]而不能为[" + parmType.FullName + "]"); return(false); } } return(true); }
public static MethodDefinition CreateSetMethod(ModuleDefinition module, TypeDefinition type, FieldDefinition field, string name, FieldDefinition dirty, int offset) { MethodDefinition set = MethodFactory.CreateMethod(module, type, "set_Sync" + name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, module.ImportReference(typeof(void)), true); set.Body.Variables.Add(new VariableDefinition(module.ImportReference(typeof(bool)))); set.Parameters.Add(new ParameterDefinition("value", ParameterAttributes.None, field.FieldType)); ILProcessor processor = set.Body.GetILProcessor(); if (BaseTypeFactory.IsSystemBaseType(field.FieldType.Resolve())) { if (field.FieldType.IsValueType) { AppendBaseTypeInstruction(processor, field, dirty, offset); } else if (field.FieldType.ToString() == "System.String") { AppendOpInequalityInstruction(module, processor, field, dirty, offset); } } else if (field.FieldType.IsValueType) { AppendOpInequalityInstruction(module, processor, field, dirty, offset); } set.SemanticsAttributes = MethodSemanticsAttributes.Setter; return(set); }
public static bool CheckSyncFiled(string module, TypeDefinition type, TypeDefinition fieldType) { if (!BaseTypeFactory.IsBaseType(fieldType)) { Debug.LogError(module + ": [" + type.FullName + "]中的字段只能为[基本类型,字符串,枚举]而不能为[" + fieldType.FullName + "]"); return(false); } return(true); }
public static bool CheckStructFiled(string module, TypeDefinition type, TypeDefinition fieldType) { if (fieldType.FullName == typeof(byte[]).FullName) { return(true); } if (fieldType.FullName == typeof(ByteBuffer).FullName) { return(true); } if (!BaseTypeFactory.IsBaseType(fieldType) && !fieldType.IsValueType) { Debug.LogError(module + ": [" + type.FullName + "]中的字段只能为[基本类型,字符串,枚举,结构体,基本类型数组,字符串数组,枚举数组,结构体数组]而不能为[" + fieldType.FullName + "]"); return(false); } return(true); }
private static void WriteDeserializeInstruction(ModuleDefinition module, MethodDefinition method, ILProcessor processor, FieldDefinition field, int index, int offset) { method.Body.Variables.Add(new VariableDefinition(module.ImportReference(typeof(bool)))); Instruction end = processor.Create(OpCodes.Nop); processor.Append(processor.Create(OpCodes.Nop)); processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(processor.Create(OpCodes.Ldc_I8, 1L << index)); processor.Append(processor.Create(OpCodes.And)); processor.Append(processor.Create(OpCodes.Ldc_I8, 1L << index)); processor.Append(processor.Create(OpCodes.Ceq)); processor.Append(processor.Create(OpCodes.Stloc, index + offset)); processor.Append(processor.Create(OpCodes.Ldloc, index + offset)); processor.Append(processor.Create(OpCodes.Brfalse_S, end)); processor.Append(processor.Create(OpCodes.Nop)); processor.Append(processor.Create(OpCodes.Ldarg_0)); processor.Append(processor.Create(OpCodes.Ldarg_1)); processor.Append(BaseTypeFactory.CreateReadInstruction(module, processor, field.FieldType.Resolve())); processor.Append(processor.Create(OpCodes.Stfld, field)); processor.Append(end); }
public static void Weave(ModuleDefinition module, Dictionary <ushort, MethodDefinition> methods, TypeDefinition protocol) { if (module == null || methods.Count == 0 || protocol == null) { return; } FieldReference connectionField = module.ImportReference(ResolveHelper.ResolveField(protocol.BaseType, "m_Connection")); { //public void Register(); MethodDefinition registerMethod = ResolveHelper.ResolveMethod(protocol, "Register"); registerMethod.Body.Variables.Clear(); registerMethod.Body.Instructions.Clear(); ILProcessor registerProcessor = registerMethod.Body.GetILProcessor(); registerProcessor.Append(registerProcessor.Create(OpCodes.Nop)); foreach (ushort msgId in methods.Keys) { MethodDefinition method = methods[msgId]; if (!CheckHelper.CheckMethodParams(WeaverProgram.Client, method)) { continue; } MethodDefinition protoMethodImpl = MethodFactory.CreateMethod(module, protocol, "OnProtocol_" + msgId, MethodAttributes.Private | MethodAttributes.HideBySig, true); protoMethodImpl.Parameters.Add(new ParameterDefinition("msg", ParameterAttributes.None, module.ImportReference(WeaverProgram.ChannelMessageType))); protoMethodImpl.Body.Variables.Add(new VariableDefinition(module.ImportReference(WeaverProgram.ByteBufferType))); { ILProcessor processor = protoMethodImpl.Body.GetILProcessor(); processor.Append(processor.Create(OpCodes.Nop)); processor.Append(processor.Create(OpCodes.Ldarg_1)); processor.Append(processor.Create(OpCodes.Ldfld, module.ImportReference(WeaverProgram.ChannelMessageBufferField))); processor.Append(processor.Create(OpCodes.Stloc_0)); List <int> indexs = new List <int>(); Collection <ParameterDefinition> parms = method.Parameters; for (int i = 0; i < parms.Count; ++i) { ParameterDefinition parm = parms[i]; TypeDefinition parmType = parm.ParameterType.Resolve(); protoMethodImpl.Body.Variables.Add(new VariableDefinition(module.ImportReference(parm.ParameterType))); int index = protoMethodImpl.Body.Variables.Count - 1; indexs.Add(index); if (parm.ParameterType.FullName == typeof(byte[]).FullName) { processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(processor.Create(OpCodes.Call, module.ImportReference(WeaverProgram.ByteUtilsReadMethod))); processor.Append(processor.Create(OpCodes.Stloc, index)); continue; } if (parm.ParameterType.FullName == typeof(ByteBuffer).FullName) { processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(processor.Create(OpCodes.Call, module.ImportReference(WeaverProgram.ByteBufferUtilsReadMethod))); processor.Append(processor.Create(OpCodes.Stloc, index)); continue; } if (parm.ParameterType.IsArray) { ArrayReadFactory.CreateMethodVariableReadInstruction(module, protoMethodImpl, processor, parmType); continue; } if (BaseTypeFactory.IsBaseType(parmType)) { processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(BaseTypeFactory.CreateReadInstruction(module, processor, parmType)); processor.Append(processor.Create(OpCodes.Stloc, index)); continue; } if (parmType.IsValueType) { MethodDefinition deserialize = StructMethodFactory.CreateDeserialize(module, parmType); processor.Append(processor.Create(OpCodes.Ldloca, index)); processor.Append(processor.Create(OpCodes.Initobj, module.ImportReference(parmType))); processor.Append(processor.Create(OpCodes.Ldloca, index)); processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(processor.Create(OpCodes.Call, module.ImportReference(deserialize))); } } for (int i = 0; i < indexs.Count; ++i) { processor.Append(processor.Create(OpCodes.Ldloc, indexs[i])); } processor.Append(processor.Create(OpCodes.Call, method)); processor.Append(processor.Create(OpCodes.Nop)); processor.Append(processor.Create(OpCodes.Ret)); } registerProcessor.Append(registerProcessor.Create(OpCodes.Ldarg_0)); registerProcessor.Append(registerProcessor.Create(OpCodes.Ldfld, connectionField)); registerProcessor.Append(registerProcessor.Create(OpCodes.Ldc_I4, msgId)); registerProcessor.Append(registerProcessor.Create(OpCodes.Ldarg_0)); registerProcessor.Append(registerProcessor.Create(OpCodes.Ldftn, protoMethodImpl)); registerProcessor.Append(registerProcessor.Create(OpCodes.Newobj, module.ImportReference(typeof(ChannelMessageDelegate).GetConstructor(new Type[] { typeof(object), typeof(IntPtr) })))); registerProcessor.Append(registerProcessor.Create(OpCodes.Callvirt, module.ImportReference(WeaverProgram.IConnectionRegisterHandlerMethod))); } registerProcessor.Append(registerProcessor.Create(OpCodes.Ret)); } { //public void Unregister(); MethodDefinition unregisterMethod = ResolveHelper.ResolveMethod(protocol, "UnRegister"); unregisterMethod.Body.Variables.Clear(); unregisterMethod.Body.Instructions.Clear(); ILProcessor unregisterProcessor = unregisterMethod.Body.GetILProcessor(); unregisterProcessor.Append(unregisterProcessor.Create(OpCodes.Nop)); foreach (ushort key in methods.Keys) { unregisterProcessor.Append(unregisterProcessor.Create(OpCodes.Ldarg_0)); unregisterProcessor.Append(unregisterProcessor.Create(OpCodes.Ldfld, connectionField)); unregisterProcessor.Append(unregisterProcessor.Create(OpCodes.Ldc_I4, key)); unregisterProcessor.Append(unregisterProcessor.Create(OpCodes.Callvirt, module.ImportReference(WeaverProgram.IConnectionUnregisterHandlerMethod))); } unregisterProcessor.Append(unregisterProcessor.Create(OpCodes.Ret)); } }
public static void CreateMethodVariableReadInstruction(ModuleDefinition module, MethodDefinition method, ILProcessor processor, TypeDefinition parmType) { int typeIndex = method.Body.Variables.Count - 1; int lenIndex = method.Body.Variables.Count; int checkIndex = method.Body.Variables.Count + 1; int intIndex = method.Body.Variables.Count + 2; int boolIndex = method.Body.Variables.Count + 3; method.Body.Variables.Add(new VariableDefinition(module.ImportReference(typeof(int)))); method.Body.Variables.Add(new VariableDefinition(module.ImportReference(typeof(bool)))); method.Body.Variables.Add(new VariableDefinition(module.ImportReference(typeof(int)))); method.Body.Variables.Add(new VariableDefinition(module.ImportReference(typeof(bool)))); Instruction goto1 = processor.Create(OpCodes.Nop); Instruction goto2 = processor.Create(OpCodes.Nop); Instruction goto3 = processor.Create(OpCodes.Nop); //T[] varArray = null; processor.Append(processor.Create(OpCodes.Ldnull)); processor.Append(processor.Create(OpCodes.Stloc, typeIndex)); //int len = reader.ReadInt32(); processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(BaseTypeFactory.CreateReadInstruction(module, processor, typeof(int).ToString())); processor.Append(processor.Create(OpCodes.Stloc, lenIndex)); //if (len > 0) processor.Append(processor.Create(OpCodes.Ldloc, lenIndex)); processor.Append(processor.Create(OpCodes.Ldc_I4_0)); processor.Append(processor.Create(OpCodes.Cgt)); processor.Append(processor.Create(OpCodes.Stloc, checkIndex)); processor.Append(processor.Create(OpCodes.Ldloc, checkIndex)); processor.Append(processor.Create(OpCodes.Brfalse_S, goto3)); //varArray = new T[len]; processor.Append(processor.Create(OpCodes.Ldloc, lenIndex)); processor.Append(processor.Create(OpCodes.Newarr, module.ImportReference(parmType))); processor.Append(processor.Create(OpCodes.Stloc, typeIndex)); //for (int i = 0; i < len; i++) processor.Append(processor.Create(OpCodes.Ldc_I4_0)); processor.Append(processor.Create(OpCodes.Stloc, intIndex)); //go to check processor.Append(processor.Create(OpCodes.Br_S, goto2)); processor.Append(goto1); if (BaseTypeFactory.IsBaseType(parmType)) { //varArray[i] = reader.ReadT(); processor.Append(processor.Create(OpCodes.Ldloc, typeIndex)); processor.Append(processor.Create(OpCodes.Ldloc, intIndex)); processor.Append(processor.Create(OpCodes.Ldelema, module.ImportReference(parmType))); processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(BaseTypeFactory.CreateReadInstruction(module, processor, parmType)); processor.Append(processor.Create(OpCodes.Stobj, module.ImportReference(parmType))); } else if (parmType.IsValueType) { //varArray[i].Deserialize(writer); processor.Append(processor.Create(OpCodes.Ldloc, typeIndex)); processor.Append(processor.Create(OpCodes.Ldloc, intIndex)); processor.Append(processor.Create(OpCodes.Ldelema, module.ImportReference(parmType))); processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(processor.Create(OpCodes.Call, StructMethodFactory.FindDeserialize(module, parmType))); } //i++ processor.Append(processor.Create(OpCodes.Nop)); processor.Append(processor.Create(OpCodes.Ldloc, intIndex)); processor.Append(processor.Create(OpCodes.Ldc_I4_1)); processor.Append(processor.Create(OpCodes.Add)); processor.Append(processor.Create(OpCodes.Stloc, intIndex)); //i < len processor.Append(goto2); processor.Append(processor.Create(OpCodes.Ldloc, intIndex)); processor.Append(processor.Create(OpCodes.Ldloc, lenIndex)); processor.Append(processor.Create(OpCodes.Clt)); processor.Append(processor.Create(OpCodes.Stloc, boolIndex)); processor.Append(processor.Create(OpCodes.Ldloc, boolIndex)); //go to start processor.Append(processor.Create(OpCodes.Brtrue_S, goto1)); processor.Append(goto3); }
public static MethodDefinition CreateDeserialize(ModuleDefinition module, TypeDefinition type) { MethodDefinition deserialize = MethodFactory.CreateMethod(module, type, "Deserialize", MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, true); deserialize.Parameters.Add(new ParameterDefinition("rBuffer", ParameterAttributes.None, module.ImportReference(WeaverProgram.ByteBufferType))); ILProcessor processor = deserialize.Body.GetILProcessor(); processor.Append(processor.Create(OpCodes.Nop)); foreach (FieldDefinition field in type.Fields) { TypeDefinition fieldType = field.FieldType.Resolve(); if (!CheckHelper.CheckStructFiled(WeaverProgram.Base, type, fieldType)) { continue; } if (field.FieldType.FullName == typeof(byte[]).FullName) { processor.Append(processor.Create(OpCodes.Ldarg, 0)); processor.Append(processor.Create(OpCodes.Ldarg, 1)); processor.Append(processor.Create(OpCodes.Call, module.ImportReference(WeaverProgram.ByteUtilsReadMethod))); processor.Append(processor.Create(OpCodes.Stfld, field)); continue; } if (field.FieldType.FullName == typeof(ByteBuffer).FullName) { processor.Append(processor.Create(OpCodes.Ldarg, 0)); processor.Append(processor.Create(OpCodes.Ldarg, 1)); processor.Append(processor.Create(OpCodes.Call, module.ImportReference(WeaverProgram.ByteBufferUtilsReadMethod))); processor.Append(processor.Create(OpCodes.Stfld, field)); continue; } if (field.FieldType.IsArray) { ArrayReadFactory.CreateStructFieldReadInstruction(module, deserialize, processor, field, fieldType); } else if (BaseTypeFactory.IsBaseType(fieldType)) { processor.Append(processor.Create(OpCodes.Ldarg_0)); processor.Append(processor.Create(OpCodes.Ldarg_1)); processor.Append(BaseTypeFactory.CreateReadInstruction(module, processor, fieldType)); processor.Append(processor.Create(OpCodes.Stfld, field)); } else if (fieldType.IsValueType) { MethodDefinition dser = CreateDeserialize(module, fieldType); processor.Append(processor.Create(OpCodes.Ldarg_0)); processor.Append(processor.Create(OpCodes.Ldflda, field)); processor.Append(processor.Create(OpCodes.Ldarg_1)); processor.Append(processor.Create(OpCodes.Call, dser)); } } processor.Append(processor.Create(OpCodes.Nop)); processor.Append(processor.Create(OpCodes.Ret)); return(deserialize); }
public static void Weave(ModuleDefinition module, Dictionary <ushort, MethodData> methods) { foreach (ushort msgId in methods.Keys) { MethodData methodData = methods[msgId]; ChannelType channel = methodData.Channel; MethodDefinition method = methodData.MethodDef; if (!CheckHelper.CheckMethodFirstParams(WeaverProgram.Server, method)) { continue; } ILProcessor processor = method.Body.GetILProcessor(); method.Body.Variables.Clear(); method.Body.Instructions.Clear(); method.Body.Variables.Add(new VariableDefinition(module.ImportReference(WeaverProgram.ByteBufferType))); processor.Append(processor.Create(OpCodes.Nop)); processor.Append(processor.Create(OpCodes.Ldc_I4, WeaverProgram.SugBufferSize)); processor.Append(processor.Create(OpCodes.Call, module.ImportReference(WeaverProgram.ByteBufferAllocateMethod))); processor.Append(processor.Create(OpCodes.Stloc_0)); Collection <ParameterDefinition> parms = method.Parameters; for (int i = 0; i < parms.Count; ++i) { if (i > 0) { ParameterDefinition parm = parms[i]; byte index = (byte)(method.IsStatic ? i : i + 1); TypeDefinition parmType = parm.ParameterType.Resolve(); if (parm.ParameterType.FullName == typeof(byte[]).FullName) { processor.Append(processor.Create(OpCodes.Ldarg_S, index)); processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(processor.Create(OpCodes.Call, module.ImportReference(WeaverProgram.ByteUtilsWriteMethod))); continue; } if (parm.ParameterType.FullName == typeof(ByteBuffer).FullName) { processor.Append(processor.Create(OpCodes.Ldarg_S, index)); processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(processor.Create(OpCodes.Call, module.ImportReference(WeaverProgram.ByteBufferUtilsWriteMethod))); continue; } if (parm.ParameterType.IsArray) { ArrayWriteFactory.CreateMethodParamWriteInstruction(module, method, processor, parmType, index); continue; } if (BaseTypeFactory.IsBaseType(parmType)) { processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(processor.Create(OpCodes.Ldarg_S, index)); processor.Append(BaseTypeFactory.CreateWriteInstruction(module, processor, parmType)); continue; } if (parmType.IsValueType) { MethodDefinition serialize = StructMethodFactory.CreateSerialize(module, parmType); processor.Append(processor.Create(OpCodes.Ldarga_S, index)); processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(processor.Create(OpCodes.Call, module.ImportReference(serialize))); } } } processor.Append(processor.Create(method.IsStatic ? OpCodes.Ldarg_0 : OpCodes.Ldarg_1)); processor.Append(processor.Create(OpCodes.Ldc_I4, msgId)); processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(processor.Create(OpCodes.Ldc_I4, (int)channel)); processor.Append(processor.Create(OpCodes.Call, module.ImportReference(WeaverProgram.NetworkServerManagerSendMethod))); processor.Append(processor.Create(OpCodes.Nop)); processor.Append(processor.Create(OpCodes.Ret)); } }
public static void Weave(ModuleDefinition module, List <TypeDefinition> syncs, out Dictionary <FieldDefinition, MethodDefinition> gets, out Dictionary <FieldDefinition, MethodDefinition> sets) { sets = new Dictionary <FieldDefinition, MethodDefinition>(); gets = new Dictionary <FieldDefinition, MethodDefinition>(); foreach (TypeDefinition type in syncs) { List <FieldDefinition> fields = new List <FieldDefinition>(); foreach (FieldDefinition field in type.Fields) { if (field.CustomAttributes.Count > 0 && field.CustomAttributes[0].AttributeType.FullName == WeaverProgram.SyncFieldType.FullName) { fields.Add(field); } } if (fields.Count == 0) { return; } FieldDefinition dirty = FieldFactory.CreateField(module, type, "m_Dirty", FieldAttributes.Private, module.ImportReference(typeof(long))); //public bool IsDirty(); ModifyIsDirtyMethod(module, type, dirty); //get set method for (int i = 0; i < fields.Count; ++i) { FieldDefinition field = fields[i]; if (!CheckHelper.CheckSyncFiled(WeaverProgram.Server, type, field.FieldType.Resolve())) { continue; } string name = field.Name; MethodDefinition get = CreateGetMethod(module, type, field, name); MethodDefinition set = CreateSetMethod(module, type, field, name, dirty, i); PropertyDefinition propertyDefinition = new PropertyDefinition("Sync" + name, PropertyAttributes.None, field.FieldType) { GetMethod = get, SetMethod = set }; type.Properties.Add(propertyDefinition); gets.Add(field, get); sets.Add(field, set); } //Serialize MethodDefinition serialize = ResolveHelper.ResolveMethod(type, "Serialize"); ILProcessor processor = serialize.Body.GetILProcessor(); processor.Body.Instructions.Clear(); Instruction ins1 = processor.Create(OpCodes.Nop); Instruction ins2 = processor.Create(OpCodes.Ldarg_0); Instruction ins3 = processor.Create(OpCodes.Ldc_I8, 0L); Instruction ins4 = processor.Create(OpCodes.Stfld, dirty); Instruction ins5 = processor.Create(OpCodes.Nop); Instruction ins6 = processor.Create(OpCodes.Ret); processor.Append(processor.Create(OpCodes.Nop)); processor.Append(processor.Create(OpCodes.Ldarg_0)); processor.Append(processor.Create(OpCodes.Ldfld, dirty)); processor.Append(processor.Create(OpCodes.Ldc_I8, 0L)); processor.Append(processor.Create(OpCodes.Cgt)); processor.Append(processor.Create(OpCodes.Stloc_0)); processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(processor.Create(OpCodes.Brfalse, ins6)); processor.Append(processor.Create(OpCodes.Nop)); processor.Append(processor.Create(OpCodes.Ldarg_1)); processor.Append(processor.Create(OpCodes.Ldarg_0)); processor.Append(processor.Create(OpCodes.Ldfld, dirty)); processor.Append(BaseTypeFactory.CreateWriteInstruction(module, processor, dirty.FieldType.Resolve())); serialize.Body.Variables.Add(new VariableDefinition(module.ImportReference(typeof(bool)))); int offset = serialize.Body.Variables.Count; for (int i = 0; i < fields.Count; ++i) { WriteSerializeInstruction(module, serialize, processor, fields[i], dirty, i, offset); } processor.Append(ins1); processor.Append(ins2); processor.Append(ins3); processor.Append(ins4); processor.Append(ins5); processor.Append(ins6); } }
public static void Weave(ModuleDefinition module, List <TypeDefinition> syncs) { if (module == null || syncs.Count == 0) { return; } foreach (TypeDefinition type in syncs) { List <FieldDefinition> fields = new List <FieldDefinition>(); foreach (FieldDefinition field in type.Fields) { if (field.CustomAttributes.Count > 0 && field.CustomAttributes[0].AttributeType.FullName == WeaverProgram.SyncFieldType.FullName) { fields.Add(field); } } if (fields.Count == 0) { return; } //Deserialize MethodDefinition deserialize = ResolveHelper.ResolveMethod(type, "Deserialize"); ILProcessor processor = deserialize.Body.GetILProcessor(); processor.Body.Instructions.Clear(); Instruction ret = processor.Create(OpCodes.Ret); processor.Append(processor.Create(OpCodes.Nop)); processor.Append(processor.Create(OpCodes.Ldarg_1)); processor.Append(BaseTypeFactory.CreateReadInstruction(module, processor, typeof(long).ToString())); processor.Append(processor.Create(OpCodes.Stloc_0)); processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(processor.Create(OpCodes.Ldc_I8, 0L)); processor.Append(processor.Create(OpCodes.Cgt)); processor.Append(processor.Create(OpCodes.Stloc_1)); processor.Append(processor.Create(OpCodes.Ldloc_1)); processor.Append(processor.Create(OpCodes.Brfalse, ret)); deserialize.Body.Variables.Add(new VariableDefinition(module.ImportReference(typeof(long)))); deserialize.Body.Variables.Add(new VariableDefinition(module.ImportReference(typeof(bool)))); int offset = deserialize.Body.Variables.Count; for (int i = 0; i < fields.Count; ++i) { FieldDefinition field = fields[i]; if (!CheckHelper.CheckSyncFiled(WeaverProgram.Client, type, field.FieldType.Resolve())) { continue; } WriteDeserializeInstruction(module, deserialize, processor, field, i, offset); } processor.Append(processor.Create(OpCodes.Nop)); processor.Append(ret); } }
public static void CreateStructFieldWriteInstruction(ModuleDefinition module, MethodDefinition method, ILProcessor processor, FieldDefinition field, TypeDefinition fieldType) { int lenIndex = method.Body.Variables.Count; int checkIndex = method.Body.Variables.Count + 1; int intIndex = method.Body.Variables.Count + 2; int boolIndex = method.Body.Variables.Count + 3; method.Body.Variables.Add(new VariableDefinition(module.ImportReference(typeof(int)))); method.Body.Variables.Add(new VariableDefinition(module.ImportReference(typeof(bool)))); method.Body.Variables.Add(new VariableDefinition(module.ImportReference(typeof(int)))); method.Body.Variables.Add(new VariableDefinition(module.ImportReference(typeof(bool)))); Instruction goto1 = processor.Create(OpCodes.Nop); Instruction goto2 = processor.Create(OpCodes.Nop); Instruction goto3 = processor.Create(OpCodes.Nop); Instruction goto4 = processor.Create(OpCodes.Nop); Instruction goto5 = processor.Create(OpCodes.Nop); //int len = this.Field != null ? this.Field.Length : 0; processor.Append(processor.Create(OpCodes.Ldarg_0)); processor.Append(processor.Create(OpCodes.Ldfld, field)); processor.Append(processor.Create(OpCodes.Brtrue_S, goto1)); processor.Append(processor.Create(OpCodes.Ldc_I4_0)); processor.Append(processor.Create(OpCodes.Br_S, goto2)); processor.Append(goto1); processor.Append(processor.Create(OpCodes.Ldarg_0)); processor.Append(processor.Create(OpCodes.Ldfld, field)); processor.Append(processor.Create(OpCodes.Ldlen)); processor.Append(processor.Create(OpCodes.Conv_I4)); processor.Append(goto2); processor.Append(processor.Create(OpCodes.Stloc, lenIndex)); //writer.Write(len); processor.Append(processor.Create(OpCodes.Ldarg_1)); processor.Append(processor.Create(OpCodes.Ldloc, lenIndex)); processor.Append(BaseTypeFactory.CreateWriteInstruction(module, processor, typeof(int).ToString())); //if (len > 0) processor.Append(processor.Create(OpCodes.Ldloc, lenIndex)); processor.Append(processor.Create(OpCodes.Ldc_I4_0)); processor.Append(processor.Create(OpCodes.Cgt)); processor.Append(processor.Create(OpCodes.Stloc, checkIndex)); processor.Append(processor.Create(OpCodes.Ldloc, checkIndex)); processor.Append(processor.Create(OpCodes.Brfalse_S, goto5)); //for (int i = 0; i < len; i++) processor.Append(processor.Create(OpCodes.Ldc_I4_0)); processor.Append(processor.Create(OpCodes.Stloc, intIndex)); //go to check processor.Append(processor.Create(OpCodes.Br_S, goto4)); processor.Append(goto3); if (BaseTypeFactory.IsBaseType(fieldType)) { //writer.Write(this.Field[i]); processor.Append(processor.Create(OpCodes.Ldarg_1)); processor.Append(processor.Create(OpCodes.Ldarg_0)); processor.Append(processor.Create(OpCodes.Ldfld, field)); processor.Append(processor.Create(OpCodes.Ldloc, intIndex)); processor.Append(processor.Create(OpCodes.Ldelema, module.ImportReference(fieldType))); processor.Append(processor.Create(OpCodes.Ldobj, module.ImportReference(fieldType))); processor.Append(BaseTypeFactory.CreateWriteInstruction(module, processor, fieldType)); } else if (fieldType.IsValueType) { //this.Field[i].Serialize(writer); processor.Append(processor.Create(OpCodes.Ldarg_0)); processor.Append(processor.Create(OpCodes.Ldfld, field)); processor.Append(processor.Create(OpCodes.Ldloc, intIndex)); processor.Append(processor.Create(OpCodes.Ldelema, module.ImportReference(fieldType))); processor.Append(processor.Create(OpCodes.Ldarg_1)); processor.Append(processor.Create(OpCodes.Call, StructMethodFactory.FindSerialize(module, fieldType))); } //i++ processor.Append(processor.Create(OpCodes.Nop)); processor.Append(processor.Create(OpCodes.Ldloc, intIndex)); processor.Append(processor.Create(OpCodes.Ldc_I4_1)); processor.Append(processor.Create(OpCodes.Add)); processor.Append(processor.Create(OpCodes.Stloc, intIndex)); //i < len processor.Append(goto4); processor.Append(processor.Create(OpCodes.Ldloc, intIndex)); processor.Append(processor.Create(OpCodes.Ldloc, lenIndex)); processor.Append(processor.Create(OpCodes.Clt)); processor.Append(processor.Create(OpCodes.Stloc, boolIndex)); processor.Append(processor.Create(OpCodes.Ldloc, boolIndex)); //go to start processor.Append(processor.Create(OpCodes.Brtrue_S, goto3)); processor.Append(goto5); }