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));
            }
        }
Example #2
0
        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);
        }