/// <summary> /// 创建 TCP 客户端 /// </summary> /// <param name="type"></param> /// <param name="attribute"></param> /// <param name="methods"></param> /// <param name="getCommandMethod"></param> /// <returns></returns> internal Type Build(Type type, TcpServer.ServerBaseAttribute attribute, Method <attributeType, methodAttributeType, serverSocketType>[] methods, MethodInfo getCommandMethod) { TypeBuilder typeBuilder = AutoCSer.Emit.Builder.Module.Builder.DefineType(Metadata.ClientTypeName + ".Emit." + type.FullName, TypeAttributes.Class | TypeAttributes.Sealed, Metadata.MethodClientType, new Type[] { type }); typeBuilder.DefineDefaultConstructor(MethodAttributes.Public); ConstructorBuilder staticConstructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, null); ILGenerator staticConstructorGenerator = staticConstructorBuilder.GetILGenerator(); Commands = new TcpServer.CommandInfoBase[methods.Length]; int parameterIndex; foreach (Method <attributeType, methodAttributeType, serverSocketType> nextMethod in methods) { if (nextMethod != null) { Method <attributeType, methodAttributeType, serverSocketType> method = nextMethod; METHOD: FieldBuilder commandInfoFieldBuilder; if (method.Attribute.IsExpired) { commandInfoFieldBuilder = null; } else { commandInfoFieldBuilder = typeBuilder.DefineField("_c" + method.Attribute.CommandIdentity.toString(), typeof(TcpServer.CommandInfoBase), FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static); TcpServer.CommandInfoBase commandInfo = new TcpServer.CommandInfoBase { Command = method.Attribute.CommandIdentity + TcpServer.Server.CommandStartIndex, IsVerifyMethod = method.Attribute.IsVerifyMethod }; Commands[method.Attribute.CommandIdentity] = commandInfo; if (method.IsJsonSerialize) { commandInfo.CommandFlags = TcpServer.CommandFlags.JsonSerialize; } if (method.ParameterType != null) { commandInfo.InputParameterIndex = method.ParameterType.Index; if (attribute.IsSimpleSerialize) { commandInfo.IsSimpleSerializeInputParamter = method.ParameterType.IsSimpleSerialize; } } if (attribute.IsSimpleSerialize && method.OutputParameterType != null) { commandInfo.IsSimpleSerializeOutputParamter = method.OutputParameterType.IsSimpleSerialize && SimpleSerialize.Serializer.IsType(method.ReturnType); } #region private static readonly AutoCSer.Net.TcpServer.CommandInfoBase @MethodIdentityCommand = AutoCSer.Net.TcpInternalSimpleServer.Emit.Client<interfaceType>.commands[method.Attribute.CommandIdentity]; staticConstructorGenerator.int32(method.Attribute.CommandIdentity); staticConstructorGenerator.call(getCommandMethod); staticConstructorGenerator.Emit(OpCodes.Stsfld, commandInfoFieldBuilder); #endregion } if (method.PropertyInfo == null) { ParameterInfo[] parameters = method.MethodInfo.GetParameters(); MethodBuilder methodBuilder = typeBuilder.DefineMethod(method.MethodInfo.Name, MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual | MethodAttributes.Final, method.MethodInfo.ReturnType, parameters.getArray(parameter => parameter.ParameterType)); typeBuilder.DefineMethodOverride(methodBuilder, method.MethodInfo); ILGenerator methodGenerator = methodBuilder.GetILGenerator(); if (method.Attribute.IsExpired) { if (method.ReturnValueType == null) { #region throw new Exception(AutoCSer.Net.TcpServer.ReturnType.VersionExpired.ToString()); methodGenerator.throwString(AutoCSer.Net.TcpServer.ReturnType.VersionExpired.ToString()); #endregion } else { #region @ParameterName = default(@ParameterType.FullName); parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.IsOut) { methodGenerator.outParameterDefault(parameter, parameterIndex, method.Attribute.IsInitobj); } } #endregion #region return new AutoCSer.Net.TcpServer.ReturnValue<@MethodReturnType.FullName> { Type = AutoCSer.Net.TcpServer.ReturnType.VersionExpired }; LocalBuilder returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType); if (method.ReturnType != typeof(void) && (method.Attribute.IsInitobj || method.ReturnType.isInitobj())) { methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType); } methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.VersionExpired); methodGenerator.Emit(OpCodes.Stfld, method.ReturnType == typeof(void) ? TcpServer.Emit.ClientMetadata.ReturnValueTypeField : method.ReturnValueType.GetField(TcpServer.Emit.ClientMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public)); methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ret); #endregion } } else { Label clientExceptionLabel = methodGenerator.DefineLabel(); #region if (_isDisposed_ == 0) methodGenerator.Emit(OpCodes.Ldarg_0); methodGenerator.call(TcpSimpleServer.Emit.ClientMetadata.MethodClientGetIsDisposedMethod); methodGenerator.Emit(method.ParameterType == null && method.OutputParameterType == null ? OpCodes.Brtrue_S : OpCodes.Brtrue, clientExceptionLabel); #endregion LocalBuilder inputParameterLocalBuilder; if (method.ParameterType == null) { inputParameterLocalBuilder = null; } else { #region TcpInternalSimpleServer.@InputParameterTypeName _inputParameter_ = new TcpInternalSimpleServer.@InputParameterTypeName { @ParameterName = @ParameterName }; inputParameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type); LocalBuilder newInputParameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type); if (method.Attribute.IsInitobj || method.ParameterType.IsInitobj) { methodGenerator.Emit(OpCodes.Ldloca_S, newInputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.ParameterType.Type); } parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (SimpleParameterType.IsInputParameter(parameter)) { methodGenerator.parameterToStructField(parameter, parameterIndex, newInputParameterLocalBuilder, method.ParameterType.GetField(parameter.Name)); } } methodGenerator.Emit(OpCodes.Ldloc_S, newInputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Stloc_S, inputParameterLocalBuilder); #endregion } if (method.OutputParameterType == null) { #region AutoCSer.Net.TcpServer.ReturnType _returnType_ = _TcpClient_.Call(@MethodIdentityCommand, ref _inputParameter_); LocalBuilder returnTypeLocalBuilder = methodGenerator.DeclareLocal(typeof(AutoCSer.Net.TcpServer.ReturnType)); methodGenerator.Emit(OpCodes.Ldarg_0); methodGenerator.call(Metadata.MethodClientGetTcpClientMethod); methodGenerator.Emit(OpCodes.Ldsfld, commandInfoFieldBuilder); if (method.ParameterType == null) { methodGenerator.call(Metadata.ClientCallMethod); } else { methodGenerator.Emit(OpCodes.Ldloca_S, inputParameterLocalBuilder); //methodGenerator.call(Metadata.ClientCallInputMethod.MakeGenericMethod(method.ParameterType.Type)); methodGenerator.call(Metadata.GetParameterGenericType(method.ParameterType.Type).ClientCallMethod); } methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder); #endregion if (method.ReturnValueType == null) { Label throwReturnTypeLabel = methodGenerator.DefineLabel(); #region if (_returnType_ == AutoCSer.Net.TcpServer.ReturnType.Success) return; methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success); methodGenerator.Emit(OpCodes.Bne_Un_S, throwReturnTypeLabel); methodGenerator.Emit(OpCodes.Ret); #endregion methodGenerator.MarkLabel(throwReturnTypeLabel); #region throw new Exception(AutoCSer.Net.TcpInternalServer.Emit.Client.ReturnTypeStrings[(byte)_returnType_]); methodGenerator.Emit(OpCodes.Ldsfld, TcpServer.Emit.ClientMetadata.ReturnTypeStringsField); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.Emit(OpCodes.Ldelem_Ref); methodGenerator.call(AutoCSer.Extensions.EmitGenerator.NewExceptionStringMethodInfo); methodGenerator.Emit(OpCodes.Throw); #endregion } else { #region return new AutoCSer.Net.TcpServer.ReturnValue { Type = _returnType_ }; LocalBuilder returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType); //methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); //methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType); methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.Emit(OpCodes.Stfld, TcpServer.Emit.ClientMetadata.ReturnValueTypeField); methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ret); #endregion } } else { #region TcpInternalSimpleServer.@OutputParameterTypeName _outputParameter_ = new TcpInternalSimpleServer.@OutputParameterTypeName { @ParameterName = @ParameterName }; LocalBuilder outputParameterLocalBuilder = methodGenerator.DeclareLocal(method.OutputParameterType.Type); if (method.Attribute.IsInitobj || method.OutputParameterType.IsInitobj) { methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.OutputParameterType.Type); } parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.ParameterType.IsByRef) { methodGenerator.parameterToStructField(parameter, parameterIndex, outputParameterLocalBuilder, method.OutputParameterType.GetField(parameter.Name)); } } //if (method.ReturnInputParameter != null) //{ //} #endregion #region AutoCSer.Net.TcpServer.ReturnType _returnType_ = _TcpClient_.Get<TcpInternalSimpleServer.@InputParameterTypeName, TcpInternalSimpleServer.@OutputParameterTypeName>(@MethodIdentityCommand, ref _inputParameter_, ref _outputParameter_); LocalBuilder returnTypeLocalBuilder = methodGenerator.DeclareLocal(typeof(AutoCSer.Net.TcpServer.ReturnType)); methodGenerator.Emit(OpCodes.Ldarg_0); methodGenerator.call(Metadata.MethodClientGetTcpClientMethod); methodGenerator.Emit(OpCodes.Ldsfld, commandInfoFieldBuilder); if (method.ParameterType == null) { methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); //methodGenerator.call(Metadata.ClientGetMethod.MakeGenericMethod(method.OutputParameterType.Type)); methodGenerator.call(Metadata.GetParameterGenericType(method.OutputParameterType.Type).ClientGetMethod); } else { methodGenerator.Emit(OpCodes.Ldloca_S, inputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); //methodGenerator.call(Metadata.ClientGetInputMethod.MakeGenericMethod(method.ParameterType.Type, method.OutputParameterType.Type)); methodGenerator.call(Metadata.GetParameterGenericType2(method.ParameterType.Type, method.OutputParameterType.Type).ClientGetMethod); } methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder); #endregion if (method.ReturnValueType == null) { Label throwReturnTypeLabel = methodGenerator.DefineLabel(); #region if (_returnType_ == AutoCSer.Net.TcpServer.ReturnType.Success) methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success); methodGenerator.Emit(OpCodes.Bne_Un, throwReturnTypeLabel); #endregion #region @ParameterName = _outputParameter_.@ParameterName; parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.ParameterType.IsByRef) { methodGenerator.outParameterFromValueField(parameter, parameterIndex, outputParameterLocalBuilder, method.OutputParameterType.GetField(parameter.Name)); } } #endregion if (method.ReturnType == typeof(void)) { #region return; methodGenerator.Emit(OpCodes.Ret); #endregion } else { #region return _outputParameter_.Ret; methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Ldfld, method.OutputParameterType.GetField(TcpServer.ReturnValue.RetParameterName)); //methodGenerator.Emit(OpCodes.Stloc_S, returnValueLocalBuilder); //methodGenerator.Emit(OpCodes.Ldloc_S, returnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ret); #endregion } methodGenerator.MarkLabel(throwReturnTypeLabel); #region throw new Exception(AutoCSer.Net.TcpServer.Emit.Client.ReturnTypeStrings[(byte)_returnType_]); methodGenerator.Emit(OpCodes.Ldsfld, TcpServer.Emit.ClientMetadata.ReturnTypeStringsField); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.Emit(OpCodes.Ldelem_Ref); methodGenerator.call(AutoCSer.Extensions.EmitGenerator.NewExceptionStringMethodInfo); methodGenerator.Emit(OpCodes.Throw); #endregion } else { #region @ParameterName = _outputParameter_.@ParameterName; parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.ParameterType.IsByRef) { methodGenerator.outParameterFromValueField(parameter, parameterIndex, outputParameterLocalBuilder, method.OutputParameterType.GetField(parameter.Name)); } } #endregion #region return new AutoCSer.Net.TcpServer.ReturnValue<@MethodReturnType.FullName> { Type = _returnType_, Value = _outputParameter_.Return }; LocalBuilder returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType); if (method.ReturnType == typeof(void)) { methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.Emit(OpCodes.Stfld, TcpServer.Emit.ClientMetadata.ReturnValueTypeField); } else { if (method.Attribute.IsInitobj || method.ReturnType.isInitobj()) { methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType); } methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.Emit(OpCodes.Stfld, method.ReturnValueType.GetField(TcpServer.Emit.ClientMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public)); methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Ldfld, method.OutputParameterType.GetField(TcpServer.ReturnValue.RetParameterName)); methodGenerator.Emit(OpCodes.Stfld, method.ReturnValueType.GetField("Value", BindingFlags.Instance | BindingFlags.Public)); } methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ret); #endregion } } methodGenerator.MarkLabel(clientExceptionLabel); if (method.ReturnValueType == null) { #region throw new Exception(AutoCSer.Net.TcpServer.ReturnType.ClientException.ToString()); methodGenerator.throwString(AutoCSer.Net.TcpServer.ReturnType.ClientException.ToString()); #endregion } else { #region @ParameterName = default(@ParameterType.FullName); parameterIndex = 0; foreach (ParameterInfo parameter in parameters) { ++parameterIndex; if (parameter.IsOut) { methodGenerator.outParameterDefault(parameter, parameterIndex, method.Attribute.IsInitobj); } } #endregion #region return new AutoCSer.Net.TcpServer.ReturnValue<@MethodReturnType.FullName> { Type = AutoCSer.Net.TcpServer.ReturnType.ClientException }; LocalBuilder returnReturnValueLocalBuilder = methodGenerator.DeclareLocal(method.ReturnValueType); if (method.ReturnType != typeof(void) && method.ReturnType.isInitobj()) { methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.ReturnValueType); } methodGenerator.Emit(OpCodes.Ldloca_S, returnReturnValueLocalBuilder); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.ClientException); methodGenerator.Emit(OpCodes.Stfld, method.ReturnType == typeof(void) ? TcpServer.Emit.ClientMetadata.ReturnValueTypeField : method.ReturnValueType.GetField(TcpServer.Emit.ClientMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public)); methodGenerator.Emit(OpCodes.Ldloc_S, returnReturnValueLocalBuilder); methodGenerator.Emit(OpCodes.Ret); #endregion } } } else if (method.IsPropertySetMethod) { if (method.PropertyBuilder != null || method.PropertyGetMethod == null) { ParameterInfo[] parameters = method.MethodInfo.GetParameters(); PropertyBuilder propertyBuilder = method.PropertyBuilder ?? typeBuilder.DefineProperty(method.PropertyInfo.Name, PropertyAttributes.HasDefault, parameters[parameters.Length - 1].ParameterType, new LeftArray <ParameterInfo> { Array = parameters, Length = parameters.Length - 1 }.GetArray(parameter => parameter.ParameterType)); MethodBuilder setMethodBuilder = typeBuilder.DefineMethod(method.MethodInfo.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual, method.MethodInfo.ReturnType, parameters.getArray(parameter => parameter.ParameterType)); ILGenerator methodGenerator = setMethodBuilder.GetILGenerator(); //XXX propertyBuilder.SetSetMethod(setMethodBuilder); method.PropertyBuilder = null; } } else { Type[] parameterTypes = method.MethodInfo.GetParameters().getArray(parameter => parameter.ParameterType); PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(method.PropertyInfo.Name, PropertyAttributes.HasDefault, method.MethodInfo.ReturnType, parameterTypes); MethodBuilder getMethodBuilder = typeBuilder.DefineMethod(method.MethodInfo.Name, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual, method.MethodInfo.ReturnType, parameterTypes); ILGenerator methodGenerator = getMethodBuilder.GetILGenerator(); //XXX propertyBuilder.SetGetMethod(getMethodBuilder); if (method.PropertySetMethod != null) { method = method.PropertySetMethod; method.PropertyBuilder = propertyBuilder; goto METHOD; } } } } staticConstructorGenerator.Emit(OpCodes.Ret); return(typeBuilder.CreateType()); }
/// <summary> /// 创建 TCP 服务端 /// </summary> /// <param name="type"></param> /// <param name="attribute"></param> /// <param name="serverInterfaceType"></param> /// <param name="serverCallType"></param> /// <param name="constructorParameterTypes"></param> /// <param name="methods"></param> /// <returns></returns> internal Type Build(Type type, ServerAttribute attribute, Type serverInterfaceType, Type serverCallType, Type[] constructorParameterTypes, Method <attributeType, methodAttributeType, serverSocketType>[] methods) { string serverIdentity = Interlocked.Increment(ref Metadata.Identity).toString(); TypeBuilder typeBuilder = AutoCSer.Emit.Builder.Module.Builder.DefineType(Metadata.ServerTypeName + ".Emit." + type.FullName, TypeAttributes.Class | TypeAttributes.Sealed, Metadata.ServerType); FieldBuilder valueFieldBuilder = typeBuilder.DefineField("_value_", typeof(object), FieldAttributes.Private | FieldAttributes.InitOnly); ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, constructorParameterTypes); ILGenerator constructorGenerator = constructorBuilder.GetILGenerator(); Label serverAttributeNotNull = constructorGenerator.DefineLabel(); bool isCallQueue = false; foreach (Method <attributeType, methodAttributeType, serverSocketType> method in methods) { if (method != null && (isCallQueue |= method.Attribute.ServerTaskType == TcpServer.ServerTaskType.Queue)) { break; } } #region base(attribute, verify, log, isCallQueue) constructorGenerator.Emit(OpCodes.Ldarg_0); constructorGenerator.Emit(OpCodes.Ldarg_1); constructorGenerator.Emit(OpCodes.Ldarg_2); constructorGenerator.Emit(OpCodes.Ldarg_S, 4); constructorGenerator.int32(isCallQueue ? 1 : 0); constructorGenerator.Emit(OpCodes.Call, Metadata.ServerConstructorInfo); #endregion #region _value_ = value; constructorGenerator.Emit(OpCodes.Ldarg_0); constructorGenerator.Emit(OpCodes.Ldarg_3); constructorGenerator.Emit(OpCodes.Stfld, valueFieldBuilder); #endregion constructorGenerator.Emit(OpCodes.Ret); ConstructorBuilder staticConstructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.Static, CallingConventions.Standard, null); ILGenerator staticConstructorGenerator = staticConstructorBuilder.GetILGenerator(); #region public override bool DoCommand(int index, AutoCSer.Net.TcpInternalSimpleServer.ServerSocket socket, ref SubArray<byte> data) MethodBuilder doCommandMethodBuilder = typeBuilder.DefineMethod("DoCommand", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot, typeof(bool), Metadata.DoCommandParameterTypes); #endregion ILGenerator doCommandGenerator = doCommandMethodBuilder.GetILGenerator(); doCommandGenerator.DeclareLocal(typeof(int)); Label doCommandReturnLabel = doCommandGenerator.DefineLabel(); Label[] doCommandLabels = new Label[methods.Length]; int doCommandLabelIndex = 0; foreach (Method <attributeType, methodAttributeType, serverSocketType> method in methods) { doCommandLabels[doCommandLabelIndex++] = method == null ? doCommandReturnLabel : (method.DoCommandLabel = doCommandGenerator.DefineLabel()); } #region switch (index - @CommandStartIndex) doCommandGenerator.Emit(OpCodes.Ldarg_1); doCommandGenerator.int32(TcpServer.Server.CommandStartIndex); doCommandGenerator.Emit(OpCodes.Sub); doCommandGenerator.Emit(OpCodes.Stloc_0); doCommandGenerator.Emit(OpCodes.Ldloc_0); doCommandGenerator.Emit(OpCodes.Switch, doCommandLabels); doCommandGenerator.MarkLabel(doCommandReturnLabel); doCommandGenerator.int32(0); doCommandGenerator.Emit(OpCodes.Ret); #endregion Outputs = new TcpSimpleServer.OutputInfo[methods.Length]; FieldInfo outputsField = serverInterfaceType.GetField("Outputs", BindingFlags.Static | BindingFlags.NonPublic); foreach (Method <attributeType, methodAttributeType, serverSocketType> method in methods) { if (method != null) { FieldBuilder outputInfoFieldBuilder; if (method.OutputParameterType == null && !method.IsAsynchronousCallback) { outputInfoFieldBuilder = null; } else { TcpSimpleServer.OutputInfo outputInfo = new TcpSimpleServer.OutputInfo(); Outputs[method.Attribute.CommandIdentity] = outputInfo; if (method.OutputParameterType != null) { outputInfo.OutputParameterIndex = method.OutputParameterType.Index; if (attribute.IsSimpleSerialize) { outputInfo.IsSimpleSerializeOutputParamter = method.OutputParameterType.IsSimpleSerialize && SimpleSerialize.Serializer.IsType(method.ReturnType); } } #region private static readonly AutoCSer.Net.TcpSimpleServer.OutputInfo @MethodIdentityCommand = AutoCSer.Net.TcpInternalSimpleServer.Emit.Server<interfaceType>.Outputs[@CommandIdentity]; staticConstructorGenerator.Emit(OpCodes.Ldsfld, outputsField); staticConstructorGenerator.int32(method.Attribute.CommandIdentity); staticConstructorGenerator.Emit(OpCodes.Ldelem_Ref); staticConstructorGenerator.Emit(OpCodes.Stsfld, outputInfoFieldBuilder = typeBuilder.DefineField("_o" + method.Attribute.CommandIdentity.toString(), typeof(TcpServer.OutputInfo), FieldAttributes.Private | FieldAttributes.InitOnly | FieldAttributes.Static)); #endregion } ParameterInfo[] parameters = method.MethodInfo.GetParameters(); TypeBuilder serverCallTypeBuilder; FieldInfo returnTypeField = method.ReturnValueType == null ? null : (method.ReturnValueType == typeof(TcpServer.ReturnValue) ? TcpServer.Emit.ServerMetadata.ReturnValueTypeField : method.ReturnValueType.GetField(TcpServer.Emit.ServerMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public)); FieldInfo returnValueField = method.ReturnValueType == null ? null : method.ReturnValueType.GetField("Value", BindingFlags.Instance | BindingFlags.Public); if (method.IsMethodServerCall) { Type baseType = method.ParameterType == null ? Metadata.ServerCallType : serverCallType.MakeGenericType(method.ParameterType.Type); FieldInfo inputParameterField = method.ParameterType == null ? null : baseType.GetField("inputParameter", BindingFlags.Instance | BindingFlags.NonPublic); serverCallTypeBuilder = typeBuilder.DefineNestedType(Metadata.ServerCallTypeName + ".Emit." + serverIdentity + "_" + method.Attribute.CommandIdentity.toString(), TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.NestedPublic, baseType); Type returnOutputType = method.OutputParameterType == null ? typeof(AutoCSer.Net.TcpServer.ReturnValue) : typeof(AutoCSer.Net.TcpServer.ReturnValue <>).MakeGenericType(method.OutputParameterType.Type); FieldInfo returnOutputValueField = method.OutputParameterType == null ? null : returnOutputType.GetField("Value", BindingFlags.Instance | BindingFlags.Public); Type returnOutputRefType = returnOutputType.MakeByRefType(); #region private void get(ref AutoCSer.Net.TcpServer.ReturnValue<@OutputParameterTypeName> value) MethodBuilder getMethodBuilder = serverCallTypeBuilder.DefineMethod("get", MethodAttributes.Private, typeof(void), new Type[] { returnOutputRefType }); #endregion ILGenerator getGenerator = getMethodBuilder.GetILGenerator(); Label getReturnLabel = getGenerator.DefineLabel(); LocalBuilder exceptionErrorLocalBuilder = getGenerator.DeclareLocal(typeof(Exception)); #region try getGenerator.BeginExceptionBlock(); #endregion #region @MethodReturnType.FullName @ReturnName = serverValue.@MethodName(Socket, inputParameter.@ParameterName); LocalBuilder returnLocalBuilder = method.IsReturnType ? getGenerator.DeclareLocal(method.ReturnValueType ?? method.ReturnType) : null; getGenerator.Emit(OpCodes.Ldarg_0); getGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallServerValueField); foreach (ParameterInfo parameter in parameters) { if (SimpleParameterType.IsInputParameter(parameter)) { getGenerator.Emit(OpCodes.Ldarg_0); getGenerator.Emit(OpCodes.Ldflda, inputParameterField); getGenerator.Emit(parameter.ParameterType.IsByRef ? OpCodes.Ldflda : OpCodes.Ldfld, method.ParameterType.GetField(parameter.Name)); } else if (parameter.IsOut) { getGenerator.Emit(OpCodes.Ldarg_1); getGenerator.Emit(OpCodes.Ldflda, returnOutputValueField); getGenerator.Emit(OpCodes.Ldflda, method.OutputParameterType.GetField(parameter.Name)); } else if (parameter.ParameterType == Metadata.SocketType) { getGenerator.Emit(OpCodes.Ldarg_0); getGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallSocketField); } else { getGenerator.Emit(OpCodes.Ldnull); } } getGenerator.call(method.MethodInfo); if (method.IsReturnType) { getGenerator.Emit(OpCodes.Stloc_S, returnLocalBuilder); } #endregion FieldInfo returnValueTypeField = method.OutputParameterType == null ? TcpServer.Emit.ServerMetadata.ReturnValueTypeField : returnOutputType.GetField(TcpServer.Emit.ServerMetadata.ReturnValueTypeField.Name, BindingFlags.Instance | BindingFlags.Public); if (method.OutputParameterType == null) { if (method.ReturnValueType != null) { Label returnTypeErrorLabel = getGenerator.DefineLabel(); #region if(@ReturnName.Type != AutoCSer.Net.TcpServer.ReturnType.Success) getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder); getGenerator.Emit(OpCodes.Ldfld, returnTypeField); getGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success); getGenerator.Emit(OpCodes.Beq_S, returnTypeErrorLabel); #endregion #region value.Type = @ReturnName.Type; getGenerator.Emit(OpCodes.Ldarg_1); getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder); getGenerator.Emit(OpCodes.Ldfld, returnTypeField); getGenerator.Emit(OpCodes.Stfld, returnValueTypeField); #endregion getGenerator.Emit(OpCodes.Leave_S, getReturnLabel); getGenerator.MarkLabel(returnTypeErrorLabel); } #region value.Type = AutoCSer.Net.TcpServer.ReturnType.Success; getGenerator.Emit(OpCodes.Ldarg_1); getGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success); getGenerator.Emit(OpCodes.Stfld, returnValueTypeField); #endregion getGenerator.Emit(OpCodes.Leave_S, getReturnLabel); } else { Label returnTypeErrorLabel; if (method.ReturnValueType == null) { returnTypeErrorLabel = default(Label); } else { #region if(@ReturnName.Type != AutoCSer.Net.TcpServer.ReturnType.Success) getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder); getGenerator.Emit(OpCodes.Ldfld, returnTypeField); getGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success); getGenerator.Emit(OpCodes.Bne_Un, returnTypeErrorLabel = getGenerator.DefineLabel()); #endregion } if (method.Attribute.IsVerifyMethod) { Label verifyEndLabel = getGenerator.DefineLabel(); #region if (@ReturnName / @ReturnName.Value) if (method.ReturnValueType == null) { getGenerator.Emit(OpCodes.Ldloc_S, returnLocalBuilder); } else { getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder); getGenerator.Emit(OpCodes.Ldfld, returnValueField); } getGenerator.Emit(OpCodes.Brfalse_S, verifyEndLabel); #endregion #region Socket.SetVerifyMethod(); getGenerator.Emit(OpCodes.Ldarg_0); getGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallSocketField); getGenerator.call(ServerMetadata.ServerSocketSetVerifyMethodMethod); #endregion getGenerator.MarkLabel(verifyEndLabel); } LocalBuilder valueLocalBuilder = getGenerator.DeclareLocal(method.OutputParameterType.Type); #region value.Value.@ParameterName = inputParameter.@ParameterName; foreach (ParameterInfo parameter in method.OutputParameters) { if (!parameter.IsOut) { getGenerator.Emit(OpCodes.Ldarg_1); getGenerator.Emit(OpCodes.Ldflda, returnOutputValueField); getGenerator.Emit(OpCodes.Ldarg_0); getGenerator.Emit(OpCodes.Ldflda, inputParameterField); getGenerator.Emit(OpCodes.Ldfld, method.ParameterType.GetField(parameter.Name)); getGenerator.Emit(OpCodes.Stfld, method.OutputParameterType.GetField(parameter.Name)); } } #endregion if (method.ReturnType != typeof(void)) { #region value.Value.@ReturnName = @ReturnName / @ReturnName.Value; getGenerator.Emit(OpCodes.Ldarg_1); getGenerator.Emit(OpCodes.Ldflda, returnOutputValueField); if (method.ReturnValueType == null) { getGenerator.Emit(OpCodes.Ldloc_S, returnLocalBuilder); } else { getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder); getGenerator.Emit(OpCodes.Ldfld, returnValueField); } getGenerator.Emit(OpCodes.Stfld, method.OutputParameterType.GetField(TcpServer.ReturnValue.RetParameterName)); #endregion } #region value.Type = AutoCSer.Net.TcpServer.ReturnType.Success; getGenerator.Emit(OpCodes.Ldarg_1); getGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success); getGenerator.Emit(OpCodes.Stfld, returnValueTypeField); #endregion getGenerator.Emit(OpCodes.Leave_S, getReturnLabel); if (method.ReturnValueType != null) { getGenerator.MarkLabel(returnTypeErrorLabel); #region value.Type = @ReturnName.Type; getGenerator.Emit(OpCodes.Ldarg_1); getGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder); getGenerator.Emit(OpCodes.Ldfld, returnTypeField); getGenerator.Emit(OpCodes.Stfld, returnValueTypeField); #endregion getGenerator.Emit(OpCodes.Leave_S, getReturnLabel); } } #region catch (Exception error) getGenerator.BeginCatchBlock(typeof(Exception)); getGenerator.Emit(OpCodes.Stloc_S, exceptionErrorLocalBuilder); #endregion #region value.Type = AutoCSer.Net.TcpServer.ReturnType.ServerException; getGenerator.Emit(OpCodes.Ldarg_1); getGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.ServerException); getGenerator.Emit(OpCodes.Stfld, returnValueTypeField); #endregion #region Socket.Log(error); getGenerator.Emit(OpCodes.Ldarg_0); getGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallSocketField); getGenerator.Emit(OpCodes.Ldloc_S, exceptionErrorLocalBuilder); getGenerator.call(Metadata.ServerSocketLogMethod); #endregion getGenerator.Emit(OpCodes.Leave_S, getReturnLabel); #region try end getGenerator.EndExceptionBlock(); #endregion getGenerator.MarkLabel(getReturnLabel); getGenerator.Emit(OpCodes.Ret); #region public override void Call() MethodBuilder callMethodBuilder = serverCallTypeBuilder.DefineMethod("Call", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.ReuseSlot, typeof(void), null); #endregion ILGenerator callGenerator = callMethodBuilder.GetILGenerator(); #region AutoCSer.Net.TcpInternalSimpleServer.ServerSocket socket = Socket; LocalBuilder socketBuilder = callGenerator.DeclareLocal(typeof(serverSocketType)); getGenerator.Emit(OpCodes.Ldarg_0); getGenerator.Emit(OpCodes.Ldfld, Metadata.ServerCallSocketField); callGenerator.Emit(OpCodes.Stloc_S, socketBuilder); #endregion #region AutoCSer.Net.TcpServer.ReturnValue<@OutputParameterTypeName> value = new AutoCSer.Net.TcpServer.ReturnValue<@OutputParameterTypeName>(); LocalBuilder valueBuilder = callGenerator.DeclareLocal(returnOutputType); if (method.OutputParameterType == null || method.Attribute.IsInitobj || method.OutputParameterType.IsInitobj) { callGenerator.Emit(OpCodes.Ldloca_S, valueBuilder); callGenerator.Emit(OpCodes.Initobj, returnOutputType); } else { callGenerator.Emit(OpCodes.Ldloca_S, valueBuilder); callGenerator.int32(0); callGenerator.Emit(OpCodes.Stfld, returnValueTypeField); } #endregion #region get(ref value); callGenerator.Emit(OpCodes.Ldarg_0); callGenerator.Emit(OpCodes.Ldloca_S, valueBuilder); callGenerator.call(getMethodBuilder); #endregion #region push(this); callGenerator.Emit(OpCodes.Ldarg_0); callGenerator.Emit(OpCodes.Ldarg_0); callGenerator.call((method.ParameterType == null ? Metadata.ServerCallPushMethod : serverCallType.MakeGenericType(method.ParameterType.Type).GetMethod("push", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)).MakeGenericMethod(serverCallTypeBuilder)); #endregion if (method.OutputParameterType == null) { #region socket.SendAsync(value.Type); callGenerator.Emit(OpCodes.Ldloc_S, socketBuilder); callGenerator.Emit(OpCodes.Ldloca_S, valueBuilder); callGenerator.Emit(OpCodes.Ldfld, returnValueTypeField); callGenerator.call(Metadata.ServerSocketSendAsyncMethod); callGenerator.Emit(OpCodes.Pop); #endregion } else { #region socket.SendAsync(@MethodIdentityCommand, ref value); callGenerator.Emit(OpCodes.Ldloc_S, socketBuilder); callGenerator.Emit(OpCodes.Ldsfld, outputInfoFieldBuilder); callGenerator.Emit(OpCodes.Ldloca_S, valueBuilder); callGenerator.call(Metadata.ServerSocketSendAsyncOutputMethod.MakeGenericMethod(method.OutputParameterType.Type)); callGenerator.Emit(OpCodes.Pop); #endregion } callGenerator.Emit(OpCodes.Ret); serverCallTypeBuilder.CreateType(); } else { serverCallTypeBuilder = null; } #region private bool @MethodIndexName(AutoCSer.Net.TcpInternalSimpleServer.ServerSocket socket, ref SubArray<byte> data) MethodBuilder methodBuilder = typeBuilder.DefineMethod("_m" + method.Attribute.CommandIdentity.toString(), MethodAttributes.Private, typeof(bool), Metadata.MethodParameterTypes); #endregion ILGenerator methodGenerator = methodBuilder.GetILGenerator(); if (method.Attribute.IsExpired) { if (method.OutputParameterType == null) { #region return socket.Send(AutoCSer.Net.TcpServer.ReturnType.VersionExpired); methodGenerator.Emit(OpCodes.Ldarg_1); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.VersionExpired); methodGenerator.call(Metadata.ServerSocketSendReturnTypeMethod); methodGenerator.Emit(OpCodes.Ret); #endregion } else { #region return socket.SendOutput(AutoCSer.Net.TcpServer.ReturnType.VersionExpired); methodGenerator.Emit(OpCodes.Ldarg_1); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.VersionExpired); methodGenerator.call(Metadata.ServerSocketSendOutputReturnTypeMethod); methodGenerator.Emit(OpCodes.Ret); #endregion } } else { Label pushLabel = methodGenerator.DefineLabel(), returnLable = methodGenerator.DefineLabel(); #region bool isReturnLocalBuilder = false; LocalBuilder isReturnLocalBuilder = methodGenerator.DeclareLocal(typeof(bool)); methodGenerator.int32(0); methodGenerator.Emit(OpCodes.Stloc_S, isReturnLocalBuilder); #endregion #region AutoCSer.Net.TcpServer.ReturnType returnType = AutoCSer.Net.TcpServer.ReturnType.Unknown; LocalBuilder returnTypeLocalBuilder = methodGenerator.DeclareLocal(typeof(AutoCSer.Net.TcpServer.ReturnType)); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Unknown); methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder); #endregion #region try methodGenerator.BeginExceptionBlock(); #endregion LocalBuilder parameterLocalBuilder, outputParameterLocalBuilder = null; Label serverDeSerializeErrorLabel; if (method.ParameterType == null) { parameterLocalBuilder = null; serverDeSerializeErrorLabel = default(Label); } else { #region @InputParameterTypeName inputParameter = new @InputParameterTypeName(); parameterLocalBuilder = methodGenerator.DeclareLocal(method.ParameterType.Type); if (method.Attribute.IsInitobj || method.ParameterType.IsInitobj) { methodGenerator.Emit(OpCodes.Ldloca_S, parameterLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.ParameterType.Type); } #endregion #region if (socket.DeSerialize(ref data, ref inputParameter)) methodGenerator.Emit(OpCodes.Ldarg_1); methodGenerator.Emit(OpCodes.Ldarg_2); methodGenerator.Emit(OpCodes.Ldloca_S, parameterLocalBuilder); methodGenerator.int32(method.ParameterType.IsSimpleSerialize ? 1 : 0); methodGenerator.call(ServerMetadata.ServerSocketDeSerializeMethod.MakeGenericMethod(method.ParameterType.Type)); methodGenerator.Emit(OpCodes.Brfalse, serverDeSerializeErrorLabel = methodGenerator.DefineLabel()); #endregion } if (method.IsMethodServerCall) { #region @MethodStreamName.Call(socket, _value_, @ServerTask, ref inputParameter); methodGenerator.Emit(OpCodes.Ldarg_1); methodGenerator.Emit(OpCodes.Ldarg_0); methodGenerator.Emit(OpCodes.Ldfld, valueFieldBuilder); methodGenerator.int32((byte)method.ServerTask); if (method.ParameterType == null) { methodGenerator.call(Metadata.ServerCallCallMethod.MakeGenericMethod(serverCallTypeBuilder)); } else { methodGenerator.Emit(OpCodes.Ldloca_S, parameterLocalBuilder); methodGenerator.call(serverCallType.MakeGenericType(method.ParameterType.Type).GetMethod("Call", BindingFlags.Static | BindingFlags.Public | BindingFlags.DeclaredOnly).MakeGenericMethod(serverCallTypeBuilder)); } #endregion #region isReturnLocalBuilder = true; methodGenerator.int32(1); methodGenerator.Emit(OpCodes.Stloc_S, isReturnLocalBuilder); #endregion } else { if (method.OutputParameterType != null) { #region @OutputParameterTypeName outputParameter = new @OutputParameterTypeName(); outputParameterLocalBuilder = methodGenerator.DeclareLocal(method.OutputParameterType.Type); if (method.Attribute.IsInitobj || method.OutputParameterType.IsInitobj) { methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Initobj, method.OutputParameterType.Type); } #endregion } #region @MethodReturnType.FullName @ReturnName = _value_.@MethodName(socket, inputParameter.@ParameterName); LocalBuilder returnLocalBuilder = method.IsReturnType ? methodGenerator.DeclareLocal(method.ReturnValueType ?? method.ReturnType) : null; methodGenerator.Emit(OpCodes.Ldarg_0); methodGenerator.Emit(OpCodes.Ldfld, valueFieldBuilder); foreach (ParameterInfo parameter in parameters) { if (SimpleParameterType.IsInputParameter(parameter)) { methodGenerator.Emit(OpCodes.Ldloca_S, parameterLocalBuilder); methodGenerator.Emit(parameter.ParameterType.IsByRef ? OpCodes.Ldflda : OpCodes.Ldfld, method.ParameterType.GetField(parameter.Name)); } else if (parameter.IsOut) { methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Ldflda, method.OutputParameterType.GetField(parameter.Name)); } else if (parameter.ParameterType == Metadata.SocketType) { methodGenerator.Emit(OpCodes.Ldarg_1); } else { methodGenerator.Emit(OpCodes.Ldnull); } } methodGenerator.call(method.MethodInfo); if (method.IsReturnType) { methodGenerator.Emit(OpCodes.Stloc_S, returnLocalBuilder); } #endregion if (method.OutputParameterType == null) { if (method.ReturnValueType == null) { #region return socket.Send(); methodGenerator.Emit(OpCodes.Ldarg_1); methodGenerator.call(Metadata.ServerSocketSendMethod); methodGenerator.Emit(OpCodes.Stloc_S, isReturnLocalBuilder); #endregion } else { #region return socket.Send(@ReturnName.Type); methodGenerator.Emit(OpCodes.Ldarg_1); methodGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder); methodGenerator.Emit(OpCodes.Ldfld, returnTypeField); methodGenerator.call(Metadata.ServerSocketSendReturnTypeMethod); methodGenerator.Emit(OpCodes.Stloc_S, isReturnLocalBuilder); #endregion } } else { Label returnTypeErrorLabel; if (method.ReturnValueType == null) { returnTypeErrorLabel = default(Label); } else { #region if(@ReturnName.Type == AutoCSer.Net.TcpServer.ReturnType.Success) methodGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder); methodGenerator.Emit(OpCodes.Ldfld, returnTypeField); methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.Success); methodGenerator.Emit(OpCodes.Bne_Un, returnTypeErrorLabel = methodGenerator.DefineLabel()); #endregion } if (method.Attribute.IsVerifyMethod) { Label verifyEndLabel = methodGenerator.DefineLabel(); #region if (@ReturnName / @ReturnName.Value) if (method.ReturnValueType == null) { methodGenerator.Emit(OpCodes.Ldloc_S, returnLocalBuilder); } else { methodGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder); methodGenerator.Emit(OpCodes.Ldfld, returnValueField); } methodGenerator.Emit(OpCodes.Brfalse_S, verifyEndLabel); #endregion #region socket.SetVerifyMethod(); methodGenerator.Emit(OpCodes.Ldarg_1); methodGenerator.call(ServerMetadata.ServerSocketSetVerifyMethodMethod); #endregion methodGenerator.MarkLabel(verifyEndLabel); } foreach (ParameterInfo parameter in method.OutputParameters) { if (!parameter.IsOut) { #region outputParameter.@ParameterName = inputParameter.@ParameterName methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); methodGenerator.Emit(OpCodes.Ldloca_S, parameterLocalBuilder); methodGenerator.Emit(OpCodes.Ldfld, method.ParameterType.GetField(parameter.Name)); methodGenerator.Emit(OpCodes.Stfld, method.OutputParameterType.GetField(parameter.Name)); #endregion } } if (method.ReturnType != typeof(void)) { #region _outputParameter_.Ret = @ReturnName / @ReturnName.Value methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); if (method.ReturnValueType == null) { methodGenerator.Emit(OpCodes.Ldloc_S, returnLocalBuilder); } else { methodGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder); methodGenerator.Emit(OpCodes.Ldfld, returnValueField); } methodGenerator.Emit(OpCodes.Stfld, method.OutputParameterType.GetField(TcpServer.ReturnValue.RetParameterName)); #endregion } #region return socket.Send(@MethodIdentityCommand, ref outputParameter) methodGenerator.Emit(OpCodes.Ldarg_1); methodGenerator.Emit(OpCodes.Ldsfld, outputInfoFieldBuilder); methodGenerator.Emit(OpCodes.Ldloca_S, outputParameterLocalBuilder); methodGenerator.call(Metadata.ServerSocketSendOutputMethod.MakeGenericMethod(method.OutputParameterType.Type)); methodGenerator.Emit(OpCodes.Stloc_S, isReturnLocalBuilder); #endregion methodGenerator.Emit(OpCodes.Leave_S, returnLable); if (method.ReturnValueType != null) { methodGenerator.MarkLabel(returnTypeErrorLabel); #region return socket.SendOutput(@ReturnValue.Type); methodGenerator.Emit(OpCodes.Ldarg_1); methodGenerator.Emit(OpCodes.Ldloca_S, returnLocalBuilder); methodGenerator.Emit(OpCodes.Ldfld, returnTypeField); methodGenerator.call(Metadata.ServerSocketSendOutputReturnTypeMethod); methodGenerator.Emit(OpCodes.Stloc_S, isReturnLocalBuilder); #endregion } } } methodGenerator.Emit(OpCodes.Leave_S, returnLable); if (method.ParameterType != null) { methodGenerator.MarkLabel(serverDeSerializeErrorLabel); #region returnType = AutoCSer.Net.TcpServer.ReturnType.ServerDeSerializeError; methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.ServerDeSerializeError); methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder); #endregion methodGenerator.Emit(OpCodes.Leave_S, pushLabel); } #region catch (Exception error) methodGenerator.BeginCatchBlock(typeof(Exception)); LocalBuilder errorLocalBuilder = methodGenerator.DeclareLocal(typeof(Exception)); methodGenerator.Emit(OpCodes.Stloc_S, errorLocalBuilder); #endregion #region returnType = AutoCSer.Net.TcpServer.ReturnType.ServerException; methodGenerator.int32((byte)AutoCSer.Net.TcpServer.ReturnType.ServerException); methodGenerator.Emit(OpCodes.Stloc_S, returnTypeLocalBuilder); #endregion #region socket.Log(error); methodGenerator.Emit(OpCodes.Ldarg_1); methodGenerator.Emit(OpCodes.Ldloc_S, errorLocalBuilder); methodGenerator.call(Metadata.ServerSocketLogMethod); #endregion methodGenerator.Emit(OpCodes.Leave_S, pushLabel); #region try end methodGenerator.EndExceptionBlock(); #endregion methodGenerator.MarkLabel(pushLabel); if (method.OutputParameterType == null) { #region return socket.Send(returnType); methodGenerator.Emit(OpCodes.Ldarg_1); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.call(Metadata.ServerSocketSendReturnTypeMethod); methodGenerator.Emit(OpCodes.Ret); #endregion } else { #region return socket.SendOutput(returnType); methodGenerator.Emit(OpCodes.Ldarg_1); methodGenerator.Emit(OpCodes.Ldloc_S, returnTypeLocalBuilder); methodGenerator.call(Metadata.ServerSocketSendOutputReturnTypeMethod); methodGenerator.Emit(OpCodes.Ret); #endregion } methodGenerator.MarkLabel(returnLable); methodGenerator.Emit(OpCodes.Ldloc_S, isReturnLocalBuilder); methodGenerator.Emit(OpCodes.Ret); } #region case @MethodIndex: return @MethodIndexName(socket, ref data); doCommandGenerator.MarkLabel(method.DoCommandLabel); doCommandGenerator.Emit(OpCodes.Ldarg_0); doCommandGenerator.Emit(OpCodes.Ldarg_2); doCommandGenerator.Emit(OpCodes.Ldarg_3); doCommandGenerator.call(methodBuilder); doCommandGenerator.Emit(OpCodes.Ret); #endregion method.DoCommandLabel = default(Label); } } doCommandGenerator.Emit(OpCodes.Ret); staticConstructorGenerator.Emit(OpCodes.Ret); return(typeBuilder.CreateType()); }