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


C# ILProcessor.Clone方法代码示例

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


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

示例1: ImplementBody

            protected override void ImplementBody(ILProcessor il, FieldReference methodInfoField, FieldReference propertyInfoField, MethodReference proceed, MethodReference proceedTargetMethod)
            {
                // If it's abstract, then the method is entirely implemented by the InvocationHandler
                if (Method.IsAbstract)
                {
                    base.ImplementBody(il, methodInfoField, propertyInfoField, proceed, proceedTargetMethod);
                }
                // Otherwise, it is implemented by the class itself, and calling this.Invocation().Proceed() calls the InvocationHandler
                else
                {
                    Method.Body.InitLocals = true;

                    // First declare the invocation in a private local variable
                    var invocation = new VariableDefinition(ClassWeaver.Context.InvocationType);
                    var instructions = Method.Body.Instructions.ToList();
                    Method.Body.Instructions.Clear();                   // Wipe out the existing instructions for the method
                    Method.Body.Variables.Add(invocation);              // Add a variable to store the invocation
                    EmitInvocation(il, methodInfoField, propertyInfoField, proceed);       // Put the invocation on the stack
                    il.Emit(OpCodes.Dup);                               // Duplicate invocation for below
                    il.Emit(OpCodes.Stloc, invocation);                 // Store the invocation in the variable declared (just) earlier

                    // Add the invocation to the end of the array
                    il.Emit(OpCodes.Call, ClassWeaver.Context.InvocationGetArguments);  // Array now on the stack with the invocation above it
                    il.Emit(OpCodes.Ldc_I4, Method.Parameters.Count);       // Array index
                    il.Emit(OpCodes.Ldloc, invocation);                     // Element value
                    il.Emit(OpCodes.Stelem_Any, ClassWeaver.Context.ModuleDefinition.TypeSystem.Object);  // Set array at index to element value

                    // Special instrumentation for async methods
                    var returnType = Method.ReturnType;
                    if (ClassWeaver.Context.TaskType.IsAssignableFrom(returnType))
                    {
                        // If the return type is Task<T>
                        if (returnType.IsTaskT())
                        {
                            var actualReturnType = returnType.GetTaskType();
                            var expectedAsyncBuilder = ClassWeaver.Context.AsyncTaskMethodBuilder.MakeGenericInstanceType(actualReturnType);

                            // Now find the call to .Start() (only will be found if we're async)
                            var startInstructionMethod = (GenericInstanceMethod)instructions
                                .Where(x => x.OpCode == OpCodes.Call)
                                .Select(x => (MethodReference)x.Operand)
                                .Where(x => x.IsGenericInstance && x.Name == "Start" && x.DeclaringType.CompareTo(expectedAsyncBuilder))
                                .SingleOrDefault();
                            if (startInstructionMethod != null)
                            {
                                var asyncType = startInstructionMethod.GenericArguments[0];
                                var invocationField = InstrumentAsyncType(asyncType);

                                // Find the first instruction that is setting a field on the async type.  We can just assume it's a three instruction 
                                // set (it always is in this context)  And we add our instructions to set the invocation field.
                                var nextSetFieldIndex = instructions.IndexOf(x => x.OpCode == OpCodes.Stfld && x.Operand is FieldDefinition && ((FieldDefinition)x.Operand).DeclaringType.CompareTo(asyncType));
                                if (nextSetFieldIndex == -1)
                                    throw new Exception($"Could not find expected stfld of async type: {asyncType}");
                                var setFieldLoadInstance = instructions[nextSetFieldIndex - 2];
                                instructions.Insert(nextSetFieldIndex - 2, il.Clone(setFieldLoadInstance));
                                instructions.Insert(nextSetFieldIndex - 1, il.Create(OpCodes.Ldloc, invocation));
                                instructions.Insert(nextSetFieldIndex, il.Create(OpCodes.Stfld, invocationField));
                            }
                        }
                    }

                    InstrumentInstructions(il, instructions, 2, x => x.Emit(OpCodes.Ldloc, invocation));
                }
            }
开发者ID:kswoll,项目名称:sexy-proxy,代码行数:64,代码来源:ReverseProxyClassWeaver.cs


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