Skip to content

Commit

Permalink
Add support for NativeAOT on macOS (#18765)
Browse files Browse the repository at this point in the history
Co-authored-by: Filip Navara <navara@emclient.com>
  • Loading branch information
rolfbjarne and filipnavara authored Aug 30, 2023
1 parent f2349d0 commit d50f52d
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 6 deletions.
6 changes: 6 additions & 0 deletions src/ObjCRuntime/Runtime.cs
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,12 @@ static IntPtr PrintAllExceptions (IntPtr exception_gchandle)
// For XM it will also register all assemblies loaded in the current appdomain.
internal static void RegisterAssemblies ()
{
#if NET
if (IsNativeAOT) {
return;
}
#endif

#if PROFILE
var watch = new Stopwatch ();
#endif
Expand Down
2 changes: 2 additions & 0 deletions src/ObjCRuntime/Runtime.mac.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,13 @@ unsafe static void InitializePlatform (InitializationOptions* options)
FrameworksPath = Path.Combine (basePath, "Frameworks");
}

#if !NET
[Preserve]
static IntPtr GetNullableType (IntPtr type)
{
return AllocGCHandle (Registrar.GetNullableType ((Type) GetGCHandleTarget (type)!));
}
#endif // !NET
#endif // !COREBUILD
}
}
Expand Down
3 changes: 2 additions & 1 deletion tests/monotouch-test/ObjCRuntime/RegistrarTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2246,7 +2246,8 @@ public void TestCtors ()
}
}

