private void EmitSetHandlerForMethod(MethodInfoMapping miMapping, ILGenerator ctIl)
        {
            var newMethod = CreateHandlerMethod(miMapping);

            ctIl.Emit(OpCodes.Ldarg_0);
            ctIl.Emit(OpCodes.Ldfld, templateType.GetField("handlers", BindingFlags.Instance | BindingFlags.NonPublic));
            ctIl.Emit(OpCodes.Ldstr, miMapping.PublicName);
            ctIl.Emit(OpCodes.Ldarg_0);
            ctIl.Emit(OpCodes.Ldftn, newMethod);
            ctIl.Emit(OpCodes.Newobj,
                      typeof(Action <FramedClient, long, MemoryStream>).GetConstructor(new[] { typeof(object), typeof(IntPtr) }));
            ctIl.EmitCall(OpCodes.Call,
                          typeof(Dictionary <string, Action <FramedClient, long, MemoryStream> >).GetMethod("set_Item"), null);
        }
Esempio n. 2
0
        private void DefineMessageTypeForActorMethodParams(MethodInfoMapping miMapping)
        {
            var messageTypeName = miMapping.PublicName + "Message";
            var typeBuilder     = this.moduleBuilder.DefineType("Messages." + messageTypeName, TypeAttributes.Public);

            // Empty ctor
            typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.HideBySig);

            // Type attributes
            var protoContractCtor = typeof(ProtoBuf.ProtoContractAttribute).GetConstructor(Type.EmptyTypes);

            typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(protoContractCtor, new object[0]));

            // Properties
            var miParams = miMapping.Info.GetParameters()
                           .ToArray();

            // Index used for proto member attribute. Must start with 1.
            for (int idx = 0, i = 1; idx < miParams.Length; ++idx)
            {
                var p = miParams[idx];

                // Ommit parameter in message if it is a IActorSession and is on first place
                if (p.ParameterType == typeof(IActorSession) && idx == 0)
                {
                    continue;
                }

                var fb = typeBuilder.DefineField(p.Name, p.ParameterType, FieldAttributes.Public);
                var protoMemberCtor = typeof(ProtoBuf.ProtoMemberAttribute).GetConstructor(new[] { typeof(int) });
                fb.SetCustomAttribute(new CustomAttributeBuilder(protoMemberCtor, new object[] { i }));
                ++i;
            }


            var createdType = typeBuilder.CreateType();

            this.messageParamTypes[miMapping.PublicName] = createdType;
        }
Esempio n. 3
0
        private void DefineMessageTypeForActorMethodParams(MethodInfoMapping miMapping)
        {
            var messageTypeName = miMapping.PublicName + "Message";
            var typeBuilder = this.moduleBuilder.DefineType("Messages." + messageTypeName, TypeAttributes.Public);

            // Empty ctor
            typeBuilder.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.HideBySig);

            // Type attributes
            var protoContractCtor = typeof(ProtoBuf.ProtoContractAttribute).GetConstructor(Type.EmptyTypes);
            typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(protoContractCtor, new object[0]));

            // Properties
            var miParams = miMapping.Info.GetParameters()
                                               .ToArray();

            // Index used for proto member attribute. Must start with 1.
            for (int idx = 0, i = 1; idx < miParams.Length; ++idx)
            {
                var p = miParams[idx];

                // Ommit parameter in message if it is a IActorSession and is on first place
                if (p.ParameterType == typeof(IActorSession) && idx == 0)
                    continue;

                var fb = typeBuilder.DefineField(p.Name, p.ParameterType, FieldAttributes.Public);
                var protoMemberCtor = typeof(ProtoBuf.ProtoMemberAttribute).GetConstructor(new[] { typeof(int) });
                fb.SetCustomAttribute(new CustomAttributeBuilder(protoMemberCtor, new object[] { i }));
                ++i;
            }

            var createdType = typeBuilder.CreateType();
            this.messageParamTypes[miMapping.PublicName] = createdType;
        }
