public void Register(Type type)
        {
            var atr = type.GetCustomAttribute(typeof(SubscribeAttribute));

            if (atr == null)
            {
                return;
            }
            var methods = type.GetMethods();

            foreach (var m in methods)
            {
                var atr2 = m.GetCustomAttribute(typeof(SubscribeAttribute));
                if (atr2 == null)
                {
                    continue;
                }
                var ed = CreateEventDeclare(atr2 as SubscribeAttribute, m);
                ed.ServiceInstanceType  = type;
                ed.ServiceInstanceCtor2 = DynamicMethodHelper.CreateCtorFunc <Func <object> >(type, Type.EmptyTypes);
                if (eventRegister.ContainsKey(ed.Name))
                {
                    throw new Exception($"已注册过相同的事件名 {ed.Name}");
                }
                eventRegister.Add(ed.Name, ed);

                if (ed.IsArray)//集合重新创建一个事件定义
                {
                    var clone = ed.Clone() as EventDeclare;
                    clone.IsCopy = true;
                    eventRegister.Add(clone.GetArrayName(), clone);
                }
            }
        }
示例#2
0
            private static bool GetFieldAccessors <T>(string name, bool writeAlso,
                                                      out Func <StringBuilder, T> getter, out Action <StringBuilder, T> setter)
            {
                var field = typeof(StringBuilder).GetField(name, BindingFlags.NonPublic | BindingFlags.Instance);

                if (field == null)
                {
                    getter = null;
                    setter = null;
                    return(false);
                }
                var method = new DynamicMethodHelper(name + "_StringBuilder_getter",
                                                     typeof(T), new[] { typeof(StringBuilder) },
                                                     typeof(StringBuilder));

                method.GetField(0, field);
                method.Return();
                getter = method.Compile <Func <StringBuilder, T> >();
                if (writeAlso)
                {
                    method = new DynamicMethodHelper(name + "_StringBuilder_setter",
                                                     null, new[] { typeof(StringBuilder), typeof(T) },
                                                     typeof(StringBuilder));
                    method.PushArg(0);
                    method.PushArg(1);
                    method.SetField(field);
                    method.Return();
                    setter = method.Compile <Action <StringBuilder, T> >();
                }
                else
                {
                    setter = null;
                }
                return(true);
            }
示例#3
0
            static StringBuilderInternalAccessor()
            {
                var method = typeof(string).GetMethod("FastAllocateString", BindingFlags.NonPublic |
                                                      BindingFlags.Static);
                var dynamic = new DynamicMethodHelper("FastAllocateString_String_caller", typeof(string),
                                                      new[] { typeof(int) }, typeof(string));

                dynamic.PushArg(0);
                dynamic.CallMethod(method);
                dynamic.Return();
                _stringAllocator = dynamic.Compile <Func <int, string> >();
                Action <StringBuilder, string> dummySetter;

                if (GetFieldAccessors("m_StringValue", false, out _stringValueGetter,
                                      out dummySetter))
                {
                    _instance = new StringBuilderInternalAccessorOriginal();
                }
                else
                {
                    GetFieldAccessors("m_ChunkPrevious", true, out _previousGetter, out _previousSetter);
                    GetFieldAccessors("m_ChunkChars", true, out _charsGetter, out _charsSetter);
                    GetFieldAccessors("m_ChunkOffset", true, out _offsetGetter, out _offsetSetter);
                    GetFieldAccessors("m_ChunkLength", true, out _lengthGetter, out _lengthSetter);
                    _instance = new StringBuilderInternalAccessor40();
                }
            }
        public void EmitConstructorInvokerInvokeWithParametersComplexTypes()
        {
            Type personType = typeof(Person);

            Type[]             parameterTypes     = { typeof(string), typeof(string), typeof(int), typeof(Child) };
            ConstructorInvoker constructorInvoker = DynamicMethodHelper.EmitConstructorInvoker(
                personType,
                personType.GetConstructor(
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
                    null,
                    parameterTypes,
                    null),
                parameterTypes);

            const string name      = "javier";
            const string surname   = "sotomayor";
            const int    age       = 45;
            const string childName = "child";

            Child  child  = new Child(childName);
            Person person = (Person)constructorInvoker(name, surname, age, child);

            Assert.IsNotNull(person);
            Assert.AreEqual(name, person.Name);
            Assert.AreEqual(surname, person.Surname);
            Assert.AreEqual(age, person.Age);

            Assert.IsNotNull(person.Child);
            Assert.AreSame(child, person.Child);
            Assert.AreEqual(childName, person.Child.Name);
        }
        public void EmitMethodInvokerInvokeStaticMethod()
        {
            MethodInfo    methodInfo    = typeof(MathHelper).GetMethod("Pow", new[] { typeof(double), typeof(double) });
            MethodInvoker methodInvoker = DynamicMethodHelper.EmitMethodInvoker(typeof(MathHelper), methodInfo);
            object        result        = methodInvoker(null, Convert.ChangeType(10, TypeCode.Double), Convert.ChangeType(2, TypeCode.Double));

            Assert.AreEqual(MathHelper.Pow(10, 2), result);
        }
        public void EmitMethodInvokerInvokeMethodWithReturnType()
        {
            Type[]     parameterTypes = { typeof(int), typeof(int) };
            MathHelper mathHelper     = new MathHelper();
            object     value          = DynamicMethodHelper.EmitMethodInvoker(typeof(MathHelper), typeof(MathHelper).GetMethod("Sum", parameterTypes))(mathHelper, 10, 5);

            Assert.AreEqual(mathHelper.Sum(10, 5), (int)value);
        }
