Skip to content

Commit a608ba8

Browse files
committed
[runtime] Create a version of our runtime that can be used with NativeAOT.
This contributes towards dotnet#17339.
1 parent ca853b8 commit a608ba8

File tree

8 files changed

+118
-4
lines changed

8 files changed

+118
-4
lines changed

Make.config

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,7 @@ DOTNET_PLATFORMS=
682682
ifdef INCLUDE_IOS
683683
DOTNET_PLATFORMS+=iOS
684684
DOTNET_IOS_BITNESSES+=64
685+
DOTNET_NATIVEAOT_PLATFORMS+=iOS
685686

686687
# 32-bit architectures
687688
ifdef IOS_SUPPORTS_32BIT_ARCHITECTURES
@@ -705,6 +706,7 @@ endif # INCLUDE_IOS
705706
ifdef INCLUDE_TVOS
706707
DOTNET_PLATFORMS+=tvOS
707708
DOTNET_TVOS_BITNESSES+=64
709+
DOTNET_NATIVEAOT_PLATFORMS+=tvOS
708710
ifdef INCLUDE_DEVICE
709711
DOTNET_TVOS_RUNTIME_IDENTIFIERS=tvos-arm64 tvossimulator-x64 tvossimulator-arm64
710712
else
@@ -728,6 +730,7 @@ endif
728730
ifdef INCLUDE_MACCATALYST
729731
DOTNET_PLATFORMS+=MacCatalyst
730732
DOTNET_MACCATALYST_BITNESSES+=64
733+
DOTNET_NATIVEAOT_PLATFORMS+=MacCatalyst
731734
DOTNET_MACCATALYST_RUNTIME_IDENTIFIERS=maccatalyst-x64 maccatalyst-arm64
732735
DOTNET_MACCATALYST_RUNTIME_IDENTIFIERS_64+=$(DOTNET_MACCATALYST_RUNTIME_IDENTIFIERS)
733736
endif
@@ -736,6 +739,7 @@ ifdef INCLUDE_MAC
736739
DOTNET_PLATFORMS+=macOS
737740
DOTNET_CORECLR_PLATFORMS+=macOS
738741
DOTNET_MACOS_BITNESSES+=64
742+
DOTNET_NATIVEAOT_PLATFORMS+=macOS
739743
DOTNET_MACOS_RUNTIME_IDENTIFIERS=osx-x64 osx-arm64
740744
DOTNET_MACOS_RUNTIME_IDENTIFIERS_64=$(DOTNET_MACOS_RUNTIME_IDENTIFIERS)
741745
endif

mk/rules.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,8 @@ $(eval $(call NativeCompilationTemplate,-dotnet,-O2 -DDOTNET))
297297
$(eval $(call NativeCompilationTemplate,-dotnet-debug,-DDEBUG -DDOTNET))
298298
$(eval $(call NativeCompilationTemplate,-dotnet-coreclr,-O2 -DCORECLR_RUNTIME -DDOTNET))
299299
$(eval $(call NativeCompilationTemplate,-dotnet-coreclr-debug,-DDEBUG -DCORECLR_RUNTIME -DDOTNET))
300+
$(eval $(call NativeCompilationTemplate,-dotnet-nativeaot,-O2 -DCORECLR_RUNTIME -DDOTNET -DNATIVEAOT))
301+
$(eval $(call NativeCompilationTemplate,-dotnet-nativeaot-debug,-DDEBUG -DCORECLR_RUNTIME -DDOTNET -DNATIVEAOT))
300302

301303
.libs/iphoneos .libs/iphonesimulator .libs/watchos .libs/watchsimulator .libs/tvos .libs/tvsimulator .libs/maccatalyst .libs/mac:
302304
$(Q) mkdir -p $@

runtime/Makefile

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ SHIPPED_HEADERS += \
2222
xamarin/monovm-bridge.h \
2323
xamarin/coreclr-bridge.h \
2424

