//============================================================================================== // Non-public methods //============================================================================================== internal MethodInvoker GetMethodInvoker(RuntimeTypeInfo declaringType, QMethodDefinition methodHandle, RuntimeTypeInfo[] genericMethodTypeArguments, MemberInfo exceptionPertainant) { if (declaringType.ContainsGenericParameters) { return(new OpenMethodInvoker()); } for (int i = 0; i < genericMethodTypeArguments.Length; i++) { if (genericMethodTypeArguments[i].ContainsGenericParameters) { return(new OpenMethodInvoker()); } } RuntimeTypeHandle typeDefinitionHandle = declaringType.TypeHandle; RuntimeTypeHandle[] genericMethodTypeArgumentHandles = new RuntimeTypeHandle[genericMethodTypeArguments.Length]; for (int i = 0; i < genericMethodTypeArguments.Length; i++) { genericMethodTypeArgumentHandles[i] = genericMethodTypeArguments[i].TypeHandle; } MethodInvoker methodInvoker = TryGetMethodInvoker(typeDefinitionHandle, methodHandle, genericMethodTypeArgumentHandles); if (methodInvoker == null) { throw ReflectionCoreExecution.ExecutionDomain.CreateNonInvokabilityException(exceptionPertainant); } return(methodInvoker); }
public MethodSignatureComparer( QMethodDefinition methodHandle) { if (methodHandle.IsNativeFormatMetadataBased) { _metadataReader = methodHandle.NativeFormatReader; _methodHandle = methodHandle.NativeFormatHandle; _method = _methodHandle.GetMethod(_metadataReader); _methodSignature = _method.Signature.GetMethodSignature(_metadataReader); _isGeneric = (_methodSignature.GenericParameterCount != 0); // Precalculate initial method attributes used in signature queries _isStatic = (_method.Flags & MethodAttributes.Static) != 0; } else { _metadataReader = null; _methodHandle = default(MethodHandle); _method = default(Method); _methodSignature = default(MethodSignature); _isGeneric = false; _isStatic = false; } }
// // Retrieves the MethodBase for a given method handle. Helper to implement Delegate.GetMethodInfo() // public MethodBase GetMethod(RuntimeTypeHandle declaringTypeHandle, QMethodDefinition methodHandle, RuntimeTypeHandle[] genericMethodTypeArgumentHandles) { RuntimeTypeInfo contextTypeInfo = declaringTypeHandle.GetTypeForRuntimeTypeHandle(); RuntimeNamedMethodInfo?runtimeNamedMethodInfo = null; if (methodHandle.IsNativeFormatMetadataBased) { MethodHandle nativeFormatMethodHandle = methodHandle.NativeFormatHandle; NativeFormatRuntimeNamedTypeInfo definingTypeInfo = contextTypeInfo.AnchoringTypeDefinitionForDeclaredMembers.CastToNativeFormatRuntimeNamedTypeInfo(); MetadataReader reader = definingTypeInfo.Reader; if (nativeFormatMethodHandle.IsConstructor(reader)) { return(RuntimePlainConstructorInfo <NativeFormatMethodCommon> .GetRuntimePlainConstructorInfo(new NativeFormatMethodCommon(nativeFormatMethodHandle, definingTypeInfo, contextTypeInfo))); } else { // RuntimeMethodHandles always yield methods whose ReflectedType is the DeclaringType. RuntimeTypeInfo reflectedType = contextTypeInfo; runtimeNamedMethodInfo = RuntimeNamedMethodInfo <NativeFormatMethodCommon> .GetRuntimeNamedMethodInfo(new NativeFormatMethodCommon(nativeFormatMethodHandle, definingTypeInfo, contextTypeInfo), reflectedType); } } #if ECMA_METADATA_SUPPORT else { System.Reflection.Metadata.MethodDefinitionHandle ecmaFormatMethodHandle = methodHandle.EcmaFormatHandle; EcmaFormatRuntimeNamedTypeInfo definingEcmaTypeInfo = contextTypeInfo.AnchoringTypeDefinitionForDeclaredMembers.CastToEcmaFormatRuntimeNamedTypeInfo(); System.Reflection.Metadata.MetadataReader reader = definingEcmaTypeInfo.Reader; if (ecmaFormatMethodHandle.IsConstructor(reader)) { return(RuntimePlainConstructorInfo <EcmaFormatMethodCommon> .GetRuntimePlainConstructorInfo(new EcmaFormatMethodCommon(ecmaFormatMethodHandle, definingEcmaTypeInfo, contextTypeInfo))); } else { // RuntimeMethodHandles always yield methods whose ReflectedType is the DeclaringType. RuntimeTypeInfo reflectedType = contextTypeInfo; runtimeNamedMethodInfo = RuntimeNamedMethodInfo <EcmaFormatMethodCommon> .GetRuntimeNamedMethodInfo(new EcmaFormatMethodCommon(ecmaFormatMethodHandle, definingEcmaTypeInfo, contextTypeInfo), reflectedType); } } #endif if (!runtimeNamedMethodInfo.IsGenericMethod || genericMethodTypeArgumentHandles == null) { return(runtimeNamedMethodInfo); } else { RuntimeTypeInfo[] genericTypeArguments = new RuntimeTypeInfo[genericMethodTypeArgumentHandles.Length]; for (int i = 0; i < genericMethodTypeArgumentHandles.Length; i++) { genericTypeArguments[i] = genericMethodTypeArgumentHandles[i].GetTypeForRuntimeTypeHandle(); } return(RuntimeConstructedGenericMethodInfo.GetRuntimeConstructedGenericMethodInfo(runtimeNamedMethodInfo, genericTypeArguments)); } }
public static int Main(string[] args) { MetadataReader r = new MetadataReader(); if (foo(QMethodDefinition.FromObjectAndInt(r, 1)) == null) { Console.WriteLine("FAIL"); return(-1); } Console.WriteLine("PASS"); return(100); }
public abstract bool TryGetMethodFromHandleAndType(RuntimeMethodHandle runtimeMethodHandle, RuntimeTypeHandle declaringTypeHandle, out QMethodDefinition methodHandle, out RuntimeTypeHandle[] genericMethodTypeArgumentHandles);
//============================================================================================== // Invoke and field access support. //============================================================================================== public abstract MethodInvoker TryGetMethodInvoker(RuntimeTypeHandle declaringTypeHandle, QMethodDefinition methodHandle, RuntimeTypeHandle[] genericMethodTypeArgumentHandles);
public static MethodInfo GetDelegateMethodInfo(Delegate del) { if (del == null) { throw new ArgumentException(); } Delegate[] invokeList = del.GetInvocationList(); del = invokeList[invokeList.Length - 1]; IntPtr originalLdFtnResult = RuntimeAugments.GetDelegateLdFtnResult(del, out RuntimeTypeHandle typeOfFirstParameterIfInstanceDelegate, out bool isOpenResolver, out bool isInterpreterEntrypoint); if (isInterpreterEntrypoint) { // This is a special kind of delegate where the invoke method is "ObjectArrayThunk". Typically, // this will be a delegate that points the the LINQ Expression interpreter. We could manufacture // a MethodInfo based on the delegate's Invoke signature, but let's just throw for now. throw new PlatformNotSupportedException(SR.DelegateGetMethodInfo_ObjectArrayDelegate); } if (originalLdFtnResult == (IntPtr)0) { return(null); } QMethodDefinition methodHandle = default(QMethodDefinition); RuntimeTypeHandle[] genericMethodTypeArgumentHandles = null; bool callTryGetMethod = true; unsafe { if (isOpenResolver) { OpenMethodResolver *resolver = (OpenMethodResolver *)originalLdFtnResult; if (resolver->IsOpenNonVirtualResolve) { originalLdFtnResult = resolver->CodePointer; // And go on to do normal ldftn processing. } else if (resolver->ResolverType == OpenMethodResolver.DispatchResolve) { callTryGetMethod = false; methodHandle = QMethodDefinition.FromObjectAndInt(resolver->Reader, resolver->Handle); genericMethodTypeArgumentHandles = null; } else { System.Diagnostics.Debug.Assert(resolver->ResolverType == OpenMethodResolver.GVMResolve); callTryGetMethod = false; methodHandle = QMethodDefinition.FromObjectAndInt(resolver->Reader, resolver->Handle); RuntimeTypeHandle declaringTypeHandleIgnored; MethodNameAndSignature nameAndSignatureIgnored; if (!TypeLoaderEnvironment.Instance.TryGetRuntimeMethodHandleComponents(resolver->GVMMethodHandle, out declaringTypeHandleIgnored, out nameAndSignatureIgnored, out genericMethodTypeArgumentHandles)) { throw new MissingRuntimeArtifactException(SR.DelegateGetMethodInfo_NoInstantiation); } } } } if (callTryGetMethod) { if (!ReflectionExecution.ExecutionEnvironment.TryGetMethodForOriginalLdFtnResult(originalLdFtnResult, ref typeOfFirstParameterIfInstanceDelegate, out methodHandle, out genericMethodTypeArgumentHandles)) { ReflectionExecution.ExecutionEnvironment.GetFunctionPointerAndInstantiationArgumentForOriginalLdFtnResult(originalLdFtnResult, out IntPtr ip, out IntPtr _); string methodDisplayString = RuntimeAugments.TryGetMethodDisplayStringFromIp(ip); if (methodDisplayString == null) { throw new MissingRuntimeArtifactException(SR.DelegateGetMethodInfo_NoDynamic); } else { throw new MissingRuntimeArtifactException(SR.Format(SR.DelegateGetMethodInfo_NoDynamic_WithDisplayString, methodDisplayString)); } } } MethodBase methodBase = ReflectionCoreExecution.ExecutionDomain.GetMethod(typeOfFirstParameterIfInstanceDelegate, methodHandle, genericMethodTypeArgumentHandles); MethodInfo methodInfo = methodBase as MethodInfo; if (methodInfo != null) { return(methodInfo); } return(null); // GetMethod() returned a ConstructorInfo. }
// // Creates the appropriate flavor of Invoker depending on the calling convention "shape" (static, instance or virtual.) // internal static MethodInvoker CreateMethodInvoker(RuntimeTypeHandle declaringTypeHandle, QMethodDefinition methodHandle, MethodInvokeInfo methodInvokeInfo) { bool isStatic = false; if (methodHandle.IsNativeFormatMetadataBased) { Method method = methodHandle.NativeFormatHandle.GetMethod(methodHandle.NativeFormatReader); MethodAttributes methodAttributes = method.Flags; if (0 != (methodAttributes & MethodAttributes.Static)) { isStatic = true; } } #if ECMA_METADATA_SUPPORT if (methodHandle.IsEcmaFormatMetadataBased) { var reader = methodHandle.EcmaFormatReader; var method = reader.GetMethodDefinition(methodHandle.EcmaFormatHandle); var blobReader = reader.GetBlobReader(method.Signature); byte sigByte = blobReader.ReadByte(); if ((sigByte & (byte)System.Reflection.Metadata.SignatureAttributes.Instance) == 0) { isStatic = true; } } #endif if (isStatic) { return(new StaticMethodInvoker(methodInvokeInfo)); } else if (methodInvokeInfo.VirtualResolveData != IntPtr.Zero) { return(new VirtualMethodInvoker(methodInvokeInfo, declaringTypeHandle)); } else { return(new InstanceMethodInvoker(methodInvokeInfo, declaringTypeHandle)); } }
static object foo(QMethodDefinition methodHandle) { Method method = methodHandle.NativeFormatHandle.GetMethod(methodHandle.NativeFormatReader); return((method.Flags != (MethodAttributes)0) ? new object() : null); }
public static MethodInfo GetDelegateMethodInfo(Delegate del) { if (del == null) { throw new ArgumentException(); } Delegate[] invokeList = del.GetInvocationList(); del = invokeList[invokeList.Length - 1]; RuntimeTypeHandle typeOfFirstParameterIfInstanceDelegate; bool isOpenResolver; IntPtr originalLdFtnResult = RuntimeAugments.GetDelegateLdFtnResult(del, out typeOfFirstParameterIfInstanceDelegate, out isOpenResolver); if (originalLdFtnResult == (IntPtr)0) { return(null); } QMethodDefinition methodHandle = default(QMethodDefinition); RuntimeTypeHandle[] genericMethodTypeArgumentHandles = null; bool callTryGetMethod = true; unsafe { if (isOpenResolver) { OpenMethodResolver *resolver = (OpenMethodResolver *)originalLdFtnResult; if (resolver->ResolverType == OpenMethodResolver.OpenNonVirtualResolve) { originalLdFtnResult = resolver->CodePointer; // And go on to do normal ldftn processing. } else if (resolver->ResolverType == OpenMethodResolver.DispatchResolve) { callTryGetMethod = false; methodHandle = QMethodDefinition.FromObjectAndInt(resolver->Reader, resolver->Handle); genericMethodTypeArgumentHandles = null; } else { System.Diagnostics.Debug.Assert(resolver->ResolverType == OpenMethodResolver.GVMResolve); callTryGetMethod = false; methodHandle = QMethodDefinition.FromObjectAndInt(resolver->Reader, resolver->Handle); RuntimeTypeHandle declaringTypeHandleIgnored; MethodNameAndSignature nameAndSignatureIgnored; if (!TypeLoaderEnvironment.Instance.TryGetRuntimeMethodHandleComponents(resolver->GVMMethodHandle, out declaringTypeHandleIgnored, out nameAndSignatureIgnored, out genericMethodTypeArgumentHandles)) { return(null); } } } } if (callTryGetMethod) { if (!ReflectionExecution.ExecutionEnvironment.TryGetMethodForOriginalLdFtnResult(originalLdFtnResult, ref typeOfFirstParameterIfInstanceDelegate, out methodHandle, out genericMethodTypeArgumentHandles)) { return(null); } } MethodBase methodBase = ReflectionCoreExecution.ExecutionDomain.GetMethod(typeOfFirstParameterIfInstanceDelegate, methodHandle, genericMethodTypeArgumentHandles); MethodInfo methodInfo = methodBase as MethodInfo; if (methodInfo != null) { return(methodInfo); } return(null); // GetMethod() returned a ConstructorInfo. }