diff options
Diffstat (limited to 'src/mscorlib/src/System/Reflection')
19 files changed, 401 insertions, 268 deletions
diff --git a/src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs b/src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs index bbbd80b58b..d437e05e31 100644 --- a/src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs +++ b/src/mscorlib/src/System/Reflection/Assembly.CoreCLR.cs @@ -22,7 +22,11 @@ namespace System.Reflection private static Assembly LoadFromResolveHandler(object sender, ResolveEventArgs args) { Assembly requestingAssembly = args.RequestingAssembly; - + if (requestingAssembly == null) + { + return null; + } + // Requesting assembly for LoadFrom is always loaded in defaultContext - proceed only if that // is the case. if (AssemblyLoadContext.Default != AssemblyLoadContext.GetLoadContext(requestingAssembly)) diff --git a/src/mscorlib/src/System/Reflection/CustomAttribute.cs b/src/mscorlib/src/System/Reflection/CustomAttribute.cs index 4bc5933d50..1dd88a23a5 100644 --- a/src/mscorlib/src/System/Reflection/CustomAttribute.cs +++ b/src/mscorlib/src/System/Reflection/CustomAttribute.cs @@ -67,7 +67,7 @@ namespace System.Reflection IList<CustomAttributeData> cad = GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken); int pcaCount = 0; - Attribute[] a = PseudoCustomAttribute.GetCustomAttributes((RuntimeType)target, typeof(object) as RuntimeType, true, out pcaCount); + Attribute[] a = PseudoCustomAttribute.GetCustomAttributes((RuntimeType)target, typeof(object) as RuntimeType, out pcaCount); if (pcaCount == 0) return cad; @@ -111,7 +111,7 @@ namespace System.Reflection IList<CustomAttributeData> cad = GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken); int pcaCount = 0; - Attribute[] a = PseudoCustomAttribute.GetCustomAttributes((RuntimeMethodInfo)target, typeof(object) as RuntimeType, true, out pcaCount); + Attribute[] a = PseudoCustomAttribute.GetCustomAttributes((RuntimeMethodInfo)target, typeof(object) as RuntimeType, out pcaCount); if (pcaCount == 0) return cad; @@ -164,7 +164,7 @@ namespace System.Reflection IList<CustomAttributeData> cad = GetCustomAttributes((RuntimeModule)target.ManifestModule, RuntimeAssembly.GetToken(target.GetNativeHandle())); int pcaCount = 0; - Attribute[] a = PseudoCustomAttribute.GetCustomAttributes(target, typeof(object) as RuntimeType, false, out pcaCount); + Attribute[] a = PseudoCustomAttribute.GetCustomAttributes(target, typeof(object) as RuntimeType, out pcaCount); if (pcaCount == 0) return cad; @@ -1276,7 +1276,7 @@ namespace System.Reflection type = type.GetGenericTypeDefinition() as RuntimeType; int pcaCount = 0; - Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(type, caType, true, out pcaCount); + Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(type, caType, out pcaCount); // if we are asked to go up the hierarchy chain we have to do it now and regardless of the // attribute usage for the specific attribute because a derived attribute may override the usage... @@ -1320,7 +1320,7 @@ namespace System.Reflection method = method.GetGenericMethodDefinition() as RuntimeMethodInfo; int pcaCount = 0; - Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(method, caType, true, out pcaCount); + Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(method, caType, out pcaCount); // if we are asked to go up the hierarchy chain we have to do it now and regardless of the // attribute usage for the specific attribute because a derived attribute may override the usage... @@ -1361,7 +1361,7 @@ namespace System.Reflection Contract.Requires(caType != null); int pcaCount = 0; - Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(ctor, caType, true, out pcaCount); + Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(ctor, caType, out pcaCount); object[] attributes = GetCustomAttributes(ctor.GetRuntimeModule(), ctor.MetadataToken, pcaCount, caType); if (pcaCount > 0) Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount); return attributes; @@ -1422,7 +1422,7 @@ namespace System.Reflection Contract.Requires(caType != null); int pcaCount = 0; - Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(assembly, caType, true, out pcaCount); + Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(assembly, caType, out pcaCount); int assemblyToken = RuntimeAssembly.GetToken(assembly.GetNativeHandle()); object[] attributes = GetCustomAttributes(assembly.ManifestModule as RuntimeModule, assemblyToken, pcaCount, caType); if (pcaCount > 0) Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount); @@ -1890,13 +1890,6 @@ namespace System.Reflection private static int s_pcasCount; #endregion - #region FCalls - internal static void GetSecurityAttributes(RuntimeModule module, int token, bool assembly, out object[] securityAttributes) - { - securityAttributes = null; - } - #endregion - #region Static Constructor static PseudoCustomAttribute() { @@ -1941,13 +1934,7 @@ namespace System.Reflection #endregion #region Internal Static - internal static bool IsSecurityAttribute(RuntimeType type) - { - // TODO: Cleanup - return false; - } - - internal static Attribute[] GetCustomAttributes(RuntimeType type, RuntimeType caType, bool includeSecCa, out int count) + internal static Attribute[] GetCustomAttributes(RuntimeType type, RuntimeType caType, out int count) { Contract.Requires(type != null); Contract.Requires(caType != null); @@ -1955,36 +1942,20 @@ namespace System.Reflection count = 0; bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); - if (!all && !s_pca.ContainsKey(caType) && !IsSecurityAttribute(caType)) + if (!all && !s_pca.ContainsKey(caType)) return Array.Empty<Attribute>(); List<Attribute> pcas = new List<Attribute>(); - Attribute pca = null; if (all || caType == (RuntimeType)typeof(SerializableAttribute)) { - pca = SerializableAttribute.GetCustomAttribute(type); - if (pca != null) pcas.Add(pca); + if ((type.Attributes & TypeAttributes.Serializable) != 0) + pcas.Add(new SerializableAttribute()); } if (all || caType == (RuntimeType)typeof(ComImportAttribute)) { - pca = ComImportAttribute.GetCustomAttribute(type); - if (pca != null) pcas.Add(pca); - } - if (includeSecCa && (all || IsSecurityAttribute(caType))) - { - if (!type.IsGenericParameter && type.GetElementType() == null) - { - if (type.IsGenericType) - type = (RuntimeType)type.GetGenericTypeDefinition(); - - object[] securityAttributes; - GetSecurityAttributes(type.Module.ModuleHandle.GetRuntimeModule(), type.MetadataToken, false, out securityAttributes); - if (securityAttributes != null) - foreach (object a in securityAttributes) - if (caType == a.GetType() || a.GetType().IsSubclassOf(caType)) - pcas.Add((Attribute)a); - } + if ((type.Attributes & TypeAttributes.Import) != 0) + pcas.Add(new ComImportAttribute()); } count = pcas.Count; @@ -1993,28 +1964,24 @@ namespace System.Reflection internal static bool IsDefined(RuntimeType type, RuntimeType caType) { bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); - if (!all && !s_pca.ContainsKey(caType) && !IsSecurityAttribute(caType)) + if (!all && !s_pca.ContainsKey(caType)) return false; if (all || caType == (RuntimeType)typeof(SerializableAttribute)) { - if (SerializableAttribute.IsDefined(type)) return true; + if ((type.Attributes & TypeAttributes.Serializable) != 0) + return true; } if (all || caType == (RuntimeType)typeof(ComImportAttribute)) { - if (ComImportAttribute.IsDefined(type)) return true; - } - if (all || IsSecurityAttribute(caType)) - { - int count; - if (GetCustomAttributes(type, caType, true, out count).Length != 0) + if ((type.Attributes & TypeAttributes.Import) != 0) return true; } return false; } - internal static Attribute[] GetCustomAttributes(RuntimeMethodInfo method, RuntimeType caType, bool includeSecCa, out int count) + internal static Attribute[] GetCustomAttributes(RuntimeMethodInfo method, RuntimeType caType, out int count) { Contract.Requires(method != null); Contract.Requires(caType != null); @@ -2022,31 +1989,21 @@ namespace System.Reflection count = 0; bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); - if (!all && !s_pca.ContainsKey(caType) && !IsSecurityAttribute(caType)) + if (!all && !s_pca.ContainsKey(caType)) return Array.Empty<Attribute>(); List<Attribute> pcas = new List<Attribute>(); - Attribute pca = null; + Attribute pca; if (all || caType == (RuntimeType)typeof(DllImportAttribute)) { - pca = DllImportAttribute.GetCustomAttribute(method); - if (pca != null) pcas.Add(pca); + pca = GetDllImportCustomAttribute(method); + if (pca != null) pcas[count++] = pca; } if (all || caType == (RuntimeType)typeof(PreserveSigAttribute)) { - pca = PreserveSigAttribute.GetCustomAttribute(method); - if (pca != null) pcas.Add(pca); - } - if (includeSecCa && (all || IsSecurityAttribute(caType))) - { - object[] securityAttributes; - - GetSecurityAttributes(method.Module.ModuleHandle.GetRuntimeModule(), method.MetadataToken, false, out securityAttributes); - if (securityAttributes != null) - foreach (object a in securityAttributes) - if (caType == a.GetType() || a.GetType().IsSubclassOf(caType)) - pcas.Add((Attribute)a); + if ((method.GetMethodImplementationFlags() & MethodImplAttributes.PreserveSig) != 0) + pcas.Add(new PreserveSigAttribute()); } count = pcas.Count; @@ -2060,17 +2017,12 @@ namespace System.Reflection if (all || caType == (RuntimeType)typeof(DllImportAttribute)) { - if (DllImportAttribute.IsDefined(method)) return true; + if ((method.Attributes & MethodAttributes.PinvokeImpl) != 0) + return true; } if (all || caType == (RuntimeType)typeof(PreserveSigAttribute)) { - if (PreserveSigAttribute.IsDefined(method)) return true; - } - if (all || IsSecurityAttribute(caType)) - { - int count; - - if (GetCustomAttributes(method, caType, true, out count).Length != 0) + if ((method.GetMethodImplementationFlags() & MethodImplAttributes.PreserveSig) != 0) return true; } @@ -2089,26 +2041,26 @@ namespace System.Reflection return null; Attribute[] pcas = new Attribute[s_pcasCount]; - Attribute pca = null; + Attribute pca; if (all || caType == (RuntimeType)typeof(InAttribute)) { - pca = InAttribute.GetCustomAttribute(parameter); - if (pca != null) pcas[count++] = pca; + if (parameter.IsIn) + pcas[count++] = new InAttribute(); } if (all || caType == (RuntimeType)typeof(OutAttribute)) { - pca = OutAttribute.GetCustomAttribute(parameter); - if (pca != null) pcas[count++] = pca; + if (parameter.IsOut) + pcas[count++] = new OutAttribute(); } if (all || caType == (RuntimeType)typeof(OptionalAttribute)) { - pca = OptionalAttribute.GetCustomAttribute(parameter); - if (pca != null) pcas[count++] = pca; + if (parameter.IsOptional) + pcas[count++] = new OptionalAttribute(); } if (all || caType == (RuntimeType)typeof(MarshalAsAttribute)) { - pca = MarshalAsAttribute.GetCustomAttribute(parameter); + pca = GetMarshalAsCustomAttribute(parameter); if (pca != null) pcas[count++] = pca; } return pcas; @@ -2122,62 +2074,32 @@ namespace System.Reflection if (all || caType == (RuntimeType)typeof(InAttribute)) { - if (InAttribute.IsDefined(parameter)) return true; + if (parameter.IsIn) return true; } if (all || caType == (RuntimeType)typeof(OutAttribute)) { - if (OutAttribute.IsDefined(parameter)) return true; + if (parameter.IsOut) return true; } if (all || caType == (RuntimeType)typeof(OptionalAttribute)) { - if (OptionalAttribute.IsDefined(parameter)) return true; + if (parameter.IsOptional) return true; } if (all || caType == (RuntimeType)typeof(MarshalAsAttribute)) { - if (MarshalAsAttribute.IsDefined(parameter)) return true; + if (GetMarshalAsCustomAttribute(parameter) != null) return true; } return false; } - internal static Attribute[] GetCustomAttributes(RuntimeAssembly assembly, RuntimeType caType, bool includeSecCa, out int count) + internal static Attribute[] GetCustomAttributes(RuntimeAssembly assembly, RuntimeType caType, out int count) { count = 0; - - bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); - - if (!all && !s_pca.ContainsKey(caType) && !IsSecurityAttribute(caType)) - return Array.Empty<Attribute>(); - - List<Attribute> pcas = new List<Attribute>(); - if (includeSecCa && (all || IsSecurityAttribute(caType))) - { - object[] securityAttributes; - - GetSecurityAttributes(assembly.ManifestModule.ModuleHandle.GetRuntimeModule(), RuntimeAssembly.GetToken(assembly.GetNativeHandle()), true, out securityAttributes); - if (securityAttributes != null) - foreach (object a in securityAttributes) - if (caType == a.GetType() || a.GetType().IsSubclassOf(caType)) - pcas.Add((Attribute)a); - } - - //TypeForwardedToAttribute.GetCustomAttribute(assembly) throws FileNotFoundException if the forwarded-to - //assemblies are not present. This breaks many V4 scenarios because some framework types are forwarded - //to assemblies not included in the client SKU. Let's omit TypeForwardedTo for now until we have a better solution. - - //if (all || caType == (RuntimeType)typeof(TypeForwardedToAttribute)) - //{ - // TypeForwardedToAttribute[] attrs = TypeForwardedToAttribute.GetCustomAttribute(assembly); - // pcas.AddRange(attrs); - //} - - count = pcas.Count; - return pcas.ToArray(); + return null; } internal static bool IsDefined(RuntimeAssembly assembly, RuntimeType caType) { - int count; - return GetCustomAttributes(assembly, caType, true, out count).Length > 0; + return false; } internal static Attribute[] GetCustomAttributes(RuntimeModule module, RuntimeType caType, out int count) @@ -2202,22 +2124,22 @@ namespace System.Reflection return null; Attribute[] pcas = new Attribute[s_pcasCount]; - Attribute pca = null; + Attribute pca; if (all || caType == (RuntimeType)typeof(MarshalAsAttribute)) { - pca = MarshalAsAttribute.GetCustomAttribute(field); + pca = GetMarshalAsCustomAttribute(field); if (pca != null) pcas[count++] = pca; } if (all || caType == (RuntimeType)typeof(FieldOffsetAttribute)) { - pca = FieldOffsetAttribute.GetCustomAttribute(field); + pca = GetFieldOffsetCustomAttribute(field); if (pca != null) pcas[count++] = pca; } if (all || caType == (RuntimeType)typeof(NonSerializedAttribute)) { - pca = NonSerializedAttribute.GetCustomAttribute(field); - if (pca != null) pcas[count++] = pca; + if ((field.Attributes & FieldAttributes.NotSerialized) != 0) + pcas[count++] = new NonSerializedAttribute(); } return pcas; } @@ -2229,60 +2151,28 @@ namespace System.Reflection if (all || caType == (RuntimeType)typeof(MarshalAsAttribute)) { - if (MarshalAsAttribute.IsDefined(field)) return true; + if (GetMarshalAsCustomAttribute(field) != null) return true; } if (all || caType == (RuntimeType)typeof(FieldOffsetAttribute)) { - if (FieldOffsetAttribute.IsDefined(field)) return true; + if (GetFieldOffsetCustomAttribute(field) != null) return true; } if (all || caType == (RuntimeType)typeof(NonSerializedAttribute)) { - if (NonSerializedAttribute.IsDefined(field)) return true; + if ((field.Attributes & FieldAttributes.NotSerialized) != 0) + return true; } return false; } - internal static Attribute[] GetCustomAttributes(RuntimeConstructorInfo ctor, RuntimeType caType, bool includeSecCa, out int count) + internal static Attribute[] GetCustomAttributes(RuntimeConstructorInfo ctor, RuntimeType caType, out int count) { count = 0; - - bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); - - if (!all && !s_pca.ContainsKey(caType) && !IsSecurityAttribute(caType)) - return Array.Empty<Attribute>(); - - List<Attribute> pcas = new List<Attribute>(); - - if (includeSecCa && (all || IsSecurityAttribute(caType))) - { - object[] securityAttributes; - - GetSecurityAttributes(ctor.Module.ModuleHandle.GetRuntimeModule(), ctor.MetadataToken, false, out securityAttributes); - if (securityAttributes != null) - foreach (object a in securityAttributes) - if (caType == a.GetType() || a.GetType().IsSubclassOf(caType)) - pcas.Add((Attribute)a); - } - - count = pcas.Count; - return pcas.ToArray(); + return null; } internal static bool IsDefined(RuntimeConstructorInfo ctor, RuntimeType caType) { - bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); - - if (!all && !s_pca.ContainsKey(caType)) - return false; - - if (all || IsSecurityAttribute(caType)) - { - int count; - - if (GetCustomAttributes(ctor, caType, true, out count).Length != 0) - return true; - } - return false; } @@ -2306,5 +2196,165 @@ namespace System.Reflection return false; } #endregion + + private static DllImportAttribute GetDllImportCustomAttribute(RuntimeMethodInfo method) + { + if ((method.Attributes & MethodAttributes.PinvokeImpl) == 0) + return null; + + MetadataImport scope = ModuleHandle.GetMetadataImport(method.Module.ModuleHandle.GetRuntimeModule()); + string entryPoint, dllName = null; + int token = method.MetadataToken; + PInvokeAttributes flags = 0; + + scope.GetPInvokeMap(token, out flags, out entryPoint, out dllName); + + CharSet charSet = CharSet.None; + + switch (flags & PInvokeAttributes.CharSetMask) + { + case PInvokeAttributes.CharSetNotSpec: charSet = CharSet.None; break; + case PInvokeAttributes.CharSetAnsi: charSet = CharSet.Ansi; break; + case PInvokeAttributes.CharSetUnicode: charSet = CharSet.Unicode; break; + case PInvokeAttributes.CharSetAuto: charSet = CharSet.Auto; break; + + // Invalid: default to CharSet.None + default: break; + } + + CallingConvention callingConvention = CallingConvention.Cdecl; + + switch (flags & PInvokeAttributes.CallConvMask) + { + case PInvokeAttributes.CallConvWinapi: callingConvention = CallingConvention.Winapi; break; + case PInvokeAttributes.CallConvCdecl: callingConvention = CallingConvention.Cdecl; break; + case PInvokeAttributes.CallConvStdcall: callingConvention = CallingConvention.StdCall; break; + case PInvokeAttributes.CallConvThiscall: callingConvention = CallingConvention.ThisCall; break; + case PInvokeAttributes.CallConvFastcall: callingConvention = CallingConvention.FastCall; break; + + // Invalid: default to CallingConvention.Cdecl + default: break; + } + + DllImportAttribute attribute = new DllImportAttribute(dllName); + + attribute.EntryPoint = entryPoint; + attribute.CharSet = charSet; + attribute.SetLastError = (flags & PInvokeAttributes.SupportsLastError) != 0; + attribute.ExactSpelling = (flags & PInvokeAttributes.NoMangle) != 0; + attribute.PreserveSig = (method.GetMethodImplementationFlags() & MethodImplAttributes.PreserveSig) != 0; + attribute.CallingConvention = callingConvention; + attribute.BestFitMapping = (flags & PInvokeAttributes.BestFitMask) == PInvokeAttributes.BestFitEnabled; + attribute.ThrowOnUnmappableChar = (flags & PInvokeAttributes.ThrowOnUnmappableCharMask) == PInvokeAttributes.ThrowOnUnmappableCharEnabled; + + return attribute; + } + + + private static MarshalAsAttribute GetMarshalAsCustomAttribute(RuntimeParameterInfo parameter) + { + return GetMarshalAsCustomAttribute(parameter.MetadataToken, parameter.GetRuntimeModule()); + } + private static MarshalAsAttribute GetMarshalAsCustomAttribute(RuntimeFieldInfo field) + { + return GetMarshalAsCustomAttribute(field.MetadataToken, field.GetRuntimeModule()); + } + + private static MarshalAsAttribute GetMarshalAsCustomAttribute(int token, RuntimeModule scope) + { + UnmanagedType unmanagedType, arraySubType; + VarEnum safeArraySubType; + int sizeParamIndex = 0, sizeConst = 0; + string marshalTypeName = null, marshalCookie = null, safeArrayUserDefinedTypeName = null; + int iidParamIndex = 0; + ConstArray nativeType = ModuleHandle.GetMetadataImport(scope.GetNativeHandle()).GetFieldMarshal(token); + + if (nativeType.Length == 0) + return null; + + MetadataImport.GetMarshalAs(nativeType, + out unmanagedType, out safeArraySubType, out safeArrayUserDefinedTypeName, out arraySubType, out sizeParamIndex, + out sizeConst, out marshalTypeName, out marshalCookie, out iidParamIndex); + + RuntimeType safeArrayUserDefinedType = safeArrayUserDefinedTypeName == null || safeArrayUserDefinedTypeName.Length == 0 ? null : + RuntimeTypeHandle.GetTypeByNameUsingCARules(safeArrayUserDefinedTypeName, scope); + RuntimeType marshalTypeRef = null; + + try + { + marshalTypeRef = marshalTypeName == null ? null : RuntimeTypeHandle.GetTypeByNameUsingCARules(marshalTypeName, scope); + } + catch (System.TypeLoadException) + { + // The user may have supplied a bad type name string causing this TypeLoadException + // Regardless, we return the bad type name + Debug.Assert(marshalTypeName != null); + } + + MarshalAsAttribute attribute = new MarshalAsAttribute(unmanagedType); + + attribute.SafeArraySubType = safeArraySubType; + attribute.SafeArrayUserDefinedSubType = safeArrayUserDefinedType; + attribute.IidParameterIndex = iidParamIndex; + attribute.ArraySubType = arraySubType; + attribute.SizeParamIndex = (short)sizeParamIndex; + attribute.SizeConst = sizeConst; + attribute.MarshalType = marshalTypeName; + attribute.MarshalTypeRef = marshalTypeRef; + attribute.MarshalCookie = marshalCookie; + + return attribute; + } + + private static FieldOffsetAttribute GetFieldOffsetCustomAttribute(RuntimeFieldInfo field) + { + int fieldOffset; + + if (field.DeclaringType != null && + field.GetRuntimeModule().MetadataImport.GetFieldOffset(field.DeclaringType.MetadataToken, field.MetadataToken, out fieldOffset)) + return new FieldOffsetAttribute(fieldOffset); + + return null; + } + + internal static StructLayoutAttribute GetStructLayoutCustomAttribute(RuntimeType type) + { + if (type.IsInterface || type.HasElementType || type.IsGenericParameter) + return null; + + int pack = 0, size = 0; + LayoutKind layoutKind = LayoutKind.Auto; + switch (type.Attributes & TypeAttributes.LayoutMask) + { + case TypeAttributes.ExplicitLayout: layoutKind = LayoutKind.Explicit; break; + case TypeAttributes.AutoLayout: layoutKind = LayoutKind.Auto; break; + case TypeAttributes.SequentialLayout: layoutKind = LayoutKind.Sequential; break; + default: Contract.Assume(false); break; + } + + CharSet charSet = CharSet.None; + switch (type.Attributes & TypeAttributes.StringFormatMask) + { + case TypeAttributes.AnsiClass: charSet = CharSet.Ansi; break; + case TypeAttributes.AutoClass: charSet = CharSet.Auto; break; + case TypeAttributes.UnicodeClass: charSet = CharSet.Unicode; break; + default: Contract.Assume(false); break; + } + type.GetRuntimeModule().MetadataImport.GetClassLayout(type.MetadataToken, out pack, out size); + + // Metadata parameter checking should not have allowed 0 for packing size. + // The runtime later converts a packing size of 0 to 8 so do the same here + // because it's more useful from a user perspective. + if (pack == 0) + pack = 8; // DEFAULT_PACKING_SIZE + + StructLayoutAttribute attribute = new StructLayoutAttribute(layoutKind); + + attribute.Pack = pack; + attribute.Size = size; + attribute.CharSet = charSet; + + return attribute; + } } } diff --git a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs index 7b190df6c2..82f460138b 100644 --- a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs +++ b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs @@ -44,7 +44,7 @@ namespace System.Reflection.Emit // This InternalAssemblyBuilder can be retrieved via a call to Assembly.GetAssemblies() by untrusted code. // In the past, when InternalAssemblyBuilder was AssemblyBuilder, the untrusted user could down cast the // Assembly to an AssemblyBuilder and emit code with the elevated permissions of the trusted code which - // origionally created the AssemblyBuilder via DefineDynamicAssembly. Today, this can no longer happen + // originally created the AssemblyBuilder via DefineDynamicAssembly. Today, this can no longer happen // because the Assembly returned via AssemblyGetAssemblies() will be an InternalAssemblyBuilder. // Only the caller of DefineDynamicAssembly will get an AssemblyBuilder. diff --git a/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs b/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs index 15792d2d68..07d886fcca 100644 --- a/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs +++ b/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs @@ -487,18 +487,19 @@ namespace System.Reflection.Emit throw new TargetParameterCountException(SR.Arg_ParmCnt); // if we are here we passed all the previous checks. Time to look at the arguments + bool wrapExceptions = (invokeAttr & BindingFlags.DoNotWrapExceptions) == 0; Object retValue = null; if (actualCount > 0) { Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig); - retValue = RuntimeMethodHandle.InvokeMethod(null, arguments, sig, false); + retValue = RuntimeMethodHandle.InvokeMethod(null, arguments, sig, false, wrapExceptions); // copy out. This should be made only if ByRef are present. for (int index = 0; index < arguments.Length; index++) parameters[index] = arguments[index]; } else { - retValue = RuntimeMethodHandle.InvokeMethod(null, null, sig, false); + retValue = RuntimeMethodHandle.InvokeMethod(null, null, sig, false, wrapExceptions); } GC.KeepAlive(this); @@ -578,7 +579,7 @@ namespace System.Reflection.Emit // This way the DynamicMethod creator is the only one responsible for DynamicMethod access, // and can control exactly who gets access to it. // - internal class RTDynamicMethod : MethodInfo + internal sealed class RTDynamicMethod : MethodInfo { internal DynamicMethod m_owner; private RuntimeParameterInfo[] m_parameters; @@ -679,7 +680,7 @@ namespace System.Reflection.Emit Contract.EndContractBlock(); if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute))) - return new Object[] { new MethodImplAttribute(GetMethodImplementationFlags()) }; + return new Object[] { new MethodImplAttribute((MethodImplOptions)GetMethodImplementationFlags()) }; else return Array.Empty<Object>(); } @@ -687,7 +688,7 @@ namespace System.Reflection.Emit public override Object[] GetCustomAttributes(bool inherit) { // support for MethodImplAttribute PCA - return new Object[] { new MethodImplAttribute(GetMethodImplementationFlags()) }; + return new Object[] { new MethodImplAttribute((MethodImplOptions)GetMethodImplementationFlags()) }; } public override bool IsDefined(Type attributeType, bool inherit) diff --git a/src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs index 75e4acc903..8256d0e6d5 100644 --- a/src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs +++ b/src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs @@ -21,7 +21,7 @@ namespace System.Reflection.Emit return IsAssignableFrom(typeInfo.AsType()); } - #region Private Data Mebers + #region Private Data Members internal TypeBuilder m_type; #endregion diff --git a/src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs b/src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs index fa31d66f6c..52e8b30e33 100644 --- a/src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs +++ b/src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs @@ -1622,7 +1622,7 @@ namespace System.Reflection.Emit /*************************** * - * Find the current active lexcial scope. For example, if we have + * Find the current active lexical scope. For example, if we have * "Open Open Open Close", * we will return 1 as the second BeginScope is currently active. * diff --git a/src/mscorlib/src/System/Reflection/Emit/MethodBuilderInstantiation.cs b/src/mscorlib/src/System/Reflection/Emit/MethodBuilderInstantiation.cs index 2d0a9b41dd..be4bfd5f48 100644 --- a/src/mscorlib/src/System/Reflection/Emit/MethodBuilderInstantiation.cs +++ b/src/mscorlib/src/System/Reflection/Emit/MethodBuilderInstantiation.cs @@ -26,7 +26,7 @@ namespace System.Reflection.Emit #endregion - #region Private Data Mebers + #region Private Data Members internal MethodInfo m_method; private Type[] m_inst; #endregion diff --git a/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs index 362b13657f..1c65bf91c2 100644 --- a/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs +++ b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs @@ -87,7 +87,7 @@ namespace System.Reflection.Emit #endregion - #region Intenral Data Members + #region Internal Data Members // m_TypeBuilder contains both TypeBuilder and EnumBuilder objects private Dictionary<string, Type> m_TypeBuilderDict; private ISymbolWriter m_iSymWriter; diff --git a/src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs index 4a9b774d15..c597dbe6b4 100644 --- a/src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs +++ b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs @@ -2,10 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -// - using System; using System.Diagnostics; using System.Diagnostics.Contracts; @@ -55,9 +51,7 @@ namespace System.Reflection.Emit internal String m_strFileName; internal bool m_fGlobalBeenCreated; internal bool m_fHasGlobal; - [NonSerialized] internal TypeBuilder m_globalTypeBuilder; - [NonSerialized] internal ModuleBuilder m_module; private int m_tkFile; @@ -65,5 +59,5 @@ namespace System.Reflection.Emit internal const String MULTI_BYTE_VALUE_CLASS = "$ArrayType$"; internal String m_strResourceFileName; internal byte[] m_resourceBytes; - } // class ModuleBuilderData + } } diff --git a/src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs b/src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs index 64a38b0995..ab5b7eeaa5 100644 --- a/src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs +++ b/src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs @@ -43,7 +43,7 @@ namespace System.Reflection.Emit #endregion - #region Private Data Mebers + #region Private Data Members private Type m_type; private Type[] m_inst; private string m_strFullQualName; diff --git a/src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs b/src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs index 78238c02b7..3894d9115b 100644 --- a/src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs +++ b/src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs @@ -23,7 +23,7 @@ namespace System.Reflection.Emit } #endregion - #region Private Data Mebers + #region Private Data Members internal MethodInfo m_method; private TypeBuilderInstantiation m_type; #endregion @@ -99,7 +99,7 @@ namespace System.Reflection.Emit } #endregion - #region Private Data Mebers + #region Private Data Members internal ConstructorInfo m_ctor; private TypeBuilderInstantiation m_type; #endregion diff --git a/src/mscorlib/src/System/Reflection/ExceptionHandlingClause.cs b/src/mscorlib/src/System/Reflection/ExceptionHandlingClause.cs index 9bb45aebb2..a61ed5e385 100644 --- a/src/mscorlib/src/System/Reflection/ExceptionHandlingClause.cs +++ b/src/mscorlib/src/System/Reflection/ExceptionHandlingClause.cs @@ -9,7 +9,7 @@ namespace System.Reflection { public class ExceptionHandlingClause { - #region costructor + #region constructor // This class can only be created from inside the EE. protected ExceptionHandlingClause() { } #endregion diff --git a/src/mscorlib/src/System/Reflection/INVOCATION_FLAGS.cs b/src/mscorlib/src/System/Reflection/INVOCATION_FLAGS.cs index 6ffc3e968b..b097b8fa0f 100644 --- a/src/mscorlib/src/System/Reflection/INVOCATION_FLAGS.cs +++ b/src/mscorlib/src/System/Reflection/INVOCATION_FLAGS.cs @@ -15,7 +15,7 @@ namespace System.Reflection INVOCATION_FLAGS_INITIALIZED = 0x00000001, // it's used for both method and field to signify that no access is allowed INVOCATION_FLAGS_NO_INVOKE = 0x00000002, - INVOCATION_FLAGS_NEED_SECURITY = 0x00000004, + /* unused 0x00000004 */ // Set for static ctors and ctors on abstract types, which // can be invoked only if the "this" object is provided (even if it's null). INVOCATION_FLAGS_NO_CTOR_INVOKE = 0x00000008, diff --git a/src/mscorlib/src/System/Reflection/MethodBody.cs b/src/mscorlib/src/System/Reflection/MethodBody.cs index 4335177efb..e1d18bf375 100644 --- a/src/mscorlib/src/System/Reflection/MethodBody.cs +++ b/src/mscorlib/src/System/Reflection/MethodBody.cs @@ -8,7 +8,7 @@ namespace System.Reflection { public class MethodBody { - #region costructor + #region constructor // This class can only be created from inside the EE. protected MethodBody() { } #endregion diff --git a/src/mscorlib/src/System/Reflection/RtFieldInfo.cs b/src/mscorlib/src/System/Reflection/RtFieldInfo.cs index ddfc56b2aa..856d254d47 100644 --- a/src/mscorlib/src/System/Reflection/RtFieldInfo.cs +++ b/src/mscorlib/src/System/Reflection/RtFieldInfo.cs @@ -13,11 +13,6 @@ namespace System.Reflection { internal unsafe sealed class RtFieldInfo : RuntimeFieldInfo, IRuntimeFieldInfo { - #region FCalls - [MethodImplAttribute(MethodImplOptions.InternalCall)] - static private extern void PerformVisibilityCheckOnField(IntPtr field, Object target, RuntimeType declaringType, FieldAttributes attr, uint invocationFlags); - #endregion - #region Private Data Members // agressive caching private IntPtr m_fieldHandle; @@ -58,13 +53,6 @@ namespace System.Reflection if ((m_fieldAttributes & FieldAttributes.HasFieldRVA) != (FieldAttributes)0) invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_SPECIAL_FIELD; - // A public field is inaccesible to Transparent code if the field is Critical. - bool needsTransparencySecurityCheck = IsSecurityCritical && !IsSecuritySafeCritical; - bool needsVisibilitySecurityCheck = ((m_fieldAttributes & FieldAttributes.FieldAccessMask) != FieldAttributes.Public) || - (declaringType != null && declaringType.NeedsReflectionSecurityCheck); - if (needsTransparencySecurityCheck || needsVisibilitySecurityCheck) - invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY; - // find out if the field type is one of the following: Primitive, Enum or Pointer Type fieldType = FieldType; if (fieldType.IsPointer || fieldType.IsEnum || fieldType.IsPrimitive) @@ -158,11 +146,6 @@ namespace System.Reflection RuntimeType fieldType = (RuntimeType)FieldType; value = fieldType.CheckValue(value, binder, culture, invokeAttr); - #region Security Check - if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_SPECIAL_FIELD | INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY)) != 0) - PerformVisibilityCheckOnField(m_fieldHandle, obj, m_declaringType, m_fieldAttributes, (uint)m_invocationFlags); - #endregion - bool domainInitialized = false; if (declaringType == null) { @@ -223,10 +206,6 @@ namespace System.Reflection CheckConsistency(obj); - RuntimeType fieldType = (RuntimeType)FieldType; - if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) != 0) - PerformVisibilityCheckOnField(m_fieldHandle, obj, m_declaringType, m_fieldAttributes, (uint)(m_invocationFlags & ~INVOCATION_FLAGS.INVOCATION_FLAGS_SPECIAL_FIELD)); - return UnsafeGetValue(obj); } diff --git a/src/mscorlib/src/System/Reflection/RuntimeAssembly.cs b/src/mscorlib/src/System/Reflection/RuntimeAssembly.cs index edcb0d5cd5..cd9c715eec 100644 --- a/src/mscorlib/src/System/Reflection/RuntimeAssembly.cs +++ b/src/mscorlib/src/System/Reflection/RuntimeAssembly.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information. using System.Collections.Generic; +using System.Diagnostics; using CultureInfo = System.Globalization.CultureInfo; using System.Security; using System.IO; @@ -800,5 +801,78 @@ namespace System.Reflection [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern int GetToken(RuntimeAssembly assembly); + + public sealed override Type[] GetForwardedTypes() + { + List<Type> types = new List<Type>(); + List<Exception> exceptions = new List<Exception>(); + + MetadataImport scope = GetManifestModule(GetNativeHandle()).MetadataImport; + scope.Enum(MetadataTokenType.ExportedType, 0, out MetadataEnumResult enumResult); + for (int i = 0; i < enumResult.Length; i++) + { + MetadataToken mdtExternalType = enumResult[i]; + Type type = null; + Exception exception = null; + ObjectHandleOnStack pType = JitHelpers.GetObjectHandleOnStack(ref type); + try + { + GetForwardedType(this, mdtExternalType, pType); + if (type == null) + continue; // mdtExternalType was not a forwarder entry. + } + catch (Exception e) + { + type = null; + exception = e; + } + + Debug.Assert((type != null) != (exception != null)); // Exactly one of these must be non-null. + + if (type != null) + { + types.Add(type); + AddPublicNestedTypes(type, types, exceptions); + } + else + { + exceptions.Add(exception); + } + } + + if (exceptions.Count != 0) + { + int numTypes = types.Count; + int numExceptions = exceptions.Count; + types.AddRange(new Type[numExceptions]); // add one null Type for each exception. + exceptions.InsertRange(0, new Exception[numTypes]); // align the Exceptions with the null Types. + throw new ReflectionTypeLoadException(types.ToArray(), exceptions.ToArray()); + } + + return types.ToArray(); + } + + private static void AddPublicNestedTypes(Type type, List<Type> types, List<Exception> exceptions) + { + Type[] nestedTypes; + try + { + nestedTypes = type.GetNestedTypes(BindingFlags.Public); + } + catch (Exception e) + { + exceptions.Add(e); + return; + } + foreach (Type nestedType in nestedTypes) + { + types.Add(nestedType); + AddPublicNestedTypes(nestedType, types, exceptions); + } + } + + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void GetForwardedType(RuntimeAssembly assembly, MetadataToken mdtExternalType, ObjectHandleOnStack type); } } diff --git a/src/mscorlib/src/System/Reflection/RuntimeConstructorInfo.cs b/src/mscorlib/src/System/Reflection/RuntimeConstructorInfo.cs index 7870e0b91e..9b11a858df 100644 --- a/src/mscorlib/src/System/Reflection/RuntimeConstructorInfo.cs +++ b/src/mscorlib/src/System/Reflection/RuntimeConstructorInfo.cs @@ -57,16 +57,7 @@ namespace System.Reflection // this should be an invocable method, determine the other flags that participate in invocation invocationFlags |= RuntimeMethodHandle.GetSecurityFlags(this); - if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) == 0 && - ((Attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public || - (declaringType != null && declaringType.NeedsReflectionSecurityCheck))) - { - // If method is non-public, or declaring type is not visible - invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY; - } - - // Check for attempt to create a delegate class, we demand unmanaged - // code permission for this since it's hard to validate the target address. + // Check for attempt to create a delegate class. if (typeof(Delegate).IsAssignableFrom(DeclaringType)) invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_IS_DELEGATE_CTOR; } @@ -363,13 +354,6 @@ namespace System.Reflection // check basic method consistency. This call will throw if there are problems in the target/method relationship CheckConsistency(obj); - if (obj != null) - { - // For unverifiable code, we require the caller to be critical. - // Adding the INVOCATION_FLAGS_NEED_SECURITY flag makes that check happen - invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY; - } - Signature sig = Signature; // get the signature @@ -379,16 +363,17 @@ namespace System.Reflection throw new TargetParameterCountException(SR.Arg_ParmCnt); // if we are here we passed all the previous checks. Time to look at the arguments + bool wrapExceptions = (invokeAttr & BindingFlags.DoNotWrapExceptions) == 0; if (actualCount > 0) { Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig); - Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, sig, false); + Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, sig, false, wrapExceptions); // copy out. This should be made only if ByRef are present. for (int index = 0; index < arguments.Length; index++) parameters[index] = arguments[index]; return retValue; } - return RuntimeMethodHandle.InvokeMethod(obj, null, sig, false); + return RuntimeMethodHandle.InvokeMethod(obj, null, sig, false, wrapExceptions); } public override MethodBody GetMethodBody() @@ -449,16 +434,17 @@ namespace System.Reflection // JIT/NGen will insert the call to .cctor in the instance ctor. // if we are here we passed all the previous checks. Time to look at the arguments + bool wrapExceptions = (invokeAttr & BindingFlags.DoNotWrapExceptions) == 0; if (actualCount > 0) { Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig); - Object retValue = RuntimeMethodHandle.InvokeMethod(null, arguments, sig, true); + Object retValue = RuntimeMethodHandle.InvokeMethod(null, arguments, sig, true, wrapExceptions); // copy out. This should be made only if ByRef are present. for (int index = 0; index < arguments.Length; index++) parameters[index] = arguments[index]; return retValue; } - return RuntimeMethodHandle.InvokeMethod(null, null, sig, true); + return RuntimeMethodHandle.InvokeMethod(null, null, sig, true, wrapExceptions); } #endregion } diff --git a/src/mscorlib/src/System/Reflection/RuntimeMethodInfo.cs b/src/mscorlib/src/System/Reflection/RuntimeMethodInfo.cs index f05508de7b..6addf74718 100644 --- a/src/mscorlib/src/System/Reflection/RuntimeMethodInfo.cs +++ b/src/mscorlib/src/System/Reflection/RuntimeMethodInfo.cs @@ -54,29 +54,6 @@ namespace System.Reflection { // this should be an invocable method, determine the other flags that participate in invocation invocationFlags = RuntimeMethodHandle.GetSecurityFlags(this); - - if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) == 0) - { - if ((Attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public || - (declaringType != null && declaringType.NeedsReflectionSecurityCheck)) - { - // If method is non-public, or declaring type is not visible - invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY; - } - else if (IsGenericMethod) - { - Type[] genericArguments = GetGenericArguments(); - - for (int i = 0; i < genericArguments.Length; i++) - { - if (genericArguments[i].NeedsReflectionSecurityCheck) - { - invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY; - break; - } - } - } - } } m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED; @@ -207,6 +184,7 @@ namespace System.Reflection return m_declaringType; } + internal sealed override int GenericParameterCount => RuntimeMethodHandle.GetGenericParameterCount(this); #endregion #region Object Overrides @@ -488,7 +466,7 @@ namespace System.Reflection { object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture); - return UnsafeInvokeInternal(obj, parameters, arguments); + return UnsafeInvokeInternal(obj, invokeAttr, parameters, arguments); } [DebuggerStepThroughAttribute] @@ -497,18 +475,19 @@ namespace System.Reflection { object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture); - return UnsafeInvokeInternal(obj, parameters, arguments); + return UnsafeInvokeInternal(obj, invokeAttr, parameters, arguments); } [DebuggerStepThroughAttribute] [Diagnostics.DebuggerHidden] - private object UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) + private object UnsafeInvokeInternal(Object obj, BindingFlags invokeAttr, Object[] parameters, Object[] arguments) { + bool wrapExceptions = (invokeAttr & BindingFlags.DoNotWrapExceptions) == 0; if (arguments == null || arguments.Length == 0) - return RuntimeMethodHandle.InvokeMethod(obj, null, Signature, false); + return RuntimeMethodHandle.InvokeMethod(obj, null, Signature, false, wrapExceptions); else { - Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, Signature, false); + Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, Signature, false, wrapExceptions); // copy out. This should be made only if ByRef are present. for (int index = 0; index < arguments.Length; index++) diff --git a/src/mscorlib/src/System/Reflection/RuntimeParameterInfo.cs b/src/mscorlib/src/System/Reflection/RuntimeParameterInfo.cs index 8c07d8f397..8f070b6827 100644 --- a/src/mscorlib/src/System/Reflection/RuntimeParameterInfo.cs +++ b/src/mscorlib/src/System/Reflection/RuntimeParameterInfo.cs @@ -118,20 +118,12 @@ namespace System.Reflection #endregion #region Private Data Members - // These are new in Whidbey, so we cannot serialize them directly or we break backwards compatibility. - [NonSerialized] private int m_tkParamDef; - [NonSerialized] private MetadataImport m_scope; - [NonSerialized] private Signature m_signature; - [NonSerialized] private volatile bool m_nameIsCached = false; - [NonSerialized] private readonly bool m_noMetadata = false; - [NonSerialized] private bool m_noDefaultValue = false; - [NonSerialized] private MethodBase m_originalMember = null; #endregion @@ -366,15 +358,15 @@ namespace System.Reflection if (attrType == typeof(DateTimeConstantAttribute)) { - defaultValue = DateTimeConstantAttribute.GetRawDateTimeConstant(attr); + defaultValue = GetRawDateTimeConstant(attr); } else if (attrType == typeof(DecimalConstantAttribute)) { - defaultValue = DecimalConstantAttribute.GetRawDecimalConstant(attr); + defaultValue = GetRawDecimalConstant(attr); } else if (attrType.IsSubclassOf(s_CustomConstantAttributeType)) { - defaultValue = CustomConstantAttribute.GetRawConstant(attr); + defaultValue = GetRawConstant(attr); } } } @@ -403,6 +395,80 @@ namespace System.Reflection return defaultValue; } + private static Decimal GetRawDecimalConstant(CustomAttributeData attr) + { + Contract.Requires(attr.Constructor.DeclaringType == typeof(DecimalConstantAttribute)); + + foreach (CustomAttributeNamedArgument namedArgument in attr.NamedArguments) + { + if (namedArgument.MemberInfo.Name.Equals("Value")) + { + // This is not possible because Decimal cannot be represented directly in the metadata. + Debug.Assert(false, "Decimal cannot be represented directly in the metadata."); + return (Decimal)namedArgument.TypedValue.Value; + } + } + + ParameterInfo[] parameters = attr.Constructor.GetParameters(); + Debug.Assert(parameters.Length == 5); + + System.Collections.Generic.IList<CustomAttributeTypedArgument> args = attr.ConstructorArguments; + Debug.Assert(args.Count == 5); + + if (parameters[2].ParameterType == typeof(uint)) + { + // DecimalConstantAttribute(byte scale, byte sign, uint hi, uint mid, uint low) + int low = (int)(UInt32)args[4].Value; + int mid = (int)(UInt32)args[3].Value; + int hi = (int)(UInt32)args[2].Value; + byte sign = (byte)args[1].Value; + byte scale = (byte)args[0].Value; + + return new System.Decimal(low, mid, hi, (sign != 0), scale); + } + else + { + // DecimalConstantAttribute(byte scale, byte sign, int hi, int mid, int low) + int low = (int)args[4].Value; + int mid = (int)args[3].Value; + int hi = (int)args[2].Value; + byte sign = (byte)args[1].Value; + byte scale = (byte)args[0].Value; + + return new System.Decimal(low, mid, hi, (sign != 0), scale); + } + } + + private static DateTime GetRawDateTimeConstant(CustomAttributeData attr) + { + Contract.Requires(attr.Constructor.DeclaringType == typeof(DateTimeConstantAttribute)); + Contract.Requires(attr.ConstructorArguments.Count == 1); + + foreach (CustomAttributeNamedArgument namedArgument in attr.NamedArguments) + { + if (namedArgument.MemberInfo.Name.Equals("Value")) + { + return new DateTime((long)namedArgument.TypedValue.Value); + } + } + + // Look at the ctor argument if the "Value" property was not explicitly defined. + return new DateTime((long)attr.ConstructorArguments[0].Value); + } + + private static object GetRawConstant(CustomAttributeData attr) + { + foreach (CustomAttributeNamedArgument namedArgument in attr.NamedArguments) + { + if (namedArgument.MemberInfo.Name.Equals("Value")) + return namedArgument.TypedValue.Value; + } + + // Return DBNull to indicate that no default value is available. + // Not to be confused with a null return which indicates a null default value. + return DBNull.Value; + } + internal RuntimeModule GetRuntimeModule() { RuntimeMethodInfo method = Member as RuntimeMethodInfo; |