当前位置: 首页>>代码示例>>C#>>正文


C# FieldDefinition.MakeGeneric方法代码示例

本文整理汇总了C#中Mono.Cecil.FieldDefinition.MakeGeneric方法的典型用法代码示例。如果您正苦于以下问题:C# FieldDefinition.MakeGeneric方法的具体用法?C# FieldDefinition.MakeGeneric怎么用?C# FieldDefinition.MakeGeneric使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在Mono.Cecil.FieldDefinition的用法示例。


在下文中一共展示了FieldDefinition.MakeGeneric方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。

示例1: ProcessDelegateAllocation

        private bool ProcessDelegateAllocation(AssemblyProcessorContext context, MethodDefinition method, Instruction delegateAllocationInstruction)
        {
            // The instruction must be a delegate allocation
            // If not, this might be a static delegate, or some unsupported construct
            if (delegateAllocationInstruction.OpCode != OpCodes.Newobj)
                return false;

            var delegateInstanceConstructor = (MethodReference)delegateAllocationInstruction.Operand;
            var delegateInstanceType = delegateInstanceConstructor.DeclaringType;

            // The previous instruction pushes the delegate method onto the stack
            var functionPointerInstruction = delegateAllocationInstruction.Previous;
            if (functionPointerInstruction.OpCode != OpCodes.Ldftn)
                return false;

            var delegateMethod = (MethodReference)functionPointerInstruction.Operand;

            // The previous instruction pushes the target onto the stack
            // If it's the this-parameter, we can create an instance field, and reuse the same delegate
            var loadClosureInstruction = functionPointerInstruction.Previous;
            if (loadClosureInstruction.OpCode == OpCodes.Ldarg_0 && !method.IsStatic)
            {
                // TODO: Handle generic methods/delegates
                // TODO: Handle multiple constructors propertly
                var constructor = method.DeclaringType.Methods.FirstOrDefault(x => x.Name == ".ctor" && !x.HasParameters);
                var retInstruction3 = constructor?.Body.Instructions.FirstOrDefault(x => x.OpCode == OpCodes.Ret);
                if (retInstruction3 == null)
                    return false;

                // Create an instance field for the shared delegate
                var sharedDelegateField = new FieldDefinition($"<delegate>{delegateMethod.Name}", FieldAttributes.Private, delegateInstanceType);
                method.DeclaringType.Fields.Add(sharedDelegateField);

                // Create and store the delegate in constructor
                var ilProcessor5 = constructor.Body.GetILProcessor();
                ilProcessor5.InsertBefore(retInstruction3, ilProcessor5.Create(OpCodes.Ldarg_0));
                ilProcessor5.InsertBefore(retInstruction3, ilProcessor5.Create(OpCodes.Ldarg_0));
                ilProcessor5.InsertBefore(retInstruction3, ilProcessor5.Create(OpCodes.Ldftn, delegateMethod));
                ilProcessor5.InsertBefore(retInstruction3, ilProcessor5.Create(OpCodes.Newobj, delegateInstanceConstructor));
                ilProcessor5.InsertBefore(retInstruction3, ilProcessor5.Create(OpCodes.Stfld, sharedDelegateField));

                // Load from field instead of allocating
                var ilProcessor4 = method.Body.GetILProcessor();
                ilProcessor4.Remove(functionPointerInstruction);
                ilProcessor4.Replace(delegateAllocationInstruction, ilProcessor4.Create(OpCodes.Ldfld, sharedDelegateField));

                return true;
            }

            // If the target is a compiler generated closure, we only handle local variable load instructions
            int variableIndex;
            OpCode storeOpCode;
            if (!TryGetStoreOpcode(loadClosureInstruction, out storeOpCode, out variableIndex))
                return false;

            // Find the instruction that stores the closure variable
            var storeClosureInstruction = loadClosureInstruction.Previous;
            VariableReference closureVarible = null;

            while (storeClosureInstruction != null)
            {
                closureVarible = storeClosureInstruction.Operand as VariableReference;
                if (storeClosureInstruction.OpCode == storeOpCode && (closureVarible == null || variableIndex == closureVarible.Index))
                    break;

                storeClosureInstruction = storeClosureInstruction.Previous;
            }
            if (storeClosureInstruction == null)
                return false;

            var closureInstanceType = method.Body.Variables[variableIndex].VariableType;
            var closureType = closureInstanceType.Resolve();
            var genericParameters = closureType.GenericParameters.Cast<TypeReference>().ToArray();

            // Patch closure
            var closure = ProcessClosure(context, closureType, genericParameters);

            // Create delegate field
            var delegateFieldType = ChangeGenericArguments(context, delegateInstanceType, closureInstanceType);
            var delegateField = new FieldDefinition($"<delegate>{delegateMethod.Name}", FieldAttributes.Public, delegateFieldType);
            closureType.Fields.Add(delegateField);
            var localDelegateFieldInstance = delegateField.MakeGeneric(genericParameters);

            // Initialize delegate field (the closure instance (local 0) is already on the stack)
            var delegateConstructorInstance = (MethodReference)delegateAllocationInstruction.Operand;
            var delegateGenericArguments = (delegateFieldType as GenericInstanceType)?.GenericArguments.ToArray() ?? new TypeReference[0];
            var genericDelegateConstructor = context.Assembly.MainModule.ImportReference(delegateConstructorInstance.Resolve()).MakeGeneric(delegateGenericArguments);

            var methodInstance = (MethodReference)functionPointerInstruction.Operand;
            var genericMethod = methodInstance.Resolve().MakeGeneric(closureType.GenericParameters.ToArray());

            if (methodInstance is GenericInstanceMethod)
                throw new NotImplementedException();

            var ilProcessor3 = closure.FactoryMethod.Body.GetILProcessor();
            var returnInstruction = ilProcessor3.Body.Instructions.FirstOrDefault(x => x.OpCode == OpCodes.Ret);
            ilProcessor3.InsertBefore(returnInstruction, ilProcessor3.Create(OpCodes.Ldloc_0));
            ilProcessor3.InsertBefore(returnInstruction, ilProcessor3.Create(OpCodes.Ldftn, genericMethod));
            ilProcessor3.InsertBefore(returnInstruction, ilProcessor3.Create(OpCodes.Newobj, genericDelegateConstructor));
            ilProcessor3.InsertBefore(returnInstruction, ilProcessor3.Create(OpCodes.Stfld, localDelegateFieldInstance));
//.........这里部分代码省略.........
开发者ID:Kryptos-FR,项目名称:xenko-reloaded,代码行数:101,代码来源:DispatcherProcessor.cs

示例2: ProcessClosure

        private ClosureInfo ProcessClosure(AssemblyProcessorContext context, TypeDefinition closureType, TypeReference[] genericParameters)
        {
            ClosureInfo closure;
            if (closures.TryGetValue(closureType, out closure))
                return closure;

            var closureTypeConstructor = closureType.Methods.FirstOrDefault(x => x.Name == ".ctor");
            var closureGenericType = closureType.MakeGenericType(genericParameters);

            // Create factory method for pool items
            var factoryMethod = new MethodDefinition("<Factory>", MethodAttributes.HideBySig | MethodAttributes.Private | MethodAttributes.Static, closureGenericType);
            closureType.Methods.Add(factoryMethod);
            factoryMethod.Body.InitLocals = true;
            factoryMethod.Body.Variables.Add(new VariableDefinition(closureGenericType));
            var factoryMethodProcessor = factoryMethod.Body.GetILProcessor();
            // Create and store closure
            factoryMethodProcessor.Emit(OpCodes.Newobj, closureTypeConstructor.MakeGeneric(genericParameters));
            factoryMethodProcessor.Emit(OpCodes.Stloc_0);
            //// Return closure
            factoryMethodProcessor.Emit(OpCodes.Ldloc_0);
            factoryMethodProcessor.Emit(OpCodes.Ret);

            // Create pool field
            var poolField = new FieldDefinition("<pool>", FieldAttributes.Public | FieldAttributes.Static, poolType.MakeGenericType(closureGenericType));
            closureType.Fields.Add(poolField);
            var poolFieldReference = poolField.MakeGeneric(genericParameters);

            // Initialize pool
            var cctor = GetOrCreateClassConstructor(closureType);
            var ilProcessor2 = cctor.Body.GetILProcessor();
            var retInstruction = cctor.Body.Instructions.FirstOrDefault(x => x.OpCode == OpCodes.Ret);
            ilProcessor2.InsertBefore(retInstruction, ilProcessor2.Create(OpCodes.Ldnull));
            ilProcessor2.InsertBefore(retInstruction, ilProcessor2.Create(OpCodes.Ldftn, factoryMethod.MakeGeneric(genericParameters)));
            ilProcessor2.InsertBefore(retInstruction, ilProcessor2.Create(OpCodes.Newobj, funcConstructor.MakeGeneric(closureGenericType)));
            ilProcessor2.InsertBefore(retInstruction, ilProcessor2.Create(OpCodes.Newobj, poolConstructor.MakeGeneric(closureGenericType)));
            ilProcessor2.InsertBefore(retInstruction, ilProcessor2.Create(OpCodes.Stsfld, poolFieldReference));

            // Implement IPooledClosure
            closureType.Interfaces.Add(pooledClosureType);

            // Create reference count field
            var countField = new FieldDefinition("<referenceCount>", FieldAttributes.Public, context.Assembly.MainModule.TypeSystem.Int32);
            closureType.Fields.Add(countField);
            var oountFieldReference = countField.MakeGeneric(genericParameters);

            // Create AddReference method
            var addReferenceMethod = new MethodDefinition("AddReference", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual | MethodAttributes.NewSlot, context.Assembly.MainModule.TypeSystem.Void);
            var ilProcessor4 = addReferenceMethod.Body.GetILProcessor();
            ilProcessor4.Emit(OpCodes.Ldarg_0);
            ilProcessor4.Emit(OpCodes.Ldflda, oountFieldReference);
            ilProcessor4.Emit(OpCodes.Call, interlockedIncrementMethod);
            ilProcessor4.Emit(OpCodes.Pop);
            ilProcessor4.Emit(OpCodes.Ret);
            closureType.Methods.Add(addReferenceMethod);

            // Create Release method
            var releaseMethod = new MethodDefinition("Release", MethodAttributes.HideBySig | MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual | MethodAttributes.NewSlot, context.Assembly.MainModule.TypeSystem.Void);
            ilProcessor4 = releaseMethod.Body.GetILProcessor();
            retInstruction = ilProcessor4.Create(OpCodes.Ret);
            // Check decremented reference count
            ilProcessor4.Emit(OpCodes.Ldarg_0);
            ilProcessor4.Emit(OpCodes.Ldflda, oountFieldReference);
            ilProcessor4.Emit(OpCodes.Call, interlockedDecrementMethod);
            ilProcessor4.Emit(OpCodes.Ldc_I4_0);
            ilProcessor4.Emit(OpCodes.Ceq);
            ilProcessor4.Emit(OpCodes.Brfalse_S, retInstruction);
            // Release this to pool
            ilProcessor4.Emit(OpCodes.Ldsfld, poolFieldReference);
            ilProcessor4.Emit(OpCodes.Ldarg_0);
            ilProcessor4.Emit(OpCodes.Callvirt, poolReleaseMethod.MakeGeneric(closureGenericType));
            ilProcessor4.Append(retInstruction);
            closureType.Methods.Add(releaseMethod);

            closures.Add(closureType, closure = new ClosureInfo
            {
                FactoryMethod = factoryMethod,
                AddReferenceMethod = addReferenceMethod,
                ReleaseMethod = releaseMethod,
                PoolField = poolField
            });

            return closure;
        }
开发者ID:Kryptos-FR,项目名称:xenko-reloaded,代码行数:83,代码来源:DispatcherProcessor.cs

示例3: Process

        public bool Process(AssemblyProcessorContext context)
        {
            var assembly = context.Assembly;
            var mscorlibAssembly = CecilExtensions.FindCorlibAssembly(assembly);
            if (mscorlibAssembly == null)
                throw new InvalidOperationException("Missing mscorlib.dll from assembly");

            // For now, use import, but this can cause mixed framework versions when processing an assembly with a different framework version.
            voidType = assembly.MainModule.TypeSystem.Void;
            stringType = assembly.MainModule.TypeSystem.String;
            objectType = assembly.MainModule.TypeSystem.Object;
            var propertyInfoType = assembly.MainModule.ImportReference(mscorlibAssembly.MainModule.GetTypeResolved(typeof(PropertyInfo).FullName));
            var typeType = mscorlibAssembly.MainModule.GetTypeResolved(typeof(Type).FullName);


            TypeDefinition propertyChangedExtendedEventArgsType;

            AssemblyDefinition siliconStudioCoreAssembly;
            try
            {
                siliconStudioCoreAssembly = assembly.Name.Name == "SiliconStudio.Core"
                    ? assembly
                    : context.AssemblyResolver.Resolve("SiliconStudio.Core");

            }
            catch (Exception)
            {
                return true;
            }

            propertyChangedExtendedEventArgsType = siliconStudioCoreAssembly.MainModule.GetTypes().First(x => x.Name == "PropertyChangedExtendedEventArgs").Resolve();

            var typeTokenInfoEx = mscorlibAssembly.MainModule.GetType("System.Reflection.TypeInfo").Resolve();
            var getPropertyMethod = typeTokenInfoEx.Methods.First(x => x.Name == "GetDeclaredProperty" && x.Parameters.Count == 1);
            var getTypeFromHandleMethod = typeType.Methods.First(x => x.Name == "GetTypeFromHandle");
            var getTokenInfoExMethod = mscorlibAssembly.MainModule.GetType("System.Reflection.IntrospectionExtensions").Resolve().Methods.First(x => x.Name == "GetTypeInfo");
            
            var propertyChangedExtendedEventArgsConstructor = assembly.MainModule.ImportReference(propertyChangedExtendedEventArgsType.Methods.First(x => x.IsConstructor));

            bool modified = false;

            foreach (var type in assembly.MainModule.GetTypes())
            {
                MethodReference getPropertyChangedMethod;

                getPropertyChangedMethod = GetGetPropertyChangedMethod(assembly, type);
                //var propertyChangedField = GetPropertyChangedField(type);
                //if (propertyChangedField == null)
                //    continue;

                var propertyChangedField = GetPropertyChangedField(type);

                if (getPropertyChangedMethod == null && propertyChangedField == null)
                    continue;

                TypeReference propertyChangedFieldType;

                if (getPropertyChangedMethod == null)
                {
                    modified = true;
                    getPropertyChangedMethod = GetOrCreateGetPropertyChangedMethod(assembly, type, propertyChangedField);
                }

                if (propertyChangedField != null)
                {
                    propertyChangedField = assembly.MainModule.ImportReference(propertyChangedField);
                    propertyChangedFieldType = propertyChangedField.FieldType;
                }
                else
                {
                    propertyChangedFieldType = getPropertyChangedMethod.ReturnType;
                }

                // Add generic to declaring type
                if (getPropertyChangedMethod.DeclaringType.HasGenericParameters)
                    getPropertyChangedMethod = getPropertyChangedMethod.MakeGeneric(getPropertyChangedMethod.DeclaringType.GenericParameters.ToArray());

                var propertyChangedInvoke = assembly.MainModule.ImportReference(propertyChangedFieldType.Resolve().Methods.First(x => x.Name == "Invoke"));

                foreach (var property in type.Properties)
                {
                    if (property.SetMethod == null || !property.HasThis)
                        continue;

                    MethodReference propertyGetMethod = property.GetMethod;

                    // Only patch properties that have a public Getter
                    var methodDefinition = propertyGetMethod.Resolve();
                    if ((methodDefinition.Attributes & MethodAttributes.Public) != MethodAttributes.Public)
                    {
                        continue;
                    }

                    // Add generic to declaring type
                    if (propertyGetMethod.DeclaringType.HasGenericParameters)
                        propertyGetMethod = propertyGetMethod.MakeGeneric(propertyGetMethod.DeclaringType.GenericParameters.ToArray());

                    //var versionableAttribute = property.CustomAttributes.FirstOrDefault(x => x.AttributeType.FullName == typeof(VersionableAttribute).FullName);
                    //if (versionableAttribute == null)
                    //    continue;
//.........这里部分代码省略.........
开发者ID:h78hy78yhoi8j,项目名称:xenko,代码行数:101,代码来源:NotifyPropertyProcessor.cs


注:本文中的Mono.Cecil.FieldDefinition.MakeGeneric方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。