public override void EmitReadValue(ILGenerator gen,
                                           ISerializerCompiler serializerCompiler,
                                           Action loadReader,
                                           Action loadSerializer,
                                           Action loadRemotingEndPoint,
                                           Type type,
                                           bool valueCanBeNull = true)
        {
            var keyType   = type.GenericTypeArguments[0];
            var valueType = type.GenericTypeArguments[1];
            var ctor      = type.GetConstructor(new[] { keyType, valueType });

            serializerCompiler.EmitReadValue(gen,
                                             loadReader,
                                             loadSerializer,
                                             loadRemotingEndPoint,
                                             keyType);

            serializerCompiler.EmitReadValue(gen,
                                             loadReader,
                                             loadSerializer,
                                             loadRemotingEndPoint,
                                             valueType);

            gen.Emit(OpCodes.Newobj, ctor);
        }
示例#2
0
 public override void EmitReadValue(ILGenerator gen,
                                    ISerializerCompiler serializerCompiler,
                                    Action loadReader,
                                    Action loadSerializer,
                                    Action loadRemotingEndPoint,
                                    Type type,
                                    bool valueCanBeNull = true)
 {
     serializerCompiler.EmitReadValue(gen,
                                      loadReader,
                                      loadSerializer,
                                      loadRemotingEndPoint,
                                      typeof(DateTime));
     serializerCompiler.EmitReadValue(gen,
                                      loadReader,
                                      loadSerializer,
                                      loadRemotingEndPoint,
                                      typeof(TimeSpan));
     gen.Emit(OpCodes.Newobj, _ctor);
 }
示例#3
0
 public override void EmitReadValue(ILGenerator gen,
                                    ISerializerCompiler serializerCompiler,
                                    Action loadReader,
                                    Action loadSerializer,
                                    Action loadRemotingEndPoint,
                                    Type type,
                                    bool valueCanBeNull = true)
 {
     serializerCompiler.EmitReadValue(gen,
                                      loadReader,
                                      loadSerializer,
                                      loadSerializer,
                                      typeof(string));
     gen.Emit(OpCodes.Ldc_I4, (int)UriKind.RelativeOrAbsolute);
     gen.Emit(OpCodes.Newobj, _ctor);
 }
示例#4
0
        public override void EmitReadValue(ILGenerator gen,
                                           ISerializerCompiler serializerCompiler,
                                           Action loadReader,
                                           Action loadSerializer,
                                           Action loadRemotingEndPoint,
                                           Type type,
                                           bool valueCanBeNull = true)
        {
            var valueType = type.GenericTypeArguments[0];
            var ctor      = type.GetConstructor(new[] { valueType });

            var end     = gen.DefineLabel();
            var noValue = gen.DefineLabel();

            loadReader();
            gen.Emit(OpCodes.Call, Methods.ReadBool);
            gen.Emit(OpCodes.Brfalse, noValue);

            serializerCompiler.EmitReadValue(gen,
                                             loadReader,
                                             loadSerializer,
                                             loadRemotingEndPoint,
                                             valueType);
            gen.Emit(OpCodes.Newobj, ctor);

            gen.Emit(OpCodes.Br_S, end);

            gen.MarkLabel(noValue);

            var @null = gen.DeclareLocal(type);

            gen.Emit(OpCodes.Ldloca, @null);
            gen.Emit(OpCodes.Initobj, type);
            gen.Emit(OpCodes.Ldloc, @null);

            gen.MarkLabel(end);
        }
示例#5
0
        protected void ExtractArgumentsAndCallMethod(ILGenerator gen,
                                                     MethodInfo methodInfo,
                                                     Action loadReader,
                                                     Action loadWriter)
        {
            Action loadSerializer = () =>
            {
                gen.Emit(OpCodes.Ldarg_0);
                gen.Emit(OpCodes.Ldfld, Serializer);
            };
            Action loadRemotingEndPoint = () =>
            {
                gen.Emit(OpCodes.Ldarg_0);
                gen.Emit(OpCodes.Ldfld, EndPoint);
            };

            ParameterInfo[] allParameters = methodInfo.GetParameters();
            foreach (ParameterInfo parameter in allParameters)
            {
                Type parameterType = parameter.ParameterType;

                if (parameter.GetCustomAttribute <ByReferenceAttribute>() != null)
                {
                    VerifyParameterConstraints(parameter);

                    // _endPoint.GetOrCreateProxy(reader.ReadUlong());
                    MethodInfo getOrCreateProxy = Methods.RemotingEndPointGetOrCreateProxy.MakeGenericMethod(parameterType);
                    gen.Emit(OpCodes.Ldarg_0);
                    gen.Emit(OpCodes.Ldfld, EndPoint);
                    loadReader();
                    gen.Emit(OpCodes.Call, Methods.ReadULong);
                    gen.Emit(OpCodes.Callvirt, getOrCreateProxy);
                }
                else
                {
                    SerializerCompiler.EmitReadValue(
                        gen,
                        loadReader,
                        loadSerializer,
                        loadRemotingEndPoint,
                        parameterType
                        );
                }
            }

            Type returnType = methodInfo.ReturnType;
            bool isAsync    = returnType == typeof(Task) ||
                              returnType.IsGenericType && returnType.GetGenericTypeDefinition() == typeof(Task <>);

            if (isAsync)
            {
                LocalBuilder task           = gen.DeclareLocal(returnType);
                Type         taskReturnType = returnType != typeof(Task) ? returnType.GetGenericArguments()[0] : typeof(void);
                if (taskReturnType != typeof(void))
                {
                    LocalBuilder taskResult = gen.DeclareLocal(taskReturnType);

                    gen.Emit(OpCodes.Callvirt, methodInfo);
                    gen.Emit(OpCodes.Stloc, task);
                    EmitVerifyTaskConstraints(methodInfo, gen, () => gen.Emit(OpCodes.Ldloc, task));

                    gen.Emit(OpCodes.Ldloc, task);
                    var getResult = returnType.GetProperty("Result").GetMethod;
                    gen.Emit(OpCodes.Call, getResult);
                    gen.Emit(OpCodes.Stloc, taskResult);

                    SerializerCompiler.EmitWriteValue(gen,
                                                      loadWriter,
                                                      () => gen.Emit(OpCodes.Ldloc, taskResult),
                                                      () => gen.Emit(OpCodes.Ldloca, taskResult),
                                                      loadSerializer,
                                                      loadRemotingEndPoint,
                                                      taskReturnType);
                }
                else
                {
                    gen.Emit(OpCodes.Callvirt, methodInfo);
                    gen.Emit(OpCodes.Stloc, task);
                    EmitVerifyTaskConstraints(methodInfo, gen, () => gen.Emit(OpCodes.Ldloc, task));

                    gen.Emit(OpCodes.Ldloc, task);
                    gen.Emit(OpCodes.Call, Methods.TaskWait);
                }
            }
            else if (returnType != typeof(void))
            {
                LocalBuilder tmp = gen.DeclareLocal(returnType);
                gen.Emit(OpCodes.Callvirt, methodInfo);
                gen.Emit(OpCodes.Stloc, tmp);

                SerializerCompiler.EmitWriteValue(gen,
                                                  loadWriter,
                                                  () => gen.Emit(OpCodes.Ldloc, tmp),
                                                  () => gen.Emit(OpCodes.Ldloca, tmp),
                                                  loadSerializer,
                                                  loadRemotingEndPoint,
                                                  returnType);
            }
            else
            {
                gen.Emit(OpCodes.Callvirt, methodInfo);
            }
        }