<commit_before>// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#nullable enable

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Loader;

namespace Internal.Runtime.InteropServices
{
    public static class ComponentActivator
    {
        private static readonly Dictionary<string, IsolatedComponentLoadContext> s_AssemblyLoadContexts;
        private static readonly Dictionary<IntPtr, Delegate> s_Delegates = new Dictionary<IntPtr, Delegate>();

        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate int ComponentEntryPoint(IntPtr args, int sizeBytes);

        static ComponentActivator()
        {
            s_AssemblyLoadContexts = new Dictionary<string, IsolatedComponentLoadContext>(StringComparer.InvariantCulture);
        }

        private static string MarshalToString(IntPtr arg, string argName)
        {
            if (arg == IntPtr.Zero)
            {
                throw new ArgumentNullException(argName);
            }
            string? result = Marshal.PtrToStringUTF8(arg);

            if (result == null)
            {
                throw new ArgumentNullException(argName);
            }
            return result;
        }

        /// <summary>
        /// Native hosting entry point for creating a native delegate
        /// </summary>
        /// <param name="assemblyPathNative">Fully qualified path to assembly</param>
        /// <param name="delegateTypeNative">Assembly qualified delegate type name</param>
        /// <param name="typeNameNative">Assembly qualified type name</param>
        /// <param name="methodNameNative">Public static method name compatible with delegateType</param>
        /// <param name="functionHandle">Pointer where to store the function pointer result</param>
        public static int CreateNativeDelegate(IntPtr assemblyPathNative,
                                               IntPtr typeNameNative,
                                               IntPtr methodNameNative,
                                               IntPtr delegateTypeNative,
                                               IntPtr functionHandle)
        {
            try
            {
                string assemblyPath = MarshalToString(assemblyPathNative, nameof(assemblyPathNative));
                string typeName     = MarshalToString(typeNameNative, nameof(typeNameNative));
                string methodName   = MarshalToString(methodNameNative, nameof(methodNameNative));

                string delegateType;
                if (delegateTypeNative == IntPtr.Zero)
                {
                    delegateType = typeof(ComponentEntryPoint).AssemblyQualifiedName!;
                }
                else
                {
                    delegateType = MarshalToString(delegateTypeNative, nameof(delegateTypeNative));
                }

                if (functionHandle == IntPtr.Zero)
                {
                    throw new ArgumentNullException(nameof(functionHandle));
                }

                Delegate d = CreateDelegate(assemblyPath, typeName, methodName, delegateType);

                IntPtr functionPtr = Marshal.GetFunctionPointerForDelegate(d);<commit_msg>Add CreateNativeDelegate flags argument (#24671)<commit_after>// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#nullable enable

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.Loader;

namespace Internal.Runtime.InteropServices
{
    public static class ComponentActivator
    {
        private static readonly Dictionary<string, IsolatedComponentLoadContext> s_AssemblyLoadContexts;
        private static readonly Dictionary<IntPtr, Delegate> s_Delegates = new Dictionary<IntPtr, Delegate>();

        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
        public delegate int ComponentEntryPoint(IntPtr args, int sizeBytes);

        static ComponentActivator()
        {
            s_AssemblyLoadContexts = new Dictionary<string, IsolatedComponentLoadContext>(StringComparer.InvariantCulture);
        }

        private static string MarshalToString(IntPtr arg, string argName)
        {
            if (arg == IntPtr.Zero)
            {
                throw new ArgumentNullException(argName);
            }
            string? result = Marshal.PtrToStringUTF8(arg);

            if (result == null)
            {
                throw new ArgumentNullException(argName);
            }
            return result;
        }

        /// <summary>
        /// Native hosting entry point for creating a native delegate
        /// </summary>
        /// <param name="assemblyPathNative">Fully qualified path to assembly</param>
        /// <param name="typeNameNative">Assembly qualified type name</param>
        /// <param name="methodNameNative">Public static method name compatible with delegateType</param>
        /// <param name="delegateTypeNative">Assembly qualified delegate type name</param>
        /// <param name="flags">Extensibility flags (currently unused)</param>
        /// <param name="functionHandle">Pointer where to store the function pointer result</param>
        public static int CreateNativeDelegate(IntPtr assemblyPathNative,
                                               IntPtr typeNameNative,
                                               IntPtr methodNameNative,
                                               IntPtr delegateTypeNative,
                                               int flags,
                                               IntPtr functionHandle)
        {
            try
            {
                string assemblyPath = MarshalToString(assemblyPathNative, nameof(assemblyPathNative));
                string typeName     = MarshalToString(typeNameNative, nameof(typeNameNative));
                string methodName   = MarshalToString(methodNameNative, nameof(methodNameNative));

                string delegateType;
                if (delegateTypeNative == IntPtr.Zero)
                {
                    delegateType = typeof(ComponentEntryPoint).AssemblyQualifiedName!;
                }
                else
                {
                    delegateType = MarshalToString(delegateTypeNative, nameof(delegateTypeNative));
                }

                if (functionHandle == IntPtr.Zero)
                {
                    throw new ArgumentNullException(nameof(functionHandle));
                }

                Delegate d = CreateDelegate(assemblyPath, typeName, methodName, delegateType);

                IntPtr functionPtr = Marshal.GetFunctionPointerForDelegate(d);
{'fraction_non_alphanumeric': 0.07150948739733787, 'fraction_numerical': 0.0009912206173888418, 'mean_word_length': 1.9978777589134125, 'pattern_counts': {'":': 0, '<': 37, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7664323', 'n_tokens_mistral': 1542, 'n_tokens_neox': 1467, 'n_words': 418}