25-
SHARED_SOURCES += mono-runtime.m bindings.m bindings-generated.m shared.m runtime.m trampolines.m trampolines-invoke.m xamarin-support.m nsstring-localization.m trampolines-varargs.m monovm-bridge.m coreclr-bridge.m
25+
SHARED_SOURCES += mono-runtime.m bindings.m bindings-generated.m shared.m runtime.m trampolines.m trampolines-invoke.m xamarin-support.m nsstring-localization.m trampolines-varargs.m monovm-bridge.m coreclr-bridge.m nativeaot-bridge.m
2626
SHARED_I386_SOURCES += trampolines-i386.m trampolines-i386-asm.s trampolines-i386-objc_msgSend.s trampolines-i386-objc_msgSendSuper.s trampolines-i386-objc_msgSend_stret.s trampolines-i386-objc_msgSendSuper_stret.s
2727
SHARED_X86_64_SOURCES += trampolines-x86_64.m trampolines-x86_64-asm.s trampolines-x86_64-objc_msgSend.s trampolines-x86_64-objc_msgSendSuper.s trampolines-x86_64-objc_msgSend_stret.s trampolines-x86_64-objc_msgSendSuper_stret.s
2828
SHARED_ARM64_SOURCES += trampolines-arm64.m trampolines-arm64-asm.s trampolines-arm64-objc_msgSend.s trampolines-arm64-objc_msgSendSuper.s
@@ -454,6 +454,11 @@ MAC_LIBS = \
454454
# This is used when using the CoreCLR runtime instead of Mono.
455455
# CORECLR_RUNTIME is defined for these versions of libxamarin.
456456
#
457+
# libxamarin-nativeaot.a:
458+
# This is used when using NativeAOT.
459+
# CORECLR_RUNTIME is defined for these versions of libxamarin (because the nativeaot bridge shares *a lot* of code with the coreclr bridge)
460+
# NATIVEAOT is defined for these versions of libxamarin
461+
#
457462

458463
ifdef INCLUDE_XAMARIN_LEGACY
459464
all-local:: $(TARGETS)
@@ -614,6 +619,15 @@ endef
614619

615620
$(foreach platform,$(DOTNET_CORECLR_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(eval $(call DotNetCoreClrLibTemplate,$(platform),$(rid)))))
616621

622+
define DotNetNativeAotLibTemplate
623+
DOTNET_TARGETS += \
624+
$(DOTNET_DESTDIR)/Microsoft.$(1).Runtime.$(2)/runtimes/$(2)/native/libxamarin-dotnet-nativeaot.a \
625+
$(DOTNET_DESTDIR)/Microsoft.$(1).Runtime.$(2)/runtimes/$(2)/native/libxamarin-dotnet-nativeaot-debug.a \
626+
627+
endef
628+
629+
$(foreach platform,$(DOTNET_NATIVEAOT_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(eval $(call DotNetNativeAotLibTemplate,$(platform),$(rid)))))
630+
617631
# a few lookup tables, because the data we have is not always in the format we need it
618632
DOTNET_iphonesimulator_DYLIB_FLAGS=-lmonosgen-2.0 -licudata -licui18n -licuuc -framework UIKit
619633
DOTNET_iphoneos_DYLIB_FLAGS=-lmonosgen-2.0 -licudata -licui18n -licuuc -framework UIKit
@@ -704,6 +718,8 @@ $(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIM
704718
$(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibXamarinTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),_DEBUG,-dotnet-debug,,.mono)))))
705719
$(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibXamarinTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),_CORECLR,-dotnet-coreclr,_CORECLR)))))
706720
$(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibXamarinTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),_CORECLR_DEBUG,-dotnet-coreclr-debug,_CORECLR)))))
721+
$(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibXamarinTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),_NATIVEAOT,-dotnet-nativeaot,_NATIVEAOT,.mono)))))
722+
$(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibXamarinTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),_NATIVEAOT_DEBUG,-dotnet-nativeaot-debug,_NATIVEAOT,.mono)))))
707723

708724
#
709725
# DotNetLibExtensionTemplate builds lib[tv]extension.a
@@ -731,6 +747,7 @@ endef
731747