Esempio n. 4
0
        private void DefineMessageTypeForActorMethodReturn(MethodInfoMapping miMapping)
        {
            Type returnType = null;

            var returnTypeTask = miMapping.Info.ReturnType;
            bool isEmptyReply = returnTypeTask == typeof(Task);
            if (returnTypeTask == typeof(Task))
                returnType = typeof(System.Reactive.Unit);
            else
            {
                var genArgs = returnTypeTask.GetGenericArguments();

                if (genArgs.Length != 1)
                    throw new InvalidOperationException("Return type of a method must be Task<T>");

                returnType = genArgs[0];
            }

            var messageTypeName = miMapping.PublicName + "MessageReply";
            var replyInterfaceType = typeof(IReplyMessage<>).MakeGenericType(returnType);
            var typeBuilder = this.moduleBuilder.DefineType("Messages." + messageTypeName, TypeAttributes.Public, null, new[] { replyInterfaceType });

            // Empty ctor
            var cb = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.HasThis, Type.EmptyTypes);
            var cbIl = cb.GetILGenerator();
            cbIl.Emit(OpCodes.Ret);

            // Type attributes
            var protoContractCtor = typeof(ProtoBuf.ProtoContractAttribute).GetConstructor(Type.EmptyTypes);
            typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(protoContractCtor, new object[0]));

            var protoMemberCtor = typeof(ProtoBuf.ProtoMemberAttribute).GetConstructor(new[] { typeof(int) });

            var errfb = typeBuilder.DefineField("$ErrorMessage", typeof(string), FieldAttributes.Public);
            errfb.SetCustomAttribute(new CustomAttributeBuilder(protoMemberCtor, new object[] { 1 }));

            FieldBuilder fb = null;

            if (!isEmptyReply)
            {
                fb = typeBuilder.DefineField("@Return", returnType, FieldAttributes.Public);
                fb.SetCustomAttribute(new CustomAttributeBuilder(protoMemberCtor, new object[] { 2 }));
            }

            //GetResult()
            var getResultMb = typeBuilder.DefineMethod("GetResult", MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.HideBySig,
                CallingConventions.HasThis, returnType, Type.EmptyTypes);
            var gril = getResultMb.GetILGenerator();
            var isOKLabel = gril.DefineLabel();

            gril.Emit(OpCodes.Ldarg_0);
            gril.Emit(OpCodes.Ldfld, errfb);
            gril.Emit(OpCodes.Ldnull);
            gril.Emit(OpCodes.Ceq);
            //if($ErrorMessage != null) {
            gril.Emit(OpCodes.Brtrue_S, isOKLabel);

            // throw new Exception($ErrorMessage);
            gril.Emit(OpCodes.Ldarg_0);
            gril.Emit(OpCodes.Ldfld, errfb);
            gril.Emit(OpCodes.Newobj, typeof(Exception).GetConstructor(new[] { typeof(string) }));
            gril.Emit(OpCodes.Throw);

            // } else {
            // return @Return; }
            gril.MarkLabel(isOKLabel);
            if (!isEmptyReply)
            {
                gril.Emit(OpCodes.Ldarg_0);
                gril.Emit(OpCodes.Ldfld, fb);
            }
            else
            {
                gril.EmitCall(OpCodes.Call, typeof(System.Reactive.Unit).GetProperty("Default", BindingFlags.Public | BindingFlags.Static).GetGetMethod(), null);
            }
            gril.Emit(OpCodes.Ret);

            //SetResult
            var setResultMb = typeBuilder.DefineMethod("SetResult", MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.HideBySig,
                CallingConventions.HasThis, typeof(void), new[] { returnType });
            var sril = setResultMb.GetILGenerator();

            if (!isEmptyReply)
            {
                sril.Emit(OpCodes.Ldarg_0);
                sril.Emit(OpCodes.Ldarg_1);
                sril.Emit(OpCodes.Stfld, fb);
            }
            sril.Emit(OpCodes.Ret);

            //SetError
            var setErrorMb = typeBuilder.DefineMethod("SetError", MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.HideBySig,
                CallingConventions.HasThis, typeof(void), new[] { typeof(string) });
            var seil = setErrorMb.GetILGenerator();

            seil.Emit(OpCodes.Ldarg_0);
            seil.Emit(OpCodes.Ldarg_1);
            seil.Emit(OpCodes.Stfld, errfb);
            seil.Emit(OpCodes.Ret);

            var createdType = typeBuilder.CreateType();
            this.messageReturnTypes[miMapping.PublicName] = createdType;
        }
