| File: System\Activator.NativeAot.cs | Web Access |
| Project: src\runtime\src\coreclr\nativeaot\System.Private.CoreLib\src\System.Private.CoreLib.csproj (System.Private.CoreLib) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // // Activator is an object that contains the Activation (CreateInstance/New) // methods for late bound support. // using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Reflection; using System.Runtime; using System.Runtime.CompilerServices; using System.Runtime.Remoting; using Internal.Reflection.Augments; using Internal.Runtime; using Internal.Runtime.CompilerServices; namespace System { public static partial class Activator { // The following methods and helper class implement the functionality of Activator.CreateInstance<T>() // The implementation relies on several compiler intrinsics that expand to quick dictionary lookups in shared // code, and direct constant references in unshared code. // // This method is the public surface area. It wraps the CreateInstance intrinsic with the appropriate try/catch // block so that the correct exceptions are generated. Also, it handles the cases where the T type doesn't have // a default constructor. // // This method is intrinsic. The compiler might replace it with more efficient implementation. [DebuggerGuidedStepThrough] [Intrinsic] public static unsafe T CreateInstance<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)] T>() { // Grab the pointer to the default constructor of the type. If T doesn't have a default // constructor, the intrinsic returns a marker pointer that we check for. IntPtr defaultConstructor = DefaultConstructorOf<T>(); // Check if we got the marker back. // // TODO: might want to disambiguate the different cases for abstract class, interface, etc. if (defaultConstructor == (IntPtr)(delegate*<Guid>)&MissingConstructorMethod) throw new MissingMethodException(SR.Format(SR.MissingConstructor_Name, typeof(T))); T t; try { // Call the default constructor on the allocated instance. if (!typeof(T).IsValueType) { // Grab a pointer to the optimized allocator for the type and call it. IntPtr allocator = AllocatorOf<T>(); t = RawCalliHelper.Call<T>(allocator, (nint)MethodTable.Of<T>()); RawCalliHelper.Call(defaultConstructor, t); // Debugger goo so that stepping in works. Only affects debug info generation. // The call gets optimized away. DebugAnnotations.PreviousCallContainsDebuggerStepInCode(); } else { t = default!; RawCalliHelper.CallDefaultStructConstructor(defaultConstructor, ref Unsafe.As<T, byte>(ref t)); // Debugger goo so that stepping in works. Only affects debug info generation. // The call gets optimized away. DebugAnnotations.PreviousCallContainsDebuggerStepInCode(); } return t; } catch (Exception e) { throw new TargetInvocationException(e); } } [Intrinsic] private static IntPtr DefaultConstructorOf<T>() { // Codegens must expand this intrinsic to the pointer to the default constructor of T // or to a marker that lets us detect there's no default constructor. // We could implement a fallback with the type loader if we wanted to, but it will be slow and unreliable. throw new NotSupportedException(); } [Intrinsic] private static IntPtr AllocatorOf<T>() { // Codegens must expand this intrinsic to the pointer to the allocator suitable to allocate an instance of T. // We could implement a fallback with the type loader if we wanted to, but it will be slow and unreliable. throw new NotSupportedException(); } internal static unsafe IntPtr GetFallbackDefaultConstructor() { return (IntPtr)(delegate*<Guid>)&MissingConstructorMethod; } // This is a marker method. We return a GUID just to make sure the body is unique // and under no circumstances gets folded. private static Guid MissingConstructorMethod() => new Guid(0x68be9718, 0xf787, 0x45ab, 0x84, 0x3b, 0x1f, 0x31, 0xb6, 0x12, 0x65, 0xeb); // The constructor of this struct is used when there's no constructor private struct StructWithNoConstructor { public StructWithNoConstructor() { } } [DebuggerHidden] [DebuggerStepThrough] public static object? CreateInstance([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.NonPublicConstructors)] Type type, bool nonPublic) => ReflectionAugments.ActivatorCreateInstance(type, nonPublic); [DebuggerHidden] [DebuggerStepThrough] public static object? CreateInstance([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.PublicConstructors)] Type type, BindingFlags bindingAttr, Binder? binder, object?[]? args, CultureInfo? culture, object?[]? activationAttributes) => ReflectionAugments.ActivatorCreateInstance(type, bindingAttr, binder, args, culture, activationAttributes); [RequiresUnreferencedCode("Type and its constructor could be removed")] public static ObjectHandle CreateInstance(string assemblyName, string typeName) { throw new PlatformNotSupportedException(); // https://github.com/dotnet/runtime/issues/26701 } [RequiresUnreferencedCode("Type and its constructor could be removed")] public static ObjectHandle CreateInstance(string assemblyName, string typeName, bool ignoreCase, BindingFlags bindingAttr, Binder? binder, object?[]? args, CultureInfo? culture, object?[]? activationAttributes) { throw new PlatformNotSupportedException(); // https://github.com/dotnet/runtime/issues/26701 } [RequiresUnreferencedCode("Type and its constructor could be removed")] public static ObjectHandle CreateInstance(string assemblyName, string typeName, object?[]? activationAttributes) { throw new PlatformNotSupportedException(); // https://github.com/dotnet/runtime/issues/26701 } } }