732748
$(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibExtensionTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),,-dotnet,,)))))
733749
$(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibExtensionTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),_CORECLR,-dotnet-coreclr,_CORECLR)))))
750+
$(foreach platform,$(DOTNET_PLATFORMS),$(foreach rid,$(DOTNET_$(platform)_RUNTIME_IDENTIFIERS),$(foreach arch,$(DOTNET_$(rid)_ARCHITECTURES),$(eval $(call DotNetLibExtensionTemplate,$(DOTNET_$(rid)_SDK_PLATFORM),$(rid),$(arch),_NATOVEAOT,-dotnet-nativeaot,_NATOVEAOT)))))
734751

735752
dotnet: $(DOTNET_TARGETS)
736753

runtime/coreclr-bridge.m

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <sys/stat.h>
1212
#include <inttypes.h>
1313
#include <pthread.h>
14+
#include <sys/mman.h>
1415

1516
#include "product.h"
1617
#include "runtime-internal.h"
@@ -477,6 +478,7 @@
477478
munmap ((void *) buf, fd_len);
478479
}
479480

481+
#if !defined (NATIVEAOT)
480482
bool
481483
xamarin_bridge_vm_initialize (int propertyCount, const char **propertyKeys, const char **propertyValues)
482484
{
@@ -510,6 +512,7 @@
510512

511513
return rv == 0;
512514
}
515+
#endif // !defined (NATIVEAOT)
513516

514517
void
515518
xamarin_install_nsautoreleasepool_hooks ()
@@ -537,18 +540,20 @@
537540
xamarin_assertion_message ("%s threw an exception: %p = %s", method, gchandle, [xamarin_print_all_exceptions (gchandle) UTF8String]);
538541
}
539542

540-
typedef void (*xamarin_runtime_initialize_decl)(struct InitializationOptions* options);
543+
#if !defined (NATIVEAOT)
544+
typedef void (*xamarin_runtime_initialize_decl)(struct InitializationOptions* options, GCHandle* exception_gchandle);
541545
void
542546
xamarin_bridge_call_runtime_initialize (struct InitializationOptions* options, GCHandle* exception_gchandle)
543547
{
544548
void *del = NULL;
545-
int rv = coreclr_create_delegate (coreclr_handle, coreclr_domainId, PRODUCT ", Version=0.0.0.0", "ObjCRuntime.Runtime", "Initialize", &del);
549+
int rv = coreclr_create_delegate (coreclr_handle, coreclr_domainId, PRODUCT ", Version=0.0.0.0", "ObjCRuntime.Runtime", "SafeInitialize", &del);
546550
if (rv != 0)
547551
xamarin_assertion_message ("xamarin_bridge_call_runtime_initialize: failed to create delegate: %i\n", rv);
548552

549553
xamarin_runtime_initialize_decl runtime_initialize = (xamarin_runtime_initialize_decl) del;
550-
runtime_initialize (options);
554+
runtime_initialize (options, exception_gchandle);
551555
}
556+
#endif // !defined (NATIVEAOT)
552557

553558
void
554559
xamarin_bridge_register_product_assembly (GCHandle* exception_gchandle)
@@ -737,6 +742,7 @@
737742
return rv;
738743
}
739744

745+
#if !defined (NATIVEAOT)
740746
int
741747
mono_jit_exec (MonoDomain * domain, MonoAssembly * assembly, int argc, const char** argv)
742748
{
@@ -766,6 +772,7 @@
766772

767773
return (int) exitCode;
768774
}
775+
#endif // !defined (NATIVEAOT)
769776

770777
MonoGHashTable *
771778
mono_g_hash_table_new_type (GHashFunc hash_func, GEqualFunc key_equal_func, MonoGHashGCType type)

