Repository: dotnet/runtime
File: src/tasks/AppleAppBuilder/Templates/runtime-coreclr.m (Objective-C)

Code before:
#endif

#if HYBRID_GLOBALIZATION
    setenv ("DOTNET_SYSTEM_GLOBALIZATION_HYBRID", "1", TRUE);
#endif

    // build using DiagnosticPorts property in AppleAppBuilder
    // or set DOTNET_DiagnosticPorts env via mlaunch, xharness when undefined.
    // NOTE, using DOTNET_DiagnosticPorts requires app build using AppleAppBuilder and RuntimeComponents=diagnostics_tracing
#ifdef DIAGNOSTIC_PORTS
    setenv ("DOTNET_DiagnosticPorts", DIAGNOSTIC_PORTS, true);
#endif

%EnvVariables%

    char **managed_argv;
    int argi = get_managed_args (&managed_argv);

    bool wait_for_debugger = FALSE;

    const char* bundle = get_bundle_path ();
    chdir (bundle);

    char icu_dat_path [1024];
    int res;
#if defined(HYBRID_GLOBALIZATION)
    res = snprintf (icu_dat_path, sizeof (icu_dat_path) - 1, "%s/%s", bundle, "icudt_hybrid.dat");
#else
    res = snprintf (icu_dat_path, sizeof (icu_dat_path) - 1, "%s/%s", bundle, "icudt.dat");
#endif
    assert (res > 0);

    struct host_runtime_contract host_contract = {
        .size = sizeof(struct host_runtime_contract),
        .pinvoke_override = &pinvoke_override,
        .get_native_code_data = &get_native_code_data
    };

    char contract_str[19]; // 0x + 16 hex digits + '\0'
    snprintf(contract_str, 19, "0x%zx", (size_t)(&host_contract));

    // TODO: set TRUSTED_PLATFORM_ASSEMBLIES, APP_PATHS and NATIVE_DLL_SEARCH_DIRECTORIES
    const char *appctx_keys [] = {
        "RUNTIME_IDENTIFIER",
        "APP_CONTEXT_BASE_DIRECTORY",
        "TRUSTED_PLATFORM_ASSEMBLIES",
        "HOST_RUNTIME_CONTRACT",
#if !defined(INVARIANT_GLOBALIZATION)
        "ICU_DAT_FILE_PATH"
#endif
    };

Review comment (suggestion):
The `host_contract` struct is allocated on the stack, but according to the host_runtime_contract.h documentation (line 44), "Any callbacks set on this contract are expected to be valid for the lifetime of the process." The runtime may hold onto this pointer beyond the scope of this function. Since `mono_ios_runtime_init` calls `exit(res)` at the end (line 259), it never returns, so the stack frame technically persists. However, this is fragile and unclear. Consider either:
1. Making `host_contract` static to ensure it persists for the process lifetime
2. Adding a comment explaining that the function never returns, so the stack frame persists

Making it static would be safer and more explicit about the lifetime requirement.

Code after:

%EnvVariables%

    char **managed_argv;
    int argi = get_managed_args (&managed_argv);

    bool wait_for_debugger = FALSE;

    const char* bundle = get_bundle_path ();
    chdir (bundle);

    char icu_dat_path [1024];
    int res;
#if defined(HYBRID_GLOBALIZATION)
    res = snprintf (icu_dat_path, sizeof (icu_dat_path) - 1, "%s/%s", bundle, "icudt_hybrid.dat");
#else
    res = snprintf (icu_dat_path, sizeof (icu_dat_path) - 1, "%s/%s", bundle, "icudt.dat");
#endif
    assert (res > 0);

    // Contract lasts the lifetime of the app. The app exists before the end of this function.
    struct host_runtime_contract host_contract = {
        .size = sizeof(struct host_runtime_contract),
        .pinvoke_override = &pinvoke_override,
        .get_native_code_data = &get_native_code_data
    };

    char contract_str[19]; // 0x + 16 hex digits + '\0'
    snprintf(contract_str, 19, "0x%zx", (size_t)(&host_contract));

    // TODO: set TRUSTED_PLATFORM_ASSEMBLIES, APP_PATHS and NATIVE_DLL_SEARCH_DIRECTORIES
    const char *appctx_keys [] = {
        "RUNTIME_IDENTIFIER",
        "APP_CONTEXT_BASE_DIRECTORY",
        "TRUSTED_PLATFORM_ASSEMBLIES",
        "HOST_RUNTIME_CONTRACT",
#if !defined(INVARIANT_GLOBALIZATION)
        "ICU_DAT_FILE_PATH"
#endif
    };
    const char *appctx_values [] = {
        APPLE_RUNTIME_IDENTIFIER,
        bundle,
        compute_trusted_platform_assemblies(),
        contract_str,
#if !defined(INVARIANT_GLOBALIZATION)
        icu_dat_path
#endif
    };

    const char* executable = "%EntryPointLibName%";