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.CheckMethodParams(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) { ParameterDefinition parm = parms[i]; TypeDefinition parmType = parm.ParameterType.Resolve(); byte index = (byte)(method.IsStatic ? i : i + 1); 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) { processor.Append(processor.Create(OpCodes.Ldarga_S, index)); processor.Append(processor.Create(OpCodes.Ldloc_0)); processor.Append(processor.Create(OpCodes.Call, StructMethodFactory.FindSerialize(module, parmType))); } } 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.NetworkServerManagerBroadcastMethod))); processor.Append(processor.Create(OpCodes.Nop)); processor.Append(processor.Create(OpCodes.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); }