22using System . Collections . Generic ;
33using System . Diagnostics ;
44using System . Diagnostics . CodeAnalysis ;
5- using System . IO ;
65using System . Linq ;
76using System . Management ;
87using System . Reflection ;
98using System . Runtime . InteropServices ;
109using System . Text . RegularExpressions ;
1110using BenchmarkDotNet . Detectors ;
12- using BenchmarkDotNet . Detectors . Cpu ;
1311using BenchmarkDotNet . Environments ;
1412using BenchmarkDotNet . Extensions ;
1513using BenchmarkDotNet . Helpers ;
16- using JetBrains . Annotations ;
17- using Microsoft . Win32 ;
18- using Perfolizer . Helpers ;
1914using static System . Runtime . InteropServices . RuntimeInformation ;
20- using RuntimeEnvironment = Microsoft . DotNet . PlatformAbstractions . RuntimeEnvironment ;
2115
2216namespace BenchmarkDotNet . Portability
2317{
@@ -50,24 +44,15 @@ internal static class RuntimeInformation
5044
5145 public static readonly bool IsNetNative = FrameworkDescription . StartsWith ( ".NET Native" , StringComparison . OrdinalIgnoreCase ) ;
5246
53- public static readonly bool IsNetCore =
54- ( ( Environment . Version . Major >= 5 ) || FrameworkDescription . StartsWith ( ".NET Core" , StringComparison . OrdinalIgnoreCase ) )
55- && ! string . IsNullOrEmpty ( typeof ( object ) . Assembly . Location ) ;
56-
5747#if NET6_0_OR_GREATER
5848 [ System . Runtime . Versioning . SupportedOSPlatformGuard ( "browser" ) ]
5949 public static readonly bool IsWasm = OperatingSystem . IsBrowser ( ) ;
6050#else
6151 public static readonly bool IsWasm = IsOSPlatform ( OSPlatform . Create ( "BROWSER" ) ) ;
6252#endif
6353
64- public static readonly bool IsNativeAOT =
65- Environment . Version . Major >= 5
66- && string . IsNullOrEmpty ( typeof ( object ) . Assembly . Location ) // it's merged to a single .exe and .Location returns null
67- && ! IsWasm ; // Wasm also returns "" for assembly locations
68-
6954#if NETSTANDARD2_0
70- public static readonly bool IsAot = IsAotMethod ( ) ;
55+ public static readonly bool IsAot = IsAotMethod ( ) || IsNetNative ;
7156
7257 private static bool IsAotMethod ( )
7358 {
@@ -88,6 +73,16 @@ private static bool IsAotMethod()
8873 public static readonly bool IsAot = ! System . Runtime . CompilerServices . RuntimeFeature . IsDynamicCodeCompiled ;
8974#endif
9075
76+ public static bool IsNetCore
77+ => ( ( Environment . Version . Major >= 5 ) || FrameworkDescription . StartsWith ( ".NET Core" , StringComparison . OrdinalIgnoreCase ) )
78+ && ! IsAot ;
79+
80+ public static bool IsNativeAOT
81+ => Environment . Version . Major >= 5
82+ && IsAot
83+ && ! IsWasm && ! IsMono ; // Wasm and MonoAOTLLVM are also AOT
84+
85+
9186 public static readonly bool IsTieredJitEnabled =
9287 IsNetCore
9388 && ( Environment . Version . Major < 3
@@ -173,10 +168,21 @@ private static string GetNetCoreVersion()
173168 }
174169 else
175170 {
176- var coreclrAssemblyInfo = FileVersionInfo . GetVersionInfo ( typeof ( object ) . GetTypeInfo ( ) . Assembly . Location ) ;
177- var corefxAssemblyInfo = FileVersionInfo . GetVersionInfo ( typeof ( Regex ) . GetTypeInfo ( ) . Assembly . Location ) ;
171+ string coreclrLocation = typeof ( object ) . GetTypeInfo ( ) . Assembly . Location ;
172+ string corefxLocation = typeof ( Regex ) . GetTypeInfo ( ) . Assembly . Location ;
178173
179- if ( CoreRuntime . TryGetVersion ( out var version ) && version >= new Version ( 5 , 0 ) )
174+ // Handle cases where assembly location is empty (e.g. single-file publish, AOT, some test runners)
175+ if ( string . IsNullOrEmpty ( coreclrLocation ) || string . IsNullOrEmpty ( corefxLocation ) )
176+ {
177+ return CoreRuntime . TryGetVersion ( out var ver ) && ver . Major >= 5
178+ ? $ ".NET { ver } (assembly location unavailable)"
179+ : $ ".NET Core { ver ? . ToString ( ) ?? Unknown } (assembly location unavailable)";
180+ }
181+
182+ var coreclrAssemblyInfo = FileVersionInfo . GetVersionInfo ( coreclrLocation ) ;
183+ var corefxAssemblyInfo = FileVersionInfo . GetVersionInfo ( corefxLocation ) ;
184+
185+ if ( CoreRuntime . TryGetVersion ( out var version ) && version . Major >= 5 )
180186 {
181187 // after the merge of dotnet/corefx and dotnet/coreclr into dotnet/runtime the version should always be the same
182188 Debug . Assert ( coreclrAssemblyInfo . FileVersion == corefxAssemblyInfo . FileVersion ) ;
@@ -185,9 +191,7 @@ private static string GetNetCoreVersion()
185191 }
186192 else
187193 {
188- string runtimeVersion = version != default ? version . ToString ( ) : Unknown ;
189-
190- return $ ".NET Core { runtimeVersion } (CoreCLR { coreclrAssemblyInfo . FileVersion } , CoreFX { corefxAssemblyInfo . FileVersion } )";
194+ return $ ".NET Core { version ? . ToString ( ) ?? Unknown } (CoreCLR { coreclrAssemblyInfo . FileVersion } , CoreFX { corefxAssemblyInfo . FileVersion } )";
191195 }
192196 }
193197 }
0 commit comments