/// <summary> /// Create a runtime method handle from name, signature and generic arguments. If the methodSignature /// is constructed from a metadata token, the methodName should be IntPtr.Zero, as it already encodes the method /// name. /// </summary> public unsafe RuntimeMethodHandle GetRuntimeMethodHandleForComponents(RuntimeTypeHandle declaringTypeHandle, IntPtr methodName, RuntimeSignature methodSignature, RuntimeTypeHandle[] genericMethodArgs) { // TODO! Consider interning these!, but if we do remember this function is called from code which isn't under the type builder lock int sizeToAllocate = sizeof(DynamicMethodHandleInfo); // Use checked arithmetics to ensure there aren't any overflows/truncations sizeToAllocate = checked (sizeToAllocate + (genericMethodArgs.Length > 0 ? sizeof(IntPtr) * (genericMethodArgs.Length - 1) : 0)); IntPtr runtimeMethodHandleValue = MemoryHelpers.AllocateMemory(sizeToAllocate); if (runtimeMethodHandleValue == IntPtr.Zero) { throw new OutOfMemoryException(); } DynamicMethodHandleInfo *methodData = (DynamicMethodHandleInfo *)runtimeMethodHandleValue.ToPointer(); methodData->DeclaringType = *(IntPtr *)&declaringTypeHandle; methodData->MethodName = methodName; methodData->MethodSignature = methodSignature; methodData->NumGenericArgs = genericMethodArgs.Length; IntPtr *genericArgPtr = &(methodData->GenericArgsArray); for (int i = 0; i < genericMethodArgs.Length; i++) { RuntimeTypeHandle currentArg = genericMethodArgs[i]; genericArgPtr[i] = *(IntPtr *)¤tArg; } // Special flag in the handle value to indicate it was dynamically allocated, and doesn't point into the InvokeMap blob runtimeMethodHandleValue = runtimeMethodHandleValue + 1; return(*(RuntimeMethodHandle *)&runtimeMethodHandleValue); }
/// <summary> /// Create a runtime method handle from name, signature and generic arguments. If the methodSignature /// is constructed from a metadata token, the methodName should be IntPtr.Zero, as it already encodes the method /// name. /// </summary> internal unsafe IntPtr TryGetRuntimeMethodHandleForComponents(RuntimeTypeHandle declaringTypeHandle, IntPtr methodName, RuntimeMethodSignature methodSignature, RuntimeTypeHandle[] genericMethodArgs) { int sizeToAllocate = sizeof(DynamicMethodHandleInfo); // Use checked arithmetics to ensure there aren't any overflows/truncations sizeToAllocate = checked (sizeToAllocate + (genericMethodArgs.Length > 0 ? sizeof(IntPtr) * (genericMethodArgs.Length - 1) : 0)); IntPtr runtimeMethodHandleValue = MemoryHelpers.AllocateMemory(sizeToAllocate); DynamicMethodHandleInfo *methodData = (DynamicMethodHandleInfo *)runtimeMethodHandleValue.ToPointer(); methodData->DeclaringType = *(IntPtr *)&declaringTypeHandle; methodData->MethodName = methodName; methodData->MethodSignature = methodSignature; methodData->NumGenericArgs = genericMethodArgs.Length; IntPtr *genericArgPtr = &(methodData->GenericArgsArray); for (int i = 0; i < genericMethodArgs.Length; i++) { RuntimeTypeHandle currentArg = genericMethodArgs[i]; genericArgPtr[i] = *(IntPtr *)¤tArg; } // Special flag in the handle value to indicate it was dynamically allocated, and doesn't point into the InvokeMap blob return(runtimeMethodHandleValue + 1); }
private unsafe bool TryGetDynamicRuntimeMethodHandleComponents(RuntimeMethodHandle runtimeMethodHandle, out RuntimeTypeHandle declaringTypeHandle, out MethodNameAndSignature nameAndSignature, out RuntimeTypeHandle[] genericMethodArgs) { IntPtr runtimeMethodHandleValue = *(IntPtr *)&runtimeMethodHandle; Debug.Assert((runtimeMethodHandleValue.ToInt64() & 0x1) == 0x1); // Special flag in the handle value to indicate it was dynamically allocated, and doesn't point into the InvokeMap blob runtimeMethodHandleValue = runtimeMethodHandleValue - 1; DynamicMethodHandleInfo *methodData = (DynamicMethodHandleInfo *)runtimeMethodHandleValue.ToPointer(); declaringTypeHandle = *(RuntimeTypeHandle *)&(methodData->DeclaringType); genericMethodArgs = Empty <RuntimeTypeHandle> .Array; if (methodData->NumGenericArgs > 0) { IntPtr *genericArgPtr = &(methodData->GenericArgsArray); genericMethodArgs = new RuntimeTypeHandle[methodData->NumGenericArgs]; for (int i = 0; i < methodData->NumGenericArgs; i++) { genericMethodArgs[i] = *(RuntimeTypeHandle *)&(genericArgPtr[i]); } } if (methodData->MethodSignature.IsNativeLayoutSignature) { // MethodName points to the method name in NativeLayout format, so we parse it using a NativeParser IntPtr methodNamePtr = methodData->MethodName; string name = GetStringFromMemoryInNativeFormat(methodNamePtr); nameAndSignature = new MethodNameAndSignature(name, methodData->MethodSignature); } else { // method signature is NativeFormat var metadataReader = ModuleList.Instance.GetMetadataReaderForModule(methodData->MethodSignature.ModuleHandle); var methodHandle = methodData->MethodSignature.Token.AsHandle().ToMethodHandle(metadataReader); var method = methodHandle.GetMethod(metadataReader); nameAndSignature = new MethodNameAndSignature(metadataReader.GetConstantStringValue(method.Name).Value, methodData->MethodSignature); } return(true); }
/// <summary> /// Create a runtime method handle from name, signature and generic arguments. If the methodSignature /// is constructed from a metadata token, the methodName should be IntPtr.Zero, as it already encodes the method /// name. /// </summary> public unsafe RuntimeMethodHandle GetRuntimeMethodHandleForComponents(RuntimeTypeHandle declaringTypeHandle, IntPtr methodName, RuntimeSignature methodSignature, RuntimeTypeHandle[] genericMethodArgs) { string methodNameStr = methodName == IntPtr.Zero ? null : GetStringFromMemoryInNativeFormat(methodName); RuntimeMethodHandleKey key = new RuntimeMethodHandleKey(declaringTypeHandle, methodNameStr, methodSignature, genericMethodArgs); RuntimeMethodHandle runtimeMethodHandle = default(RuntimeMethodHandle); lock (_runtimeMethodHandles) { if (!_runtimeMethodHandles.TryGetValue(key, out runtimeMethodHandle)) { int sizeToAllocate = sizeof(DynamicMethodHandleInfo); int numGenericMethodArgs = genericMethodArgs == null ? 0 : genericMethodArgs.Length; // Use checked arithmetics to ensure there aren't any overflows/truncations sizeToAllocate = checked (sizeToAllocate + (numGenericMethodArgs > 0 ? sizeof(IntPtr) * (numGenericMethodArgs - 1) : 0)); IntPtr runtimeMethodHandleValue = MemoryHelpers.AllocateMemory(sizeToAllocate); if (runtimeMethodHandleValue == IntPtr.Zero) { throw new OutOfMemoryException(); } DynamicMethodHandleInfo *methodData = (DynamicMethodHandleInfo *)runtimeMethodHandleValue.ToPointer(); methodData->DeclaringType = *(IntPtr *)&declaringTypeHandle; methodData->MethodName = methodName; methodData->MethodSignature = methodSignature; methodData->NumGenericArgs = numGenericMethodArgs; IntPtr *genericArgPtr = &(methodData->GenericArgsArray); for (int i = 0; i < numGenericMethodArgs; i++) { RuntimeTypeHandle currentArg = genericMethodArgs[i]; genericArgPtr[i] = *(IntPtr *)¤tArg; } // Special flag in the handle value to indicate it was dynamically allocated, and doesn't point into the InvokeMap blob runtimeMethodHandleValue = runtimeMethodHandleValue + 1; runtimeMethodHandle = *(RuntimeMethodHandle *)&runtimeMethodHandleValue; _runtimeMethodHandles.Add(key, runtimeMethodHandle); } return(runtimeMethodHandle); } }
private unsafe bool TryGetDynamicRuntimeMethodHandleComponents(RuntimeMethodHandle runtimeMethodHandle, out RuntimeTypeHandle declaringTypeHandle, out MethodNameAndSignature nameAndSignature, out RuntimeTypeHandle[] genericMethodArgs) { IntPtr runtimeMethodHandleValue = *(IntPtr *)&runtimeMethodHandle; Debug.Assert((runtimeMethodHandleValue.ToInt64() & 0x1) == 0x1); // Special flag in the handle value to indicate it was dynamically allocated, and doesn't point into the InvokeMap blob runtimeMethodHandleValue = runtimeMethodHandleValue - 1; DynamicMethodHandleInfo *methodData = (DynamicMethodHandleInfo *)runtimeMethodHandleValue.ToPointer(); declaringTypeHandle = *(RuntimeTypeHandle *)&(methodData->DeclaringType); genericMethodArgs = null; if (methodData->NumGenericArgs > 0) { IntPtr *genericArgPtr = &(methodData->GenericArgsArray); genericMethodArgs = new RuntimeTypeHandle[methodData->NumGenericArgs]; for (int i = 0; i < methodData->NumGenericArgs; i++) { genericMethodArgs[i] = *(RuntimeTypeHandle *)&(genericArgPtr[i]); } } if (methodData->MethodSignature.IsNativeLayoutSignature) { // MethodName points to the method name in NativeLayout format, so we parse it using a NativeParser IntPtr methodNamePtr = methodData->MethodName; string name = GetStringFromMemoryInNativeFormat(methodNamePtr); nameAndSignature = new MethodNameAndSignature(name, methodData->MethodSignature); } else { ModuleInfo moduleInfo = methodData->MethodSignature.GetModuleInfo(); string name; #if ECMA_METADATA_SUPPORT if (moduleInfo is NativeFormatModuleInfo) #endif { var metadataReader = ((NativeFormatModuleInfo)moduleInfo).MetadataReader; var methodHandle = methodData->MethodSignature.Token.AsHandle().ToMethodHandle(metadataReader); var method = methodHandle.GetMethod(metadataReader); name = metadataReader.GetConstantStringValue(method.Name).Value; } #if ECMA_METADATA_SUPPORT else { var ecmaReader = ((EcmaModuleInfo)moduleInfo).MetadataReader; var ecmaHandle = System.Reflection.Metadata.Ecma335.MetadataTokens.Handle(methodData->MethodSignature.Token); var ecmaMethodHandle = (System.Reflection.Metadata.MethodDefinitionHandle)ecmaHandle; var ecmaMethod = ecmaReader.GetMethodDefinition(ecmaMethodHandle); name = ecmaReader.GetString(ecmaMethod.Name); } #endif nameAndSignature = new MethodNameAndSignature(name, methodData->MethodSignature); } return(true); }