@@ -302,16 +302,16 @@ private RuntimeCustomAttributeData(RuntimeModule scope, MetadataToken caCtorToke
302302 #region Pseudo Custom Attribute Constructor
303303 internal RuntimeCustomAttributeData ( Attribute attribute )
304304 {
305- if ( attribute is DllImportAttribute dllImportAttribute )
306- Init ( dllImportAttribute ) ;
307- else if ( attribute is FieldOffsetAttribute fieldOffsetAttribute )
308- Init ( fieldOffsetAttribute ) ;
309- else if ( attribute is MarshalAsAttribute marshalAsAttribute )
310- Init ( marshalAsAttribute ) ;
311- else if ( attribute is TypeForwardedToAttribute typeForwardedToAttribute )
312- Init ( typeForwardedToAttribute ) ;
313- else
314- Init ( attribute ) ;
305+ if ( attribute is DllImportAttribute dllImportAttribute )
306+ Init ( dllImportAttribute ) ;
307+ else if ( attribute is FieldOffsetAttribute fieldOffsetAttribute )
308+ Init ( fieldOffsetAttribute ) ;
309+ else if ( attribute is MarshalAsAttribute marshalAsAttribute )
310+ Init ( marshalAsAttribute ) ;
311+ else if ( attribute is TypeForwardedToAttribute typeForwardedToAttribute )
312+ Init ( typeForwardedToAttribute ) ;
313+ else
314+ Init ( attribute ) ;
315315 }
316316 private void Init ( DllImportAttribute dllImport )
317317 {
@@ -849,24 +849,24 @@ private static CustomAttributeEncodedArgument ParseCustomAttributeValue(
849849 arg . StringValue = parser . GetString ( ) ;
850850 break ;
851851 case CustomAttributeEncoding . Array :
852- {
853- arg . ArrayValue = null ;
854- int len = parser . GetI4 ( ) ;
855- if ( len != - 1 ) // indicates array is null - ECMA-335 II.23.3.
856852 {
857- attributeType = new CustomAttributeType (
858- attributeType . EncodedArrayType ,
859- CustomAttributeEncoding . Undefined , // Array type
860- attributeType . EncodedEnumType ,
861- attributeType . EnumType ) ;
862- arg . ArrayValue = new CustomAttributeEncodedArgument [ len ] ;
863- for ( int i = 0 ; i < len ; ++ i )
853+ arg . ArrayValue = null ;
854+ int len = parser . GetI4 ( ) ;
855+ if ( len != - 1 ) // indicates array is null - ECMA-335 II.23.3.
864856 {
865- arg . ArrayValue [ i ] = ParseCustomAttributeValue ( ref parser , attributeType , module ) ;
857+ attributeType = new CustomAttributeType (
858+ attributeType . EncodedArrayType ,
859+ CustomAttributeEncoding . Undefined , // Array type
860+ attributeType . EncodedEnumType ,
861+ attributeType . EnumType ) ;
862+ arg . ArrayValue = new CustomAttributeEncodedArgument [ len ] ;
863+ for ( int i = 0 ; i < len ; ++ i )
864+ {
865+ arg . ArrayValue [ i ] = ParseCustomAttributeValue ( ref parser , attributeType , module ) ;
866+ }
866867 }
868+ break ;
867869 }
868- break ;
869- }
870870 default :
871871 throw new BadImageFormatException ( ) ;
872872 }
@@ -1859,6 +1859,193 @@ private static bool ParseAttributeUsageAttribute(
18591859 return result != 0 ;
18601860 }
18611861
1862+ [ UnmanagedCallersOnly ]
1863+ [ RequiresUnsafe ]
1864+ private static unsafe void InvokeCustomAttributeCtor ( NativeCtorInvokeContract * pContract , object * pResult , Exception * pException )
1865+ {
1866+ try
1867+ {
1868+ object ? [ ] ? parameters = * pContract ->CtorArgs ;
1869+ byte [ ] ? argIsValueType = * pContract ->ArgIsValueType ;
1870+ object ? target = * pContract ->CtorTarget ;
1871+
1872+ int argCount = pContract ->ArgCount ;
1873+ if ( argCount < 0 || parameters is null || argIsValueType is null || parameters . Length != argCount || argIsValueType . Length != argCount )
1874+ {
1875+ throw new TargetParameterCountException ( SR . Arg_ParmCnt ) ;
1876+ }
1877+
1878+ if ( target is null )
1879+ {
1880+ throw new InvalidOperationException ( "Invalid constructor target." ) ;
1881+ }
1882+
1883+ object ctorTarget = target ;
1884+ object ? [ ] ctorArgs = parameters ;
1885+ byte [ ] argIsValueTypeFlags = argIsValueType ;
1886+
1887+ if ( pContract ->CtorEntryPoint == IntPtr . Zero )
1888+ {
1889+ throw new InvalidOperationException ( "Invalid constructor entry point." ) ;
1890+ }
1891+
1892+ if ( argCount == 0 )
1893+ {
1894+ ( ( delegate * < object , void > ) pContract ->CtorEntryPoint ) ( ctorTarget ) ;
1895+ * pResult = ctorTarget ;
1896+ return ;
1897+ }
1898+
1899+ if ( argCount == 1 )
1900+ {
1901+ object ? arg0 = ctorArgs [ 0 ] ;
1902+ if ( argIsValueTypeFlags [ 0 ] == 0 )
1903+ {
1904+ InstanceCalliHelper . Call ( ( delegate * < object , object ? , void > ) pContract ->CtorEntryPoint , ctorTarget , arg0 ) ;
1905+ }
1906+ else
1907+ {
1908+ if ( arg0 is null )
1909+ {
1910+ throw new InvalidOperationException ( "Value-type custom attribute ctor argument cannot be null." ) ;
1911+ }
1912+
1913+ Type argType = arg0 . GetType ( ) ;
1914+ if ( argType . IsEnum )
1915+ {
1916+ argType = Enum . GetUnderlyingType ( argType ) ;
1917+ }
1918+
1919+ switch ( Type . GetTypeCode ( argType ) )
1920+ {
1921+ case TypeCode . Boolean :
1922+ InstanceCalliHelper . Call ( ( delegate * < object , bool , void > ) pContract ->CtorEntryPoint , ctorTarget , ( bool ) arg0 ) ;
1923+ break ;
1924+ case TypeCode . Char :
1925+ InstanceCalliHelper . Call ( ( delegate * < object , char , void > ) pContract ->CtorEntryPoint , ctorTarget , ( char ) arg0 ) ;
1926+ break ;
1927+ case TypeCode . SByte :
1928+ InstanceCalliHelper . Call ( ( delegate * < object , sbyte , void > ) pContract ->CtorEntryPoint , ctorTarget , ( sbyte ) arg0 ) ;
1929+ break ;
1930+ case TypeCode . Byte :
1931+ InstanceCalliHelper . Call ( ( delegate * < object , byte , void > ) pContract ->CtorEntryPoint , ctorTarget , ( byte ) arg0 ) ;
1932+ break ;
1933+ case TypeCode . Int16 :
1934+ InstanceCalliHelper . Call ( ( delegate * < object , short , void > ) pContract ->CtorEntryPoint , ctorTarget , ( short ) arg0 ) ;
1935+ break ;
1936+ case TypeCode . UInt16 :
1937+ InstanceCalliHelper . Call ( ( delegate * < object , ushort , void > ) pContract ->CtorEntryPoint , ctorTarget , ( ushort ) arg0 ) ;
1938+ break ;
1939+ case TypeCode . Int32 :
1940+ InstanceCalliHelper . Call ( ( delegate * < object , int , void > ) pContract ->CtorEntryPoint , ctorTarget , ( int ) arg0 ) ;
1941+ break ;
1942+ case TypeCode . UInt32 :
1943+ InstanceCalliHelper . Call ( ( delegate * < object , uint , void > ) pContract ->CtorEntryPoint , ctorTarget , ( uint ) arg0 ) ;
1944+ break ;
1945+ case TypeCode . Int64 :
1946+ InstanceCalliHelper . Call ( ( delegate * < object , long , void > ) pContract ->CtorEntryPoint , ctorTarget , ( long ) arg0 ) ;
1947+ break ;
1948+ case TypeCode . UInt64 :
1949+ InstanceCalliHelper . Call ( ( delegate * < object , ulong , void > ) pContract ->CtorEntryPoint , ctorTarget , ( ulong ) arg0 ) ;
1950+ break ;
1951+ case TypeCode . Single :
1952+ InstanceCalliHelper . Call ( ( delegate * < object , float , void > ) pContract ->CtorEntryPoint , ctorTarget , ( float ) arg0 ) ;
1953+ break ;
1954+ case TypeCode . Double :
1955+ InstanceCalliHelper . Call ( ( delegate * < object , double , void > ) pContract ->CtorEntryPoint , ctorTarget , ( double ) arg0 ) ;
1956+ break ;
1957+ default :
1958+ throw new InvalidOperationException ( "Unsupported value-type custom attribute ctor argument." ) ;
1959+ }
1960+ }
1961+
1962+ * pResult = ctorTarget ;
1963+ return ;
1964+ }
1965+
1966+ if ( argCount <= 6 )
1967+ {
1968+ bool hasValueTypeArg = false ;
1969+ for ( int i = 0 ; i < argCount ; i ++ )
1970+ {
1971+ if ( argIsValueTypeFlags [ i ] != 0 )
1972+ {
1973+ hasValueTypeArg = true ;
1974+ }
1975+ }
1976+
1977+ if ( hasValueTypeArg )
1978+ {
1979+ // DecimalConstantAttribute: .ctor(byte scale, byte sign, uint hi, uint mid, uint low)
1980+ if ( ctorArgs . Length == 5
1981+ && ctorArgs [ 0 ] is byte scale
1982+ && ctorArgs [ 1 ] is byte sign
1983+ && ctorArgs [ 2 ] is uint uHi
1984+ && ctorArgs [ 3 ] is uint uMid
1985+ && ctorArgs [ 4 ] is uint uLow )
1986+ {
1987+ ( ( delegate * < object , byte , byte , uint , uint , uint , void > ) pContract ->CtorEntryPoint ) ( ctorTarget , scale , sign , uHi , uMid , uLow ) ;
1988+ * pResult = ctorTarget ;
1989+ return ;
1990+ }
1991+
1992+ // DecimalConstantAttribute: .ctor(byte scale, byte sign, int hi, int mid, int low)
1993+ if ( ctorArgs . Length == 5
1994+ && ctorArgs [ 0 ] is byte scaleInt
1995+ && ctorArgs [ 1 ] is byte signInt
1996+ && ctorArgs [ 2 ] is int hi
1997+ && ctorArgs [ 3 ] is int mid
1998+ && ctorArgs [ 4 ] is int low )
1999+ {
2000+ ( ( delegate * < object , byte , byte , int , int , int , void > ) pContract ->CtorEntryPoint ) ( ctorTarget , scaleInt , signInt , hi , mid , low ) ;
2001+ * pResult = ctorTarget ;
2002+ return ;
2003+ }
2004+
2005+ throw new InvalidOperationException ( "Unsupported multi-argument value-type custom attribute ctor signature." ) ;
2006+ }
2007+
2008+ switch ( argCount )
2009+ {
2010+ case 2 :
2011+ InstanceCalliHelper . Call ( ( delegate * < object , object ? , object ? , void > ) pContract ->CtorEntryPoint , ctorTarget , ctorArgs [ 0 ] , ctorArgs [ 1 ] ) ;
2012+ break ;
2013+ case 3 :
2014+ InstanceCalliHelper . Call ( ( delegate * < object , object ? , object ? , object ? , void > ) pContract ->CtorEntryPoint , ctorTarget , ctorArgs [ 0 ] , ctorArgs [ 1 ] , ctorArgs [ 2 ] ) ;
2015+ break ;
2016+ case 4 :
2017+ InstanceCalliHelper . Call ( ( delegate * < object , object ? , object ? , object ? , object ? , void > ) pContract ->CtorEntryPoint , ctorTarget , ctorArgs [ 0 ] , ctorArgs [ 1 ] , ctorArgs [ 2 ] , ctorArgs [ 3 ] ) ;
2018+ break ;
2019+ case 5 :
2020+ InstanceCalliHelper . Call ( ( delegate * < object , object ? , object ? , object ? , object ? , object ? , void > ) pContract ->CtorEntryPoint , ctorTarget , ctorArgs [ 0 ] , ctorArgs [ 1 ] , ctorArgs [ 2 ] , ctorArgs [ 3 ] , ctorArgs [ 4 ] ) ;
2021+ break ;
2022+ case 6 :
2023+ InstanceCalliHelper . Call ( ( delegate * < object , object ? , object ? , object ? , object ? , object ? , object ? , void > ) pContract ->CtorEntryPoint , ctorTarget , ctorArgs [ 0 ] , ctorArgs [ 1 ] , ctorArgs [ 2 ] , ctorArgs [ 3 ] , ctorArgs [ 4 ] , ctorArgs [ 5 ] ) ;
2024+ break ;
2025+ }
2026+
2027+ * pResult = ctorTarget ;
2028+ return ;
2029+ }
2030+
2031+ throw new InvalidOperationException ( "Custom attribute ctor has too many arguments for UCO invoke path." ) ;
2032+ }
2033+ catch ( Exception ex )
2034+ {
2035+ * pException = ex ;
2036+ }
2037+ }
2038+
2039+ [ StructLayout ( LayoutKind . Sequential ) ]
2040+ private unsafe struct NativeCtorInvokeContract
2041+ {
2042+ public object [ ] * CtorArgs ;
2043+ public byte [ ] * ArgIsValueType ;
2044+ public int ArgCount ;
2045+ public object * CtorTarget ;
2046+ public IntPtr CtorEntryPoint ;
2047+ }
2048+
18622049 [ LibraryImport ( RuntimeHelpers . QCall , EntryPoint = "CustomAttribute_CreateCustomAttributeInstance" ) ]
18632050 private static partial void CreateCustomAttributeInstance (
18642051 QCallModule pModule ,
0 commit comments