private void EmitMethodCallInterception(ILProcessor il, MethodReference targetMethod, MethodDefinition callingMethod, ModuleDefinition module,
                                                Instruction skipInterception)
        {
            il.Emit(OpCodes.Ldloc, _callMap);

            il.PushMethod(targetMethod, module);

            il.Emit(OpCodes.Callvirt, _getMethodCall);


            il.Emit(OpCodes.Stloc, _currentMethodCall);

            il.Emit(OpCodes.Ldloc, _currentMethodCall);
            il.Emit(OpCodes.Brfalse, skipInterception);

            // if (currentMethodCall != null) {

            // var returnValue = currentMethodCall.Invoke(methodCallInvocationInfo);

            // Resolve the return type if the target method's declaring type is a generic type
            var returnType = targetMethod.GetReturnType();

            SaveMethodCallInvocationInfo(il, targetMethod, callingMethod, module);

            il.Emit(OpCodes.Ldloc, _currentMethodCall);
            il.Emit(OpCodes.Ldloc, _invocationInfo);
            il.Emit(OpCodes.Callvirt, _invokeMethod);

            il.PackageReturnValue(module, returnType);
        }
        static public void EmitInvoke(TypeEmitter declaringType, MethodReference targetMethod)
        {
            var definition = new FunctorMethodEmitter(declaringType, "Invoke", targetMethod.GetReturnType(),
                                                      MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig);

            definition.EmitInvokeBody(targetMethod);
        }
Пример #3
0
        static bool MethodMatch(MethodReference candidate, MethodDefinition method)
        {
            var candidateDef = candidate.Resolve();

            if (!candidateDef.IsVirtual)
            {
                return(false);
            }

            if (candidate.HasParameters != method.HasParameters)
            {
                return(false);
            }

            if (candidate.Name != method.Name)
            {
                return(false);
            }

            if (candidate.HasGenericParameters != method.HasGenericParameters)
            {
                return(false);
            }

            // we need to track what the generic parameter represent - as we cannot allow it to
            // differ between the return type or any parameter
            if (!TypeMatch(candidate.GetReturnType(), method.GetReturnType()))
            {
                return(false);
            }

            if (!candidate.HasParameters)
            {
                return(true);
            }

            var cp = candidate.Parameters;
            var mp = method.Parameters;

            if (cp.Count != mp.Count)
            {
                return(false);
            }

            if (candidate.GenericParameters.Count != method.GenericParameters.Count)
            {
                return(false);
            }

            for (int i = 0; i < cp.Count; i++)
            {
                if (!TypeMatch(candidate.GetParameterType(i), method.GetParameterType(i)))
                {
                    return(false);
                }
            }

            return(true);
        }
        public static TypeReference GetFunctorType(AssemblyEmitter assembly, MethodReference containedMethod)
        {
            var parameters = containedMethod.GetParameterTypes();

            return(GetFunctorType(assembly, containedMethod.GetReturnType(), parameters));
        }