示例#7
0
 public object Invoke(object[] parameters)
 {
     if (delgate != null)
     {
         return(delgate(parameters));
     }
     this.delgate = DynamicMethodHelper.CreateDynamicConstructorInfoHandler(type, info);
     return(this.delgate(parameters));
 }
 public object GetValue(object obj, object[] index)
 {
     if (this.getDelegate != null)
     {
         return(this.getDelegate(obj, index));
     }
     this.getDelegate = DynamicMethodHelper.CreateGetHandler(type, info);
     return(this.getDelegate(obj, index));
 }
 public void SetValue(object obj, object value)
 {
     if (this.setDelegate != null)
     {
         this.setDelegate(obj, value);
         return;
     }
     this.setDelegate = DynamicMethodHelper.CreateSetHandler(type, info);
     this.setDelegate(obj, value);
 }
示例#10
0
文件: Hook.cs 项目: qipa/MonoMod
 private void _Free()
 {
     if (_RefTarget != null)
     {
         DynamicMethodHelper.FreeReference(_RefTarget.Value);
     }
     if (_RefTrampoline != null)
     {
         DynamicMethodHelper.FreeReference(_RefTrampoline.Value);
     }
 }
        public void EmitMethodInvokerInvokeMethodWithoutReturnType()
        {
            MathHelper    mathHelper    = new MathHelper();
            MethodInvoker methodInvoker = DynamicMethodHelper.EmitMethodInvoker(
                typeof(MathHelper),
                typeof(MathHelper).GetMethod("SetPI", new[] { typeof(double) }));

            methodInvoker(mathHelper, Math.PI);

            Assert.AreEqual(Math.PI, mathHelper.PI);
        }
示例#12
0
        internal void _UpdateOrig(MethodBase invoke)
        {
            if (_OrigDelegateType == null)
            {
                return;
            }
            Delegate orig = (invoke ?? GenerateTrampoline(_OrigDelegateInvoke)).CreateDelegate(_OrigDelegateType);

            DynamicMethodHelper.SetReference(_RefTrampoline.Value, orig);
            DynamicMethodHelper.SetReference(_RefTrampolineTmp.Value, orig);
        }
        public void EmitMethodInvokerInvokeMethodWithReturnTypeAndNoArguments()
        {
            MathHelper mathHelper = new MathHelper();

            mathHelper.SetPI(Math.PI);
            object value = DynamicMethodHelper.EmitMethodInvoker(
                typeof(MathHelper),
                typeof(MathHelper).GetMethod("GetPI"))(mathHelper);

            Assert.AreEqual(Math.PI, (double)value);
        }
 public void EmitConstructorInvokerConstructNullableValues()
 {
     Assert.AreEqual(default(bool?), DynamicMethodHelper.EmitConstructorInvoker(typeof(bool?))());
     Assert.AreEqual(default(byte?), DynamicMethodHelper.EmitConstructorInvoker(typeof(byte?))());
     Assert.AreEqual(default(sbyte?), DynamicMethodHelper.EmitConstructorInvoker(typeof(sbyte?))());
     Assert.AreEqual(default(short?), DynamicMethodHelper.EmitConstructorInvoker(typeof(short?))());
     Assert.AreEqual(default(ushort?), DynamicMethodHelper.EmitConstructorInvoker(typeof(ushort?))());
     Assert.AreEqual(default(int?), DynamicMethodHelper.EmitConstructorInvoker(typeof(int?))());
     Assert.AreEqual(default(uint?), DynamicMethodHelper.EmitConstructorInvoker(typeof(uint?))());
     Assert.AreEqual(default(long?), DynamicMethodHelper.EmitConstructorInvoker(typeof(long?))());
     Assert.AreEqual(default(ulong?), DynamicMethodHelper.EmitConstructorInvoker(typeof(ulong?))());
     Assert.AreEqual(default(float?), DynamicMethodHelper.EmitConstructorInvoker(typeof(float?))());
     Assert.AreEqual(default(decimal?), DynamicMethodHelper.EmitConstructorInvoker(typeof(decimal?))());
     Assert.AreEqual(default(DateTime?), DynamicMethodHelper.EmitConstructorInvoker(typeof(DateTime?))());
 }