Esempio n. 5
0
        private void EmitSetHandlerForMethod(MethodInfoMapping miMapping, ILGenerator ctIl)
        {
            var newMethod = CreateHandlerMethod(miMapping);

            ctIl.Emit(OpCodes.Ldarg_0);
            ctIl.Emit(OpCodes.Ldfld, templateType.GetField("handlers", BindingFlags.Instance | BindingFlags.NonPublic));
            ctIl.Emit(OpCodes.Ldstr, miMapping.PublicName);
            ctIl.Emit(OpCodes.Ldarg_0);
            ctIl.Emit(OpCodes.Ldftn, newMethod);
            ctIl.Emit(OpCodes.Newobj,
                typeof (Action<FramedClient, long, MemoryStream>).GetConstructor(new[] {typeof (object), typeof (IntPtr)}));
            ctIl.EmitCall(OpCodes.Call,
                typeof (Dictionary<string, Action<FramedClient, long, MemoryStream>>).GetMethod("set_Item"), null);
        }
Esempio n. 6
0
        private MethodBuilder CreateHandlerMethod(MethodInfoMapping miMapping)
        {
            var sendMethodTaskRet = miMapping.Info.ReturnType;
            bool isNoParamTask = sendMethodTaskRet == typeof(Task);
            var sendMethodInnerRet = sendMethodTaskRet == typeof(Task)
                                        ? typeof(System.Reactive.Unit)
                                        : sendMethodTaskRet.GetGenericArguments()[0];

            var mb = actorImplBuilder.DefineMethod(miMapping.PublicName + "Handler",
                                                 MethodAttributes.Private |
                                                 MethodAttributes.HideBySig,
                                               CallingConventions.HasThis,
                                               typeof(void),
                                               new[] { typeof(FramedClient), typeof(long), typeof(MemoryStream) });
            Type messageType = moduleBuilder.GetType("Messages." + miMapping.PublicName + "Message");
            Type replyMessageType = moduleBuilder.GetType("Messages." + miMapping.PublicName + "MessageReply");
            var desMethod = typeof(IStacksSerializer).GetMethod("Deserialize").MakeGenericMethod(messageType);

            var il = mb.GetILGenerator();

            var messageLocal = il.DeclareLocal(messageType);
            var endLabel = il.DefineLabel();

            // try {
            il.BeginExceptionBlock();

            //var msg = base.serializer.Deserialize<P>(ms);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, templateType.GetField("serializer", BindingFlags.Instance | BindingFlags.NonPublic));
            il.Emit(OpCodes.Ldarg_3);
            il.EmitCall(OpCodes.Callvirt, desMethod, null);
            il.Emit(OpCodes.Stloc_0);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);

            {
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, templateType.GetField("actorImplementation", BindingFlags.Instance | BindingFlags.NonPublic));

                //actorImplementation.[methodName](params);

                var sendParams = miMapping.Info.GetParameters();

                // If first parameter is IActorSession, load session for dictionary and
                // place it on stack as first parameter.
                if (sendParams.Length >= 1 &&
                    sendParams[0].ParameterType == typeof(IActorSession))
                {
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, templateType.GetField("actorSessions", BindingFlags.Instance | BindingFlags.NonPublic));
                    il.Emit(OpCodes.Ldarg_1); //FramedClient used as a key for session cache
                    il.EmitCall(OpCodes.Call, typeof(Dictionary<IFramedClient, IActorSession>).GetMethod("get_Item"), null);
                }

                for (int idx = 0, i = 1; idx < sendParams.Length; ++idx)
                {
                    // Ommit first parameter if it is an IActorSession
                    if (idx == 0 && sendParams[0].ParameterType == typeof(IActorSession))
                        continue;

                    var field = GetFieldInfoFromProtobufMessage(messageType, i);
                    il.Emit(OpCodes.Ldloc_0);
                    il.Emit(OpCodes.Ldfld, field);

                    ++i;
                }

                il.EmitCall(OpCodes.Callvirt, miMapping.InterfaceInfo, null);
            }

            il.Emit(OpCodes.Newobj, replyMessageType.GetConstructor(Type.EmptyTypes));

            if (isNoParamTask)
            {
                il.EmitCall(OpCodes.Call, templateType.GetMethod("HandleResponseNoResult", BindingFlags.Instance | BindingFlags.NonPublic), null);
            }
            else
            {
                il.EmitCall(OpCodes.Call, templateType.GetMethod("HandleResponse", BindingFlags.Instance | BindingFlags.NonPublic)
                                                      .MakeGenericMethod(sendMethodInnerRet),
                                          null);
            }

            // } catch (Exception e) {
            il.BeginCatchBlock(typeof(Exception));
            var excMsgLocal = il.DeclareLocal(typeof(string));
            var replyMsgLocal = il.DeclareLocal(typeof(IReplyMessage<>).MakeGenericType(sendMethodInnerRet));

            //var excMsgLocal = e.Message;
            il.EmitCall(OpCodes.Call, typeof(Exception).GetProperty("Message").GetGetMethod(), null);
            il.Emit(OpCodes.Stloc, excMsgLocal);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Newobj, replyMessageType.GetConstructor(Type.EmptyTypes));
            il.Emit(OpCodes.Stloc, replyMsgLocal);
            il.Emit(OpCodes.Ldloc, replyMsgLocal);
            il.Emit(OpCodes.Ldloc, excMsgLocal);
            il.EmitCall(OpCodes.Callvirt, typeof(IReplyMessage<>).MakeGenericType(sendMethodInnerRet).GetMethod("SetError"), null);
            il.Emit(OpCodes.Ldloc, replyMsgLocal);

            if (isNoParamTask)
            {
                il.EmitCall(OpCodes.Call, templateType.GetMethod("HandleResponseNoResult", BindingFlags.Instance | BindingFlags.NonPublic), null);
            }
            else
            {
                il.EmitCall(OpCodes.Call, templateType.GetMethod("HandleResponse", BindingFlags.Instance | BindingFlags.NonPublic)
                                                      .MakeGenericMethod(sendMethodInnerRet),
                                          null);
            }

            // }
            il.EndExceptionBlock();

            il.MarkLabel(endLabel);
            il.Emit(OpCodes.Ret);

            return mb;
        }