#if __MACOS__
// This test uses Assembly.LoadFrom, which isn't supported with NativeAOT
#if __MACOS__ && !NATIVEAOT
[Test]
public void CustomUserTypeWithDynamicallyLoadedAssembly ()
{
Expand Down
4 changes: 4 additions & 0 deletions tests/mtouch/Cache.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ public static class Cache // Not really a cache (since the root directory is cle

static Cache ()
{
#if NATIVEAOT
root = Path.Combine (Path.GetDirectoryName (Environment.ProcessPath)!, "tmp-test-dir");
#else
root = Path.Combine (Path.GetDirectoryName (System.Reflection.Assembly.GetExecutingAssembly ().Location)!, "tmp-test-dir");
#endif
if (Directory.Exists (root)) {
var movedRoot = root + DateTime.UtcNow.Ticks.ToString () + "-deletion-in-progress";
// The temporary directory can be big, and it can take a while to clean it out.
Expand Down
5 changes: 2 additions & 3 deletions tests/xharness/Jenkins/TestVariationsFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,8 @@ IEnumerable<TestData> GetTestData (RunTestTask test)
if (test.Platform != TestPlatform.MacCatalyst) {
yield return new TestData { Variation = "Debug (static registrar)", Registrar = "static", Debug = true, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.Mac), };
yield return new TestData { Variation = "Debug (static registrar, ARM64)", Registrar = "static", Debug = true, Profiling = false, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.Mac) || !mac_supports_arm64, RuntimeIdentifier = arm64_runtime_identifier, };
// Pending: We need the NativeAOT's runtime bits to ship using runtime packs for macOS (https://github.com/dotnet/runtime/issues/87060) before we can enable this
// yield return new TestData { Variation = "Release (NativeAOT)", Debug = false, PublishAot = true, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.Mac), Defines = "NATIVEAOT", LinkMode = "Full" };
// yield return new TestData { Variation = "Release (NativeAOT, ARM64)", Debug = false, PublishAot = true, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.Mac) || !mac_supports_arm64, Defines = "NATIVEAOT", RuntimeIdentifier = arm64_runtime_identifier, LinkMode = "Full" };
yield return new TestData { Variation = "Release (NativeAOT, ARM64)", Debug = false, PublishAot = true, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.Mac) || !mac_supports_arm64, Defines = "NATIVEAOT", RuntimeIdentifier = arm64_runtime_identifier, LinkMode = "Full" };
yield return new TestData { Variation = "Release (NativeAOT, x64)", Debug = false, PublishAot = true, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.Mac), Defines = "NATIVEAOT", RuntimeIdentifier = "osx-x64", LinkMode = "Full" };
}
if (test.Platform == TestPlatform.MacCatalyst) {
yield return new TestData { Variation = "Release (ARM64, LLVM)", Debug = false, UseLlvm = true, Ignored = !jenkins.TestSelection.IsEnabled (TestLabel.Monotouch) || !jenkins.TestSelection.IsEnabled (PlatformLabel.MacCatalyst) || !mac_supports_arm64, RuntimeIdentifier = arm64_runtime_identifier };
Expand Down
4 changes: 2 additions & 2 deletions tools/common/Optimizations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ public void Initialize (Application app, out List<ProductException> messages)
// This means it won't be listed in --help, and it won't be enabled if all optimizations
// are enabled. Yet we still might want to enable it manually, and this condition
// allows us to manually pass --optimize=remove-dynamic-registrar and enable it that way.
if (app.Platform == ApplePlatform.MacOSX && (Opt) i == Opt.RemoveDynamicRegistrar)
if (app.Platform == ApplePlatform.MacOSX && app.XamarinRuntime != XamarinRuntime.NativeAOT && (Opt) i == Opt.RemoveDynamicRegistrar)
continue;

// check if the optimization is valid for the current platform
Expand Down Expand Up @@ -264,7 +264,7 @@ public void Initialize (Application app, out List<ProductException> messages)

// We will register protocols if the static registrar is enabled and loading assemblies is not possible
if (!RegisterProtocols.HasValue) {
if (app.Platform != ApplePlatform.MacOSX) {
if (app.Platform != ApplePlatform.MacOSX || app.XamarinRuntime == XamarinRuntime.NativeAOT) {
RegisterProtocols = (app.Registrar == RegistrarMode.Static || app.Registrar == RegistrarMode.ManagedStatic) && !app.UseInterpreter;
} else {
RegisterProtocols = false;
Expand Down
20 changes: 20 additions & 0 deletions tools/common/StaticRegistrar.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3442,6 +3442,12 @@ bool SpecializeTrampoline (AutoIndentStringBuilder sb, ObjCMethod method, List<E
sb.AppendLine ("}");
return true;
case Trampoline.CopyWithZone2:
#if NET
// Managed Static Registrar handles CopyWithZone2 in GenerateCallToUnmanagedCallersOnlyMethod
if (LinkContext.App.Registrar == RegistrarMode.ManagedStatic) {
return false;
}
#endif
sb.AppendLine ("-(id) copyWithZone: (NSZone *) zone");
sb.AppendLine ("{");
sb.AppendLine ("return xamarin_copyWithZone_trampoline2 (self, _cmd, zone);");
Expand Down Expand Up @@ -3490,6 +3496,7 @@ bool TryGetReturnType (ObjCMethod method, string descriptiveMethodName, List<Exc
case Trampoline.X86_DoubleABI_StretTrampoline:
case Trampoline.StaticStret:
case Trampoline.Stret:
case Trampoline.CopyWithZone2:
switch (method.NativeReturnType.FullName) {
case "System.Int64":
rettype = "long long";
Expand Down Expand Up @@ -4369,6 +4376,14 @@ void GenerateCallToUnmanagedCallersOnlyMethod (AutoIndentStringBuilder sb, ObjCM
sb.WriteLine ($"bool call_super = false;");
if (hasReturnType)
sb.WriteLine ($"{callbackReturnType} rv = {{ 0 }};");
if (method.CurrentTrampoline == Trampoline.CopyWithZone2) {
sb.WriteLine ("id p0 = (id)zone;");
sb.WriteLine ("GCHandle gchandle;");
sb.WriteLine ("enum XamarinGCHandleFlags flags = XamarinGCHandleFlags_None;");
sb.WriteLine ("gchandle = xamarin_get_gchandle_with_flags (self, &flags);");
sb.WriteLine ("if (gchandle != INVALID_GCHANDLE)");
sb.Indent ().WriteLine ("xamarin_set_gchandle_with_flags (self, INVALID_GCHANDLE, XamarinGCHandleFlags_None);").Unindent ();
}

if (!staticCall) {
sb.WriteLine ($"static {ucoEntryPoint}_function {ucoEntryPoint};");
Expand All @@ -4392,6 +4407,11 @@ void GenerateCallToUnmanagedCallersOnlyMethod (AutoIndentStringBuilder sb, ObjCM
GenerateCallToSuperForConstructor (sb, method, exceptions);
}

if (method.CurrentTrampoline == Trampoline.CopyWithZone2) {
sb.WriteLine ("if (gchandle != INVALID_GCHANDLE)");
sb.Indent ().WriteLine ("xamarin_set_gchandle_with_flags (self, gchandle, flags);").Unindent ();
}

if (hasReturnType)
sb.WriteLine ("return rv;");

Expand Down

6 comments on commit d50f52d

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

Please sign in to comment.