示例#15
0
        /// <summary>
        ///     Creates a CIL method body from a dynamic method.
        /// </summary>
        /// <param name="method">The method that owns the method body.</param>
        /// <param name="dynamicMethodObj">The Dynamic Method/Delegate/DynamicResolver.</param>
        /// <param name="operandResolver">
        ///     The object instance to use for resolving operands of an instruction in the
        ///     method body.
        /// </param>
        /// <param name="importer">
        ///     The object instance to use for importing operands of an instruction in the
        ///     method body.
        /// </param>
        /// <returns>The method body.</returns>
        public static CilMethodBody FromDynamicMethod(
            MethodDefinition method,
            object dynamicMethodObj,
            ICilOperandResolver operandResolver = null,
            ReferenceImporter importer          = null)
        {
            if (!(method.Module is SerializedModuleDefinition module))
            {
                throw new ArgumentException("Method body should reference a serialized module.");
            }

            var result = new CilMethodBody(method);

            operandResolver ??= new CilOperandResolver(method.Module, result);
            importer ??= new ReferenceImporter(method.Module);

            dynamicMethodObj = DynamicMethodHelper.ResolveDynamicResolver(dynamicMethodObj);

            //Get Runtime Fields
            var code      = FieldReader.ReadField <byte[]>(dynamicMethodObj, "m_code");
            var scope     = FieldReader.ReadField <object>(dynamicMethodObj, "m_scope");
            var tokenList = FieldReader.ReadField <List <object> >(scope, "m_tokens");
            var localSig  = FieldReader.ReadField <byte[]>(dynamicMethodObj, "m_localSignature");
            var ehHeader  = FieldReader.ReadField <byte[]>(dynamicMethodObj, "m_exceptionHeader");
            var ehInfos   = FieldReader.ReadField <IList <object> >(dynamicMethodObj, "m_exceptions");

            // Read raw instructions.
            var reader       = new ByteArrayReader(code);
            var disassembler = new CilDisassembler(reader);

            result.Instructions.AddRange(disassembler.ReadAllInstructions());

            //Local Variables
            DynamicMethodHelper.ReadLocalVariables(result, method, localSig);

            //Exception Handlers
            DynamicMethodHelper.ReadReflectionExceptionHandlers(result, ehInfos, ehHeader, importer);

            // Resolve all operands.
            foreach (var instruction in result.Instructions)
            {
                instruction.Operand =
                    DynamicMethodHelper.ResolveOperandReflection(module.ReaderContext, result, instruction, operandResolver, tokenList, importer) ??
                    instruction.Operand;
            }

            return(result);
        }
        public void EmitMethodInvokerInvokeVirtualMethodWithReturnTypeAndNoArguments()
        {
            MathHelper mathHelper = new MathHelper();
            object     value      = DynamicMethodHelper.EmitMethodInvoker(
                typeof(MathHelper),
                typeof(MathHelper).GetMethod("GetAnInteger"))(mathHelper);

            Assert.AreEqual(10, (int)value);

            MathHelperImpl mathHelperImpl = new MathHelperImpl();

            value = DynamicMethodHelper.EmitMethodInvoker(
                typeof(MathHelperImpl),
                typeof(MathHelperImpl).GetMethod("GetAnInteger"))(mathHelperImpl);

            Assert.AreEqual(20, (int)value);
        }
        public void EmitConstructorInvokerConstructStructValuesWithParameters()
        {
            const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;

            Type[] parameterTypes = { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) };
            object value          = DynamicMethodHelper.EmitConstructorInvoker(typeof(DateTime), typeof(DateTime).GetConstructor(bindingFlags, null, parameterTypes, null), parameterTypes)(2013, 9, 10, 16, 40, 30);

            Assert.AreEqual(new DateTime(2013, 9, 10, 16, 40, 30), value);

            parameterTypes = new [] { typeof(int), typeof(int), typeof(int), typeof(int) };
            value          = DynamicMethodHelper.EmitConstructorInvoker(typeof(Rectangle), typeof(Rectangle).GetConstructor(bindingFlags, null, parameterTypes, null), parameterTypes)(40, 20, 300, 200);
            Assert.AreEqual(new Rectangle(40, 20, 300, 200), value);

            parameterTypes = new [] { typeof(int), typeof(int) };
            value          = DynamicMethodHelper.EmitConstructorInvoker(typeof(Point), typeof(Point).GetConstructor(bindingFlags, null, parameterTypes, null), parameterTypes)(10, 20);
            Assert.AreEqual(new Point(10, 20), value);
        }
示例#18
0
        public static object UnPack(Type type, byte[] datas)
        {
            if (addInvoker == null)
            {
                var method = type.GetMethod("Add");
                addInvoker = DynamicMethodHelper.CreateMethodInvoker(method);
            }
            var obj       = DynamicMethodHelper.CreateCtorFuncFromCache(type)();
            var innerType = type.GenericTypeArguments[0];
            int dataIndex = 0;

            while (dataIndex < datas.Length)
            {
                var value = FieldFormat.UnPack(innerType, datas, ref dataIndex);
                addInvoker.Invoke(obj, new object[] { value });
            }
            return(obj);
        }
 public void EmitConstructorInvokerConstructStructValues()
 {
     Assert.AreEqual(default(bool), DynamicMethodHelper.EmitConstructorInvoker(typeof(bool))());
     Assert.AreEqual(default(byte), DynamicMethodHelper.EmitConstructorInvoker(typeof(byte))());
     Assert.AreEqual(default(sbyte), DynamicMethodHelper.EmitConstructorInvoker(typeof(sbyte))());
     Assert.AreEqual(default(short), DynamicMethodHelper.EmitConstructorInvoker(typeof(short))());
     Assert.AreEqual(default(ushort), DynamicMethodHelper.EmitConstructorInvoker(typeof(ushort))());
     Assert.AreEqual(default(int), DynamicMethodHelper.EmitConstructorInvoker(typeof(int))());
     Assert.AreEqual(default(uint), DynamicMethodHelper.EmitConstructorInvoker(typeof(uint))());
     Assert.AreEqual(default(long), DynamicMethodHelper.EmitConstructorInvoker(typeof(long))());
     Assert.AreEqual(default(ulong), DynamicMethodHelper.EmitConstructorInvoker(typeof(ulong))());
     Assert.AreEqual(default(float), DynamicMethodHelper.EmitConstructorInvoker(typeof(float))());
     Assert.AreEqual(default(decimal), DynamicMethodHelper.EmitConstructorInvoker(typeof(decimal))());
     Assert.AreEqual(default(Rectangle), DynamicMethodHelper.EmitConstructorInvoker(typeof(Rectangle))());
     Assert.AreEqual(default(Point), DynamicMethodHelper.EmitConstructorInvoker(typeof(Point))());
     Assert.AreEqual(default(Color), DynamicMethodHelper.EmitConstructorInvoker(typeof(Color))());
     Assert.AreEqual(default(DateTime), DynamicMethodHelper.EmitConstructorInvoker(typeof(DateTime))());
 }
