3
3
4
4
using System . Diagnostics ;
5
5
using System . Diagnostics . CodeAnalysis ;
6
+ using System . Reflection ;
7
+ using System . Runtime . CompilerServices ;
6
8
using System . Runtime . InteropServices ;
9
+ using System . Runtime . Serialization ;
7
10
using Internal . Runtime . CompilerServices ;
8
11
9
12
namespace System . Runtime . CompilerServices
@@ -39,12 +42,16 @@ public static partial class RuntimeHelpers
39
42
// This call will generate an exception if the specified class constructor threw an
40
43
// exception when it ran.
41
44
42
- [ MethodImpl ( MethodImplOptions . InternalCall ) ]
43
- private static extern void _RunClassConstructor ( RuntimeType type ) ;
45
+ [ DllImport ( RuntimeHelpers . QCall , CharSet = CharSet . Unicode ) ]
46
+ private static extern void RunClassConstructor ( QCallTypeHandle type ) ;
44
47
45
48
public static void RunClassConstructor ( RuntimeTypeHandle type )
46
49
{
47
- _RunClassConstructor ( type . GetRuntimeType ( ) ) ;
50
+ RuntimeType rt = type . GetRuntimeType ( ) ;
51
+ if ( rt is null )
52
+ throw new ArgumentException ( SR . InvalidOperation_HandleIsNotInitialized , nameof ( type ) ) ;
53
+
54
+ RunClassConstructor ( new QCallTypeHandle ( ref rt ) ) ;
48
55
}
49
56
50
57
// RunModuleConstructor causes the module constructor for the given type to be triggered
@@ -55,42 +62,41 @@ public static void RunClassConstructor(RuntimeTypeHandle type)
55
62
// This call will generate an exception if the specified module constructor threw an
56
63
// exception when it ran.
57
64
58
- [ MethodImpl ( MethodImplOptions . InternalCall ) ]
59
- private static extern void _RunModuleConstructor ( System . Reflection . RuntimeModule module ) ;
65
+ [ DllImport ( RuntimeHelpers . QCall , CharSet = CharSet . Unicode ) ]
66
+ private static extern void RunModuleConstructor ( QCallModule module ) ;
60
67
61
68
public static void RunModuleConstructor ( ModuleHandle module )
62
69
{
63
- _RunModuleConstructor ( module . GetRuntimeModule ( ) ) ;
70
+ RuntimeModule rm = module . GetRuntimeModule ( ) ;
71
+ if ( rm is null )
72
+ throw new ArgumentException ( SR . InvalidOperation_HandleIsNotInitialized , nameof ( module ) ) ;
73
+
74
+ RunModuleConstructor ( new QCallModule ( ref rm ) ) ;
64
75
}
65
76
77
+ [ DllImport ( RuntimeHelpers . QCall , CharSet = CharSet . Unicode ) ]
78
+ internal static extern void CompileMethod ( RuntimeMethodHandleInternal method ) ;
66
79
67
80
[ DllImport ( RuntimeHelpers . QCall , CharSet = CharSet . Unicode ) ]
68
- internal static extern void _CompileMethod ( RuntimeMethodHandleInternal method ) ;
81
+ private static extern unsafe void PrepareMethod ( RuntimeMethodHandleInternal method , IntPtr * pInstantiation , int cInstantiation ) ;
69
82
70
- [ MethodImpl ( MethodImplOptions . InternalCall ) ]
71
- private static extern unsafe void _PrepareMethod ( IRuntimeMethodInfo method , IntPtr * pInstantiation , int cInstantiation ) ;
83
+ public static void PrepareMethod ( RuntimeMethodHandle method ) => PrepareMethod ( method , null ) ;
72
84
73
- public static void PrepareMethod ( RuntimeMethodHandle method )
85
+ public static unsafe void PrepareMethod ( RuntimeMethodHandle method , RuntimeTypeHandle [ ] ? instantiation )
74
86
{
75
- unsafe
76
- {
77
- _PrepareMethod ( method . GetMethodInfo ( ) , null , 0 ) ;
78
- }
79
- }
87
+ IRuntimeMethodInfo methodInfo = method . GetMethodInfo ( ) ;
88
+ if ( methodInfo == null )
89
+ throw new ArgumentException ( SR . InvalidOperation_HandleIsNotInitialized , nameof ( method ) ) ;
80
90
81
- public static void PrepareMethod ( RuntimeMethodHandle method , RuntimeTypeHandle [ ] ? instantiation )
82
- {
83
91
// defensive copy of user-provided array, per CopyRuntimeTypeHandles contract
84
92
instantiation = ( RuntimeTypeHandle [ ] ? ) instantiation ? . Clone ( ) ;
85
93
86
- unsafe
94
+ IntPtr [ ] ? instantiationHandles = RuntimeTypeHandle . CopyRuntimeTypeHandles ( instantiation , out int length ) ;
95
+ fixed ( IntPtr * pInstantiation = instantiationHandles )
87
96
{
88
- IntPtr [ ] ? instantiationHandles = RuntimeTypeHandle . CopyRuntimeTypeHandles ( instantiation , out int length ) ;
89
- fixed ( IntPtr * pInstantiation = instantiationHandles )
90
- {
91
- _PrepareMethod ( method . GetMethodInfo ( ) , pInstantiation , length ) ;
92
- GC . KeepAlive ( instantiation ) ;
93
- }
97
+ PrepareMethod ( methodInfo . Value , pInstantiation , length ) ;
98
+ GC . KeepAlive ( instantiation ) ;
99
+ GC . KeepAlive ( methodInfo ) ;
94
100
}
95
101
}
96
102
@@ -138,15 +144,32 @@ public static int OffsetToStringData
138
144
[ MethodImpl ( MethodImplOptions . InternalCall ) ]
139
145
public static extern bool TryEnsureSufficientExecutionStack ( ) ;
140
146
141
- [ MethodImpl ( MethodImplOptions . InternalCall ) ]
142
- private static extern object GetUninitializedObjectInternal (
147
+ public static object GetUninitializedObject (
143
148
// This API doesn't call any constructors, but the type needs to be seen as constructed.
144
149
// A type is seen as constructed if a constructor is kept.
145
150
// This obviously won't cover a type with no constructor. Reference types with no
146
151
// constructor are an academic problem. Valuetypes with no constructors are a problem,
147
152
// but IL Linker currently treats them as always implicitly boxed.
148
153
[ DynamicallyAccessedMembers ( DynamicallyAccessedMemberTypes . PublicConstructors | DynamicallyAccessedMemberTypes . NonPublicConstructors ) ]
149
- Type type ) ;
154
+ Type type )
155
+ {
156
+ if ( type is not RuntimeType rt )
157
+ {
158
+ if ( type is null )
159
+ {
160
+ throw new ArgumentNullException ( nameof ( type ) , SR . ArgumentNull_Type ) ;
161
+ }
162
+
163
+ throw new SerializationException ( SR . Format ( SR . Serialization_InvalidType , type ) ) ;
164
+ }
165
+
166
+ object ? obj = null ;
167
+ GetUninitializedObject ( new QCallTypeHandle ( ref rt ) , ObjectHandleOnStack . Create ( ref obj ) ) ;
168
+ return obj ! ;
169
+ }
170
+
171
+ [ DllImport ( RuntimeHelpers . QCall ) ]
172
+ private static extern void GetUninitializedObject ( QCallTypeHandle type , ObjectHandleOnStack retObject ) ;
150
173
151
174
[ MethodImpl ( MethodImplOptions . InternalCall ) ]
152
175
internal static extern object AllocateUninitializedClone ( object obj ) ;
@@ -280,11 +303,11 @@ public static IntPtr AllocateTypeAssociatedMemory(Type type, int size)
280
303
if ( size < 0 )
281
304
throw new ArgumentOutOfRangeException ( nameof ( size ) ) ;
282
305
283
- return AllocateTypeAssociatedMemoryInternal ( new QCallTypeHandle ( ref rt ) , ( uint ) size ) ;
306
+ return AllocateTypeAssociatedMemory ( new QCallTypeHandle ( ref rt ) , ( uint ) size ) ;
284
307
}
285
308
286
309
[ DllImport ( RuntimeHelpers . QCall ) ]
287
- private static extern IntPtr AllocateTypeAssociatedMemoryInternal ( QCallTypeHandle type , uint size ) ;
310
+ private static extern IntPtr AllocateTypeAssociatedMemory ( QCallTypeHandle type , uint size ) ;
288
311
289
312
[ MethodImpl ( MethodImplOptions . InternalCall ) ]
290
313
private static extern IntPtr AllocTailCallArgBuffer ( int size , IntPtr gcDesc ) ;
0 commit comments