@@ -141,10 +141,14 @@ public static InvokeFunc_ObjSpanArgs CreateInvokeDelegate_ObjSpanArgs(MethodBase
141141 }
142142
143143 public static InvokeFunc_RefArgs CreateInvokeDelegate_RefArgs ( MethodBase method , bool backwardsCompat )
144+ => CreateInvokeDelegate_RefArgs ( method , backwardsCompat , constructorWithoutAllocation : false ) ;
145+
146+ public static InvokeFunc_RefArgs CreateInvokeDelegate_RefArgs ( MethodBase method , bool backwardsCompat , bool constructorWithoutAllocation )
144147 {
145148 Debug . Assert ( ! method . ContainsGenericParameters ) ;
149+ Debug . Assert ( ! constructorWithoutAllocation || method is RuntimeConstructorInfo ) ;
146150
147- bool emitNew = method is RuntimeConstructorInfo ;
151+ bool emitNew = method is RuntimeConstructorInfo && ! constructorWithoutAllocation ;
148152 bool hasThis = ! ( emitNew || method . IsStatic ) ;
149153
150154 // The first parameter is unused but supports treating the DynamicMethod as an instance method which is slightly faster than a static.
@@ -190,7 +194,7 @@ public static InvokeFunc_RefArgs CreateInvokeDelegate_RefArgs(MethodBase method,
190194 }
191195 }
192196
193- EmitCallAndReturnHandling ( il , method , emitNew , backwardsCompat ) ;
197+ EmitCallAndReturnHandling ( il , method , emitNew , backwardsCompat , constructorWithoutAllocation ) ;
194198
195199 // Create the delegate; it is also compiled at this point due to restrictedSkipVisibility=true.
196200 return ( InvokeFunc_RefArgs ) dm . CreateDelegate ( typeof ( InvokeFunc_RefArgs ) , target : null ) ;
@@ -205,7 +209,7 @@ private static void Unbox(ILGenerator il, Type parameterType)
205209 il . Emit ( OpCodes . Ldobj , parameterType ) ;
206210 }
207211
208- private static void EmitCallAndReturnHandling ( ILGenerator il , MethodBase method , bool emitNew , bool backwardsCompat )
212+ private static void EmitCallAndReturnHandling ( ILGenerator il , MethodBase method , bool emitNew , bool backwardsCompat , bool constructorWithoutAllocation = false )
209213 {
210214 // For CallStack reasons, don't inline target method.
211215 // Mono interpreter does not support\need this.
@@ -224,6 +228,11 @@ private static void EmitCallAndReturnHandling(ILGenerator il, MethodBase method,
224228 {
225229 il . Emit ( OpCodes . Newobj , ( ConstructorInfo ) method ) ;
226230 }
231+ else if ( method is RuntimeConstructorInfo )
232+ {
233+ // Constructor invocation on an existing target object.
234+ il . Emit ( OpCodes . Call , ( ConstructorInfo ) method ) ;
235+ }
227236 else if ( method . IsStatic || method . DeclaringType ! . IsValueType )
228237 {
229238 il . Emit ( OpCodes . Call , ( MethodInfo ) method ) ;
@@ -242,6 +251,10 @@ private static void EmitCallAndReturnHandling(ILGenerator il, MethodBase method,
242251 il . Emit ( OpCodes . Box , returnType ) ;
243252 }
244253 }
254+ else if ( constructorWithoutAllocation )
255+ {
256+ il . Emit ( OpCodes . Ldnull ) ;
257+ }
245258 else
246259 {
247260 RuntimeType returnType ;
0 commit comments