示例#20
0
        //static Dictionary<Type, TypeInfo> TypeInfoCache = new Dictionary<Type, TypeInfo>();
        //static TypeInfo getTypeInfo(Type type)
        //{
        //    var a = TypeInfoCache.TryGetValue(type, out TypeInfo typeInfo);
        //    if (!a)
        //    {
        //        var typeRef = typeof(ReflectionHelper);
        //        var method = typeRef.GetMethod(nameof(ReflectionHelper.GetInfo), BindingFlags.Public | BindingFlags.Static);
        //        var refInfo = method.MakeGenericMethod(new Type[] { type }).Invoke(null, new object[] { null }) as IReflectionInfo;
        //        var pro = type.GetProperties().Where(b => b.GetSetMethod() != null);
        //        typeInfo = new TypeInfo() { Properties = pro, ReflectionInfo = refInfo };
        //        TypeInfoCache.Add(type, typeInfo);
        //    }
        //    return typeInfo;
        //}
        public static object UnPack(Type type, byte[] datas)
        {
            var obj       = DynamicMethodHelper.CreateCtorFuncFromCache(type)();
            var typeInfo  = type.GetReflectionInfo();
            int dataIndex = 0;

            foreach (var p in typeInfo.Properties)
            {
                var value = FieldFormat.UnPack(p.PropertyType, datas, ref dataIndex);
                if (value == null)
                {
                    continue;
                }
                typeInfo.ReflectionInfo.SetValue(obj, p.Name, value);
                //p.SetValue(obj, value);
            }
            return(obj);
        }
示例#21
0
        public static serviceInfo GetServiceInfo(Type type, bool initObjCtor = false)
        {
            var a = serviceInfoCache.TryGetValue(type, out var info);

            if (a)
            {
                return(info);
            }
            info = new serviceInfo()
            {
                ServiceType = type,
                Attributes  = type.GetCustomAttributes().ToList(),
            };
            if (initObjCtor)
            {
                info.InstaceCtor = DynamicMethodHelper.CreateCtorFunc <Func <object> >(type, Type.EmptyTypes);
            }
            var methods        = type.GetMethods(BindingFlags.Public | BindingFlags.Instance);
            var methodInfoList = new List <methodInfo>();

            foreach (var m in methods)
            {
                var mInfo = new methodInfo()
                {
                    Attributes    = m.GetCustomAttributes().ToList(),
                    MethodInfo    = m,
                    Parameters    = m.GetParameters(),
                    MethodInvoker = DynamicMethodHelper.CreateMethodInvoker(m)
                };
                mInfo.IsAsync = m.ReturnType.Name.StartsWith("Task`1");
                if (mInfo.IsAsync) //总是返回同步结果
                {
                    mInfo.TaskInvoker = DynamicMethodHelper.TaskResultInvoker <object>(m.ReturnType);
                    var taskType = typeof(AsyncResult <>).MakeGenericType(m.ReturnType.GetGenericArguments()[0]);
                    mInfo.TaskCreater = DynamicMethodHelper.CreateCtorFunc <Func <AsyncResult> >(taskType, new Type[0]);
                }
                methodInfoList.Add(mInfo);
            }
            info.Methods          = methodInfoList;
            info.ServiceAttribute = type.GetCustomAttribute <ServiceAttribute>() ?? new ServiceAttribute();
            apiPrefixCache.TryAdd(info.ServiceAttribute.ApiPrefix, type);
            serviceInfoCache.TryAdd(type, info);
            return(info);
        }
示例#22
0
        public static object UnPack(Type type, byte[] datas)
        {
            var dic        = (System.Collections.IDictionary)DynamicMethodHelper.CreateCtorFuncFromCache(type)();
            var allArgs    = type.GenericTypeArguments;
            var innerType  = allArgs[0];
            var innerType2 = allArgs[1];
            int dataIndex  = 0;

            while (dataIndex < datas.Length)
            {
                var key   = FieldFormat.UnPack(innerType, datas, ref dataIndex);
                var value = FieldFormat.UnPack(innerType2, datas, ref dataIndex);
                if (key == null)
                {
                    continue;
                }
                dic.Add(key, value);
            }
            return(dic);
        }
示例#23
0
        private static void RunConstructorBenchmark()
        {
            ConstructorInfo constructorInfo = typeof(Person).GetConstructor(
                BindingFlags.Instance | BindingFlags.NonPublic,
                null,
                new Type[0],
                null);
            ConstructorInvoker constructorInvoker = DynamicMethodHelper.EmitConstructorInvoker(typeof(Person));

            object[] emptyParameters = new object[0];

            Dictionary <string, Action> actions = new Dictionary <string, Action>
            {
                { "Direct ctor", () => new Person() },
                { "Reflection ctor", () => constructorInfo.Invoke(emptyParameters) },
                { "Labo ctor", () => ReflectionHelper.CreateInstance(typeof(Person), constructorInfo, Type.EmptyTypes) },
                { "Labo cached ctor", () => constructorInvoker() },
            };

            Execute("Benchmark for Object Construction", actions);
        }
        public void EmitConstructorInvokerInvokeParameterlessConstructor()
        {
            Type personType = typeof(Person);

            Type[]             parameterTypes     = { };
            ConstructorInvoker constructorInvoker = DynamicMethodHelper.EmitConstructorInvoker(
                personType,
                personType.GetConstructor(
                    BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
                    null,
                    parameterTypes,
                    null),
                parameterTypes);

            Person person = (Person)constructorInvoker();

            Assert.IsNotNull(person);
            Assert.AreEqual(Person.DEFAULT_NAME, person.Name);
            Assert.AreEqual(Person.DEFAULT_SURNAME, person.Surname);
            Assert.AreEqual(Person.DEFAULT_AGE, person.Age);
        }
