@@ -70,6 +70,7 @@ internal static SignatureHelper GetMethodSigHelper(
7070 sigHelp = new SignatureHelper ( scope , intCall , cGenericParam , returnType ,
7171 requiredReturnTypeCustomModifiers , optionalReturnTypeCustomModifiers ) ;
7272
73+ sigHelp . m_returnType = returnType ;
7374 sigHelp . AddArguments ( parameterTypes , requiredParameterTypeCustomModifiers , optionalParameterTypeCustomModifiers ) ;
7475
7576 return sigHelp ;
@@ -105,6 +106,52 @@ internal static SignatureHelper GetMethodSigHelper(Module? mod, CallingConventio
105106 return new SignatureHelper ( mod , intCall , returnType , null , null ) ;
106107 }
107108
109+ internal static SignatureHelper GetMethodSigHelper ( DynamicScope scope , Type functionPointerType )
110+ {
111+ Debug . Assert ( functionPointerType . IsFunctionPointer ) ;
112+
113+ Type retType = functionPointerType . GetFunctionPointerReturnType ( ) ;
114+ Type [ ] retTypeModReqs = retType . GetRequiredCustomModifiers ( ) ;
115+ Type [ ] retTypeModOpts = retType . GetOptionalCustomModifiers ( ) ;
116+ Type [ ] paramTypes = functionPointerType . GetFunctionPointerParameterTypes ( ) ;
117+ Type [ ] [ ] paramModReqs = new Type [ paramTypes . Length ] [ ] ;
118+ Type [ ] [ ] paramModOpts = new Type [ paramTypes . Length ] [ ] ;
119+
120+ retType = retType . UnderlyingSystemType ;
121+
122+ for ( int i = 0 ; i < paramTypes . Length ; i ++ )
123+ {
124+ paramModReqs [ i ] = paramTypes [ i ] . GetRequiredCustomModifiers ( ) ;
125+ paramModOpts [ i ] = paramTypes [ i ] . GetOptionalCustomModifiers ( ) ;
126+ paramTypes [ i ] = paramTypes [ i ] . UnderlyingSystemType ;
127+ }
128+
129+ MdSigCallingConvention callConv = MdSigCallingConvention . Default ;
130+
131+ if ( functionPointerType . IsUnmanagedFunctionPointer )
132+ {
133+ callConv = MdSigCallingConvention . Unmanaged ;
134+
135+ if ( functionPointerType . GetFunctionPointerCallingConventions ( ) is { Length : 1 } conventions )
136+ {
137+ callConv = conventions [ 0 ] . FullName switch
138+ {
139+ "System.Runtime.CompilerServices.CallConvCdecl" => MdSigCallingConvention . C ,
140+ "System.Runtime.CompilerServices.CallConvStdcall" => MdSigCallingConvention . StdCall ,
141+ "System.Runtime.CompilerServices.CallConvThiscall" => MdSigCallingConvention . ThisCall ,
142+ "System.Runtime.CompilerServices.CallConvFastcall" => MdSigCallingConvention . FastCall ,
143+ _ => MdSigCallingConvention . Unmanaged
144+ } ;
145+ }
146+ }
147+
148+ SignatureHelper sig = new ( null , callConv ) ;
149+ sig . m_returnType = retType ;
150+ sig . AddDynamicArgument ( scope , retType , retTypeModReqs , retTypeModOpts , false ) ;
151+ sig . AddArguments ( scope , paramTypes , paramModReqs , paramModOpts ) ;
152+ return sig ;
153+ }
154+
108155 public static SignatureHelper GetLocalVarSigHelper ( )
109156 {
110157 return GetLocalVarSigHelper ( null ) ;
@@ -179,6 +226,7 @@ internal static SignatureHelper GetTypeSigToken(Module module, Type type)
179226 private ModuleBuilder ? m_module ;
180227 private bool m_sigDone ;
181228 private int m_argCount ; // tracking number of arguments in the signature
229+ private Type ? m_returnType ;
182230 #endregion
183231
184232 #region Constructor
@@ -197,6 +245,7 @@ private SignatureHelper(Module? mod, MdSigCallingConvention callingConvention, i
197245 if ( callingConvention == MdSigCallingConvention . Field )
198246 throw new ArgumentException ( SR . Argument_BadFieldSig ) ;
199247
248+ m_returnType = returnType ;
200249 AddOneArgTypeHelper ( returnType , requiredCustomModifiers , optionalCustomModifiers ) ;
201250 }
202251
@@ -320,8 +369,8 @@ private void AddOneArgTypeHelper(Type clsArgument, Type[]? requiredCustomModifie
320369 AddOneArgTypeHelper ( clsArgument ) ;
321370 }
322371
323- private void AddOneArgTypeHelper ( Type clsArgument ) { AddOneArgTypeHelperWorker ( clsArgument , false ) ; }
324- private void AddOneArgTypeHelperWorker ( Type clsArgument , bool lastWasGenericInst )
372+ private void AddOneArgTypeHelper ( Type clsArgument , DynamicScope ? scope = null ) { AddOneArgTypeHelperWorker ( clsArgument , false , scope ) ; }
373+ private void AddOneArgTypeHelperWorker ( Type clsArgument , bool lastWasGenericInst , DynamicScope ? scope )
325374 {
326375 if ( clsArgument . IsGenericParameter )
327376 {
@@ -336,14 +385,14 @@ private void AddOneArgTypeHelperWorker(Type clsArgument, bool lastWasGenericInst
336385 {
337386 AddElementType ( CorElementType . ELEMENT_TYPE_GENERICINST ) ;
338387
339- AddOneArgTypeHelperWorker ( clsArgument . GetGenericTypeDefinition ( ) , true ) ;
388+ AddOneArgTypeHelperWorker ( clsArgument . GetGenericTypeDefinition ( ) , true , scope ) ;
340389
341390 Type [ ] args = clsArgument . GetGenericArguments ( ) ;
342391
343392 AddData ( args . Length ) ;
344393
345394 foreach ( Type t in args )
346- AddOneArgTypeHelper ( t ) ;
395+ AddOneArgTypeHelper ( t , scope ) ;
347396 }
348397 else if ( clsArgument is RuntimeTypeBuilder clsBuilder )
349398 {
@@ -394,26 +443,26 @@ private void AddOneArgTypeHelperWorker(Type clsArgument, bool lastWasGenericInst
394443 {
395444 AddElementType ( CorElementType . ELEMENT_TYPE_BYREF ) ;
396445 clsArgument = clsArgument . GetElementType ( ) ! ;
397- AddOneArgTypeHelper ( clsArgument ) ;
446+ AddOneArgTypeHelper ( clsArgument , scope ) ;
398447 }
399448 else if ( clsArgument . IsPointer )
400449 {
401450 AddElementType ( CorElementType . ELEMENT_TYPE_PTR ) ;
402- AddOneArgTypeHelper ( clsArgument . GetElementType ( ) ! ) ;
451+ AddOneArgTypeHelper ( clsArgument . GetElementType ( ) ! , scope ) ;
403452 }
404453 else if ( clsArgument . IsArray )
405454 {
406455 if ( clsArgument . IsSZArray )
407456 {
408457 AddElementType ( CorElementType . ELEMENT_TYPE_SZARRAY ) ;
409458
410- AddOneArgTypeHelper ( clsArgument . GetElementType ( ) ! ) ;
459+ AddOneArgTypeHelper ( clsArgument . GetElementType ( ) ! , scope ) ;
411460 }
412461 else
413462 {
414463 AddElementType ( CorElementType . ELEMENT_TYPE_ARRAY ) ;
415464
416- AddOneArgTypeHelper ( clsArgument . GetElementType ( ) ! ) ;
465+ AddOneArgTypeHelper ( clsArgument . GetElementType ( ) ! , scope ) ;
417466
418467 // put the rank information
419468 int rank = clsArgument . GetArrayRank ( ) ;
@@ -424,6 +473,25 @@ private void AddOneArgTypeHelperWorker(Type clsArgument, bool lastWasGenericInst
424473 AddData ( 0 ) ;
425474 }
426475 }
476+ else if ( clsArgument . IsFunctionPointer )
477+ {
478+ if ( scope == null )
479+ throw new NotSupportedException ( SR . NotSupported_FunctionPointerSignature ) ;
480+
481+ AddData ( ( int ) CorElementType . ELEMENT_TYPE_FNPTR ) ;
482+ SignatureHelper sig = GetMethodSigHelper ( scope , clsArgument ) ;
483+ byte [ ] bytes = sig . GetSignature ( ) ;
484+
485+ if ( m_currSig + bytes . Length > m_signature . Length )
486+ {
487+ m_signature = ExpandArray ( m_signature , m_signature . Length + bytes . Length ) ;
488+ }
489+
490+ for ( int i = 0 ; i < bytes . Length ; i ++ )
491+ {
492+ m_signature [ m_currSig ++ ] = bytes [ i ] ;
493+ }
494+ }
427495 else
428496 {
429497 CorElementType type = CorElementType . ELEMENT_TYPE_MAX ;
@@ -649,6 +717,7 @@ private void SetNumberOfSignatureElements(bool forceCopy)
649717
650718 #region Internal Members
651719 internal int ArgumentCount => m_argCount ;
720+ internal Type ? ReturnType => m_returnType ;
652721
653722 internal static bool IsSimpleType ( CorElementType type )
654723 {
@@ -729,9 +798,10 @@ internal byte[] InternalGetSignatureArray()
729798 return temp ;
730799 }
731800
732- internal void AddDynamicArgument ( DynamicScope dynamicScope , Type clsArgument , Type [ ] ? requiredCustomModifiers , Type [ ] ? optionalCustomModifiers )
801+ internal void AddDynamicArgument ( DynamicScope dynamicScope , Type clsArgument , Type [ ] ? requiredCustomModifiers , Type [ ] ? optionalCustomModifiers , bool incrementArgCount = true )
733802 {
734- IncrementArgCounts ( ) ;
803+ if ( incrementArgCount )
804+ IncrementArgCounts ( ) ;
735805
736806 Debug . Assert ( clsArgument != null ) ;
737807
@@ -750,6 +820,9 @@ internal void AddDynamicArgument(DynamicScope dynamicScope, Type clsArgument, Ty
750820 if ( t . ContainsGenericParameters )
751821 throw new ArgumentException ( SR . Argument_GenericsInvalid , nameof ( optionalCustomModifiers ) ) ;
752822
823+ if ( t . IsFunctionPointer )
824+ throw new ArgumentException ( SR . Argument_FunctionPointersInvalid , nameof ( optionalCustomModifiers ) ) ;
825+
753826 AddElementType ( CorElementType . ELEMENT_TYPE_CMOD_OPT ) ;
754827
755828 int token = dynamicScope . GetTokenFor ( rtType . TypeHandle ) ;
@@ -773,6 +846,9 @@ internal void AddDynamicArgument(DynamicScope dynamicScope, Type clsArgument, Ty
773846 if ( t . ContainsGenericParameters )
774847 throw new ArgumentException ( SR . Argument_GenericsInvalid , nameof ( requiredCustomModifiers ) ) ;
775848
849+ if ( t . IsFunctionPointer )
850+ throw new ArgumentException ( SR . Argument_FunctionPointersInvalid , nameof ( requiredCustomModifiers ) ) ;
851+
776852 AddElementType ( CorElementType . ELEMENT_TYPE_CMOD_REQD ) ;
777853
778854 int token = dynamicScope . GetTokenFor ( rtType . TypeHandle ) ;
@@ -781,7 +857,18 @@ internal void AddDynamicArgument(DynamicScope dynamicScope, Type clsArgument, Ty
781857 }
782858 }
783859
784- AddOneArgTypeHelper ( clsArgument ) ;
860+ AddOneArgTypeHelper ( clsArgument , dynamicScope ) ;
861+ }
862+
863+ internal void AddArguments ( DynamicScope dynamicScope , Type [ ] ? arguments , Type [ ] [ ] ? requiredCustomModifiers , Type [ ] [ ] ? optionalCustomModifiers )
864+ {
865+ if ( arguments is null )
866+ return ;
867+
868+ for ( int i = 0 ; i < arguments . Length ; i ++ )
869+ {
870+ AddDynamicArgument ( dynamicScope , arguments [ i ] , requiredCustomModifiers ? [ i ] , optionalCustomModifiers ? [ i ] ) ;
871+ }
785872 }
786873
787874 #endregion
0 commit comments