Ejemplo n.º 1
0
        private void ImplementSignal(SignalDescription signalDescription, bool isPropertiesChanged)
        {
            var         method = _typeBuilder.ImplementInterfaceMethod(signalDescription.MethodInfo);
            ILGenerator ilg    = method.GetILGenerator();

            // call Watch(...)

            // BusObject (this)
            ilg.Emit(OpCodes.Ldarg_0);
            ilg.Emit(OpCodes.Castclass, s_dbusObjectProxyType);

            // Interface
            ilg.Emit(OpCodes.Ldstr, signalDescription.Interface.Name);

            // Member
            ilg.Emit(OpCodes.Ldstr, signalDescription.Name);

            // Action<Exception>
            if (signalDescription.HasOnError)
            {
                ilg.Emit(OpCodes.Ldarg_2);
            }
            else
            {
                ilg.Emit(OpCodes.Ldnull);
            }

            // Action/Action<>
            ilg.Emit(OpCodes.Ldarg_1);

            if (signalDescription.SignalType != null)
            {
                // ReadMethodDelegate
                ilg.Emit(OpCodes.Ldnull);
                ilg.Emit(OpCodes.Ldftn, ReadMethodFactory.CreateReadMethodForType(signalDescription.SignalType));
                var readDelegateConstructor = s_readMethodDelegateGenericType.MakeGenericType(new[] { signalDescription.SignalType }).GetConstructors()[0];
                ilg.Emit(OpCodes.Newobj, readDelegateConstructor);

                // isPropertiesChanged
                ilg.Emit(isPropertiesChanged ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);

                // Watch
                ilg.Emit(OpCodes.Call, s_watchNonVoidSignal.MakeGenericMethod(new[] { signalDescription.SignalType }));
            }
            else
            {
                // Watch
                ilg.Emit(OpCodes.Call, s_watchVoidSignal);
            }

            ilg.Emit(OpCodes.Ret);
        }
Ejemplo n.º 2
0
        private MethodInfo GenMethodHandler(string key, MethodDescription dbusMethod, bool propertyMethod)
        {
            // Task<Message> MethodCall(object o(Ldarg_1), Message methodCall(Ldarg_2), IProxyFactory(Ldarg_3));

            string methodName = $"Handle{key}".Replace('.', '_');
            var    method     = _typeBuilder.DefineMethod(methodName, MethodAttributes.Private, s_taskOfMessageType, s_methodHandlerParameterTypes);

            var ilg = method.GetILGenerator();

            // call CreateReply

            // this
            ilg.Emit(OpCodes.Ldarg_0);
            // Message
            ilg.Emit(OpCodes.Ldarg_2);
            // Task = (IDbusInterface)object.CallMethod(arguments)
            {
                // (IIinterface)object
                ilg.Emit(OpCodes.Ldarg_1);
                ilg.Emit(OpCodes.Castclass, dbusMethod.Interface.Type);

                // Arguments
                if (dbusMethod.InArguments.Count != 0)
                {
                    // create reader for reading the arguments
                    ilg.Emit(OpCodes.Ldarg_2);                            // message
                    ilg.Emit(OpCodes.Ldarg_3);                            // IProxyFactory
                    LocalBuilder reader = ilg.DeclareLocal(s_messageReaderType);
                    ilg.Emit(OpCodes.Newobj, s_messageReaderConstructor); // new MessageReader(message, proxyFactory)
                    ilg.Emit(OpCodes.Stloc, reader);

                    if (propertyMethod)
                    {
                        ilg.Emit(OpCodes.Ldloc, reader);
                        ilg.Emit(OpCodes.Call, s_readerSkipString);
                    }

                    foreach (var argument in dbusMethod.InArguments)
                    {
                        Type parameterType = argument.Type;
                        ilg.Emit(OpCodes.Ldloc, reader);
                        ilg.Emit(OpCodes.Call, ReadMethodFactory.CreateReadMethodForType(parameterType));
                    }
                }

                // Call method
                ilg.Emit(OpCodes.Callvirt, dbusMethod.MethodInfo);
            }

            if (dbusMethod.OutType != null)
            {
                //  Action<MessageWriter, T>
                ilg.Emit(OpCodes.Ldnull);
                ilg.Emit(OpCodes.Ldftn, WriteMethodFactory.CreateWriteMethodForType(dbusMethod.OutType, isCompileTimeType: true));
                var actionConstructor = s_action2GenericType.MakeGenericType(new[] { s_messageWriterType, dbusMethod.OutType }).GetConstructors()[0];
                ilg.Emit(OpCodes.Newobj, actionConstructor);

                // signature
                if (dbusMethod.OutSignature.HasValue)
                {
                    ilg.Emit(OpCodes.Ldstr, dbusMethod.OutSignature.Value.Value);
                    ilg.Emit(OpCodes.Newobj, s_signatureConstructor);
                    ilg.Emit(OpCodes.Newobj, s_nullableSignatureConstructor);
                }
                else
                {
                    LocalBuilder signature = ilg.DeclareLocal(s_nullableSignatureType);
                    ilg.Emit(OpCodes.Ldloca_S, signature);
                    ilg.Emit(OpCodes.Initobj, s_nullableSignatureType);
                    ilg.Emit(OpCodes.Ldloc, signature);
                }

                // CreateReply
                ilg.Emit(OpCodes.Call, s_createNonVoidReply.MakeGenericMethod(new[] { dbusMethod.OutType }));
            }
            else
            {
                // CreateReply
                ilg.Emit(OpCodes.Call, s_createVoidReply);
            }

            ilg.Emit(OpCodes.Ret);

            return(method);
        }