示例#25
0
        /// <summary>
        /// 扫码程序集,注册事件处理程序
        /// </summary>
        /// <param name="assembly"></param>
        public void ScanEventHandler(Assembly assembly)
        {
            foreach (var type in assembly.GetTypes())
            {
                var methodInfos = type.GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public |
                                                  BindingFlags.NonPublic ^ BindingFlags.GetProperty ^
                                                  BindingFlags.SetProperty);

                foreach (var methodInfo in methodInfos)
                {
                    var mehAttr = methodInfo.GetCustomAttribute <AppEventHandlerAttribute>();
                    if (mehAttr == null)
                    {
                        continue;
                    }
                    var fun = DynamicMethodHelper.GetExecuteDelegate(methodInfo);

                    AddHandler(mehAttr.EventKey,
                               (args) => fun(methodInfo.IsStatic ? null : Activator.CreateInstance(type), args));
                }
            }
        }
示例#26
0
        /// <summary>
        /// 扫描容器中的服务,注册时间处理程序
        /// </summary>
        /// <param name="services"></param>
        public void ScanEventHandler(IServiceCollection services)
        {
            foreach (var service in services)
            {
                var methodInfos = service.ServiceType.GetMethods(
                    BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic ^
                    BindingFlags.GetProperty ^ BindingFlags.SetProperty);
                foreach (var methodInfo in methodInfos)
                {
                    var mehAttr = methodInfo.GetCustomAttribute <AppEventHandlerAttribute>();
                    if (mehAttr == null)
                    {
                        continue;
                    }
                    var fun = DynamicMethodHelper.GetExecuteDelegate(methodInfo);

                    AddHandler(mehAttr.EventKey,
                               (args) => fun(methodInfo.IsStatic ? null : _serviceProvider.GetService(service.ServiceType),
                                             args));
                }
            }
        }
