Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
 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);
 }
Exemple #4
0
        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);
        }
Exemple #5
0
        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);
        }
Exemple #6
0
        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));
            }
        }
Exemple #10
0
        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);
            }
        }
Exemple #11
0
        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);
        }