Ejemplo n.º 3
0
        private void ImplementMethod(MethodDescription methodDescription, bool propertyMethod)
        {
            var method = _typeBuilder.ImplementInterfaceMethod(methodDescription.MethodInfo);

            ILGenerator ilg = method.GetILGenerator();

            //CallMethod(...)

            // BusObject (this)
            ilg.Emit(OpCodes.Ldarg_0);
            ilg.Emit(OpCodes.Castclass, s_dbusObjectProxyType);

            // Interface
            if (propertyMethod)
            {
                ilg.Emit(OpCodes.Ldstr, "org.freedesktop.DBus.Properties");
            }
            else
            {
                ilg.Emit(OpCodes.Ldstr, methodDescription.Interface.Name);
            }

            // Member
            ilg.Emit(OpCodes.Ldstr, methodDescription.Name);

            // Signature
            if (methodDescription.InSignature.HasValue || propertyMethod)
            {
                string inSig = methodDescription.InSignature?.Value ?? string.Empty;
                if (propertyMethod)
                {
                    inSig = "s" + inSig;
                }
                ilg.Emit(OpCodes.Ldstr, inSig);
                ilg.Emit(OpCodes.Newobj, s_signatureConstructor);
                ilg.Emit(OpCodes.Newobj, s_nullableSignatureConstructor);
            }
            else
            {
                LocalBuilder signature = ilg.DeclareLocal(s_nullableSignatureType);
                ilg.Emit(OpCodes.Ldloca_S, signature);
                ilg.Emit(OpCodes.Initobj, s_nullableSignatureType);
                ilg.Emit(OpCodes.Ldloc, signature);
            }

            // MessageWriter
            var argumentOffset = 1; //offset by one to account for "this"

            if (methodDescription.InArguments.Count != 0 || propertyMethod)
            {
                LocalBuilder writer = ilg.DeclareLocal(s_messageWriterType);
                ilg.Emit(OpCodes.Newobj, s_messageWriterConstructor);
                ilg.Emit(OpCodes.Stloc, writer);

                if (propertyMethod)
                {
                    // Write parameter
                    Type parameterType = typeof(string);
                    ilg.Emit(OpCodes.Ldloc, writer);
                    ilg.Emit(OpCodes.Ldstr, methodDescription.Interface.Name);
                    ilg.Emit(OpCodes.Call, WriteMethodFactory.CreateWriteMethodForType(parameterType, isCompileTimeType: true));
                }

                foreach (var argument in methodDescription.InArguments)
                {
                    // Write parameter
                    Type parameterType = argument.Type;
                    ilg.Emit(OpCodes.Ldloc, writer);
                    ilg.Emit(OpCodes.Ldarg, argumentOffset);
                    ilg.Emit(OpCodes.Call, WriteMethodFactory.CreateWriteMethodForType(parameterType, isCompileTimeType: true));

                    argumentOffset++;
                }

                ilg.Emit(OpCodes.Ldloc, writer);
            }
            else
            {
                ilg.Emit(OpCodes.Ldnull);
            }

            if (methodDescription.OutType != null)
            {
                // CallMethod
                if (methodDescription.IsGenericOut)
                {
                    Type genericParameter = method.GetGenericArguments()[0];
                    ilg.Emit(OpCodes.Call, s_callGenericOutMethod.MakeGenericMethod(new[] { genericParameter }));
                }
                else
                {
                    // ReadMethodDelegate
                    ilg.Emit(OpCodes.Ldnull);
                    ilg.Emit(OpCodes.Ldftn, ReadMethodFactory.CreateReadMethodForType(methodDescription.OutType));
                    var readDelegateConstructor = s_readMethodDelegateGenericType.MakeGenericType(new[] { methodDescription.OutType }).GetConstructors()[0];
                    ilg.Emit(OpCodes.Newobj, readDelegateConstructor);

                    ilg.Emit(OpCodes.Call, s_callNonVoidMethod.MakeGenericMethod(new[] { methodDescription.OutType }));
                }
            }
            else
            {
                // CallMethod
                ilg.Emit(OpCodes.Call, s_callVoidMethod);
            }

            ilg.Emit(OpCodes.Ret);
        }