示例#27
0
        private static void RunMethodBenchmark()
        {
            MethodInfo    methodInfo    = typeof(Person).GetMethod("GetName", BindingFlags.Instance | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
            MethodInvoker methodInvoker = DynamicMethodHelper.EmitMethodInvoker(typeof(Person), methodInfo);

            object[] emptyParameters = new object[0];

            Dictionary <string, Action> actions = new Dictionary <string, Action>
            {
                { "Direct method", () => new Person().GetName() },
                { "Reflection method", () => methodInfo.Invoke(new Person(), emptyParameters) },
                { "dynamic method", () =>
                  {
                      dynamic person = new Person();
                      string  name   = person.GetName();
                  } },
                { "Labo expression method", () => ExpressionHelper.CallMethod(new Person(), methodInfo) },
                { "Labo method", () => ReflectionHelper.CallMethod(new Person(), methodInfo) },
                { "Labo cached method", () => methodInvoker(new Person()) },
            };

            Execute("Benchmark for Method Invocation", actions);
        }
示例#28
0
        bool SubscribeData(object args)
        {
            var ed   = args as EventDeclare;
            var name = $"CRL_QUEUE_{ed.Name}";
            var coll = database.GetCollection <MongoData>(name);
            var list = coll.Find(b => true).SortBy(b => b.Time).Limit(ed.ListTake).ToList();

            if (list.Count == 0)
            {
                return(true);
            }
            if (ed.IsArray)
            {
                var objInstance = DynamicMethodHelper.CreateCtorFuncFromCache(ed.EventDataType)();
                var innerType   = ed.EventDataType.GenericTypeArguments[0];
                var method      = ed.EventDataType.GetMethod("Add");
                foreach (var m in list)
                {
                    var item = m.Data.ToObject(innerType);
                    method.Invoke(objInstance, new object[] { item });
                }
                ed.MethodInvoke.Invoke(ed.CreateServiceInstance(), new object[] { objInstance });
                var ids = list.Select(b => b.Id).ToArray();
                coll.DeleteMany(b => ids.Contains(b.Id));
            }
            else
            {
                foreach (var m in list)
                {
                    var item = m.Data.ToObject(ed.EventDataType);
                    ed.MethodInvoke.Invoke(ed.CreateServiceInstance(), new object[] { item });
                    coll.DeleteOne(b => b.Id == m.Id);
                }
            }
            return(true);
        }
示例#29
0
        public object Execute(ParameterList parameters, FunctionContextContainer context)
        {
            try
            {
                var dynamicMethod = DynamicMethodHelper.GetDynamicMethod("<C1 function> " + _functionToWrap.CompositeName());

                return(dynamicMethod(() => _functionToWrap.Execute(parameters, context)));
            }
            catch (Exception ex)
            {
                if (_functionToWrap.ReturnType == typeof(XhtmlDocument) || (_functionToWrap.ReturnType == typeof(void) && ex is HttpCompileException))
                {
                    XElement errorBoxHtml;
                    if (context.ProcessException(_functionToWrap.CompositeName(), ex, LogTitle, out errorBoxHtml))
                    {
                        XhtmlDocument errorInfoDocument = new XhtmlDocument();
                        errorInfoDocument.Body.Add(errorBoxHtml);
                        return(errorInfoDocument);
                    }
                }

                throw;
            }
        }
		static void GenerateCompareTypeIL(DynamicMethodHelper il, Type t)
		{
			MethodInfo method = GetTypeMethod(t, TypeMethodType.Compare);

			if ((method == null) && (t.IsPrimitive == false))
			{
				il.Pop();
				il.Pop();
				il.PushInt(1);
				return;
			}

			il.BeginScope();
			{
				const string valX = "x";
				const string valY = "y";
				const string valThis = "_thisX";
				const string trueLabel = "endTrue";
				const string falseLabel = "endFalse";
				const string endLabel = "endCheck";

				il.DeclareLocal(valX, typeof(object));
				il.PopLocal(valX);
				il.DeclareLocal(valY, typeof(object));
				il.PopLocal(valY);

				//  If both null or the same object then return true
				il.PushLocal(valX);
				il.PushLocal(valY);
				il.GotoIfEqual(trueLabel);

				//  Exit false if either value is null
				il.PushLocal(valX);
				il.GotoIfFalse(falseLabel);

				il.PushLocal(valY);
				il.GotoIfFalse(falseLabel);

				//  Both operands are non-null so call the type-specific comparison method
				if (t.IsPrimitive)
				{
					il.PushLocal(valX);
					il.UnboxValueType(t);
					il.PushLocal(valX);
					il.UnboxValueType(t);
					il.CompareEqual();
				}
				else
				{
					Type paramType = method.GetParameters()[0].ParameterType;

					il.DebugWriteLine("Calling " + method);
					if (method.IsStatic)
					{
						il.PushLocal(valX);
						if (paramType.IsValueType) il.UnboxValueType(paramType);
					}
					else
					{
						il.DeclareLocal(valThis, t);
						il.PushLocal(valX);
						il.PopLocalFromObject(valThis);
						il.PushThis(valThis, method);
					}
					il.PushLocal(valY);
					if (paramType.IsValueType) il.UnboxValueType(paramType);
					il.CallMethod(method);
				}
				il.GotoIfFalse(falseLabel);

				il.MarkLabel(trueLabel);
				il.PushInt(1);
				il.Goto(endLabel);

				il.MarkLabel(falseLabel);
				il.DebugWriteLine("The following values are not equal:");
				il.DebugWriteLocal(valX);
				il.DebugWriteLocal(valY);
				il.PushInt(0);

				il.MarkLabel(endLabel);
			}
			il.EndScope();
		}
		public void GenerateCompareIL(DynamicMethodHelper il, int xIndex, int yIndex)
		{
			#region Names
			const string instanceX = "instanceX";
			const string propVarX = "propValueX";
			const string enumerableX = "enumerableX";
			const string enumVarX = "enumX";
			const string dictEnumVarX = "dictEnumX";

			const string instanceY = "instanceY";
			const string propVarY = "propValueY";
			const string enumerableY = "enumerableY";
			const string enumVarY = "enumY";
			const string dictEnumVarY = "dictEnumY";

			const string endFalseLabel = "logBadPropertyLabel";
			const string endTrueLabel = "endTrue";
			const string endLabel = "endLabel";
			const string loopStart = "loopStart";
			const string loopEnd = "loopEnd";
			#endregion

			il.DebugWriteLine("Comparing property " + this.Name);

			il.DeclareLocal(instanceX, this.OwnerType);
			il.PushArg(xIndex);
			il.PopLocal(instanceX);

			il.DeclareLocal(instanceY, this.OwnerType);
			il.PushArg(yIndex);
			il.PopLocal(instanceY);

			il.DeclareLocal(propVarX, this.Type);
			il.DeclareLocal(propVarY, this.Type);

			if (this.classType != null)
			{
				il.CopyLocal(instanceX, propVarX);
				il.CopyLocal(instanceY, propVarY);
			}
			else if (this.property is PropertyInfo)
			{
				PropertyInfo pi = (PropertyInfo)this.property;
				MethodInfo getMethod = pi.GetGetMethod(true);

				il.CallMethod(instanceX, getMethod);
				il.PopLocal(propVarX);
				il.CallMethod(instanceY, getMethod);
				il.PopLocal(propVarY);
			}
			else
			{
				il.GetField(instanceX, this.property as FieldInfo);
				il.PopLocal(propVarX);
				il.GetField(instanceY, this.property as FieldInfo);
				il.PopLocal(propVarY);
			}

			//  For ref types, if both null or the same object then return true
			//  For value types, this is a value comparison
			Type t = IsCollection ? (IsDictionary ? null : this.elementType) : this.Type;
			bool doDefault = true;
			if (t != null && t.IsValueType)
			{
				MethodInfo mi = t.GetMethod("op_Equality", new [] { t, t });
				if (mi != null)
				{
					il.PushLocal(propVarX);
					il.PushLocal(propVarY);
					il.CallMethod(mi);
					il.GotoIfFalse(endTrueLabel);
					doDefault = false;
				}
				else if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
				{
					Type it = t.GetGenericArguments()[0];
					mi = typeof(Nullable).GetMethod("Equals", BindingFlags.Public | BindingFlags.Static | BindingFlags.DeclaredOnly);
					mi = mi.MakeGenericMethod(it);

					il.PushLocal(propVarX);
					il.PushLocal(propVarY);
					il.CallMethod(mi);
					il.GotoIfFalse(endTrueLabel);
					doDefault = false;
				}
			}

			if (doDefault)
			{
				il.PushLocal(propVarX);
				il.PushLocal(propVarY);
				il.GotoIfEqual(endTrueLabel);
			}

			if (IsCollection)
			{
				il.DeclareLocal(enumerableX, typeof(IEnumerable));
				il.DeclareLocal(enumVarX, typeof(IEnumerator));
				il.DeclareLocal(enumerableY, typeof(IEnumerable));
				il.DeclareLocal(enumVarY, typeof(IEnumerator));

				il.CopyLocal(propVarX, enumerableX);
				il.CallMethod(enumerableX, "GetEnumerator");
				il.PopLocal(enumVarX);

				il.CopyLocal(propVarY, enumerableX);
				il.CallMethod(enumerableX, "GetEnumerator");
				il.PopLocal(enumVarY);

				if (IsDictionary)
				{
					il.DeclareLocal(dictEnumVarX, typeof(IDictionaryEnumerator));
					il.CopyLocal(enumVarX, dictEnumVarX);
					il.DeclareLocal(dictEnumVarY, typeof(IDictionaryEnumerator));
					il.CopyLocal(enumVarY, dictEnumVarY);
				}

				il.MarkLabel(loopStart);
				il.CallMethod(enumVarX, "MoveNext");
				il.GotoIfFalse(loopEnd);

				il.CallMethod(enumVarY, "MoveNext");
				il.GotoIfFalse(endFalseLabel); // y has less elements than x

				if (IsDictionary)
				{
					il.CallMethod(dictEnumVarX, "get_Key");
					il.CallMethod(dictEnumVarY, "get_Key");
					GenerateCompareTypeIL(il, this.dictionaryKeyType);
					il.GotoIfFalse(endFalseLabel);

					il.CallMethod(dictEnumVarX, "get_Value");
					il.CallMethod(dictEnumVarY, "get_Value");
					GenerateCompareTypeIL(il, this.dictionaryValueType);
					il.GotoIfFalse(endFalseLabel);
				}
				else // if (not dictionary)
				{
					il.CallMethod(enumVarX, "get_Current");
					il.CallMethod(enumVarY, "get_Current");
					GenerateCompareTypeIL(il, this.elementType);
					il.GotoIfFalse(endFalseLabel);
				}

				il.Goto(loopStart);
				il.MarkLabel(loopEnd);

				//  enumVarX has no more elements so enumVarY shouldn't
				//  have any more either
				il.CallMethod(enumVarY, "MoveNext");
				il.GotoIfTrue(endFalseLabel); // count mismatch
			}
			else // if (not collection)
			{
				il.PushLocalAsObject(propVarX);
				il.PushLocalAsObject(propVarY);
				GenerateCompareTypeIL(il, this.Type);
				il.GotoIfFalse(endFalseLabel);
			}

			il.MarkLabel(endTrueLabel);
			//il.DebugWriteLine(string.Format("Property {0} is equal", this.Name));
			il.PushInt(1);
			il.Goto(endLabel);

			//  Log out name of property if not equal
			il.MarkLabel(endFalseLabel);
			il.DebugWriteLine(string.Format("Property {0} is not equal", this.Name));
			il.PushInt(0);  // set success to false

			il.MarkLabel(endLabel);
		}
示例#32
0
文件: Hook.cs 项目: qipa/MonoMod
        public Hook(MethodBase from, MethodInfo to, object target)
        {
            Method = from;
            _Hook  = to;

            if (_Hook.ReturnType != ((from as MethodInfo)?.ReturnType ?? typeof(void)))
            {
                throw new InvalidOperationException($"Return type of hook for {from} doesn't match, must be {((from as MethodInfo)?.ReturnType ?? typeof(void)).FullName}");
            }

            if (target == null && !to.IsStatic)
            {
                throw new InvalidOperationException($"Hook for method {from} must be static, or you must pass a target instance.");
            }

            ParameterInfo[] hookArgs = _Hook.GetParameters();

            // Check if the parameters match.
            // If the delegate has got an extra first parameter that itself is a delegate, it's the orig trampoline passthrough.
            ParameterInfo[] args = Method.GetParameters();
            Type[]          argTypes;
            if (!Method.IsStatic)
            {
                argTypes    = new Type[args.Length + 1];
                argTypes[0] = Method.DeclaringType;
                for (int i = 0; i < args.Length; i++)
                {
                    argTypes[i + 1] = args[i].ParameterType;
                }
            }
            else
            {
                argTypes = new Type[args.Length];
                for (int i = 0; i < args.Length; i++)
                {
                    argTypes[i] = args[i].ParameterType;
                }
            }

            Type origType = null;

            if (hookArgs.Length == argTypes.Length + 1 && typeof(Delegate).IsAssignableFrom(hookArgs[0].ParameterType))
            {
                origType = hookArgs[0].ParameterType;
            }
            else if (hookArgs.Length != argTypes.Length)
            {
                throw new InvalidOperationException($"Parameter count of hook for {from} doesn't match, must be {argTypes.Length}");
            }

            for (int i = 0; i < argTypes.Length; i++)
            {
                Type argMethod = argTypes[i];
                Type argHook   = hookArgs[i + (origType == null ? 0 : 1)].ParameterType;
                if (!argMethod.IsAssignableFrom(argHook) &&
                    !argHook.IsAssignableFrom(argMethod))
                {
                    throw new InvalidOperationException($"Parameter #{i} of hook for {from} doesn't match, must be {argMethod.FullName} or related");
                }
            }

            MethodInfo origInvoke = origType?.GetMethod("Invoke");
            // TODO: Check origType Invoke arguments.

            DynamicMethod dm;
            ILGenerator   il;

            dm = new DynamicMethod(
                $"hook_{Method.Name}_{GetHashCode()}",
                (Method as MethodInfo)?.ReturnType ?? typeof(void), argTypes,
                Method.DeclaringType,
                true
                );
            il = dm.GetILGenerator();

            if (target != null)
            {
                _RefTarget = il.EmitReference(target);
            }

            if (origType != null)
            {
                _RefTrampoline = il.EmitReference <Delegate>(null);
            }

            // TODO: Use specialized Ldarg.* if possible; What about ref types?
            for (int i = 0; i < argTypes.Length; i++)
            {
                il.Emit(OpCodes.Ldarg, i);
            }

            il.Emit(OpCodes.Call, _Hook);

            il.Emit(OpCodes.Ret);

            Target = dm.Pin();

            _Detour = new Detour(Method, Target);

            if (origType != null)
            {
                DynamicMethodHelper.SetReference(_RefTrampoline.Value, GenerateTrampoline(origInvoke).CreateDelegate(origType));
            }
        }
        public MethodInvoker Create()
        {
            #if DIAGNOSTICS
            Cef.Logger.Trace(LogTarget.ScriptableObject, "Creating method [{0}]", GetMethodInvokerName(this.def));
            #endif

            // Passing method arguments by ref is not supported.
            if (this.def.GetMethods().Any(_ => _.GetParameters().Any(p => p.ParameterType.IsByRef)))
            {
                throw new JSBindingException("Passing method arguments by ref is not supported.");
            }

            // Mixing static and instance methods are not supported.
            if (this.def.GetMethods().All(_ => _.IsStatic)
                == this.def.GetMethods().All(_ => !_.IsStatic)
                )
            {
                throw new JSBindingException("Mixing static and instance methods are not supported.");
            }

            var methodInvoker = typeof(MethodInvoker).GetMethod("Invoke");
            var emit = new DynamicMethodHelper(
                GetMethodInvokerName(def),
                methodInvoker.ReturnType,
                methodInvoker.GetParameters().Select(_ => _.ParameterType).ToArray()
                )
                .Emitter;

            if (!this.def.HasOverloads && this.def.GetMethods().Single().GetParameters().All(_ => !_.IsOptional))
            {
                EmitInvoker(emit,
                    this.def.GetMethods().Single(),
                    null,
                    this.def.Setter
                    );
            }
            else
            {
                var methods = this.def.GetMethods()
                    .GroupBy(_ => _.GetParameters().Length, _ => _)
                    .ToDictionary(_ => _.Key, _ => _.ToList())
                    ;

                // expand methods with optional arguments
                var methodsWithOptArgs = this.def.GetMethods().Where(_ => _.GetParameters().Any(p => p.IsOptional));
                foreach (var m in methodsWithOptArgs)
                {
                    // if full method signature already placed in methods dictionary
                    var parameters = m.GetParameters();
                    for (var k = parameters.Length - 1; k >= 0; k--)
                    {
                        if (!parameters[k].IsOptional) break;

                        if (!methods.ContainsKey(k)) methods.Add(k, new List<MethodInfo>());

                        // check, that if methods already includes this signature, then doesn't expand
                        if (!methods[k].Any(_ =>
                        {
                            var p0 = _.GetParameters();
                            for (var i = 0; i < k; i++)
                            {
                                if (parameters[i].ParameterType != p0[i].ParameterType) return false;
                            }
                            return true;
                        }))
                        {
                            methods[k].Add(m);
                        }
                    }
                }

                // type variance handling
                foreach (var k in methods.Keys)
                {
                    var mlist = methods[k];
                    if (mlist.Count > 1) // if methods for argc==k has overloads
                    {
                        // detect arguments which have type variance
                        List<int> vargs = new List<int>();
                        for (int i = 0; i < k; i++)
                        {
                            if (mlist.Select(_ => _.GetParameters()[i].ParameterType).Distinct().Count() != 1)
                            {
                                vargs.Add(i);
                            }
                        }

                        // TODO: hide methods which not reacheable by type priority (int hides short or byte)

                        // stub, throw exception for currently unsupported
                        if (vargs.Count > 0)
                        {
                            throw new JSBindingException(
                                string.Format("Overloading by argument type variance currently is not supported. name=[{0}], argc=[{1}], vargs=[{2}]",
                                    this.def.Name, k, string.Join(", ", vargs)
                                    )
                                );
                        }
                    }
                }

                var defaultLabel = emit.DefineLabel();
                var labels = new Label[methods.Keys.Max() + 1];
                for (var i = 0; i < labels.Length; i++)
                {
                    if (methods.ContainsKey(i))
                    {
                        labels[i] = emit.DefineLabel();
                    }
                    else
                    {
                        labels[i] = defaultLabel;
                    }
                }

                emit.LdArg(argumentsCountArgIndex)
                    .Switch(labels)
                    ;

                emit.MarkLabel(defaultLabel)
                    .Call(throwArgumentCountMismatchMethod)
                    ;

                // write labels
                for (var i = 0; i < labels.Length; i++)
                {
                    if (labels[i] == defaultLabel) continue;

                    emit.MarkLabel(labels[i]);

                    EmitInvoker(emit,
                        methods[i].Single(),
                        i,
                        false
                        );
                }

                // TODO: check, optimize type variance or throw if not supported
            }

            return (MethodInvoker)emit.DynamicMethod.CreateDelegate(typeof(MethodInvoker));
        }