Esempio n. 7
0
        private void DefineMessageTypeForActorMethodReturn(MethodInfoMapping miMapping)
        {
            Type returnType = null;

            var  returnTypeTask = miMapping.Info.ReturnType;
            bool isEmptyReply   = returnTypeTask == typeof(Task);

            if (returnTypeTask == typeof(Task))
            {
                returnType = typeof(System.Reactive.Unit);
            }
            else
            {
                var genArgs = returnTypeTask.GetGenericArguments();

                if (genArgs.Length != 1)
                {
                    throw new InvalidOperationException("Return type of a method must be Task<T>");
                }

                returnType = genArgs[0];
            }

            var messageTypeName    = miMapping.PublicName + "MessageReply";
            var replyInterfaceType = typeof(IReplyMessage <>).MakeGenericType(returnType);
            var typeBuilder        = this.moduleBuilder.DefineType("Messages." + messageTypeName, TypeAttributes.Public, null, new[] { replyInterfaceType });

            // Empty ctor
            var cb   = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.HasThis, Type.EmptyTypes);
            var cbIl = cb.GetILGenerator();

            cbIl.Emit(OpCodes.Ret);

            // Type attributes
            var protoContractCtor = typeof(ProtoBuf.ProtoContractAttribute).GetConstructor(Type.EmptyTypes);

            typeBuilder.SetCustomAttribute(new CustomAttributeBuilder(protoContractCtor, new object[0]));

            var protoMemberCtor = typeof(ProtoBuf.ProtoMemberAttribute).GetConstructor(new[] { typeof(int) });

            var errfb = typeBuilder.DefineField("$ErrorMessage", typeof(string), FieldAttributes.Public);

            errfb.SetCustomAttribute(new CustomAttributeBuilder(protoMemberCtor, new object[] { 1 }));

            FieldBuilder fb = null;

            if (!isEmptyReply)
            {
                fb = typeBuilder.DefineField("@Return", returnType, FieldAttributes.Public);
                fb.SetCustomAttribute(new CustomAttributeBuilder(protoMemberCtor, new object[] { 2 }));
            }

            //GetResult()
            var getResultMb = typeBuilder.DefineMethod("GetResult", MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.HideBySig,
                                                       CallingConventions.HasThis, returnType, Type.EmptyTypes);
            var gril      = getResultMb.GetILGenerator();
            var isOKLabel = gril.DefineLabel();

            gril.Emit(OpCodes.Ldarg_0);
            gril.Emit(OpCodes.Ldfld, errfb);
            gril.Emit(OpCodes.Ldnull);
            gril.Emit(OpCodes.Ceq);
            //if($ErrorMessage != null) {
            gril.Emit(OpCodes.Brtrue_S, isOKLabel);

            // throw new Exception($ErrorMessage);
            gril.Emit(OpCodes.Ldarg_0);
            gril.Emit(OpCodes.Ldfld, errfb);
            gril.Emit(OpCodes.Newobj, typeof(Exception).GetConstructor(new[] { typeof(string) }));
            gril.Emit(OpCodes.Throw);

            // } else {
            // return @Return; }
            gril.MarkLabel(isOKLabel);
            if (!isEmptyReply)
            {
                gril.Emit(OpCodes.Ldarg_0);
                gril.Emit(OpCodes.Ldfld, fb);
            }
            else
            {
                gril.EmitCall(OpCodes.Call, typeof(System.Reactive.Unit).GetProperty("Default", BindingFlags.Public | BindingFlags.Static).GetGetMethod(), null);
            }
            gril.Emit(OpCodes.Ret);


            //SetResult
            var setResultMb = typeBuilder.DefineMethod("SetResult", MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.HideBySig,
                                                       CallingConventions.HasThis, typeof(void), new[] { returnType });
            var sril = setResultMb.GetILGenerator();

            if (!isEmptyReply)
            {
                sril.Emit(OpCodes.Ldarg_0);
                sril.Emit(OpCodes.Ldarg_1);
                sril.Emit(OpCodes.Stfld, fb);
            }
            sril.Emit(OpCodes.Ret);

            //SetError
            var setErrorMb = typeBuilder.DefineMethod("SetError", MethodAttributes.Virtual | MethodAttributes.Public | MethodAttributes.HideBySig,
                                                      CallingConventions.HasThis, typeof(void), new[] { typeof(string) });
            var seil = setErrorMb.GetILGenerator();

            seil.Emit(OpCodes.Ldarg_0);
            seil.Emit(OpCodes.Ldarg_1);
            seil.Emit(OpCodes.Stfld, errfb);
            seil.Emit(OpCodes.Ret);


            var createdType = typeBuilder.CreateType();

            this.messageReturnTypes[miMapping.PublicName] = createdType;
        }
        private MethodBuilder CreateHandlerMethod(MethodInfoMapping miMapping)
        {
            var  sendMethodTaskRet  = miMapping.Info.ReturnType;
            bool isNoParamTask      = sendMethodTaskRet == typeof(Task);
            var  sendMethodInnerRet = sendMethodTaskRet == typeof(Task)
                                        ? typeof(System.Reactive.Unit)
                                        : sendMethodTaskRet.GetGenericArguments()[0];

            var mb = actorImplBuilder.DefineMethod(miMapping.PublicName + "Handler",
                                                   MethodAttributes.Private |
                                                   MethodAttributes.HideBySig,
                                                   CallingConventions.HasThis,
                                                   typeof(void),
                                                   new[] { typeof(FramedClient), typeof(long), typeof(MemoryStream) });
            Type messageType      = moduleBuilder.GetType("Messages." + miMapping.PublicName + "Message");
            Type replyMessageType = moduleBuilder.GetType("Messages." + miMapping.PublicName + "MessageReply");
            var  desMethod        = typeof(IStacksSerializer).GetMethod("Deserialize").MakeGenericMethod(messageType);

            var il = mb.GetILGenerator();

            var messageLocal = il.DeclareLocal(messageType);
            var endLabel     = il.DefineLabel();

            // try {
            il.BeginExceptionBlock();

            //var msg = base.serializer.Deserialize<P>(ms);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, templateType.GetField("serializer", BindingFlags.Instance | BindingFlags.NonPublic));
            il.Emit(OpCodes.Ldarg_3);
            il.EmitCall(OpCodes.Callvirt, desMethod, null);
            il.Emit(OpCodes.Stloc_0);


            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);

            {
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, templateType.GetField("actorImplementation", BindingFlags.Instance | BindingFlags.NonPublic));

                //actorImplementation.[methodName](params);

                var sendParams = miMapping.Info.GetParameters();

                // If first parameter is IActorSession, load session for dictionary and
                // place it on stack as first parameter.
                if (sendParams.Length >= 1 &&
                    sendParams[0].ParameterType == typeof(IActorSession))
                {
                    il.Emit(OpCodes.Ldarg_0);
                    il.Emit(OpCodes.Ldfld, templateType.GetField("actorSessions", BindingFlags.Instance | BindingFlags.NonPublic));
                    il.Emit(OpCodes.Ldarg_1); //FramedClient used as a key for session cache
                    il.EmitCall(OpCodes.Call, typeof(Dictionary <IFramedClient, IActorSession>).GetMethod("get_Item"), null);
                }

                for (int idx = 0, i = 1; idx < sendParams.Length; ++idx)
                {
                    // Ommit first parameter if it is an IActorSession
                    if (idx == 0 && sendParams[0].ParameterType == typeof(IActorSession))
                    {
                        continue;
                    }

                    var field = GetFieldInfoFromProtobufMessage(messageType, i);
                    il.Emit(OpCodes.Ldloc_0);
                    il.Emit(OpCodes.Ldfld, field);

                    ++i;
                }

                il.EmitCall(OpCodes.Callvirt, miMapping.InterfaceInfo, null);
            }

            il.Emit(OpCodes.Newobj, replyMessageType.GetConstructor(Type.EmptyTypes));

            if (isNoParamTask)
            {
                il.EmitCall(OpCodes.Call, templateType.GetMethod("HandleResponseNoResult", BindingFlags.Instance | BindingFlags.NonPublic), null);
            }
            else
            {
                il.EmitCall(OpCodes.Call, templateType.GetMethod("HandleResponse", BindingFlags.Instance | BindingFlags.NonPublic)
                            .MakeGenericMethod(sendMethodInnerRet),
                            null);
            }

            // } catch (Exception e) {
            il.BeginCatchBlock(typeof(Exception));
            var excMsgLocal   = il.DeclareLocal(typeof(string));
            var replyMsgLocal = il.DeclareLocal(typeof(IReplyMessage <>).MakeGenericType(sendMethodInnerRet));

            //var excMsgLocal = e.Message;
            il.EmitCall(OpCodes.Call, typeof(Exception).GetProperty("Message").GetGetMethod(), null);
            il.Emit(OpCodes.Stloc, excMsgLocal);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Newobj, replyMessageType.GetConstructor(Type.EmptyTypes));
            il.Emit(OpCodes.Stloc, replyMsgLocal);
            il.Emit(OpCodes.Ldloc, replyMsgLocal);
            il.Emit(OpCodes.Ldloc, excMsgLocal);
            il.EmitCall(OpCodes.Callvirt, typeof(IReplyMessage <>).MakeGenericType(sendMethodInnerRet).GetMethod("SetError"), null);
            il.Emit(OpCodes.Ldloc, replyMsgLocal);

            if (isNoParamTask)
            {
                il.EmitCall(OpCodes.Call, templateType.GetMethod("HandleResponseNoResult", BindingFlags.Instance | BindingFlags.NonPublic), null);
            }
            else
            {
                il.EmitCall(OpCodes.Call, templateType.GetMethod("HandleResponse", BindingFlags.Instance | BindingFlags.NonPublic)
                            .MakeGenericMethod(sendMethodInnerRet),
                            null);
            }


            // }
            il.EndExceptionBlock();

            il.MarkLabel(endLabel);
            il.Emit(OpCodes.Ret);

            return(mb);
        }