Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support loading ICU data from managed Interop #49406

Merged
merged 5 commits into from
Mar 13, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/libraries/Common/src/Interop/Interop.ICU.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,16 @@ internal static partial class Interop
internal static partial class Globalization
{
[DllImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_LoadICU")]
internal static extern int LoadICU();
private static extern int LoadICUDirect();

[DllImport(Libraries.GlobalizationNative, EntryPoint = "GlobalizationNative_LoadICUData")]
private static extern int LoadICUData(string? path);

internal static int LoadICU()
{
object? datPath = AppContext.GetData("ICU_DAT_FILE_PATH");
return (datPath != null) ? LoadICUData(datPath.ToString()) : LoadICUDirect();
}

internal static void InitICUFunctions(IntPtr icuuc, IntPtr icuin, ReadOnlySpan<char> version, ReadOnlySpan<char> suffix)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ static const Entry s_globalizationNative[] =
DllImportEntry(GlobalizationNative_IsPredefinedLocale)
DllImportEntry(GlobalizationNative_LastIndexOf)
DllImportEntry(GlobalizationNative_LoadICU)
DllImportEntry(GlobalizationNative_LoadICUData)
DllImportEntry(GlobalizationNative_NormalizeString)
DllImportEntry(GlobalizationNative_StartsWith)
DllImportEntry(GlobalizationNative_ToAscii)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ PALEXPORT void GlobalizationNative_InitICUFunctions(void* icuuc, void* icuin, co

PALEXPORT int32_t GlobalizationNative_GetICUVersion(void);

#if defined(STATIC_ICU)
PALEXPORT int32_t GlobalizationNative_LoadICUData(const char* path);

PALEXPORT int32_t GlobalizationNative_LoadICUData(char* path);
#if defined(STATIC_ICU)

PALEXPORT const char* GlobalizationNative_GetICUDTName(const char* culture);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ static int32_t load_icu_data(void* pData)
}
}

int32_t GlobalizationNative_LoadICUData(char* path)
int32_t GlobalizationNative_LoadICUData(const char* path)
{
int32_t ret = -1;
char* icu_data;
Expand Down Expand Up @@ -127,7 +127,12 @@ int32_t GlobalizationNative_LoadICUData(char* path)

fclose (fp);

return load_icu_data (icu_data);
if (load_icu_data (icu_data) == 0) {
fprintf (stderr, "ICU BAD EXIT %d.", ret);
return ret;
}

return GlobalizationNative_LoadICU ();
}

const char* GlobalizationNative_GetICUDTName(const char* culture)
Expand Down
2 changes: 1 addition & 1 deletion src/tasks/AppleAppBuilder/AppleAppBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ public override bool Execute()

if (GenerateXcodeProject)
{
Xcode generator = new Xcode(TargetOS);
Xcode generator = new Xcode(TargetOS, Arch);
generator.EnableRuntimeLogging = EnableRuntimeLogging;

XcodeProjectPath = generator.GenerateXCode(ProjectName, MainLibraryFileName, assemblerFiles,
Expand Down
42 changes: 30 additions & 12 deletions src/tasks/AppleAppBuilder/Templates/runtime.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#define MONO_ENTER_GC_UNSAFE
#define MONO_EXIT_GC_UNSAFE

#define APPLE_RUNTIME_IDENTIFIER "//%APPLE_RUNTIME_IDENTIFIER%"

const char *
get_bundle_path (void)
{
Expand Down Expand Up @@ -237,16 +239,6 @@ static int32_t load_icu_data ()
setenv ("MONO_LOG_MASK", "all", TRUE);
#endif

#if !INVARIANT_GLOBALIZATION
int32_t ret = load_icu_data ();

if (ret == 0) {
os_log_info (OS_LOG_DEFAULT, "ICU BAD EXIT %d.", ret);
exit (ret);
return;
}
#endif

id args_array = [[NSProcessInfo processInfo] arguments];
assert ([args_array count] <= 128);
const char *managed_argv [128];
Expand All @@ -261,8 +253,34 @@ static int32_t load_icu_data ()
const char* bundle = get_bundle_path ();
chdir (bundle);

char icu_dat_path[1024];
int res;

res = snprintf (icu_dat_path, sizeof (icu_dat_path) - 1, "%s/%s", bundle, "icudt.dat");
assert (res > 0);

// TODO: set TRUSTED_PLATFORM_ASSEMBLIES, APP_PATHS and NATIVE_DLL_SEARCH_DIRECTORIES
monovm_initialize(0, NULL, NULL);
#if !INVARIANT_GLOBALIZATION
const char* appctx_keys[3];
appctx_keys[0] = "RUNTIME_IDENTIFIER";
appctx_keys[1] = "APP_CONTEXT_BASE_DIRECTORY";
appctx_keys[2] = "ICU_DAT_FILE_PATH";

const char* appctx_values[3];
appctx_values[0] = APPLE_RUNTIME_IDENTIFIER;
appctx_values[1] = bundle;
appctx_values[2] = icu_dat_path;
monovm_initialize(3, appctx_keys, appctx_values);
#else
const char* appctx_keys[2];
appctx_keys[0] = "RUNTIME_IDENTIFIER";
appctx_keys[1] = "APP_CONTEXT_BASE_DIRECTORY";

const char* appctx_values[2];
appctx_values[0] = APPLE_RUNTIME_IDENTIFIER;
appctx_values[1] = bundle;
monovm_initialize(2, appctx_keys, appctx_values);
#endif

#if FORCE_INTERPRETER
os_log_info (OS_LOG_DEFAULT, "INTERP Enabled");
Expand Down Expand Up @@ -300,7 +318,7 @@ static int32_t load_icu_data ()
assert (assembly);
os_log_info (OS_LOG_DEFAULT, "Executable: %{public}s", executable);

int res = mono_jit_exec (mono_domain_get (), assembly, argi, managed_argv);
res = mono_jit_exec (mono_domain_get (), assembly, argi, managed_argv);
// Print this so apps parsing logs can detect when we exited
os_log_info (OS_LOG_DEFAULT, "Exit code: %d.", res);

Expand Down
6 changes: 5 additions & 1 deletion src/tasks/AppleAppBuilder/Xcode.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@

internal class Xcode
{
private string RuntimeIdentifier { get; set; }
private string SysRoot { get; set; }
private string Target { get; set; }

public Xcode(string target)
public Xcode(string target, string arch)
{
Target = target;
switch (Target)
Expand All @@ -27,6 +28,8 @@ public Xcode(string target)
SysRoot = Utils.RunProcess("xcrun", "--sdk macosx --show-sdk-path");
break;
}

RuntimeIdentifier = $"{Target}-{arch}";
}

public bool EnableRuntimeLogging { get; set; }
Expand Down Expand Up @@ -175,6 +178,7 @@ public string GenerateXCode(
File.WriteAllText(Path.Combine(binDir, "runtime.m"),
Utils.GetEmbeddedResource("runtime.m")
.Replace("//%DllMap%", dllMap.ToString())
.Replace("//%APPLE_RUNTIME_IDENTIFIER%", RuntimeIdentifier)
.Replace("%EntryPointLibName%", Path.GetFileName(entryPointLib)));

Utils.RunProcess("cmake", cmakeArgs.ToString(), workingDir: binDir);
Expand Down