<commit_before>using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Net;
using System.Reflection;
using System.Reflection.Emit;
using System.Diagnostics;
using System.IO;
using System.Threading;

// TODO: Consider caching the results of the Get*Stub(string, ...) methods
//       (although it's not really necessary, Haskell will cache the results).

namespace Salsa
{
    public class Driver
    {
        internal static AssemblyBuilder _assemblyBuilder;
        internal static ModuleBuilder _dynamicModuleBuilder;
        internal static TypeBuilder _stubsTypeBuilder;

        static Driver()
        {
            Console.WriteLine("Using Salsa.dll (built {0})",
                File.GetLastWriteTime(Assembly.GetExecutingAssembly().Location).ToString());

            Trace.Listeners.Add(new ConsoleTraceListener());
            System.Windows.Forms.Application.EnableVisualStyles();

            _assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
                new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndSave);
            _dynamicModuleBuilder = _assemblyBuilder.DefineDynamicModule("DynamicModule", "Dynamic.dll");
            _stubsTypeBuilder = _dynamicModuleBuilder.DefineType("Stubs");

            _inTable.Add(_nextId++, true);  // ObjectId 1
            _inTable.Add(_nextId++, false); // ObjectId 2
        }

        /// <summary>
        /// Returns a native function pointer (as an int) to a stub wrapping the given method.
        /// </summary>
        /// <remarks>
        /// This is the first .NET function called by Haskell, and is called by using the 
        /// ICLRRuntimeHost.ExecuteInDefaultAppDomain method.
        /// </remarks>
        public static int GetPointerToMethod(string methodName)
        {
            // TODO: Accept an option from Salsa for the threading model to use
            Thread.CurrentThread.SetApartmentState(ApartmentState.STA);

            Trace.WriteLine("GetPointerToMethod(" + methodName + ")");
            //Console.WriteLine("Called on thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId);

            MethodInfo meth = typeof(Driver).GetMethod(methodName);
            if (meth == null)
                throw new ArgumentException("Method not found.", "methodName");

            // Return a delegate pointing to the indicated method (cast to an int 
            // so we can call this method using ExecuteInDefaultAppDomain)
            return (int)GenerateMethodStub(meth);
        }

        #region Entry points

        /// <summary>
        /// This method is called by Haskell so that the .NET side of the bridge
        /// has access to the Haskell function 'freeHaskellFunPtr'.<commit_msg>Added Boot method to driver assembly<commit_after>using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Net;
using System.Reflection;
using System.Reflection.Emit;
using System.Diagnostics;
using System.IO;
using System.Threading;

// TODO: Consider caching the results of the Get*Stub(string, ...) methods
//       (although it's not really necessary, Haskell will cache the results).

namespace Salsa
{
    public class Driver
    {
        internal static AssemblyBuilder _assemblyBuilder;
        internal static ModuleBuilder _dynamicModuleBuilder;
        internal static TypeBuilder _stubsTypeBuilder;

        static Driver()
        {
            //Console.WriteLine("Using Salsa.dll (version {0})",
            //    Assembly.GetExecutingAssembly().GetName().Version);

            Trace.Listeners.Add(new ConsoleTraceListener());
            System.Windows.Forms.Application.EnableVisualStyles();

            _assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(
                new AssemblyName("DynamicAssembly"), AssemblyBuilderAccess.RunAndSave);
            _dynamicModuleBuilder = _assemblyBuilder.DefineDynamicModule("DynamicModule", "Dynamic.dll");
            _stubsTypeBuilder = _dynamicModuleBuilder.DefineType("Stubs");

            _inTable.Add(_nextId++, true);  // ObjectId 1
            _inTable.Add(_nextId++, false); // ObjectId 2
        }

        public static IntPtr Boot()
        {
            // TODO: Accept an option from Salsa for the threading model to use
            // Thread.CurrentThread.SetApartmentState(ApartmentState.STA);

            return GetPointerToMethod("GetPointerToMethod");
        }

        /// <summary>
        /// Returns a native function pointer (as an int) to a stub wrapping the given method.
        /// </summary>
        /// <remarks>
        /// This is the first .NET function called by Haskell, and is called by using the 
        /// ICLRRuntimeHost.ExecuteInDefaultAppDomain method.
        /// </remarks>
        public static IntPtr GetPointerToMethod(string methodName)
        {
            //Trace.WriteLine("GetPointerToMethod(" + methodName + ")");
            //Console.WriteLine("Called on thread: " + System.Threading.Thread.CurrentThread.ManagedThreadId);

            MethodInfo meth = typeof(Driver).GetMethod(methodName);
            if (meth == null)
                throw new ArgumentException("Method not found.", "methodName");

            // Return a delegate pointing to the indicated method (cast to an int 
            // so we can call this method using ExecuteInDefaultAppDomain)
            return GenerateMethodStub(meth);
        }

        #region Entry points

        /// <summary>
        /// This method is called by Haskell so that the .NET side of the bridge
        /// has access to the Haskell function 'freeHaskellFunPtr'.
{'fraction_non_alphanumeric': 0.09290096406660824, 'fraction_numerical': 0.0010517090271691498, 'mean_word_length': 2.5331269349845202, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4785564', 'n_tokens_mistral': 1424, 'n_tokens_neox': 1355, 'n_words': 416}