@@ -963,18 +963,60 @@ private bool ImportReferences(ModuleDefinition moduleDefinition, string[] assemb
963963
964964 foreach ( var method in type . Methods )
965965 {
966+ // to reduce unnecessary type resolution, we first check if it can be a serialization extension without type resolution
967+
966968 if ( ! method . IsStatic )
967969 {
968970 continue ;
969971 }
970972
973+ if ( method . Name is not ( k_WriteValueMethodName or k_ReadValueMethodName ) )
974+ {
975+ continue ;
976+ }
977+
978+ var mayHaveExtensionAttr = false ;
979+
980+ foreach ( var attr in method . CustomAttributes )
981+ {
982+ if ( attr . Constructor . DeclaringType . FullName == extensionConstructor . DeclaringType . FullName )
983+ {
984+ mayHaveExtensionAttr = true ;
985+ break ;
986+ }
987+ }
988+
989+ if ( ! mayHaveExtensionAttr )
990+ {
991+ continue ;
992+ }
993+
994+ var parameters = method . Parameters ;
995+
996+ if ( parameters . Count != 2 )
997+ {
998+ continue ;
999+ }
1000+
1001+ var firstParameterType = parameters [ 0 ] . ParameterType ;
1002+
1003+ // ReadValueSafe() and WriteValueSafe() can use both by-ref and non-by-ref type for the first parameter type
1004+ var firstParameterElementType = firstParameterType is ByReferenceType byRefType ? byRefType . ElementType : firstParameterType ;
1005+
1006+ if ( firstParameterElementType . FullName != m_FastBufferWriter_TypeRef . FullName && firstParameterElementType . FullName != m_FastBufferReader_TypeRef . FullName )
1007+ {
1008+ continue ;
1009+ }
1010+
9711011 var isExtension = false ;
9721012
9731013 foreach ( var attr in method . CustomAttributes )
9741014 {
975- if ( attr . Constructor . Resolve ( ) == extensionConstructor . Resolve ( ) )
1015+ if ( attr . Constructor . DeclaringType . FullName == extensionConstructor . DeclaringType . FullName &&
1016+ attr . Constructor . Resolve ( ) == extensionConstructor . Resolve ( ) )
9761017 {
9771018 isExtension = true ;
1019+ break ;
9781020 }
9791021 }
9801022
@@ -983,13 +1025,11 @@ private bool ImportReferences(ModuleDefinition moduleDefinition, string[] assemb
9831025 continue ;
9841026 }
9851027
986- var parameters = method . Parameters ;
987-
988- if ( parameters . Count == 2 && parameters [ 0 ] . ParameterType . Resolve ( ) == m_FastBufferWriter_TypeRef . MakeByReferenceType ( ) . Resolve ( ) )
1028+ if ( method . Name == k_WriteValueMethodName && firstParameterType . Resolve ( ) == m_FastBufferWriter_TypeRef . MakeByReferenceType ( ) . Resolve ( ) )
9891029 {
9901030 m_FastBufferWriter_ExtensionMethodRefs . Add ( m_MainModule . ImportReference ( method ) ) ;
9911031 }
992- else if ( parameters . Count == 2 && parameters [ 0 ] . ParameterType . Resolve ( ) == m_FastBufferReader_TypeRef . MakeByReferenceType ( ) . Resolve ( ) )
1032+ else if ( method . Name == k_ReadValueMethodName && firstParameterType . Resolve ( ) == m_FastBufferReader_TypeRef . MakeByReferenceType ( ) . Resolve ( ) )
9931033 {
9941034 m_FastBufferReader_ExtensionMethodRefs . Add ( m_MainModule . ImportReference ( method ) ) ;
9951035 }
@@ -1789,27 +1829,24 @@ private bool GetWriteMethodForParameter(TypeReference paramType, out MethodRefer
17891829 {
17901830 var parameters = method. Resolve( ) . Parameters;
17911831
1792- if ( method . Name = = k_WriteValueMethodName )
1832+ if ( parameters [ 1 ] . IsIn )
17931833 {
1794- if ( parameters [ 1 ] . IsIn )
1834+ if ( ( ( ByReferenceType ) parameters [ 1 ] . ParameterType ) . ElementType . FullName == paramType . FullName &&
1835+ ( ( ByReferenceType ) parameters [ 1 ] . ParameterType ) . ElementType . IsArray == paramType . IsArray )
17951836 {
1796- if ( ( ( ByReferenceType ) parameters [ 1 ] . ParameterType ) . ElementType . FullName == paramType . FullName &&
1797- ( ( ByReferenceType ) parameters [ 1 ] . ParameterType ) . ElementType . IsArray == paramType . IsArray )
1798- {
1799- methodRef = method ;
1800- m_FastBufferWriter_WriteValue_MethodRefs[ assemblyQualifiedName ] = methodRef ;
1801- return true;
1802- }
1837+ methodRef = method ;
1838+ m_FastBufferWriter_WriteValue_MethodRefs[ assemblyQualifiedName ] = methodRef ;
1839+ return true;
18031840 }
1804- else
1841+ }
1842+ else
1843+ {
1844+ if ( parameters [ 1 ] . ParameterType . FullName == paramType . FullName &&
1845+ parameters [ 1 ] . ParameterType . IsArray == paramType . IsArray )
18051846 {
1806- if ( parameters [ 1 ] . ParameterType . FullName == paramType . FullName &&
1807- parameters [ 1 ] . ParameterType . IsArray == paramType . IsArray )
1808- {
1809- methodRef = method ;
1810- m_FastBufferWriter_WriteValue_MethodRefs[ assemblyQualifiedName ] = methodRef ;
1811- return true;
1812- }
1847+ methodRef = method ;
1848+ m_FastBufferWriter_WriteValue_MethodRefs[ assemblyQualifiedName ] = methodRef ;
1849+ return true;
18131850 }
18141851 }
18151852 }
@@ -2025,8 +2062,7 @@ private bool GetReadMethodForParameter(TypeReference paramType, out MethodRefere
20252062 foreach ( var method in m_FastBufferReader_ExtensionMethodRefs )
20262063 {
20272064 var parameters = method. Resolve( ) . Parameters;
2028- if ( method. Name = = k_ReadValueMethodName &&
2029- parameters [ 1 ] . IsOut &&
2065+ if ( parameters [ 1 ] . IsOut &&
20302066 ( ( ByReferenceType ) parameters [ 1 ] . ParameterType ) . ElementType . FullName == paramType . FullName &&
20312067 ( ( ByReferenceType ) parameters [ 1 ] . ParameterType ) . ElementType . IsArray == paramType . IsArray )
20322068 {
0 commit comments