Example #1
0
        /// <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 *)&currentArg;
            }

            // 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 *)&currentArg;
            }

            // 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);
        }
Example #4
0
        /// <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 *)&currentArg;
                    }

                    // 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);
            }
        }
Example #5
0
        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);
        }