runtime/nativeaot-bridge.m

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2+
/*
3+
* Authors: Rolf Bjarne Kvinge
4+
*
5+
* Copyright (C) 2023 Microsoft Corp.
6+
*
7+
*/
8+
9+
#if defined (NATIVEAOT)
10+
11+
#include <sys/stat.h>
12+
#include <inttypes.h>
13+
#include <pthread.h>
14+
#include <sys/mman.h>
15+
#include <dlfcn.h>
16+
17+
#include "product.h"
18+
#include "runtime-internal.h"
19+
#include "slinked-list.h"
20+
#include "xamarin/xamarin.h"
21+
#include "xamarin/coreclr-bridge.h"
22+
#include "xamarin/nativeaot-bridge.h"
23+
24+
void
25+
xamarin_bridge_call_runtime_initialize (struct InitializationOptions* options, GCHandle* exception_gchandle)
26+
{
27+
xamarin_objcruntime_runtime_nativeaotinitialize (options, exception_gchandle);
28+
}
29+
30+
bool
31+
xamarin_bridge_vm_initialize (int propertyCount, const char **propertyKeys, const char **propertyValues)
32+
{
33+
return true;
34+
}
35+
36+
int
37+
mono_jit_exec (MonoDomain * domain, MonoAssembly * assembly, int argc, const char** argv)
38+
{
39+
return __managed__Main (argc, argv);
40+
}
41+
42+
#endif // NATIVEAOT

runtime/runtime.m

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,12 +1304,14 @@ -(void) xamarinSetFlags: (enum XamarinGCHandleFlags) flags;
13041304
#endif
13051305

13061306
#if defined (CORECLR_RUNTIME)
1307+
#if !defined(__arm__) // the dynamic trampolines haven't been implemented in 32-bit ARM assembly.
13071308
options.xamarin_objc_msgsend = (void *) xamarin_dyn_objc_msgSend;
13081309
options.xamarin_objc_msgsend_super = (void *) xamarin_dyn_objc_msgSendSuper;
13091310
#if !defined(__aarch64__)
13101311
options.xamarin_objc_msgsend_stret = (void *) xamarin_dyn_objc_msgSend_stret;
13111312
options.xamarin_objc_msgsend_super_stret = (void *) xamarin_dyn_objc_msgSendSuper_stret;
13121313
#endif // !defined(__aarch64__)
1314+
#endif // !defined(__arm__)
13131315
options.unhandled_exception_handler = (void *) &xamarin_coreclr_unhandled_exception_handler;
13141316
options.reference_tracking_begin_end_callback = (void *) &xamarin_coreclr_reference_tracking_begin_end_callback;
13151317
options.reference_tracking_is_referenced_callback = (void *) &xamarin_coreclr_reference_tracking_is_referenced_callback;

runtime/xamarin/nativeaot-bridge.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
2+
/* Support for using NativeAOT */
3+
4+
#if defined (NATIVEAOT)
5+
6+
#ifndef __NATIVEAOT_BRIDGE__
7+
#define __NATIVEAOT_BRIDGE__
8+
9+
#include <stdatomic.h>
10+
11+
#include "runtime.h"
12+
13+
#ifdef __cplusplus
14+
extern "C" {
15+
#endif
16+
17+
void xamarin_objcruntime_runtime_nativeaotinitialize (struct InitializationOptions* options, GCHandle* exception_gchandle);
18+
int __managed__Main (int argc, const char** argv);
19+
20+
#ifdef __cplusplus
21+
} /* extern "C" */
22+
#endif
23+
24+
#endif /* __NATIVEAOT_BRIDGE__ */
25+
26+
#endif // NATIVEAOT

src/ObjCRuntime/Runtime.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,20 @@ internal static bool Initialized {
249249
static extern int _NSGetExecutablePath (byte[] buf, ref int bufsize);
250250
#endif
251251

252+
#if NET
253+
[Preserve] // called from native - nativeaot-bridge.m and coreclr-bridge.m.
254+
[UnmanagedCallersOnly (EntryPoint = "xamarin_objcruntime_runtime_nativeaotinitialize")]
255+
unsafe static void SafeInitialize (InitializationOptions* options, IntPtr* exception_gchandle)
256+
{
257+
*exception_gchandle = IntPtr.Zero;
258+
try {
259+
Initialize (options);
260+
} catch (Exception e) {
261+
*exception_gchandle = AllocGCHandle (e);
262+
}
263+
}
264+
#endif
265+
252266
[Preserve] // called from native - runtime.m.
253267
[BindingImpl (BindingImplOptions.Optimizable)] // To inline the Runtime.DynamicRegistrationSupported code if possible.
254268
unsafe static void Initialize (InitializationOptions* options)

0 commit comments

Comments
 (0)