From 4b4aad7217d3292650e77eec2cf4c198ea9c3b4b Mon Sep 17 00:00:00 2001 From: Jiyoung Yun Date: Wed, 23 Nov 2016 19:09:09 +0900 Subject: Imported Upstream version 1.1.0 --- .../System/Reflection/AmbiguousMatchException.cs | 42 + src/mscorlib/src/System/Reflection/Assembly.cs | 3013 ++++++++++++++++++++ .../src/System/Reflection/AssemblyAttributes.cs | 406 +++ src/mscorlib/src/System/Reflection/AssemblyName.cs | 539 ++++ .../src/System/Reflection/AssemblyNameFlags.cs | 56 + .../src/System/Reflection/AssemblyNameProxy.cs | 28 + src/mscorlib/src/System/Reflection/Associates.cs | 212 ++ src/mscorlib/src/System/Reflection/Binder.cs | 51 + src/mscorlib/src/System/Reflection/BindingFlags.cs | 64 + .../src/System/Reflection/CallingConventions.cs | 29 + .../src/System/Reflection/ComInterfaces.cs | 673 +++++ .../src/System/Reflection/ConstructorInfo.cs | 781 +++++ .../src/System/Reflection/CustomAttribute.cs | 2527 ++++++++++++++++ .../System/Reflection/CustomAttributeExtensions.cs | 174 ++ .../Reflection/CustomAttributeFormatException.cs | 38 + .../System/Reflection/DefaultMemberAttribute.cs | 40 + .../src/System/Reflection/Emit/AQNBuilder.cs | 208 ++ .../src/System/Reflection/Emit/AssemblyBuilder.cs | 2245 +++++++++++++++ .../Reflection/Emit/AssemblyBuilderAccess.cs | 29 + .../System/Reflection/Emit/AssemblyBuilderData.cs | 583 ++++ .../src/System/Reflection/Emit/ComInterfaces.cs | 288 ++ .../System/Reflection/Emit/ConstructorBuilder.cs | 335 +++ .../Reflection/Emit/CustomAttributeBuilder.cs | 582 ++++ .../System/Reflection/Emit/DynamicILGenerator.cs | 1329 +++++++++ .../src/System/Reflection/Emit/DynamicMethod.cs | 1039 +++++++ .../src/System/Reflection/Emit/EnumBuilder.cs | 448 +++ .../src/System/Reflection/Emit/EventBuilder.cs | 174 ++ .../src/System/Reflection/Emit/EventToken.cs | 69 + .../src/System/Reflection/Emit/FieldBuilder.cs | 281 ++ .../src/System/Reflection/Emit/FieldToken.cs | 86 + .../src/System/Reflection/Emit/FlowControl.cs | 37 + .../Reflection/Emit/GenericTypeParameterBuilder.cs | 248 ++ .../src/System/Reflection/Emit/ILGenerator.cs | 2012 +++++++++++++ .../src/System/Reflection/Emit/ISymWrapperCore.cs | 828 ++++++ src/mscorlib/src/System/Reflection/Emit/Label.cs | 74 + .../src/System/Reflection/Emit/LocalBuilder.cs | 151 + .../src/System/Reflection/Emit/MethodBuilder.cs | 1610 +++++++++++ .../Reflection/Emit/MethodBuilderInstantiation.cs | 142 + .../src/System/Reflection/Emit/MethodToken.cs | 65 + .../src/System/Reflection/Emit/ModuleBuilder.cs | 2422 ++++++++++++++++ .../System/Reflection/Emit/ModuleBuilderData.cs | 104 + src/mscorlib/src/System/Reflection/Emit/OpCodes.cs | 2552 +++++++++++++++++ src/mscorlib/src/System/Reflection/Emit/Opcode.cs | 312 ++ .../src/System/Reflection/Emit/OpcodeType.cs | 35 + .../src/System/Reflection/Emit/OperandType.cs | 47 + .../src/System/Reflection/Emit/PEFileKinds.cs | 17 + .../src/System/Reflection/Emit/ParameterBuilder.cs | 172 ++ .../src/System/Reflection/Emit/ParameterToken.cs | 73 + .../src/System/Reflection/Emit/PropertyBuilder.cs | 306 ++ .../src/System/Reflection/Emit/PropertyToken.cs | 70 + .../src/System/Reflection/Emit/SignatureHelper.cs | 1019 +++++++ .../src/System/Reflection/Emit/SignatureToken.cs | 68 + .../src/System/Reflection/Emit/StackBehaviour.cs | 54 + .../src/System/Reflection/Emit/StringToken.cs | 79 + .../src/System/Reflection/Emit/SymbolMethod.cs | 184 ++ .../src/System/Reflection/Emit/SymbolType.cs | 606 ++++ .../src/System/Reflection/Emit/TypeBuilder.cs | 2620 +++++++++++++++++ .../Reflection/Emit/TypeBuilderInstantiation.cs | 276 ++ .../src/System/Reflection/Emit/TypeToken.cs | 74 + .../src/System/Reflection/Emit/UnmanagedMarshal.cs | 184 ++ .../Emit/XXXOnTypeBuilderInstantiation.cs | 331 +++ .../src/System/Reflection/EventAttributes.cs | 30 + src/mscorlib/src/System/Reflection/EventInfo.cs | 443 +++ .../src/System/Reflection/FieldAttributes.cs | 43 + src/mscorlib/src/System/Reflection/FieldInfo.cs | 955 +++++++ .../Reflection/GenericParameterAttributes.cs | 22 + .../System/Reflection/ICustomAttributeProvider.cs | 34 + src/mscorlib/src/System/Reflection/IReflect.cs | 117 + .../src/System/Reflection/IReflectableType.cs | 20 + .../src/System/Reflection/InterfaceMapping.cs | 27 + .../System/Reflection/IntrospectionExtensions.cs | 35 + .../Reflection/InvalidFilterCriteriaException.cs | 44 + .../src/System/Reflection/LoaderAllocator.cs | 86 + .../src/System/Reflection/ManifestResourceInfo.cs | 67 + src/mscorlib/src/System/Reflection/MdConstant.cs | 169 ++ src/mscorlib/src/System/Reflection/MdImport.cs | 736 +++++ src/mscorlib/src/System/Reflection/MemberFilter.cs | 19 + src/mscorlib/src/System/Reflection/MemberInfo.cs | 148 + .../Reflection/MemberInfoSerializationHolder.cs | 287 ++ src/mscorlib/src/System/Reflection/MemberTypes.cs | 34 + .../Reflection/Metadata/AssemblyExtensions.cs | 47 + .../src/System/Reflection/MethodAttributes.cs | 56 + src/mscorlib/src/System/Reflection/MethodBase.cs | 402 +++ src/mscorlib/src/System/Reflection/MethodBody.cs | 169 ++ .../src/System/Reflection/MethodImplAttributes.cs | 45 + src/mscorlib/src/System/Reflection/MethodInfo.cs | 1061 +++++++ src/mscorlib/src/System/Reflection/Missing.cs | 38 + src/mscorlib/src/System/Reflection/Module.cs | 1230 ++++++++ .../Reflection/ObfuscateAssemblyAttribute.cs | 46 + .../src/System/Reflection/ObfuscationAttribute.cs | 75 + .../src/System/Reflection/ParameterAttributes.cs | 36 + .../src/System/Reflection/ParameterInfo.cs | 795 ++++++ .../src/System/Reflection/ParameterModifier.cs | 46 + src/mscorlib/src/System/Reflection/Pointer.cs | 82 + .../src/System/Reflection/PropertyAttributes.cs | 33 + src/mscorlib/src/System/Reflection/PropertyInfo.cs | 657 +++++ .../src/System/Reflection/ReflectionContext.cs | 36 + .../Reflection/ReflectionTypeLoadException.cs | 80 + .../src/System/Reflection/ResourceAttributes.cs | 24 + .../Reflection/RuntimeReflectionExtensions.cs | 88 + .../src/System/Reflection/StrongNameKeyPair.cs | 194 ++ .../src/System/Reflection/TargetException.cs | 42 + .../System/Reflection/TargetInvocationException.cs | 51 + .../Reflection/TargetParameterCountException.cs | 45 + .../src/System/Reflection/TypeAttributes.cs | 66 + .../src/System/Reflection/TypeDelegator.cs | 263 ++ src/mscorlib/src/System/Reflection/TypeFilter.cs | 19 + src/mscorlib/src/System/Reflection/TypeInfo.cs | 195 ++ src/mscorlib/src/System/Reflection/__Filters.cs | 67 + 109 files changed, 42445 insertions(+) create mode 100644 src/mscorlib/src/System/Reflection/AmbiguousMatchException.cs create mode 100644 src/mscorlib/src/System/Reflection/Assembly.cs create mode 100644 src/mscorlib/src/System/Reflection/AssemblyAttributes.cs create mode 100644 src/mscorlib/src/System/Reflection/AssemblyName.cs create mode 100644 src/mscorlib/src/System/Reflection/AssemblyNameFlags.cs create mode 100644 src/mscorlib/src/System/Reflection/AssemblyNameProxy.cs create mode 100644 src/mscorlib/src/System/Reflection/Associates.cs create mode 100644 src/mscorlib/src/System/Reflection/Binder.cs create mode 100644 src/mscorlib/src/System/Reflection/BindingFlags.cs create mode 100644 src/mscorlib/src/System/Reflection/CallingConventions.cs create mode 100644 src/mscorlib/src/System/Reflection/ComInterfaces.cs create mode 100644 src/mscorlib/src/System/Reflection/ConstructorInfo.cs create mode 100644 src/mscorlib/src/System/Reflection/CustomAttribute.cs create mode 100644 src/mscorlib/src/System/Reflection/CustomAttributeExtensions.cs create mode 100644 src/mscorlib/src/System/Reflection/CustomAttributeFormatException.cs create mode 100644 src/mscorlib/src/System/Reflection/DefaultMemberAttribute.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/AQNBuilder.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderAccess.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderData.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/ComInterfaces.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/ConstructorBuilder.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/CustomAttributeBuilder.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/DynamicILGenerator.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/EnumBuilder.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/EventBuilder.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/EventToken.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/FieldBuilder.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/FieldToken.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/FlowControl.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/ISymWrapperCore.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/Label.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/LocalBuilder.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/MethodBuilder.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/MethodBuilderInstantiation.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/MethodToken.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/OpCodes.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/Opcode.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/OpcodeType.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/OperandType.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/PEFileKinds.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/ParameterBuilder.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/ParameterToken.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/PropertyBuilder.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/PropertyToken.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/SignatureHelper.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/SignatureToken.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/StackBehaviour.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/StringToken.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/SymbolMethod.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/SymbolType.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/TypeToken.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/UnmanagedMarshal.cs create mode 100644 src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs create mode 100644 src/mscorlib/src/System/Reflection/EventAttributes.cs create mode 100644 src/mscorlib/src/System/Reflection/EventInfo.cs create mode 100644 src/mscorlib/src/System/Reflection/FieldAttributes.cs create mode 100644 src/mscorlib/src/System/Reflection/FieldInfo.cs create mode 100644 src/mscorlib/src/System/Reflection/GenericParameterAttributes.cs create mode 100644 src/mscorlib/src/System/Reflection/ICustomAttributeProvider.cs create mode 100644 src/mscorlib/src/System/Reflection/IReflect.cs create mode 100644 src/mscorlib/src/System/Reflection/IReflectableType.cs create mode 100644 src/mscorlib/src/System/Reflection/InterfaceMapping.cs create mode 100644 src/mscorlib/src/System/Reflection/IntrospectionExtensions.cs create mode 100644 src/mscorlib/src/System/Reflection/InvalidFilterCriteriaException.cs create mode 100644 src/mscorlib/src/System/Reflection/LoaderAllocator.cs create mode 100644 src/mscorlib/src/System/Reflection/ManifestResourceInfo.cs create mode 100644 src/mscorlib/src/System/Reflection/MdConstant.cs create mode 100644 src/mscorlib/src/System/Reflection/MdImport.cs create mode 100644 src/mscorlib/src/System/Reflection/MemberFilter.cs create mode 100644 src/mscorlib/src/System/Reflection/MemberInfo.cs create mode 100644 src/mscorlib/src/System/Reflection/MemberInfoSerializationHolder.cs create mode 100644 src/mscorlib/src/System/Reflection/MemberTypes.cs create mode 100644 src/mscorlib/src/System/Reflection/Metadata/AssemblyExtensions.cs create mode 100644 src/mscorlib/src/System/Reflection/MethodAttributes.cs create mode 100644 src/mscorlib/src/System/Reflection/MethodBase.cs create mode 100644 src/mscorlib/src/System/Reflection/MethodBody.cs create mode 100644 src/mscorlib/src/System/Reflection/MethodImplAttributes.cs create mode 100644 src/mscorlib/src/System/Reflection/MethodInfo.cs create mode 100644 src/mscorlib/src/System/Reflection/Missing.cs create mode 100644 src/mscorlib/src/System/Reflection/Module.cs create mode 100644 src/mscorlib/src/System/Reflection/ObfuscateAssemblyAttribute.cs create mode 100644 src/mscorlib/src/System/Reflection/ObfuscationAttribute.cs create mode 100644 src/mscorlib/src/System/Reflection/ParameterAttributes.cs create mode 100644 src/mscorlib/src/System/Reflection/ParameterInfo.cs create mode 100644 src/mscorlib/src/System/Reflection/ParameterModifier.cs create mode 100644 src/mscorlib/src/System/Reflection/Pointer.cs create mode 100644 src/mscorlib/src/System/Reflection/PropertyAttributes.cs create mode 100644 src/mscorlib/src/System/Reflection/PropertyInfo.cs create mode 100644 src/mscorlib/src/System/Reflection/ReflectionContext.cs create mode 100644 src/mscorlib/src/System/Reflection/ReflectionTypeLoadException.cs create mode 100644 src/mscorlib/src/System/Reflection/ResourceAttributes.cs create mode 100644 src/mscorlib/src/System/Reflection/RuntimeReflectionExtensions.cs create mode 100644 src/mscorlib/src/System/Reflection/StrongNameKeyPair.cs create mode 100644 src/mscorlib/src/System/Reflection/TargetException.cs create mode 100644 src/mscorlib/src/System/Reflection/TargetInvocationException.cs create mode 100644 src/mscorlib/src/System/Reflection/TargetParameterCountException.cs create mode 100644 src/mscorlib/src/System/Reflection/TypeAttributes.cs create mode 100644 src/mscorlib/src/System/Reflection/TypeDelegator.cs create mode 100644 src/mscorlib/src/System/Reflection/TypeFilter.cs create mode 100644 src/mscorlib/src/System/Reflection/TypeInfo.cs create mode 100644 src/mscorlib/src/System/Reflection/__Filters.cs (limited to 'src/mscorlib/src/System/Reflection') diff --git a/src/mscorlib/src/System/Reflection/AmbiguousMatchException.cs b/src/mscorlib/src/System/Reflection/AmbiguousMatchException.cs new file mode 100644 index 0000000000..6df371bd11 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/AmbiguousMatchException.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// AmbiguousMatchException is thrown when binding to a method results in more +// +// than one method matching the binding criteria. This exception is thrown in +// general when something is Ambiguous. +// +// +// +// +namespace System.Reflection { + using System; + using SystemException = System.SystemException; + using System.Runtime.Serialization; + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public sealed class AmbiguousMatchException : SystemException + { + + public AmbiguousMatchException() + : base(Environment.GetResourceString("RFLCT.Ambiguous")) { + SetErrorCode(__HResults.COR_E_AMBIGUOUSMATCH); + } + + public AmbiguousMatchException(String message) : base(message) { + SetErrorCode(__HResults.COR_E_AMBIGUOUSMATCH); + } + + public AmbiguousMatchException(String message, Exception inner) : base(message, inner) { + SetErrorCode(__HResults.COR_E_AMBIGUOUSMATCH); + } + + internal AmbiguousMatchException(SerializationInfo info, StreamingContext context) : base(info, context) { + } + + } +} diff --git a/src/mscorlib/src/System/Reflection/Assembly.cs b/src/mscorlib/src/System/Reflection/Assembly.cs new file mode 100644 index 0000000000..479d6ca3a6 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Assembly.cs @@ -0,0 +1,3013 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================================= +** +** +** +** +** +** +** Purpose: For Assembly-related stuff. +** +** +=============================================================================*/ + +namespace System.Reflection +{ + using System; + using System.Collections; + using System.Collections.Generic; + using CultureInfo = System.Globalization.CultureInfo; + using System.Security; + using System.Security.Policy; + using System.Security.Permissions; + using System.IO; + using StringBuilder = System.Text.StringBuilder; + using System.Configuration.Assemblies; + using StackCrawlMark = System.Threading.StackCrawlMark; + using System.Runtime.InteropServices; + using System.Runtime.CompilerServices; + using SecurityZone = System.Security.SecurityZone; + using IEvidenceFactory = System.Security.IEvidenceFactory; + using System.Runtime.Serialization; + using Microsoft.Win32; + using System.Threading; + using __HResults = System.__HResults; + using System.Runtime.Versioning; + using System.Diagnostics.Contracts; + + + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public delegate Module ModuleResolveEventHandler(Object sender, ResolveEventArgs e); + + + [Serializable] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_Assembly))] + [System.Runtime.InteropServices.ComVisible(true)] +#pragma warning disable 618 + [PermissionSetAttribute(SecurityAction.InheritanceDemand, Unrestricted = true)] +#pragma warning restore 618 + public abstract class Assembly : _Assembly, IEvidenceFactory, ICustomAttributeProvider, ISerializable + { +#region constructors + protected Assembly() {} +#endregion + +#region public static methods + + public static String CreateQualifiedName(String assemblyName, String typeName) + { + return typeName + ", " + assemblyName; + } + + public static Assembly GetAssembly(Type type) + { + if (type == null) + throw new ArgumentNullException("type"); + Contract.EndContractBlock(); + + Module m = type.Module; + if (m == null) + return null; + else + return m.Assembly; + } + + public static bool operator ==(Assembly left, Assembly right) + { + if (ReferenceEquals(left, right)) + return true; + + if ((object)left == null || (object)right == null || + left is RuntimeAssembly || right is RuntimeAssembly) + { + return false; + } + return left.Equals(right); + } + + public static bool operator !=(Assembly left, Assembly right) + { + return !(left == right); + } + + public override bool Equals(object o) + { + return base.Equals(o); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + // Locate an assembly by the name of the file containing the manifest. +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly LoadFrom(String assemblyFile) + { + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(!Contract.Result().ReflectionOnly); + +#if FEATURE_WINDOWSPHONE + throw new NotSupportedException(Environment.GetResourceString("NotSupported_WindowsPhone", "Assembly.LoadFrom")); +#else + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + + return RuntimeAssembly.InternalLoadFrom( + assemblyFile, + null, // securityEvidence + null, // hashValue + AssemblyHashAlgorithm.None, + false,// forIntrospection + false,// suppressSecurityChecks + ref stackMark); +#endif // FEATURE_WINDOWSPHONE + } + + // Locate an assembly for reflection by the name of the file containing the manifest. + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly ReflectionOnlyLoadFrom(String assemblyFile) + { + Contract.Ensures(Contract.Result() != null); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + + return RuntimeAssembly.InternalLoadFrom( + assemblyFile, + null, //securityEvidence + null, //hashValue + AssemblyHashAlgorithm.None, + true, //forIntrospection + false, //suppressSecurityChecks + ref stackMark); + } + + // Evidence is protected in Assembly.Load() + [System.Security.SecuritySafeCritical] // auto-generated + [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use an overload of LoadFrom which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")] + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly LoadFrom(String assemblyFile, + Evidence securityEvidence) + { + Contract.Ensures(Contract.Result() != null); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + + return RuntimeAssembly.InternalLoadFrom( + assemblyFile, + securityEvidence, + null, // hashValue + AssemblyHashAlgorithm.None, + false,// forIntrospection); + false,// suppressSecurityChecks + ref stackMark); + } + + // Evidence is protected in Assembly.Load() + [System.Security.SecuritySafeCritical] // auto-generated + [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use an overload of LoadFrom which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")] + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly LoadFrom(String assemblyFile, + Evidence securityEvidence, + byte[] hashValue, + AssemblyHashAlgorithm hashAlgorithm) + { + Contract.Ensures(Contract.Result() != null); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + + return RuntimeAssembly.InternalLoadFrom( + assemblyFile, + securityEvidence, + hashValue, + hashAlgorithm, + false, + false, + ref stackMark); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly LoadFrom(String assemblyFile, + byte[] hashValue, + AssemblyHashAlgorithm hashAlgorithm) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + + return RuntimeAssembly.InternalLoadFrom( + assemblyFile, + null, + hashValue, + hashAlgorithm, + false, + false, + ref stackMark); + } + +#if FEATURE_CAS_POLICY + // Load an assembly into the LoadFrom context bypassing some security checks + [SecurityCritical] + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly UnsafeLoadFrom(string assemblyFile) + { + + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(!Contract.Result().ReflectionOnly); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + + return RuntimeAssembly.InternalLoadFrom(assemblyFile, + null, // securityEvidence + null, // hashValue + AssemblyHashAlgorithm.None, + false, // forIntrospection + true, // suppressSecurityChecks + ref stackMark); + } +#endif // FEATURE_CAS_POLICY + + // Locate an assembly by the long form of the assembly name. + // eg. "Toolbox.dll, version=1.1.10.1220, locale=en, publickey=1234567890123456789012345678901234567890" + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly Load(String assemblyString) + { + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(!Contract.Result().ReflectionOnly); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.InternalLoad(assemblyString, null, ref stackMark, false /*forIntrospection*/); + } + + // Returns type from the assembly while keeping compatibility with Assembly.Load(assemblyString).GetType(typeName) for managed types. + // Calls Type.GetType for WinRT types. + // Note: Type.GetType fails for assembly names that start with weird characters like '['. By calling it for managed types we would + // break AppCompat. + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + internal static Type GetType_Compat(String assemblyString, String typeName) + { + // Normally we would get the stackMark only in public APIs. This is internal API, but it is AppCompat replacement of public API + // call Assembly.Load(assemblyString).GetType(typeName), therefore we take the stackMark here as well, to be fully compatible with + // the call sequence. + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + + RuntimeAssembly assembly; + AssemblyName assemblyName = RuntimeAssembly.CreateAssemblyName( + assemblyString, + false /*forIntrospection*/, + out assembly); + + if (assembly == null) { + if (assemblyName.ContentType == AssemblyContentType.WindowsRuntime) { + return Type.GetType(typeName + ", " + assemblyString, true /*throwOnError*/, false /*ignoreCase*/); + } + + assembly = RuntimeAssembly.InternalLoadAssemblyName( + assemblyName, null, null, ref stackMark, + true /*thrownOnFileNotFound*/, false /*forIntrospection*/, false /*suppressSecurityChecks*/); + } + return assembly.GetType(typeName, true /*throwOnError*/, false /*ignoreCase*/); + } + + // Locate an assembly for reflection by the long form of the assembly name. + // eg. "Toolbox.dll, version=1.1.10.1220, locale=en, publickey=1234567890123456789012345678901234567890" + // + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly ReflectionOnlyLoad(String assemblyString) + { + Contract.Ensures(Contract.Result() != null); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.InternalLoad(assemblyString, null, ref stackMark, true /*forIntrospection*/); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use an overload of Load which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")] + public static Assembly Load(String assemblyString, Evidence assemblySecurity) + { + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(!Contract.Result().ReflectionOnly); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.InternalLoad(assemblyString, assemblySecurity, ref stackMark, false /*forIntrospection*/); + } + + // Locate an assembly by its name. The name can be strong or + // weak. The assembly is loaded into the domain of the caller. +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly Load(AssemblyName assemblyRef) + { + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(!Contract.Result().ReflectionOnly); + +#if FEATURE_WINDOWSPHONE + if (assemblyRef != null && assemblyRef.CodeBase != null) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_AssemblyLoadCodeBase")); + } +#endif + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.InternalLoadAssemblyName(assemblyRef, null, null, ref stackMark, true /*thrownOnFileNotFound*/, false /*forIntrospection*/, false /*suppressSecurityChecks*/); + } + + // Locate an assembly by its name. The name can be strong or + // weak. The assembly is loaded into the domain of the caller. +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + internal static Assembly Load(AssemblyName assemblyRef, IntPtr ptrLoadContextBinder) + { + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(!Contract.Result().ReflectionOnly); + +#if FEATURE_WINDOWSPHONE + if (assemblyRef != null && assemblyRef.CodeBase != null) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_AssemblyLoadCodeBase")); + } +#endif + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.InternalLoadAssemblyName(assemblyRef, null, null, ref stackMark, true /*thrownOnFileNotFound*/, false /*forIntrospection*/, false /*suppressSecurityChecks*/, ptrLoadContextBinder); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use an overload of Load which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")] + public static Assembly Load(AssemblyName assemblyRef, Evidence assemblySecurity) + { + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(!Contract.Result().ReflectionOnly); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.InternalLoadAssemblyName(assemblyRef, assemblySecurity, null, ref stackMark, true /*thrownOnFileNotFound*/, false /*forIntrospection*/, false /*suppressSecurityChecks*/); + } + +#if FEATURE_FUSION + [System.Security.SecuritySafeCritical] // auto-generated + [Obsolete("This method has been deprecated. Please use Assembly.Load() instead. http://go.microsoft.com/fwlink/?linkid=14202")] + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly LoadWithPartialName(String partialName) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.LoadWithPartialNameInternal(partialName, null, ref stackMark); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [Obsolete("This method has been deprecated. Please use Assembly.Load() instead. http://go.microsoft.com/fwlink/?linkid=14202")] + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly LoadWithPartialName(String partialName, Evidence securityEvidence) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.LoadWithPartialNameInternal(partialName, securityEvidence, ref stackMark); + } +#endif // FEATURE_FUSION + + // Loads the assembly with a COFF based IMAGE containing + // an emitted assembly. The assembly is loaded into the domain + // of the caller. +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly Load(byte[] rawAssembly) + { + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(!Contract.Result().ReflectionOnly); + + AppDomain.CheckLoadByteArraySupported(); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.nLoadImage( + rawAssembly, + null, // symbol store + null, // evidence + ref stackMark, + false, // fIntrospection + SecurityContextSource.CurrentAssembly); + } + + // Loads the assembly for reflection with a COFF based IMAGE containing + // an emitted assembly. The assembly is loaded into the domain + // of the caller. + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly ReflectionOnlyLoad(byte[] rawAssembly) + { + Contract.Ensures(Contract.Result() != null); + + AppDomain.CheckReflectionOnlyLoadSupported(); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.nLoadImage( + rawAssembly, + null, // symbol store + null, // evidence + ref stackMark, + true, // fIntrospection + SecurityContextSource.CurrentAssembly); + } + + // Loads the assembly with a COFF based IMAGE containing + // an emitted assembly. The assembly is loaded into the domain + // of the caller. The second parameter is the raw bytes + // representing the symbol store that matches the assembly. +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly Load(byte[] rawAssembly, + byte[] rawSymbolStore) + { + + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(!Contract.Result().ReflectionOnly); + + AppDomain.CheckLoadByteArraySupported(); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.nLoadImage( + rawAssembly, + rawSymbolStore, + null, // evidence + ref stackMark, + false, // fIntrospection + SecurityContextSource.CurrentAssembly); + } + + // Load an assembly from a byte array, controlling where the grant set of this assembly is + // propigated from. + [SecuritySafeCritical] + [MethodImpl(MethodImplOptions.NoInlining)] // Due to the stack crawl mark + public static Assembly Load(byte[] rawAssembly, + byte[] rawSymbolStore, + SecurityContextSource securityContextSource) + { + + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(!Contract.Result().ReflectionOnly); + + AppDomain.CheckLoadByteArraySupported(); + + if (securityContextSource < SecurityContextSource.CurrentAppDomain || + securityContextSource > SecurityContextSource.CurrentAssembly) + { + throw new ArgumentOutOfRangeException("securityContextSource"); + } + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.nLoadImage(rawAssembly, + rawSymbolStore, + null, // evidence + ref stackMark, + false, // fIntrospection + securityContextSource); + } + +#if FEATURE_CAS_POLICY + [System.Security.SecuritySafeCritical] // auto-generated + [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlEvidence)] + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use an overload of Load which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")] + public static Assembly Load(byte[] rawAssembly, + byte[] rawSymbolStore, + Evidence securityEvidence) + { + + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(!Contract.Result().ReflectionOnly); + + AppDomain.CheckLoadByteArraySupported(); + + if (securityEvidence != null && !AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled) + { + // A zone of MyComputer could not have been used to sandbox, so for compatibility we do not + // throw an exception when we see it. + Zone zone = securityEvidence.GetHostEvidence(); + if (zone == null || zone.SecurityZone != SecurityZone.MyComputer) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit")); + } + } + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.nLoadImage( + rawAssembly, + rawSymbolStore, + securityEvidence, + ref stackMark, + false, // fIntrospection + SecurityContextSource.CurrentAssembly); + } +#endif // FEATURE_CAS_POLICY + + [System.Security.SecuritySafeCritical] // auto-generated + public static Assembly LoadFile(String path) + { + + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(!Contract.Result().ReflectionOnly); + + AppDomain.CheckLoadFileSupported(); + + new FileIOPermission(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, path).Demand(); + return RuntimeAssembly.nLoadFile(path, null); + } + +#if FEATURE_CAS_POLICY + [System.Security.SecuritySafeCritical] // auto-generated + [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlEvidence)] + [Obsolete("This method is obsolete and will be removed in a future release of the .NET Framework. Please use an overload of LoadFile which does not take an Evidence parameter. See http://go.microsoft.com/fwlink/?LinkID=155570 for more information.")] + public static Assembly LoadFile(String path, + Evidence securityEvidence) + { + + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(!Contract.Result().ReflectionOnly); + + AppDomain.CheckLoadFileSupported(); + + if (securityEvidence != null && !AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit")); + + new FileIOPermission(FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read, path).Demand(); + return RuntimeAssembly.nLoadFile(path, securityEvidence); + } +#endif // FEATURE_CAS_POLICY + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly Load(Stream assemblyStream, Stream pdbStream) + { + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(!Contract.Result().ReflectionOnly); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.InternalLoadFromStream(assemblyStream, pdbStream, ref stackMark); + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly Load(Stream assemblyStream) + { + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(!Contract.Result().ReflectionOnly); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.InternalLoadFromStream(assemblyStream, null, ref stackMark); + } +#endif //FEATURE_CORECLR + + /* + * Get the assembly that the current code is running from. + */ + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly GetExecutingAssembly() + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeAssembly.GetExecutingAssembly(ref stackMark); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static Assembly GetCallingAssembly() + { + // LookForMyCallersCaller is not guarantee to return the correct stack frame + // because of inlining, tail calls, etc. As a result GetCallingAssembly is not + // ganranteed to return the correct result. We should document it as such. + StackCrawlMark stackMark = StackCrawlMark.LookForMyCallersCaller; + return RuntimeAssembly.GetExecutingAssembly(ref stackMark); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public static Assembly GetEntryAssembly() { + AppDomainManager domainManager = AppDomain.CurrentDomain.DomainManager; + if (domainManager == null) + domainManager = new AppDomainManager(); + return domainManager.EntryAssembly; + } + +#endregion // public static methods + +#region public methods + public virtual event ModuleResolveEventHandler ModuleResolve + { + [System.Security.SecurityCritical] // auto-generated_required + add + { + throw new NotImplementedException(); + } + [System.Security.SecurityCritical] // auto-generated_required + remove + { + throw new NotImplementedException(); + } + } + + public virtual String CodeBase + { +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + get + { + throw new NotImplementedException(); + } + } + + public virtual String EscapedCodeBase + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + return AssemblyName.EscapeCodeBase(CodeBase); + } + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + public virtual AssemblyName GetName() + { + return GetName(false); + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + public virtual AssemblyName GetName(bool copiedName) + { + throw new NotImplementedException(); + } + + public virtual String FullName + { + get + { + throw new NotImplementedException(); + } + } + + public virtual MethodInfo EntryPoint + { + get + { + throw new NotImplementedException(); + } + } + +#if !FEATURE_CORECLR + Type _Assembly.GetType() + { + return base.GetType(); + } +#endif + + public virtual Type GetType(String name) + { + return GetType(name, false, false); + } + + public virtual Type GetType(String name, bool throwOnError) + { + return GetType(name, throwOnError, false); + } + + public virtual Type GetType(String name, bool throwOnError, bool ignoreCase) + { + throw new NotImplementedException(); + } + + public virtual IEnumerable ExportedTypes + { + get + { + return GetExportedTypes(); + } + } + + public virtual Type[] GetExportedTypes() + { + throw new NotImplementedException(); + } + + public virtual IEnumerable DefinedTypes + { + get + { + Type[] types = GetTypes(); + + TypeInfo[] typeinfos = new TypeInfo[types.Length]; + + for (int i = 0; i < types.Length; i++) + { + + TypeInfo typeinfo = types[i].GetTypeInfo(); + if (typeinfo == null) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NoTypeInfo", types[i].FullName)); + + typeinfos[i] = typeinfo; + } + + return typeinfos; + } + } + + public virtual Type[] GetTypes() + { + Module[] m = GetModules(false); + + int iNumModules = m.Length; + int iFinalLength = 0; + Type[][] ModuleTypes = new Type[iNumModules][]; + + for (int i = 0; i < iNumModules; i++) + { + ModuleTypes[i] = m[i].GetTypes(); + iFinalLength += ModuleTypes[i].Length; + } + + int iCurrent = 0; + Type[] ret = new Type[iFinalLength]; + for (int i = 0; i < iNumModules; i++) + { + int iLength = ModuleTypes[i].Length; + Array.Copy(ModuleTypes[i], 0, ret, iCurrent, iLength); + iCurrent += iLength; + } + + return ret; + } + + // Load a resource based on the NameSpace of the type. + public virtual Stream GetManifestResourceStream(Type type, String name) + { + throw new NotImplementedException(); + } + + public virtual Stream GetManifestResourceStream(String name) + { + throw new NotImplementedException(); + } + + public virtual Assembly GetSatelliteAssembly(CultureInfo culture) + { + throw new NotImplementedException(); + } + + // Useful for binding to a very specific version of a satellite assembly + public virtual Assembly GetSatelliteAssembly(CultureInfo culture, Version version) + { + throw new NotImplementedException(); + } + +#if FEATURE_CAS_POLICY + public virtual Evidence Evidence + { + get + { + throw new NotImplementedException(); + } + } + + public virtual PermissionSet PermissionSet + { + // SecurityCritical because permissions can contain sensitive information such as paths + [SecurityCritical] + get + { + throw new NotImplementedException(); + } + } + + public bool IsFullyTrusted + { + [SecuritySafeCritical] + get + { + return PermissionSet.IsUnrestricted(); + } + } + + public virtual SecurityRuleSet SecurityRuleSet + { + get + { + throw new NotImplementedException(); + } + } + +#endif // FEATURE_CAS_POLICY + + // ISerializable implementation + [System.Security.SecurityCritical] // auto-generated_required + public virtual void GetObjectData(SerializationInfo info, StreamingContext context) + { + throw new NotImplementedException(); + } + + [ComVisible(false)] + public virtual Module ManifestModule + { + get + { + // This API was made virtual in V4. Code compiled against V2 might use + // "call" rather than "callvirt" to call it. + // This makes sure those code still works. + RuntimeAssembly rtAssembly = this as RuntimeAssembly; + if (rtAssembly != null) + return rtAssembly.ManifestModule; + + throw new NotImplementedException(); + } + } + + public virtual IEnumerable CustomAttributes + { + get + { + return GetCustomAttributesData(); + } + } + public virtual Object[] GetCustomAttributes(bool inherit) + { + Contract.Ensures(Contract.Result() != null); + throw new NotImplementedException(); + } + + public virtual Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + Contract.Ensures(Contract.Result() != null); + throw new NotImplementedException(); + } + + public virtual bool IsDefined(Type attributeType, bool inherit) + { + throw new NotImplementedException(); + } + + public virtual IList GetCustomAttributesData() + { + throw new NotImplementedException(); + } + + // To not break compatibility with the V1 _Assembly interface we need to make this + // new member ComVisible(false). + [ComVisible(false)] + public virtual bool ReflectionOnly + { + get + { + throw new NotImplementedException(); + } + } + +#if FEATURE_MULTIMODULE_ASSEMBLIES + + public Module LoadModule(String moduleName, + byte[] rawModule) + { + return LoadModule(moduleName, rawModule, null); + } + + public virtual Module LoadModule(String moduleName, + byte[] rawModule, + byte[] rawSymbolStore) + { + throw new NotImplementedException(); + } +#endif //FEATURE_MULTIMODULE_ASSEMBLIES + + // + // Locates a type from this assembly and creates an instance of it using + // the system activator. + // + public Object CreateInstance(String typeName) + { + return CreateInstance(typeName, + false, // ignore case + BindingFlags.Public | BindingFlags.Instance, + null, // binder + null, // args + null, // culture + null); // activation attributes + } + + public Object CreateInstance(String typeName, + bool ignoreCase) + { + return CreateInstance(typeName, + ignoreCase, + BindingFlags.Public | BindingFlags.Instance, + null, // binder + null, // args + null, // culture + null); // activation attributes + } + + public virtual Object CreateInstance(String typeName, + bool ignoreCase, + BindingFlags bindingAttr, + Binder binder, + Object[] args, + CultureInfo culture, + Object[] activationAttributes) + { + Type t = GetType(typeName, false, ignoreCase); + if (t == null) return null; + return Activator.CreateInstance(t, + bindingAttr, + binder, + args, + culture, + activationAttributes); + } + + public virtual IEnumerable Modules + { + get + { + return GetLoadedModules(true); + } + } + + public Module[] GetLoadedModules() + { + return GetLoadedModules(false); + } + + public virtual Module[] GetLoadedModules(bool getResourceModules) + { + throw new NotImplementedException(); + } + + public Module[] GetModules() + { + return GetModules(false); + } + + public virtual Module[] GetModules(bool getResourceModules) + { + throw new NotImplementedException(); + } + + public virtual Module GetModule(String name) + { + throw new NotImplementedException(); + } + + // Returns the file in the File table of the manifest that matches the + // given name. (Name should not include path.) +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + public virtual FileStream GetFile(String name) + { + throw new NotImplementedException(); + } + + public virtual FileStream[] GetFiles() + { + return GetFiles(false); + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + public virtual FileStream[] GetFiles(bool getResourceModules) + { + throw new NotImplementedException(); + } + + // Returns the names of all the resources + public virtual String[] GetManifestResourceNames() + { + throw new NotImplementedException(); + } + + public virtual AssemblyName[] GetReferencedAssemblies() + { + throw new NotImplementedException(); + } + + public virtual ManifestResourceInfo GetManifestResourceInfo(String resourceName) + { + throw new NotImplementedException(); + } + + public override String ToString() + { + String displayName = FullName; + if (displayName == null) + return base.ToString(); + else + return displayName; + } + + public virtual String Location + { +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + get + { + throw new NotImplementedException(); + } + } + + // To not break compatibility with the V1 _Assembly interface we need to make this + // new member ComVisible(false). + [ComVisible(false)] + public virtual String ImageRuntimeVersion + { + get + { + throw new NotImplementedException(); + } + } + + /* + Returns true if the assembly was loaded from the global assembly cache. + */ + public virtual bool GlobalAssemblyCache + { + get + { + throw new NotImplementedException(); + } + } + + [ComVisible(false)] + public virtual Int64 HostContext + { + get + { + // This API was made virtual in V4. Code compiled against V2 might use + // "call" rather than "callvirt" to call it. + // This makes sure those code still works. + RuntimeAssembly rtAssembly = this as RuntimeAssembly; + if (rtAssembly != null) + return rtAssembly.HostContext; + + throw new NotImplementedException(); + } + } + + public virtual bool IsDynamic + { + get + { + return false; + } + } +#endregion // public methods + + } + + // Keep this in sync with LOADCTX_TYPE defined in fusionpriv.idl + internal enum LoadContext + { + DEFAULT, + LOADFROM, + UNKNOWN, + HOSTED, + } + + [Serializable] + internal class RuntimeAssembly : Assembly +#if !FEATURE_CORECLR + , ICustomQueryInterface +#endif + { +#if !FEATURE_CORECLR +#region ICustomQueryInterface + [System.Security.SecurityCritical] + CustomQueryInterfaceResult ICustomQueryInterface.GetInterface([In]ref Guid iid, out IntPtr ppv) + { + if (iid == typeof(NativeMethods.IDispatch).GUID) + { + ppv = Marshal.GetComInterfaceForObject(this, typeof(_Assembly)); + return CustomQueryInterfaceResult.Handled; + } + + ppv = IntPtr.Zero; + return CustomQueryInterfaceResult.NotHandled; + } +#endregion +#endif // !FEATURE_CORECLR + +#if FEATURE_APPX + // The highest byte is the flags and the lowest 3 bytes are + // the cached ctor token of [DynamicallyInvocableAttribute]. + private enum ASSEMBLY_FLAGS : uint + { + ASSEMBLY_FLAGS_UNKNOWN = 0x00000000, + ASSEMBLY_FLAGS_INITIALIZED = 0x01000000, + ASSEMBLY_FLAGS_FRAMEWORK = 0x02000000, + ASSEMBLY_FLAGS_SAFE_REFLECTION = 0x04000000, + ASSEMBLY_FLAGS_TOKEN_MASK = 0x00FFFFFF, + } +#endif // FEATURE_APPX + + private const uint COR_E_LOADING_REFERENCE_ASSEMBLY = 0x80131058U; + + internal RuntimeAssembly() { throw new NotSupportedException(); } + +#region private data members + [method: System.Security.SecurityCritical] + private event ModuleResolveEventHandler _ModuleResolve; + private string m_fullname; + private object m_syncRoot; // Used to keep collectible types alive and as the syncroot for reflection.emit + private IntPtr m_assembly; // slack for ptr datum on unmanaged side + +#if FEATURE_APPX + private ASSEMBLY_FLAGS m_flags; +#endif +#endregion + +#if FEATURE_APPX + internal int InvocableAttributeCtorToken + { + get + { + int token = (int)(Flags & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_TOKEN_MASK); + + return token | (int)MetadataTokenType.MethodDef; + } + } + + private ASSEMBLY_FLAGS Flags + { + [SecuritySafeCritical] + get + { + if ((m_flags & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_INITIALIZED) == 0) + { + ASSEMBLY_FLAGS flags = ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_UNKNOWN; + +#if FEATURE_CORECLR + flags |= ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_FRAMEWORK | ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_SAFE_REFLECTION; +#else + if (RuntimeAssembly.IsFrameworkAssembly(GetName())) + { + flags |= ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_FRAMEWORK | ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_SAFE_REFLECTION; + + foreach (string name in s_unsafeFrameworkAssemblyNames) + { + if (String.Compare(GetSimpleName(), name, StringComparison.OrdinalIgnoreCase) == 0) + { + flags &= ~ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_SAFE_REFLECTION; + break; + } + } + + // Each blessed API will be annotated with a "__DynamicallyInvokableAttribute". + // This "__DynamicallyInvokableAttribute" is a type defined in its own assembly. + // So the ctor is always a MethodDef and the type a TypeDef. + // We cache this ctor MethodDef token for faster custom attribute lookup. + // If this attribute type doesn't exist in the assembly, it means the assembly + // doesn't contain any blessed APIs. + Type invocableAttribute = GetType("__DynamicallyInvokableAttribute", false); + if (invocableAttribute != null) + { + Contract.Assert(((MetadataToken)invocableAttribute.MetadataToken).IsTypeDef); + + ConstructorInfo ctor = invocableAttribute.GetConstructor(Type.EmptyTypes); + Contract.Assert(ctor != null); + + int token = ctor.MetadataToken; + Contract.Assert(((MetadataToken)token).IsMethodDef); + + flags |= (ASSEMBLY_FLAGS)token & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_TOKEN_MASK; + } + } + else if (IsDesignerBindingContext()) + { + flags = ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_SAFE_REFLECTION; + } +#endif + + m_flags = flags | ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_INITIALIZED; + } + + return m_flags; + } + } +#endif // FEATURE_CORECLR + + internal object SyncRoot + { + get + { + if (m_syncRoot == null) + { + Interlocked.CompareExchange(ref m_syncRoot, new object(), null); + } + return m_syncRoot; + } + } + + public override event ModuleResolveEventHandler ModuleResolve + { + [System.Security.SecurityCritical] // auto-generated_required + add + { + _ModuleResolve += value; + } + [System.Security.SecurityCritical] // auto-generated_required + remove + { + _ModuleResolve -= value; + } + } + + private const String s_localFilePrefix = "file:"; + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void GetCodeBase(RuntimeAssembly assembly, + bool copiedName, + StringHandleOnStack retString); + + [System.Security.SecurityCritical] // auto-generated + internal String GetCodeBase(bool copiedName) + { + String codeBase = null; + GetCodeBase(GetNativeHandle(), copiedName, JitHelpers.GetStringHandleOnStack(ref codeBase)); + return codeBase; + } + + public override String CodeBase + { +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + get { + String codeBase = GetCodeBase(false); + VerifyCodeBaseDiscovery(codeBase); + return codeBase; + } + } + + internal RuntimeAssembly GetNativeHandle() + { + return this; + } + + // If the assembly is copied before it is loaded, the codebase will be set to the + // actual file loaded if copiedName is true. If it is false, then the original code base + // is returned. +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public override AssemblyName GetName(bool copiedName) + { + AssemblyName an = new AssemblyName(); + + String codeBase = GetCodeBase(copiedName); + VerifyCodeBaseDiscovery(codeBase); + + an.Init(GetSimpleName(), + GetPublicKey(), + null, // public key token + GetVersion(), + GetLocale(), + GetHashAlgorithm(), + AssemblyVersionCompatibility.SameMachine, + codeBase, + GetFlags() | AssemblyNameFlags.PublicKey, + null); // strong name key pair + + PortableExecutableKinds pek; + ImageFileMachine ifm; + + Module manifestModule = ManifestModule; + if (manifestModule != null) + { + if (manifestModule.MDStreamVersion > 0x10000) + { + ManifestModule.GetPEKind(out pek, out ifm); + an.SetProcArchIndex(pek,ifm); + } + } + return an; + } + +#if FEATURE_APTCA + // This method is called from the VM when creating conditional APTCA exceptions, in order to include + // the text which must be added to the partial trust visible assembly list + [SecurityCritical] + [PermissionSet(SecurityAction.Assert, Unrestricted = true)] + private string GetNameForConditionalAptca() + { + AssemblyName assemblyName = GetName(); + return assemblyName.GetNameWithPublicKey(); + + } +#endif // FEATURE_APTCA + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static void GetFullName(RuntimeAssembly assembly, StringHandleOnStack retString); + + public override String FullName + { + [System.Security.SecuritySafeCritical] // auto-generated + get { + // If called by Object.ToString(), return val may be NULL. + if (m_fullname == null) + { + string s = null; + GetFullName(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref s)); + Interlocked.CompareExchange(ref m_fullname, s, null); + } + + return m_fullname; + } + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void GetEntryPoint(RuntimeAssembly assembly, ObjectHandleOnStack retMethod); + + public override MethodInfo EntryPoint + { + [System.Security.SecuritySafeCritical] // auto-generated + get { + IRuntimeMethodInfo methodHandle = null; + GetEntryPoint(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref methodHandle)); + + if (methodHandle == null) + return null; + + return (MethodInfo)RuntimeType.GetMethodBase(methodHandle); + } + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void GetType(RuntimeAssembly assembly, + String name, + bool throwOnError, + bool ignoreCase, + ObjectHandleOnStack type, + ObjectHandleOnStack keepAlive); + + [System.Security.SecuritySafeCritical] + public override Type GetType(String name, bool throwOnError, bool ignoreCase) + { + // throw on null strings regardless of the value of "throwOnError" + if (name == null) + throw new ArgumentNullException("name"); + + RuntimeType type = null; + Object keepAlive = null; + GetType(GetNativeHandle(), name, throwOnError, ignoreCase, JitHelpers.GetObjectHandleOnStack(ref type), JitHelpers.GetObjectHandleOnStack(ref keepAlive)); + GC.KeepAlive(keepAlive); + + return type; + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal extern static void GetForwardedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static void GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes); + + [System.Security.SecuritySafeCritical] // auto-generated + public override Type[] GetExportedTypes() + { + Type[] types = null; + GetExportedTypes(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref types)); + return types; + } + + public override IEnumerable DefinedTypes + { + [System.Security.SecuritySafeCritical] + get + { + List rtTypes = new List(); + + RuntimeModule[] modules = GetModulesInternal(true, false); + + for (int i = 0; i < modules.Length; i++) + { + rtTypes.AddRange(modules[i].GetDefinedTypes()); + } + + return rtTypes.ToArray(); + } + } + + // Load a resource based on the NameSpace of the type. + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public override Stream GetManifestResourceStream(Type type, String name) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return GetManifestResourceStream(type, name, false, ref stackMark); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public override Stream GetManifestResourceStream(String name) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return GetManifestResourceStream(name, ref stackMark, false); + } + +#if FEATURE_CAS_POLICY + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static void GetEvidence(RuntimeAssembly assembly, ObjectHandleOnStack retEvidence); + + [SecurityCritical] + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static SecurityRuleSet GetSecurityRuleSet(RuntimeAssembly assembly); + + public override Evidence Evidence + { + [SecuritySafeCritical] + [SecurityPermissionAttribute( SecurityAction.Demand, ControlEvidence = true )] + get + { + Evidence evidence = EvidenceNoDemand; + return evidence.Clone(); + } + } + + internal Evidence EvidenceNoDemand + { + [SecurityCritical] + get + { + Evidence evidence = null; + GetEvidence(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref evidence)); + return evidence; + } + } + + public override PermissionSet PermissionSet + { + [SecurityCritical] + get + { + PermissionSet grantSet = null; + PermissionSet deniedSet = null; + + GetGrantSet(out grantSet, out deniedSet); + + if (grantSet != null) + { + return grantSet.Copy(); + } + else + { + return new PermissionSet(PermissionState.Unrestricted); + } + } + } + + public override SecurityRuleSet SecurityRuleSet + { + [SecuritySafeCritical] + get + { + return GetSecurityRuleSet(GetNativeHandle()); + } + } +#endif // FEATURE_CAS_POLICY + + // ISerializable implementation + [System.Security.SecurityCritical] // auto-generated_required + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info==null) + throw new ArgumentNullException("info"); + + Contract.EndContractBlock(); + + UnitySerializationHolder.GetUnitySerializationInfo(info, + UnitySerializationHolder.AssemblyUnity, + this.FullName, + this); + } + + public override Module ManifestModule + { + get + { + // We don't need to return the "external" ModuleBuilder because + // it is meant to be read-only + return RuntimeAssembly.GetManifestModule(GetNativeHandle()); + } + } + + public override Object[] GetCustomAttributes(bool inherit) + { + return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType"); + + return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType); + } + + public override bool IsDefined(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"caType"); + + return CustomAttribute.IsDefined(this, attributeRuntimeType); + } + + public override IList GetCustomAttributesData() + { + return CustomAttributeData.GetCustomAttributesInternal(this); + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + internal static RuntimeAssembly InternalLoadFrom(String assemblyFile, + Evidence securityEvidence, + byte[] hashValue, + AssemblyHashAlgorithm hashAlgorithm, + bool forIntrospection, + bool suppressSecurityChecks, + ref StackCrawlMark stackMark) + { + if (assemblyFile == null) + throw new ArgumentNullException("assemblyFile"); + + Contract.EndContractBlock(); + +#if FEATURE_CAS_POLICY + if (securityEvidence != null && !AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit")); + } +#endif // FEATURE_CAS_POLICY + AssemblyName an = new AssemblyName(); + an.CodeBase = assemblyFile; + an.SetHashControl(hashValue, hashAlgorithm); + // The stack mark is used for MDA filtering + return InternalLoadAssemblyName(an, securityEvidence, null, ref stackMark, true /*thrownOnFileNotFound*/, forIntrospection, suppressSecurityChecks); + } + + // Wrapper function to wrap the typical use of InternalLoad. + [System.Security.SecurityCritical] // auto-generated + internal static RuntimeAssembly InternalLoad(String assemblyString, + Evidence assemblySecurity, + ref StackCrawlMark stackMark, + bool forIntrospection) + { + return InternalLoad(assemblyString, assemblySecurity, ref stackMark, IntPtr.Zero, forIntrospection); + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + internal static RuntimeAssembly InternalLoad(String assemblyString, + Evidence assemblySecurity, + ref StackCrawlMark stackMark, + IntPtr pPrivHostBinder, + bool forIntrospection) + { + RuntimeAssembly assembly; + AssemblyName an = CreateAssemblyName(assemblyString, forIntrospection, out assembly); + + if (assembly != null) { + // The assembly was returned from ResolveAssemblyEvent + return assembly; + } + + return InternalLoadAssemblyName(an, assemblySecurity, null, ref stackMark, + pPrivHostBinder, + true /*thrownOnFileNotFound*/, forIntrospection, false /* suppressSecurityChecks */); + } + + // Creates AssemblyName. Fills assembly if AssemblyResolve event has been raised. + [System.Security.SecurityCritical] // auto-generated + internal static AssemblyName CreateAssemblyName( + String assemblyString, + bool forIntrospection, + out RuntimeAssembly assemblyFromResolveEvent) + { + if (assemblyString == null) + throw new ArgumentNullException("assemblyString"); + Contract.EndContractBlock(); + + if ((assemblyString.Length == 0) || + (assemblyString[0] == '\0')) + throw new ArgumentException(Environment.GetResourceString("Format_StringZeroLength")); + + if (forIntrospection) + AppDomain.CheckReflectionOnlyLoadSupported(); + + AssemblyName an = new AssemblyName(); + + an.Name = assemblyString; + an.nInit(out assemblyFromResolveEvent, forIntrospection, true); + + return an; + } + + // Wrapper function to wrap the typical use of InternalLoadAssemblyName. + [System.Security.SecurityCritical] // auto-generated + internal static RuntimeAssembly InternalLoadAssemblyName( + AssemblyName assemblyRef, + Evidence assemblySecurity, + RuntimeAssembly reqAssembly, + ref StackCrawlMark stackMark, + bool throwOnFileNotFound, + bool forIntrospection, + bool suppressSecurityChecks, + IntPtr ptrLoadContextBinder = default(IntPtr)) + { + return InternalLoadAssemblyName(assemblyRef, assemblySecurity, reqAssembly, ref stackMark, IntPtr.Zero, true /*throwOnError*/, forIntrospection, suppressSecurityChecks, ptrLoadContextBinder); + } + + [System.Security.SecurityCritical] // auto-generated + internal static RuntimeAssembly InternalLoadAssemblyName( + AssemblyName assemblyRef, + Evidence assemblySecurity, + RuntimeAssembly reqAssembly, + ref StackCrawlMark stackMark, + IntPtr pPrivHostBinder, + bool throwOnFileNotFound, + bool forIntrospection, + bool suppressSecurityChecks, + IntPtr ptrLoadContextBinder = default(IntPtr)) + { + + if (assemblyRef == null) + throw new ArgumentNullException("assemblyRef"); + Contract.EndContractBlock(); + + if (assemblyRef.CodeBase != null) + { + AppDomain.CheckLoadFromSupported(); + } + + assemblyRef = (AssemblyName)assemblyRef.Clone(); +#if FEATURE_VERSIONING + if (!forIntrospection && + (assemblyRef.ProcessorArchitecture != ProcessorArchitecture.None)) { + // PA does not have a semantics for by-name binds for execution + assemblyRef.ProcessorArchitecture = ProcessorArchitecture.None; + } +#endif + + if (assemblySecurity != null) + { +#if FEATURE_CAS_POLICY + if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit")); + } +#endif // FEATURE_CAS_POLICY + + if (!suppressSecurityChecks) + { +#pragma warning disable 618 + new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand(); +#pragma warning restore 618 + } + } + + + String codeBase = VerifyCodeBase(assemblyRef.CodeBase); + if (codeBase != null && !suppressSecurityChecks) { + + if (String.Compare( codeBase, 0, s_localFilePrefix, 0, 5, StringComparison.OrdinalIgnoreCase) != 0) { +#if FEATURE_FUSION // Of all the binders, Fusion is the only one that understands Web locations + IPermission perm = CreateWebPermission( assemblyRef.EscapedCodeBase ); + perm.Demand(); +#else + throw new ArgumentException(Environment.GetResourceString("Arg_InvalidFileName"), "assemblyRef.CodeBase"); +#endif + } + else { + System.Security.Util.URLString urlString = new System.Security.Util.URLString( codeBase, true ); + new FileIOPermission( FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read , urlString.GetFileName() ).Demand(); + } + } + + return nLoad(assemblyRef, codeBase, assemblySecurity, reqAssembly, ref stackMark, + pPrivHostBinder, + throwOnFileNotFound, forIntrospection, suppressSecurityChecks, ptrLoadContextBinder); + } + + // These are the framework assemblies that does reflection invocation + // on behalf of user code. We allow framework code to invoke non-W8P + // framework APIs but don't want user code to gain that privilege + // through these assemblies. So we blaklist them. + static string[] s_unsafeFrameworkAssemblyNames = new string[] { + "System.Reflection.Context", + "Microsoft.VisualBasic" + }; + +#if FEATURE_APPX + [System.Security.SecuritySafeCritical] + internal bool IsFrameworkAssembly() + { + ASSEMBLY_FLAGS flags = Flags; + return (flags & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_FRAMEWORK) != 0; + } + + // Returns true if we want to allow this assembly to invoke non-W8P + // framework APIs through reflection. + internal bool IsSafeForReflection() + { + ASSEMBLY_FLAGS flags = Flags; + return (flags & ASSEMBLY_FLAGS.ASSEMBLY_FLAGS_SAFE_REFLECTION) != 0; + } + + [System.Security.SecuritySafeCritical] + private bool IsDesignerBindingContext() + { + return RuntimeAssembly.nIsDesignerBindingContext(this); + } + + [System.Security.SecurityCritical] + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static bool nIsDesignerBindingContext(RuntimeAssembly assembly); +#endif + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern RuntimeAssembly _nLoad(AssemblyName fileName, + String codeBase, + Evidence assemblySecurity, + RuntimeAssembly locationHint, + ref StackCrawlMark stackMark, + IntPtr pPrivHostBinder, + bool throwOnFileNotFound, + bool forIntrospection, + bool suppressSecurityChecks, + IntPtr ptrLoadContextBinder); + +#if !FEATURE_CORECLR + // The NGEN task uses this method, so please do not modify its signature + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern bool IsFrameworkAssembly(AssemblyName assemblyName); + + [System.Security.SecurityCritical] + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal static extern bool IsNewPortableAssembly(AssemblyName assemblyName); +#endif + + [System.Security.SecurityCritical] // auto-generated + private static RuntimeAssembly nLoad(AssemblyName fileName, + String codeBase, + Evidence assemblySecurity, + RuntimeAssembly locationHint, + ref StackCrawlMark stackMark, + IntPtr pPrivHostBinder, + bool throwOnFileNotFound, + bool forIntrospection, + bool suppressSecurityChecks, IntPtr ptrLoadContextBinder = default(IntPtr)) + { + return _nLoad(fileName, codeBase, assemblySecurity, locationHint, ref stackMark, + pPrivHostBinder, + throwOnFileNotFound, forIntrospection, suppressSecurityChecks, ptrLoadContextBinder); + } + +#if FEATURE_FUSION + // used by vm + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + private static unsafe RuntimeAssembly LoadWithPartialNameHack(String partialName, bool cropPublicKey) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + + AssemblyName an = new AssemblyName(partialName); + + if (!IsSimplyNamed(an)) + { + if (cropPublicKey) + { + an.SetPublicKey(null); + an.SetPublicKeyToken(null); + } + + if(IsFrameworkAssembly(an) || !AppDomain.IsAppXModel()) + { + AssemblyName GACAssembly = EnumerateCache(an); + if(GACAssembly != null) + return InternalLoadAssemblyName(GACAssembly, null, null,ref stackMark, true /*thrownOnFileNotFound*/, false, false); + else + return null; + } + } + + if (AppDomain.IsAppXModel()) + { + // also try versionless bind from the package + an.Version = null; + return nLoad(an, null, null, null, ref stackMark, + IntPtr.Zero, + false, false, false); + } + return null; + + } + +#if !FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + internal static RuntimeAssembly LoadWithPartialNameInternal(String partialName, Evidence securityEvidence, ref StackCrawlMark stackMark) + { + AssemblyName an = new AssemblyName(partialName); + return LoadWithPartialNameInternal(an, securityEvidence, ref stackMark); + } + + [System.Security.SecurityCritical] // auto-generated + internal static RuntimeAssembly LoadWithPartialNameInternal(AssemblyName an, Evidence securityEvidence, ref StackCrawlMark stackMark) + { + if (securityEvidence != null) + { +#if FEATURE_CAS_POLICY + if (!AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyImplicit")); + } +#endif // FEATURE_CAS_POLICY + new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand(); + } + + AppDomain.CheckLoadWithPartialNameSupported(stackMark); + + RuntimeAssembly result = null; + try { + result = nLoad(an, null, securityEvidence, null, ref stackMark, + IntPtr.Zero, + true, false, false); + } + catch(Exception e) { + if (e.IsTransient) + throw e; + + if (IsUserError(e)) + throw; + + + if(IsFrameworkAssembly(an) || !AppDomain.IsAppXModel()) + { + if (IsSimplyNamed(an)) + return null; + + AssemblyName GACAssembly = EnumerateCache(an); + if(GACAssembly != null) + result = InternalLoadAssemblyName(GACAssembly, securityEvidence, null, ref stackMark, true /*thrownOnFileNotFound*/, false, false); + } + else + { + an.Version = null; + result = nLoad(an, null, securityEvidence, null, ref stackMark, + IntPtr.Zero, + false, false, false); + } + } + + + return result; + } +#endif // !FEATURE_CORECLR + + [SecuritySafeCritical] + private static bool IsUserError(Exception e) + { + return (uint)e.HResult == COR_E_LOADING_REFERENCE_ASSEMBLY; + } + + private static bool IsSimplyNamed(AssemblyName partialName) + { + byte[] pk = partialName.GetPublicKeyToken(); + if ((pk != null) && + (pk.Length == 0)) + return true; + + pk = partialName.GetPublicKey(); + if ((pk != null) && + (pk.Length == 0)) + return true; + + return false; + } + + [System.Security.SecurityCritical] // auto-generated + private static AssemblyName EnumerateCache(AssemblyName partialName) + { + new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); + + partialName.Version = null; + + ArrayList a = new ArrayList(); + Fusion.ReadCache(a, partialName.FullName, ASM_CACHE.GAC); + + IEnumerator myEnum = a.GetEnumerator(); + AssemblyName ainfoBest = null; + CultureInfo refCI = partialName.CultureInfo; + + while (myEnum.MoveNext()) { + AssemblyName ainfo = new AssemblyName((String)myEnum.Current); + + if (CulturesEqual(refCI, ainfo.CultureInfo)) { + if (ainfoBest == null) + ainfoBest = ainfo; + else { + // Choose highest version + if (ainfo.Version > ainfoBest.Version) + ainfoBest = ainfo; + } + } + } + + return ainfoBest; + } + + private static bool CulturesEqual(CultureInfo refCI, CultureInfo defCI) + { + bool defNoCulture = defCI.Equals(CultureInfo.InvariantCulture); + + // cultured asms aren't allowed to be bound to if + // the ref doesn't ask for them specifically + if ((refCI == null) || refCI.Equals(CultureInfo.InvariantCulture)) + return defNoCulture; + + if (defNoCulture || + ( !defCI.Equals(refCI) )) + return false; + + return true; + } +#endif // FEATURE_FUSION + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern bool IsReflectionOnly(RuntimeAssembly assembly); + + // To not break compatibility with the V1 _Assembly interface we need to make this + // new member ComVisible(false). + [ComVisible(false)] + public override bool ReflectionOnly + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + return IsReflectionOnly(GetNativeHandle()); + } + } + +#if FEATURE_CORECLR + // Loads the assembly with a COFF based IMAGE containing + // an emitted assembly. The assembly is loaded into the domain + // of the caller. Currently is implemented only for UnmanagedMemoryStream + // (no derived classes since we are not calling Read()) + [System.Security.SecurityCritical] // auto-generated + internal static RuntimeAssembly InternalLoadFromStream(Stream assemblyStream, Stream pdbStream, ref StackCrawlMark stackMark) + { + if (assemblyStream == null) + throw new ArgumentNullException("assemblyStream"); + + if (assemblyStream.GetType()!=typeof(UnmanagedMemoryStream)) + throw new NotSupportedException(); + + if (pdbStream!= null && pdbStream.GetType()!=typeof(UnmanagedMemoryStream)) + throw new NotSupportedException(); + + AppDomain.CheckLoadFromSupported(); + + UnmanagedMemoryStream umAssemblyStream = (UnmanagedMemoryStream)assemblyStream; + UnmanagedMemoryStream umPdbStream = (UnmanagedMemoryStream)pdbStream; + + unsafe + { + byte* umAssemblyStreamBuffer=umAssemblyStream.PositionPointer; + byte* umPdbStreamBuffer=(umPdbStream!=null)?umPdbStream.PositionPointer:null; + long assemblyDataLength = umAssemblyStream.Length-umAssemblyStream.Position; + long pdbDataLength = (umPdbStream!=null)?(umPdbStream.Length-umPdbStream.Position):0; + + // use Seek() to benefit from boundary checking, the actual read is done using *StreamBuffer + umAssemblyStream.Seek(assemblyDataLength,SeekOrigin.Current); + + if(umPdbStream != null) + { + umPdbStream.Seek(pdbDataLength,SeekOrigin.Current); + } + + BCLDebug.Assert(assemblyDataLength > 0L, "assemblyDataLength > 0L"); + + RuntimeAssembly assembly = null; + + nLoadFromUnmanagedArray(false, + umAssemblyStreamBuffer, + (ulong)assemblyDataLength, + umPdbStreamBuffer, + (ulong)pdbDataLength, + JitHelpers.GetStackCrawlMarkHandle(ref stackMark), + JitHelpers.GetObjectHandleOnStack(ref assembly)); + + return assembly; + } + } +#endif //FEATURE_CORECLR + +#if FEATURE_MULTIMODULE_ASSEMBLIES + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static void LoadModule(RuntimeAssembly assembly, + String moduleName, + byte[] rawModule, int cbModule, + byte[] rawSymbolStore, int cbSymbolStore, + ObjectHandleOnStack retModule); + + [SecurityPermissionAttribute(SecurityAction.Demand, ControlEvidence = true)] + [System.Security.SecuritySafeCritical] // auto-generated + public override Module LoadModule(String moduleName, byte[] rawModule, byte[] rawSymbolStore) + { + RuntimeModule retModule = null; + LoadModule( + GetNativeHandle(), + moduleName, + rawModule, + (rawModule != null) ? rawModule.Length : 0, + rawSymbolStore, + (rawSymbolStore != null) ? rawSymbolStore.Length : 0, + JitHelpers.GetObjectHandleOnStack(ref retModule)); + + return retModule; + } +#endif //FEATURE_MULTIMODULE_ASSEMBLIES + + // Returns the module in this assembly with name 'name' + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void GetModule(RuntimeAssembly assembly, String name, ObjectHandleOnStack retModule); + + [System.Security.SecuritySafeCritical] // auto-generated + public override Module GetModule(String name) + { + Module retModule = null; + GetModule(GetNativeHandle(), name, JitHelpers.GetObjectHandleOnStack(ref retModule)); + return retModule; + } + + // Returns the file in the File table of the manifest that matches the + // given name. (Name should not include path.) +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public override FileStream GetFile(String name) + { + RuntimeModule m = (RuntimeModule)GetModule(name); + if (m == null) + return null; + + return new FileStream(m.GetFullyQualifiedName(), + FileMode.Open, + FileAccess.Read, FileShare.Read, FileStream.DefaultBufferSize, false); + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public override FileStream[] GetFiles(bool getResourceModules) + { + Module[] m = GetModules(getResourceModules); + int iLength = m.Length; + FileStream[] fs = new FileStream[iLength]; + + for(int i = 0; i < iLength; i++) + fs[i] = new FileStream(((RuntimeModule)m[i]).GetFullyQualifiedName(), + FileMode.Open, + FileAccess.Read, FileShare.Read, FileStream.DefaultBufferSize, false); + + return fs; + } + + + // Returns the names of all the resources + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern String[] GetManifestResourceNames(RuntimeAssembly assembly); + + // Returns the names of all the resources + [System.Security.SecuritySafeCritical] // auto-generated + public override String[] GetManifestResourceNames() + { + return GetManifestResourceNames(GetNativeHandle()); + } + + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static void GetExecutingAssembly(StackCrawlMarkHandle stackMark, ObjectHandleOnStack retAssembly); + + [System.Security.SecurityCritical] // auto-generated + internal static RuntimeAssembly GetExecutingAssembly(ref StackCrawlMark stackMark) + { + RuntimeAssembly retAssembly = null; + GetExecutingAssembly(JitHelpers.GetStackCrawlMarkHandle(ref stackMark), JitHelpers.GetObjectHandleOnStack(ref retAssembly)); + return retAssembly; + } + + // Returns the names of all the resources + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern AssemblyName[] GetReferencedAssemblies(RuntimeAssembly assembly); + + [System.Security.SecuritySafeCritical] // auto-generated + public override AssemblyName[] GetReferencedAssemblies() + { + return GetReferencedAssemblies(GetNativeHandle()); + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern int GetManifestResourceInfo(RuntimeAssembly assembly, + String resourceName, + ObjectHandleOnStack assemblyRef, + StringHandleOnStack retFileName, + StackCrawlMarkHandle stackMark); + + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public override ManifestResourceInfo GetManifestResourceInfo(String resourceName) + { + RuntimeAssembly retAssembly = null; + String fileName = null; + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + int location = GetManifestResourceInfo(GetNativeHandle(), resourceName, + JitHelpers.GetObjectHandleOnStack(ref retAssembly), + JitHelpers.GetStringHandleOnStack(ref fileName), + JitHelpers.GetStackCrawlMarkHandle(ref stackMark)); + + if (location == -1) + return null; + + return new ManifestResourceInfo(retAssembly, fileName, + (ResourceLocation) location); + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void GetLocation(RuntimeAssembly assembly, StringHandleOnStack retString); + + public override String Location + { +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + get { + String location = null; + + GetLocation(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref location)); + + if (location != null) + new FileIOPermission( FileIOPermissionAccess.PathDiscovery, location ).Demand(); + + return location; + } + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static void GetImageRuntimeVersion(RuntimeAssembly assembly, StringHandleOnStack retString); + + // To not break compatibility with the V1 _Assembly interface we need to make this + // new member ComVisible(false). + [ComVisible(false)] + public override String ImageRuntimeVersion + { + [System.Security.SecuritySafeCritical] // auto-generated + get{ + String s = null; + GetImageRuntimeVersion(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref s)); + return s; + } + } + + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private extern static bool IsGlobalAssemblyCache(RuntimeAssembly assembly); + + public override bool GlobalAssemblyCache + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + return IsGlobalAssemblyCache(GetNativeHandle()); + } + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static Int64 GetHostContext(RuntimeAssembly assembly); + + public override Int64 HostContext + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + return GetHostContext(GetNativeHandle()); + } + } + + private static String VerifyCodeBase(String codebase) + { + if(codebase == null) + return null; + + int len = codebase.Length; + if (len == 0) + return null; + + + int j = codebase.IndexOf(':'); + // Check to see if the url has a prefix + if( (j != -1) && + (j+2 < len) && + ((codebase[j+1] == '/') || (codebase[j+1] == '\\')) && + ((codebase[j+2] == '/') || (codebase[j+2] == '\\')) ) + return codebase; +#if !PLATFORM_UNIX + else if ((len > 2) && (codebase[0] == '\\') && (codebase[1] == '\\')) + return "file://" + codebase; + else + return "file:///" + Path.GetFullPathInternal( codebase ); +#else + else + return "file://" + Path.GetFullPathInternal( codebase ); +#endif // !PLATFORM_UNIX + } + + [System.Security.SecurityCritical] // auto-generated + internal Stream GetManifestResourceStream( + Type type, + String name, + bool skipSecurityCheck, + ref StackCrawlMark stackMark) + { + StringBuilder sb = new StringBuilder(); + if(type == null) { + if (name == null) + throw new ArgumentNullException("type"); + } + else { + String nameSpace = type.Namespace; + if(nameSpace != null) { + sb.Append(nameSpace); + if(name != null) + sb.Append(Type.Delimiter); + } + } + + if(name != null) + sb.Append(name); + + return GetManifestResourceStream(sb.ToString(), ref stackMark, skipSecurityCheck); + } + +#if FEATURE_CAS_POLICY + internal bool IsStrongNameVerified + { + [System.Security.SecurityCritical] // auto-generated + get { return GetIsStrongNameVerified(GetNativeHandle()); } + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern bool GetIsStrongNameVerified(RuntimeAssembly assembly); +#endif // FEATURE_CAS_POLICY + + // GetResource will return a pointer to the resources in memory. + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static unsafe extern byte* GetResource(RuntimeAssembly assembly, + String resourceName, + out ulong length, + StackCrawlMarkHandle stackMark, + bool skipSecurityCheck); + + [System.Security.SecurityCritical] // auto-generated + internal unsafe Stream GetManifestResourceStream(String name, ref StackCrawlMark stackMark, bool skipSecurityCheck) + { + ulong length = 0; + byte* pbInMemoryResource = GetResource(GetNativeHandle(), name, out length, JitHelpers.GetStackCrawlMarkHandle(ref stackMark), skipSecurityCheck); + + if (pbInMemoryResource != null) { + //Console.WriteLine("Creating an unmanaged memory stream of length "+length); + if (length > Int64.MaxValue) + throw new NotImplementedException(Environment.GetResourceString("NotImplemented_ResourcesLongerThan2^63")); + + return new UnmanagedMemoryStream(pbInMemoryResource, (long)length, (long)length, FileAccess.Read, true); + } + + //Console.WriteLine("GetManifestResourceStream: Blob "+name+" not found..."); + return null; + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void GetVersion(RuntimeAssembly assembly, + out int majVer, + out int minVer, + out int buildNum, + out int revNum); + + [System.Security.SecurityCritical] // auto-generated + internal Version GetVersion() + { + int majorVer, minorVer, build, revision; + GetVersion(GetNativeHandle(), out majorVer, out minorVer, out build, out revision); + return new Version (majorVer, minorVer, build, revision); + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void GetLocale(RuntimeAssembly assembly, StringHandleOnStack retString); + + [System.Security.SecurityCritical] // auto-generated + internal CultureInfo GetLocale() + { + String locale = null; + + GetLocale(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref locale)); + + if (locale == null) + return CultureInfo.InvariantCulture; + + return new CultureInfo(locale); + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern bool FCallIsDynamic(RuntimeAssembly assembly); + + public override bool IsDynamic + { + [SecuritySafeCritical] + get { + return FCallIsDynamic(GetNativeHandle()); + } + } + + [System.Security.SecurityCritical] // auto-generated + private void VerifyCodeBaseDiscovery(String codeBase) + { +#if FEATURE_CAS_POLICY + if (CodeAccessSecurityEngine.QuickCheckForAllDemands()) { + return; + } +#endif // FEATURE_CAS_POLICY + + if ((codeBase != null) && + (String.Compare( codeBase, 0, s_localFilePrefix, 0, 5, StringComparison.OrdinalIgnoreCase) == 0)) { + System.Security.Util.URLString urlString = new System.Security.Util.URLString( codeBase, true ); + new FileIOPermission( FileIOPermissionAccess.PathDiscovery, urlString.GetFileName() ).Demand(); + } + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void GetSimpleName(RuntimeAssembly assembly, StringHandleOnStack retSimpleName); + + [SecuritySafeCritical] + internal String GetSimpleName() + { + string name = null; + GetSimpleName(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref name)); + return name; + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static AssemblyHashAlgorithm GetHashAlgorithm(RuntimeAssembly assembly); + + [System.Security.SecurityCritical] // auto-generated + private AssemblyHashAlgorithm GetHashAlgorithm() + { + return GetHashAlgorithm(GetNativeHandle()); + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static AssemblyNameFlags GetFlags(RuntimeAssembly assembly); + + [System.Security.SecurityCritical] // auto-generated + private AssemblyNameFlags GetFlags() + { + return GetFlags(GetNativeHandle()); + } + + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SecurityCritical] + [SuppressUnmanagedCodeSecurity] + private static extern void GetRawBytes(RuntimeAssembly assembly, ObjectHandleOnStack retRawBytes); + + // Get the raw bytes of the assembly + [SecuritySafeCritical] + internal byte[] GetRawBytes() + { + byte[] rawBytes = null; + + GetRawBytes(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref rawBytes)); + return rawBytes; + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void GetPublicKey(RuntimeAssembly assembly, ObjectHandleOnStack retPublicKey); + + [System.Security.SecurityCritical] // auto-generated + internal byte[] GetPublicKey() + { + byte[] publicKey = null; + GetPublicKey(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref publicKey)); + return publicKey; + } + + [SecurityCritical] + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static void GetGrantSet(RuntimeAssembly assembly, ObjectHandleOnStack granted, ObjectHandleOnStack denied); + + [SecurityCritical] + internal void GetGrantSet(out PermissionSet newGrant, out PermissionSet newDenied) + { + PermissionSet granted = null, denied = null; + GetGrantSet(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref granted), JitHelpers.GetObjectHandleOnStack(ref denied)); + newGrant = granted; newDenied = denied; + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + private extern static bool IsAllSecurityCritical(RuntimeAssembly assembly); + + // Is everything introduced by this assembly critical + [System.Security.SecuritySafeCritical] // auto-generated + internal bool IsAllSecurityCritical() + { + return IsAllSecurityCritical(GetNativeHandle()); + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + private extern static bool IsAllSecuritySafeCritical(RuntimeAssembly assembly); + + // Is everything introduced by this assembly safe critical + [System.Security.SecuritySafeCritical] // auto-generated + internal bool IsAllSecuritySafeCritical() + { + return IsAllSecuritySafeCritical(GetNativeHandle()); + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + private extern static bool IsAllPublicAreaSecuritySafeCritical(RuntimeAssembly assembly); + + // Is everything introduced by this assembly safe critical + [System.Security.SecuritySafeCritical] // auto-generated + internal bool IsAllPublicAreaSecuritySafeCritical() + { + return IsAllPublicAreaSecuritySafeCritical(GetNativeHandle()); + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + private extern static bool IsAllSecurityTransparent(RuntimeAssembly assembly); + + // Is everything introduced by this assembly transparent + [System.Security.SecuritySafeCritical] // auto-generated + internal bool IsAllSecurityTransparent() + { + return IsAllSecurityTransparent(GetNativeHandle()); + } + +#if FEATURE_FUSION + // demandFlag: + // 0 demand PathDiscovery permission only + // 1 demand Read permission only + // 2 demand both Read and PathDiscovery + // 3 demand Web permission only + [System.Security.SecurityCritical] // auto-generated + private static void DemandPermission(String codeBase, bool havePath, + int demandFlag) + { + FileIOPermissionAccess access = FileIOPermissionAccess.PathDiscovery; + switch(demandFlag) { + + case 0: // default + break; + case 1: + access = FileIOPermissionAccess.Read; + break; + case 2: + access = FileIOPermissionAccess.PathDiscovery | FileIOPermissionAccess.Read; + break; + + case 3: + IPermission perm = CreateWebPermission(AssemblyName.EscapeCodeBase(codeBase)); + perm.Demand(); + return; + } + + if (!havePath) { + System.Security.Util.URLString urlString = new System.Security.Util.URLString( codeBase, true ); + codeBase = urlString.GetFileName(); + } + + codeBase = Path.GetFullPathInternal(codeBase); // canonicalize + + new FileIOPermission(access, codeBase).Demand(); + } +#endif + +#if FEATURE_FUSION + private static IPermission CreateWebPermission( String codeBase ) + { + Contract.Assert( codeBase != null, "Must pass in a valid CodeBase" ); + Assembly sys = Assembly.Load("System, Version=" + ThisAssembly.Version + ", Culture=neutral, PublicKeyToken=" + AssemblyRef.EcmaPublicKeyToken); + + Type type = sys.GetType("System.Net.NetworkAccess", true); + + IPermission retval = null; + if (!type.IsEnum || !type.IsVisible) + goto Exit; + + Object[] webArgs = new Object[2]; + webArgs[0] = (Enum) Enum.Parse(type, "Connect", true); + if (webArgs[0] == null) + goto Exit; + + webArgs[1] = codeBase; + + type = sys.GetType("System.Net.WebPermission", true); + + if (!type.IsVisible) + goto Exit; + + retval = (IPermission) Activator.CreateInstance(type, webArgs); + + Exit: + if (retval == null) { + Contract.Assert( false, "Unable to create WebPermission" ); + throw new InvalidOperationException(); + } + + return retval; + } +#endif + // This method is called by the VM. + [System.Security.SecurityCritical] + private RuntimeModule OnModuleResolveEvent(String moduleName) + { + ModuleResolveEventHandler moduleResolve = _ModuleResolve; + if (moduleResolve == null) + return null; + + Delegate[] ds = moduleResolve.GetInvocationList(); + int len = ds.Length; + for (int i = 0; i < len; i++) { + RuntimeModule ret = (RuntimeModule)((ModuleResolveEventHandler) ds[i])(this, new ResolveEventArgs(moduleName,this)); + if (ret != null) + return ret; + } + + return null; + } + + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public override Assembly GetSatelliteAssembly(CultureInfo culture) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return InternalGetSatelliteAssembly(culture, null, ref stackMark); + } + + // Useful for binding to a very specific version of a satellite assembly + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public override Assembly GetSatelliteAssembly(CultureInfo culture, Version version) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return InternalGetSatelliteAssembly(culture, version, ref stackMark); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + internal Assembly InternalGetSatelliteAssembly(CultureInfo culture, + Version version, + ref StackCrawlMark stackMark) + { + if (culture == null) + throw new ArgumentNullException("culture"); + Contract.EndContractBlock(); + + + String name = GetSimpleName() + ".resources"; + return InternalGetSatelliteAssembly(name, culture, version, true, ref stackMark); + } + +#if !FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + private static extern bool UseRelativeBindForSatellites(); +#endif + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + internal RuntimeAssembly InternalGetSatelliteAssembly(String name, + CultureInfo culture, + Version version, + bool throwOnFileNotFound, + ref StackCrawlMark stackMark) + { + + AssemblyName an = new AssemblyName(); + + an.SetPublicKey(GetPublicKey()); + an.Flags = GetFlags() | AssemblyNameFlags.PublicKey; + + if (version == null) + an.Version = GetVersion(); + else + an.Version = version; + + an.CultureInfo = culture; + an.Name = name; + + RuntimeAssembly retAssembly = null; + +#if !FEATURE_CORECLR + bool bIsAppXDevMode = AppDomain.IsAppXDesignMode(); + + bool useRelativeBind = false; + if (CodeAccessSecurityEngine.QuickCheckForAllDemands()) + { + if (IsFrameworkAssembly()) + useRelativeBind = true; + else + useRelativeBind = UseRelativeBindForSatellites(); + } + + + if (bIsAppXDevMode || useRelativeBind) + { + if (GlobalAssemblyCache) + { + // lookup in GAC + ArrayList a = new ArrayList(); + bool bTryLoadAnyway = false; + try + { + Fusion.ReadCache(a, an.FullName, ASM_CACHE.GAC); + } + catch(Exception e) + { + if (e.IsTransient) + throw; + + // We also catch any other exception types we haven't come across yet, + // not just UnauthorizedAccessException. + + // We do not want this by itself to cause us to fail to load resources. + + // On Classic, try the old unoptimized way, for full compatibility with 4.0. + // i.e. fall back to using nLoad. + if (!AppDomain.IsAppXModel()) + bTryLoadAnyway = true; + + // On AppX: + // Do not try nLoad since that would effectively allow Framework + // resource satellite assemblies to be placed in AppX packages. + // Instead, leave retAssembly == null. If we were called by the + // ResourceManager, this will usually result in falling back to + // the next culture in the resource fallback chain, possibly the + // neutral culture. + + // Note: if throwOnFileNotFound is true, arbitrary + // exceptions will be absorbed here and + // FileNotFoundException will be thrown in their place. + // (See below: "throw new FileNotFoundException"). + } + if (a.Count > 0 || bTryLoadAnyway) + { + // present in the GAC, load it from there + retAssembly = nLoad(an, null, null, this, ref stackMark, + IntPtr.Zero, + throwOnFileNotFound, false, false); + } + } + else + { + String codeBase = CodeBase; + + if ((codeBase != null) && + (String.Compare(codeBase, 0, s_localFilePrefix, 0, 5, StringComparison.OrdinalIgnoreCase) == 0)) + { + retAssembly = InternalProbeForSatelliteAssemblyNextToParentAssembly(an, + name, + codeBase, + culture, + throwOnFileNotFound, + bIsAppXDevMode /* useLoadFile */, // if bIsAppXDevMode is false, then useRelativeBind is true. + ref stackMark); + if (retAssembly != null && !IsSimplyNamed(an)) + { + AssemblyName defName = retAssembly.GetName(); + if (!AssemblyName.ReferenceMatchesDefinitionInternal(an,defName,false)) + retAssembly = null; + } + } + else if (!bIsAppXDevMode) + { + retAssembly = nLoad(an, null, null, this, ref stackMark, + IntPtr.Zero, + throwOnFileNotFound, false, false); + } + } + } + else +#endif // !FEATURE_CORECLR + { + retAssembly = nLoad(an, null, null, this, ref stackMark, + IntPtr.Zero, + throwOnFileNotFound, false, false); + } + + if (retAssembly == this || (retAssembly == null && throwOnFileNotFound)) + { + throw new FileNotFoundException(String.Format(culture, Environment.GetResourceString("IO.FileNotFound_FileName"), an.Name)); + } + + return retAssembly; + } + + // Helper method used by InternalGetSatelliteAssembly only. Not abstracted for use elsewhere. + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + private RuntimeAssembly InternalProbeForSatelliteAssemblyNextToParentAssembly(AssemblyName an, + String name, + String codeBase, + CultureInfo culture, + bool throwOnFileNotFound, + bool useLoadFile, + ref StackCrawlMark stackMark) + { + // if useLoadFile == false, we do LoadFrom binds + + RuntimeAssembly retAssembly = null; + String location = null; + + if (useLoadFile) + location = Location; + + FileNotFoundException dllNotFoundException = null; + + StringBuilder assemblyFile = new StringBuilder(useLoadFile ? location : codeBase, + 0, + useLoadFile ? location.LastIndexOf('\\') + 1 : codeBase.LastIndexOf('/') + 1, + Path.MaxPath); + assemblyFile.Append(an.CultureInfo.Name); + assemblyFile.Append(useLoadFile ? '\\' : '/'); + assemblyFile.Append(name); + assemblyFile.Append(".DLL"); + + string fileNameOrCodeBase = assemblyFile.ToString(); + + AssemblyName loadFromAsmName = null; + + if (useLoadFile == false) + { + loadFromAsmName = new AssemblyName(); + // set just the codebase - we want this to be a pure LoadFrom + loadFromAsmName.CodeBase = fileNameOrCodeBase; + } + + try + { + try + { + retAssembly = useLoadFile ? nLoadFile(fileNameOrCodeBase, null) : + nLoad(loadFromAsmName, fileNameOrCodeBase, null, this, ref stackMark, + IntPtr.Zero, + throwOnFileNotFound, false, false); + } + catch (FileNotFoundException) + { + // Create our own exception since the one caught doesn't have a filename associated with it, making it less useful for debugging. + dllNotFoundException = new FileNotFoundException(String.Format(culture, + Environment.GetResourceString("IO.FileNotFound_FileName"), + fileNameOrCodeBase), + fileNameOrCodeBase); // Save this exception so we can throw it if we also don't find the .EXE + retAssembly = null; + } + + if (retAssembly == null) + { + // LoadFile will always throw, but LoadFrom will only throw if throwOnFileNotFound is true. + // If an exception was thrown, we must have a dllNotFoundException ready for throwing later. + BCLDebug.Assert((useLoadFile == false && throwOnFileNotFound == false) || dllNotFoundException != null, + "(useLoadFile == false && throwOnFileNotFound == false) || dllNotFoundException != null"); + + assemblyFile.Remove(assemblyFile.Length - 4, 4); + assemblyFile.Append(".EXE"); + fileNameOrCodeBase = assemblyFile.ToString(); + + if (useLoadFile == false) + loadFromAsmName.CodeBase = fileNameOrCodeBase; + + try + { + retAssembly = useLoadFile ? nLoadFile(fileNameOrCodeBase, null) : + nLoad(loadFromAsmName, fileNameOrCodeBase, null, this, ref stackMark, + IntPtr.Zero, + false /* do not throw on file not found */, false, false); + + } + catch (FileNotFoundException) + { + retAssembly = null; + } + + // It would be messy to have a FileNotFoundException that reports both .DLL and .EXE not found. + // Using a .DLL extension for satellite assemblies is the more common scenario, + // so just throw that exception. + + // In classic (i.e. non-AppX) mode, if binder logging is turned on, there will be separate logs for + // the .DLL and .EXE load attempts if the user is interested in digging deeper. + + if (retAssembly == null && throwOnFileNotFound) + throw dllNotFoundException; + } + } + catch (DirectoryNotFoundException) + { + if (throwOnFileNotFound) + throw; + retAssembly = null; + } + // No other exceptions should be caught here. + + return retAssembly; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + static internal extern RuntimeAssembly nLoadFile(String path, Evidence evidence); + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + static internal extern RuntimeAssembly nLoadImage(byte[] rawAssembly, + byte[] rawSymbolStore, + Evidence evidence, + ref StackCrawlMark stackMark, + bool fIntrospection, + SecurityContextSource securityContextSource); +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + static internal extern unsafe void nLoadFromUnmanagedArray(bool fIntrospection, + byte* assemblyContent, + ulong assemblySize, + byte* pdbContent, + ulong pdbSize, + StackCrawlMarkHandle stackMark, + ObjectHandleOnStack retAssembly); +#endif + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static void GetModules(RuntimeAssembly assembly, + bool loadIfNotFound, + bool getResourceModules, + ObjectHandleOnStack retModuleHandles); + + [System.Security.SecuritySafeCritical] // auto-generated + private RuntimeModule[] GetModulesInternal(bool loadIfNotFound, + bool getResourceModules) + { + RuntimeModule[] modules = null; + GetModules(GetNativeHandle(), loadIfNotFound, getResourceModules, JitHelpers.GetObjectHandleOnStack(ref modules)); + return modules; + } + + public override Module[] GetModules(bool getResourceModules) + { + return GetModulesInternal(true, getResourceModules); + } + + public override Module[] GetLoadedModules(bool getResourceModules) + { + return GetModulesInternal(false, getResourceModules); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal static extern RuntimeModule GetManifestModule(RuntimeAssembly assembly); + +#if FEATURE_APTCA + [System.Security.SecuritySafeCritical] + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal static extern bool AptcaCheck(RuntimeAssembly targetAssembly, RuntimeAssembly sourceAssembly); +#endif // FEATURE_APTCA + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal static extern int GetToken(RuntimeAssembly assembly); + } +} diff --git a/src/mscorlib/src/System/Reflection/AssemblyAttributes.cs b/src/mscorlib/src/System/Reflection/AssemblyAttributes.cs new file mode 100644 index 0000000000..955255572b --- /dev/null +++ b/src/mscorlib/src/System/Reflection/AssemblyAttributes.cs @@ -0,0 +1,406 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================================= +** +** +** +** +** +** Purpose: For Assembly-related custom attributes. +** +** +=============================================================================*/ + +namespace System.Reflection { + + using System; + using System.Configuration.Assemblies; + using System.Diagnostics.Contracts; + + [AttributeUsage (AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class AssemblyCopyrightAttribute : Attribute + { + private String m_copyright; + + public AssemblyCopyrightAttribute(String copyright) + { + m_copyright = copyright; + } + + public String Copyright + { + get { return m_copyright; } + } + } + + + [AttributeUsage (AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class AssemblyTrademarkAttribute : Attribute + { + private String m_trademark; + + public AssemblyTrademarkAttribute(String trademark) + { + m_trademark = trademark; + } + + public String Trademark + { + get { return m_trademark; } + } + } + + + [AttributeUsage (AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class AssemblyProductAttribute : Attribute + { + private String m_product; + + public AssemblyProductAttribute(String product) + { + m_product = product; + } + + public String Product + { + get { return m_product; } + } + } + + + [AttributeUsage (AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class AssemblyCompanyAttribute : Attribute + { + private String m_company; + + public AssemblyCompanyAttribute(String company) + { + m_company = company; + } + + public String Company + { + get { return m_company; } + } + } + + + [AttributeUsage (AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class AssemblyDescriptionAttribute : Attribute + { + private String m_description; + + public AssemblyDescriptionAttribute(String description) + { + m_description = description; + } + + public String Description + { + get { return m_description; } + } + } + + + [AttributeUsage (AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class AssemblyTitleAttribute : Attribute + { + private String m_title; + + public AssemblyTitleAttribute(String title) + { + m_title = title; + } + + public String Title + { + get { return m_title; } + } + } + + + [AttributeUsage (AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class AssemblyConfigurationAttribute : Attribute + { + private String m_configuration; + + public AssemblyConfigurationAttribute(String configuration) + { + m_configuration = configuration; + } + + public String Configuration + { + get { return m_configuration; } + } + } + + + [AttributeUsage (AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class AssemblyDefaultAliasAttribute : Attribute + { + private String m_defaultAlias; + + public AssemblyDefaultAliasAttribute(String defaultAlias) + { + m_defaultAlias = defaultAlias; + } + + public String DefaultAlias + { + get { return m_defaultAlias; } + } + } + + + [AttributeUsage (AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class AssemblyInformationalVersionAttribute : Attribute + { + private String m_informationalVersion; + + public AssemblyInformationalVersionAttribute(String informationalVersion) + { + m_informationalVersion = informationalVersion; + } + + public String InformationalVersion + { + get { return m_informationalVersion; } + } + } + + + [AttributeUsage(AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class AssemblyFileVersionAttribute : Attribute + { + private String _version; + + public AssemblyFileVersionAttribute(String version) + { + if (version == null) + throw new ArgumentNullException("version"); + Contract.EndContractBlock(); + _version = version; + } + + public String Version { + get { return _version; } + } + } + + + [AttributeUsage (AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public unsafe sealed class AssemblyCultureAttribute : Attribute + { + private String m_culture; + + public AssemblyCultureAttribute(String culture) + { + m_culture = culture; + } + + public String Culture + { + get { return m_culture; } + } + } + + + [AttributeUsage (AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public unsafe sealed class AssemblyVersionAttribute : Attribute + { + private String m_version; + + public AssemblyVersionAttribute(String version) + { + m_version = version; + } + + public String Version + { + get { return m_version; } + } + } + + + [AttributeUsage (AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class AssemblyKeyFileAttribute : Attribute + { + private String m_keyFile; + + public AssemblyKeyFileAttribute(String keyFile) + { + m_keyFile = keyFile; + } + + public String KeyFile + { + get { return m_keyFile; } + } + } + + + [AttributeUsage (AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class AssemblyDelaySignAttribute : Attribute + { + private bool m_delaySign; + + public AssemblyDelaySignAttribute(bool delaySign) + { + m_delaySign = delaySign; + } + + public bool DelaySign + { get + { return m_delaySign; } + } + } + + + [AttributeUsage(AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public unsafe sealed class AssemblyAlgorithmIdAttribute : Attribute + { + private uint m_algId; + + public AssemblyAlgorithmIdAttribute(AssemblyHashAlgorithm algorithmId) + { + m_algId = (uint) algorithmId; + } + + [CLSCompliant(false)] + public AssemblyAlgorithmIdAttribute(uint algorithmId) + { + m_algId = algorithmId; + } + + [CLSCompliant(false)] + public uint AlgorithmId + { + get { return m_algId; } + } + } + + + [AttributeUsage(AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public unsafe sealed class AssemblyFlagsAttribute : Attribute + { + private AssemblyNameFlags m_flags; + + [Obsolete("This constructor has been deprecated. Please use AssemblyFlagsAttribute(AssemblyNameFlags) instead. http://go.microsoft.com/fwlink/?linkid=14202")] + [CLSCompliant(false)] + public AssemblyFlagsAttribute(uint flags) + { + m_flags = (AssemblyNameFlags)flags; + } + + [Obsolete("This property has been deprecated. Please use AssemblyFlags instead. http://go.microsoft.com/fwlink/?linkid=14202")] + [CLSCompliant(false)] + public uint Flags + { + get { return (uint)m_flags; } + } + + // This, of course, should be typed as AssemblyNameFlags. The compat police don't allow such changes. + public int AssemblyFlags + { + get { return (int)m_flags; } + } + + [Obsolete("This constructor has been deprecated. Please use AssemblyFlagsAttribute(AssemblyNameFlags) instead. http://go.microsoft.com/fwlink/?linkid=14202")] + public AssemblyFlagsAttribute(int assemblyFlags) + { + m_flags = (AssemblyNameFlags)assemblyFlags; + } + + + public AssemblyFlagsAttribute(AssemblyNameFlags assemblyFlags) + { + m_flags = assemblyFlags; + } + } + + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=true, Inherited=false)] + public sealed class AssemblyMetadataAttribute : Attribute + { + private String m_key; + private String m_value; + + public AssemblyMetadataAttribute(string key, string value) + { + m_key = key; + m_value = value; + } + + public string Key + { + get { return m_key; } + } + + public string Value + { + get { return m_value;} + } + } + +#if FEATURE_STRONGNAME_MIGRATION + [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple=false)] + public sealed class AssemblySignatureKeyAttribute : Attribute + { + private String _publicKey; + private String _countersignature; + + public AssemblySignatureKeyAttribute(String publicKey, String countersignature) + { + _publicKey = publicKey; + _countersignature = countersignature; + } + + public String PublicKey + { + get { return _publicKey; } + } + + public String Countersignature + { + get { return _countersignature; } + } + } +#endif + + [AttributeUsage (AttributeTargets.Assembly, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class AssemblyKeyNameAttribute : Attribute + { + private String m_keyName; + + public AssemblyKeyNameAttribute(String keyName) + { + m_keyName = keyName; + } + + public String KeyName + { + get { return m_keyName; } + } + } + +} + diff --git a/src/mscorlib/src/System/Reflection/AssemblyName.cs b/src/mscorlib/src/System/Reflection/AssemblyName.cs new file mode 100644 index 0000000000..051f3b5f0e --- /dev/null +++ b/src/mscorlib/src/System/Reflection/AssemblyName.cs @@ -0,0 +1,539 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** +** Purpose: Used for binding and retrieving info about an assembly +** +** +===========================================================*/ +namespace System.Reflection { + using System; + using System.IO; + using System.Configuration.Assemblies; + using System.Runtime.CompilerServices; + using CultureInfo = System.Globalization.CultureInfo; + using System.Runtime.Serialization; + using System.Security.Permissions; + using System.Runtime.InteropServices; + using System.Runtime.Versioning; + using System.Diagnostics.Contracts; + + [Serializable] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_AssemblyName))] + [System.Runtime.InteropServices.ComVisible(true)] + public sealed class AssemblyName : _AssemblyName, ICloneable, ISerializable, IDeserializationCallback + { + // + // READ ME + // If you modify any of these fields, you must also update the + // AssemblyBaseObject structure in object.h + // + private String _Name; // Name + private byte[] _PublicKey; + private byte[] _PublicKeyToken; + private CultureInfo _CultureInfo; + private String _CodeBase; // Potential location to get the file + private Version _Version; + + private StrongNameKeyPair _StrongNameKeyPair; + + private SerializationInfo m_siInfo; //A temporary variable which we need during deserialization. + + private byte[] _HashForControl; + private AssemblyHashAlgorithm _HashAlgorithm; + private AssemblyHashAlgorithm _HashAlgorithmForControl; + + private AssemblyVersionCompatibility _VersionCompatibility; + private AssemblyNameFlags _Flags; + + public AssemblyName() + { + _HashAlgorithm = AssemblyHashAlgorithm.None; + _VersionCompatibility = AssemblyVersionCompatibility.SameMachine; + _Flags = AssemblyNameFlags.None; + } + + // Set and get the name of the assembly. If this is a weak Name + // then it optionally contains a site. For strong assembly names, + // the name partitions up the strong name's namespace + public String Name + { + get { return _Name; } + set { _Name = value; } + } + + public Version Version + { + get { + return _Version; + } + set { + _Version = value; + } + } + + // Locales, internally the LCID is used for the match. + public CultureInfo CultureInfo + { + get { + return _CultureInfo; + } + set { + _CultureInfo = value; + } + } + + public String CultureName + { + get { + return (_CultureInfo == null) ? null : _CultureInfo.Name; + } + set { + _CultureInfo = (value == null) ? null : new CultureInfo(value); + } + } + + public String CodeBase + { +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + get { return _CodeBase; } +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + set { _CodeBase = value; } + } + + public String EscapedCodeBase + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + if (_CodeBase == null) + return null; + else + return EscapeCodeBase(_CodeBase); + } + } + + public ProcessorArchitecture ProcessorArchitecture + { + get { + int x = (((int)_Flags) & 0x70) >> 4; + if(x > 5) + x = 0; + return (ProcessorArchitecture)x; + } + set { + int x = ((int)value) & 0x07; + if(x <= 5) { + _Flags = (AssemblyNameFlags)((int)_Flags & 0xFFFFFF0F); + _Flags |= (AssemblyNameFlags)(x << 4); + } + } + } + + [System.Runtime.InteropServices.ComVisible(false)] + public AssemblyContentType ContentType + { + get + { + int x = (((int)_Flags) & 0x00000E00) >> 9; + if (x > 1) + x = 0; + return (AssemblyContentType)x; + } + set + { + int x = ((int)value) & 0x07; + if (x <= 1) + { + _Flags = (AssemblyNameFlags)((int)_Flags & 0xFFFFF1FF); + _Flags |= (AssemblyNameFlags)(x << 9); + } + } + } + + + + // Make a copy of this assembly name. + public Object Clone() + { + AssemblyName name = new AssemblyName(); + name.Init(_Name, + _PublicKey, + _PublicKeyToken, + _Version, + _CultureInfo, + _HashAlgorithm, + _VersionCompatibility, + _CodeBase, + _Flags, + _StrongNameKeyPair); + name._HashForControl=_HashForControl; + name._HashAlgorithmForControl=_HashAlgorithmForControl; + return name; + } + + /* + * Get the AssemblyName for a given file. This will only work + * if the file contains an assembly manifest. This method causes + * the file to be opened and closed. + */ + [System.Security.SecuritySafeCritical] // auto-generated + static public AssemblyName GetAssemblyName(String assemblyFile) + { + if(assemblyFile == null) + throw new ArgumentNullException("assemblyFile"); + Contract.EndContractBlock(); + + // Assembly.GetNameInternal() will not demand path discovery + // permission, so do that first. + String fullPath = Path.GetFullPathInternal(assemblyFile); + new FileIOPermission( FileIOPermissionAccess.PathDiscovery, fullPath ).Demand(); + return nGetFileInformation(fullPath); + } + + internal void SetHashControl(byte[] hash, AssemblyHashAlgorithm hashAlgorithm) + { + _HashForControl=hash; + _HashAlgorithmForControl=hashAlgorithm; + } + + // The public key that is used to verify an assemblies + // inclusion into the namespace. If the public key associated + // with the namespace cannot verify the assembly the assembly + // will fail to load. + public byte[] GetPublicKey() + { + return _PublicKey; + } + + public void SetPublicKey(byte[] publicKey) + { + _PublicKey = publicKey; + + if (publicKey == null) + _Flags &= ~AssemblyNameFlags.PublicKey; + else + _Flags |= AssemblyNameFlags.PublicKey; + } + + // The compressed version of the public key formed from a truncated hash. + // Will throw a SecurityException if _PublicKey is invalid + [System.Security.SecuritySafeCritical] // auto-generated + public byte[] GetPublicKeyToken() + { + if (_PublicKeyToken == null) + _PublicKeyToken = nGetPublicKeyToken(); + return _PublicKeyToken; + } + + public void SetPublicKeyToken(byte[] publicKeyToken) + { + _PublicKeyToken = publicKeyToken; + } + + // Flags modifying the name. So far the only flag is PublicKey, which + // indicates that a full public key and not the compressed version is + // present. + // Processor Architecture flags are set only through ProcessorArchitecture + // property and can't be set or retrieved directly + // Content Type flags are set only through ContentType property and can't be + // set or retrieved directly + public AssemblyNameFlags Flags + { + get { return (AssemblyNameFlags)((uint)_Flags & 0xFFFFF10F); } + set { + _Flags &= unchecked((AssemblyNameFlags)0x00000EF0); + _Flags |= (value & unchecked((AssemblyNameFlags)0xFFFFF10F)); + } + } + + public AssemblyHashAlgorithm HashAlgorithm + { + get { return _HashAlgorithm; } + set { _HashAlgorithm = value; } + } + + public AssemblyVersionCompatibility VersionCompatibility + { + get { return _VersionCompatibility; } + set { _VersionCompatibility = value; } + } + + public StrongNameKeyPair KeyPair + { + get { return _StrongNameKeyPair; } + set { _StrongNameKeyPair = value; } + } + + public String FullName + { + [System.Security.SecuritySafeCritical] // auto-generated + get { + return nToString(); + } + } + + // Returns the stringized version of the assembly name. + public override String ToString() + { + String s = FullName; + if(s == null) + return base.ToString(); + else + return s; + } + + [System.Security.SecurityCritical] // auto-generated_required + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException("info"); + Contract.EndContractBlock(); + + //Allocate the serialization info and serialize our static data. + info.AddValue("_Name", _Name); + info.AddValue("_PublicKey", _PublicKey, typeof(byte[])); + info.AddValue("_PublicKeyToken", _PublicKeyToken, typeof(byte[])); +#if FEATURE_USE_LCID + info.AddValue("_CultureInfo", (_CultureInfo == null) ? -1 :_CultureInfo.LCID); +#endif + info.AddValue("_CodeBase", _CodeBase); + info.AddValue("_Version", _Version); + info.AddValue("_HashAlgorithm", _HashAlgorithm, typeof(AssemblyHashAlgorithm)); + info.AddValue("_HashAlgorithmForControl", _HashAlgorithmForControl, typeof(AssemblyHashAlgorithm)); + info.AddValue("_StrongNameKeyPair", _StrongNameKeyPair, typeof(StrongNameKeyPair)); + info.AddValue("_VersionCompatibility", _VersionCompatibility, typeof(AssemblyVersionCompatibility)); + info.AddValue("_Flags", _Flags, typeof(AssemblyNameFlags)); + info.AddValue("_HashForControl",_HashForControl,typeof(byte[])); + } + + public void OnDeserialization(Object sender) + { + // Deserialization has already been performed + if (m_siInfo == null) + return; + + _Name = m_siInfo.GetString("_Name"); + _PublicKey = (byte[]) m_siInfo.GetValue("_PublicKey", typeof(byte[])); + _PublicKeyToken = (byte[]) m_siInfo.GetValue("_PublicKeyToken", typeof(byte[])); +#if FEATURE_USE_LCID + int lcid = (int)m_siInfo.GetInt32("_CultureInfo"); + if (lcid != -1) + _CultureInfo = new CultureInfo(lcid); +#endif + + _CodeBase = m_siInfo.GetString("_CodeBase"); + _Version = (Version) m_siInfo.GetValue("_Version", typeof(Version)); + _HashAlgorithm = (AssemblyHashAlgorithm) m_siInfo.GetValue("_HashAlgorithm", typeof(AssemblyHashAlgorithm)); + _StrongNameKeyPair = (StrongNameKeyPair) m_siInfo.GetValue("_StrongNameKeyPair", typeof(StrongNameKeyPair)); + _VersionCompatibility = (AssemblyVersionCompatibility)m_siInfo.GetValue("_VersionCompatibility", typeof(AssemblyVersionCompatibility)); + _Flags = (AssemblyNameFlags) m_siInfo.GetValue("_Flags", typeof(AssemblyNameFlags)); + + try { + _HashAlgorithmForControl = (AssemblyHashAlgorithm) m_siInfo.GetValue("_HashAlgorithmForControl", typeof(AssemblyHashAlgorithm)); + _HashForControl = (byte[]) m_siInfo.GetValue("_HashForControl", typeof(byte[])); + } + catch (SerializationException) { // RTM did not have these defined + _HashAlgorithmForControl = AssemblyHashAlgorithm.None; + _HashForControl = null; + } + + m_siInfo = null; + } + + // Constructs a new AssemblyName during deserialization. + internal AssemblyName(SerializationInfo info, StreamingContext context) + { + //The graph is not valid until OnDeserialization() has been called. + m_siInfo = info; + } + + [System.Security.SecuritySafeCritical] // auto-generated + public AssemblyName(String assemblyName) + { + if (assemblyName == null) + throw new ArgumentNullException("assemblyName"); + Contract.EndContractBlock(); + if ((assemblyName.Length == 0) || + (assemblyName[0] == '\0')) + throw new ArgumentException(Environment.GetResourceString("Format_StringZeroLength")); + + _Name = assemblyName; + nInit(); + } + + [System.Security.SecuritySafeCritical] // auto-generated + static public bool ReferenceMatchesDefinition(AssemblyName reference, + AssemblyName definition) + { + // Optimization for common use case + if (Object.ReferenceEquals(reference, definition)) + { + return true; + } + return ReferenceMatchesDefinitionInternal(reference, definition, true); + } + + + /// "parse" tells us to parse the simple name of the assembly as if it was the full name + /// almost never the right thing to do, but needed for compat + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + static internal extern bool ReferenceMatchesDefinitionInternal(AssemblyName reference, + AssemblyName definition, + bool parse); + + + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal extern void nInit(out RuntimeAssembly assembly, bool forIntrospection, bool raiseResolveEvent); + + [System.Security.SecurityCritical] // auto-generated + internal void nInit() + { + RuntimeAssembly dummy = null; + nInit(out dummy, false, false); + } + + internal void SetProcArchIndex(PortableExecutableKinds pek, ImageFileMachine ifm) + { + ProcessorArchitecture = CalculateProcArchIndex(pek, ifm, _Flags); + } + + internal static ProcessorArchitecture CalculateProcArchIndex(PortableExecutableKinds pek, ImageFileMachine ifm, AssemblyNameFlags flags) + { + if (((uint)flags & 0xF0) == 0x70) + return ProcessorArchitecture.None; + + if ((pek & System.Reflection.PortableExecutableKinds.PE32Plus) == System.Reflection.PortableExecutableKinds.PE32Plus) + { + switch (ifm) + { + case System.Reflection.ImageFileMachine.IA64: + return ProcessorArchitecture.IA64; + case System.Reflection.ImageFileMachine.AMD64: + return ProcessorArchitecture.Amd64; + case System.Reflection.ImageFileMachine.I386: + if ((pek & System.Reflection.PortableExecutableKinds.ILOnly) == System.Reflection.PortableExecutableKinds.ILOnly) + return ProcessorArchitecture.MSIL; + break; + } + } + else + { + if (ifm == System.Reflection.ImageFileMachine.I386) + { + if ((pek & System.Reflection.PortableExecutableKinds.Required32Bit) == System.Reflection.PortableExecutableKinds.Required32Bit) + return ProcessorArchitecture.X86; + + if ((pek & System.Reflection.PortableExecutableKinds.ILOnly) == System.Reflection.PortableExecutableKinds.ILOnly) + return ProcessorArchitecture.MSIL; + + return ProcessorArchitecture.X86; + } + if (ifm == System.Reflection.ImageFileMachine.ARM) + { + return ProcessorArchitecture.Arm; + } + } + return ProcessorArchitecture.None; + } + + internal void Init(String name, + byte[] publicKey, + byte[] publicKeyToken, + Version version, + CultureInfo cultureInfo, + AssemblyHashAlgorithm hashAlgorithm, + AssemblyVersionCompatibility versionCompatibility, + String codeBase, + AssemblyNameFlags flags, + StrongNameKeyPair keyPair) // Null if ref, matching Assembly if def + { + _Name = name; + + if (publicKey != null) { + _PublicKey = new byte[publicKey.Length]; + Array.Copy(publicKey, _PublicKey, publicKey.Length); + } + + if (publicKeyToken != null) { + _PublicKeyToken = new byte[publicKeyToken.Length]; + Array.Copy(publicKeyToken, _PublicKeyToken, publicKeyToken.Length); + } + + if (version != null) + _Version = (Version) version.Clone(); + + _CultureInfo = cultureInfo; + _HashAlgorithm = hashAlgorithm; + _VersionCompatibility = versionCompatibility; + _CodeBase = codeBase; + _Flags = flags; + _StrongNameKeyPair = keyPair; + } + +#if !FEATURE_CORECLR + void _AssemblyName.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _AssemblyName.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _AssemblyName.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _AssemblyName.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + +#if FEATURE_APTCA + internal string GetNameWithPublicKey() + { + byte[] key = GetPublicKey(); + + // The following string should not be localized because it is used in security decisions. + return Name + ", PublicKey=" + System.Security.Util.Hex.EncodeHexString(key); + } +#endif + + // This call opens and closes the file, but does not add the + // assembly to the domain. + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + static internal extern AssemblyName nGetFileInformation(String s); + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private extern String nToString(); + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private extern byte[] nGetPublicKeyToken(); + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + static internal extern String EscapeCodeBase(String codeBase); + } +} diff --git a/src/mscorlib/src/System/Reflection/AssemblyNameFlags.cs b/src/mscorlib/src/System/Reflection/AssemblyNameFlags.cs new file mode 100644 index 0000000000..35a5370cc6 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/AssemblyNameFlags.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** +** Purpose: Flags controlling how an AssemblyName is used +** during binding +** +** +===========================================================*/ +namespace System.Reflection { + + using System; + [Serializable] + [FlagsAttribute()] + [System.Runtime.InteropServices.ComVisible(true)] + public enum AssemblyNameFlags + { + None = 0x0000, + // Flag used to indicate that an assembly ref contains the full public key, not the compressed token. + // Must match afPublicKey in CorHdr.h. + PublicKey = 0x0001, + //ProcArchMask = 0x00F0, // Bits describing the processor architecture + // Accessible via AssemblyName.ProcessorArchitecture + EnableJITcompileOptimizer = 0x4000, + EnableJITcompileTracking = 0x8000, + Retargetable = 0x0100, + //ContentType = 0x0E00, // Bits describing the ContentType are accessible via AssemblyName.ContentType + } + + [Serializable] + [System.Runtime.InteropServices.ComVisible(false)] + public enum AssemblyContentType + { + Default = 0x0000, + WindowsRuntime = 0x0001 + } + + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public enum ProcessorArchitecture + { + None = 0x0000, + MSIL = 0x0001, + X86 = 0x0002, + IA64 = 0x0003, + Amd64 = 0x0004, + Arm = 0x0005 + } +} diff --git a/src/mscorlib/src/System/Reflection/AssemblyNameProxy.cs b/src/mscorlib/src/System/Reflection/AssemblyNameProxy.cs new file mode 100644 index 0000000000..8c8fa8d286 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/AssemblyNameProxy.cs @@ -0,0 +1,28 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** +** Purpose: Remotable version the AssemblyName +** +** +===========================================================*/ +namespace System.Reflection { + using System; + using System.Runtime.Versioning; + + [System.Runtime.InteropServices.ComVisible(true)] + public class AssemblyNameProxy : MarshalByRefObject + { + public AssemblyName GetAssemblyName(String assemblyFile) + { + return AssemblyName.GetAssemblyName(assemblyFile); + } + } +} diff --git a/src/mscorlib/src/System/Reflection/Associates.cs b/src/mscorlib/src/System/Reflection/Associates.cs new file mode 100644 index 0000000000..8b34e77b63 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Associates.cs @@ -0,0 +1,212 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection +{ + using System; + using System.Collections.Generic; + using System.Diagnostics.Contracts; + + internal static class Associates + { + [Flags] + internal enum Attributes + { + ComposedOfAllVirtualMethods = 0x1, + ComposedOfAllPrivateMethods = 0x2, + ComposedOfNoPublicMembers = 0x4, + ComposedOfNoStaticMembers = 0x8, + } + + internal static bool IncludeAccessor(MethodInfo associate, bool nonPublic) + { + if ((object)associate == null) + return false; + + if (nonPublic) + return true; + + if (associate.IsPublic) + return true; + + return false; + } + + [System.Security.SecurityCritical] // auto-generated + private static unsafe RuntimeMethodInfo AssignAssociates( + int tkMethod, + RuntimeType declaredType, + RuntimeType reflectedType) + { + if (MetadataToken.IsNullToken(tkMethod)) + return null; + + Contract.Assert(declaredType != null); + Contract.Assert(reflectedType != null); + + bool isInherited = declaredType != reflectedType; + + IntPtr[] genericArgumentHandles = null; + int genericArgumentCount = 0; + RuntimeType [] genericArguments = declaredType.GetTypeHandleInternal().GetInstantiationInternal(); + if (genericArguments != null) + { + genericArgumentCount = genericArguments.Length; + genericArgumentHandles = new IntPtr[genericArguments.Length]; + for (int i = 0; i < genericArguments.Length; i++) + { + genericArgumentHandles[i] = genericArguments[i].GetTypeHandleInternal().Value; + } + } + + RuntimeMethodHandleInternal associateMethodHandle = ModuleHandle.ResolveMethodHandleInternalCore(RuntimeTypeHandle.GetModule(declaredType), tkMethod, genericArgumentHandles, genericArgumentCount, null, 0); + Contract.Assert(!associateMethodHandle.IsNullHandle(), "Failed to resolve associateRecord methodDef token"); + + if (isInherited) + { + MethodAttributes methAttr = RuntimeMethodHandle.GetAttributes(associateMethodHandle); + + // ECMA MethodSemantics: "All methods for a given Property or Event shall have the same accessibility + //(ie the MemberAccessMask subfield of their Flags row) and cannot be CompilerControlled [CLS]" + // Consequently, a property may be composed of public and private methods. If the declared type != + // the reflected type, the private methods should not be exposed. Note that this implies that the + // identity of a property includes it's reflected type. + + if ((methAttr & MethodAttributes.MemberAccessMask) == MethodAttributes.Private) + return null; + + // Note this is the first time the property was encountered walking from the most derived class + // towards the base class. It would seem to follow that any associated methods would not + // be overriden -- but this is not necessarily true. A more derived class may have overriden a + // virtual method associated with a property in a base class without associating the override with + // the same or any property in the derived class. + if ((methAttr & MethodAttributes.Virtual) != 0) + { + bool declaringTypeIsClass = + (RuntimeTypeHandle.GetAttributes(declaredType) & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Class; + + // It makes no sense to search for a virtual override of a method declared on an interface. + if (declaringTypeIsClass) + { + int slot = RuntimeMethodHandle.GetSlot(associateMethodHandle); + + // Find the override visible from the reflected type + associateMethodHandle = RuntimeTypeHandle.GetMethodAt(reflectedType, slot); + } + } + } + + RuntimeMethodInfo associateMethod = + RuntimeType.GetMethodBase(reflectedType, associateMethodHandle) as RuntimeMethodInfo; + + // suppose a property was mapped to a method not in the derivation hierarchy of the reflectedTypeHandle + if (associateMethod == null) + associateMethod = reflectedType.Module.ResolveMethod(tkMethod, null, null) as RuntimeMethodInfo; + + return associateMethod; + } + + [System.Security.SecurityCritical] // auto-generated + internal static unsafe void AssignAssociates( + MetadataImport scope, + int mdPropEvent, + RuntimeType declaringType, + RuntimeType reflectedType, + out RuntimeMethodInfo addOn, + out RuntimeMethodInfo removeOn, + out RuntimeMethodInfo fireOn, + out RuntimeMethodInfo getter, + out RuntimeMethodInfo setter, + out MethodInfo[] other, + out bool composedOfAllPrivateMethods, + out BindingFlags bindingFlags) + { + addOn = removeOn = fireOn = getter = setter = null; + + Attributes attributes = + Attributes.ComposedOfAllPrivateMethods | + Attributes.ComposedOfAllVirtualMethods | + Attributes.ComposedOfNoPublicMembers | + Attributes.ComposedOfNoStaticMembers; + + while(RuntimeTypeHandle.IsGenericVariable(reflectedType)) + reflectedType = (RuntimeType)reflectedType.BaseType; + + bool isInherited = declaringType != reflectedType; + + List otherList = null; + + MetadataEnumResult associatesData; + scope.Enum(MetadataTokenType.MethodDef, mdPropEvent, out associatesData); + + int cAssociates = associatesData.Length / 2; + + for (int i = 0; i < cAssociates; i++) + { + int methodDefToken = associatesData[i * 2]; + MethodSemanticsAttributes semantics = (MethodSemanticsAttributes)associatesData[i * 2 + 1]; + + #region Assign each associate + RuntimeMethodInfo associateMethod = + AssignAssociates(methodDefToken, declaringType, reflectedType); + + if (associateMethod == null) + continue; + + MethodAttributes methAttr = associateMethod.Attributes; + bool isPrivate =(methAttr & MethodAttributes.MemberAccessMask) == MethodAttributes.Private; + bool isVirtual =(methAttr & MethodAttributes.Virtual) != 0; + + MethodAttributes visibility = methAttr & MethodAttributes.MemberAccessMask; + bool isPublic = visibility == MethodAttributes.Public; + bool isStatic =(methAttr & MethodAttributes.Static) != 0; + + if (isPublic) + { + attributes &= ~Attributes.ComposedOfNoPublicMembers; + attributes &= ~Attributes.ComposedOfAllPrivateMethods; + } + else if (!isPrivate) + { + attributes &= ~Attributes.ComposedOfAllPrivateMethods; + } + + if (isStatic) + attributes &= ~Attributes.ComposedOfNoStaticMembers; + + if (!isVirtual) + attributes &= ~Attributes.ComposedOfAllVirtualMethods; + #endregion + + if (semantics == MethodSemanticsAttributes.Setter) + setter = associateMethod; + else if (semantics == MethodSemanticsAttributes.Getter) + getter = associateMethod; + else if (semantics == MethodSemanticsAttributes.Fire) + fireOn = associateMethod; + else if (semantics == MethodSemanticsAttributes.AddOn) + addOn = associateMethod; + else if (semantics == MethodSemanticsAttributes.RemoveOn) + removeOn = associateMethod; + else + { + if (otherList == null) + otherList = new List(cAssociates); + otherList.Add(associateMethod); + } + } + + bool isPseudoPublic = (attributes & Attributes.ComposedOfNoPublicMembers) == 0; + bool isPseudoStatic = (attributes & Attributes.ComposedOfNoStaticMembers) == 0; + bindingFlags = RuntimeType.FilterPreCalculate(isPseudoPublic, isInherited, isPseudoStatic); + + composedOfAllPrivateMethods =(attributes & Attributes.ComposedOfAllPrivateMethods) != 0; + + other = (otherList != null) ? otherList.ToArray() : null; + } + } + +} diff --git a/src/mscorlib/src/System/Reflection/Binder.cs b/src/mscorlib/src/System/Reflection/Binder.cs new file mode 100644 index 0000000000..d06899f6c6 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Binder.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +// +// +// This interface defines a set of methods which interact with reflection +// during the binding process. This control allows systems to apply language +// specific semantics to the binding and invocation process. +// +// +namespace System.Reflection { + using System; + using System.Runtime.InteropServices; + using CultureInfo = System.Globalization.CultureInfo; + + [Serializable] + [ClassInterface(ClassInterfaceType.AutoDual)] +[System.Runtime.InteropServices.ComVisible(true)] + public abstract class Binder + { + // Given a set of methods that match the basic criteria, select a method to + // invoke. When this method is finished, we should have + public abstract MethodBase BindToMethod(BindingFlags bindingAttr,MethodBase[] match,ref Object[] args, + ParameterModifier[] modifiers,CultureInfo culture,String[] names, out Object state); + + // Given a set of methods that match the basic criteria, select a method to + // invoke. When this method is finished, we should have + public abstract FieldInfo BindToField(BindingFlags bindingAttr,FieldInfo[] match, + Object value,CultureInfo culture); + + // Given a set of methods that match the base criteria, select a method based + // upon an array of types. This method should return null if no method matchs + // the criteria. + public abstract MethodBase SelectMethod(BindingFlags bindingAttr,MethodBase[] match, + Type[] types,ParameterModifier[] modifiers); + + + // Given a set of propreties that match the base criteria, select one. + public abstract PropertyInfo SelectProperty(BindingFlags bindingAttr,PropertyInfo[] match, + Type returnType,Type[] indexes,ParameterModifier[] modifiers); + + // ChangeType + // This method will convert the value into the property type. + // It throws a cast exception if this fails. + public abstract Object ChangeType(Object value,Type type,CultureInfo culture); + + public abstract void ReorderArgumentArray(ref Object[] args, Object state); + } +} diff --git a/src/mscorlib/src/System/Reflection/BindingFlags.cs b/src/mscorlib/src/System/Reflection/BindingFlags.cs new file mode 100644 index 0000000000..591dfbb249 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/BindingFlags.cs @@ -0,0 +1,64 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// BindingFlags are a set of flags that control the binding and invocation process +// +// in Reflection. There are two processes. The first is selection of a Member which +// is the binding phase. The second, is invocation. These flags control how this +// process works. +// +// +namespace System.Reflection { + + using System; + [Serializable] + [Flags] + [System.Runtime.InteropServices.ComVisible(true)] + public enum BindingFlags + { + + // NOTES: We have lookup masks defined in RuntimeType and Activator. If we + // change the lookup values then these masks may need to change also. + + // a place holder for no flag specifed + Default = 0x00, + + // These flags indicate what to search for when binding + IgnoreCase = 0x01, // Ignore the case of Names while searching + DeclaredOnly = 0x02, // Only look at the members declared on the Type + Instance = 0x04, // Include Instance members in search + Static = 0x08, // Include Static members in search + Public = 0x10, // Include Public members in search + NonPublic = 0x20, // Include Non-Public members in search + FlattenHierarchy = 0x40, // Rollup the statics into the class. + + // These flags are used by InvokeMember to determine + // what type of member we are trying to Invoke. + // BindingAccess = 0xFF00; + InvokeMethod = 0x0100, + CreateInstance = 0x0200, + GetField = 0x0400, + SetField = 0x0800, + GetProperty = 0x1000, + SetProperty = 0x2000, + + // These flags are also used by InvokeMember but they should only + // be used when calling InvokeMember on a COM object. + PutDispProperty = 0x4000, + PutRefDispProperty = 0x8000, + + ExactBinding = 0x010000, // Bind with Exact Type matching, No Change type + SuppressChangeType = 0x020000, + + // DefaultValueBinding will return the set of methods having ArgCount or + // more parameters. This is used for default values, etc. + OptionalParamBinding = 0x040000, + + // These are a couple of misc attributes used + IgnoreReturn = 0x01000000, // This is used in COM Interop + } +} diff --git a/src/mscorlib/src/System/Reflection/CallingConventions.cs b/src/mscorlib/src/System/Reflection/CallingConventions.cs new file mode 100644 index 0000000000..6ca11c9021 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/CallingConventions.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// CallingConventions is a set of Bits representing the calling conventions +// +// in the system. +// +// +namespace System.Reflection { + using System.Runtime.InteropServices; + using System; + [Serializable] + [Flags] + [System.Runtime.InteropServices.ComVisible(true)] + public enum CallingConventions + { + //NOTE: If you change this please update COMMember.cpp. These + // are defined there. + Standard = 0x0001, + VarArgs = 0x0002, + Any = Standard | VarArgs, + HasThis = 0x0020, + ExplicitThis = 0x0040, + } +} diff --git a/src/mscorlib/src/System/Reflection/ComInterfaces.cs b/src/mscorlib/src/System/Reflection/ComInterfaces.cs new file mode 100644 index 0000000000..63438115fc --- /dev/null +++ b/src/mscorlib/src/System/Reflection/ComInterfaces.cs @@ -0,0 +1,673 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Globalization; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.Serialization; +using System.Security.Permissions; +using System.Security.Policy; + +namespace System.Runtime.InteropServices +{ + [GuidAttribute("BCA8B44D-AAD6-3A86-8AB7-03349F4F2DA2")] + [CLSCompliant(false)] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [TypeLibImportClassAttribute(typeof(System.Type))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _Type + { +#if !FEATURE_CORECLR + #region IDispatch Members + void GetTypeInfoCount(out uint pcTInfo); + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); + #endregion + + #region Object Members + String ToString(); + bool Equals(Object other); + int GetHashCode(); + Type GetType(); + #endregion + + #region MemberInfo Members + MemberTypes MemberType { get; } + String Name { get; } + Type DeclaringType { get; } + Type ReflectedType { get; } + Object[] GetCustomAttributes(Type attributeType, bool inherit); + Object[] GetCustomAttributes(bool inherit); + bool IsDefined(Type attributeType, bool inherit); + #endregion + + #region Type Members + Guid GUID { get; } + Module Module { get; } + Assembly Assembly { get; } + RuntimeTypeHandle TypeHandle { get; } + String FullName { get; } + String Namespace { get; } + String AssemblyQualifiedName { get; } + int GetArrayRank(); + Type BaseType { get; } + + ConstructorInfo[] GetConstructors(BindingFlags bindingAttr); + Type GetInterface(String name, bool ignoreCase); + Type[] GetInterfaces(); + Type[] FindInterfaces(TypeFilter filter,Object filterCriteria); + EventInfo GetEvent(String name,BindingFlags bindingAttr); + EventInfo[] GetEvents(); + EventInfo[] GetEvents(BindingFlags bindingAttr); + Type[] GetNestedTypes(BindingFlags bindingAttr); + Type GetNestedType(String name, BindingFlags bindingAttr); + MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr); + MemberInfo[] GetDefaultMembers(); + MemberInfo[] FindMembers(MemberTypes memberType,BindingFlags bindingAttr,MemberFilter filter,Object filterCriteria); + Type GetElementType(); + bool IsSubclassOf(Type c); + bool IsInstanceOfType(Object o); + bool IsAssignableFrom(Type c); + InterfaceMapping GetInterfaceMap(Type interfaceType); + MethodInfo GetMethod(String name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers); + MethodInfo GetMethod(String name, BindingFlags bindingAttr); + MethodInfo[] GetMethods(BindingFlags bindingAttr); + FieldInfo GetField(String name, BindingFlags bindingAttr); + FieldInfo[] GetFields(BindingFlags bindingAttr); + PropertyInfo GetProperty(String name, BindingFlags bindingAttr); + PropertyInfo GetProperty(String name,BindingFlags bindingAttr,Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers); + PropertyInfo[] GetProperties(BindingFlags bindingAttr); + MemberInfo[] GetMember(String name, BindingFlags bindingAttr); + MemberInfo[] GetMembers(BindingFlags bindingAttr); + Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters); + Type UnderlyingSystemType + { + get; + } + + Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder, Object target, Object[] args, CultureInfo culture); + Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder, Object target, Object[] args); + ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers); + ConstructorInfo GetConstructor(BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers); + ConstructorInfo GetConstructor(Type[] types); + ConstructorInfo[] GetConstructors(); + ConstructorInfo TypeInitializer + { + get; + } + + MethodInfo GetMethod(String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers); + MethodInfo GetMethod(String name, Type[] types, ParameterModifier[] modifiers); + MethodInfo GetMethod(String name, Type[] types); + MethodInfo GetMethod(String name); + MethodInfo[] GetMethods(); + FieldInfo GetField(String name); + FieldInfo[] GetFields(); + Type GetInterface(String name); + EventInfo GetEvent(String name); + PropertyInfo GetProperty(String name, Type returnType, Type[] types,ParameterModifier[] modifiers); + PropertyInfo GetProperty(String name, Type returnType, Type[] types); + PropertyInfo GetProperty(String name, Type[] types); + PropertyInfo GetProperty(String name, Type returnType); + PropertyInfo GetProperty(String name); + PropertyInfo[] GetProperties(); + Type[] GetNestedTypes(); + Type GetNestedType(String name); + MemberInfo[] GetMember(String name); + MemberInfo[] GetMembers(); + TypeAttributes Attributes { get; } + bool IsNotPublic { get; } + bool IsPublic { get; } + bool IsNestedPublic { get; } + bool IsNestedPrivate { get; } + bool IsNestedFamily { get; } + bool IsNestedAssembly { get; } + bool IsNestedFamANDAssem { get; } + bool IsNestedFamORAssem { get; } + bool IsAutoLayout { get; } + bool IsLayoutSequential { get; } + bool IsExplicitLayout { get; } + bool IsClass { get; } + bool IsInterface { get; } + bool IsValueType { get; } + bool IsAbstract { get; } + bool IsSealed { get; } + bool IsEnum { get; } + bool IsSpecialName { get; } + bool IsImport { get; } + bool IsSerializable { get; } + bool IsAnsiClass { get; } + bool IsUnicodeClass { get; } + bool IsAutoClass { get; } + bool IsArray { get; } + bool IsByRef { get; } + bool IsPointer { get; } + bool IsPrimitive { get; } + bool IsCOMObject { get; } + bool HasElementType { get; } + bool IsContextful { get; } + bool IsMarshalByRef { get; } + bool Equals(Type o); + #endregion +#endif + } + + [GuidAttribute("17156360-2f1a-384a-bc52-fde93c215c5b")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Assembly))] + [CLSCompliant(false)] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _Assembly + { +#if !FEATURE_CORECLR + #region Object Members + String ToString(); + bool Equals(Object other); + int GetHashCode(); + Type GetType(); + #endregion + + #region Assembly Members + String CodeBase { +#if FEATURE_CORECLR +[System.Security.SecurityCritical] // auto-generated +#endif +get; } + String EscapedCodeBase { get; } + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + AssemblyName GetName(); + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + AssemblyName GetName(bool copiedName); + String FullName { get; } + MethodInfo EntryPoint { get; } + Type GetType(String name); + Type GetType(String name, bool throwOnError); + Type[] GetExportedTypes(); + Type[] GetTypes(); + Stream GetManifestResourceStream(Type type, String name); + Stream GetManifestResourceStream(String name); + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + FileStream GetFile(String name); + FileStream[] GetFiles(); + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + FileStream[] GetFiles(bool getResourceModules); + String[] GetManifestResourceNames(); + ManifestResourceInfo GetManifestResourceInfo(String resourceName); + String Location { +#if FEATURE_CORECLR +[System.Security.SecurityCritical] // auto-generated +#endif +get; } +#if FEATURE_CAS_POLICY + Evidence Evidence { get; } +#endif // FEATURE_CAS_POLICY + Object[] GetCustomAttributes(Type attributeType, bool inherit); + Object[] GetCustomAttributes(bool inherit); + bool IsDefined(Type attributeType, bool inherit); +#if FEATURE_SERIALIZATION + [System.Security.SecurityCritical] // auto-generated_required + void GetObjectData(SerializationInfo info, StreamingContext context); +#endif + [method: System.Security.SecurityCritical] + event ModuleResolveEventHandler ModuleResolve; + Type GetType(String name, bool throwOnError, bool ignoreCase); + Assembly GetSatelliteAssembly(CultureInfo culture); + Assembly GetSatelliteAssembly(CultureInfo culture, Version version); +#if FEATURE_MULTIMODULE_ASSEMBLIES + Module LoadModule(String moduleName, byte[] rawModule); + Module LoadModule(String moduleName, byte[] rawModule, byte[] rawSymbolStore); +#endif + Object CreateInstance(String typeName); + Object CreateInstance(String typeName, bool ignoreCase); + Object CreateInstance(String typeName, bool ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes); + Module[] GetLoadedModules(); + Module[] GetLoadedModules(bool getResourceModules); + Module[] GetModules(); + Module[] GetModules(bool getResourceModules); + Module GetModule(String name); + AssemblyName[] GetReferencedAssemblies(); + bool GlobalAssemblyCache { get; } + #endregion +#endif + } + + + [GuidAttribute("f7102fa9-cabb-3a74-a6da-b4567ef1b079")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [TypeLibImportClassAttribute(typeof(System.Reflection.MemberInfo))] + [CLSCompliant(false)] + [System.Runtime.InteropServices.ComVisible(true)] + public interface _MemberInfo + { +#if !FEATURE_CORECLR + #region IDispatch Members + void GetTypeInfoCount(out uint pcTInfo); + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); + #endregion + + #region Object Members + String ToString(); + bool Equals(Object other); + int GetHashCode(); + Type GetType(); + #endregion + + #region MemberInfo Members + MemberTypes MemberType { get; } + String Name { get; } + Type DeclaringType { get; } + Type ReflectedType { get; } + Object[] GetCustomAttributes(Type attributeType, bool inherit); + Object[] GetCustomAttributes(bool inherit); + bool IsDefined(Type attributeType, bool inherit); + #endregion +#endif + } + + + [GuidAttribute("6240837A-707F-3181-8E98-A36AE086766B")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.MethodBase))] + [System.Runtime.InteropServices.ComVisible(true)] + public interface _MethodBase + { +#if !FEATURE_CORECLR + #region IDispatch Members + void GetTypeInfoCount(out uint pcTInfo); + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); + #endregion + + #region Object Members + String ToString(); + bool Equals(Object other); + int GetHashCode(); + Type GetType(); + #endregion + + #region MemberInfo Members + MemberTypes MemberType { get; } + String Name { get; } + Type DeclaringType { get; } + Type ReflectedType { get; } + Object[] GetCustomAttributes(Type attributeType, bool inherit); + Object[] GetCustomAttributes(bool inherit); + bool IsDefined(Type attributeType, bool inherit); + #endregion + + #region MethodBase Members + ParameterInfo[] GetParameters(); + MethodImplAttributes GetMethodImplementationFlags(); + RuntimeMethodHandle MethodHandle { get; } + MethodAttributes Attributes { get; } + CallingConventions CallingConvention { get; } + Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture); + bool IsPublic { get; } + bool IsPrivate { get; } + bool IsFamily { get; } + bool IsAssembly { get; } + bool IsFamilyAndAssembly { get; } + bool IsFamilyOrAssembly { get; } + bool IsStatic { get; } + bool IsFinal { get; } + bool IsVirtual { get; } + bool IsHideBySig { get; } + bool IsAbstract { get; } + bool IsSpecialName { get; } + bool IsConstructor { get; } + Object Invoke(Object obj, Object[] parameters); + #endregion +#endif + } + + + [GuidAttribute("FFCC1B5D-ECB8-38DD-9B01-3DC8ABC2AA5F")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.MethodInfo))] + [System.Runtime.InteropServices.ComVisible(true)] + public interface _MethodInfo + { +#if !FEATURE_CORECLR + #region IDispatch Members + void GetTypeInfoCount(out uint pcTInfo); + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); + #endregion + + #region Object Members + String ToString(); + bool Equals(Object other); + int GetHashCode(); + Type GetType(); + #endregion + + #region MemberInfo Members + MemberTypes MemberType { get; } + String Name { get; } + Type DeclaringType { get; } + Type ReflectedType { get; } + Object[] GetCustomAttributes(Type attributeType, bool inherit); + Object[] GetCustomAttributes(bool inherit); + bool IsDefined(Type attributeType, bool inherit); + #endregion + + #region MethodBase Members + ParameterInfo[] GetParameters(); + MethodImplAttributes GetMethodImplementationFlags(); + RuntimeMethodHandle MethodHandle { get; } + MethodAttributes Attributes { get; } + CallingConventions CallingConvention { get; } + Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture); + bool IsPublic { get; } + bool IsPrivate { get; } + bool IsFamily { get; } + bool IsAssembly { get; } + bool IsFamilyAndAssembly { get; } + bool IsFamilyOrAssembly { get; } + bool IsStatic { get; } + bool IsFinal { get; } + bool IsVirtual { get; } + bool IsHideBySig { get; } + bool IsAbstract { get; } + bool IsSpecialName { get; } + bool IsConstructor { get; } + Object Invoke(Object obj, Object[] parameters); + #endregion + + #region MethodInfo Members + Type ReturnType { get; } + ICustomAttributeProvider ReturnTypeCustomAttributes { get; } + MethodInfo GetBaseDefinition(); + #endregion +#endif + } + + + [GuidAttribute("E9A19478-9646-3679-9B10-8411AE1FD57D")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.ConstructorInfo))] + [System.Runtime.InteropServices.ComVisible(true)] + public interface _ConstructorInfo + { +#if !FEATURE_CORECLR + #region IDispatch Members + void GetTypeInfoCount(out uint pcTInfo); + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); + #endregion + + #region Object Members + String ToString(); + bool Equals(Object other); + int GetHashCode(); + Type GetType(); + #endregion + + #region MemberInfo Members + MemberTypes MemberType { get; } + String Name { get; } + Type DeclaringType { get; } + Type ReflectedType { get; } + Object[] GetCustomAttributes(Type attributeType, bool inherit); + Object[] GetCustomAttributes(bool inherit); + bool IsDefined(Type attributeType, bool inherit); + #endregion + + #region MethodBase Members + ParameterInfo[] GetParameters(); + MethodImplAttributes GetMethodImplementationFlags(); + RuntimeMethodHandle MethodHandle { get; } + MethodAttributes Attributes { get; } + CallingConventions CallingConvention { get; } + Object Invoke_2(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture); + bool IsPublic { get; } + bool IsPrivate { get; } + bool IsFamily { get; } + bool IsAssembly { get; } + bool IsFamilyAndAssembly { get; } + bool IsFamilyOrAssembly { get; } + bool IsStatic { get; } + bool IsFinal { get; } + bool IsVirtual { get; } + bool IsHideBySig { get; } + bool IsAbstract { get; } + bool IsSpecialName { get; } + bool IsConstructor { get; } + Object Invoke_3(Object obj, Object[] parameters); + #endregion + + #region ConstructorInfo + Object Invoke_4(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture); + Object Invoke_5(Object[] parameters); + #endregion +#endif + } + + + [GuidAttribute("8A7C1442-A9FB-366B-80D8-4939FFA6DBE0")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.FieldInfo))] + [System.Runtime.InteropServices.ComVisible(true)] + public interface _FieldInfo + { +#if !FEATURE_CORECLR + #region IDispatch Members + void GetTypeInfoCount(out uint pcTInfo); + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); + #endregion + + #region Object Members + String ToString(); + bool Equals(Object other); + int GetHashCode(); + Type GetType(); + #endregion + + #region MemberInfo Members + MemberTypes MemberType { get; } + String Name { get; } + Type DeclaringType { get; } + Type ReflectedType { get; } + Object[] GetCustomAttributes(Type attributeType, bool inherit); + Object[] GetCustomAttributes(bool inherit); + bool IsDefined(Type attributeType, bool inherit); + #endregion + + #region FieldInfo Members + Type FieldType { get; } + Object GetValue(Object obj); + Object GetValueDirect(TypedReference obj); + void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture); + void SetValueDirect(TypedReference obj,Object value); + RuntimeFieldHandle FieldHandle { get; } + FieldAttributes Attributes { get; } + void SetValue(Object obj, Object value); + bool IsPublic { get; } + bool IsPrivate { get; } + bool IsFamily { get; } + bool IsAssembly { get; } + bool IsFamilyAndAssembly { get; } + bool IsFamilyOrAssembly { get; } + bool IsStatic { get; } + bool IsInitOnly { get; } + bool IsLiteral { get; } + bool IsNotSerialized { get; } + bool IsSpecialName { get; } + bool IsPinvokeImpl { get; } + #endregion +#endif + } + + + [GuidAttribute("F59ED4E4-E68F-3218-BD77-061AA82824BF")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.PropertyInfo))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _PropertyInfo + { +#if !FEATURE_CORECLR + #region IDispatch Members + void GetTypeInfoCount(out uint pcTInfo); + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); + #endregion + + #region Object Members + String ToString(); + bool Equals(Object other); + int GetHashCode(); + Type GetType(); + #endregion + + #region MemberInfo Members + MemberTypes MemberType { get; } + String Name { get; } + Type DeclaringType { get; } + Type ReflectedType { get; } + Object[] GetCustomAttributes(Type attributeType, bool inherit); + Object[] GetCustomAttributes(bool inherit); + bool IsDefined(Type attributeType, bool inherit); + #endregion + + #region Property Members + Type PropertyType { get; } + Object GetValue(Object obj,Object[] index); + Object GetValue(Object obj,BindingFlags invokeAttr,Binder binder, Object[] index, CultureInfo culture); + void SetValue(Object obj, Object value, Object[] index); + void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture); + MethodInfo[] GetAccessors(bool nonPublic); + MethodInfo GetGetMethod(bool nonPublic); + MethodInfo GetSetMethod(bool nonPublic); + ParameterInfo[] GetIndexParameters(); + PropertyAttributes Attributes { get; } + bool CanRead { get; } + bool CanWrite { get; } + MethodInfo[] GetAccessors(); + MethodInfo GetGetMethod(); + MethodInfo GetSetMethod(); + bool IsSpecialName { get; } + #endregion +#endif + } + + + [GuidAttribute("9DE59C64-D889-35A1-B897-587D74469E5B")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.EventInfo))] + [System.Runtime.InteropServices.ComVisible(true)] + public interface _EventInfo + { +#if !FEATURE_CORECLR + #region IDispatch Members + void GetTypeInfoCount(out uint pcTInfo); + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); + #endregion + + #region Object Members + String ToString(); + bool Equals(Object other); + int GetHashCode(); + Type GetType(); + #endregion + + #region MemberInfo Members + MemberTypes MemberType { get; } + String Name { get; } + Type DeclaringType { get; } + Type ReflectedType { get; } + Object[] GetCustomAttributes(Type attributeType, bool inherit); + Object[] GetCustomAttributes(bool inherit); + bool IsDefined(Type attributeType, bool inherit); + #endregion + + #region EventInfo Members + MethodInfo GetAddMethod(bool nonPublic); + MethodInfo GetRemoveMethod(bool nonPublic); + MethodInfo GetRaiseMethod(bool nonPublic); + EventAttributes Attributes { get; } + MethodInfo GetAddMethod(); + MethodInfo GetRemoveMethod(); + MethodInfo GetRaiseMethod(); + void AddEventHandler(Object target, Delegate handler); + void RemoveEventHandler(Object target, Delegate handler); + Type EventHandlerType { get; } + bool IsSpecialName { get; } + bool IsMulticast { get; } + #endregion +#endif + } + + [GuidAttribute("993634C4-E47A-32CC-BE08-85F567DC27D6")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.ParameterInfo))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _ParameterInfo + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + + [GuidAttribute("D002E9BA-D9E3-3749-B1D3-D565A08B13E7")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Module))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _Module + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + + [GuidAttribute("B42B6AAC-317E-34D5-9FA9-093BB4160C50")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.AssemblyName))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _AssemblyName + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } +} + diff --git a/src/mscorlib/src/System/Reflection/ConstructorInfo.cs b/src/mscorlib/src/System/Reflection/ConstructorInfo.cs new file mode 100644 index 0000000000..d5b5cc36eb --- /dev/null +++ b/src/mscorlib/src/System/Reflection/ConstructorInfo.cs @@ -0,0 +1,781 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Diagnostics.Contracts; + using System.Globalization; + using System.Runtime; + using System.Runtime.ConstrainedExecution; + using System.Runtime.InteropServices; +#if FEATURE_REMOTING + using System.Runtime.Remoting.Metadata; +#endif //FEATURE_REMOTING + using System.Runtime.Serialization; + using System.Security; + using System.Security.Permissions; + using System.Threading; + using MemberListType = System.RuntimeType.MemberListType; + using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache; + using System.Runtime.CompilerServices; + + [Serializable] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_ConstructorInfo))] +#pragma warning disable 618 + [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")] +#pragma warning restore 618 + [System.Runtime.InteropServices.ComVisible(true)] + public abstract class ConstructorInfo : MethodBase, _ConstructorInfo + { + #region Static Members + [System.Runtime.InteropServices.ComVisible(true)] + public readonly static String ConstructorName = ".ctor"; + + [System.Runtime.InteropServices.ComVisible(true)] + public readonly static String TypeConstructorName = ".cctor"; + #endregion + + #region Constructor + protected ConstructorInfo() { } + #endregion + + public static bool operator ==(ConstructorInfo left, ConstructorInfo right) + { + if (ReferenceEquals(left, right)) + return true; + + if ((object)left == null || (object)right == null || + left is RuntimeConstructorInfo || right is RuntimeConstructorInfo) + { + return false; + } + return left.Equals(right); + } + + public static bool operator !=(ConstructorInfo left, ConstructorInfo right) + { + return !(left == right); + } + + public override bool Equals(object obj) + { + return base.Equals(obj); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + #region Internal Members + internal virtual Type GetReturnType() { throw new NotImplementedException(); } + #endregion + + #region MemberInfo Overrides + [System.Runtime.InteropServices.ComVisible(true)] + public override MemberTypes MemberType { get { return System.Reflection.MemberTypes.Constructor; } } + #endregion + + #region Public Abstract\Virtual Members + public abstract Object Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture); + #endregion + + #region Public Members + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public Object Invoke(Object[] parameters) + { + // Theoretically we should set up a LookForMyCaller stack mark here and pass that along. + // But to maintain backward compatibility we can't switch to calling an + // internal overload that takes a stack mark. + // Fortunately the stack walker skips all the reflection invocation frames including this one. + // So this method will never be returned by the stack walker as the caller. + // See SystemDomain::CallersMethodCallbackWithStackMark in AppDomain.cpp. + return Invoke(BindingFlags.Default, null, parameters, null); + } + #endregion + +#if !FEATURE_CORECLR + #region COM Interop Support + Type _ConstructorInfo.GetType() + { + return base.GetType(); + } + + Object _ConstructorInfo.Invoke_2(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) + { + return Invoke(obj, invokeAttr, binder, parameters, culture); + } + + Object _ConstructorInfo.Invoke_3(Object obj, Object[] parameters) + { + return Invoke(obj, parameters); + } + + Object _ConstructorInfo.Invoke_4(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) + { + return Invoke(invokeAttr, binder, parameters, culture); + } + + Object _ConstructorInfo.Invoke_5(Object[] parameters) + { + return Invoke(parameters); + } + + void _ConstructorInfo.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _ConstructorInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _ConstructorInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + // If you implement this method, make sure to include _ConstructorInfo.Invoke in VM\DangerousAPIs.h and + // include _ConstructorInfo in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp. + void _ConstructorInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } + #endregion +#endif + } + + [Serializable] + internal sealed class RuntimeConstructorInfo : ConstructorInfo, ISerializable, IRuntimeMethodInfo + { + #region Private Data Members + private volatile RuntimeType m_declaringType; + private RuntimeTypeCache m_reflectedTypeCache; + private string m_toString; + private ParameterInfo[] m_parameters = null; // Created lazily when GetParameters() is called. +#pragma warning disable 169 + private object _empty1; // These empties are used to ensure that RuntimeConstructorInfo and RuntimeMethodInfo are have a layout which is sufficiently similar + private object _empty2; + private object _empty3; +#pragma warning restore 169 + private IntPtr m_handle; + private MethodAttributes m_methodAttributes; + private BindingFlags m_bindingFlags; + private volatile Signature m_signature; + private INVOCATION_FLAGS m_invocationFlags; + +#if FEATURE_APPX + private bool IsNonW8PFrameworkAPI() + { + if (DeclaringType.IsArray && IsPublic && !IsStatic) + return false; + + RuntimeAssembly rtAssembly = GetRuntimeAssembly(); + if (rtAssembly.IsFrameworkAssembly()) + { + int ctorToken = rtAssembly.InvocableAttributeCtorToken; + if (System.Reflection.MetadataToken.IsNullToken(ctorToken) || + !CustomAttribute.IsAttributeDefined(GetRuntimeModule(), MetadataToken, ctorToken)) + return true; + } + + if (GetRuntimeType().IsNonW8PFrameworkAPI()) + return true; + + return false; + } + + internal override bool IsDynamicallyInvokable + { + get + { + return !AppDomain.ProfileAPICheck || !IsNonW8PFrameworkAPI(); + } + } +#endif // FEATURE_APPX + + internal INVOCATION_FLAGS InvocationFlags + { + [System.Security.SecuritySafeCritical] + get + { + if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0) + { + INVOCATION_FLAGS invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_IS_CTOR; // this is a given + + Type declaringType = DeclaringType; + + // + // first take care of all the NO_INVOKE cases. + if ( declaringType == typeof(void) || + (declaringType != null && declaringType.ContainsGenericParameters) || + ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) || + ((Attributes & MethodAttributes.RequireSecObject) == MethodAttributes.RequireSecObject)) + { + // We don't need other flags if this method cannot be invoked + invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE; + } + else if (IsStatic || declaringType != null && declaringType.IsAbstract) + { + invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NO_CTOR_INVOKE; + } + else + { + // 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. + if (typeof(Delegate).IsAssignableFrom(DeclaringType)) + invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_IS_DELEGATE_CTOR; + } + +#if FEATURE_APPX + if (AppDomain.ProfileAPICheck && IsNonW8PFrameworkAPI()) + invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API; +#endif // FEATURE_APPX + + m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED; + } + + return m_invocationFlags; + } + } + #endregion + + #region Constructor + [System.Security.SecurityCritical] // auto-generated + internal RuntimeConstructorInfo( + RuntimeMethodHandleInternal handle, RuntimeType declaringType, RuntimeTypeCache reflectedTypeCache, + MethodAttributes methodAttributes, BindingFlags bindingFlags) + { + Contract.Ensures(methodAttributes == RuntimeMethodHandle.GetAttributes(handle)); + + m_bindingFlags = bindingFlags; + m_reflectedTypeCache = reflectedTypeCache; + m_declaringType = declaringType; + m_handle = handle.Value; + m_methodAttributes = methodAttributes; + } + #endregion + +#if FEATURE_REMOTING + #region Legacy Remoting Cache + // The size of CachedData is accounted for by BaseObjectWithCachedData in object.h. + // This member is currently being used by Remoting for caching remoting data. If you + // need to cache data here, talk to the Remoting team to work out a mechanism, so that + // both caching systems can happily work together. + private RemotingMethodCachedData m_cachedData; + + internal RemotingMethodCachedData RemotingCache + { + get + { + // This grabs an internal copy of m_cachedData and uses + // that instead of looking at m_cachedData directly because + // the cache may get cleared asynchronously. This prevents + // us from having to take a lock. + RemotingMethodCachedData cache = m_cachedData; + if (cache == null) + { + cache = new RemotingMethodCachedData(this); + RemotingMethodCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null); + if (ret != null) + cache = ret; + } + return cache; + } + } + #endregion +#endif //FEATURE_REMOTING + + #region NonPublic Methods + RuntimeMethodHandleInternal IRuntimeMethodInfo.Value + { + [System.Security.SecuritySafeCritical] + get + { + return new RuntimeMethodHandleInternal(m_handle); + } + } + + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + internal override bool CacheEquals(object o) + { + RuntimeConstructorInfo m = o as RuntimeConstructorInfo; + + if ((object)m == null) + return false; + + return m.m_handle == m_handle; + } + + private Signature Signature + { + get + { + if (m_signature == null) + m_signature = new Signature(this, m_declaringType); + + return m_signature; + } + } + + private RuntimeType ReflectedTypeInternal + { + get + { + return m_reflectedTypeCache.GetRuntimeType(); + } + } + + private void CheckConsistency(Object target) + { + if (target == null && IsStatic) + return; + + if (!m_declaringType.IsInstanceOfType(target)) + { + if (target == null) + throw new TargetException(Environment.GetResourceString("RFLCT.Targ_StatMethReqTarg")); + + throw new TargetException(Environment.GetResourceString("RFLCT.Targ_ITargMismatch")); + } + } + + internal BindingFlags BindingFlags { get { return m_bindingFlags; } } + + // Differs from MethodHandle in that it will return a valid handle even for reflection only loaded types + internal RuntimeMethodHandle GetMethodHandle() + { + return new RuntimeMethodHandle(this); + } + + internal bool IsOverloaded + { + get + { + return m_reflectedTypeCache.GetConstructorList(MemberListType.CaseSensitive, Name).Length > 1; + } + } + #endregion + + #region Object Overrides + public override String ToString() + { + // "Void" really doesn't make sense here. But we'll keep it for compat reasons. + if (m_toString == null) + m_toString = "Void " + FormatNameAndSig(); + + return m_toString; + } + #endregion + + #region ICustomAttributeProvider + public override Object[] GetCustomAttributes(bool inherit) + { + return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType"); + + return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public override bool IsDefined(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType"); + + return CustomAttribute.IsDefined(this, attributeRuntimeType); + } + + public override IList GetCustomAttributesData() + { + return CustomAttributeData.GetCustomAttributesInternal(this); + } + #endregion + + + #region MemberInfo Overrides + public override String Name + { + [System.Security.SecuritySafeCritical] // auto-generated + get { return RuntimeMethodHandle.GetName(this); } + } +[System.Runtime.InteropServices.ComVisible(true)] + public override MemberTypes MemberType { get { return MemberTypes.Constructor; } } + + public override Type DeclaringType + { + get + { + return m_reflectedTypeCache.IsGlobal ? null : m_declaringType; + } + } + + public override Type ReflectedType + { + get + { + return m_reflectedTypeCache.IsGlobal ? null : ReflectedTypeInternal; + } + } + + public override int MetadataToken + { + [System.Security.SecuritySafeCritical] // auto-generated + get { return RuntimeMethodHandle.GetMethodDef(this); } + } + public override Module Module + { + get { return GetRuntimeModule(); } + } + + internal RuntimeType GetRuntimeType() { return m_declaringType; } + internal RuntimeModule GetRuntimeModule() { return RuntimeTypeHandle.GetModule(m_declaringType); } + internal RuntimeAssembly GetRuntimeAssembly() { return GetRuntimeModule().GetRuntimeAssembly(); } + #endregion + + #region MethodBase Overrides + + // This seems to always returns System.Void. + internal override Type GetReturnType() { return Signature.ReturnType; } + + [System.Security.SecuritySafeCritical] // auto-generated + internal override ParameterInfo[] GetParametersNoCopy() + { + if (m_parameters == null) + m_parameters = RuntimeParameterInfo.GetParameters(this, this, Signature); + + return m_parameters; + } + + [Pure] + public override ParameterInfo[] GetParameters() + { + ParameterInfo[] parameters = GetParametersNoCopy(); + + if (parameters.Length == 0) + return parameters; + + ParameterInfo[] ret = new ParameterInfo[parameters.Length]; + Array.Copy(parameters, ret, parameters.Length); + return ret; + } + + public override MethodImplAttributes GetMethodImplementationFlags() + { + return RuntimeMethodHandle.GetImplAttributes(this); + } + + public override RuntimeMethodHandle MethodHandle + { + get + { + Type declaringType = DeclaringType; + if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly")); + return new RuntimeMethodHandle(this); + } + } + + public override MethodAttributes Attributes + { + get + { + return m_methodAttributes; + } + } + + public override CallingConventions CallingConvention + { + get + { + return Signature.CallingConvention; + } + } + + internal static void CheckCanCreateInstance(Type declaringType, bool isVarArg) + { + if (declaringType == null) + throw new ArgumentNullException("declaringType"); + Contract.EndContractBlock(); + + // ctor is ReflectOnly + if (declaringType is ReflectionOnlyType) + throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyInvoke")); + + // ctor is declared on interface class + else if (declaringType.IsInterface) + throw new MemberAccessException( + String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Acc_CreateInterfaceEx"), declaringType)); + + // ctor is on an abstract class + else if (declaringType.IsAbstract) + throw new MemberAccessException( + String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Acc_CreateAbstEx"), declaringType)); + + // ctor is on a class that contains stack pointers + else if (declaringType.GetRootElementType() == typeof(ArgIterator)) + throw new NotSupportedException(); + + // ctor is vararg + else if (isVarArg) + throw new NotSupportedException(); + + // ctor is generic or on a generic class + else if (declaringType.ContainsGenericParameters) + { + throw new MemberAccessException( + String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Acc_CreateGenericEx"), declaringType)); + } + + // ctor is declared on System.Void + else if (declaringType == typeof(void)) + throw new MemberAccessException(Environment.GetResourceString("Access_Void")); + } + + internal void ThrowNoInvokeException() + { + CheckCanCreateInstance(DeclaringType, (CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs); + + // ctor is .cctor + if ((Attributes & MethodAttributes.Static) == MethodAttributes.Static) + throw new MemberAccessException(Environment.GetResourceString("Acc_NotClassInit")); + + throw new TargetException(); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public override Object Invoke( + Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) + { + INVOCATION_FLAGS invocationFlags = InvocationFlags; + + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE) != 0) + ThrowNoInvokeException(); + + // check basic method consistency. This call will throw if there are problems in the target/method relationship + CheckConsistency(obj); + +#if FEATURE_APPX + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark); + if (caller != null && !caller.IsSafeForReflection()) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", FullName)); + } +#endif + + if (obj != null) + { + +#if FEATURE_CORECLR + // 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; +#else // FEATURE_CORECLR + new SecurityPermission(SecurityPermissionFlag.SkipVerification).Demand(); +#endif // FEATURE_CORECLR + + } + +#if !FEATURE_CORECLR + if ((invocationFlags &(INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD | INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY)) != 0) + { + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD) != 0) + CodeAccessPermission.Demand(PermissionType.ReflectionMemberAccess); + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) != 0) + RuntimeMethodHandle.PerformSecurityCheck(obj, this, m_declaringType, (uint)m_invocationFlags); + } +#endif // !FEATURE_CORECLR + + Signature sig = Signature; + + // get the signature + int formalCount = sig.Arguments.Length; + int actualCount =(parameters != null) ? parameters.Length : 0; + if (formalCount != actualCount) + throw new TargetParameterCountException(Environment.GetResourceString("Arg_ParmCnt")); + + // if we are here we passed all the previous checks. Time to look at the arguments + if (actualCount > 0) + { + Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig); + Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, sig, false); + // 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); + } + + + [System.Security.SecuritySafeCritical] // overrides SC member +#pragma warning disable 618 + [ReflectionPermissionAttribute(SecurityAction.Demand, Flags = ReflectionPermissionFlag.MemberAccess)] +#pragma warning restore 618 + public override MethodBody GetMethodBody() + { + MethodBody mb = RuntimeMethodHandle.GetMethodBody(this, ReflectedTypeInternal); + if (mb != null) + mb.m_methodBase = this; + return mb; + } + + public override bool IsSecurityCritical + { + get { return RuntimeMethodHandle.IsSecurityCritical(this); } + } + + public override bool IsSecuritySafeCritical + { + get { return RuntimeMethodHandle.IsSecuritySafeCritical(this); } + } + + public override bool IsSecurityTransparent + { + get { return RuntimeMethodHandle.IsSecurityTransparent(this); } + } + + public override bool ContainsGenericParameters + { + get + { + return (DeclaringType != null && DeclaringType.ContainsGenericParameters); + } + } + #endregion + + #region ConstructorInfo Overrides + [System.Security.SecuritySafeCritical] // auto-generated + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public override Object Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) + { + INVOCATION_FLAGS invocationFlags = InvocationFlags; + + // get the declaring TypeHandle early for consistent exceptions in IntrospectionOnly context + RuntimeTypeHandle declaringTypeHandle = m_declaringType.TypeHandle; + + if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE | INVOCATION_FLAGS.INVOCATION_FLAGS_CONTAINS_STACK_POINTERS | INVOCATION_FLAGS.INVOCATION_FLAGS_NO_CTOR_INVOKE)) != 0) + ThrowNoInvokeException(); + +#if FEATURE_APPX + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark); + if (caller != null && !caller.IsSafeForReflection()) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", FullName)); + } +#endif + +#if !FEATURE_CORECLR + if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD | INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY | INVOCATION_FLAGS.INVOCATION_FLAGS_IS_DELEGATE_CTOR)) != 0) + { + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD) != 0) + CodeAccessPermission.Demand(PermissionType.ReflectionMemberAccess); + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) != 0) + RuntimeMethodHandle.PerformSecurityCheck(null, this, m_declaringType, (uint)(m_invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_CONSTRUCTOR_INVOKE)); + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_IS_DELEGATE_CTOR) != 0) + new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); + } +#endif // !FEATURE_CORECLR + + // get the signature + Signature sig = Signature; + + int formalCount = sig.Arguments.Length; + int actualCount =(parameters != null) ? parameters.Length : 0; + if (formalCount != actualCount) + throw new TargetParameterCountException(Environment.GetResourceString("Arg_ParmCnt")); + + // We don't need to explicitly invoke the class constructor here, + // 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 + if (actualCount > 0) + { + Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig); + Object retValue = RuntimeMethodHandle.InvokeMethod(null, arguments, sig, true); + // 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); + } + #endregion + + #region ISerializable Implementation + [System.Security.SecurityCritical] // auto-generated + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException("info"); + Contract.EndContractBlock(); + MemberInfoSerializationHolder.GetSerializationInfo( + info, + Name, + ReflectedTypeInternal, + ToString(), + SerializationToString(), + MemberTypes.Constructor, + null); + } + + internal string SerializationToString() + { + // We don't need the return type for constructors. + return FormatNameAndSig(true); + } + + internal void SerializationInvoke(Object target, SerializationInfo info, StreamingContext context) + { + RuntimeMethodHandle.SerializationInvoke(this, target, info, ref context); + } + #endregion + } + +} diff --git a/src/mscorlib/src/System/Reflection/CustomAttribute.cs b/src/mscorlib/src/System/Reflection/CustomAttribute.cs new file mode 100644 index 0000000000..463c976357 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/CustomAttribute.cs @@ -0,0 +1,2527 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using System.Collections.Generic; +using System.Resources; +using System.Diagnostics; +using System.Diagnostics.Tracing; +using System.Globalization; +using System.Security; +using System.Security.Permissions; +using System.Runtime.ConstrainedExecution; +using System.Runtime.Versioning; +using System.Diagnostics.Contracts; + +namespace System.Reflection +{ + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public class CustomAttributeData + { + #region Public Static Members + public static IList GetCustomAttributes(MemberInfo target) + { + if (target == null) + throw new ArgumentNullException("target"); + + return target.GetCustomAttributesData(); + } + + public static IList GetCustomAttributes(Module target) + { + if (target == null) + throw new ArgumentNullException("target"); + Contract.EndContractBlock(); + + return target.GetCustomAttributesData(); + } + + public static IList GetCustomAttributes(Assembly target) + { + if (target == null) + throw new ArgumentNullException("target"); + Contract.EndContractBlock(); + + return target.GetCustomAttributesData(); + } + + public static IList GetCustomAttributes(ParameterInfo target) + { + if (target == null) + throw new ArgumentNullException("target"); + Contract.EndContractBlock(); + + return target.GetCustomAttributesData(); + } + #endregion + + #region Internal Static Members + [System.Security.SecuritySafeCritical] // auto-generated + internal static IList GetCustomAttributesInternal(RuntimeType target) + { + Contract.Assert(target != null); + + IList cad = GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken); + + int pcaCount = 0; + Attribute[] a = PseudoCustomAttribute.GetCustomAttributes((RuntimeType)target, typeof(object) as RuntimeType, true, out pcaCount); + + if (pcaCount == 0) + return cad; + + CustomAttributeData[] pca = new CustomAttributeData[cad.Count + pcaCount]; + cad.CopyTo(pca, pcaCount); + for (int i = 0; i < pcaCount; i++) + { + pca[i] = new CustomAttributeData(a[i]); + } + + return Array.AsReadOnly(pca); + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static IList GetCustomAttributesInternal(RuntimeFieldInfo target) + { + Contract.Assert(target != null); + + IList cad = GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken); + + int pcaCount = 0; + Attribute[] a = PseudoCustomAttribute.GetCustomAttributes((RuntimeFieldInfo)target, typeof(object) as RuntimeType, out pcaCount); + + if (pcaCount == 0) + return cad; + + CustomAttributeData[] pca = new CustomAttributeData[cad.Count + pcaCount]; + cad.CopyTo(pca, pcaCount); + for (int i = 0; i < pcaCount; i++) + { + pca[i] = new CustomAttributeData(a[i]); + } + + return Array.AsReadOnly(pca); + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static IList GetCustomAttributesInternal(RuntimeMethodInfo target) + { + Contract.Assert(target != null); + + IList cad = GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken); + + int pcaCount = 0; + Attribute[] a = PseudoCustomAttribute.GetCustomAttributes((RuntimeMethodInfo)target, typeof(object) as RuntimeType, true, out pcaCount); + + if (pcaCount == 0) + return cad; + + CustomAttributeData[] pca = new CustomAttributeData[cad.Count + pcaCount]; + cad.CopyTo(pca, pcaCount); + for (int i = 0; i < pcaCount; i++) + { + pca[i] = new CustomAttributeData(a[i]); + } + + return Array.AsReadOnly(pca); + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static IList GetCustomAttributesInternal(RuntimeConstructorInfo target) + { + Contract.Assert(target != null); + + return GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken); + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static IList GetCustomAttributesInternal(RuntimeEventInfo target) + { + Contract.Assert(target != null); + + return GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken); + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static IList GetCustomAttributesInternal(RuntimePropertyInfo target) + { + Contract.Assert(target != null); + + return GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken); + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static IList GetCustomAttributesInternal(RuntimeModule target) + { + Contract.Assert(target != null); + + if (target.IsResource()) + return new List(); + + return GetCustomAttributes(target, target.MetadataToken); + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static IList GetCustomAttributesInternal(RuntimeAssembly target) + { + Contract.Assert(target != null); + + IList cad = GetCustomAttributes((RuntimeModule)target.ManifestModule, RuntimeAssembly.GetToken(target.GetNativeHandle())); + + int pcaCount = 0; + Attribute[] a = PseudoCustomAttribute.GetCustomAttributes(target, typeof(object) as RuntimeType, false, out pcaCount); + + if (pcaCount == 0) + return cad; + + CustomAttributeData[] pca = new CustomAttributeData[cad.Count + pcaCount]; + cad.CopyTo(pca, pcaCount); + for (int i = 0; i < pcaCount; i++) + { + pca[i] = new CustomAttributeData(a[i]); + } + + return Array.AsReadOnly(pca); + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static IList GetCustomAttributesInternal(RuntimeParameterInfo target) + { + Contract.Assert(target != null); + + IList cad = GetCustomAttributes(target.GetRuntimeModule(), target.MetadataToken); + + int pcaCount = 0; + Attribute[] a = PseudoCustomAttribute.GetCustomAttributes(target, typeof(object) as RuntimeType, out pcaCount); + + if (pcaCount == 0) + return cad; + + CustomAttributeData[] pca = new CustomAttributeData[cad.Count + pcaCount]; + cad.CopyTo(pca, pcaCount); + for (int i = 0; i < pcaCount; i++) + pca[i] = new CustomAttributeData(a[i]); + + return Array.AsReadOnly(pca); + } + #endregion + + #region Private Static Methods + private static CustomAttributeEncoding TypeToCustomAttributeEncoding(RuntimeType type) + { + if (type == (RuntimeType)typeof(int)) + return CustomAttributeEncoding.Int32; + + if (type.IsEnum) + return CustomAttributeEncoding.Enum; + + if (type == (RuntimeType)typeof(string)) + return CustomAttributeEncoding.String; + + if (type == (RuntimeType)typeof(Type)) + return CustomAttributeEncoding.Type; + + if (type == (RuntimeType)typeof(object)) + return CustomAttributeEncoding.Object; + + if (type.IsArray) + return CustomAttributeEncoding.Array; + + if (type == (RuntimeType)typeof(char)) + return CustomAttributeEncoding.Char; + + if (type == (RuntimeType)typeof(bool)) + return CustomAttributeEncoding.Boolean; + + if (type == (RuntimeType)typeof(byte)) + return CustomAttributeEncoding.Byte; + + if (type == (RuntimeType)typeof(sbyte)) + return CustomAttributeEncoding.SByte; + + if (type == (RuntimeType)typeof(short)) + return CustomAttributeEncoding.Int16; + + if (type == (RuntimeType)typeof(ushort)) + return CustomAttributeEncoding.UInt16; + + if (type == (RuntimeType)typeof(uint)) + return CustomAttributeEncoding.UInt32; + + if (type == (RuntimeType)typeof(long)) + return CustomAttributeEncoding.Int64; + + if (type == (RuntimeType)typeof(ulong)) + return CustomAttributeEncoding.UInt64; + + if (type == (RuntimeType)typeof(float)) + return CustomAttributeEncoding.Float; + + if (type == (RuntimeType)typeof(double)) + return CustomAttributeEncoding.Double; + + // System.Enum is neither an Enum nor a Class + if (type == (RuntimeType)typeof(Enum)) + return CustomAttributeEncoding.Object; + + if (type.IsClass) + return CustomAttributeEncoding.Object; + + if (type.IsInterface) + return CustomAttributeEncoding.Object; + + if (type.IsValueType) + return CustomAttributeEncoding.Undefined; + + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidKindOfTypeForCA"), "type"); + } + private static CustomAttributeType InitCustomAttributeType(RuntimeType parameterType) + { + CustomAttributeEncoding encodedType = CustomAttributeData.TypeToCustomAttributeEncoding(parameterType); + CustomAttributeEncoding encodedArrayType = CustomAttributeEncoding.Undefined; + CustomAttributeEncoding encodedEnumType = CustomAttributeEncoding.Undefined; + string enumName = null; + + if (encodedType == CustomAttributeEncoding.Array) + { + parameterType = (RuntimeType)parameterType.GetElementType(); + encodedArrayType = CustomAttributeData.TypeToCustomAttributeEncoding(parameterType); + } + + if (encodedType == CustomAttributeEncoding.Enum || encodedArrayType == CustomAttributeEncoding.Enum) + { + encodedEnumType = TypeToCustomAttributeEncoding((RuntimeType)Enum.GetUnderlyingType(parameterType)); + enumName = parameterType.AssemblyQualifiedName; + } + + return new CustomAttributeType(encodedType, encodedArrayType, encodedEnumType, enumName); + } + [System.Security.SecurityCritical] // auto-generated + private static IList GetCustomAttributes(RuntimeModule module, int tkTarget) + { + CustomAttributeRecord[] records = GetCustomAttributeRecords(module, tkTarget); + + CustomAttributeData[] customAttributes = new CustomAttributeData[records.Length]; + for (int i = 0; i < records.Length; i++) + customAttributes[i] = new CustomAttributeData(module, records[i]); + + return Array.AsReadOnly(customAttributes); + } + #endregion + + #region Internal Static Members + [System.Security.SecurityCritical] // auto-generated + internal unsafe static CustomAttributeRecord[] GetCustomAttributeRecords(RuntimeModule module, int targetToken) + { + MetadataImport scope = module.MetadataImport; + + MetadataEnumResult tkCustomAttributeTokens; + scope.EnumCustomAttributes(targetToken, out tkCustomAttributeTokens); + + if (tkCustomAttributeTokens.Length == 0) + { + return Array.Empty(); + } + + CustomAttributeRecord[] records = new CustomAttributeRecord[tkCustomAttributeTokens.Length]; + + for (int i = 0; i < records.Length; i++) + { + scope.GetCustomAttributeProps( + tkCustomAttributeTokens[i], out records[i].tkCtor.Value, out records[i].blob); + } + + return records; + } + + internal static CustomAttributeTypedArgument Filter(IList attrs, Type caType, int parameter) + { + for (int i = 0; i < attrs.Count; i++) + { + if (attrs[i].Constructor.DeclaringType == caType) + { + return attrs[i].ConstructorArguments[parameter]; + } + } + + return new CustomAttributeTypedArgument(); + } + #endregion + + #region Private Data Members + private ConstructorInfo m_ctor; + private RuntimeModule m_scope; + private MemberInfo[] m_members; + private CustomAttributeCtorParameter[] m_ctorParams; + private CustomAttributeNamedParameter[] m_namedParams; + private IList m_typedCtorArgs; + private IList m_namedArgs; + #endregion + + #region Constructor + protected CustomAttributeData() + { + } + + [System.Security.SecuritySafeCritical] // auto-generated + private CustomAttributeData(RuntimeModule scope, CustomAttributeRecord caRecord) + { + m_scope = scope; + m_ctor = (RuntimeConstructorInfo)RuntimeType.GetMethodBase(scope, caRecord.tkCtor); + + ParameterInfo[] parameters = m_ctor.GetParametersNoCopy(); + m_ctorParams = new CustomAttributeCtorParameter[parameters.Length]; + for (int i = 0; i < parameters.Length; i++) + m_ctorParams[i] = new CustomAttributeCtorParameter(InitCustomAttributeType((RuntimeType)parameters[i].ParameterType)); + + FieldInfo[] fields = m_ctor.DeclaringType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + PropertyInfo[] properties = m_ctor.DeclaringType.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + m_namedParams = new CustomAttributeNamedParameter[properties.Length + fields.Length]; + for (int i = 0; i < fields.Length; i++) + m_namedParams[i] = new CustomAttributeNamedParameter( + fields[i].Name, CustomAttributeEncoding.Field, InitCustomAttributeType((RuntimeType)fields[i].FieldType)); + for (int i = 0; i < properties.Length; i++) + m_namedParams[i + fields.Length] = new CustomAttributeNamedParameter( + properties[i].Name, CustomAttributeEncoding.Property, InitCustomAttributeType((RuntimeType)properties[i].PropertyType)); + + m_members = new MemberInfo[fields.Length + properties.Length]; + fields.CopyTo(m_members, 0); + properties.CopyTo(m_members, fields.Length); + + CustomAttributeEncodedArgument.ParseAttributeArguments(caRecord.blob, ref m_ctorParams, ref m_namedParams, m_scope); + } + #endregion + + #region Pseudo Custom Attribute Constructor + internal CustomAttributeData(Attribute attribute) + { + if (attribute is DllImportAttribute) + Init((DllImportAttribute)attribute); + else if (attribute is FieldOffsetAttribute) + Init((FieldOffsetAttribute)attribute); + else if (attribute is MarshalAsAttribute) + Init((MarshalAsAttribute)attribute); + else if (attribute is TypeForwardedToAttribute) + Init((TypeForwardedToAttribute)attribute); + else + Init(attribute); + } + private void Init(DllImportAttribute dllImport) + { + Type type = typeof(DllImportAttribute); + m_ctor = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance)[0]; + m_typedCtorArgs = Array.AsReadOnly(new CustomAttributeTypedArgument[] + { + new CustomAttributeTypedArgument(dllImport.Value), + }); + + m_namedArgs = Array.AsReadOnly(new CustomAttributeNamedArgument[] + { + new CustomAttributeNamedArgument(type.GetField("EntryPoint"), dllImport.EntryPoint), + new CustomAttributeNamedArgument(type.GetField("CharSet"), dllImport.CharSet), + new CustomAttributeNamedArgument(type.GetField("ExactSpelling"), dllImport.ExactSpelling), + new CustomAttributeNamedArgument(type.GetField("SetLastError"), dllImport.SetLastError), + new CustomAttributeNamedArgument(type.GetField("PreserveSig"), dllImport.PreserveSig), + new CustomAttributeNamedArgument(type.GetField("CallingConvention"), dllImport.CallingConvention), + new CustomAttributeNamedArgument(type.GetField("BestFitMapping"), dllImport.BestFitMapping), + new CustomAttributeNamedArgument(type.GetField("ThrowOnUnmappableChar"), dllImport.ThrowOnUnmappableChar) + + }); + } + private void Init(FieldOffsetAttribute fieldOffset) + { + m_ctor = typeof(FieldOffsetAttribute).GetConstructors(BindingFlags.Public | BindingFlags.Instance)[0]; + m_typedCtorArgs = Array.AsReadOnly(new CustomAttributeTypedArgument[] { + new CustomAttributeTypedArgument(fieldOffset.Value) + }); + m_namedArgs = Array.AsReadOnly(Array.Empty()); + } + private void Init(MarshalAsAttribute marshalAs) + { + Type type = typeof(MarshalAsAttribute); + m_ctor = type.GetConstructors(BindingFlags.Public | BindingFlags.Instance)[0]; + m_typedCtorArgs = Array.AsReadOnly(new CustomAttributeTypedArgument[] + { + new CustomAttributeTypedArgument(marshalAs.Value), + }); + + int i = 3; // ArraySubType, SizeParamIndex, SizeConst + if (marshalAs.MarshalType != null) i++; + if (marshalAs.MarshalTypeRef != null) i++; + if (marshalAs.MarshalCookie != null) i++; + i++; // IidParameterIndex + i++; // SafeArraySubType + if (marshalAs.SafeArrayUserDefinedSubType != null) i++; + CustomAttributeNamedArgument[] namedArgs = new CustomAttributeNamedArgument[i]; + + // For compatibility with previous runtimes, we always include the following 5 attributes, regardless + // of if they apply to the UnmanagedType being marshaled or not. + i = 0; + namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("ArraySubType"), marshalAs.ArraySubType); + namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("SizeParamIndex"), marshalAs.SizeParamIndex); + namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("SizeConst"), marshalAs.SizeConst); + namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("IidParameterIndex"), marshalAs.IidParameterIndex); + namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("SafeArraySubType"), marshalAs.SafeArraySubType); + if (marshalAs.MarshalType != null) + namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("MarshalType"), marshalAs.MarshalType); + if (marshalAs.MarshalTypeRef != null) + namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("MarshalTypeRef"), marshalAs.MarshalTypeRef); + if (marshalAs.MarshalCookie != null) + namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("MarshalCookie"), marshalAs.MarshalCookie); + if (marshalAs.SafeArrayUserDefinedSubType != null) + namedArgs[i++] = new CustomAttributeNamedArgument(type.GetField("SafeArrayUserDefinedSubType"), marshalAs.SafeArrayUserDefinedSubType); + + m_namedArgs = Array.AsReadOnly(namedArgs); + } + private void Init(TypeForwardedToAttribute forwardedTo) + { + Type type = typeof(TypeForwardedToAttribute); + + Type[] sig = new Type[] { typeof(Type) }; + m_ctor = type.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, sig, null); + + CustomAttributeTypedArgument[] typedArgs = new CustomAttributeTypedArgument[1]; + typedArgs[0] = new CustomAttributeTypedArgument(typeof(Type), forwardedTo.Destination); + m_typedCtorArgs = Array.AsReadOnly(typedArgs); + + CustomAttributeNamedArgument[] namedArgs = Array.Empty(); + m_namedArgs = Array.AsReadOnly(namedArgs); + } + private void Init(object pca) + { + m_ctor = pca.GetType().GetConstructors(BindingFlags.Public | BindingFlags.Instance)[0]; + m_typedCtorArgs = Array.AsReadOnly(Array.Empty()); + m_namedArgs = Array.AsReadOnly(Array.Empty()); + } + #endregion + + #region Object Override + public override string ToString() + { + string ctorArgs = ""; + for (int i = 0; i < ConstructorArguments.Count; i ++) + ctorArgs += String.Format(CultureInfo.CurrentCulture, i == 0 ? "{0}" : ", {0}", ConstructorArguments[i]); + + string namedArgs = ""; + for (int i = 0; i < NamedArguments.Count; i ++) + namedArgs += String.Format(CultureInfo.CurrentCulture, i == 0 && ctorArgs.Length == 0 ? "{0}" : ", {0}", NamedArguments[i]); + + return String.Format(CultureInfo.CurrentCulture, "[{0}({1}{2})]", Constructor.DeclaringType.FullName, ctorArgs, namedArgs); + } + public override int GetHashCode() + { + return base.GetHashCode(); + } + public override bool Equals(object obj) + { + return obj == (object)this; + } + #endregion + + #region Public Members + public Type AttributeType { get { return Constructor.DeclaringType; } } + + [System.Runtime.InteropServices.ComVisible(true)] + public virtual ConstructorInfo Constructor { get { return m_ctor; } } + + [System.Runtime.InteropServices.ComVisible(true)] + public virtual IList ConstructorArguments + { + get + { + if (m_typedCtorArgs == null) + { + CustomAttributeTypedArgument[] typedCtorArgs = new CustomAttributeTypedArgument[m_ctorParams.Length]; + + for (int i = 0; i < typedCtorArgs.Length; i++) + { + CustomAttributeEncodedArgument encodedArg = m_ctorParams[i].CustomAttributeEncodedArgument; + + typedCtorArgs[i] = new CustomAttributeTypedArgument(m_scope, m_ctorParams[i].CustomAttributeEncodedArgument); + } + + m_typedCtorArgs = Array.AsReadOnly(typedCtorArgs); + } + + return m_typedCtorArgs; + } + } + + public virtual IList NamedArguments + { + get + { + if (m_namedArgs == null) + { + if (m_namedParams == null) + return null; + + int cNamedArgs = 0; + for (int i = 0; i < m_namedParams.Length; i++) + { + if (m_namedParams[i].EncodedArgument.CustomAttributeType.EncodedType != CustomAttributeEncoding.Undefined) + cNamedArgs++; + } + + CustomAttributeNamedArgument[] namedArgs = new CustomAttributeNamedArgument[cNamedArgs]; + + for (int i = 0, j = 0; i < m_namedParams.Length; i++) + { + if (m_namedParams[i].EncodedArgument.CustomAttributeType.EncodedType != CustomAttributeEncoding.Undefined) + namedArgs[j++] = new CustomAttributeNamedArgument( + m_members[i], new CustomAttributeTypedArgument(m_scope, m_namedParams[i].EncodedArgument)); + } + + m_namedArgs = Array.AsReadOnly(namedArgs); + } + + return m_namedArgs; + } + } + #endregion + } + + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public struct CustomAttributeNamedArgument + { + #region Public Static Members + public static bool operator ==(CustomAttributeNamedArgument left, CustomAttributeNamedArgument right) + { + return left.Equals(right); + } + public static bool operator !=(CustomAttributeNamedArgument left, CustomAttributeNamedArgument right) + { + return !left.Equals(right); + } + #endregion + + #region Private Data Members + private MemberInfo m_memberInfo; + private CustomAttributeTypedArgument m_value; + #endregion + + #region Constructor + public CustomAttributeNamedArgument(MemberInfo memberInfo, object value) + { + if (memberInfo == null) + throw new ArgumentNullException("memberInfo"); + + Type type = null; + FieldInfo field = memberInfo as FieldInfo; + PropertyInfo property = memberInfo as PropertyInfo; + + if (field != null) + type = field.FieldType; + else if (property != null) + type = property.PropertyType; + else + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidMemberForNamedArgument")); + + m_memberInfo = memberInfo; + m_value = new CustomAttributeTypedArgument(type, value); + } + + public CustomAttributeNamedArgument(MemberInfo memberInfo, CustomAttributeTypedArgument typedArgument) + { + if (memberInfo == null) + throw new ArgumentNullException("memberInfo"); + + m_memberInfo = memberInfo; + m_value = typedArgument; + } + #endregion + + #region Object Override + public override string ToString() + { + if (m_memberInfo == null) + return base.ToString(); + + return String.Format(CultureInfo.CurrentCulture, "{0} = {1}", MemberInfo.Name, TypedValue.ToString(ArgumentType != typeof(object))); + } + public override int GetHashCode() + { + return base.GetHashCode(); + } + public override bool Equals(object obj) + { + return obj == (object)this; + } + #endregion + + #region Internal Members + internal Type ArgumentType + { + get + { + return m_memberInfo is FieldInfo ? + ((FieldInfo)m_memberInfo).FieldType : + ((PropertyInfo)m_memberInfo).PropertyType; + } + } + #endregion + + #region Public Members + public MemberInfo MemberInfo { get { return m_memberInfo; } } + public CustomAttributeTypedArgument TypedValue { get { return m_value; } } + public string MemberName { get { return MemberInfo.Name; } } + public bool IsField { get { return MemberInfo is FieldInfo; } } + #endregion + + } + + [Serializable] + [ComVisible(true)] + public struct CustomAttributeTypedArgument + { + #region Public Static Members + public static bool operator ==(CustomAttributeTypedArgument left, CustomAttributeTypedArgument right) + { + return left.Equals(right); + } + public static bool operator !=(CustomAttributeTypedArgument left, CustomAttributeTypedArgument right) + { + return !left.Equals(right); + } + #endregion + + #region Private Static Methods + private static Type CustomAttributeEncodingToType(CustomAttributeEncoding encodedType) + { + switch (encodedType) + { + case (CustomAttributeEncoding.Enum): + return typeof(Enum); + + case (CustomAttributeEncoding.Int32): + return typeof(int); + + case (CustomAttributeEncoding.String): + return typeof(string); + + case (CustomAttributeEncoding.Type): + return typeof(Type); + + case (CustomAttributeEncoding.Array): + return typeof(Array); + + case (CustomAttributeEncoding.Char): + return typeof(char); + + case (CustomAttributeEncoding.Boolean): + return typeof(bool); + + case (CustomAttributeEncoding.SByte): + return typeof(sbyte); + + case (CustomAttributeEncoding.Byte): + return typeof(byte); + + case (CustomAttributeEncoding.Int16): + return typeof(short); + + case (CustomAttributeEncoding.UInt16): + return typeof(ushort); + + case (CustomAttributeEncoding.UInt32): + return typeof(uint); + + case (CustomAttributeEncoding.Int64): + return typeof(long); + + case (CustomAttributeEncoding.UInt64): + return typeof(ulong); + + case (CustomAttributeEncoding.Float): + return typeof(float); + + case (CustomAttributeEncoding.Double): + return typeof(double); + + case (CustomAttributeEncoding.Object): + return typeof(object); + + default : + throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)encodedType), "encodedType"); + } + } + + [SecuritySafeCritical] + private static object EncodedValueToRawValue(long val, CustomAttributeEncoding encodedType) + { + switch (encodedType) + { + case CustomAttributeEncoding.Boolean: + return (byte)val != 0; + + case CustomAttributeEncoding.Char: + return (char)val; + + case CustomAttributeEncoding.Byte: + return (byte)val; + + case CustomAttributeEncoding.SByte: + return (sbyte)val; + + case CustomAttributeEncoding.Int16: + return (short)val; + + case CustomAttributeEncoding.UInt16: + return (ushort)val; + + case CustomAttributeEncoding.Int32: + return (int)val; + + case CustomAttributeEncoding.UInt32: + return (uint)val; + + case CustomAttributeEncoding.Int64: + return (long)val; + + case CustomAttributeEncoding.UInt64: + return (ulong)val; + + case CustomAttributeEncoding.Float: + unsafe { return *(float*)&val; } + + case CustomAttributeEncoding.Double: + unsafe { return *(double*)&val; } + + default: + throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)val), "val"); + } + } + private static RuntimeType ResolveType(RuntimeModule scope, string typeName) + { + RuntimeType type = RuntimeTypeHandle.GetTypeByNameUsingCARules(typeName, scope); + + if (type == null) + throw new InvalidOperationException( + String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_CATypeResolutionFailed"), typeName)); + + return type; + } + #endregion + + #region Private Data Members + private object m_value; + private Type m_argumentType; + #endregion + + #region Constructor + public CustomAttributeTypedArgument(Type argumentType, object value) + { + // value can be null. + if (argumentType == null) + throw new ArgumentNullException("argumentType"); + + m_value = (value == null) ? null : CanonicalizeValue(value); + m_argumentType = argumentType; + } + + public CustomAttributeTypedArgument(object value) + { + // value cannot be null. + if (value == null) + throw new ArgumentNullException("value"); + + m_value = CanonicalizeValue(value); + m_argumentType = value.GetType(); + } + + private static object CanonicalizeValue(object value) + { + Contract.Assert(value != null); + + if (value.GetType().IsEnum) + { + return ((Enum)value).GetValue(); + } + return value; + } + + internal CustomAttributeTypedArgument(RuntimeModule scope, CustomAttributeEncodedArgument encodedArg) + { + CustomAttributeEncoding encodedType = encodedArg.CustomAttributeType.EncodedType; + + if (encodedType == CustomAttributeEncoding.Undefined) + throw new ArgumentException("encodedArg"); + + else if (encodedType == CustomAttributeEncoding.Enum) + { + m_argumentType = ResolveType(scope, encodedArg.CustomAttributeType.EnumName); + m_value = EncodedValueToRawValue(encodedArg.PrimitiveValue, encodedArg.CustomAttributeType.EncodedEnumType); + } + else if (encodedType == CustomAttributeEncoding.String) + { + m_argumentType = typeof(string); + m_value = encodedArg.StringValue; + } + else if (encodedType == CustomAttributeEncoding.Type) + { + m_argumentType = typeof(Type); + + m_value = null; + + if (encodedArg.StringValue != null) + m_value = ResolveType(scope, encodedArg.StringValue); + } + else if (encodedType == CustomAttributeEncoding.Array) + { + encodedType = encodedArg.CustomAttributeType.EncodedArrayType; + Type elementType; + + if (encodedType == CustomAttributeEncoding.Enum) + { + elementType = ResolveType(scope, encodedArg.CustomAttributeType.EnumName); + } + else + { + elementType = CustomAttributeEncodingToType(encodedType); + } + + m_argumentType = elementType.MakeArrayType(); + + if (encodedArg.ArrayValue == null) + { + m_value = null; + } + else + { + CustomAttributeTypedArgument[] arrayValue = new CustomAttributeTypedArgument[encodedArg.ArrayValue.Length]; + for (int i = 0; i < arrayValue.Length; i++) + arrayValue[i] = new CustomAttributeTypedArgument(scope, encodedArg.ArrayValue[i]); + + m_value = Array.AsReadOnly(arrayValue); + } + } + else + { + m_argumentType = CustomAttributeEncodingToType(encodedType); + m_value = EncodedValueToRawValue(encodedArg.PrimitiveValue, encodedType); + } + } + #endregion + + #region Object Overrides + public override string ToString() { return ToString(false); } + + internal string ToString(bool typed) + { + if (m_argumentType == null) + return base.ToString(); + + if (ArgumentType.IsEnum) + return String.Format(CultureInfo.CurrentCulture, typed ? "{0}" : "({1}){0}", Value, ArgumentType.FullName); + + else if (Value == null) + return String.Format(CultureInfo.CurrentCulture, typed ? "null" : "({0})null", ArgumentType.Name); + + else if (ArgumentType == typeof(string)) + return String.Format(CultureInfo.CurrentCulture, "\"{0}\"", Value); + + else if (ArgumentType == typeof(char)) + return String.Format(CultureInfo.CurrentCulture, "'{0}'", Value); + + else if (ArgumentType == typeof(Type)) + return String.Format(CultureInfo.CurrentCulture, "typeof({0})", ((Type)Value).FullName); + + else if (ArgumentType.IsArray) + { + string result = null; + IList array = Value as IList; + + Type elementType = ArgumentType.GetElementType(); + result = String.Format(CultureInfo.CurrentCulture, @"new {0}[{1}] {{ ", elementType.IsEnum ? elementType.FullName : elementType.Name, array.Count); + + for (int i = 0; i < array.Count; i++) + result += String.Format(CultureInfo.CurrentCulture, i == 0 ? "{0}" : ", {0}", array[i].ToString(elementType != typeof(object))); + + return result += " }"; + } + + return String.Format(CultureInfo.CurrentCulture, typed ? "{0}" : "({1}){0}", Value, ArgumentType.Name); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + public override bool Equals(object obj) + { + return obj == (object)this; + } + #endregion + + #region Public Members + public Type ArgumentType + { + get + { + return m_argumentType; + } + } + public object Value + { + get + { + return m_value; + } + } + #endregion + } + + [Serializable] + internal struct CustomAttributeRecord + { + internal ConstArray blob; + internal MetadataToken tkCtor; + } + + [Serializable] + internal enum CustomAttributeEncoding : int + { + Undefined = 0, + Boolean = CorElementType.Boolean, + Char = CorElementType.Char, + SByte = CorElementType.I1, + Byte = CorElementType.U1, + Int16 = CorElementType.I2, + UInt16 = CorElementType.U2, + Int32 = CorElementType.I4, + UInt32 = CorElementType.U4, + Int64 = CorElementType.I8, + UInt64 = CorElementType.U8, + Float = CorElementType.R4, + Double = CorElementType.R8, + String = CorElementType.String, + Array = CorElementType.SzArray, + Type = 0x50, + Object = 0x51, + Field = 0x53, + Property = 0x54, + Enum = 0x55 + } + + [Serializable] + [StructLayout(LayoutKind.Auto)] + internal struct CustomAttributeEncodedArgument + { + #region Parser + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern void ParseAttributeArguments( + IntPtr pCa, + int cCa, + ref CustomAttributeCtorParameter[] CustomAttributeCtorParameters, + ref CustomAttributeNamedParameter[] CustomAttributeTypedArgument, + RuntimeAssembly assembly); + + [System.Security.SecurityCritical] // auto-generated + internal static void ParseAttributeArguments(ConstArray attributeBlob, + ref CustomAttributeCtorParameter[] customAttributeCtorParameters, + ref CustomAttributeNamedParameter[] customAttributeNamedParameters, + RuntimeModule customAttributeModule) + { + if (customAttributeModule == null) + throw new ArgumentNullException("customAttributeModule"); + Contract.EndContractBlock(); + + Contract.Assert(customAttributeCtorParameters != null); + Contract.Assert(customAttributeNamedParameters != null); + + if (customAttributeCtorParameters.Length != 0 || customAttributeNamedParameters.Length != 0) + { + unsafe + { + ParseAttributeArguments( + attributeBlob.Signature, + (int)attributeBlob.Length, + ref customAttributeCtorParameters, + ref customAttributeNamedParameters, + (RuntimeAssembly)customAttributeModule.Assembly); + } + } + } + #endregion + + #region Private Data Members + private long m_primitiveValue; + private CustomAttributeEncodedArgument[] m_arrayValue; + private string m_stringValue; + private CustomAttributeType m_type; + #endregion + + #region Public Members + public CustomAttributeType CustomAttributeType { get { return m_type; } } + public long PrimitiveValue { get { return m_primitiveValue; } } + public CustomAttributeEncodedArgument[] ArrayValue { get { return m_arrayValue; } } + public string StringValue { get { return m_stringValue; } } + #endregion + } + + [Serializable] + [StructLayout(LayoutKind.Auto)] + internal struct CustomAttributeNamedParameter + { + #region Private Data Members + private string m_argumentName; + private CustomAttributeEncoding m_fieldOrProperty; + private CustomAttributeEncoding m_padding; + private CustomAttributeType m_type; + private CustomAttributeEncodedArgument m_encodedArgument; + #endregion + + #region Constructor + public CustomAttributeNamedParameter(string argumentName, CustomAttributeEncoding fieldOrProperty, CustomAttributeType type) + { + if (argumentName == null) + throw new ArgumentNullException("argumentName"); + Contract.EndContractBlock(); + + m_argumentName = argumentName; + m_fieldOrProperty = fieldOrProperty; + m_padding = fieldOrProperty; + m_type = type; + m_encodedArgument = new CustomAttributeEncodedArgument(); + } + #endregion + + #region Public Members + public CustomAttributeEncodedArgument EncodedArgument { get { return m_encodedArgument; } } + #endregion + } + + [Serializable] + [StructLayout(LayoutKind.Auto)] + internal struct CustomAttributeCtorParameter + { + #region Private Data Members + private CustomAttributeType m_type; + private CustomAttributeEncodedArgument m_encodedArgument; + #endregion + + #region Constructor + public CustomAttributeCtorParameter(CustomAttributeType type) + { + m_type = type; + m_encodedArgument = new CustomAttributeEncodedArgument(); + } + #endregion + + #region Public Members + public CustomAttributeEncodedArgument CustomAttributeEncodedArgument { get { return m_encodedArgument; } } + #endregion + } + + // Note: This is a managed representation of a frame type defined in vm\frames.h; please ensure the layout remains + // synchronized. + [StructLayout(LayoutKind.Sequential)] + internal struct SecurityContextFrame + { + IntPtr m_GSCookie; // This is actually at a negative offset in the real frame definition + IntPtr __VFN_table; // This is the real start of the SecurityContextFrame + IntPtr m_Next; + IntPtr m_Assembly; + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + public extern void Push(RuntimeAssembly assembly); + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + public extern void Pop(); + } + + [Serializable] + [StructLayout(LayoutKind.Auto)] + internal struct CustomAttributeType + { + #region Private Data Members + /// The most complicated type is an enum[] in which case... + private string m_enumName; // ...enum name + private CustomAttributeEncoding m_encodedType; // ...array + private CustomAttributeEncoding m_encodedEnumType; // ...enum + private CustomAttributeEncoding m_encodedArrayType; // ...enum type + private CustomAttributeEncoding m_padding; + #endregion + + #region Constructor + public CustomAttributeType(CustomAttributeEncoding encodedType, CustomAttributeEncoding encodedArrayType, + CustomAttributeEncoding encodedEnumType, string enumName) + { + m_encodedType = encodedType; + m_encodedArrayType = encodedArrayType; + m_encodedEnumType = encodedEnumType; + m_enumName = enumName; + m_padding = m_encodedType; + } + #endregion + + #region Public Members + public CustomAttributeEncoding EncodedType { get { return m_encodedType; } } + public CustomAttributeEncoding EncodedEnumType { get { return m_encodedEnumType; } } + public CustomAttributeEncoding EncodedArrayType { get { return m_encodedArrayType; } } + [System.Runtime.InteropServices.ComVisible(true)] + public string EnumName { get { return m_enumName; } } + #endregion + } + + internal unsafe static class CustomAttribute + { + #region Private Data Members + private static RuntimeType Type_RuntimeType = (RuntimeType)typeof(RuntimeType); + private static RuntimeType Type_Type = (RuntimeType)typeof(Type); + #endregion + + #region Internal Static Members + [System.Security.SecurityCritical] // auto-generated + internal static bool IsDefined(RuntimeType type, RuntimeType caType, bool inherit) + { + Contract.Requires(type != null); + + if (type.GetElementType() != null) + return false; + + if (PseudoCustomAttribute.IsDefined(type, caType)) + return true; + + if (IsCustomAttributeDefined(type.GetRuntimeModule(), type.MetadataToken, caType)) + return true; + + if (!inherit) + return false; + + type = type.BaseType as RuntimeType; + + while (type != null) + { + if (IsCustomAttributeDefined(type.GetRuntimeModule(), type.MetadataToken, caType, 0, inherit)) + return true; + + type = type.BaseType as RuntimeType; + } + + return false; + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static bool IsDefined(RuntimeMethodInfo method, RuntimeType caType, bool inherit) + { + Contract.Requires(method != null); + Contract.Requires(caType != null); + + if (PseudoCustomAttribute.IsDefined(method, caType)) + return true; + + if (IsCustomAttributeDefined(method.GetRuntimeModule(), method.MetadataToken, caType)) + return true; + + if (!inherit) + return false; + + method = method.GetParentDefinition(); + + while (method != null) + { + if (IsCustomAttributeDefined(method.GetRuntimeModule(), method.MetadataToken, caType, 0, inherit)) + return true; + + method = method.GetParentDefinition(); + } + + return false; + } + + [System.Security.SecurityCritical] // auto-generated + internal static bool IsDefined(RuntimeConstructorInfo ctor, RuntimeType caType) + { + Contract.Requires(ctor != null); + Contract.Requires(caType != null); + + if (PseudoCustomAttribute.IsDefined(ctor, caType)) + return true; + + return IsCustomAttributeDefined(ctor.GetRuntimeModule(), ctor.MetadataToken, caType); + } + + [System.Security.SecurityCritical] // auto-generated + internal static bool IsDefined(RuntimePropertyInfo property, RuntimeType caType) + { + Contract.Requires(property != null); + Contract.Requires(caType != null); + + if (PseudoCustomAttribute.IsDefined(property, caType)) + return true; + + return IsCustomAttributeDefined(property.GetRuntimeModule(), property.MetadataToken, caType); + } + + [System.Security.SecurityCritical] // auto-generated + internal static bool IsDefined(RuntimeEventInfo e, RuntimeType caType) + { + Contract.Requires(e != null); + Contract.Requires(caType != null); + + if (PseudoCustomAttribute.IsDefined(e, caType)) + return true; + + return IsCustomAttributeDefined(e.GetRuntimeModule(), e.MetadataToken, caType); + } + + [System.Security.SecurityCritical] // auto-generated + internal static bool IsDefined(RuntimeFieldInfo field, RuntimeType caType) + { + Contract.Requires(field != null); + Contract.Requires(caType != null); + + if (PseudoCustomAttribute.IsDefined(field, caType)) + return true; + + return IsCustomAttributeDefined(field.GetRuntimeModule(), field.MetadataToken, caType); + } + + [System.Security.SecurityCritical] // auto-generated + internal static bool IsDefined(RuntimeParameterInfo parameter, RuntimeType caType) + { + Contract.Requires(parameter != null); + Contract.Requires(caType != null); + + if (PseudoCustomAttribute.IsDefined(parameter, caType)) + return true; + + return IsCustomAttributeDefined(parameter.GetRuntimeModule(), parameter.MetadataToken, caType); + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static bool IsDefined(RuntimeAssembly assembly, RuntimeType caType) + { + Contract.Requires(assembly != null); + Contract.Requires(caType != null); + + if (PseudoCustomAttribute.IsDefined(assembly, caType)) + return true; + + return IsCustomAttributeDefined(assembly.ManifestModule as RuntimeModule, RuntimeAssembly.GetToken(assembly.GetNativeHandle()), caType); + } + + [System.Security.SecurityCritical] // auto-generated + internal static bool IsDefined(RuntimeModule module, RuntimeType caType) + { + Contract.Requires(module != null); + Contract.Requires(caType != null); + + if (PseudoCustomAttribute.IsDefined(module, caType)) + return true; + + return IsCustomAttributeDefined(module, module.MetadataToken, caType); + } + + [System.Security.SecurityCritical] // auto-generated + internal static Object[] GetCustomAttributes(RuntimeType type, RuntimeType caType, bool inherit) + { + Contract.Requires(type != null); + Contract.Requires(caType != null); + + if (type.GetElementType() != null) + return (caType.IsValueType) ? EmptyArray.Value : CreateAttributeArrayHelper(caType, 0); + + if (type.IsGenericType && !type.IsGenericTypeDefinition) + type = type.GetGenericTypeDefinition() as RuntimeType; + + int pcaCount = 0; + Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(type, caType, true, 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... + // ... however if the attribute is sealed we can rely on the attribute usage + if (!inherit || (caType.IsSealed && !CustomAttribute.GetAttributeUsage(caType).Inherited)) + { + object[] attributes = GetCustomAttributes(type.GetRuntimeModule(), type.MetadataToken, pcaCount, caType, !AllowCriticalCustomAttributes(type)); + if (pcaCount > 0) Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount); + return attributes; + } + + List result = new List(); + bool mustBeInheritable = false; + bool useObjectArray = (caType == null || caType.IsValueType || caType.ContainsGenericParameters); + Type arrayType = useObjectArray ? typeof(object) : caType; + + while (pcaCount > 0) + result.Add(pca[--pcaCount]); + + while (type != (RuntimeType)typeof(object) && type != null) + { + object[] attributes = GetCustomAttributes(type.GetRuntimeModule(), type.MetadataToken, 0, caType, mustBeInheritable, result, !AllowCriticalCustomAttributes(type)); + mustBeInheritable = true; + for (int i = 0; i < attributes.Length; i++) + result.Add(attributes[i]); + + type = type.BaseType as RuntimeType; + } + + object[] typedResult = CreateAttributeArrayHelper(arrayType, result.Count); + Array.Copy(result.ToArray(), 0, typedResult, 0, result.Count); + return typedResult; + } + + private static bool AllowCriticalCustomAttributes(RuntimeType type) + { + if (type.IsGenericParameter) + { + // Generic parameters don't have transparency state, so look at the + // declaring method/type. One of declaringMethod or declaringType + // must be set. + MethodBase declaringMethod = type.DeclaringMethod; + if (declaringMethod != null) + { + return AllowCriticalCustomAttributes(declaringMethod); + } + else + { + type = type.DeclaringType as RuntimeType; + Contract.Assert(type != null); + } + } + + return !type.IsSecurityTransparent || SpecialAllowCriticalAttributes(type); + } + + private static bool SpecialAllowCriticalAttributes(RuntimeType type) + { + // Types participating in Type Equivalence are always transparent. + // See TokenSecurityDescriptor::VerifySemanticDataComputed in securitymeta.cpp. + // Because of that we allow critical attributes applied to full trust equivalent types. + // DeclaringType is null for global methods and fields and the global type never participates in type equivalency. + +#if FEATURE_CORECLR + return false; +#else + return type != null && type.Assembly.IsFullyTrusted && RuntimeTypeHandle.IsEquivalentType(type); +#endif //!FEATURE_CORECLR + } + + private static bool AllowCriticalCustomAttributes(MethodBase method) + { + Contract.Requires(method is RuntimeMethodInfo || method is RuntimeConstructorInfo); + + return !method.IsSecurityTransparent || + SpecialAllowCriticalAttributes((RuntimeType)method.DeclaringType); + } + + private static bool AllowCriticalCustomAttributes(RuntimeFieldInfo field) + { + return !field.IsSecurityTransparent || + SpecialAllowCriticalAttributes((RuntimeType)field.DeclaringType); + } + + private static bool AllowCriticalCustomAttributes(RuntimeParameterInfo parameter) + { + // Since parameters have no transparency state, we look at the defining method instead. + return AllowCriticalCustomAttributes(parameter.DefiningMethod); + } + + [System.Security.SecurityCritical] // auto-generated + internal static Object[] GetCustomAttributes(RuntimeMethodInfo method, RuntimeType caType, bool inherit) + { + Contract.Requires(method != null); + Contract.Requires(caType != null); + + if (method.IsGenericMethod && !method.IsGenericMethodDefinition) + method = method.GetGenericMethodDefinition() as RuntimeMethodInfo; + + int pcaCount = 0; + Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(method, caType, true, 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... + // ... however if the attribute is sealed we can rely on the attribute usage + if (!inherit || (caType.IsSealed && !CustomAttribute.GetAttributeUsage(caType).Inherited)) + { + object[] attributes = GetCustomAttributes(method.GetRuntimeModule(), method.MetadataToken, pcaCount, caType, !AllowCriticalCustomAttributes(method)); + if (pcaCount > 0) Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount); + return attributes; + } + + List result = new List(); + bool mustBeInheritable = false; + bool useObjectArray = (caType == null || caType.IsValueType || caType.ContainsGenericParameters); + Type arrayType = useObjectArray ? typeof(object) : caType; + + while (pcaCount > 0) + result.Add(pca[--pcaCount]); + + while (method != null) + { + object[] attributes = GetCustomAttributes(method.GetRuntimeModule(), method.MetadataToken, 0, caType, mustBeInheritable, result, !AllowCriticalCustomAttributes(method)); + mustBeInheritable = true; + for (int i = 0; i < attributes.Length; i++) + result.Add(attributes[i]); + + method = method.GetParentDefinition(); + } + + object[] typedResult = CreateAttributeArrayHelper(arrayType, result.Count); + Array.Copy(result.ToArray(), 0, typedResult, 0, result.Count); + return typedResult; + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static Object[] GetCustomAttributes(RuntimeConstructorInfo ctor, RuntimeType caType) + { + Contract.Requires(ctor != null); + Contract.Requires(caType != null); + + int pcaCount = 0; + Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(ctor, caType, true, out pcaCount); + object[] attributes = GetCustomAttributes(ctor.GetRuntimeModule(), ctor.MetadataToken, pcaCount, caType, !AllowCriticalCustomAttributes(ctor)); + if (pcaCount > 0) Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount); + return attributes; + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static Object[] GetCustomAttributes(RuntimePropertyInfo property, RuntimeType caType) + { + Contract.Requires(property != null); + Contract.Requires(caType != null); + + int pcaCount = 0; + Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(property, caType, out pcaCount); + // Since properties and events have no transparency state, logically we should check the declaring types. + // But then if someone wanted to apply critical attributes on a property/event he would need to make the type critical, + // which would also implicitly made all the members critical. + // So we check the containing assembly instead. If the assembly can contain critical code we allow critical attributes on properties/events. + bool disallowCriticalCustomAttributes = property.GetRuntimeModule().GetRuntimeAssembly().IsAllSecurityTransparent(); + + object[] attributes = GetCustomAttributes(property.GetRuntimeModule(), property.MetadataToken, pcaCount, caType, disallowCriticalCustomAttributes); + if (pcaCount > 0) Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount); + return attributes; + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static Object[] GetCustomAttributes(RuntimeEventInfo e, RuntimeType caType) + { + Contract.Requires(e != null); + Contract.Requires(caType != null); + + int pcaCount = 0; + Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(e, caType, out pcaCount); + // Since properties and events have no transparency state, logically we should check the declaring types. + // But then if someone wanted to apply critical attributes on a property/event he would need to make the type critical, + // which would also implicitly made all the members critical. + // So we check the containing assembly instead. If the assembly can contain critical code we allow critical attributes on properties/events. + bool disallowCriticalCustomAttributes = e.GetRuntimeModule().GetRuntimeAssembly().IsAllSecurityTransparent(); + object[] attributes = GetCustomAttributes(e.GetRuntimeModule(), e.MetadataToken, pcaCount, caType, disallowCriticalCustomAttributes); + if (pcaCount > 0) Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount); + return attributes; + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static Object[] GetCustomAttributes(RuntimeFieldInfo field, RuntimeType caType) + { + Contract.Requires(field != null); + Contract.Requires(caType != null); + + int pcaCount = 0; + Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(field, caType, out pcaCount); + object[] attributes = GetCustomAttributes(field.GetRuntimeModule(), field.MetadataToken, pcaCount, caType, !AllowCriticalCustomAttributes(field)); + if (pcaCount > 0) Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount); + return attributes; + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static Object[] GetCustomAttributes(RuntimeParameterInfo parameter, RuntimeType caType) + { + Contract.Requires(parameter != null); + Contract.Requires(caType != null); + + int pcaCount = 0; + Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(parameter, caType, out pcaCount); + object[] attributes = GetCustomAttributes(parameter.GetRuntimeModule(), parameter.MetadataToken, pcaCount, caType, !AllowCriticalCustomAttributes(parameter)); + if (pcaCount > 0) Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount); + return attributes; + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static Object[] GetCustomAttributes(RuntimeAssembly assembly, RuntimeType caType) + { + Contract.Requires(assembly != null); + Contract.Requires(caType != null); + + int pcaCount = 0; + Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(assembly, caType, true, out pcaCount); + int assemblyToken = RuntimeAssembly.GetToken(assembly.GetNativeHandle()); + bool isAssemblySecurityTransparent = assembly.IsAllSecurityTransparent(); + object[] attributes = GetCustomAttributes(assembly.ManifestModule as RuntimeModule, assemblyToken, pcaCount, caType, isAssemblySecurityTransparent); + if (pcaCount > 0) Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount); + return attributes; + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal static Object[] GetCustomAttributes(RuntimeModule module, RuntimeType caType) + { + Contract.Requires(module != null); + Contract.Requires(caType != null); + + int pcaCount = 0; + Attribute[] pca = PseudoCustomAttribute.GetCustomAttributes(module, caType, out pcaCount); + bool isModuleSecurityTransparent = module.GetRuntimeAssembly().IsAllSecurityTransparent(); + object[] attributes = GetCustomAttributes(module, module.MetadataToken, pcaCount, caType, isModuleSecurityTransparent); + if (pcaCount > 0) Array.Copy(pca, 0, attributes, attributes.Length - pcaCount, pcaCount); + return attributes; + } + + [System.Security.SecuritySafeCritical] + internal static bool IsAttributeDefined(RuntimeModule decoratedModule, int decoratedMetadataToken, int attributeCtorToken) + { + return IsCustomAttributeDefined(decoratedModule, decoratedMetadataToken, null, attributeCtorToken, false); + } + + [System.Security.SecurityCritical] // auto-generated + private static bool IsCustomAttributeDefined( + RuntimeModule decoratedModule, int decoratedMetadataToken, RuntimeType attributeFilterType) + { + return IsCustomAttributeDefined(decoratedModule, decoratedMetadataToken, attributeFilterType, 0, false); + } + + [System.Security.SecurityCritical] // auto-generated + private static bool IsCustomAttributeDefined( + RuntimeModule decoratedModule, int decoratedMetadataToken, RuntimeType attributeFilterType, int attributeCtorToken, bool mustBeInheritable) + { + if (decoratedModule.Assembly.ReflectionOnly) + throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyCA")); + Contract.EndContractBlock(); + + CustomAttributeRecord[] car = CustomAttributeData.GetCustomAttributeRecords(decoratedModule, decoratedMetadataToken); + + if (attributeFilterType != null) + { + Contract.Assert(attributeCtorToken == 0); + + MetadataImport scope = decoratedModule.MetadataImport; + RuntimeType attributeType; + IRuntimeMethodInfo ctor; + bool ctorHasParameters, isVarArg; + + // Optimization for the case where attributes decorate entities in the same assembly in which case + // we can cache the successful APTCA check between the decorated and the declared assembly. + Assembly lastAptcaOkAssembly = null; + + for (int i = 0; i < car.Length; i++) + { + CustomAttributeRecord caRecord = car[i]; + + if (FilterCustomAttributeRecord(caRecord, scope, ref lastAptcaOkAssembly, + decoratedModule, decoratedMetadataToken, attributeFilterType, mustBeInheritable, null, null, + out attributeType, out ctor, out ctorHasParameters, out isVarArg)) + return true; + } + } + else + { + Contract.Assert(attributeFilterType == null); + Contract.Assert(!MetadataToken.IsNullToken(attributeCtorToken)); + + for (int i = 0; i < car.Length; i++) + { + CustomAttributeRecord caRecord = car[i]; + + if (caRecord.tkCtor == attributeCtorToken) + return true; + } + } + + return false; + } + + [System.Security.SecurityCritical] // auto-generated + private unsafe static object[] GetCustomAttributes( + RuntimeModule decoratedModule, int decoratedMetadataToken, int pcaCount, RuntimeType attributeFilterType, bool isDecoratedTargetSecurityTransparent) + { + return GetCustomAttributes(decoratedModule, decoratedMetadataToken, pcaCount, attributeFilterType, false, null, isDecoratedTargetSecurityTransparent); + } + + [System.Security.SecurityCritical] + private unsafe static object[] GetCustomAttributes( + RuntimeModule decoratedModule, int decoratedMetadataToken, int pcaCount, + RuntimeType attributeFilterType, bool mustBeInheritable, IList derivedAttributes, bool isDecoratedTargetSecurityTransparent) + { + if (decoratedModule.Assembly.ReflectionOnly) + throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyCA")); + Contract.EndContractBlock(); + + MetadataImport scope = decoratedModule.MetadataImport; + CustomAttributeRecord[] car = CustomAttributeData.GetCustomAttributeRecords(decoratedModule, decoratedMetadataToken); + + bool useObjectArray = (attributeFilterType == null || attributeFilterType.IsValueType || attributeFilterType.ContainsGenericParameters); + Type arrayType = useObjectArray ? typeof(object) : attributeFilterType; + + if (attributeFilterType == null && car.Length == 0) + return CreateAttributeArrayHelper(arrayType, 0); + + object[] attributes = CreateAttributeArrayHelper(arrayType, car.Length); + int cAttributes = 0; + + // Custom attribute security checks are done with respect to the assembly *decorated* with the + // custom attribute as opposed to the *caller of GetCustomAttributes*. + // Since this assembly might not be on the stack and the attribute ctor or property setters we're about to invoke may + // make security demands, we push a frame on the stack as a proxy for the decorated assembly (this frame will be picked + // up an interpreted by the security stackwalker). + // Once we push the frame it will be automatically popped in the event of an exception, so no need to use CERs or the + // like. + SecurityContextFrame frame = new SecurityContextFrame(); + frame.Push(decoratedModule.GetRuntimeAssembly()); + + // Optimization for the case where attributes decorate entities in the same assembly in which case + // we can cache the successful APTCA check between the decorated and the declared assembly. + Assembly lastAptcaOkAssembly = null; + + for (int i = 0; i < car.Length; i++) + { + object attribute = null; + CustomAttributeRecord caRecord = car[i]; + + IRuntimeMethodInfo ctor = null; + RuntimeType attributeType = null; + bool ctorHasParameters, isVarArg; + int cNamedArgs = 0; + + IntPtr blobStart = caRecord.blob.Signature; + IntPtr blobEnd = (IntPtr)((byte*)blobStart + caRecord.blob.Length); + int blobLen = (int)((byte*)blobEnd - (byte*)blobStart); + + if (!FilterCustomAttributeRecord(caRecord, scope, ref lastAptcaOkAssembly, + decoratedModule, decoratedMetadataToken, attributeFilterType, mustBeInheritable, + attributes, derivedAttributes, + out attributeType, out ctor, out ctorHasParameters, out isVarArg)) + continue; + + if (ctor != null) + { + // Linktime demand checks + // decoratedMetadataToken needed as it may be "transparent" in which case we do a full stack walk + RuntimeMethodHandle.CheckLinktimeDemands(ctor, decoratedModule, isDecoratedTargetSecurityTransparent); + } + else + { + + } + + // Leverage RuntimeConstructorInfo standard .ctor verfication + RuntimeConstructorInfo.CheckCanCreateInstance(attributeType, isVarArg); + + // Create custom attribute object + if (ctorHasParameters) + { + attribute = CreateCaObject(decoratedModule, ctor, ref blobStart, blobEnd, out cNamedArgs); + } + else + { + attribute = RuntimeTypeHandle.CreateCaInstance(attributeType, ctor); + + // It is allowed by the ECMA spec to have an empty signature blob + if (blobLen == 0) + cNamedArgs = 0; + else + { + // Metadata is always written in little-endian format. Must account for this on + // big-endian platforms. +#if BIGENDIAN + const int CustomAttributeVersion = 0x0100; +#else + const int CustomAttributeVersion = 0x0001; +#endif + if (Marshal.ReadInt16(blobStart) != CustomAttributeVersion) + throw new CustomAttributeFormatException(); + blobStart = (IntPtr)((byte*)blobStart + 2); // skip version prefix + + cNamedArgs = Marshal.ReadInt16(blobStart); + blobStart = (IntPtr)((byte*)blobStart + 2); // skip namedArgs count +#if BIGENDIAN + cNamedArgs = ((cNamedArgs & 0xff00) >> 8) | ((cNamedArgs & 0x00ff) << 8); +#endif + } + } + + for (int j = 0; j < cNamedArgs; j++) + { + #region // Initialize named properties and fields + string name; + bool isProperty; + RuntimeType type; + object value; + + IntPtr blobItr = caRecord.blob.Signature; + + GetPropertyOrFieldData(decoratedModule, ref blobStart, blobEnd, out name, out isProperty, out type, out value); + + try + { + if (isProperty) + { + #region // Initialize property + if (type == null && value != null) + { + type = (RuntimeType)value.GetType(); + if (type == Type_RuntimeType) + type = Type_Type; + } + + RuntimePropertyInfo property = null; + + if (type == null) + property = attributeType.GetProperty(name) as RuntimePropertyInfo; + else + property = attributeType.GetProperty(name, type, Type.EmptyTypes) as RuntimePropertyInfo; + + // Did we get a valid property reference? + if (property == null) + { + throw new CustomAttributeFormatException( + String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString( + isProperty ? "RFLCT.InvalidPropFail" : "RFLCT.InvalidFieldFail"), name)); + } + + RuntimeMethodInfo setMethod = property.GetSetMethod(true) as RuntimeMethodInfo; + + // Public properties may have non-public setter methods + if (!setMethod.IsPublic) + continue; + + RuntimeMethodHandle.CheckLinktimeDemands(setMethod, decoratedModule, isDecoratedTargetSecurityTransparent); + + setMethod.UnsafeInvoke(attribute, BindingFlags.Default, null, new object[] { value }, null); + #endregion + } + else + { + RtFieldInfo field = attributeType.GetField(name) as RtFieldInfo; + + if (isDecoratedTargetSecurityTransparent) + { + RuntimeFieldHandle.CheckAttributeAccess(field.FieldHandle, decoratedModule.GetNativeHandle()); + } + + field.CheckConsistency(attribute); + field.UnsafeSetValue(attribute, value, BindingFlags.Default, Type.DefaultBinder, null); + } + } + catch (Exception e) + { + throw new CustomAttributeFormatException( + String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString( + isProperty ? "RFLCT.InvalidPropFail" : "RFLCT.InvalidFieldFail"), name), e); + } + #endregion + } + + if (!blobStart.Equals(blobEnd)) + throw new CustomAttributeFormatException(); + + attributes[cAttributes++] = attribute; + } + + // The frame will be popped automatically if we take an exception any time after we pushed it. So no need of a catch or + // finally or CERs here. + frame.Pop(); + + if (cAttributes == car.Length && pcaCount == 0) + return attributes; + + object[] result = CreateAttributeArrayHelper(arrayType, cAttributes + pcaCount); + Array.Copy(attributes, 0, result, 0, cAttributes); + return result; + } + + [System.Security.SecurityCritical] // auto-generated + private unsafe static bool FilterCustomAttributeRecord( + CustomAttributeRecord caRecord, + MetadataImport scope, + ref Assembly lastAptcaOkAssembly, + RuntimeModule decoratedModule, + MetadataToken decoratedToken, + RuntimeType attributeFilterType, + bool mustBeInheritable, + object[] attributes, + IList derivedAttributes, + out RuntimeType attributeType, + out IRuntimeMethodInfo ctor, + out bool ctorHasParameters, + out bool isVarArg) + { + ctor = null; + attributeType = null; + ctorHasParameters = false; + isVarArg = false; + + IntPtr blobStart = caRecord.blob.Signature; + IntPtr blobEnd = (IntPtr)((byte*)blobStart + caRecord.blob.Length); + + // Resolve attribute type from ctor parent token found in decorated decoratedModule scope + attributeType = decoratedModule.ResolveType(scope.GetParentToken(caRecord.tkCtor), null, null) as RuntimeType; + + + // Test attribute type against user provided attribute type filter + if (!(attributeFilterType.IsAssignableFrom(attributeType))) + return false; + + // Ensure if attribute type must be inheritable that it is inhertiable + // Ensure that to consider a duplicate attribute type AllowMultiple is true + if (!AttributeUsageCheck(attributeType, mustBeInheritable, attributes, derivedAttributes)) + return false; + + // Windows Runtime attributes aren't real types - they exist to be read as metadata only, and as such + // should be filtered out of the GetCustomAttributes path. + if ((attributeType.Attributes & TypeAttributes.WindowsRuntime) == TypeAttributes.WindowsRuntime) + { + return false; + } + +#if FEATURE_APTCA + // APTCA checks + RuntimeAssembly attributeAssembly = (RuntimeAssembly)attributeType.Assembly; + RuntimeAssembly decoratedModuleAssembly = (RuntimeAssembly)decoratedModule.Assembly; + + if (attributeAssembly != lastAptcaOkAssembly && + !RuntimeAssembly.AptcaCheck(attributeAssembly, decoratedModuleAssembly)) + return false; + + // Cache last successful APTCA check (optimization) + lastAptcaOkAssembly = decoratedModuleAssembly; +#endif // FEATURE_APTCA + + // Resolve the attribute ctor + ConstArray ctorSig = scope.GetMethodSignature(caRecord.tkCtor); + isVarArg = (ctorSig[0] & 0x05) != 0; + ctorHasParameters = ctorSig[1] != 0; + + if (ctorHasParameters) + { + // Resolve method ctor token found in decorated decoratedModule scope + ctor = ModuleHandle.ResolveMethodHandleInternal(decoratedModule.GetNativeHandle(), caRecord.tkCtor); + } + else + { + // Resolve method ctor token from decorated decoratedModule scope + ctor = attributeType.GetTypeHandleInternal().GetDefaultConstructor(); + + if (ctor == null && !attributeType.IsValueType) + throw new MissingMethodException(".ctor"); + } + + // Visibility checks + MetadataToken tkParent = new MetadataToken(); + + if (decoratedToken.IsParamDef) + { + tkParent = new MetadataToken(scope.GetParentToken(decoratedToken)); + tkParent = new MetadataToken(scope.GetParentToken(tkParent)); + } + else if (decoratedToken.IsMethodDef || decoratedToken.IsProperty || decoratedToken.IsEvent || decoratedToken.IsFieldDef) + { + tkParent = new MetadataToken(scope.GetParentToken(decoratedToken)); + } + else if (decoratedToken.IsTypeDef) + { + tkParent = decoratedToken; + } + else if (decoratedToken.IsGenericPar) + { + tkParent = new MetadataToken(scope.GetParentToken(decoratedToken)); + + // decoratedToken is a generic parameter on a method. Get the declaring Type of the method. + if (tkParent.IsMethodDef) + tkParent = new MetadataToken(scope.GetParentToken(tkParent)); + } + else + { + // We need to relax this when we add support for other types of decorated tokens. + Contract.Assert(decoratedToken.IsModule || decoratedToken.IsAssembly, + "The decoratedToken must be either an assembly, a module, a type, or a member."); + } + + // If the attribute is on a type, member, or parameter we check access against the (declaring) type, + // otherwise we check access against the module. + RuntimeTypeHandle parentTypeHandle = tkParent.IsTypeDef ? + decoratedModule.ModuleHandle.ResolveTypeHandle(tkParent) : + new RuntimeTypeHandle(); + + return RuntimeMethodHandle.IsCAVisibleFromDecoratedType(attributeType.TypeHandle, ctor, parentTypeHandle, decoratedModule); + } + #endregion + + #region Private Static Methods + [System.Security.SecurityCritical] // auto-generated + private static bool AttributeUsageCheck( + RuntimeType attributeType, bool mustBeInheritable, object[] attributes, IList derivedAttributes) + { + AttributeUsageAttribute attributeUsageAttribute = null; + + if (mustBeInheritable) + { + attributeUsageAttribute = CustomAttribute.GetAttributeUsage(attributeType); + + if (!attributeUsageAttribute.Inherited) + return false; + } + + // Legacy: AllowMultiple ignored for none inheritable attributes + + if (derivedAttributes == null) + return true; + + for (int i = 0; i < derivedAttributes.Count; i++) + { + if (derivedAttributes[i].GetType() == attributeType) + { + if (attributeUsageAttribute == null) + attributeUsageAttribute = CustomAttribute.GetAttributeUsage(attributeType); + + return attributeUsageAttribute.AllowMultiple; + } + } + + return true; + } + + [System.Security.SecurityCritical] // auto-generated + internal static AttributeUsageAttribute GetAttributeUsage(RuntimeType decoratedAttribute) + { + RuntimeModule decoratedModule = decoratedAttribute.GetRuntimeModule(); + MetadataImport scope = decoratedModule.MetadataImport; + CustomAttributeRecord[] car = CustomAttributeData.GetCustomAttributeRecords(decoratedModule, decoratedAttribute.MetadataToken); + + AttributeUsageAttribute attributeUsageAttribute = null; + + for (int i = 0; i < car.Length; i++) + { + CustomAttributeRecord caRecord = car[i]; + RuntimeType attributeType = decoratedModule.ResolveType(scope.GetParentToken(caRecord.tkCtor), null, null) as RuntimeType; + + if (attributeType != (RuntimeType)typeof(AttributeUsageAttribute)) + continue; + + if (attributeUsageAttribute != null) + throw new FormatException(String.Format( + CultureInfo.CurrentUICulture, Environment.GetResourceString("Format_AttributeUsage"), attributeType)); + + AttributeTargets targets; + bool inherited, allowMultiple; + ParseAttributeUsageAttribute(caRecord.blob, out targets, out inherited, out allowMultiple); + attributeUsageAttribute = new AttributeUsageAttribute(targets, allowMultiple, inherited); + } + + if (attributeUsageAttribute == null) + return AttributeUsageAttribute.Default; + + return attributeUsageAttribute; + } + #endregion + + #region Private Static FCalls + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern void _ParseAttributeUsageAttribute( + IntPtr pCa, int cCa, out int targets, out bool inherited, out bool allowMultiple); + [System.Security.SecurityCritical] // auto-generated + private static void ParseAttributeUsageAttribute( + ConstArray ca, out AttributeTargets targets, out bool inherited, out bool allowMultiple) + { + int _targets; + _ParseAttributeUsageAttribute(ca.Signature, ca.Length, out _targets, out inherited, out allowMultiple); + targets = (AttributeTargets)_targets; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static unsafe extern Object _CreateCaObject(RuntimeModule pModule, IRuntimeMethodInfo pCtor, byte** ppBlob, byte* pEndBlob, int* pcNamedArgs); + [System.Security.SecurityCritical] // auto-generated + private static unsafe Object CreateCaObject(RuntimeModule module, IRuntimeMethodInfo ctor, ref IntPtr blob, IntPtr blobEnd, out int namedArgs) + { + byte* pBlob = (byte*)blob; + byte* pBlobEnd = (byte*)blobEnd; + int cNamedArgs; + object ca = _CreateCaObject(module, ctor, &pBlob, pBlobEnd, &cNamedArgs); + blob = (IntPtr)pBlob; + namedArgs = cNamedArgs; + return ca; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private unsafe extern static void _GetPropertyOrFieldData( + RuntimeModule pModule, byte** ppBlobStart, byte* pBlobEnd, out string name, out bool bIsProperty, out RuntimeType type, out object value); + [System.Security.SecurityCritical] // auto-generated + private unsafe static void GetPropertyOrFieldData( + RuntimeModule module, ref IntPtr blobStart, IntPtr blobEnd, out string name, out bool isProperty, out RuntimeType type, out object value) + { + byte* pBlobStart = (byte*)blobStart; + _GetPropertyOrFieldData( + module.GetNativeHandle(), &pBlobStart, (byte*)blobEnd, out name, out isProperty, out type, out value); + blobStart = (IntPtr)pBlobStart; + } + + [System.Security.SecuritySafeCritical] + private static object[] CreateAttributeArrayHelper(Type elementType, int elementCount) + { + return (object[])Array.UnsafeCreateInstance(elementType, elementCount); + } + #endregion + } + + internal static class PseudoCustomAttribute + { + #region Private Static Data Members + // Here we can avoid the need to take a lock when using Dictionary by rearranging + // the only method that adds values to the Dictionary. For more details on + // Dictionary versus Hashtable thread safety: + // See code:Dictionary#DictionaryVersusHashtableThreadSafety + private static Dictionary s_pca; + private static int s_pcasCount; + #endregion + + #region FCalls + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + unsafe private static extern void _GetSecurityAttributes(RuntimeModule module, int token, bool assembly, out object[] securityAttributes); + [System.Security.SecurityCritical] // auto-generated + unsafe internal static void GetSecurityAttributes(RuntimeModule module, int token, bool assembly, out object[] securityAttributes) + { + _GetSecurityAttributes(module.GetNativeHandle(), token, assembly, out securityAttributes); + } + #endregion + + #region Static Constructor + [System.Security.SecurityCritical] // auto-generated + static PseudoCustomAttribute() + { + RuntimeType[] pcas = new RuntimeType[] + { + // See //depot/DevDiv/private/Main/ndp/clr/src/MD/Compiler/CustAttr.cpp + typeof(FieldOffsetAttribute) as RuntimeType, // field + typeof(SerializableAttribute) as RuntimeType, // class, struct, enum, delegate + typeof(MarshalAsAttribute) as RuntimeType, // parameter, field, return-value + typeof(ComImportAttribute) as RuntimeType, // class, interface + typeof(NonSerializedAttribute) as RuntimeType, // field, inherited + typeof(InAttribute) as RuntimeType, // parameter + typeof(OutAttribute) as RuntimeType, // parameter + typeof(OptionalAttribute) as RuntimeType, // parameter + typeof(DllImportAttribute) as RuntimeType, // method + typeof(PreserveSigAttribute) as RuntimeType, // method + typeof(TypeForwardedToAttribute) as RuntimeType, // assembly + }; + + s_pcasCount = pcas.Length; + Dictionary temp_pca = new Dictionary(s_pcasCount); + + for (int i = 0; i < s_pcasCount; i++) + { + VerifyPseudoCustomAttribute(pcas[i]); + temp_pca[pcas[i]] = pcas[i]; + } + s_pca = temp_pca; + } + + [System.Security.SecurityCritical] // auto-generated + [Conditional("_DEBUG")] + private static void VerifyPseudoCustomAttribute(RuntimeType pca) + { + // If any of these are invariants are no longer true will have to + // re-architect the PCA product logic and test cases -- you've been warned! + Contract.Assert(pca.BaseType == (RuntimeType)typeof(Attribute), "Pseudo CA Error"); + AttributeUsageAttribute usage = CustomAttribute.GetAttributeUsage(pca); + Contract.Assert(usage.Inherited == false, "Pseudo CA Error"); + //AllowMultiple is true for TypeForwardedToAttribute + //Contract.Assert(usage.AllowMultiple == false, "Pseudo CA Error"); + } + #endregion + + #region Internal Static + internal static bool IsSecurityAttribute(RuntimeType type) + { +#pragma warning disable 618 + return type == (RuntimeType)typeof(SecurityAttribute) || type.IsSubclassOf(typeof(SecurityAttribute)); +#pragma warning restore 618 + } + + [System.Security.SecurityCritical] // auto-generated + internal static Attribute[] GetCustomAttributes(RuntimeType type, RuntimeType caType, bool includeSecCa, out int count) + { + Contract.Requires(type != null); + Contract.Requires(caType != null); + + count = 0; + + bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); + if (!all && s_pca.GetValueOrDefault(caType) == null && !IsSecurityAttribute(caType)) + return Array.Empty(); + + List pcas = new List(); + Attribute pca = null; + + if (all || caType == (RuntimeType)typeof(SerializableAttribute)) + { + pca = SerializableAttribute.GetCustomAttribute(type); + if (pca != null) pcas.Add(pca); + } + 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); + } + } + + count = pcas.Count; + return pcas.ToArray(); + } + [System.Security.SecurityCritical] // auto-generated + internal static bool IsDefined(RuntimeType type, RuntimeType caType) + { + bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); + if (!all && s_pca.GetValueOrDefault(caType) == null && !IsSecurityAttribute(caType)) + return false; + + if (all || caType == (RuntimeType)typeof(SerializableAttribute)) + { + if (SerializableAttribute.IsDefined(type)) 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) + return true; + } + + return false; + } + + [System.Security.SecurityCritical] // auto-generated + internal static Attribute[] GetCustomAttributes(RuntimeMethodInfo method, RuntimeType caType, bool includeSecCa, out int count) + { + Contract.Requires(method != null); + Contract.Requires(caType != null); + + count = 0; + + bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); + if (!all && s_pca.GetValueOrDefault(caType) == null && !IsSecurityAttribute(caType)) + return Array.Empty(); + + List pcas = new List(); + Attribute pca = null; + + if (all || caType == (RuntimeType)typeof(DllImportAttribute)) + { + pca = DllImportAttribute.GetCustomAttribute(method); + if (pca != null) pcas.Add(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); + } + + count = pcas.Count; + return pcas.ToArray(); + } + [System.Security.SecurityCritical] // auto-generated + internal static bool IsDefined(RuntimeMethodInfo method, RuntimeType caType) + { + bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); + if (!all && s_pca.GetValueOrDefault(caType) == null) + return false; + + if (all || caType == (RuntimeType)typeof(DllImportAttribute)) + { + if (DllImportAttribute.IsDefined(method)) 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) + return true; + } + + return false; + } + + [System.Security.SecurityCritical] // auto-generated + internal static Attribute[] GetCustomAttributes(RuntimeParameterInfo parameter, RuntimeType caType, out int count) + { + Contract.Requires(parameter != null); + Contract.Requires(caType != null); + + count = 0; + + bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); + if (!all && s_pca.GetValueOrDefault(caType) == null) + return null; + + Attribute[] pcas = new Attribute[s_pcasCount]; + Attribute pca = null; + + if (all || caType == (RuntimeType)typeof(InAttribute)) + { + pca = InAttribute.GetCustomAttribute(parameter); + if (pca != null) pcas[count++] = pca; + } + if (all || caType == (RuntimeType)typeof(OutAttribute)) + { + pca = OutAttribute.GetCustomAttribute(parameter); + if (pca != null) pcas[count++] = pca; + } + if (all || caType == (RuntimeType)typeof(OptionalAttribute)) + { + pca = OptionalAttribute.GetCustomAttribute(parameter); + if (pca != null) pcas[count++] = pca; + } + if (all || caType == (RuntimeType)typeof(MarshalAsAttribute)) + { + pca = MarshalAsAttribute.GetCustomAttribute(parameter); + if (pca != null) pcas[count++] = pca; + } + return pcas; + } + [System.Security.SecurityCritical] // auto-generated + internal static bool IsDefined(RuntimeParameterInfo parameter, RuntimeType caType) + { + bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); + if (!all && s_pca.GetValueOrDefault(caType) == null) + return false; + + + if (all || caType == (RuntimeType)typeof(InAttribute)) + { + if (InAttribute.IsDefined(parameter)) return true; + } + if (all || caType == (RuntimeType)typeof(OutAttribute)) + { + if (OutAttribute.IsDefined(parameter)) return true; + } + if (all || caType == (RuntimeType)typeof(OptionalAttribute)) + { + if (OptionalAttribute.IsDefined(parameter)) return true; + } + if (all || caType == (RuntimeType)typeof(MarshalAsAttribute)) + { + if (MarshalAsAttribute.IsDefined(parameter)) return true; + } + + return false; + } + + [System.Security.SecurityCritical] // auto-generated + internal static Attribute[] GetCustomAttributes(RuntimeAssembly assembly, RuntimeType caType, bool includeSecCa, out int count) + { + count = 0; + + bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); + + if (!all && s_pca.GetValueOrDefault(caType) == null && !IsSecurityAttribute(caType)) + return Array.Empty(); + + List pcas = new List(); + 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(); + } + [System.Security.SecurityCritical] // auto-generated + internal static bool IsDefined(RuntimeAssembly assembly, RuntimeType caType) + { + int count; + return GetCustomAttributes(assembly, caType, true, out count).Length > 0; + } + + internal static Attribute[] GetCustomAttributes(RuntimeModule module, RuntimeType caType, out int count) + { + count = 0; + return null; + } + internal static bool IsDefined(RuntimeModule module, RuntimeType caType) + { + return false; + } + + [System.Security.SecurityCritical] // auto-generated + internal static Attribute[] GetCustomAttributes(RuntimeFieldInfo field, RuntimeType caType, out int count) + { + Contract.Requires(field != null); + Contract.Requires(caType != null); + + count = 0; + + bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); + if (!all && s_pca.GetValueOrDefault(caType) == null) + return null; + + Attribute[] pcas = new Attribute[s_pcasCount]; + Attribute pca = null; + + if (all || caType == (RuntimeType)typeof(MarshalAsAttribute)) + { + pca = MarshalAsAttribute.GetCustomAttribute(field); + if (pca != null) pcas[count++] = pca; + } + if (all || caType == (RuntimeType)typeof(FieldOffsetAttribute)) + { + pca = FieldOffsetAttribute.GetCustomAttribute(field); + if (pca != null) pcas[count++] = pca; + } + if (all || caType == (RuntimeType)typeof(NonSerializedAttribute)) + { + pca = NonSerializedAttribute.GetCustomAttribute(field); + if (pca != null) pcas[count++] = pca; + } + return pcas; + } + [System.Security.SecurityCritical] // auto-generated + internal static bool IsDefined(RuntimeFieldInfo field, RuntimeType caType) + { + bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); + if (!all && s_pca.GetValueOrDefault(caType) == null) + return false; + + if (all || caType == (RuntimeType)typeof(MarshalAsAttribute)) + { + if (MarshalAsAttribute.IsDefined(field)) return true; + } + if (all || caType == (RuntimeType)typeof(FieldOffsetAttribute)) + { + if (FieldOffsetAttribute.IsDefined(field)) return true; + } + if (all || caType == (RuntimeType)typeof(NonSerializedAttribute)) + { + if (NonSerializedAttribute.IsDefined(field)) return true; + } + + return false; + } + + [System.Security.SecurityCritical] // auto-generated + internal static Attribute[] GetCustomAttributes(RuntimeConstructorInfo ctor, RuntimeType caType, bool includeSecCa, out int count) + { + count = 0; + + bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); + + if (!all && s_pca.GetValueOrDefault(caType) == null && !IsSecurityAttribute(caType)) + return Array.Empty(); + + List pcas = new List(); + + 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(); + } + [System.Security.SecurityCritical] // auto-generated + internal static bool IsDefined(RuntimeConstructorInfo ctor, RuntimeType caType) + { + bool all = caType == (RuntimeType)typeof(object) || caType == (RuntimeType)typeof(Attribute); + + if (!all && s_pca.GetValueOrDefault(caType) == null) + return false; + + if (all || IsSecurityAttribute(caType)) + { + int count; + + if (GetCustomAttributes(ctor, caType, true, out count).Length != 0) + return true; + } + + return false; + } + + internal static Attribute[] GetCustomAttributes(RuntimePropertyInfo property, RuntimeType caType, out int count) + { + count = 0; + return null; + } + internal static bool IsDefined(RuntimePropertyInfo property, RuntimeType caType) + { + return false; + } + + internal static Attribute[] GetCustomAttributes(RuntimeEventInfo e, RuntimeType caType, out int count) + { + count = 0; + return null; + } + internal static bool IsDefined(RuntimeEventInfo e, RuntimeType caType) + { + return false; + } + #endregion + } +} diff --git a/src/mscorlib/src/System/Reflection/CustomAttributeExtensions.cs b/src/mscorlib/src/System/Reflection/CustomAttributeExtensions.cs new file mode 100644 index 0000000000..c3287e17d1 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/CustomAttributeExtensions.cs @@ -0,0 +1,174 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Collections.Generic; + +namespace System.Reflection +{ + public static class CustomAttributeExtensions + { + #region APIs that return a single attribute + public static Attribute GetCustomAttribute(this Assembly element, Type attributeType) + { + return Attribute.GetCustomAttribute(element, attributeType); + } + public static Attribute GetCustomAttribute(this Module element, Type attributeType) + { + return Attribute.GetCustomAttribute(element, attributeType); + } + public static Attribute GetCustomAttribute(this MemberInfo element, Type attributeType) + { + return Attribute.GetCustomAttribute(element, attributeType); + } + public static Attribute GetCustomAttribute(this ParameterInfo element, Type attributeType) + { + return Attribute.GetCustomAttribute(element, attributeType); + } + + public static T GetCustomAttribute(this Assembly element) where T : Attribute + { + return (T)GetCustomAttribute(element, typeof(T)); + } + public static T GetCustomAttribute(this Module element) where T : Attribute + { + return (T)GetCustomAttribute(element, typeof(T)); + } + public static T GetCustomAttribute(this MemberInfo element) where T : Attribute + { + return (T)GetCustomAttribute(element, typeof(T)); + } + public static T GetCustomAttribute(this ParameterInfo element) where T : Attribute + { + return (T)GetCustomAttribute(element, typeof(T)); + } + + public static Attribute GetCustomAttribute(this MemberInfo element, Type attributeType, bool inherit) + { + return Attribute.GetCustomAttribute(element, attributeType, inherit); + } + public static Attribute GetCustomAttribute(this ParameterInfo element, Type attributeType, bool inherit) + { + return Attribute.GetCustomAttribute(element, attributeType, inherit); + } + + public static T GetCustomAttribute(this MemberInfo element, bool inherit) where T : Attribute + { + return (T)GetCustomAttribute(element, typeof(T), inherit); + } + public static T GetCustomAttribute(this ParameterInfo element, bool inherit) where T : Attribute + { + return (T)GetCustomAttribute(element, typeof(T), inherit); + } + #endregion + + #region APIs that return all attributes + public static IEnumerable GetCustomAttributes(this Assembly element) + { + return Attribute.GetCustomAttributes(element); + } + public static IEnumerable GetCustomAttributes(this Module element) + { + return Attribute.GetCustomAttributes(element); + } + public static IEnumerable GetCustomAttributes(this MemberInfo element) + { + return Attribute.GetCustomAttributes(element); + } + public static IEnumerable GetCustomAttributes(this ParameterInfo element) + { + return Attribute.GetCustomAttributes(element); + } + + public static IEnumerable GetCustomAttributes(this MemberInfo element, bool inherit) + { + return Attribute.GetCustomAttributes(element, inherit); + } + public static IEnumerable GetCustomAttributes(this ParameterInfo element, bool inherit) + { + return Attribute.GetCustomAttributes(element, inherit); + } + #endregion + + #region APIs that return all attributes of a particular type + public static IEnumerable GetCustomAttributes(this Assembly element, Type attributeType) + { + return Attribute.GetCustomAttributes(element, attributeType); + } + public static IEnumerable GetCustomAttributes(this Module element, Type attributeType) + { + return Attribute.GetCustomAttributes(element, attributeType); + } + public static IEnumerable GetCustomAttributes(this MemberInfo element, Type attributeType) + { + return Attribute.GetCustomAttributes(element, attributeType); + } + public static IEnumerable GetCustomAttributes(this ParameterInfo element, Type attributeType) + { + return Attribute.GetCustomAttributes(element, attributeType); + } + + public static IEnumerable GetCustomAttributes(this Assembly element) where T : Attribute + { + return (IEnumerable)GetCustomAttributes(element, typeof(T)); + } + public static IEnumerable GetCustomAttributes(this Module element) where T : Attribute + { + return (IEnumerable)GetCustomAttributes(element, typeof(T)); + } + public static IEnumerable GetCustomAttributes(this MemberInfo element) where T : Attribute + { + return (IEnumerable)GetCustomAttributes(element, typeof(T)); + } + public static IEnumerable GetCustomAttributes(this ParameterInfo element) where T : Attribute + { + return (IEnumerable)GetCustomAttributes(element, typeof(T)); + } + + public static IEnumerable GetCustomAttributes(this MemberInfo element, Type attributeType, bool inherit) + { + return Attribute.GetCustomAttributes(element, attributeType, inherit); + } + public static IEnumerable GetCustomAttributes(this ParameterInfo element, Type attributeType, bool inherit) + { + return Attribute.GetCustomAttributes(element, attributeType, inherit); + } + + public static IEnumerable GetCustomAttributes(this MemberInfo element, bool inherit) where T : Attribute + { + return (IEnumerable)GetCustomAttributes(element, typeof(T), inherit); + } + public static IEnumerable GetCustomAttributes(this ParameterInfo element, bool inherit) where T : Attribute + { + return (IEnumerable)GetCustomAttributes(element, typeof(T), inherit); + } + #endregion + + #region IsDefined + public static bool IsDefined(this Assembly element, Type attributeType) + { + return Attribute.IsDefined(element, attributeType); + } + public static bool IsDefined(this Module element, Type attributeType) + { + return Attribute.IsDefined(element, attributeType); + } + public static bool IsDefined(this MemberInfo element, Type attributeType) + { + return Attribute.IsDefined(element, attributeType); + } + public static bool IsDefined(this ParameterInfo element, Type attributeType) + { + return Attribute.IsDefined(element, attributeType); + } + + public static bool IsDefined(this MemberInfo element, Type attributeType, bool inherit) + { + return Attribute.IsDefined(element, attributeType, inherit); + } + public static bool IsDefined(this ParameterInfo element, Type attributeType, bool inherit) + { + return Attribute.IsDefined(element, attributeType, inherit); + } + #endregion + } +} diff --git a/src/mscorlib/src/System/Reflection/CustomAttributeFormatException.cs b/src/mscorlib/src/System/Reflection/CustomAttributeFormatException.cs new file mode 100644 index 0000000000..3eb8b1f1ef --- /dev/null +++ b/src/mscorlib/src/System/Reflection/CustomAttributeFormatException.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// CustomAttributeFormatException is thrown when the binary format of a +// +// custom attribute is invalid. +// +// +namespace System.Reflection { + using System; + using ApplicationException = System.ApplicationException; + using System.Runtime.Serialization; + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public class CustomAttributeFormatException : FormatException { + + public CustomAttributeFormatException() + : base(Environment.GetResourceString("Arg_CustomAttributeFormatException")) { + SetErrorCode(__HResults.COR_E_CUSTOMATTRIBUTEFORMAT); + } + + public CustomAttributeFormatException(String message) : base(message) { + SetErrorCode(__HResults.COR_E_CUSTOMATTRIBUTEFORMAT); + } + + public CustomAttributeFormatException(String message, Exception inner) : base(message, inner) { + SetErrorCode(__HResults.COR_E_CUSTOMATTRIBUTEFORMAT); + } + + protected CustomAttributeFormatException(SerializationInfo info, StreamingContext context) : base(info, context) { + } + + } +} diff --git a/src/mscorlib/src/System/Reflection/DefaultMemberAttribute.cs b/src/mscorlib/src/System/Reflection/DefaultMemberAttribute.cs new file mode 100644 index 0000000000..1fec75906a --- /dev/null +++ b/src/mscorlib/src/System/Reflection/DefaultMemberAttribute.cs @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// DefaultMemberAttribute is defines the Member of a Type that is the "default" +// +// member used by Type.InvokeMember. The default member is simply a name given +// to a type. +// +// +// +// +namespace System.Reflection { + + using System; + +[Serializable] + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class DefaultMemberAttribute : Attribute + { + // The name of the member + private String m_memberName; + + // You must provide the name of the member, this is required + public DefaultMemberAttribute(String memberName) { + m_memberName = memberName; + } + + // A get accessor to return the name from the attribute. + // NOTE: There is no setter because the name must be provided + // to the constructor. The name is not optional. + public String MemberName { + get {return m_memberName;} + } + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/AQNBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/AQNBuilder.cs new file mode 100644 index 0000000000..6484677c62 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/AQNBuilder.cs @@ -0,0 +1,208 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Collections.Generic; +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; +using System.Runtime.InteropServices; +using System.Security; + +namespace System.Reflection.Emit +{ + // TypeNameBuilder is NOT thread safe NOR reliable + internal class TypeNameBuilder + { + internal enum Format + { + ToString, + FullName, + AssemblyQualifiedName, + } + + #region QCalls + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern IntPtr CreateTypeNameBuilder(); + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void ReleaseTypeNameBuilder(IntPtr pAQN); + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void OpenGenericArguments(IntPtr tnb); + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void CloseGenericArguments(IntPtr tnb); + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void OpenGenericArgument(IntPtr tnb); + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void CloseGenericArgument(IntPtr tnb); + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void AddName(IntPtr tnb, string name); + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void AddPointer(IntPtr tnb); + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void AddByRef(IntPtr tnb); + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void AddSzArray(IntPtr tnb); + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void AddArray(IntPtr tnb, int rank); + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void AddAssemblySpec(IntPtr tnb, string assemblySpec); + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void ToString(IntPtr tnb, StringHandleOnStack retString); + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void Clear(IntPtr tnb); + #endregion + + #region Static Members + + // TypeNameBuilder is NOT thread safe NOR reliable + [System.Security.SecuritySafeCritical] // auto-generated + internal static string ToString(Type type, Format format) + { + if (format == Format.FullName || format == Format.AssemblyQualifiedName) + { + if (!type.IsGenericTypeDefinition && type.ContainsGenericParameters) + return null; + } + + TypeNameBuilder tnb = new TypeNameBuilder(CreateTypeNameBuilder()); + tnb.Clear(); + tnb.ConstructAssemblyQualifiedNameWorker(type, format); + string toString = tnb.ToString(); + tnb.Dispose(); + return toString; + } + #endregion + + #region Private Data Members + private IntPtr m_typeNameBuilder; + #endregion + + #region Constructor + private TypeNameBuilder(IntPtr typeNameBuilder) { m_typeNameBuilder = typeNameBuilder; } + [System.Security.SecurityCritical] // auto-generated + internal void Dispose() { ReleaseTypeNameBuilder(m_typeNameBuilder); } + #endregion + + #region private Members + [System.Security.SecurityCritical] // auto-generated + private void AddElementType(Type elementType) + { + if (elementType.HasElementType) + AddElementType(elementType.GetElementType()); + + if (elementType.IsPointer) + AddPointer(); + + else if (elementType.IsByRef) + AddByRef(); + + else if (elementType.IsSzArray) + AddSzArray(); + + else if (elementType.IsArray) + AddArray(elementType.GetArrayRank()); + } + + [System.Security.SecurityCritical] // auto-generated + private void ConstructAssemblyQualifiedNameWorker(Type type, Format format) + { + Type rootType = type; + + while (rootType.HasElementType) + rootType = rootType.GetElementType(); + + // Append namespace + nesting + name + List nestings = new List(); + for (Type t = rootType; t != null; t = t.IsGenericParameter ? null : t.DeclaringType) + nestings.Add(t); + + for (int i = nestings.Count - 1; i >= 0; i--) + { + Type enclosingType = nestings[i]; + string name = enclosingType.Name; + + if (i == nestings.Count - 1 && enclosingType.Namespace != null && enclosingType.Namespace.Length != 0) + name = enclosingType.Namespace + "." + name; + + AddName(name); + } + + // Append generic arguments + if (rootType.IsGenericType && (!rootType.IsGenericTypeDefinition || format == Format.ToString)) + { + Type[] genericArguments = rootType.GetGenericArguments(); + + OpenGenericArguments(); + for (int i = 0; i < genericArguments.Length; i++) + { + Format genericArgumentsFormat = format == Format.FullName ? Format.AssemblyQualifiedName : format; + + OpenGenericArgument(); + ConstructAssemblyQualifiedNameWorker(genericArguments[i], genericArgumentsFormat); + CloseGenericArgument(); + } + CloseGenericArguments(); + } + + // Append pointer, byRef and array qualifiers + AddElementType(type); + + if (format == Format.AssemblyQualifiedName) + AddAssemblySpec(type.Module.Assembly.FullName); + } + + [System.Security.SecurityCritical] // auto-generated + private void OpenGenericArguments() { OpenGenericArguments(m_typeNameBuilder); } + [System.Security.SecurityCritical] // auto-generated + private void CloseGenericArguments() { CloseGenericArguments(m_typeNameBuilder); } + [System.Security.SecurityCritical] // auto-generated + private void OpenGenericArgument() { OpenGenericArgument(m_typeNameBuilder); } + [System.Security.SecurityCritical] // auto-generated + private void CloseGenericArgument() { CloseGenericArgument(m_typeNameBuilder); } + [System.Security.SecurityCritical] // auto-generated + private void AddName(string name) { AddName(m_typeNameBuilder, name); } + [System.Security.SecurityCritical] // auto-generated + private void AddPointer() { AddPointer(m_typeNameBuilder); } + [System.Security.SecurityCritical] // auto-generated + private void AddByRef() { AddByRef(m_typeNameBuilder); } + [System.Security.SecurityCritical] // auto-generated + private void AddSzArray() { AddSzArray(m_typeNameBuilder); } + [System.Security.SecurityCritical] // auto-generated + private void AddArray(int rank) { AddArray(m_typeNameBuilder, rank); } + [System.Security.SecurityCritical] // auto-generated + private void AddAssemblySpec(string assemblySpec) { AddAssemblySpec(m_typeNameBuilder, assemblySpec); } + [System.Security.SecuritySafeCritical] // auto-generated + public override string ToString() { string ret = null; ToString(m_typeNameBuilder, JitHelpers.GetStringHandleOnStack(ref ret)); return ret; } + [System.Security.SecurityCritical] // auto-generated + private void Clear() { Clear(m_typeNameBuilder); } + #endregion + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs new file mode 100644 index 0000000000..5e7f83f2df --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilder.cs @@ -0,0 +1,2245 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +//************************************************************************************************************* +// For each dynamic assembly there will be two AssemblyBuilder objects: the "internal" +// AssemblyBuilder object and the "external" AssemblyBuilder object. +// 1. The "internal" object is the real assembly object that the VM creates and knows about. However, +// you can perform RefEmit operations on it only if you have its granted permission. From the AppDomain +// and other "internal" objects like the "internal" ModuleBuilders and runtime types, you can only +// get the "internal" objects. This is to prevent low-trust code from getting a hold of the dynamic +// AssemblyBuilder/ModuleBuilder/TypeBuilder/MethodBuilder/etc other people have created by simply +// enumerating the AppDomain and inject code in it. +// 2. The "external" object is merely an wrapper of the "internal" object and all operations on it +// are directed to the internal object. This is the one you get by calling DefineDynamicAssembly +// on AppDomain and the one you can always perform RefEmit operations on. You can get other "external" +// objects from the "external" AssemblyBuilder, ModuleBuilder, TypeBuilder, MethodBuilder, etc. Note +// that VM doesn't know about this object. So every time we call into the VM we need to pass in the +// "internal" object. +// +// "internal" and "external" ModuleBuilders are similar +//************************************************************************************************************* + +namespace System.Reflection.Emit +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Diagnostics.Contracts; + using System.Diagnostics.SymbolStore; + using CultureInfo = System.Globalization.CultureInfo; + using System.IO; + using System.Reflection; + using System.Resources; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + using System.Runtime.Serialization; + using System.Runtime.Versioning; + using System.Security; + using System.Security.Permissions; + using System.Security.Policy; + using System.Threading; + + // These must match the definitions in Assembly.hpp + [Flags] + internal enum DynamicAssemblyFlags + { + None = 0x00000000, + + // Security attributes which affect the module security descriptor + AllCritical = 0x00000001, + Aptca = 0x00000002, + Critical = 0x00000004, + Transparent = 0x00000008, + TreatAsSafe = 0x00000010, + } + + // When the user calls AppDomain.DefineDynamicAssembly the loader creates a new InternalAssemblyBuilder. + // 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 + // because the Assembly returned via AssemblyGetAssemblies() will be an InternalAssemblyBuilder. + + // Only the caller of DefineDynamicAssembly will get an AssemblyBuilder. + // There is a 1-1 relationship between InternalAssemblyBuilder and AssemblyBuilder. + // AssemblyBuilder is composed of its InternalAssemblyBuilder. + // The AssemblyBuilder data members (e.g. m_foo) were changed to properties which then delegate + // the access to the composed InternalAssemblyBuilder. This way, AssemblyBuilder simply wraps + // InternalAssemblyBuilder and still operates on InternalAssemblyBuilder members. + // This also makes the change transparent to the loader. This is good because most of the complexity + // of Assembly building is in the loader code so not touching that code reduces the chance of + // introducing new bugs. + internal sealed class InternalAssemblyBuilder : RuntimeAssembly + { + private InternalAssemblyBuilder() { } + + #region object overrides + public override bool Equals(object obj) + { + if (obj == null) + return false; + + if (obj is InternalAssemblyBuilder) + return ((object)this == obj); + + return obj.Equals(this); + } + // Need a dummy GetHashCode to pair with Equals + public override int GetHashCode() { return base.GetHashCode(); } + #endregion + + // Assembly methods that are overridden by AssemblyBuilder should be overridden by InternalAssemblyBuilder too + #region Methods inherited from Assembly + public override String[] GetManifestResourceNames() + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly")); + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + public override FileStream GetFile(String name) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly")); + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + public override FileStream[] GetFiles(bool getResourceModules) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly")); + } + + public override Stream GetManifestResourceStream(Type type, String name) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly")); + } + + public override Stream GetManifestResourceStream(String name) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly")); + } + + public override ManifestResourceInfo GetManifestResourceInfo(String resourceName) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly")); + } + + public override String Location + { +#if FEATURE_CORECLR + [SecurityCritical] +#endif // FEATURE_CORECLR + get + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly")); + } + } + + public override String CodeBase + { +#if FEATURE_CORECLR + [SecurityCritical] +#endif // FEATURE_CORECLR + get + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly")); + } + } + + public override Type[] GetExportedTypes() + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicAssembly")); + } + + public override String ImageRuntimeVersion + { + get + { + return RuntimeEnvironment.GetSystemVersion(); + } + } + #endregion + } + + // AssemblyBuilder class. + // deliberately not [serializable] + [HostProtection(MayLeakOnAbort = true)] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_AssemblyBuilder))] + [ComVisible(true)] + public sealed class AssemblyBuilder : Assembly, _AssemblyBuilder + { + #region FCALL + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern RuntimeModule GetInMemoryAssemblyModule(RuntimeAssembly assembly); + + [System.Security.SecurityCritical] // auto-generated + private Module nGetInMemoryAssemblyModule() + { + return AssemblyBuilder.GetInMemoryAssemblyModule(GetNativeHandle()); + } + +#if !FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern RuntimeModule GetOnDiskAssemblyModule(RuntimeAssembly assembly); + + [System.Security.SecurityCritical] // auto-generated + private ModuleBuilder GetOnDiskAssemblyModuleBuilder() + { + if (m_onDiskAssemblyModuleBuilder == null) + { + Module module = AssemblyBuilder.GetOnDiskAssemblyModule(InternalAssembly.GetNativeHandle()); + ModuleBuilder modBuilder = new ModuleBuilder(this, (InternalModuleBuilder)module); + modBuilder.Init("RefEmit_OnDiskManifestModule", null, 0); + m_onDiskAssemblyModuleBuilder = modBuilder; + } + + return m_onDiskAssemblyModuleBuilder; + } +#endif // FEATURE_CORECLR + + #endregion + + #region Internal Data Members + // This is only valid in the "external" AssemblyBuilder + internal AssemblyBuilderData m_assemblyData; + private InternalAssemblyBuilder m_internalAssemblyBuilder; + private ModuleBuilder m_manifestModuleBuilder; + // Set to true if the manifest module was returned by code:DefineDynamicModule to the user + private bool m_fManifestModuleUsedAsDefinedModule; + internal const string MANIFEST_MODULE_NAME = "RefEmit_InMemoryManifestModule"; +#if !FEATURE_CORECLR + private ModuleBuilder m_onDiskAssemblyModuleBuilder; +#endif // !FEATURE_CORECLR + +#if FEATURE_APPX + private bool m_profileAPICheck; +#endif + + internal ModuleBuilder GetModuleBuilder(InternalModuleBuilder module) + { + Contract.Requires(module != null); + Contract.Assert(this.InternalAssembly == module.Assembly); + + lock(SyncRoot) + { +#if !FEATURE_CORECLR + foreach (ModuleBuilder modBuilder in m_assemblyData.m_moduleBuilderList) + { + if (modBuilder.InternalModule == module) + return modBuilder; + } + + // m_onDiskAssemblyModuleBuilder is null before Save + if (m_onDiskAssemblyModuleBuilder != null && m_onDiskAssemblyModuleBuilder.InternalModule == module) + return m_onDiskAssemblyModuleBuilder; +#endif // !FEATURE_CORECLR + + // in CoreCLR there is only one module in each dynamic assembly, the manifest module + if (m_manifestModuleBuilder.InternalModule == module) + return m_manifestModuleBuilder; + + throw new ArgumentException("module"); + } + } + + internal object SyncRoot + { + get + { + return InternalAssembly.SyncRoot; + } + } + + internal InternalAssemblyBuilder InternalAssembly + { + get + { + return m_internalAssemblyBuilder; + } + } + + internal RuntimeAssembly GetNativeHandle() + { + return InternalAssembly.GetNativeHandle(); + } + + [SecurityCritical] + internal Version GetVersion() + { + return InternalAssembly.GetVersion(); + } + +#if FEATURE_APPX + internal bool ProfileAPICheck + { + get + { + return m_profileAPICheck; + } + } +#endif + #endregion + + #region Constructor + [System.Security.SecurityCritical] // auto-generated + internal AssemblyBuilder(AppDomain domain, + AssemblyName name, + AssemblyBuilderAccess access, + String dir, + Evidence evidence, + PermissionSet requiredPermissions, + PermissionSet optionalPermissions, + PermissionSet refusedPermissions, + ref StackCrawlMark stackMark, + IEnumerable unsafeAssemblyAttributes, + SecurityContextSource securityContextSource) + { + if (name == null) + throw new ArgumentNullException("name"); + + if (access != AssemblyBuilderAccess.Run +#if !FEATURE_CORECLR + && access != AssemblyBuilderAccess.Save + && access != AssemblyBuilderAccess.RunAndSave +#endif // !FEATURE_CORECLR +#if FEATURE_REFLECTION_ONLY_LOAD + && access != AssemblyBuilderAccess.ReflectionOnly +#endif // FEATURE_REFLECTION_ONLY_LOAD +#if FEATURE_COLLECTIBLE_TYPES + && access != AssemblyBuilderAccess.RunAndCollect +#endif // FEATURE_COLLECTIBLE_TYPES + ) + { + throw new ArgumentException(Environment.GetResourceString("Arg_EnumIllegalVal", (int)access), "access"); + } + + if (securityContextSource < SecurityContextSource.CurrentAppDomain || + securityContextSource > SecurityContextSource.CurrentAssembly) + { + throw new ArgumentOutOfRangeException("securityContextSource"); + } + + // Clone the name in case the caller modifies it underneath us. + name = (AssemblyName)name.Clone(); + +#if !FEATURE_CORECLR + // Set the public key from the key pair if one has been provided. + // (Overwite any public key in the Assembly name, since it's no + // longer valid to have a disparity). + if (name.KeyPair != null) + name.SetPublicKey(name.KeyPair.PublicKey); +#endif + + // If the caller is trusted they can supply identity + // evidence for the new assembly. Otherwise we copy the + // current grant and deny sets from the caller's assembly, + // inject them into the new assembly and mark policy as + // resolved. If/when the assembly is persisted and + // reloaded, the normal rules for gathering evidence will + // be used. + if (evidence != null) +#pragma warning disable 618 + new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand(); +#pragma warning restore 618 + +#if FEATURE_COLLECTIBLE_TYPES && !FEATURE_CORECLR + // Collectible assemblies require FullTrust. This demand may be removed if we deem the + // feature robust enough to be used directly by untrusted API consumers. + if (access == AssemblyBuilderAccess.RunAndCollect) + new PermissionSet(PermissionState.Unrestricted).Demand(); +#endif // FEATURE_COLLECTIBLE_TYPES && !FEATURE_CORECLR + + // Scan the assembly level attributes for any attributes which modify how we create the + // assembly. Currently, we look for any attribute which modifies the security transparency + // of the assembly. + List assemblyAttributes = null; + DynamicAssemblyFlags assemblyFlags = DynamicAssemblyFlags.None; + byte[] securityRulesBlob = null; + byte[] aptcaBlob = null; + if (unsafeAssemblyAttributes != null) + { + // Create a copy to ensure that it cannot be modified from another thread + // as it is used further below. + assemblyAttributes = new List(unsafeAssemblyAttributes); + +#pragma warning disable 618 // We deal with legacy attributes here as well for compat + foreach (CustomAttributeBuilder attribute in assemblyAttributes) + { + if (attribute.m_con.DeclaringType == typeof(SecurityTransparentAttribute)) + { + assemblyFlags |= DynamicAssemblyFlags.Transparent; + } + else if (attribute.m_con.DeclaringType == typeof(SecurityCriticalAttribute)) + { +#if !FEATURE_CORECLR + SecurityCriticalScope scope = SecurityCriticalScope.Everything; + if (attribute.m_constructorArgs != null && + attribute.m_constructorArgs.Length == 1 && + attribute.m_constructorArgs[0] is SecurityCriticalScope) + { + scope = (SecurityCriticalScope)attribute.m_constructorArgs[0]; + } + + assemblyFlags |= DynamicAssemblyFlags.Critical; + if (scope == SecurityCriticalScope.Everything) +#endif // !FEATURE_CORECLR + { + assemblyFlags |= DynamicAssemblyFlags.AllCritical; + } + } +#if !FEATURE_CORECLR + else if (attribute.m_con.DeclaringType == typeof(SecurityRulesAttribute)) + { + securityRulesBlob = new byte[attribute.m_blob.Length]; + Buffer.BlockCopy(attribute.m_blob, 0, securityRulesBlob, 0, securityRulesBlob.Length); + } + else if (attribute.m_con.DeclaringType == typeof(SecurityTreatAsSafeAttribute)) + { + assemblyFlags |= DynamicAssemblyFlags.TreatAsSafe; + } +#endif // !FEATURE_CORECLR +#if FEATURE_APTCA + else if (attribute.m_con.DeclaringType == typeof(AllowPartiallyTrustedCallersAttribute)) + { + assemblyFlags |= DynamicAssemblyFlags.Aptca; + aptcaBlob = new byte[attribute.m_blob.Length]; + Buffer.BlockCopy(attribute.m_blob, 0, aptcaBlob, 0, aptcaBlob.Length); + } +#endif // FEATURE_APTCA + } +#pragma warning restore 618 + } + + m_internalAssemblyBuilder = (InternalAssemblyBuilder)nCreateDynamicAssembly(domain, + name, + evidence, + ref stackMark, + requiredPermissions, + optionalPermissions, + refusedPermissions, + securityRulesBlob, + aptcaBlob, + access, + assemblyFlags, + securityContextSource); + + m_assemblyData = new AssemblyBuilderData(m_internalAssemblyBuilder, + name.Name, + access, + dir); + m_assemblyData.AddPermissionRequests(requiredPermissions, + optionalPermissions, + refusedPermissions); + +#if FEATURE_APPX + if (AppDomain.ProfileAPICheck) + { + RuntimeAssembly creator = RuntimeAssembly.GetExecutingAssembly(ref stackMark); + if (creator != null && !creator.IsFrameworkAssembly()) + m_profileAPICheck = true; + } +#endif + // Make sure that ManifestModule is properly initialized + // We need to do this before setting any CustomAttribute + InitManifestModule(); + + if (assemblyAttributes != null) + { + foreach (CustomAttributeBuilder assemblyAttribute in assemblyAttributes) + SetCustomAttribute(assemblyAttribute); + } + } + + [System.Security.SecurityCritical] // auto-generated + private void InitManifestModule() + { + InternalModuleBuilder modBuilder = (InternalModuleBuilder)nGetInMemoryAssemblyModule(); + + // Note that this ModuleBuilder cannot be used for RefEmit yet + // because it hasn't been initialized. + // However, it can be used to set the custom attribute on the Assembly + m_manifestModuleBuilder = new ModuleBuilder(this, modBuilder); + + // We are only setting the name in the managed ModuleBuilderData here. + // The name in the underlying metadata will be set when the + // manifest module is created during nCreateDynamicAssembly. + + // This name needs to stay in sync with that used in + // Assembly::Init to call ReflectionModule::Create (in VM) + m_manifestModuleBuilder.Init(AssemblyBuilder.MANIFEST_MODULE_NAME, null, 0); + + m_fManifestModuleUsedAsDefinedModule = false; + } + #endregion + + #region DefineDynamicAssembly + + /********************************************** + * If an AssemblyName has a public key specified, the assembly is assumed + * to have a strong name and a hash will be computed when the assembly + * is saved. + **********************************************/ + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static AssemblyBuilder DefineDynamicAssembly( + AssemblyName name, + AssemblyBuilderAccess access) + { + Contract.Ensures(Contract.Result() != null); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return InternalDefineDynamicAssembly(name, access, null, + null, null, null, null, ref stackMark, null, SecurityContextSource.CurrentAssembly); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static AssemblyBuilder DefineDynamicAssembly( + AssemblyName name, + AssemblyBuilderAccess access, + IEnumerable assemblyAttributes) + { + Contract.Ensures(Contract.Result() != null); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return InternalDefineDynamicAssembly(name, + access, + null, null, null, null, null, + ref stackMark, + assemblyAttributes, SecurityContextSource.CurrentAssembly); + } + + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern Assembly nCreateDynamicAssembly(AppDomain domain, + AssemblyName name, + Evidence identity, + ref StackCrawlMark stackMark, + PermissionSet requiredPermissions, + PermissionSet optionalPermissions, + PermissionSet refusedPermissions, + byte[] securityRulesBlob, + byte[] aptcaBlob, + AssemblyBuilderAccess access, + DynamicAssemblyFlags flags, + SecurityContextSource securityContextSource); + + private class AssemblyBuilderLock { } + + [System.Security.SecurityCritical] // auto-generated + internal static AssemblyBuilder InternalDefineDynamicAssembly( + AssemblyName name, + AssemblyBuilderAccess access, + String dir, + Evidence evidence, + PermissionSet requiredPermissions, + PermissionSet optionalPermissions, + PermissionSet refusedPermissions, + ref StackCrawlMark stackMark, + IEnumerable unsafeAssemblyAttributes, + SecurityContextSource securityContextSource) + { +#if FEATURE_CAS_POLICY + if (evidence != null && !AppDomain.CurrentDomain.IsLegacyCasPolicyEnabled) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_RequiresCasPolicyExplicit")); + } +#endif // FEATURE_CAS_POLICY + + lock (typeof(AssemblyBuilderLock)) + { + // we can only create dynamic assemblies in the current domain + return new AssemblyBuilder(AppDomain.CurrentDomain, + name, + access, + dir, + evidence, + requiredPermissions, + optionalPermissions, + refusedPermissions, + ref stackMark, + unsafeAssemblyAttributes, + securityContextSource); + } //lock(typeof(AssemblyBuilderLock)) + } + #endregion + + #region DefineDynamicModule + /********************************************** + * + * Defines a named dynamic module. It is an error to define multiple + * modules within an Assembly with the same name. This dynamic module is + * a transient module. + * + **********************************************/ + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public ModuleBuilder DefineDynamicModule( + String name) + { + Contract.Ensures(Contract.Result() != null); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return DefineDynamicModuleInternal(name, false, ref stackMark); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public ModuleBuilder DefineDynamicModule( + String name, + bool emitSymbolInfo) // specify if emit symbol info or not + { + Contract.Ensures(Contract.Result() != null); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return DefineDynamicModuleInternal( name, emitSymbolInfo, ref stackMark ); + } + + [System.Security.SecurityCritical] // auto-generated + private ModuleBuilder DefineDynamicModuleInternal( + String name, + bool emitSymbolInfo, // specify if emit symbol info or not + ref StackCrawlMark stackMark) + { + lock(SyncRoot) + { + return DefineDynamicModuleInternalNoLock(name, emitSymbolInfo, ref stackMark); + } + } + + [System.Security.SecurityCritical] // auto-generated + private ModuleBuilder DefineDynamicModuleInternalNoLock( + String name, + bool emitSymbolInfo, // specify if emit symbol info or not + ref StackCrawlMark stackMark) + { + if (name == null) + throw new ArgumentNullException("name"); + if (name.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + if (name[0] == '\0') + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidName"), "name"); + Contract.Ensures(Contract.Result() != null); + Contract.EndContractBlock(); + + BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineDynamicModule( " + name + " )"); + + Contract.Assert(m_assemblyData != null, "m_assemblyData is null in DefineDynamicModuleInternal"); + + ModuleBuilder dynModule; + ISymbolWriter writer = null; + IntPtr pInternalSymWriter = new IntPtr(); + + // create the dynamic module + +#if FEATURE_MULTIMODULE_ASSEMBLIES + +#if FEATURE_CORECLR +#error FEATURE_MULTIMODULE_ASSEMBLIES should always go with !FEATURE_CORECLR +#endif //FEATURE_CORECLR + + m_assemblyData.CheckNameConflict(name); + + if (m_fManifestModuleUsedAsDefinedModule == true) + { // We need to define a new module + int tkFile; + InternalModuleBuilder internalDynModule = (InternalModuleBuilder)DefineDynamicModule( + InternalAssembly, + emitSymbolInfo, + name, + name, + ref stackMark, + ref pInternalSymWriter, + true /*fIsTransient*/, + out tkFile); + dynModule = new ModuleBuilder(this, internalDynModule); + + // initialize the dynamic module's managed side information + dynModule.Init(name, null, tkFile); + } + else + { // We will reuse the manifest module + m_manifestModuleBuilder.ModifyModuleName(name); + dynModule = m_manifestModuleBuilder; + + if (emitSymbolInfo) + { + pInternalSymWriter = ModuleBuilder.nCreateISymWriterForDynamicModule(dynModule.InternalModule, name); + } + } + +#else // FEATURE_MULTIMODULE_ASSEMBLIES + // Without FEATURE_MULTIMODULE_ASSEMBLIES only one ModuleBuilder per AssemblyBuilder can be created + if (m_fManifestModuleUsedAsDefinedModule == true) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoMultiModuleAssembly")); + + // Init(...) has already been called on m_manifestModuleBuilder in InitManifestModule() + dynModule = m_manifestModuleBuilder; +#endif // FEATURE_MULTIMODULE_ASSEMBLIES + + // Create the symbol writer + if (emitSymbolInfo) + { +#if FEATURE_MULTIMODULE_ASSEMBLIES && !FEATURE_CORECLR + // this is the code path for the desktop runtime + + // create the default SymWriter + Assembly assem = LoadISymWrapper(); + Type symWriter = assem.GetType("System.Diagnostics.SymbolStore.SymWriter", true, false); + if (symWriter != null && !symWriter.IsVisible) + symWriter = null; + + if (symWriter == null) + { + // cannot find SymWriter - throw TypeLoadException since we couldnt find the type. + throw new TypeLoadException(Environment.GetResourceString(ResId.MissingType, "SymWriter")); + } + + new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); + + try + { + (new PermissionSet(PermissionState.Unrestricted)).Assert(); + writer = (ISymbolWriter)Activator.CreateInstance(symWriter); + + // Set the underlying writer for the managed writer + // that we're using. Note that this function requires + // unmanaged code access. + writer.SetUnderlyingWriter(pInternalSymWriter); + } + finally + { + CodeAccessPermission.RevertAssert(); + } +#endif // FEATURE_MULTIMODULE_ASSEMBLIES && !FEATURE_CORECLR + +#if !FEATURE_MULTIMODULE_ASSEMBLIES && FEATURE_CORECLR + // this is the code path for CoreCLR + + writer = SymWrapperCore.SymWriter.CreateSymWriter(); + // Set the underlying writer for the managed writer + // that we're using. Note that this function requires + // unmanaged code access. +#pragma warning disable 618 + new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Assert(); +#pragma warning restore 618 + + String fileName = "Unused"; // this symfile is never written to disk so filename does not matter. + + // Pass the "real" module to the VM + pInternalSymWriter = ModuleBuilder.nCreateISymWriterForDynamicModule(dynModule.InternalModule, fileName); + + // In Telesto, we took the SetUnderlyingWriter method private as it's a very rickety method. + // This might someday be a good move for the desktop CLR too. + ((SymWrapperCore.SymWriter)writer).InternalSetUnderlyingWriter(pInternalSymWriter); +#endif // !FEATURE_MULTIMODULE_ASSEMBLIES && FEATURE_CORECLR + } // Creating the symbol writer + + dynModule.SetSymWriter(writer); + m_assemblyData.AddModule(dynModule); + + if (dynModule == m_manifestModuleBuilder) + { // We are reusing manifest module as user-defined dynamic module + m_fManifestModuleUsedAsDefinedModule = true; + } + + return dynModule; + } // DefineDynamicModuleInternalNoLock + +#if !FEATURE_CORECLR + // All dynamic modules in SilverLight are transient so we removed this overload of DefineDynamicModule + // Note that it is assumed that !FEATURE_CORECLR always goes with FEATURE_MULTIMODULE_ASSEMBLIES + // If we ever will build a non coreclr version of the runtime without FEATURE_MULTIMODULE_ASSEMBLIES + // we will need to make the same changes here as the ones we made in the transient overload + + /********************************************** + * + * Defines a named dynamic module. It is an error to define multiple + * modules within an Assembly with the same name. No symbol information + * will be emitted. + * + **********************************************/ + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public ModuleBuilder DefineDynamicModule( + String name, + String fileName) + { + Contract.Ensures(Contract.Result() != null); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + + // delegate to the next DefineDynamicModule + return DefineDynamicModuleInternal(name, fileName, false, ref stackMark); + } + + /********************************************** + * + * Emit symbol information if emitSymbolInfo is true using the + * default symbol writer interface. + * An exception will be thrown if the assembly is transient. + * + **********************************************/ + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public ModuleBuilder DefineDynamicModule( + String name, // module name + String fileName, // module file name + bool emitSymbolInfo) // specify if emit symbol info or not + { + Contract.Ensures(Contract.Result() != null); + + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return DefineDynamicModuleInternal(name, fileName, emitSymbolInfo, ref stackMark); + } + + [System.Security.SecurityCritical] // auto-generated + private ModuleBuilder DefineDynamicModuleInternal( + String name, // module name + String fileName, // module file name + bool emitSymbolInfo, // specify if emit symbol info or not + ref StackCrawlMark stackMark) // stack crawl mark used to find caller + { + lock(SyncRoot) + { + return DefineDynamicModuleInternalNoLock(name, fileName, emitSymbolInfo, ref stackMark); + } + } + + // "name" will be used for: + // 1. The Name field in the Module table. + // 2. ModuleBuilder.GetModule(string). + // "fileName" will be used for: + // 1. The name field in the ModuleRef table when this module is being referenced by + // another module in the same assembly. + // 2. .file record in the in memory assembly manifest when the module is created in memory + // 3. .file record in the on disk assembly manifest when the assembly is saved to disk + // 4. The file name of the saved module. + [System.Security.SecurityCritical] // auto-generated + private ModuleBuilder DefineDynamicModuleInternalNoLock( + String name, // module name + String fileName, // module file name + bool emitSymbolInfo, // specify if emit symbol info or not + ref StackCrawlMark stackMark) // stack crawl mark used to find caller + { + if (name == null) + throw new ArgumentNullException("name"); + if (name.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + if (name[0] == '\0') + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidName"), "name"); + + if (fileName == null) + throw new ArgumentNullException("fileName"); + if (fileName.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "fileName"); + if (!String.Equals(fileName, Path.GetFileName(fileName))) + throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "fileName"); + Contract.Ensures(Contract.Result() != null); + Contract.EndContractBlock(); + + BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineDynamicModule( " + name + ", " + fileName + ", " + emitSymbolInfo + " )"); + if (m_assemblyData.m_access == AssemblyBuilderAccess.Run) + { + // Error! You cannot define a persistable module within a transient data. + throw new NotSupportedException(Environment.GetResourceString("Argument_BadPersistableModuleInTransientAssembly")); + } + + if (m_assemblyData.m_isSaved == true) + { + // assembly has been saved before! + throw new InvalidOperationException(Environment.GetResourceString( + "InvalidOperation_CannotAlterAssembly")); + } + + ModuleBuilder dynModule; + ISymbolWriter writer = null; + IntPtr pInternalSymWriter = new IntPtr(); + + // create the dynamic module + + m_assemblyData.CheckNameConflict(name); + m_assemblyData.CheckFileNameConflict(fileName); + + int tkFile; + InternalModuleBuilder internalDynModule = (InternalModuleBuilder)DefineDynamicModule( + InternalAssembly, + emitSymbolInfo, + name, + fileName, + ref stackMark, + ref pInternalSymWriter, + false /*fIsTransient*/, + out tkFile); + dynModule = new ModuleBuilder(this, internalDynModule); + + // initialize the dynamic module's managed side information + dynModule.Init(name, fileName, tkFile); + + // Create the symbol writer + if (emitSymbolInfo) + { + // create the default SymWriter + Assembly assem = LoadISymWrapper(); + Type symWriter = assem.GetType("System.Diagnostics.SymbolStore.SymWriter", true, false); + if (symWriter != null && !symWriter.IsVisible) + symWriter = null; + + if (symWriter == null) + { + // cannot find SymWriter - throw TypeLoadException since we couldnt find the type. + throw new TypeLoadException(Environment.GetResourceString("MissingType", "SymWriter")); + } + try + { + (new PermissionSet(PermissionState.Unrestricted)).Assert(); + writer = (ISymbolWriter)Activator.CreateInstance(symWriter); + + // Set the underlying writer for the managed writer + // that we're using. Note that this function requires + // unmanaged code access. + writer.SetUnderlyingWriter(pInternalSymWriter); + } + finally + { + CodeAccessPermission.RevertAssert(); + } + } + + dynModule.SetSymWriter(writer); + + m_assemblyData.AddModule(dynModule); + + return dynModule; + } // DefineDynamicModuleInternalNoLock +#endif // !FEATURE_CORECLR + #endregion + + private Assembly LoadISymWrapper() + { + if (m_assemblyData.m_ISymWrapperAssembly != null) + return m_assemblyData.m_ISymWrapperAssembly; + + Assembly assem = Assembly.Load("ISymWrapper, Version=" + ThisAssembly.Version + + ", Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken); + + m_assemblyData.m_ISymWrapperAssembly = assem; + return assem; + } + + internal void CheckContext(params Type[][] typess) + { + if (typess == null) + return; + + foreach(Type[] types in typess) + if (types != null) + CheckContext(types); + } + + internal void CheckContext(params Type[] types) + { + if (types == null) + return; + + foreach (Type type in types) + { + if (type == null) + continue; + + if (type.Module == null || type.Module.Assembly == null) + throw new ArgumentException(Environment.GetResourceString("Argument_TypeNotValid")); + + if (type.Module.Assembly == typeof(object).Module.Assembly) + continue; + + if (type.Module.Assembly.ReflectionOnly && !ReflectionOnly) + throw new InvalidOperationException(Environment.GetResourceString("Arugment_EmitMixedContext1", type.AssemblyQualifiedName)); + + if (!type.Module.Assembly.ReflectionOnly && ReflectionOnly) + throw new InvalidOperationException(Environment.GetResourceString("Arugment_EmitMixedContext2", type.AssemblyQualifiedName)); + } + } + +#if !FEATURE_CORECLR + /********************************************** + * + * Define stand alone managed resource for Assembly + * + **********************************************/ + public IResourceWriter DefineResource( + String name, + String description, + String fileName) + { + return DefineResource(name, description, fileName, ResourceAttributes.Public); + } + + /********************************************** + * + * Define stand alone managed resource for Assembly + * + **********************************************/ + public IResourceWriter DefineResource( + String name, + String description, + String fileName, + ResourceAttributes attribute) + { + lock(SyncRoot) + { + return DefineResourceNoLock(name, description, fileName, attribute); + } + } + + private IResourceWriter DefineResourceNoLock( + String name, + String description, + String fileName, + ResourceAttributes attribute) + { + if (name == null) + throw new ArgumentNullException("name"); + if (name.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), name); + if (fileName == null) + throw new ArgumentNullException("fileName"); + if (fileName.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "fileName"); + if (!String.Equals(fileName, Path.GetFileName(fileName))) + throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "fileName"); + Contract.EndContractBlock(); + + BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.DefineResource( " + name + ", " + fileName + ")"); + + m_assemblyData.CheckResNameConflict(name); + m_assemblyData.CheckFileNameConflict(fileName); + + ResourceWriter resWriter; + String fullFileName; + + if (m_assemblyData.m_strDir == null) + { + // If assembly directory is null, use current directory + fullFileName = Path.Combine(Directory.GetCurrentDirectory(), fileName); + resWriter = new ResourceWriter(fullFileName); + } + else + { + // Form the full path given the directory provided by user + fullFileName = Path.Combine(m_assemblyData.m_strDir, fileName); + resWriter = new ResourceWriter(fullFileName); + } + // get the full path + fullFileName = Path.GetFullPath(fullFileName); + + // retrieve just the file name + fileName = Path.GetFileName(fullFileName); + + m_assemblyData.AddResWriter( new ResWriterData( resWriter, null, name, fileName, fullFileName, attribute) ); + return resWriter; + } + +#endif // !FEATURE_CORECLR + + /********************************************** + * + * Add an existing resource file to the Assembly + * + **********************************************/ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + public void AddResourceFile( + String name, + String fileName) + { + AddResourceFile(name, fileName, ResourceAttributes.Public); + } + + /********************************************** + * + * Add an existing resource file to the Assembly + * + **********************************************/ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + public void AddResourceFile( + String name, + String fileName, + ResourceAttributes attribute) + { + lock(SyncRoot) + { + AddResourceFileNoLock(name, fileName, attribute); + } + } + + [System.Security.SecuritySafeCritical] + private void AddResourceFileNoLock( + String name, + String fileName, + ResourceAttributes attribute) + { + if (name == null) + throw new ArgumentNullException("name"); + if (name.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), name); + if (fileName == null) + throw new ArgumentNullException("fileName"); + if (fileName.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), fileName); + if (!String.Equals(fileName, Path.GetFileName(fileName))) + throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "fileName"); + Contract.EndContractBlock(); + + BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.AddResourceFile( " + name + ", " + fileName + ")"); + + m_assemblyData.CheckResNameConflict(name); + m_assemblyData.CheckFileNameConflict(fileName); + + String fullFileName; + + if (m_assemblyData.m_strDir == null) + { + // If assembly directory is null, use current directory + fullFileName = Path.Combine(Directory.GetCurrentDirectory(), fileName); + } + else + { + // Form the full path given the directory provided by user + fullFileName = Path.Combine(m_assemblyData.m_strDir, fileName); + } + + // get the full path + fullFileName = Path.UnsafeGetFullPath(fullFileName); + + // retrieve just the file name + fileName = Path.GetFileName(fullFileName); + + if (File.UnsafeExists(fullFileName) == false) + throw new FileNotFoundException(Environment.GetResourceString( + "IO.FileNotFound_FileName", + fileName), fileName); + m_assemblyData.AddResWriter( new ResWriterData( null, null, name, fileName, fullFileName, attribute) ); + } + + #region object overrides + public override bool Equals(object obj) + { + return InternalAssembly.Equals(obj); + } + // Need a dummy GetHashCode to pair with Equals + public override int GetHashCode() { return InternalAssembly.GetHashCode(); } + #endregion + + #region ICustomAttributeProvider Members + public override Object[] GetCustomAttributes(bool inherit) + { + return InternalAssembly.GetCustomAttributes(inherit); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + return InternalAssembly.GetCustomAttributes(attributeType, inherit); + } + + public override bool IsDefined(Type attributeType, bool inherit) + { + return InternalAssembly.IsDefined(attributeType, inherit); + } + + public override IList GetCustomAttributesData() + { + return InternalAssembly.GetCustomAttributesData(); + } + #endregion + + #region Assembly overrides + // Returns the names of all the resources + public override String[] GetManifestResourceNames() + { + return InternalAssembly.GetManifestResourceNames(); + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + public override FileStream GetFile(String name) + { + return InternalAssembly.GetFile(name); + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + public override FileStream[] GetFiles(bool getResourceModules) + { + return InternalAssembly.GetFiles(getResourceModules); + } + + public override Stream GetManifestResourceStream(Type type, String name) + { + return InternalAssembly.GetManifestResourceStream(type, name); + } + + public override Stream GetManifestResourceStream(String name) + { + return InternalAssembly.GetManifestResourceStream(name); + } + + public override ManifestResourceInfo GetManifestResourceInfo(String resourceName) + { + return InternalAssembly.GetManifestResourceInfo(resourceName); + } + + public override String Location + { + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + get + { + return InternalAssembly.Location; + } + } + + public override String ImageRuntimeVersion + { + get + { + return InternalAssembly.ImageRuntimeVersion; + } + } + + public override String CodeBase + { + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + get + { + return InternalAssembly.CodeBase; + } + } + + // Override the EntryPoint method on Assembly. + // This doesn't need to be synchronized because it is simple enough + public override MethodInfo EntryPoint + { + get + { + return m_assemblyData.m_entryPointMethod; + } + } + + // Get an array of all the public types defined in this assembly + public override Type[] GetExportedTypes() + { + return InternalAssembly.GetExportedTypes(); + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + public override AssemblyName GetName(bool copiedName) + { + return InternalAssembly.GetName(copiedName); + } + + public override String FullName + { + get + { + return InternalAssembly.FullName; + } + } + + public override Type GetType(String name, bool throwOnError, bool ignoreCase) + { + return InternalAssembly.GetType(name, throwOnError, ignoreCase); + } + +#if FEATURE_CAS_POLICY + public override Evidence Evidence + { + get + { + return InternalAssembly.Evidence; + } + } + + public override PermissionSet PermissionSet + { + [SecurityCritical] + get + { + return InternalAssembly.PermissionSet; + } + } + + public override SecurityRuleSet SecurityRuleSet + { + get + { + return InternalAssembly.SecurityRuleSet; + } + } +#endif // FEATURE_CAS_POLICY + + public override Module ManifestModule + { + get + { + return m_manifestModuleBuilder.InternalModule; + } + } + + public override bool ReflectionOnly + { + get + { + return InternalAssembly.ReflectionOnly; + } + } + + public override Module GetModule(String name) + { + return InternalAssembly.GetModule(name); + } + + public override AssemblyName[] GetReferencedAssemblies() + { + return InternalAssembly.GetReferencedAssemblies(); + } + + public override bool GlobalAssemblyCache + { + get + { + return InternalAssembly.GlobalAssemblyCache; + } + } + + public override Int64 HostContext + { + get + { + return InternalAssembly.HostContext; + } + } + + public override Module[] GetModules(bool getResourceModules) + { + return InternalAssembly.GetModules(getResourceModules); + } + + public override Module[] GetLoadedModules(bool getResourceModules) + { + return InternalAssembly.GetLoadedModules(getResourceModules); + } + + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public override Assembly GetSatelliteAssembly(CultureInfo culture) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return InternalAssembly.InternalGetSatelliteAssembly(culture, null, ref stackMark); + } + + // Useful for binding to a very specific version of a satellite assembly + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public override Assembly GetSatelliteAssembly(CultureInfo culture, Version version) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return InternalAssembly.InternalGetSatelliteAssembly(culture, version, ref stackMark); + } + + public override bool IsDynamic + { + get { + return true; + } + } + #endregion + + + /********************************************** + * + * Add an unmanaged Version resource to the + * assembly + * + **********************************************/ + public void DefineVersionInfoResource( + String product, + String productVersion, + String company, + String copyright, + String trademark) + { + lock(SyncRoot) + { + DefineVersionInfoResourceNoLock( + product, + productVersion, + company, + copyright, + trademark); + } + } + + private void DefineVersionInfoResourceNoLock( + String product, + String productVersion, + String company, + String copyright, + String trademark) + { + if (m_assemblyData.m_strResourceFileName != null || + m_assemblyData.m_resourceBytes != null || + m_assemblyData.m_nativeVersion != null) + throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined")); + + m_assemblyData.m_nativeVersion = new NativeVersionInfo(); + + m_assemblyData.m_nativeVersion.m_strCopyright = copyright; + m_assemblyData.m_nativeVersion.m_strTrademark = trademark; + m_assemblyData.m_nativeVersion.m_strCompany = company; + m_assemblyData.m_nativeVersion.m_strProduct = product; + m_assemblyData.m_nativeVersion.m_strProductVersion = productVersion; + m_assemblyData.m_hasUnmanagedVersionInfo = true; + m_assemblyData.m_OverrideUnmanagedVersionInfo = true; + + } + + public void DefineVersionInfoResource() + { + lock(SyncRoot) + { + DefineVersionInfoResourceNoLock(); + } + } + + private void DefineVersionInfoResourceNoLock() + { + if (m_assemblyData.m_strResourceFileName != null || + m_assemblyData.m_resourceBytes != null || + m_assemblyData.m_nativeVersion != null) + throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined")); + + m_assemblyData.m_hasUnmanagedVersionInfo = true; + m_assemblyData.m_nativeVersion = new NativeVersionInfo(); + } + + public void DefineUnmanagedResource(Byte[] resource) + { + if (resource == null) + throw new ArgumentNullException("resource"); + Contract.EndContractBlock(); + + lock(SyncRoot) + { + DefineUnmanagedResourceNoLock(resource); + } + } + + private void DefineUnmanagedResourceNoLock(Byte[] resource) + { + if (m_assemblyData.m_strResourceFileName != null || + m_assemblyData.m_resourceBytes != null || + m_assemblyData.m_nativeVersion != null) + throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined")); + + m_assemblyData.m_resourceBytes = new byte[resource.Length]; + Buffer.BlockCopy(resource, 0, m_assemblyData.m_resourceBytes, 0, resource.Length); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void DefineUnmanagedResource(String resourceFileName) + { + if (resourceFileName == null) + throw new ArgumentNullException("resourceFileName"); + Contract.EndContractBlock(); + + lock(SyncRoot) + { + DefineUnmanagedResourceNoLock(resourceFileName); + } + } + + [System.Security.SecurityCritical] // auto-generated + private void DefineUnmanagedResourceNoLock(String resourceFileName) + { + if (m_assemblyData.m_strResourceFileName != null || + m_assemblyData.m_resourceBytes != null || + m_assemblyData.m_nativeVersion != null) + throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined")); + + // Check caller has the right to read the file. + string strFullFileName; + if (m_assemblyData.m_strDir == null) + { + // If assembly directory is null, use current directory + strFullFileName = Path.Combine(Directory.GetCurrentDirectory(), resourceFileName); + } + else + { + // Form the full path given the directory provided by user + strFullFileName = Path.Combine(m_assemblyData.m_strDir, resourceFileName); + } + strFullFileName = Path.GetFullPath(resourceFileName); + new FileIOPermission(FileIOPermissionAccess.Read, strFullFileName).Demand(); + + if (File.Exists(strFullFileName) == false) + throw new FileNotFoundException(Environment.GetResourceString( + "IO.FileNotFound_FileName", + resourceFileName), resourceFileName); + m_assemblyData.m_strResourceFileName = strFullFileName; + } + + + + /********************************************** + * + * return a dynamic module with the specified name. + * + **********************************************/ + public ModuleBuilder GetDynamicModule( + String name) // the name of module for the look up + { + lock(SyncRoot) + { + return GetDynamicModuleNoLock(name); + } + } + + private ModuleBuilder GetDynamicModuleNoLock( + String name) // the name of module for the look up + { + if (name == null) + throw new ArgumentNullException("name"); + if (name.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + Contract.EndContractBlock(); + + BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.GetDynamicModule( " + name + " )"); + int size = m_assemblyData.m_moduleBuilderList.Count; + for (int i = 0; i < size; i++) + { + ModuleBuilder moduleBuilder = (ModuleBuilder) m_assemblyData.m_moduleBuilderList[i]; + if (moduleBuilder.m_moduleData.m_strModuleName.Equals(name)) + { + return moduleBuilder; + } + } + return null; + } + + /********************************************** + * + * Setting the entry point if the assembly builder is building + * an exe. + * + **********************************************/ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + public void SetEntryPoint( + MethodInfo entryMethod) + { + SetEntryPoint(entryMethod, PEFileKinds.ConsoleApplication); + } + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + public void SetEntryPoint( + MethodInfo entryMethod, // entry method for the assembly. We use this to determine the entry module + PEFileKinds fileKind) // file kind for the assembly. + { + lock(SyncRoot) + { + SetEntryPointNoLock(entryMethod, fileKind); + } + } + + private void SetEntryPointNoLock( + MethodInfo entryMethod, // entry method for the assembly. We use this to determine the entry module + PEFileKinds fileKind) // file kind for the assembly. + { + + if (entryMethod == null) + throw new ArgumentNullException("entryMethod"); + Contract.EndContractBlock(); + + BCLDebug.Log("DYNIL", "## DYNIL LOGGING: AssemblyBuilder.SetEntryPoint"); + + Module tmpModule = entryMethod.Module; + if (tmpModule == null || !InternalAssembly.Equals(tmpModule.Assembly)) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_EntryMethodNotDefinedInAssembly")); + + m_assemblyData.m_entryPointMethod = entryMethod; + m_assemblyData.m_peFileKind = fileKind; + +#if !FEATURE_CORECLR + // Setting the entry point + ModuleBuilder tmpMB = tmpModule as ModuleBuilder; + if (tmpMB != null) + m_assemblyData.m_entryPointModule = tmpMB; + else + m_assemblyData.m_entryPointModule = GetModuleBuilder((InternalModuleBuilder)tmpModule); + + MethodToken entryMethodToken = m_assemblyData.m_entryPointModule.GetMethodToken(entryMethod); + m_assemblyData.m_entryPointModule.SetEntryPoint(entryMethodToken); +#endif //!FEATURE_CORECLR + } + + + /********************************************** + * Use this function if client decides to form the custom attribute blob themselves + **********************************************/ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #else + [System.Security.SecuritySafeCritical] + #endif + [System.Runtime.InteropServices.ComVisible(true)] + public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + { + if (con == null) + throw new ArgumentNullException("con"); + if (binaryAttribute == null) + throw new ArgumentNullException("binaryAttribute"); + Contract.EndContractBlock(); + + lock(SyncRoot) + { + SetCustomAttributeNoLock(con, binaryAttribute); + } + } + + [System.Security.SecurityCritical] // auto-generated + private void SetCustomAttributeNoLock(ConstructorInfo con, byte[] binaryAttribute) + { + TypeBuilder.DefineCustomAttribute( + m_manifestModuleBuilder, // pass in the in-memory assembly module + AssemblyBuilderData.m_tkAssembly, // This is the AssemblyDef token + m_manifestModuleBuilder.GetConstructorToken(con).Token, + binaryAttribute, + false, + typeof(System.Diagnostics.DebuggableAttribute) == con.DeclaringType); + + // Track the CA for persistence + if (m_assemblyData.m_access != AssemblyBuilderAccess.Run) + { + // tracking the CAs for persistence + m_assemblyData.AddCustomAttribute(con, binaryAttribute); + } + } + + /********************************************** + * Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder + **********************************************/ + [System.Security.SecuritySafeCritical] // auto-generated + public void SetCustomAttribute(CustomAttributeBuilder customBuilder) + { + if (customBuilder == null) + { + throw new ArgumentNullException("customBuilder"); + } + Contract.EndContractBlock(); + + lock(SyncRoot) + { + SetCustomAttributeNoLock(customBuilder); + } + } + + [System.Security.SecurityCritical] // auto-generated + private void SetCustomAttributeNoLock(CustomAttributeBuilder customBuilder) + { + customBuilder.CreateCustomAttribute( + m_manifestModuleBuilder, + AssemblyBuilderData.m_tkAssembly); // This is the AssemblyDef token + + // Track the CA for persistence + if (m_assemblyData.m_access != AssemblyBuilderAccess.Run) + { + m_assemblyData.AddCustomAttribute(customBuilder); + } + } + + + /********************************************** + * + * Saves the assembly to disk. Also saves all dynamic modules defined + * in this dynamic assembly. Assembly file name can be the same as one of + * the module's name. If so, assembly info is stored within that module. + * Assembly file name can be different from all of the modules underneath. In + * this case, assembly is stored stand alone. + * + **********************************************/ + + public void Save(String assemblyFileName) // assembly file name + { + Save(assemblyFileName, System.Reflection.PortableExecutableKinds.ILOnly, System.Reflection.ImageFileMachine.I386); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void Save(String assemblyFileName, + PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) + { + lock(SyncRoot) + { + SaveNoLock(assemblyFileName, portableExecutableKind, imageFileMachine); + } + } + +#if FEATURE_CORECLR + private void SaveNoLock(String assemblyFileName, + PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) + { + // AssemblyBuilderAccess.Save can never be set with FEATURE_CORECLR + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CantSaveTransientAssembly")); + } +#else // FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + private void SaveNoLock(String assemblyFileName, + PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) + { + if (assemblyFileName == null) + throw new ArgumentNullException("assemblyFileName"); + if (assemblyFileName.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyFileName"), "assemblyFileName"); + if (!String.Equals(assemblyFileName, Path.GetFileName(assemblyFileName))) + throw new ArgumentException(Environment.GetResourceString("Argument_NotSimpleFileName"), "assemblyFileName"); + Contract.EndContractBlock(); + + int i; + int size; + Type type; + TypeBuilder typeBuilder; + ModuleBuilder modBuilder; + String strModFileName; + ModuleBuilder assemblyModule; + ResWriterData tempRes; + int[] tkAttrs = null; + int[] tkAttrs2 = null; + ModuleBuilder onDiskAssemblyModule; + + BCLDebug.Log("DYNIL","## DYNIL LOGGING: AssemblyBuilder.Save( " + assemblyFileName + " )"); + + String tmpVersionFile = null; + + try + { + if (m_assemblyData.m_iCABuilder != 0) + tkAttrs = new int[m_assemblyData.m_iCABuilder]; + if ( m_assemblyData.m_iCAs != 0) + tkAttrs2 = new int[m_assemblyData.m_iCAs]; + + if (m_assemblyData.m_isSaved == true) + { + // assembly has been saved before! + throw new InvalidOperationException(Environment.GetResourceString(ResId.InvalidOperation_AssemblyHasBeenSaved, + InternalAssembly.GetSimpleName())); + } + + if ((m_assemblyData.m_access & AssemblyBuilderAccess.Save) != AssemblyBuilderAccess.Save) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CantSaveTransientAssembly")); + } + + // Check if assembly info is supposed to be stored with one of the module files. + assemblyModule = m_assemblyData.FindModuleWithFileName(assemblyFileName); + + if (assemblyModule != null) + { + m_onDiskAssemblyModuleBuilder = assemblyModule; + + // In memory this module is not the manifest module and has a valid file token + // On disk it will be the manifest module so lets clean the file token + // We should not retrieve FileToken after the assembly has been saved + // If that is absolutely necessary, we need two separate fields on ModuleBuilderData: + // the in memory file token and the on disk file token. + assemblyModule.m_moduleData.FileToken = 0; + } + else + { // If assembly is to be stored alone, then no file name should conflict with it. + // This check will ensure resource file names are different assembly file name. + m_assemblyData.CheckFileNameConflict(assemblyFileName); + } + + if (m_assemblyData.m_strDir == null) + { + // set it to current directory + m_assemblyData.m_strDir = Directory.GetCurrentDirectory(); + } + else if (Directory.Exists(m_assemblyData.m_strDir) == false) + { + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidDirectory", + m_assemblyData.m_strDir)); + } + + // after this point, assemblyFileName is the full path name. + assemblyFileName = Path.Combine(m_assemblyData.m_strDir, assemblyFileName); + assemblyFileName = Path.GetFullPath(assemblyFileName); + + // Check caller has the right to create the assembly file itself. + new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Append, assemblyFileName).Demand(); + + // 1. setup/create the IMetaDataAssemblyEmit for the on disk version + if (assemblyModule != null) + { + // prepare saving CAs on assembly def. We need to introduce the MemberRef for + // the CA's type first of all. This is for the case the we have embedded manifest. + // We need to introduce these MRs before we call PreSave where we will snap + // into a ondisk metadata. If we do it after this, the ondisk metadata will + // not contain the proper MRs. + // + for (i=0; i < m_assemblyData.m_iCABuilder; i++) + { + tkAttrs[i] = m_assemblyData.m_CABuilders[i].PrepareCreateCustomAttributeToDisk( + assemblyModule); + } + for (i=0; i < m_assemblyData.m_iCAs; i++) + { + tkAttrs2[i] = assemblyModule.InternalGetConstructorToken(m_assemblyData.m_CACons[i], true).Token; + } + assemblyModule.PreSave(assemblyFileName, portableExecutableKind, imageFileMachine); + } + + RuntimeModule runtimeAssemblyModule = (assemblyModule != null) ? assemblyModule.ModuleHandle.GetRuntimeModule() : null; + PrepareForSavingManifestToDisk(GetNativeHandle(), runtimeAssemblyModule); + + // This function will return the embedded manifest module, an already exposed ModuleBuilder + // created by user, or make the stand alone manifest module exposed through managed code. + // + onDiskAssemblyModule = GetOnDiskAssemblyModuleBuilder(); + + // Set any native resources on the OnDiskAssemblyModule. + if (m_assemblyData.m_strResourceFileName != null) + onDiskAssemblyModule.DefineUnmanagedResourceFileInternalNoLock(m_assemblyData.m_strResourceFileName); + else if (m_assemblyData.m_resourceBytes != null) + onDiskAssemblyModule.DefineUnmanagedResourceInternalNoLock(m_assemblyData.m_resourceBytes); + else if (m_assemblyData.m_hasUnmanagedVersionInfo == true) + { + // calculate unmanaged version info from assembly's custom attributes + m_assemblyData.FillUnmanagedVersionInfo(); + + String strFileVersion = m_assemblyData.m_nativeVersion.m_strFileVersion; + if (strFileVersion == null) + strFileVersion = GetVersion().ToString(); + + // Create the file. + CreateVersionInfoResource( + assemblyFileName, + m_assemblyData.m_nativeVersion.m_strTitle, // title + null, // Icon filename + m_assemblyData.m_nativeVersion.m_strDescription, // description + m_assemblyData.m_nativeVersion.m_strCopyright, + m_assemblyData.m_nativeVersion.m_strTrademark, + m_assemblyData.m_nativeVersion.m_strCompany, + m_assemblyData.m_nativeVersion.m_strProduct, + m_assemblyData.m_nativeVersion.m_strProductVersion, + strFileVersion, + m_assemblyData.m_nativeVersion.m_lcid, + m_assemblyData.m_peFileKind == PEFileKinds.Dll, + JitHelpers.GetStringHandleOnStack(ref tmpVersionFile)); + + onDiskAssemblyModule.DefineUnmanagedResourceFileInternalNoLock(tmpVersionFile); + } + + if (assemblyModule == null) + { + + // This is for introducing the MRs for CA's type. This case is for stand alone + // manifest. We need to wait till PrepareForSavingManifestToDisk is called. + // That will trigger the creation of the on-disk stand alone manifest module. + // + for (i=0; i < m_assemblyData.m_iCABuilder; i++) + { + tkAttrs[i] = m_assemblyData.m_CABuilders[i].PrepareCreateCustomAttributeToDisk( + onDiskAssemblyModule); + } + for (i=0; i < m_assemblyData.m_iCAs; i++) + { + tkAttrs2[i] = onDiskAssemblyModule.InternalGetConstructorToken(m_assemblyData.m_CACons[i], true).Token; + } + } + + // 2. save all of the persistable modules contained by this AssemblyBuilder except the module that is going to contain + // Assembly information + // + // 3. create the file list in the manifest and track the file token. If it is embedded assembly, + // the assembly file should not be on the file list. + // + size = m_assemblyData.m_moduleBuilderList.Count; + for (i = 0; i < size; i++) + { + ModuleBuilder mBuilder = (ModuleBuilder) m_assemblyData.m_moduleBuilderList[i]; + if (mBuilder.IsTransient() == false && mBuilder != assemblyModule) + { + strModFileName = mBuilder.m_moduleData.m_strFileName; + if (m_assemblyData.m_strDir != null) + { + strModFileName = Path.Combine(m_assemblyData.m_strDir, strModFileName); + strModFileName = Path.GetFullPath(strModFileName); + } + + // Check caller has the right to create the Module file itself. + new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Append, strModFileName).Demand(); + + mBuilder.m_moduleData.FileToken = AddFile(GetNativeHandle(), mBuilder.m_moduleData.m_strFileName); + mBuilder.PreSave(strModFileName, portableExecutableKind, imageFileMachine); + mBuilder.Save(strModFileName, false, portableExecutableKind, imageFileMachine); + + // Cannot set the hash value when creating the file since the file token + // is needed to created the entries for the embedded resources in the + // module and the resources need to be there before you figure the hash. + SetFileHashValue(GetNativeHandle(), mBuilder.m_moduleData.FileToken, strModFileName); + } + } + + // 4. Add the public ComType + for (i=0; i < m_assemblyData.m_iPublicComTypeCount; i++) + { + type = m_assemblyData.m_publicComTypeList[i]; + // If the type that was added as a Public Com Type was obtained via Reflection, + // it will be a System.RuntimeType, even if it was really, at the same time, + // a TypeBuilder. Unfortunately, you can't get back to the TypeBuilder, so + // this code has to deal with either-or. + if (type is RuntimeType) + { + // If type is a runtime type, it must be a baked TypeBuilder, + // ttype.Module should be an InternalModuleBuilder + + InternalModuleBuilder internalMB = (InternalModuleBuilder)type.Module; + modBuilder = this.GetModuleBuilder(internalMB); + if (modBuilder != assemblyModule) + DefineNestedComType(type, modBuilder.m_moduleData.FileToken, type.MetadataToken); + } + else + { + // Could assert that "type" is a TypeBuilder, but next statement throws if it isn't. + typeBuilder = (TypeBuilder) type; + // If type is a TypeBuilder, type.Module must be a ModuleBuilder. + modBuilder = typeBuilder.GetModuleBuilder(); + if (modBuilder != assemblyModule) + DefineNestedComType(type, modBuilder.m_moduleData.FileToken, typeBuilder.MetadataTokenInternal); + } + } + + // 5. write AssemblyDef's CAs (only if we are not saving directly the manifest module itself) + if (onDiskAssemblyModule != m_manifestModuleBuilder) + { + for (i = 0; i < m_assemblyData.m_iCABuilder; i++) + { + m_assemblyData.m_CABuilders[i].CreateCustomAttribute( + onDiskAssemblyModule, + AssemblyBuilderData.m_tkAssembly, // This is the AssemblyDef token + tkAttrs[i], true); + } + + for (i = 0; i < m_assemblyData.m_iCAs; i++) + { + TypeBuilder.DefineCustomAttribute( + onDiskAssemblyModule, // pass in the in-memory assembly module + AssemblyBuilderData.m_tkAssembly, // This is the AssemblyDef token + tkAttrs2[i], + m_assemblyData.m_CABytes[i], + true, false); + } + } + + // 6. write security permission requests to the manifest. +#pragma warning disable 618 + if (m_assemblyData.m_RequiredPset != null) + AddDeclarativeSecurity(m_assemblyData.m_RequiredPset, SecurityAction.RequestMinimum); + + if (m_assemblyData.m_RefusedPset != null) + AddDeclarativeSecurity(m_assemblyData.m_RefusedPset, SecurityAction.RequestRefuse); + + if (m_assemblyData.m_OptionalPset != null) + AddDeclarativeSecurity(m_assemblyData.m_OptionalPset, SecurityAction.RequestOptional); +#pragma warning restore 618 + + // 7. Save the stand alone managed resources + size = m_assemblyData.m_resWriterList.Count; + for (i = 0; i < size; i++) + { + tempRes = null; + + try + { + tempRes = (ResWriterData)m_assemblyData.m_resWriterList[i]; + + // If the user added an existing resource to the manifest, the + // corresponding ResourceWriter will be null. + if (tempRes.m_resWriter != null) + // Check caller has the right to create the Resource file itself. + new FileIOPermission(FileIOPermissionAccess.Write | FileIOPermissionAccess.Append, tempRes.m_strFullFileName).Demand(); + } + finally + { + if (tempRes != null && tempRes.m_resWriter != null) + tempRes.m_resWriter.Close(); + } + + // Add entry to manifest for this stand alone resource + AddStandAloneResource(GetNativeHandle(), tempRes.m_strName, tempRes.m_strFileName, tempRes.m_strFullFileName, (int)tempRes.m_attribute); + } + + // Save now!! + if (assemblyModule == null) + { + onDiskAssemblyModule.DefineNativeResource(portableExecutableKind, imageFileMachine); + + // Stand alone manifest + int entryPoint = (m_assemblyData.m_entryPointModule != null) ? m_assemblyData.m_entryPointModule.m_moduleData.FileToken : 0; + + SaveManifestToDisk(GetNativeHandle(), assemblyFileName, entryPoint, (int)m_assemblyData.m_peFileKind, + (int)portableExecutableKind, (int)imageFileMachine); + } + else + { + // embedded manifest + + // If the module containing the entry point is not the manifest file, we need to + // let the manifest file point to the module which contains the entry point. + // + // + // + // + if (m_assemblyData.m_entryPointModule != null && m_assemblyData.m_entryPointModule != assemblyModule) + assemblyModule.SetEntryPoint(new MethodToken(m_assemblyData.m_entryPointModule.m_moduleData.FileToken)); + assemblyModule.Save(assemblyFileName, true, portableExecutableKind, imageFileMachine); + } + m_assemblyData.m_isSaved = true; + } + finally + { + if (tmpVersionFile != null) + { + // Delete file. + System.IO.File.Delete(tmpVersionFile); + } + } + } +#endif // FEATURE_CORECLR + +#if FEATURE_CAS_POLICY + [System.Security.SecurityCritical] // auto-generated + private void AddDeclarativeSecurity(PermissionSet pset, SecurityAction action) + { + // Translate sets into internal encoding (uses standard binary serialization). + byte[] blob = pset.EncodeXml(); + AddDeclarativeSecurity(GetNativeHandle(), action, blob, blob.Length); + } +#endif // FEATURE_CAS_POLICY + + internal bool IsPersistable() + { +#if !FEATURE_CORECLR // AssemblyBuilderAccess.Save is never set in CoreCLR + if ((m_assemblyData.m_access & AssemblyBuilderAccess.Save) == AssemblyBuilderAccess.Save) + { + return true; + } + else +#endif // FEATURE_CORECLR + { + return false; + } + } + + /********************************************** + * + * Internal helper to walk the nested type hierachy + * + **********************************************/ + [System.Security.SecurityCritical] // auto-generated + private int DefineNestedComType(Type type, int tkResolutionScope, int tkTypeDef) + { + Type enclosingType = type.DeclaringType; + if (enclosingType == null) + { + // Use full type name for non-nested types. + return AddExportedTypeOnDisk(GetNativeHandle(), type.FullName, tkResolutionScope, tkTypeDef, type.Attributes); + } + + tkResolutionScope = DefineNestedComType(enclosingType, tkResolutionScope, tkTypeDef); + // Use simple name for nested types. + return AddExportedTypeOnDisk(GetNativeHandle(), type.Name, tkResolutionScope, tkTypeDef, type.Attributes); + } + + [System.Security.SecurityCritical] // auto-generated + internal int DefineExportedTypeInMemory(Type type, int tkResolutionScope, int tkTypeDef) + { + Type enclosingType = type.DeclaringType; + if (enclosingType == null) + { + // Use full type name for non-nested types. + return AddExportedTypeInMemory(GetNativeHandle(), type.FullName, tkResolutionScope, tkTypeDef, type.Attributes); + } + + tkResolutionScope = DefineExportedTypeInMemory(enclosingType, tkResolutionScope, tkTypeDef); + // Use simple name for nested types. + return AddExportedTypeInMemory(GetNativeHandle(), type.Name, tkResolutionScope, tkTypeDef, type.Attributes); + } + + /********************************************** + * + * Private methods + * + **********************************************/ + + /********************************************** + * Make a private constructor so these cannot be constructed externally. + * @internonly + **********************************************/ + private AssemblyBuilder() {} + +#if !FEATURE_CORECLR + void _AssemblyBuilder.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _AssemblyBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _AssemblyBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + // If you implement this method, make sure to include _AssemblyBuilder.Invoke in VM\DangerousAPIs.h and + // include _AssemblyBuilder in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp. + void _AssemblyBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + + // Create a new module in which to emit code. This module will not contain the manifest. + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + static private extern void DefineDynamicModule(RuntimeAssembly containingAssembly, + bool emitSymbolInfo, + String name, + String filename, + StackCrawlMarkHandle stackMark, + ref IntPtr pInternalSymWriter, + ObjectHandleOnStack retModule, + bool fIsTransient, + out int tkFile); + + [System.Security.SecurityCritical] // auto-generated + private static Module DefineDynamicModule(RuntimeAssembly containingAssembly, + bool emitSymbolInfo, + String name, + String filename, + ref StackCrawlMark stackMark, + ref IntPtr pInternalSymWriter, + bool fIsTransient, + out int tkFile) + { + RuntimeModule retModule = null; + + DefineDynamicModule(containingAssembly.GetNativeHandle(), + emitSymbolInfo, + name, + filename, + JitHelpers.GetStackCrawlMarkHandle(ref stackMark), + ref pInternalSymWriter, + JitHelpers.GetObjectHandleOnStack(ref retModule), + fIsTransient, + out tkFile); + + return retModule; + } + + // The following functions are native helpers for creating on-disk manifest + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + static private extern void PrepareForSavingManifestToDisk(RuntimeAssembly assembly, RuntimeModule assemblyModule); // module to contain assembly information if assembly is embedded + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + static private extern void SaveManifestToDisk(RuntimeAssembly assembly, + String strFileName, + int entryPoint, + int fileKind, + int portableExecutableKind, + int ImageFileMachine); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + static private extern int AddFile(RuntimeAssembly assembly, String strFileName); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + static private extern void SetFileHashValue(RuntimeAssembly assembly, + int tkFile, + String strFullFileName); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + static private extern int AddExportedTypeInMemory(RuntimeAssembly assembly, + String strComTypeName, + int tkAssemblyRef, + int tkTypeDef, + TypeAttributes flags); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + static private extern int AddExportedTypeOnDisk(RuntimeAssembly assembly, + String strComTypeName, + int tkAssemblyRef, + int tkTypeDef, + TypeAttributes flags); + + // Add an entry to assembly's manifestResource table for a stand alone resource. + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + static private extern void AddStandAloneResource(RuntimeAssembly assembly, + String strName, + String strFileName, + String strFullFileName, + int attribute); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] +#pragma warning disable 618 + static private extern void AddDeclarativeSecurity(RuntimeAssembly assembly, SecurityAction action, byte[] blob, int length); +#pragma warning restore 618 + + // Functions for defining unmanaged resources. + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + static private extern void CreateVersionInfoResource(String filename, String title, String iconFilename, String description, + String copyright, String trademark, String company, String product, + String productVersion, String fileVersion, int lcid, bool isDll, + StringHandleOnStack retFileName); + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderAccess.cs b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderAccess.cs new file mode 100644 index 0000000000..00a961dd89 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderAccess.cs @@ -0,0 +1,29 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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; + +// This enumeration defines the access modes for a dynamic assembly. +// EE uses these enum values..look for m_dwDynamicAssemblyAccess in Assembly.hpp + +namespace System.Reflection.Emit +{ + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + [Flags] + public enum AssemblyBuilderAccess + { + Run = 1, +#if !FEATURE_CORECLR // these are unsupported + Save = 2, + RunAndSave = Run | Save, +#endif // !FEATURE_CORECLR +#if FEATURE_REFLECTION_ONLY_LOAD + ReflectionOnly = 6, // 4 | Save, +#endif // FEATURE_REFLECTION_ONLY_LOAD +#if FEATURE_COLLECTIBLE_TYPES + RunAndCollect = 8 | Run +#endif + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderData.cs b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderData.cs new file mode 100644 index 0000000000..f1a38c611b --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/AssemblyBuilderData.cs @@ -0,0 +1,583 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// + +namespace System.Reflection.Emit { + using System; + using IList = System.Collections.IList; + using System.Collections.Generic; + using System.Reflection; + using System.Security; + using System.Diagnostics; + using CultureInfo = System.Globalization.CultureInfo; +#if !FEATURE_CORECLR + using ResourceWriter = System.Resources.ResourceWriter; +#else // FEATURE_CORECLR + using IResourceWriter = System.Resources.IResourceWriter; +#endif // !FEATURE_CORECLR + using System.IO; + using System.Runtime.Versioning; + using System.Diagnostics.SymbolStore; + using System.Diagnostics.Contracts; + + // This is a package private class. This class hold all of the managed + // data member for AssemblyBuilder. Note that what ever data members added to + // this class cannot be accessed from the EE. + internal class AssemblyBuilderData + { + [SecurityCritical] + internal AssemblyBuilderData( + InternalAssemblyBuilder assembly, + String strAssemblyName, + AssemblyBuilderAccess access, + String dir) + { + m_assembly = assembly; + m_strAssemblyName = strAssemblyName; + m_access = access; + m_moduleBuilderList = new List(); + m_resWriterList = new List(); + + //Init to null/0 done for you by the CLR. FXCop has spoken + + if (dir == null && access != AssemblyBuilderAccess.Run) + m_strDir = Environment.CurrentDirectory; + else + m_strDir = dir; + + m_peFileKind = PEFileKinds.Dll; + } + + // Helper to add a dynamic module into the tracking list + internal void AddModule(ModuleBuilder dynModule) + { + m_moduleBuilderList.Add(dynModule); + } + + // Helper to add a resource information into the tracking list + internal void AddResWriter(ResWriterData resData) + { + m_resWriterList.Add(resData); + } + + + // Helper to track CAs to persist onto disk + internal void AddCustomAttribute(CustomAttributeBuilder customBuilder) + { + + // make sure we have room for this CA + if (m_CABuilders == null) + { + m_CABuilders = new CustomAttributeBuilder[m_iInitialSize]; + } + if (m_iCABuilder == m_CABuilders.Length) + { + CustomAttributeBuilder[] tempCABuilders = new CustomAttributeBuilder[m_iCABuilder * 2]; + Array.Copy(m_CABuilders, 0, tempCABuilders, 0, m_iCABuilder); + m_CABuilders = tempCABuilders; + } + m_CABuilders[m_iCABuilder] = customBuilder; + + m_iCABuilder++; + } + + // Helper to track CAs to persist onto disk + internal void AddCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + { + + // make sure we have room for this CA + if (m_CABytes == null) + { + m_CABytes = new byte[m_iInitialSize][]; + m_CACons = new ConstructorInfo[m_iInitialSize]; + } + if (m_iCAs == m_CABytes.Length) + { + // enlarge the arrays + byte[][] temp = new byte[m_iCAs * 2][]; + ConstructorInfo[] tempCon = new ConstructorInfo[m_iCAs * 2]; + for (int i=0; i < m_iCAs; i++) + { + temp[i] = m_CABytes[i]; + tempCon[i] = m_CACons[i]; + } + m_CABytes = temp; + m_CACons = tempCon; + } + + byte[] attrs = new byte[binaryAttribute.Length]; + Buffer.BlockCopy(binaryAttribute, 0, attrs, 0, binaryAttribute.Length); + m_CABytes[m_iCAs] = attrs; + m_CACons[m_iCAs] = con; + m_iCAs++; + } + + // Helper to calculate unmanaged version info from Assembly's custom attributes. + // If DefineUnmanagedVersionInfo is called, the parameter provided will override + // the CA's value. + // + [System.Security.SecurityCritical] // auto-generated + internal void FillUnmanagedVersionInfo() + { + // Get the lcid set on the assembly name as default if available + // Note that if LCID is not avaible from neither AssemblyName or AssemblyCultureAttribute, + // it is default to -1 which is treated as language neutral. + // + CultureInfo locale = m_assembly.GetLocale(); +#if FEATURE_USE_LCID + if (locale != null) + m_nativeVersion.m_lcid = locale.LCID; +#endif + + for (int i = 0; i < m_iCABuilder; i++) + { + // check for known attributes + Type conType = m_CABuilders[i].m_con.DeclaringType; + if (m_CABuilders[i].m_constructorArgs.Length == 0 || m_CABuilders[i].m_constructorArgs[0] == null) + continue; + + if (conType.Equals(typeof(System.Reflection.AssemblyCopyrightAttribute))) + { + // assert that we should only have one argument for this CA and the type should + // be a string. + // + if (m_CABuilders[i].m_constructorArgs.Length != 1) + { + throw new ArgumentException(Environment.GetResourceString( + "Argument_BadCAForUnmngRSC", + m_CABuilders[i].m_con.ReflectedType.Name)); + } + if (m_OverrideUnmanagedVersionInfo == false) + { + m_nativeVersion.m_strCopyright = m_CABuilders[i].m_constructorArgs[0].ToString(); + } + } + else if (conType.Equals(typeof(System.Reflection.AssemblyTrademarkAttribute))) + { + // assert that we should only have one argument for this CA and the type should + // be a string. + // + if (m_CABuilders[i].m_constructorArgs.Length != 1) + { + throw new ArgumentException(Environment.GetResourceString( + "Argument_BadCAForUnmngRSC", + m_CABuilders[i].m_con.ReflectedType.Name)); + } + if (m_OverrideUnmanagedVersionInfo == false) + { + m_nativeVersion.m_strTrademark = m_CABuilders[i].m_constructorArgs[0].ToString(); + } + } + else if (conType.Equals(typeof(System.Reflection.AssemblyProductAttribute))) + { + if (m_OverrideUnmanagedVersionInfo == false) + { + // assert that we should only have one argument for this CA and the type should + // be a string. + // + m_nativeVersion.m_strProduct = m_CABuilders[i].m_constructorArgs[0].ToString(); + } + } + else if (conType.Equals(typeof(System.Reflection.AssemblyCompanyAttribute))) + { + if (m_CABuilders[i].m_constructorArgs.Length != 1) + { + throw new ArgumentException(Environment.GetResourceString( + "Argument_BadCAForUnmngRSC", + m_CABuilders[i].m_con.ReflectedType.Name)); + } + if (m_OverrideUnmanagedVersionInfo == false) + { + // assert that we should only have one argument for this CA and the type should + // be a string. + // + m_nativeVersion.m_strCompany = m_CABuilders[i].m_constructorArgs[0].ToString(); + } + } + else if (conType.Equals(typeof(System.Reflection.AssemblyDescriptionAttribute))) + { + if (m_CABuilders[i].m_constructorArgs.Length != 1) + { + throw new ArgumentException(Environment.GetResourceString( + "Argument_BadCAForUnmngRSC", + m_CABuilders[i].m_con.ReflectedType.Name)); + } + m_nativeVersion.m_strDescription = m_CABuilders[i].m_constructorArgs[0].ToString(); + } + else if (conType.Equals(typeof(System.Reflection.AssemblyTitleAttribute))) + { + if (m_CABuilders[i].m_constructorArgs.Length != 1) + { + throw new ArgumentException(Environment.GetResourceString( + "Argument_BadCAForUnmngRSC", + m_CABuilders[i].m_con.ReflectedType.Name)); + } + m_nativeVersion.m_strTitle = m_CABuilders[i].m_constructorArgs[0].ToString(); + } + else if (conType.Equals(typeof(System.Reflection.AssemblyInformationalVersionAttribute))) + { + if (m_CABuilders[i].m_constructorArgs.Length != 1) + { + throw new ArgumentException(Environment.GetResourceString( + "Argument_BadCAForUnmngRSC", + m_CABuilders[i].m_con.ReflectedType.Name)); + } + if (m_OverrideUnmanagedVersionInfo == false) + { + m_nativeVersion.m_strProductVersion = m_CABuilders[i].m_constructorArgs[0].ToString(); + } + } + else if (conType.Equals(typeof(System.Reflection.AssemblyCultureAttribute))) + { + // retrieve the LCID + if (m_CABuilders[i].m_constructorArgs.Length != 1) + { + throw new ArgumentException(Environment.GetResourceString( + "Argument_BadCAForUnmngRSC", + m_CABuilders[i].m_con.ReflectedType.Name)); + } + // CultureInfo attribute overrides the lcid from AssemblyName. + CultureInfo culture = new CultureInfo(m_CABuilders[i].m_constructorArgs[0].ToString()); +#if FEATURE_USE_LCID + m_nativeVersion.m_lcid = culture.LCID; +#endif + } + else if (conType.Equals(typeof(System.Reflection.AssemblyFileVersionAttribute))) + { + if (m_CABuilders[i].m_constructorArgs.Length != 1) + { + throw new ArgumentException(Environment.GetResourceString( + "Argument_BadCAForUnmngRSC", + m_CABuilders[i].m_con.ReflectedType.Name)); + } + if (m_OverrideUnmanagedVersionInfo == false) + { + m_nativeVersion.m_strFileVersion = m_CABuilders[i].m_constructorArgs[0].ToString(); + } + } + } + } + + + // Helper to ensure the resource name is unique underneath assemblyBuilder + internal void CheckResNameConflict(String strNewResName) + { + int size = m_resWriterList.Count; + int i; + for (i = 0; i < size; i++) + { + ResWriterData resWriter = m_resWriterList[i]; + if (resWriter.m_strName.Equals(strNewResName)) + { + // Cannot have two resources with the same name + throw new ArgumentException(Environment.GetResourceString("Argument_DuplicateResourceName")); + } + } + } + + + // Helper to ensure the module name is unique underneath assemblyBuilder + internal void CheckNameConflict(String strNewModuleName) + { + int size = m_moduleBuilderList.Count; + int i; + for (i = 0; i < size; i++) + { + ModuleBuilder moduleBuilder = m_moduleBuilderList[i]; + if (moduleBuilder.m_moduleData.m_strModuleName.Equals(strNewModuleName)) + { + // Cannot have two dynamic modules with the same name + throw new ArgumentException(Environment.GetResourceString("Argument_DuplicateModuleName")); + } + } + + // Right now dynamic modules can only be added to dynamic assemblies in which + // all modules are dynamic. Otherwise we would also need to check the static modules + // with this: + // if (m_assembly.GetModule(strNewModuleName) != null) + // { + // // Cannot have two dynamic modules with the same name + // throw new ArgumentException(Environment.GetResourceString("Argument_DuplicateModuleName")); + // } + } + + // Helper to ensure the type name is unique underneath assemblyBuilder + internal void CheckTypeNameConflict(String strTypeName, TypeBuilder enclosingType) + { + BCLDebug.Log("DYNIL","## DYNIL LOGGING: AssemblyBuilderData.CheckTypeNameConflict( " + strTypeName + " )"); + for (int i = 0; i < m_moduleBuilderList.Count; i++) + { + ModuleBuilder curModule = m_moduleBuilderList[i]; + curModule.CheckTypeNameConflict(strTypeName, enclosingType); + } + + // Right now dynamic modules can only be added to dynamic assemblies in which + // all modules are dynamic. Otherwise we would also need to check loaded types. + // We only need to make this test for non-nested types since any + // duplicates in nested types will be caught at the top level. + // if (enclosingType == null && m_assembly.GetType(strTypeName, false, false) != null) + // { + // // Cannot have two types with the same name + // throw new ArgumentException(Environment.GetResourceString("Argument_DuplicateTypeName")); + // } + } + + + // Helper to ensure the file name is unique underneath assemblyBuilder. This includes + // modules and resources. + // + // + // + internal void CheckFileNameConflict(String strFileName) + { + int size = m_moduleBuilderList.Count; + int i; + for (i = 0; i < size; i++) + { + ModuleBuilder moduleBuilder = m_moduleBuilderList[i]; + if (moduleBuilder.m_moduleData.m_strFileName != null) + { + if (String.Compare(moduleBuilder.m_moduleData.m_strFileName, strFileName, StringComparison.OrdinalIgnoreCase) == 0) + { + // Cannot have two dynamic module with the same name + throw new ArgumentException(Environment.GetResourceString("Argument_DuplicatedFileName")); + } + } + } + size = m_resWriterList.Count; + for (i = 0; i < size; i++) + { + ResWriterData resWriter = m_resWriterList[i]; + if (resWriter.m_strFileName != null) + { + if (String.Compare(resWriter.m_strFileName, strFileName, StringComparison.OrdinalIgnoreCase) == 0) + { + // Cannot have two dynamic module with the same name + throw new ArgumentException(Environment.GetResourceString("Argument_DuplicatedFileName")); + } + } + } + + } + + // Helper to look up which module that assembly is supposed to be stored at + // + // + // + internal ModuleBuilder FindModuleWithFileName(String strFileName) + { + int size = m_moduleBuilderList.Count; + int i; + for (i = 0; i < size; i++) + { + ModuleBuilder moduleBuilder = m_moduleBuilderList[i]; + if (moduleBuilder.m_moduleData.m_strFileName != null) + { + if (String.Compare(moduleBuilder.m_moduleData.m_strFileName, strFileName, StringComparison.OrdinalIgnoreCase) == 0) + { + return moduleBuilder; + } + } + } + return null; + } + + // Helper to look up module by name. + // + // + // + internal ModuleBuilder FindModuleWithName(String strName) + { + int size = m_moduleBuilderList.Count; + int i; + for (i = 0; i < size; i++) + { + ModuleBuilder moduleBuilder = m_moduleBuilderList[i]; + if (moduleBuilder.m_moduleData.m_strModuleName != null) + { + if (String.Compare(moduleBuilder.m_moduleData.m_strModuleName, strName, StringComparison.OrdinalIgnoreCase) == 0) + return moduleBuilder; + } + } + return null; + } + + + // add type to public COMType tracking list + internal void AddPublicComType(Type type) + { + BCLDebug.Log("DYNIL","## DYNIL LOGGING: AssemblyBuilderData.AddPublicComType( " + type.FullName + " )"); + if (m_isSaved == true) + { + // assembly has been saved before! + throw new InvalidOperationException(Environment.GetResourceString( + "InvalidOperation_CannotAlterAssembly")); + } + EnsurePublicComTypeCapacity(); + m_publicComTypeList[m_iPublicComTypeCount] = type; + m_iPublicComTypeCount++; + } + + // add security permission requests + internal void AddPermissionRequests( + PermissionSet required, + PermissionSet optional, + PermissionSet refused) + { + BCLDebug.Log("DYNIL","## DYNIL LOGGING: AssemblyBuilderData.AddPermissionRequests"); + if (m_isSaved == true) + { + // assembly has been saved before! + throw new InvalidOperationException(Environment.GetResourceString( + "InvalidOperation_CannotAlterAssembly")); + } + m_RequiredPset = required; + m_OptionalPset = optional; + m_RefusedPset = refused; + } + + private void EnsurePublicComTypeCapacity() + { + if (m_publicComTypeList == null) + { + m_publicComTypeList = new Type[m_iInitialSize]; + } + if (m_iPublicComTypeCount == m_publicComTypeList.Length) + { + Type[] tempTypeList = new Type[m_iPublicComTypeCount * 2]; + Array.Copy(m_publicComTypeList, 0, tempTypeList, 0, m_iPublicComTypeCount); + m_publicComTypeList = tempTypeList; + } + } + + internal List m_moduleBuilderList; + internal List m_resWriterList; + internal String m_strAssemblyName; + internal AssemblyBuilderAccess m_access; + private InternalAssemblyBuilder m_assembly; + + internal Type[] m_publicComTypeList; + internal int m_iPublicComTypeCount; + + internal bool m_isSaved; + internal const int m_iInitialSize = 16; + internal String m_strDir; + + // hard coding the assembly def token + internal const int m_tkAssembly = 0x20000001; + + // Security permission requests + internal PermissionSet m_RequiredPset; + internal PermissionSet m_OptionalPset; + internal PermissionSet m_RefusedPset; + + // tracking AssemblyDef's CAs for persistence to disk + internal CustomAttributeBuilder[] m_CABuilders; + internal int m_iCABuilder; + internal byte[][] m_CABytes; + internal ConstructorInfo[] m_CACons; + internal int m_iCAs; + internal PEFileKinds m_peFileKind; // assembly file kind + internal MethodInfo m_entryPointMethod; + internal Assembly m_ISymWrapperAssembly; + +#if !FEATURE_CORECLR + internal ModuleBuilder m_entryPointModule; +#endif //!FEATURE_CORECLR + + // For unmanaged resources + internal String m_strResourceFileName; + internal byte[] m_resourceBytes; + internal NativeVersionInfo m_nativeVersion; + internal bool m_hasUnmanagedVersionInfo; + internal bool m_OverrideUnmanagedVersionInfo; + + } + + + /********************************************** + * + * Internal structure to track the list of ResourceWriter for + * AssemblyBuilder & ModuleBuilder. + * + **********************************************/ + internal class ResWriterData + { +#if FEATURE_CORECLR + internal ResWriterData( + IResourceWriter resWriter, + Stream memoryStream, + String strName, + String strFileName, + String strFullFileName, + ResourceAttributes attribute) + { + m_resWriter = resWriter; + m_memoryStream = memoryStream; + m_strName = strName; + m_strFileName = strFileName; + m_strFullFileName = strFullFileName; + m_nextResWriter = null; + m_attribute = attribute; + } +#else + internal ResWriterData( + ResourceWriter resWriter, + Stream memoryStream, + String strName, + String strFileName, + String strFullFileName, + ResourceAttributes attribute) + { + m_resWriter = resWriter; + m_memoryStream = memoryStream; + m_strName = strName; + m_strFileName = strFileName; + m_strFullFileName = strFullFileName; + m_nextResWriter = null; + m_attribute = attribute; + } +#endif +#if !FEATURE_CORECLR + internal ResourceWriter m_resWriter; +#else // FEATURE_CORECLR + internal IResourceWriter m_resWriter; +#endif // !FEATURE_CORECLR + internal String m_strName; + internal String m_strFileName; + internal String m_strFullFileName; + internal Stream m_memoryStream; + internal ResWriterData m_nextResWriter; + internal ResourceAttributes m_attribute; + } + + internal class NativeVersionInfo + { + internal NativeVersionInfo() + { + m_strDescription = null; + m_strCompany = null; + m_strTitle = null; + m_strCopyright = null; + m_strTrademark = null; + m_strProduct = null; + m_strProductVersion = null; + m_strFileVersion = null; + m_lcid = -1; + } + + internal String m_strDescription; + internal String m_strCompany; + internal String m_strTitle; + internal String m_strCopyright; + internal String m_strTrademark; + internal String m_strProduct; + internal String m_strProductVersion; + internal String m_strFileVersion; + internal int m_lcid; + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/ComInterfaces.cs b/src/mscorlib/src/System/Reflection/Emit/ComInterfaces.cs new file mode 100644 index 0000000000..0d8ce5a8d4 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/ComInterfaces.cs @@ -0,0 +1,288 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Globalization; +using System.IO; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.Serialization; +using System.Security.Permissions; +using System.Security.Policy; + +namespace System.Runtime.InteropServices +{ + [GuidAttribute("BEBB2505-8B54-3443-AEAD-142A16DD9CC7")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Emit.AssemblyBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _AssemblyBuilder + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + + [GuidAttribute("ED3E4384-D7E2-3FA7-8FFD-8940D330519A")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Emit.ConstructorBuilder))] + [System.Runtime.InteropServices.ComVisible(true)] + public interface _ConstructorBuilder + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + + [GuidAttribute("BE9ACCE8-AAFF-3B91-81AE-8211663F5CAD")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Emit.CustomAttributeBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _CustomAttributeBuilder + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + + [GuidAttribute("C7BD73DE-9F85-3290-88EE-090B8BDFE2DF")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Emit.EnumBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _EnumBuilder + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + + [GuidAttribute("AADABA99-895D-3D65-9760-B1F12621FAE8")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Emit.EventBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _EventBuilder + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + + [GuidAttribute("CE1A3BF5-975E-30CC-97C9-1EF70F8F3993")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Emit.FieldBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _FieldBuilder + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + + [GuidAttribute("A4924B27-6E3B-37F7-9B83-A4501955E6A7")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Emit.ILGenerator))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _ILGenerator + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + + [GuidAttribute("4E6350D1-A08B-3DEC-9A3E-C465F9AEEC0C")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Emit.LocalBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _LocalBuilder + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + + [GuidAttribute("007D8A14-FDF3-363E-9A0B-FEC0618260A2")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Emit.MethodBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _MethodBuilder + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + +#if FEATURE_METHOD_RENTAL + [GuidAttribute("C2323C25-F57F-3880-8A4D-12EBEA7A5852")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Emit.MethodRental))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _MethodRental + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } +#endif + + [GuidAttribute("D05FFA9A-04AF-3519-8EE1-8D93AD73430B")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Emit.ModuleBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _ModuleBuilder + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + + [GuidAttribute("36329EBA-F97A-3565-BC07-0ED5C6EF19FC")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Emit.ParameterBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _ParameterBuilder + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + + [GuidAttribute("15F9A479-9397-3A63-ACBD-F51977FB0F02")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Emit.PropertyBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _PropertyBuilder + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + + [GuidAttribute("7D13DD37-5A04-393C-BBCA-A5FEA802893D")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Emit.SignatureHelper))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _SignatureHelper + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + + [GuidAttribute("7E5678EE-48B3-3F83-B076-C58543498A58")] + [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] + [CLSCompliant(false)] + [TypeLibImportClassAttribute(typeof(System.Reflection.Emit.TypeBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + public interface _TypeBuilder + { +#if !FEATURE_CORECLR + void GetTypeInfoCount(out uint pcTInfo); + + void GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo); + + void GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId); + + void Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr); +#endif + } + +} diff --git a/src/mscorlib/src/System/Reflection/Emit/ConstructorBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/ConstructorBuilder.cs new file mode 100644 index 0000000000..e5062d3365 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/ConstructorBuilder.cs @@ -0,0 +1,335 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection.Emit +{ + using System; + using System.Reflection; + using CultureInfo = System.Globalization.CultureInfo; + using System.Collections.Generic; + using System.Diagnostics.SymbolStore; + using System.Security; + using System.Security.Permissions; + using System.Runtime.InteropServices; + using System.Diagnostics.Contracts; + + [HostProtection(MayLeakOnAbort = true)] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_ConstructorBuilder))] + [System.Runtime.InteropServices.ComVisible(true)] + public sealed class ConstructorBuilder : ConstructorInfo, _ConstructorBuilder + { + private readonly MethodBuilder m_methodBuilder; + internal bool m_isDefaultConstructor; + + #region Constructor + + private ConstructorBuilder() + { + } + + [System.Security.SecurityCritical] // auto-generated + internal ConstructorBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention, + Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers, ModuleBuilder mod, TypeBuilder type) + { + int sigLength; + byte[] sigBytes; + MethodToken token; + + m_methodBuilder = new MethodBuilder(name, attributes, callingConvention, null, null, null, + parameterTypes, requiredCustomModifiers, optionalCustomModifiers, mod, type, false); + + type.m_listMethods.Add(m_methodBuilder); + + sigBytes = m_methodBuilder.GetMethodSignature().InternalGetSignature(out sigLength); + + token = m_methodBuilder.GetToken(); + } + + [System.Security.SecurityCritical] // auto-generated + internal ConstructorBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention, + Type[] parameterTypes, ModuleBuilder mod, TypeBuilder type) : + this(name, attributes, callingConvention, parameterTypes, null, null, mod, type) + { + } + + #endregion + + #region Internal + internal override Type[] GetParameterTypes() + { + return m_methodBuilder.GetParameterTypes(); + } + + private TypeBuilder GetTypeBuilder() + { + return m_methodBuilder.GetTypeBuilder(); + } + + internal ModuleBuilder GetModuleBuilder() + { + return GetTypeBuilder().GetModuleBuilder(); + } + #endregion + + #region Object Overrides + public override String ToString() + { + return m_methodBuilder.ToString(); + } + + #endregion + + #region MemberInfo Overrides + internal int MetadataTokenInternal + { + get { return m_methodBuilder.MetadataTokenInternal; } + } + + public override Module Module + { + get { return m_methodBuilder.Module; } + } + + public override Type ReflectedType + { + get { return m_methodBuilder.ReflectedType; } + } + + public override Type DeclaringType + { + get { return m_methodBuilder.DeclaringType; } + } + + public override String Name + { + get { return m_methodBuilder.Name; } + } + + #endregion + + #region MethodBase Overrides + public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + [Pure] + public override ParameterInfo[] GetParameters() + { + ConstructorInfo rci = GetTypeBuilder().GetConstructor(m_methodBuilder.m_parameterTypes); + return rci.GetParameters(); + } + + public override MethodAttributes Attributes + { + get { return m_methodBuilder.Attributes; } + } + + public override MethodImplAttributes GetMethodImplementationFlags() + { + return m_methodBuilder.GetMethodImplementationFlags(); + } + + public override RuntimeMethodHandle MethodHandle + { + get { return m_methodBuilder.MethodHandle; } + } + + #endregion + + #region ConstructorInfo Overrides + public override Object Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + #endregion + + #region ICustomAttributeProvider Implementation + public override Object[] GetCustomAttributes(bool inherit) + { + return m_methodBuilder.GetCustomAttributes(inherit); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + return m_methodBuilder.GetCustomAttributes(attributeType, inherit); + } + + public override bool IsDefined (Type attributeType, bool inherit) + { + return m_methodBuilder.IsDefined(attributeType, inherit); + } + + #endregion + + #region Public Members + public MethodToken GetToken() + { + return m_methodBuilder.GetToken(); + } + + public ParameterBuilder DefineParameter(int iSequence, ParameterAttributes attributes, String strParamName) + { + // Theoretically we shouldn't allow iSequence to be 0 because in reflection ctors don't have + // return parameters. But we'll allow it for backward compatibility with V2. The attributes + // defined on the return parameters won't be very useful but won't do much harm either. + + // MD will assert if we try to set the reserved bits explicitly + attributes = attributes & ~ParameterAttributes.ReservedMask; + return m_methodBuilder.DefineParameter(iSequence, attributes, strParamName); + } + + public void SetSymCustomAttribute(String name, byte[] data) + { + m_methodBuilder.SetSymCustomAttribute(name, data); + } + + public ILGenerator GetILGenerator() + { + if (m_isDefaultConstructor) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_DefaultConstructorILGen")); + + return m_methodBuilder.GetILGenerator(); + } + + public ILGenerator GetILGenerator(int streamSize) + { + if (m_isDefaultConstructor) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_DefaultConstructorILGen")); + + return m_methodBuilder.GetILGenerator(streamSize); + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + public void SetMethodBody(byte[] il, int maxStack, byte[] localSignature, IEnumerable exceptionHandlers, IEnumerable tokenFixups) + { + if (m_isDefaultConstructor) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_DefaultConstructorDefineBody")); + } + + m_methodBuilder.SetMethodBody(il, maxStack, localSignature, exceptionHandlers, tokenFixups); + } + +#if FEATURE_CAS_POLICY + [System.Security.SecuritySafeCritical] // auto-generated + public void AddDeclarativeSecurity(SecurityAction action, PermissionSet pset) + { + if (pset == null) + throw new ArgumentNullException("pset"); + +#pragma warning disable 618 + if (!Enum.IsDefined(typeof(SecurityAction), action) || + action == SecurityAction.RequestMinimum || + action == SecurityAction.RequestOptional || + action == SecurityAction.RequestRefuse) + { + throw new ArgumentOutOfRangeException("action"); + } +#pragma warning restore 618 + Contract.EndContractBlock(); + + // Cannot add declarative security after type is created. + if (m_methodBuilder.IsTypeCreated()) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TypeHasBeenCreated")); + + // Translate permission set into serialized format (use standard binary serialization). + byte[] blob = pset.EncodeXml(); + + // Write the blob into the metadata. + TypeBuilder.AddDeclarativeSecurity(GetModuleBuilder().GetNativeHandle(), GetToken().Token, action, blob, blob.Length); + } +#endif // FEATURE_CAS_POLICY + + public override CallingConventions CallingConvention + { + get + { + if (DeclaringType.IsGenericType) + return CallingConventions.HasThis; + + return CallingConventions.Standard; + } + } + + public Module GetModule() + { + return m_methodBuilder.GetModule(); + } + + + [Obsolete("This property has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")] //It always returns null. + public Type ReturnType + { + get { return GetReturnType(); } + } + + // This always returns null. Is that what we want? + internal override Type GetReturnType() + { + return m_methodBuilder.ReturnType; + } + + public String Signature + { + get { return m_methodBuilder.Signature; } + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + [System.Runtime.InteropServices.ComVisible(true)] + public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + { + m_methodBuilder.SetCustomAttribute(con, binaryAttribute); + } + + public void SetCustomAttribute(CustomAttributeBuilder customBuilder) + { + m_methodBuilder.SetCustomAttribute(customBuilder); + } + + public void SetImplementationFlags(MethodImplAttributes attributes) + { + m_methodBuilder.SetImplementationFlags(attributes); + } + + public bool InitLocals + { + get { return m_methodBuilder.InitLocals; } + set { m_methodBuilder.InitLocals = value; } + } + + #endregion + +#if !FEATURE_CORECLR + void _ConstructorBuilder.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _ConstructorBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _ConstructorBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _ConstructorBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + } +} + diff --git a/src/mscorlib/src/System/Reflection/Emit/CustomAttributeBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/CustomAttributeBuilder.cs new file mode 100644 index 0000000000..2a29a5c190 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/CustomAttributeBuilder.cs @@ -0,0 +1,582 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** CustomAttributeBuilder is a helper class to help building custom attribute. +** +** +===========================================================*/ +namespace System.Reflection.Emit { + + + using System; + using System.Reflection; + using System.IO; + using System.Text; + using System.Security.Permissions; + using System.Runtime.InteropServices; + using System.Globalization; + using System.Diagnostics.Contracts; + + [HostProtection(MayLeakOnAbort = true)] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_CustomAttributeBuilder))] + [System.Runtime.InteropServices.ComVisible(true)] + public class CustomAttributeBuilder : _CustomAttributeBuilder + { + // public constructor to form the custom attribute with constructor and constructor + // parameters. + public CustomAttributeBuilder(ConstructorInfo con, Object[] constructorArgs) + { + InitCustomAttributeBuilder(con, constructorArgs, + new PropertyInfo[]{}, new Object[]{}, + new FieldInfo[]{}, new Object[]{}); + } + + // public constructor to form the custom attribute with constructor, constructor + // parameters and named properties. + public CustomAttributeBuilder(ConstructorInfo con, Object[] constructorArgs, + PropertyInfo[] namedProperties, Object[] propertyValues) + { + InitCustomAttributeBuilder(con, constructorArgs, namedProperties, + propertyValues, new FieldInfo[]{}, new Object[]{}); + } + + // public constructor to form the custom attribute with constructor and constructor + // parameters. + public CustomAttributeBuilder(ConstructorInfo con, Object[] constructorArgs, + FieldInfo[] namedFields, Object[] fieldValues) + { + InitCustomAttributeBuilder(con, constructorArgs, new PropertyInfo[]{}, + new Object[]{}, namedFields, fieldValues); + } + + // public constructor to form the custom attribute with constructor and constructor + // parameters. + public CustomAttributeBuilder(ConstructorInfo con, Object[] constructorArgs, + PropertyInfo[] namedProperties, Object[] propertyValues, + FieldInfo[] namedFields, Object[] fieldValues) + { + InitCustomAttributeBuilder(con, constructorArgs, namedProperties, + propertyValues, namedFields, fieldValues); + } + + // Check that a type is suitable for use in a custom attribute. + private bool ValidateType(Type t) + { + if (t.IsPrimitive || t == typeof(String) || t == typeof(Type)) + return true; + if (t.IsEnum) + { + switch (Type.GetTypeCode(Enum.GetUnderlyingType(t))) + { + case TypeCode.SByte: + case TypeCode.Byte: + case TypeCode.Int16: + case TypeCode.UInt16: + case TypeCode.Int32: + case TypeCode.UInt32: + case TypeCode.Int64: + case TypeCode.UInt64: + return true; + default: + return false; + } + } + if (t.IsArray) + { + if (t.GetArrayRank() != 1) + return false; + return ValidateType(t.GetElementType()); + } + return t == typeof(Object); + } + + internal void InitCustomAttributeBuilder(ConstructorInfo con, Object[] constructorArgs, + PropertyInfo[] namedProperties, Object[] propertyValues, + FieldInfo[] namedFields, Object[] fieldValues) + { + if (con == null) + throw new ArgumentNullException("con"); + if (constructorArgs == null) + throw new ArgumentNullException("constructorArgs"); + if (namedProperties == null) + throw new ArgumentNullException("namedProperties"); + if (propertyValues == null) + throw new ArgumentNullException("propertyValues"); + if (namedFields == null) + throw new ArgumentNullException("namedFields"); + if (fieldValues == null) + throw new ArgumentNullException("fieldValues"); + if (namedProperties.Length != propertyValues.Length) + throw new ArgumentException(Environment.GetResourceString("Arg_ArrayLengthsDiffer"), "namedProperties, propertyValues"); + if (namedFields.Length != fieldValues.Length) + throw new ArgumentException(Environment.GetResourceString("Arg_ArrayLengthsDiffer"), "namedFields, fieldValues"); + Contract.EndContractBlock(); + + if ((con.Attributes & MethodAttributes.Static) == MethodAttributes.Static || + (con.Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private) + throw new ArgumentException(Environment.GetResourceString("Argument_BadConstructor")); + + if ((con.CallingConvention & CallingConventions.Standard) != CallingConventions.Standard) + throw new ArgumentException(Environment.GetResourceString("Argument_BadConstructorCallConv")); + + // Cache information used elsewhere. + m_con = con; + m_constructorArgs = new Object[constructorArgs.Length]; + Array.Copy(constructorArgs, 0, m_constructorArgs, 0, constructorArgs.Length); + + Type[] paramTypes; + int i; + + // Get the types of the constructor's formal parameters. + paramTypes = con.GetParameterTypes(); + + // Since we're guaranteed a non-var calling convention, the number of arguments must equal the number of parameters. + if (paramTypes.Length != constructorArgs.Length) + throw new ArgumentException(Environment.GetResourceString("Argument_BadParameterCountsForConstructor")); + + // Verify that the constructor has a valid signature (custom attributes only support a subset of our type system). + for (i = 0; i < paramTypes.Length; i++) + if (!ValidateType(paramTypes[i])) + throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeInCustomAttribute")); + + // Now verify that the types of the actual parameters are compatible with the types of the formal parameters. + for (i = 0; i < paramTypes.Length; i++) + { + if (constructorArgs[i] == null) + continue; + TypeCode paramTC = Type.GetTypeCode(paramTypes[i]); + if (paramTC != Type.GetTypeCode(constructorArgs[i].GetType())) + if (paramTC != TypeCode.Object || !ValidateType(constructorArgs[i].GetType())) + throw new ArgumentException(Environment.GetResourceString("Argument_BadParameterTypeForConstructor", i)); + } + + // Allocate a memory stream to represent the CA blob in the metadata and a binary writer to help format it. + MemoryStream stream = new MemoryStream(); + BinaryWriter writer = new BinaryWriter(stream); + + // Write the blob protocol version (currently 1). + writer.Write((ushort)1); + + // Now emit the constructor argument values (no need for types, they're inferred from the constructor signature). + for (i = 0; i < constructorArgs.Length; i++) + EmitValue(writer, paramTypes[i], constructorArgs[i]); + + // Next a short with the count of properties and fields. + writer.Write((ushort)(namedProperties.Length + namedFields.Length)); + + // Emit all the property sets. + for (i = 0; i < namedProperties.Length; i++) + { + // Validate the property. + if (namedProperties[i] == null) + throw new ArgumentNullException("namedProperties[" + i + "]"); + + // Allow null for non-primitive types only. + Type propType = namedProperties[i].PropertyType; + if (propertyValues[i] == null && propType.IsPrimitive) + throw new ArgumentNullException("propertyValues[" + i + "]"); + + // Validate property type. + if (!ValidateType(propType)) + throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeInCustomAttribute")); + + // Property has to be writable. + if (!namedProperties[i].CanWrite) + throw new ArgumentException(Environment.GetResourceString("Argument_NotAWritableProperty")); + + // Property has to be from the same class or base class as ConstructorInfo. + if (namedProperties[i].DeclaringType != con.DeclaringType + && (!(con.DeclaringType is TypeBuilderInstantiation)) + && !con.DeclaringType.IsSubclassOf(namedProperties[i].DeclaringType)) + { + // Might have failed check because one type is a XXXBuilder + // and the other is not. Deal with these special cases + // separately. + if (!TypeBuilder.IsTypeEqual(namedProperties[i].DeclaringType, con.DeclaringType)) + { + // IsSubclassOf is overloaded to do the right thing if + // the constructor is a TypeBuilder, but we still need + // to deal with the case where the property's declaring + // type is one. + if (!(namedProperties[i].DeclaringType is TypeBuilder) || + !con.DeclaringType.IsSubclassOf(((TypeBuilder)namedProperties[i].DeclaringType).BakedRuntimeType)) + throw new ArgumentException(Environment.GetResourceString("Argument_BadPropertyForConstructorBuilder")); + } + } + + // Make sure the property's type can take the given value. + // Note that there will be no coersion. + if (propertyValues[i] != null && + propType != typeof(Object) && + Type.GetTypeCode(propertyValues[i].GetType()) != Type.GetTypeCode(propType)) + throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch")); + + // First a byte indicating that this is a property. + writer.Write((byte)CustomAttributeEncoding.Property); + + // Emit the property type, name and value. + EmitType(writer, propType); + EmitString(writer, namedProperties[i].Name); + EmitValue(writer, propType, propertyValues[i]); + } + + // Emit all the field sets. + for (i = 0; i < namedFields.Length; i++) + { + // Validate the field. + if (namedFields[i] == null) + throw new ArgumentNullException("namedFields[" + i + "]"); + + // Allow null for non-primitive types only. + Type fldType = namedFields[i].FieldType; + if (fieldValues[i] == null && fldType.IsPrimitive) + throw new ArgumentNullException("fieldValues[" + i + "]"); + + // Validate field type. + if (!ValidateType(fldType)) + throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeInCustomAttribute")); + + // Field has to be from the same class or base class as ConstructorInfo. + if (namedFields[i].DeclaringType != con.DeclaringType + && (!(con.DeclaringType is TypeBuilderInstantiation)) + && !con.DeclaringType.IsSubclassOf(namedFields[i].DeclaringType)) + { + // Might have failed check because one type is a XXXBuilder + // and the other is not. Deal with these special cases + // separately. + if (!TypeBuilder.IsTypeEqual(namedFields[i].DeclaringType, con.DeclaringType)) + { + // IsSubclassOf is overloaded to do the right thing if + // the constructor is a TypeBuilder, but we still need + // to deal with the case where the field's declaring + // type is one. + if (!(namedFields[i].DeclaringType is TypeBuilder) || + !con.DeclaringType.IsSubclassOf(((TypeBuilder)namedFields[i].DeclaringType).BakedRuntimeType)) + throw new ArgumentException(Environment.GetResourceString("Argument_BadFieldForConstructorBuilder")); + } + } + + // Make sure the field's type can take the given value. + // Note that there will be no coersion. + if (fieldValues[i] != null && + fldType != typeof(Object) && + Type.GetTypeCode(fieldValues[i].GetType()) != Type.GetTypeCode(fldType)) + throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch")); + + // First a byte indicating that this is a field. + writer.Write((byte)CustomAttributeEncoding.Field); + + // Emit the field type, name and value. + EmitType(writer, fldType); + EmitString(writer, namedFields[i].Name); + EmitValue(writer, fldType, fieldValues[i]); + } + + // Create the blob array. + m_blob = ((MemoryStream)writer.BaseStream).ToArray(); + } + + private void EmitType(BinaryWriter writer, Type type) + { + if (type.IsPrimitive) + { + switch (Type.GetTypeCode(type)) + { + case TypeCode.SByte: + writer.Write((byte)CustomAttributeEncoding.SByte); + break; + case TypeCode.Byte: + writer.Write((byte)CustomAttributeEncoding.Byte); + break; + case TypeCode.Char: + writer.Write((byte)CustomAttributeEncoding.Char); + break; + case TypeCode.Boolean: + writer.Write((byte)CustomAttributeEncoding.Boolean); + break; + case TypeCode.Int16: + writer.Write((byte)CustomAttributeEncoding.Int16); + break; + case TypeCode.UInt16: + writer.Write((byte)CustomAttributeEncoding.UInt16); + break; + case TypeCode.Int32: + writer.Write((byte)CustomAttributeEncoding.Int32); + break; + case TypeCode.UInt32: + writer.Write((byte)CustomAttributeEncoding.UInt32); + break; + case TypeCode.Int64: + writer.Write((byte)CustomAttributeEncoding.Int64); + break; + case TypeCode.UInt64: + writer.Write((byte)CustomAttributeEncoding.UInt64); + break; + case TypeCode.Single: + writer.Write((byte)CustomAttributeEncoding.Float); + break; + case TypeCode.Double: + writer.Write((byte)CustomAttributeEncoding.Double); + break; + default: + Contract.Assert(false, "Invalid primitive type"); + break; + } + } + else if (type.IsEnum) + { + writer.Write((byte)CustomAttributeEncoding.Enum); + EmitString(writer, type.AssemblyQualifiedName); + } + else if (type == typeof(String)) + { + writer.Write((byte)CustomAttributeEncoding.String); + } + else if (type == typeof(Type)) + { + writer.Write((byte)CustomAttributeEncoding.Type); + } + else if (type.IsArray) + { + writer.Write((byte)CustomAttributeEncoding.Array); + EmitType(writer, type.GetElementType()); + } + else + { + // Tagged object case. + writer.Write((byte)CustomAttributeEncoding.Object); + } + } + + private void EmitString(BinaryWriter writer, String str) + { + // Strings are emitted with a length prefix in a compressed format (1, 2 or 4 bytes) as used internally by metadata. + byte[] utf8Str = Encoding.UTF8.GetBytes(str); + uint length = (uint)utf8Str.Length; + if (length <= 0x7f) + { + writer.Write((byte)length); + } + else if (length <= 0x3fff) + { + writer.Write((byte)((length >> 8) | 0x80)); + writer.Write((byte)(length & 0xff)); + } + else + { + writer.Write((byte)((length >> 24) | 0xc0)); + writer.Write((byte)((length >> 16) & 0xff)); + writer.Write((byte)((length >> 8) & 0xff)); + writer.Write((byte)(length & 0xff)); + } + writer.Write(utf8Str); + } + + private void EmitValue(BinaryWriter writer, Type type, Object value) + { + if (type.IsEnum) + { + switch (Type.GetTypeCode(Enum.GetUnderlyingType(type))) + { + case TypeCode.SByte: + writer.Write((sbyte)value); + break; + case TypeCode.Byte: + writer.Write((byte)value); + break; + case TypeCode.Int16: + writer.Write((short)value); + break; + case TypeCode.UInt16: + writer.Write((ushort)value); + break; + case TypeCode.Int32: + writer.Write((int)value); + break; + case TypeCode.UInt32: + writer.Write((uint)value); + break; + case TypeCode.Int64: + writer.Write((long)value); + break; + case TypeCode.UInt64: + writer.Write((ulong)value); + break; + default: + Contract.Assert(false, "Invalid enum base type"); + break; + } + } + else if (type == typeof(String)) + { + if (value == null) + writer.Write((byte)0xff); + else + EmitString(writer, (String)value); + } + else if (type == typeof(Type)) + { + if (value == null) + writer.Write((byte)0xff); + else + { + String typeName = TypeNameBuilder.ToString((Type)value, TypeNameBuilder.Format.AssemblyQualifiedName); + if (typeName == null) + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeForCA", + value.GetType())); + EmitString(writer, typeName); + } + } + else if (type.IsArray) + { + if (value == null) + writer.Write((uint)0xffffffff); + else + { + Array a = (Array)value; + Type et = type.GetElementType(); + writer.Write(a.Length); + for (int i = 0; i < a.Length; i++) + EmitValue(writer, et, a.GetValue(i)); + } + } + else if (type.IsPrimitive) + { + switch (Type.GetTypeCode(type)) + { + case TypeCode.SByte: + writer.Write((sbyte)value); + break; + case TypeCode.Byte: + writer.Write((byte)value); + break; + case TypeCode.Char: + writer.Write(Convert.ToUInt16((char)value)); + break; + case TypeCode.Boolean: + writer.Write((byte)((bool)value ? 1 : 0)); + break; + case TypeCode.Int16: + writer.Write((short)value); + break; + case TypeCode.UInt16: + writer.Write((ushort)value); + break; + case TypeCode.Int32: + writer.Write((int)value); + break; + case TypeCode.UInt32: + writer.Write((uint)value); + break; + case TypeCode.Int64: + writer.Write((long)value); + break; + case TypeCode.UInt64: + writer.Write((ulong)value); + break; + case TypeCode.Single: + writer.Write((float)value); + break; + case TypeCode.Double: + writer.Write((double)value); + break; + default: + Contract.Assert(false, "Invalid primitive type"); + break; + } + } + else if (type == typeof(object)) + { + // Tagged object case. Type instances aren't actually Type, they're some subclass (such as RuntimeType or + // TypeBuilder), so we need to canonicalize this case back to Type. If we have a null value we follow the convention + // used by C# and emit a null typed as a string (it doesn't really matter what type we pick as long as it's a + // reference type). + Type ot = value == null ? typeof(String) : value is Type ? typeof(Type) : value.GetType(); + + // value cannot be a "System.Object" object. + // If we allow this we will get into an infinite recursion + if (ot == typeof(object)) + throw new ArgumentException(Environment.GetResourceString("Argument_BadParameterTypeForCAB", ot.ToString())); + + EmitType(writer, ot); + EmitValue(writer, ot, value); + } + else + { + string typename = "null"; + + if (value != null) + typename = value.GetType().ToString(); + + throw new ArgumentException(Environment.GetResourceString("Argument_BadParameterTypeForCAB", typename)); + } + } + + + + + // return the byte interpretation of the custom attribute + [System.Security.SecurityCritical] // auto-generated + internal void CreateCustomAttribute(ModuleBuilder mod, int tkOwner) + { + CreateCustomAttribute(mod, tkOwner, mod.GetConstructorToken(m_con).Token, false); + } + + //************************************************* + // Upon saving to disk, we need to create the memberRef token for the custom attribute's type + // first of all. So when we snap the in-memory module for on disk, this token will be there. + // We also need to enforce the use of MemberRef. Because MemberDef token might move. + // This function has to be called before we snap the in-memory module for on disk (i.e. Presave on + // ModuleBuilder. + //************************************************* + [System.Security.SecurityCritical] // auto-generated + internal int PrepareCreateCustomAttributeToDisk(ModuleBuilder mod) + { + return mod.InternalGetConstructorToken(m_con, true).Token; + } + + //************************************************* + // Call this function with toDisk=1, after on disk module has been snapped. + //************************************************* + [System.Security.SecurityCritical] // auto-generated + internal void CreateCustomAttribute(ModuleBuilder mod, int tkOwner, int tkAttrib, bool toDisk) + { + TypeBuilder.DefineCustomAttribute(mod, tkOwner, tkAttrib, m_blob, toDisk, + typeof(System.Diagnostics.DebuggableAttribute) == m_con.DeclaringType); + } + +#if !FEATURE_CORECLR + void _CustomAttributeBuilder.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _CustomAttributeBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _CustomAttributeBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _CustomAttributeBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + + internal ConstructorInfo m_con; + internal Object[] m_constructorArgs; + internal byte[] m_blob; + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/DynamicILGenerator.cs b/src/mscorlib/src/System/Reflection/Emit/DynamicILGenerator.cs new file mode 100644 index 0000000000..b66fdad1e2 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/DynamicILGenerator.cs @@ -0,0 +1,1329 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection.Emit +{ + + using System; + using System.Globalization; + using TextWriter = System.IO.TextWriter; + using System.Diagnostics.SymbolStore; + using System.Runtime.InteropServices; + using System.Reflection; + using System.Collections; + using System.Collections.Generic; + using System.Security.Permissions; + using System.Threading; + using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; + using System.Security; + + internal class DynamicILGenerator : ILGenerator + { + + internal DynamicScope m_scope; + private int m_methodSigToken; + + internal unsafe DynamicILGenerator(DynamicMethod method, byte[] methodSignature, int size) + : base(method, size) + { + m_scope = new DynamicScope(); + + m_methodSigToken = m_scope.GetTokenFor(methodSignature); + } + + + [System.Security.SecurityCritical] // auto-generated + internal void GetCallableMethod(RuntimeModule module, DynamicMethod dm) + { + dm.m_methodHandle = ModuleHandle.GetDynamicMethod(dm, + module, + m_methodBuilder.Name, + (byte[])m_scope[m_methodSigToken], + new DynamicResolver(this)); + } + +#if FEATURE_APPX + private bool ProfileAPICheck + { + get + { + return ((DynamicMethod)m_methodBuilder).ProfileAPICheck; + } + } +#endif // FEATURE_APPX + + // *** ILGenerator api *** + + public override LocalBuilder DeclareLocal(Type localType, bool pinned) + { + LocalBuilder localBuilder; + if (localType == null) + throw new ArgumentNullException("localType"); + Contract.EndContractBlock(); + + RuntimeType rtType = localType as RuntimeType; + + if (rtType == null) + throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType")); + +#if FEATURE_APPX + if (ProfileAPICheck && (rtType.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtType.FullName)); +#endif + + localBuilder = new LocalBuilder(m_localCount, localType, m_methodBuilder); + // add the localType to local signature + m_localSignature.AddArgument(localType, pinned); + m_localCount++; + return localBuilder; + } + + // + // + // Token resolution calls + // + // + [System.Security.SecuritySafeCritical] // auto-generated + public override void Emit(OpCode opcode, MethodInfo meth) + { + if (meth == null) + throw new ArgumentNullException("meth"); + Contract.EndContractBlock(); + + int stackchange = 0; + int token = 0; + DynamicMethod dynMeth = meth as DynamicMethod; + if (dynMeth == null) + { + RuntimeMethodInfo rtMeth = meth as RuntimeMethodInfo; + if (rtMeth == null) + throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "meth"); + + RuntimeType declaringType = rtMeth.GetRuntimeType(); + if (declaringType != null && (declaringType.IsGenericType || declaringType.IsArray)) + token = GetTokenFor(rtMeth, declaringType); + else + token = GetTokenFor(rtMeth); + } + else + { + // rule out not allowed operations on DynamicMethods + if (opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn) || opcode.Equals(OpCodes.Ldvirtftn)) + { + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidOpCodeOnDynamicMethod")); + } + token = GetTokenFor(dynMeth); + } + + EnsureCapacity(7); + InternalEmit(opcode); + + if (opcode.StackBehaviourPush == StackBehaviour.Varpush + && meth.ReturnType != typeof(void)) + { + stackchange++; + } + if (opcode.StackBehaviourPop == StackBehaviour.Varpop) + { + stackchange -= meth.GetParametersNoCopy().Length; + } + // Pop the "this" parameter if the method is non-static, + // and the instruction is not newobj/ldtoken/ldftn. + if (!meth.IsStatic && + !(opcode.Equals(OpCodes.Newobj) || opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn))) + { + stackchange--; + } + + UpdateStackSize(opcode, stackchange); + + PutInteger4(token); + } + + [System.Runtime.InteropServices.ComVisible(true)] + public override void Emit(OpCode opcode, ConstructorInfo con) + { + if (con == null) + throw new ArgumentNullException("con"); + Contract.EndContractBlock(); + + RuntimeConstructorInfo rtConstructor = con as RuntimeConstructorInfo; + if (rtConstructor == null) + throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "con"); + + RuntimeType declaringType = rtConstructor.GetRuntimeType(); + int token; + + if (declaringType != null && (declaringType.IsGenericType || declaringType.IsArray)) + // need to sort out the stack size story + token = GetTokenFor(rtConstructor, declaringType); + else + token = GetTokenFor(rtConstructor); + + EnsureCapacity(7); + InternalEmit(opcode); + + // need to sort out the stack size story + UpdateStackSize(opcode, 1); + + PutInteger4(token); + } + + public override void Emit(OpCode opcode, Type type) + { + if (type == null) + throw new ArgumentNullException("type"); + Contract.EndContractBlock(); + + RuntimeType rtType = type as RuntimeType; + + if (rtType == null) + throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType")); + + int token = GetTokenFor(rtType); + EnsureCapacity(7); + InternalEmit(opcode); + PutInteger4(token); + } + + public override void Emit(OpCode opcode, FieldInfo field) + { + if (field == null) + throw new ArgumentNullException("field"); + Contract.EndContractBlock(); + + RuntimeFieldInfo runtimeField = field as RuntimeFieldInfo; + if (runtimeField == null) + throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeFieldInfo"), "field"); + + int token; + if (field.DeclaringType == null) + token = GetTokenFor(runtimeField); + else + token = GetTokenFor(runtimeField, runtimeField.GetRuntimeType()); + + EnsureCapacity(7); + InternalEmit(opcode); + PutInteger4(token); + } + + public override void Emit(OpCode opcode, String str) + { + if (str == null) + throw new ArgumentNullException("str"); + Contract.EndContractBlock(); + + int tempVal = GetTokenForString(str); + EnsureCapacity(7); + InternalEmit(opcode); + PutInteger4(tempVal); + } + + // + // + // Signature related calls (vararg, calli) + // + // + [System.Security.SecuritySafeCritical] // overrides SC + public override void EmitCalli(OpCode opcode, + CallingConventions callingConvention, + Type returnType, + Type[] parameterTypes, + Type[] optionalParameterTypes) + { + int stackchange = 0; + SignatureHelper sig; + if (optionalParameterTypes != null) + if ((callingConvention & CallingConventions.VarArgs) == 0) + + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAVarArgCallingConvention")); + + sig = GetMemberRefSignature(callingConvention, + returnType, + parameterTypes, + optionalParameterTypes); + + EnsureCapacity(7); + Emit(OpCodes.Calli); + + // If there is a non-void return type, push one. + if (returnType != typeof(void)) + stackchange++; + // Pop off arguments if any. + if (parameterTypes != null) + stackchange -= parameterTypes.Length; + // Pop off vararg arguments. + if (optionalParameterTypes != null) + stackchange -= optionalParameterTypes.Length; + // Pop the this parameter if the method has a this parameter. + if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis) + stackchange--; + // Pop the native function pointer. + stackchange--; + UpdateStackSize(OpCodes.Calli, stackchange); + + int token = GetTokenForSig(sig.GetSignature(true)); + PutInteger4(token); + } + + public override void EmitCalli(OpCode opcode, + CallingConvention unmanagedCallConv, + Type returnType, + Type[] parameterTypes) + { + int stackchange = 0; + int cParams = 0; + int i; + SignatureHelper sig; + + if (parameterTypes != null) + cParams = parameterTypes.Length; + + sig = SignatureHelper.GetMethodSigHelper(unmanagedCallConv, returnType); + + if (parameterTypes != null) + for (i = 0; i < cParams; i++) + sig.AddArgument(parameterTypes[i]); + + // If there is a non-void return type, push one. + if (returnType != typeof(void)) + stackchange++; + + // Pop off arguments if any. + if (parameterTypes != null) + stackchange -= cParams; + + // Pop the native function pointer. + stackchange--; + UpdateStackSize(OpCodes.Calli, stackchange); + + EnsureCapacity(7); + Emit(OpCodes.Calli); + int token = GetTokenForSig(sig.GetSignature(true)); + PutInteger4(token); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public override void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes) + { + if (methodInfo == null) + throw new ArgumentNullException("methodInfo"); + + if (!(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj))) + throw new ArgumentException(Environment.GetResourceString("Argument_NotMethodCallOpcode"), "opcode"); + + if (methodInfo.ContainsGenericParameters) + throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "methodInfo"); + + if (methodInfo.DeclaringType != null && methodInfo.DeclaringType.ContainsGenericParameters) + throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "methodInfo"); + Contract.EndContractBlock(); + + int tk; + int stackchange = 0; + + tk = GetMemberRefToken(methodInfo, optionalParameterTypes); + + EnsureCapacity(7); + InternalEmit(opcode); + + // Push the return value if there is one. + if (methodInfo.ReturnType != typeof(void)) + stackchange++; + // Pop the parameters. + stackchange -= methodInfo.GetParameterTypes().Length; + // Pop the this parameter if the method is non-static and the + // instruction is not newobj. + if (!(methodInfo is SymbolMethod) && methodInfo.IsStatic == false && !(opcode.Equals(OpCodes.Newobj))) + stackchange--; + // Pop the optional parameters off the stack. + if (optionalParameterTypes != null) + stackchange -= optionalParameterTypes.Length; + UpdateStackSize(opcode, stackchange); + + PutInteger4(tk); + } + + public override void Emit(OpCode opcode, SignatureHelper signature) + { + if (signature == null) + throw new ArgumentNullException("signature"); + Contract.EndContractBlock(); + + int stackchange = 0; + EnsureCapacity(7); + InternalEmit(opcode); + + // The only IL instruction that has VarPop behaviour, that takes a + // Signature token as a parameter is calli. Pop the parameters and + // the native function pointer. To be conservative, do not pop the + // this pointer since this information is not easily derived from + // SignatureHelper. + if (opcode.StackBehaviourPop == StackBehaviour.Varpop) + { + Contract.Assert(opcode.Equals(OpCodes.Calli), + "Unexpected opcode encountered for StackBehaviour VarPop."); + // Pop the arguments.. + stackchange -= signature.ArgumentCount; + // Pop native function pointer off the stack. + stackchange--; + UpdateStackSize(opcode, stackchange); + } + + int token = GetTokenForSig(signature.GetSignature(true)); ; + PutInteger4(token); + } + + // + // + // Exception related generation + // + // + public override Label BeginExceptionBlock() + { + return base.BeginExceptionBlock(); + } + + public override void EndExceptionBlock() + { + base.EndExceptionBlock(); + } + + public override void BeginExceptFilterBlock() + { + throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); + } + + public override void BeginCatchBlock(Type exceptionType) + { + if (CurrExcStackCount == 0) + throw new NotSupportedException(Environment.GetResourceString("Argument_NotInExceptionBlock")); + Contract.EndContractBlock(); + + __ExceptionInfo current = CurrExcStack[CurrExcStackCount - 1]; + + RuntimeType rtType = exceptionType as RuntimeType; + + if (current.GetCurrentState() == __ExceptionInfo.State_Filter) + { + if (exceptionType != null) + { + throw new ArgumentException(Environment.GetResourceString("Argument_ShouldNotSpecifyExceptionType")); + } + + this.Emit(OpCodes.Endfilter); + } + else + { + // execute this branch if previous clause is Catch or Fault + if (exceptionType == null) + throw new ArgumentNullException("exceptionType"); + + if (rtType == null) + throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType")); + + Label endLabel = current.GetEndLabel(); + this.Emit(OpCodes.Leave, endLabel); + + // if this is a catch block the exception will be pushed on the stack and we need to update the stack info + UpdateStackSize(OpCodes.Nop, 1); + } + + current.MarkCatchAddr(ILOffset, exceptionType); + + + // this is relying on too much implementation details of the base and so it's highly breaking + // Need to have a more integreted story for exceptions + current.m_filterAddr[current.m_currentCatch - 1] = GetTokenFor(rtType); + } + + public override void BeginFaultBlock() + { + throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); + } + + public override void BeginFinallyBlock() + { + base.BeginFinallyBlock(); + } + + // + // + // debugger related calls. + // + // + [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems. + public override void UsingNamespace(String ns) + { + throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); + } + + [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems. + public override void MarkSequencePoint(ISymbolDocumentWriter document, + int startLine, + int startColumn, + int endLine, + int endColumn) + { + throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); + } + + public override void BeginScope() + { + throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); + } + + public override void EndScope() + { + throw new NotSupportedException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); + } + + [System.Security.SecurityCritical] // auto-generated + private int GetMemberRefToken(MethodBase methodInfo, Type[] optionalParameterTypes) + { + Type[] parameterTypes; + + if (optionalParameterTypes != null && (methodInfo.CallingConvention & CallingConventions.VarArgs) == 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAVarArgCallingConvention")); + + RuntimeMethodInfo rtMeth = methodInfo as RuntimeMethodInfo; + DynamicMethod dm = methodInfo as DynamicMethod; + + if (rtMeth == null && dm == null) + throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "methodInfo"); + + ParameterInfo[] paramInfo = methodInfo.GetParametersNoCopy(); + if (paramInfo != null && paramInfo.Length != 0) + { + parameterTypes = new Type[paramInfo.Length]; + for (int i = 0; i < paramInfo.Length; i++) + parameterTypes[i] = paramInfo[i].ParameterType; + } + else + { + parameterTypes = null; + } + + SignatureHelper sig = GetMemberRefSignature(methodInfo.CallingConvention, + MethodBuilder.GetMethodBaseReturnType(methodInfo), + parameterTypes, + optionalParameterTypes); + + if (rtMeth != null) + return GetTokenForVarArgMethod(rtMeth, sig); + else + return GetTokenForVarArgMethod(dm, sig); + } + + [System.Security.SecurityCritical] // auto-generated + internal override SignatureHelper GetMemberRefSignature( + CallingConventions call, + Type returnType, + Type[] parameterTypes, + Type[] optionalParameterTypes) + { + int cParams; + int i; + SignatureHelper sig; + if (parameterTypes == null) + cParams = 0; + else + cParams = parameterTypes.Length; + sig = SignatureHelper.GetMethodSigHelper(call, returnType); + for (i = 0; i < cParams; i++) + sig.AddArgument(parameterTypes[i]); + if (optionalParameterTypes != null && optionalParameterTypes.Length != 0) + { + // add the sentinel + sig.AddSentinel(); + for (i = 0; i < optionalParameterTypes.Length; i++) + sig.AddArgument(optionalParameterTypes[i]); + } + return sig; + } + + internal override void RecordTokenFixup() + { + // DynamicMethod doesn't need fixup. + } + + #region GetTokenFor helpers + private int GetTokenFor(RuntimeType rtType) + { +#if FEATURE_APPX + if (ProfileAPICheck && (rtType.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtType.FullName)); +#endif + + return m_scope.GetTokenFor(rtType.TypeHandle); + } + + private int GetTokenFor(RuntimeFieldInfo runtimeField) + { +#if FEATURE_APPX + if (ProfileAPICheck) + { + RtFieldInfo rtField = runtimeField as RtFieldInfo; + if (rtField != null && (rtField.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtField.FullName)); + } +#endif + + return m_scope.GetTokenFor(runtimeField.FieldHandle); + } + + private int GetTokenFor(RuntimeFieldInfo runtimeField, RuntimeType rtType) + { +#if FEATURE_APPX + if (ProfileAPICheck) + { + RtFieldInfo rtField = runtimeField as RtFieldInfo; + if (rtField != null && (rtField.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtField.FullName)); + + if ((rtType.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtType.FullName)); + } +#endif + + return m_scope.GetTokenFor(runtimeField.FieldHandle, rtType.TypeHandle); + } + + private int GetTokenFor(RuntimeConstructorInfo rtMeth) + { +#if FEATURE_APPX + if (ProfileAPICheck && (rtMeth.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtMeth.FullName)); +#endif + + return m_scope.GetTokenFor(rtMeth.MethodHandle); + } + + private int GetTokenFor(RuntimeConstructorInfo rtMeth, RuntimeType rtType) + { +#if FEATURE_APPX + if (ProfileAPICheck) + { + if ((rtMeth.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtMeth.FullName)); + + if ((rtType.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtType.FullName)); + } +#endif + + return m_scope.GetTokenFor(rtMeth.MethodHandle, rtType.TypeHandle); + } + + private int GetTokenFor(RuntimeMethodInfo rtMeth) + { +#if FEATURE_APPX + if (ProfileAPICheck && (rtMeth.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtMeth.FullName)); +#endif + + return m_scope.GetTokenFor(rtMeth.MethodHandle); + } + + private int GetTokenFor(RuntimeMethodInfo rtMeth, RuntimeType rtType) + { +#if FEATURE_APPX + if (ProfileAPICheck) + { + if ((rtMeth.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtMeth.FullName)); + + if ((rtType.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtType.FullName)); + } +#endif + + return m_scope.GetTokenFor(rtMeth.MethodHandle, rtType.TypeHandle); + } + + private int GetTokenFor(DynamicMethod dm) + { + return m_scope.GetTokenFor(dm); + } + + private int GetTokenForVarArgMethod(RuntimeMethodInfo rtMeth, SignatureHelper sig) + { +#if FEATURE_APPX + if (ProfileAPICheck && (rtMeth.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtMeth.FullName)); +#endif + VarArgMethod varArgMeth = new VarArgMethod(rtMeth, sig); + return m_scope.GetTokenFor(varArgMeth); + } + + private int GetTokenForVarArgMethod(DynamicMethod dm, SignatureHelper sig) + { + VarArgMethod varArgMeth = new VarArgMethod(dm, sig); + return m_scope.GetTokenFor(varArgMeth); + } + + private int GetTokenForString(String s) + { + return m_scope.GetTokenFor(s); + } + + private int GetTokenForSig(byte[] sig) + { + return m_scope.GetTokenFor(sig); + } + #endregion + + } + + internal class DynamicResolver : Resolver + { + #region Private Data Members + private __ExceptionInfo[] m_exceptions; + private byte[] m_exceptionHeader; + private DynamicMethod m_method; + private byte[] m_code; + private byte[] m_localSignature; + private int m_stackSize; + private DynamicScope m_scope; + #endregion + + #region Internal Methods + internal DynamicResolver(DynamicILGenerator ilGenerator) + { + m_stackSize = ilGenerator.GetMaxStackSize(); + m_exceptions = ilGenerator.GetExceptions(); + m_code = ilGenerator.BakeByteArray(); + m_localSignature = ilGenerator.m_localSignature.InternalGetSignatureArray(); + m_scope = ilGenerator.m_scope; + + m_method = (DynamicMethod)ilGenerator.m_methodBuilder; + m_method.m_resolver = this; + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + internal DynamicResolver(DynamicILInfo dynamicILInfo) + { + m_stackSize = dynamicILInfo.MaxStackSize; + m_code = dynamicILInfo.Code; + m_localSignature = dynamicILInfo.LocalSignature; + m_exceptionHeader = dynamicILInfo.Exceptions; + //m_exceptions = dynamicILInfo.Exceptions; + m_scope = dynamicILInfo.DynamicScope; + + m_method = dynamicILInfo.DynamicMethod; + m_method.m_resolver = this; + } + + // + // We can destroy the unmanaged part of dynamic method only after the managed part is definitely gone and thus + // nobody can call the dynamic method anymore. A call to finalizer alone does not guarantee that the managed + // part is gone. A malicious code can keep a reference to DynamicMethod in long weak reference that survives finalization, + // or we can be running during shutdown where everything is finalized. + // + // The unmanaged resolver keeps a reference to the managed resolver in long weak handle. If the long weak handle + // is null, we can be sure that the managed part of the dynamic method is definitely gone and that it is safe to + // destroy the unmanaged part. (Note that the managed finalizer has to be on the same object that the long weak handle + // points to in order for this to work.) Unfortunately, we can not perform the above check when out finalizer + // is called - the long weak handle won't be cleared yet. Instead, we create a helper scout object that will attempt + // to do the destruction after next GC. + // + // The finalization does not have to be done using CriticalFinalizerObject. We have to go over all DynamicMethodDescs + // during AppDomain shutdown anyway to avoid leaks e.g. if somebody stores reference to DynamicMethod in static. + // + ~DynamicResolver() + { + DynamicMethod method = m_method; + + if (method == null) + return; + + if (method.m_methodHandle == null) + return; + + DestroyScout scout = null; + try + { + scout = new DestroyScout(); + } + catch + { + // We go over all DynamicMethodDesc during AppDomain shutdown and make sure + // that everything associated with them is released. So it is ok to skip reregistration + // for finalization during appdomain shutdown + if (!Environment.HasShutdownStarted && + !AppDomain.CurrentDomain.IsFinalizingForUnload()) + { + // Try again later. + GC.ReRegisterForFinalize(this); + } + return; + } + + // We can never ever have two active destroy scouts for the same method. We need to initialize the scout + // outside the try/reregister block to avoid possibility of reregistration for finalization with active scout. + scout.m_methodHandle = method.m_methodHandle.Value; + } + + private class DestroyScout + { + internal RuntimeMethodHandleInternal m_methodHandle; + + [System.Security.SecuritySafeCritical] // auto-generated + ~DestroyScout() + { + if (m_methodHandle.IsNullHandle()) + return; + + // It is not safe to destroy the method if the managed resolver is alive. + if (RuntimeMethodHandle.GetResolver(m_methodHandle) != null) + { + if (!Environment.HasShutdownStarted && + !AppDomain.CurrentDomain.IsFinalizingForUnload()) + { + // Somebody might have been holding a reference on us via weak handle. + // We will keep trying. It will be hopefully released eventually. + GC.ReRegisterForFinalize(this); + } + return; + } + + RuntimeMethodHandle.Destroy(m_methodHandle); + } + } + + // Keep in sync with vm/dynamicmethod.h + [Flags] + internal enum SecurityControlFlags + { + Default = 0x0, + SkipVisibilityChecks = 0x1, + RestrictedSkipVisibilityChecks = 0x2, + HasCreationContext = 0x4, + CanSkipCSEvaluation = 0x8, + } + + internal override RuntimeType GetJitContext(ref int securityControlFlags) + { + RuntimeType typeOwner; + + SecurityControlFlags flags = SecurityControlFlags.Default; + + if (m_method.m_restrictedSkipVisibility) + flags |= SecurityControlFlags.RestrictedSkipVisibilityChecks; + else if (m_method.m_skipVisibility) + flags |= SecurityControlFlags.SkipVisibilityChecks; + + typeOwner = m_method.m_typeOwner; + +#if FEATURE_COMPRESSEDSTACK + if (m_method.m_creationContext != null) + { + flags |= SecurityControlFlags.HasCreationContext; + if(m_method.m_creationContext.CanSkipEvaluation) + { + flags |= SecurityControlFlags.CanSkipCSEvaluation; + } + } + +#endif // FEATURE_COMPRESSEDSTACK + + securityControlFlags = (int)flags; + + return typeOwner; + } + + private static int CalculateNumberOfExceptions(__ExceptionInfo[] excp) + { + int num = 0; + if (excp == null) + return 0; + for (int i = 0; i < excp.Length; i++) + num += excp[i].GetNumberOfCatches(); + return num; + } + + internal override byte[] GetCodeInfo( + ref int stackSize, ref int initLocals, ref int EHCount) + { + stackSize = m_stackSize; + if (m_exceptionHeader != null && m_exceptionHeader.Length != 0) + { + if (m_exceptionHeader.Length < 4) + throw new FormatException(); + + byte header = m_exceptionHeader[0]; + + if ((header & 0x40) != 0) // Fat + { + byte[] size = new byte[4]; + for (int q = 0; q < 3; q++) + size[q] = m_exceptionHeader[q + 1]; + EHCount = (BitConverter.ToInt32(size, 0) - 4) / 24; + } + else + EHCount = (m_exceptionHeader[1] - 2) / 12; + } + else + { + EHCount = CalculateNumberOfExceptions(m_exceptions); + } + initLocals = (m_method.InitLocals) ? 1 : 0; + return m_code; + } + + internal override byte[] GetLocalsSignature() + { + return m_localSignature; + } + + internal override unsafe byte[] GetRawEHInfo() + { + return m_exceptionHeader; + } + + [System.Security.SecurityCritical] // auto-generated + internal override unsafe void GetEHInfo(int excNumber, void* exc) + { + CORINFO_EH_CLAUSE* exception = (CORINFO_EH_CLAUSE*)exc; + for (int i = 0; i < m_exceptions.Length; i++) + { + int excCount = m_exceptions[i].GetNumberOfCatches(); + if (excNumber < excCount) + { + // found the right exception block + exception->Flags = m_exceptions[i].GetExceptionTypes()[excNumber]; + exception->TryOffset = m_exceptions[i].GetStartAddress(); + if ((exception->Flags & __ExceptionInfo.Finally) != __ExceptionInfo.Finally) + exception->TryLength = m_exceptions[i].GetEndAddress() - exception->TryOffset; + else + exception->TryLength = m_exceptions[i].GetFinallyEndAddress() - exception->TryOffset; + exception->HandlerOffset = m_exceptions[i].GetCatchAddresses()[excNumber]; + exception->HandlerLength = m_exceptions[i].GetCatchEndAddresses()[excNumber] - exception->HandlerOffset; + // this is cheating because the filter address is the token of the class only for light code gen + exception->ClassTokenOrFilterOffset = m_exceptions[i].GetFilterAddresses()[excNumber]; + break; + } + excNumber -= excCount; + } + } + + internal override String GetStringLiteral(int token) { return m_scope.GetString(token); } + +#if FEATURE_COMPRESSEDSTACK + internal override CompressedStack GetSecurityContext() + { + return m_method.m_creationContext; + } +#endif // FEATURE_COMPRESSEDSTACK + + [System.Security.SecurityCritical] + internal override void ResolveToken(int token, out IntPtr typeHandle, out IntPtr methodHandle, out IntPtr fieldHandle) + { + typeHandle = new IntPtr(); + methodHandle = new IntPtr(); + fieldHandle = new IntPtr(); + + Object handle = m_scope[token]; + + if (handle == null) + throw new InvalidProgramException(); + + if (handle is RuntimeTypeHandle) + { + typeHandle = ((RuntimeTypeHandle)handle).Value; + return; + } + + if (handle is RuntimeMethodHandle) + { + methodHandle = ((RuntimeMethodHandle)handle).Value; + return; + } + + if (handle is RuntimeFieldHandle) + { + fieldHandle = ((RuntimeFieldHandle)handle).Value; + return; + } + + DynamicMethod dm = handle as DynamicMethod; + if (dm != null) + { + methodHandle = dm.GetMethodDescriptor().Value; + return; + } + + GenericMethodInfo gmi = handle as GenericMethodInfo; + if (gmi != null) + { + methodHandle = gmi.m_methodHandle.Value; + typeHandle = gmi.m_context.Value; + return; + } + + GenericFieldInfo gfi = handle as GenericFieldInfo; + if (gfi != null) + { + fieldHandle = gfi.m_fieldHandle.Value; + typeHandle = gfi.m_context.Value; + return; + } + + VarArgMethod vaMeth = handle as VarArgMethod; + if (vaMeth != null) + { + if (vaMeth.m_dynamicMethod == null) + { + methodHandle = vaMeth.m_method.MethodHandle.Value; + typeHandle = vaMeth.m_method.GetDeclaringTypeInternal().GetTypeHandleInternal().Value; + } + else + methodHandle = vaMeth.m_dynamicMethod.GetMethodDescriptor().Value; + + return; + } + } + + internal override byte[] ResolveSignature(int token, int fromMethod) + { + return m_scope.ResolveSignature(token, fromMethod); + } + + internal override MethodInfo GetDynamicMethod() + { + return m_method.GetMethodInfo(); + } + #endregion + } + + +#if FEATURE_CORECLR +[System.Security.SecurityCritical] // auto-generated +#endif + [System.Runtime.InteropServices.ComVisible(true)] + public class DynamicILInfo + { + #region Private Data Members + private DynamicMethod m_method; + private DynamicScope m_scope; + private byte[] m_exceptions; + private byte[] m_code; + private byte[] m_localSignature; + private int m_maxStackSize; + private int m_methodSignature; + #endregion + + #region Constructor + internal DynamicILInfo(DynamicScope scope, DynamicMethod method, byte[] methodSignature) + { + m_method = method; + m_scope = scope; + m_methodSignature = m_scope.GetTokenFor(methodSignature); + m_exceptions = EmptyArray.Value; + m_code = EmptyArray.Value; + m_localSignature = EmptyArray.Value; + } + #endregion + + #region Internal Methods + [System.Security.SecurityCritical] // auto-generated + internal void GetCallableMethod(RuntimeModule module, DynamicMethod dm) + { + dm.m_methodHandle = ModuleHandle.GetDynamicMethod(dm, + module, m_method.Name, (byte[])m_scope[m_methodSignature], new DynamicResolver(this)); + } + + internal byte[] LocalSignature + { + get + { + if (m_localSignature == null) + m_localSignature = SignatureHelper.GetLocalVarSigHelper().InternalGetSignatureArray(); + + return m_localSignature; + } + } + internal byte[] Exceptions { get { return m_exceptions; } } + internal byte[] Code { get { return m_code; } } + internal int MaxStackSize { get { return m_maxStackSize; } } + #endregion + + #region Public ILGenerator Methods + public DynamicMethod DynamicMethod { get { return m_method; } } + internal DynamicScope DynamicScope { get { return m_scope; } } + + public void SetCode(byte[] code, int maxStackSize) + { + m_code = (code != null) ? (byte[])code.Clone() : EmptyArray.Value; + m_maxStackSize = maxStackSize; + } + + [System.Security.SecurityCritical] // auto-generated + [CLSCompliant(false)] + public unsafe void SetCode(byte* code, int codeSize, int maxStackSize) + { + if (codeSize < 0) + throw new ArgumentOutOfRangeException("codeSize", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive")); + + if (codeSize > 0 && code == null) + throw new ArgumentNullException("code"); + Contract.EndContractBlock(); + + m_code = new byte[codeSize]; + for (int i = 0; i < codeSize; i++) + { + m_code[i] = *code; + code++; + } + + m_maxStackSize = maxStackSize; + } + + public void SetExceptions(byte[] exceptions) + { + m_exceptions = (exceptions != null) ? (byte[])exceptions.Clone() : EmptyArray.Value; + } + + [System.Security.SecurityCritical] // auto-generated + [CLSCompliant(false)] + public unsafe void SetExceptions(byte* exceptions, int exceptionsSize) + { + if (exceptionsSize < 0) + throw new ArgumentOutOfRangeException("exceptionsSize", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive")); + + if (exceptionsSize > 0 && exceptions == null) + throw new ArgumentNullException("exceptions"); + Contract.EndContractBlock(); + + m_exceptions = new byte[exceptionsSize]; + + for (int i = 0; i < exceptionsSize; i++) + { + m_exceptions[i] = *exceptions; + exceptions++; + } + } + + public void SetLocalSignature(byte[] localSignature) + { + m_localSignature = (localSignature != null) ? (byte[])localSignature.Clone() : EmptyArray.Value; + } + + [System.Security.SecurityCritical] // auto-generated + [CLSCompliant(false)] + public unsafe void SetLocalSignature(byte* localSignature, int signatureSize) + { + if (signatureSize < 0) + throw new ArgumentOutOfRangeException("signatureSize", Environment.GetResourceString("ArgumentOutOfRange_GenericPositive")); + + if (signatureSize > 0 && localSignature == null) + throw new ArgumentNullException("localSignature"); + Contract.EndContractBlock(); + + m_localSignature = new byte[signatureSize]; + for (int i = 0; i < signatureSize; i++) + { + m_localSignature[i] = *localSignature; + localSignature++; + } + } + #endregion + + #region Public Scope Methods + [System.Security.SecuritySafeCritical] // auto-generated + public int GetTokenFor(RuntimeMethodHandle method) + { + return DynamicScope.GetTokenFor(method); + } + public int GetTokenFor(DynamicMethod method) + { + return DynamicScope.GetTokenFor(method); + } + public int GetTokenFor(RuntimeMethodHandle method, RuntimeTypeHandle contextType) + { + return DynamicScope.GetTokenFor(method, contextType); + } + public int GetTokenFor(RuntimeFieldHandle field) + { + return DynamicScope.GetTokenFor(field); + } + public int GetTokenFor(RuntimeFieldHandle field, RuntimeTypeHandle contextType) + { + return DynamicScope.GetTokenFor(field, contextType); + } + public int GetTokenFor(RuntimeTypeHandle type) + { + return DynamicScope.GetTokenFor(type); + } + public int GetTokenFor(string literal) + { + return DynamicScope.GetTokenFor(literal); + } + public int GetTokenFor(byte[] signature) + { + return DynamicScope.GetTokenFor(signature); + } + #endregion + } + + internal class DynamicScope + { + #region Private Data Members + internal List m_tokens; + #endregion + + #region Constructor + internal unsafe DynamicScope() + { + m_tokens = new List(); + m_tokens.Add(null); + } + #endregion + + #region Internal Methods + internal object this[int token] + { + get + { + token &= 0x00FFFFFF; + + if (token < 0 || token > m_tokens.Count) + return null; + + return m_tokens[token]; + } + } + + internal int GetTokenFor(VarArgMethod varArgMethod) + { + m_tokens.Add(varArgMethod); + return m_tokens.Count - 1 | (int)MetadataTokenType.MemberRef; + } + internal string GetString(int token) { return this[token] as string; } + + internal byte[] ResolveSignature(int token, int fromMethod) + { + if (fromMethod == 0) + return (byte[])this[token]; + + VarArgMethod vaMethod = this[token] as VarArgMethod; + + if (vaMethod == null) + return null; + + return vaMethod.m_signature.GetSignature(true); + } + #endregion + + #region Public Methods + [System.Security.SecuritySafeCritical] // auto-generated + public int GetTokenFor(RuntimeMethodHandle method) + { + IRuntimeMethodInfo methodReal = method.GetMethodInfo(); + RuntimeMethodHandleInternal rmhi = methodReal.Value; + + if (methodReal != null && !RuntimeMethodHandle.IsDynamicMethod(rmhi)) + { + RuntimeType type = RuntimeMethodHandle.GetDeclaringType(rmhi); + if ((type != null) && RuntimeTypeHandle.HasInstantiation(type)) + { + // Do we really need to retrieve this much info just to throw an exception? + MethodBase m = RuntimeType.GetMethodBase(methodReal); + Type t = m.DeclaringType.GetGenericTypeDefinition(); + + throw new ArgumentException(String.Format( + CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_MethodDeclaringTypeGenericLcg"), m, t)); + } + } + + m_tokens.Add(method); + return m_tokens.Count - 1 | (int)MetadataTokenType.MethodDef; + } + public int GetTokenFor(RuntimeMethodHandle method, RuntimeTypeHandle typeContext) + { + m_tokens.Add(new GenericMethodInfo(method, typeContext)); + return m_tokens.Count - 1 | (int)MetadataTokenType.MethodDef; + } + public int GetTokenFor(DynamicMethod method) + { + m_tokens.Add(method); + return m_tokens.Count - 1 | (int)MetadataTokenType.MethodDef; + } + public int GetTokenFor(RuntimeFieldHandle field) + { + m_tokens.Add(field); + return m_tokens.Count - 1 | (int)MetadataTokenType.FieldDef; + } + public int GetTokenFor(RuntimeFieldHandle field, RuntimeTypeHandle typeContext) + { + m_tokens.Add(new GenericFieldInfo(field, typeContext)); + return m_tokens.Count - 1 | (int)MetadataTokenType.FieldDef; + } + public int GetTokenFor(RuntimeTypeHandle type) + { + m_tokens.Add(type); + return m_tokens.Count - 1 | (int)MetadataTokenType.TypeDef; + } + public int GetTokenFor(string literal) + { + m_tokens.Add(literal); + return m_tokens.Count - 1 | (int)MetadataTokenType.String; + } + public int GetTokenFor(byte[] signature) + { + m_tokens.Add(signature); + return m_tokens.Count - 1 | (int)MetadataTokenType.Signature; + } + #endregion + } + + internal sealed class GenericMethodInfo + { + internal RuntimeMethodHandle m_methodHandle; + internal RuntimeTypeHandle m_context; + + internal GenericMethodInfo(RuntimeMethodHandle methodHandle, RuntimeTypeHandle context) + { + m_methodHandle = methodHandle; + m_context = context; + } + } + + internal sealed class GenericFieldInfo + { + internal RuntimeFieldHandle m_fieldHandle; + internal RuntimeTypeHandle m_context; + + internal GenericFieldInfo(RuntimeFieldHandle fieldHandle, RuntimeTypeHandle context) + { + m_fieldHandle = fieldHandle; + m_context = context; + } + } + + internal sealed class VarArgMethod + { + internal RuntimeMethodInfo m_method; + internal DynamicMethod m_dynamicMethod; + internal SignatureHelper m_signature; + + internal VarArgMethod(DynamicMethod dm, SignatureHelper signature) + { + m_dynamicMethod = dm; + m_signature = signature; + } + + internal VarArgMethod(RuntimeMethodInfo method, SignatureHelper signature) + { + m_method = method; + m_signature = signature; + } + } + +} diff --git a/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs b/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs new file mode 100644 index 0000000000..6f6b436706 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/DynamicMethod.cs @@ -0,0 +1,1039 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection.Emit +{ + using System; + using System.Collections.Generic; + using CultureInfo = System.Globalization.CultureInfo; + using System.Reflection; + using System.Security; + using System.Security.Permissions; + using System.Threading; + using System.Runtime.CompilerServices; + using System.Runtime.Versioning; + using System.Diagnostics.Contracts; + using System.Runtime.InteropServices; + + [System.Runtime.InteropServices.ComVisible(true)] + public sealed class DynamicMethod : MethodInfo + { + private RuntimeType[] m_parameterTypes; + internal IRuntimeMethodInfo m_methodHandle; + private RuntimeType m_returnType; + private DynamicILGenerator m_ilGenerator; + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + private DynamicILInfo m_DynamicILInfo; + private bool m_fInitLocals; + private RuntimeModule m_module; + internal bool m_skipVisibility; + internal RuntimeType m_typeOwner; // can be null + + // We want the creator of the DynamicMethod to control who has access to the + // DynamicMethod (just like we do for delegates). However, a user can get to + // the corresponding RTDynamicMethod using Exception.TargetSite, StackFrame.GetMethod, etc. + // If we allowed use of RTDynamicMethod, the creator of the DynamicMethod would + // not be able to bound access to the DynamicMethod. Hence, we need to ensure that + // we do not allow direct use of RTDynamicMethod. + private RTDynamicMethod m_dynMethod; + + // needed to keep the object alive during jitting + // assigned by the DynamicResolver ctor + internal DynamicResolver m_resolver; + + // Always false unless we are in an immersive (non dev mode) process. +#if FEATURE_APPX + private bool m_profileAPICheck; + + private RuntimeAssembly m_creatorAssembly; +#endif + + internal bool m_restrictedSkipVisibility; + // The context when the method was created. We use this to do the RestrictedMemberAccess checks. + // These checks are done when the method is compiled. This can happen at an arbitrary time, + // when CreateDelegate or Invoke is called, or when another DynamicMethod executes OpCodes.Call. + // We capture the creation context so that we can do the checks against the same context, + // irrespective of when the method gets compiled. Note that the DynamicMethod does not know when + // it is ready for use since there is not API which indictates that IL generation has completed. +#if FEATURE_COMPRESSEDSTACK + internal CompressedStack m_creationContext; +#endif // FEATURE_COMPRESSEDSTACK + private static volatile InternalModuleBuilder s_anonymouslyHostedDynamicMethodsModule; + private static readonly object s_anonymouslyHostedDynamicMethodsModuleLock = new object(); + + // + // class initialization (ctor and init) + // + + private DynamicMethod() { } + + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public DynamicMethod(string name, + Type returnType, + Type[] parameterTypes) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + + Init(name, + MethodAttributes.Public | MethodAttributes.Static, + CallingConventions.Standard, + returnType, + parameterTypes, + null, // owner + null, // m + false, // skipVisibility + true, + ref stackMark); // transparentMethod + } + + [System.Security.SecuritySafeCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public DynamicMethod(string name, + Type returnType, + Type[] parameterTypes, + bool restrictedSkipVisibility) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + + Init(name, + MethodAttributes.Public | MethodAttributes.Static, + CallingConventions.Standard, + returnType, + parameterTypes, + null, // owner + null, // m + restrictedSkipVisibility, + true, + ref stackMark); // transparentMethod + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #else + [System.Security.SecuritySafeCritical] + #endif + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public DynamicMethod(string name, + Type returnType, + Type[] parameterTypes, + Module m) { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + PerformSecurityCheck(m, ref stackMark, false); + Init(name, + MethodAttributes.Public | MethodAttributes.Static, + CallingConventions.Standard, + returnType, + parameterTypes, + null, // owner + m, // m + false, // skipVisibility + false, + ref stackMark); // transparentMethod + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #else + [System.Security.SecuritySafeCritical] + #endif + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public DynamicMethod(string name, + Type returnType, + Type[] parameterTypes, + Module m, + bool skipVisibility) { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + PerformSecurityCheck(m, ref stackMark, skipVisibility); + Init(name, + MethodAttributes.Public | MethodAttributes.Static, + CallingConventions.Standard, + returnType, + parameterTypes, + null, // owner + m, // m + skipVisibility, + false, + ref stackMark); // transparentMethod + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #else + [System.Security.SecuritySafeCritical] + #endif + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public DynamicMethod(string name, + MethodAttributes attributes, + CallingConventions callingConvention, + Type returnType, + Type[] parameterTypes, + Module m, + bool skipVisibility) { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + PerformSecurityCheck(m, ref stackMark, skipVisibility); + Init(name, + attributes, + callingConvention, + returnType, + parameterTypes, + null, // owner + m, // m + skipVisibility, + false, + ref stackMark); // transparentMethod + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #else + [System.Security.SecuritySafeCritical] + #endif + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public DynamicMethod(string name, + Type returnType, + Type[] parameterTypes, + Type owner) { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + PerformSecurityCheck(owner, ref stackMark, false); + Init(name, + MethodAttributes.Public | MethodAttributes.Static, + CallingConventions.Standard, + returnType, + parameterTypes, + owner, // owner + null, // m + false, // skipVisibility + false, + ref stackMark); // transparentMethod + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #else + [System.Security.SecuritySafeCritical] + #endif + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public DynamicMethod(string name, + Type returnType, + Type[] parameterTypes, + Type owner, + bool skipVisibility) { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + PerformSecurityCheck(owner, ref stackMark, skipVisibility); + Init(name, + MethodAttributes.Public | MethodAttributes.Static, + CallingConventions.Standard, + returnType, + parameterTypes, + owner, // owner + null, // m + skipVisibility, + false, + ref stackMark); // transparentMethod + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #else + [System.Security.SecuritySafeCritical] + #endif + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public DynamicMethod(string name, + MethodAttributes attributes, + CallingConventions callingConvention, + Type returnType, + Type[] parameterTypes, + Type owner, + bool skipVisibility) { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + PerformSecurityCheck(owner, ref stackMark, skipVisibility); + Init(name, + attributes, + callingConvention, + returnType, + parameterTypes, + owner, // owner + null, // m + skipVisibility, + false, + ref stackMark); // transparentMethod + } + + // helpers for intialization + + static private void CheckConsistency(MethodAttributes attributes, CallingConventions callingConvention) { + // only static public for method attributes + if ((attributes & ~MethodAttributes.MemberAccessMask) != MethodAttributes.Static) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags")); + if ((attributes & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags")); + Contract.EndContractBlock(); + + // only standard or varargs supported + if (callingConvention != CallingConventions.Standard && callingConvention != CallingConventions.VarArgs) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags")); + + // vararg is not supported at the moment + if (callingConvention == CallingConventions.VarArgs) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicMethodFlags")); + } + + // We create a transparent assembly to host DynamicMethods. Since the assembly does not have any + // non-public fields (or any fields at all), it is a safe anonymous assembly to host DynamicMethods + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + private static RuntimeModule GetDynamicMethodsModule() + { + if (s_anonymouslyHostedDynamicMethodsModule != null) + return s_anonymouslyHostedDynamicMethodsModule; + + lock (s_anonymouslyHostedDynamicMethodsModuleLock) + { + if (s_anonymouslyHostedDynamicMethodsModule != null) + return s_anonymouslyHostedDynamicMethodsModule; + + ConstructorInfo transparencyCtor = typeof(SecurityTransparentAttribute).GetConstructor(Type.EmptyTypes); + CustomAttributeBuilder transparencyAttribute = new CustomAttributeBuilder(transparencyCtor, EmptyArray.Value); + List assemblyAttributes = new List(); + assemblyAttributes.Add(transparencyAttribute); +#if !FEATURE_CORECLR + // On the desktop, we need to use the security rule set level 1 for anonymously hosted + // dynamic methods. In level 2, transparency rules are strictly enforced, which leads to + // errors when a fully trusted application causes a dynamic method to be generated that tries + // to call a method with a LinkDemand or a SecurityCritical method. To retain compatibility + // with the v2.0 and v3.x frameworks, these calls should be allowed. + // + // If this rule set was not explicitly called out, then the anonymously hosted dynamic methods + // assembly would inherit the rule set from the creating assembly - which would cause it to + // be level 2 because mscorlib.dll is using the level 2 rules. + ConstructorInfo securityRulesCtor = typeof(SecurityRulesAttribute).GetConstructor(new Type[] { typeof(SecurityRuleSet) }); + CustomAttributeBuilder securityRulesAttribute = + new CustomAttributeBuilder(securityRulesCtor, new object[] { SecurityRuleSet.Level1 }); + assemblyAttributes.Add(securityRulesAttribute); +#endif // !FEATURE_CORECLR + + AssemblyName assemblyName = new AssemblyName("Anonymously Hosted DynamicMethods Assembly"); + StackCrawlMark stackMark = StackCrawlMark.LookForMe; + + AssemblyBuilder assembly = AssemblyBuilder.InternalDefineDynamicAssembly( + assemblyName, + AssemblyBuilderAccess.Run, + null, null, null, null, null, + ref stackMark, + assemblyAttributes, + SecurityContextSource.CurrentAssembly); + + AppDomain.PublishAnonymouslyHostedDynamicMethodsAssembly(assembly.GetNativeHandle()); + + // this always gets the internal module. + s_anonymouslyHostedDynamicMethodsModule = (InternalModuleBuilder)assembly.ManifestModule; + } + + return s_anonymouslyHostedDynamicMethodsModule; + } + + [System.Security.SecurityCritical] // auto-generated + private unsafe void Init(String name, + MethodAttributes attributes, + CallingConventions callingConvention, + Type returnType, + Type[] signature, + Type owner, + Module m, + bool skipVisibility, + bool transparentMethod, + ref StackCrawlMark stackMark) + { + DynamicMethod.CheckConsistency(attributes, callingConvention); + + // check and store the signature + if (signature != null) { + m_parameterTypes = new RuntimeType[signature.Length]; + for (int i = 0; i < signature.Length; i++) { + if (signature[i] == null) + throw new ArgumentException(Environment.GetResourceString("Arg_InvalidTypeInSignature")); + m_parameterTypes[i] = signature[i].UnderlyingSystemType as RuntimeType; + if ( m_parameterTypes[i] == null || !(m_parameterTypes[i] is RuntimeType) || m_parameterTypes[i] == (RuntimeType)typeof(void) ) + throw new ArgumentException(Environment.GetResourceString("Arg_InvalidTypeInSignature")); + } + } + else { + m_parameterTypes = Array.Empty(); + } + + // check and store the return value + m_returnType = (returnType == null) ? (RuntimeType)typeof(void) : returnType.UnderlyingSystemType as RuntimeType; + if ( (m_returnType == null) || !(m_returnType is RuntimeType) || m_returnType.IsByRef ) + throw new NotSupportedException(Environment.GetResourceString("Arg_InvalidTypeInRetType")); + + if (transparentMethod) + { + Contract.Assert(owner == null && m == null, "owner and m cannot be set for transparent methods"); + m_module = GetDynamicMethodsModule(); + if (skipVisibility) + { + m_restrictedSkipVisibility = true; + } + +#if FEATURE_COMPRESSEDSTACK + m_creationContext = CompressedStack.Capture(); +#endif // FEATURE_COMPRESSEDSTACK + } + else + { + Contract.Assert(m != null || owner != null, "PerformSecurityCheck should ensure that either m or owner is set"); + Contract.Assert(m == null || !m.Equals(s_anonymouslyHostedDynamicMethodsModule), "The user cannot explicitly use this assembly"); + Contract.Assert(m == null || owner == null, "m and owner cannot both be set"); + + if (m != null) + m_module = m.ModuleHandle.GetRuntimeModule(); // this returns the underlying module for all RuntimeModule and ModuleBuilder objects. + else + { + RuntimeType rtOwner = null; + if (owner != null) + rtOwner = owner.UnderlyingSystemType as RuntimeType; + + if (rtOwner != null) + { + if (rtOwner.HasElementType || rtOwner.ContainsGenericParameters + || rtOwner.IsGenericParameter || rtOwner.IsInterface) + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeForDynamicMethod")); + + m_typeOwner = rtOwner; + m_module = rtOwner.GetRuntimeModule(); + } + } + + m_skipVisibility = skipVisibility; + } + + // initialize remaining fields + m_ilGenerator = null; + m_fInitLocals = true; + m_methodHandle = null; + + if (name == null) + throw new ArgumentNullException("name"); + +#if FEATURE_APPX + if (AppDomain.ProfileAPICheck) + { + if (m_creatorAssembly == null) + m_creatorAssembly = RuntimeAssembly.GetExecutingAssembly(ref stackMark); + + if (m_creatorAssembly != null && !m_creatorAssembly.IsFrameworkAssembly()) + m_profileAPICheck = true; + } +#endif // FEATURE_APPX + + m_dynMethod = new RTDynamicMethod(this, name, attributes, callingConvention); + } + + [System.Security.SecurityCritical] // auto-generated + private void PerformSecurityCheck(Module m, ref StackCrawlMark stackMark, bool skipVisibility) + { + if (m == null) + throw new ArgumentNullException("m"); + Contract.EndContractBlock(); +#if !FEATURE_CORECLR + + RuntimeModule rtModule; + ModuleBuilder mb = m as ModuleBuilder; + if (mb != null) + rtModule = mb.InternalModule; + else + rtModule = m as RuntimeModule; + + if (rtModule == null) + { + throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeModule"), "m"); + } + + // The user cannot explicitly use this assembly + if (rtModule == s_anonymouslyHostedDynamicMethodsModule) + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidValue"), "m"); + + // ask for member access if skip visibility + if (skipVisibility) + new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); + +#if !FEATURE_CORECLR + // ask for control evidence if outside of the caller assembly + RuntimeType callingType = RuntimeMethodHandle.GetCallerType(ref stackMark); + m_creatorAssembly = callingType.GetRuntimeAssembly(); + if (m.Assembly != m_creatorAssembly) + { + // Demand the permissions of the assembly where the DynamicMethod will live + CodeAccessSecurityEngine.ReflectionTargetDemandHelper(PermissionType.SecurityControlEvidence, + m.Assembly.PermissionSet); + } +#else //FEATURE_CORECLR +#pragma warning disable 618 + new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand(); +#pragma warning restore 618 +#endif //FEATURE_CORECLR +#endif //!FEATURE_CORECLR + } + + [System.Security.SecurityCritical] // auto-generated + private void PerformSecurityCheck(Type owner, ref StackCrawlMark stackMark, bool skipVisibility) + { + if (owner == null) + throw new ArgumentNullException("owner"); +#if !FEATURE_CORECLR + + RuntimeType rtOwner = owner as RuntimeType; + if (rtOwner == null) + rtOwner = owner.UnderlyingSystemType as RuntimeType; + + if (rtOwner == null) + throw new ArgumentNullException("owner", Environment.GetResourceString("Argument_MustBeRuntimeType")); + + // get the type the call is coming from + RuntimeType callingType = RuntimeMethodHandle.GetCallerType(ref stackMark); + + // ask for member access if skip visibility + if (skipVisibility) + new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); + else + { + // if the call is not coming from the same class ask for member access + if (callingType != rtOwner) + new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); + } +#if !FEATURE_CORECLR + m_creatorAssembly = callingType.GetRuntimeAssembly(); + + // ask for control evidence if outside of the caller module + if (rtOwner.Assembly != m_creatorAssembly) + { + // Demand the permissions of the assembly where the DynamicMethod will live + CodeAccessSecurityEngine.ReflectionTargetDemandHelper(PermissionType.SecurityControlEvidence, + owner.Assembly.PermissionSet); + } +#else //FEATURE_CORECLR +#pragma warning disable 618 + new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand(); +#pragma warning restore 618 +#endif //FEATURE_CORECLR +#endif //!FEATURE_CORECLR + } + + // + // Delegate and method creation + // + + [System.Security.SecuritySafeCritical] // auto-generated + [System.Runtime.InteropServices.ComVisible(true)] + public sealed override Delegate CreateDelegate(Type delegateType) { + if (m_restrictedSkipVisibility) + { + // Compile the method since accessibility checks are done as part of compilation. + GetMethodDescriptor(); + System.Runtime.CompilerServices.RuntimeHelpers._CompileMethod(m_methodHandle); + } + + MulticastDelegate d = (MulticastDelegate)Delegate.CreateDelegateNoSecurityCheck(delegateType, null, GetMethodDescriptor()); + // stash this MethodInfo by brute force. + d.StoreDynamicMethod(GetMethodInfo()); + return d; + } + + [System.Security.SecuritySafeCritical] // auto-generated + [System.Runtime.InteropServices.ComVisible(true)] + public sealed override Delegate CreateDelegate(Type delegateType, Object target) { + if (m_restrictedSkipVisibility) + { + // Compile the method since accessibility checks are done as part of compilation + GetMethodDescriptor(); + System.Runtime.CompilerServices.RuntimeHelpers._CompileMethod(m_methodHandle); + } + + MulticastDelegate d = (MulticastDelegate)Delegate.CreateDelegateNoSecurityCheck(delegateType, target, GetMethodDescriptor()); + // stash this MethodInfo by brute force. + d.StoreDynamicMethod(GetMethodInfo()); + return d; + } + +#if FEATURE_APPX + internal bool ProfileAPICheck + { + get + { + return m_profileAPICheck; + } + + [FriendAccessAllowed] + set + { + m_profileAPICheck = value; + } + } +#endif + + // This is guaranteed to return a valid handle + [System.Security.SecurityCritical] // auto-generated + internal unsafe RuntimeMethodHandle GetMethodDescriptor() { + if (m_methodHandle == null) { + lock (this) { + if (m_methodHandle == null) { + if (m_DynamicILInfo != null) + m_DynamicILInfo.GetCallableMethod(m_module, this); + else { + if (m_ilGenerator == null || m_ilGenerator.ILOffset == 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadEmptyMethodBody", Name)); + + m_ilGenerator.GetCallableMethod(m_module, this); + } + } + } + } + return new RuntimeMethodHandle(m_methodHandle); + } + + // + // MethodInfo api. They mostly forward to RTDynamicMethod + // + + public override String ToString() { return m_dynMethod.ToString(); } + + public override String Name { get { return m_dynMethod.Name; } } + + public override Type DeclaringType { get { return m_dynMethod.DeclaringType; } } + + public override Type ReflectedType { get { return m_dynMethod.ReflectedType; } } + + public override Module Module { get { return m_dynMethod.Module; } } + + // we cannot return a MethodHandle because we cannot track it via GC so this method is off limits + public override RuntimeMethodHandle MethodHandle { get { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); } } + + public override MethodAttributes Attributes { get { return m_dynMethod.Attributes; } } + + public override CallingConventions CallingConvention { get { return m_dynMethod.CallingConvention; } } + + public override MethodInfo GetBaseDefinition() { return this; } + + [Pure] + public override ParameterInfo[] GetParameters() { return m_dynMethod.GetParameters(); } + + public override MethodImplAttributes GetMethodImplementationFlags() { return m_dynMethod.GetMethodImplementationFlags(); } + + // + // Security transparency accessors + // + // Since the dynamic method may not be JITed yet, we don't always have the runtime method handle + // which is needed to determine the official runtime transparency status of the dynamic method. We + // fall back to saying that the dynamic method matches the transparency of its containing module + // until we get a JITed version, since dynamic methods cannot have attributes of their own. + // + + public override bool IsSecurityCritical + { + [SecuritySafeCritical] + get + { + if (m_methodHandle != null) + { + return RuntimeMethodHandle.IsSecurityCritical(m_methodHandle); + } + else if (m_typeOwner != null) + { + RuntimeAssembly assembly = m_typeOwner.Assembly as RuntimeAssembly; + Contract.Assert(assembly != null); + + return assembly.IsAllSecurityCritical(); + } + else + { + RuntimeAssembly assembly = m_module.Assembly as RuntimeAssembly; + Contract.Assert(assembly != null); + + return assembly.IsAllSecurityCritical(); + } + } + } + + public override bool IsSecuritySafeCritical + { + [SecuritySafeCritical] + get + { + if (m_methodHandle != null) + { + return RuntimeMethodHandle.IsSecuritySafeCritical(m_methodHandle); + } + else if (m_typeOwner != null) + { + RuntimeAssembly assembly = m_typeOwner.Assembly as RuntimeAssembly; + Contract.Assert(assembly != null); + + return assembly.IsAllPublicAreaSecuritySafeCritical(); + } + else + { + RuntimeAssembly assembly = m_module.Assembly as RuntimeAssembly; + Contract.Assert(assembly != null); + + return assembly.IsAllSecuritySafeCritical(); + } + } + } + + public override bool IsSecurityTransparent + { + [SecuritySafeCritical] + get + { + if (m_methodHandle != null) + { + return RuntimeMethodHandle.IsSecurityTransparent(m_methodHandle); + } + else if (m_typeOwner != null) + { + RuntimeAssembly assembly = m_typeOwner.Assembly as RuntimeAssembly; + Contract.Assert(assembly != null); + + return !assembly.IsAllSecurityCritical(); + } + else + { + RuntimeAssembly assembly = m_module.Assembly as RuntimeAssembly; + Contract.Assert(assembly != null); + + return !assembly.IsAllSecurityCritical(); + } + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) { + if ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_CallToVarArg")); + Contract.EndContractBlock(); + + // + // We do not demand any permission here because the caller already has access + // to the current DynamicMethod object, and it could just as easily emit another + // Transparent DynamicMethod to call the current DynamicMethod. + // + + RuntimeMethodHandle method = GetMethodDescriptor(); + // ignore obj since it's a static method + + // create a signature object + Signature sig = new Signature( + this.m_methodHandle, m_parameterTypes, m_returnType, CallingConvention); + + + // verify arguments + int formalCount = sig.Arguments.Length; + int actualCount = (parameters != null) ? parameters.Length : 0; + if (formalCount != actualCount) + throw new TargetParameterCountException(Environment.GetResourceString("Arg_ParmCnt")); + + // if we are here we passed all the previous checks. Time to look at the arguments + Object retValue = null; + if (actualCount > 0) + { + Object[] arguments = CheckArguments(parameters, binder, invokeAttr, culture, sig); + retValue = RuntimeMethodHandle.InvokeMethod(null, arguments, sig, false); + // 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); + } + + GC.KeepAlive(this); + return retValue; + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + return m_dynMethod.GetCustomAttributes(attributeType, inherit); + } + + public override Object[] GetCustomAttributes(bool inherit) { return m_dynMethod.GetCustomAttributes(inherit); } + + public override bool IsDefined(Type attributeType, bool inherit) { return m_dynMethod.IsDefined(attributeType, inherit); } + + public override Type ReturnType { get { return m_dynMethod.ReturnType; } } + + public override ParameterInfo ReturnParameter { get { return m_dynMethod.ReturnParameter; } } + + public override ICustomAttributeProvider ReturnTypeCustomAttributes { get { return m_dynMethod.ReturnTypeCustomAttributes; } } + + // + // DynamicMethod specific methods + // + + public ParameterBuilder DefineParameter(int position, ParameterAttributes attributes, String parameterName) { + if (position < 0 || position > m_parameterTypes.Length) + throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_ParamSequence")); + position--; // it's 1 based. 0 is the return value + + if (position >= 0) { + ParameterInfo[] parameters = m_dynMethod.LoadParameters(); + parameters[position].SetName(parameterName); + parameters[position].SetAttributes(attributes); + } + return null; + } + + [System.Security.SecuritySafeCritical] // auto-generated + public DynamicILInfo GetDynamicILInfo() + { +#pragma warning disable 618 + new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand(); +#pragma warning restore 618 + + if (m_DynamicILInfo != null) + return m_DynamicILInfo; + + return GetDynamicILInfo(new DynamicScope()); + } + + [System.Security.SecurityCritical] // auto-generated + internal DynamicILInfo GetDynamicILInfo(DynamicScope scope) + { + if (m_DynamicILInfo == null) + { + byte[] methodSignature = SignatureHelper.GetMethodSigHelper( + null, CallingConvention, ReturnType, null, null, m_parameterTypes, null, null).GetSignature(true); + m_DynamicILInfo = new DynamicILInfo(scope, this, methodSignature); + } + + return m_DynamicILInfo; + } + + public ILGenerator GetILGenerator() { + return GetILGenerator(64); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public ILGenerator GetILGenerator(int streamSize) + { + if (m_ilGenerator == null) + { + byte[] methodSignature = SignatureHelper.GetMethodSigHelper( + null, CallingConvention, ReturnType, null, null, m_parameterTypes, null, null).GetSignature(true); + m_ilGenerator = new DynamicILGenerator(this, methodSignature, streamSize); + } + return m_ilGenerator; + } + + public bool InitLocals { + get {return m_fInitLocals;} + set {m_fInitLocals = value;} + } + + // + // Internal API + // + + internal MethodInfo GetMethodInfo() { + return m_dynMethod; + } + + ////////////////////////////////////////////////////////////////////////////////////////////// + // RTDynamicMethod + // + // this is actually the real runtime instance of a method info that gets used for invocation + // We need this so we never leak the DynamicMethod out via an exception. + // 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 DynamicMethod m_owner; + ParameterInfo[] m_parameters; + String m_name; + MethodAttributes m_attributes; + CallingConventions m_callingConvention; + + // + // ctors + // + private RTDynamicMethod() {} + + internal RTDynamicMethod(DynamicMethod owner, String name, MethodAttributes attributes, CallingConventions callingConvention) { + m_owner = owner; + m_name = name; + m_attributes = attributes; + m_callingConvention = callingConvention; + } + + // + // MethodInfo api + // + public override String ToString() { + return ReturnType.FormatTypeName() + " " + FormatNameAndSig(); + } + + public override String Name { + get { return m_name; } + } + + public override Type DeclaringType { + get { return null; } + } + + public override Type ReflectedType { + get { return null; } + } + + public override Module Module { + get { return m_owner.m_module; } + } + + public override RuntimeMethodHandle MethodHandle { + get { throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInDynamicMethod")); } + } + + public override MethodAttributes Attributes { + get { return m_attributes; } + } + + public override CallingConventions CallingConvention { + get { return m_callingConvention; } + } + + public override MethodInfo GetBaseDefinition() { + return this; + } + + [Pure] + public override ParameterInfo[] GetParameters() { + ParameterInfo[] privateParameters = LoadParameters(); + ParameterInfo[] parameters = new ParameterInfo[privateParameters.Length]; + Array.Copy(privateParameters, 0, parameters, 0, privateParameters.Length); + return parameters; + } + + public override MethodImplAttributes GetMethodImplementationFlags() { + return MethodImplAttributes.IL | MethodImplAttributes.NoInlining; + } + + public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) { + // We want the creator of the DynamicMethod to control who has access to the + // DynamicMethod (just like we do for delegates). However, a user can get to + // the corresponding RTDynamicMethod using Exception.TargetSite, StackFrame.GetMethod, etc. + // If we allowed use of RTDynamicMethod, the creator of the DynamicMethod would + // not be able to bound access to the DynamicMethod. Hence, we do not allow + // direct use of RTDynamicMethod. + throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeMethodInfo"), "this"); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute))) + return new Object[] { new MethodImplAttribute(GetMethodImplementationFlags()) }; + else + return EmptyArray.Value; + } + + public override Object[] GetCustomAttributes(bool inherit) { + // support for MethodImplAttribute PCA + return new Object[] { new MethodImplAttribute(GetMethodImplementationFlags()) }; + } + + public override bool IsDefined(Type attributeType, bool inherit) { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + if (attributeType.IsAssignableFrom(typeof(MethodImplAttribute))) + return true; + else + return false; + } + + public override bool IsSecurityCritical + { + get { return m_owner.IsSecurityCritical; } + } + + public override bool IsSecuritySafeCritical + { + get { return m_owner.IsSecuritySafeCritical; } + } + + public override bool IsSecurityTransparent + { + get { return m_owner.IsSecurityTransparent; } + } + + public override Type ReturnType + { + get + { + return m_owner.m_returnType; + } + } + + public override ParameterInfo ReturnParameter { + get { return null; } + } + + public override ICustomAttributeProvider ReturnTypeCustomAttributes { + get { return GetEmptyCAHolder(); } + } + + // + // private implementation + // + + internal ParameterInfo[] LoadParameters() { + if (m_parameters == null) { + Type[] parameterTypes = m_owner.m_parameterTypes; + ParameterInfo[] parameters = new ParameterInfo[parameterTypes.Length]; + for (int i = 0; i < parameterTypes.Length; i++) + parameters[i] = new RuntimeParameterInfo(this, null, parameterTypes[i], i); + if (m_parameters == null) + // should we interlockexchange? + m_parameters = parameters; + } + return m_parameters; + } + + // private implementation of CA for the return type + private ICustomAttributeProvider GetEmptyCAHolder() { + return new EmptyCAHolder(); + } + + /////////////////////////////////////////////////// + // EmptyCAHolder + private class EmptyCAHolder : ICustomAttributeProvider { + internal EmptyCAHolder() {} + + Object[] ICustomAttributeProvider.GetCustomAttributes(Type attributeType, bool inherit) { + return EmptyArray.Value; + } + + Object[] ICustomAttributeProvider.GetCustomAttributes(bool inherit) { + return EmptyArray.Value; + } + + bool ICustomAttributeProvider.IsDefined (Type attributeType, bool inherit) { + return false; + } + } + + } + + } + +} + diff --git a/src/mscorlib/src/System/Reflection/Emit/EnumBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/EnumBuilder.cs new file mode 100644 index 0000000000..f8e3ab2991 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/EnumBuilder.cs @@ -0,0 +1,448 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** EnumBuilder is a helper class to build Enum ( a special type ). +** +** +===========================================================*/ +namespace System.Reflection.Emit { + + using System; + using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; + using System.Reflection; + using System.Runtime.InteropServices; + using CultureInfo = System.Globalization.CultureInfo; + using System.Security.Permissions; + + + [HostProtection(MayLeakOnAbort = true)] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_EnumBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + sealed public class EnumBuilder : TypeInfo, _EnumBuilder + { + public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){ + if(typeInfo==null) return false; + return IsAssignableFrom(typeInfo.AsType()); + } + + // Define literal for enum + + public FieldBuilder DefineLiteral(String literalName, Object literalValue) + { + BCLDebug.Log("DYNIL","## DYNIL LOGGING: EnumBuilder.DefineLiteral( " + literalName + " )"); + + // Define the underlying field for the enum. It will be a non-static, private field with special name bit set. + FieldBuilder fieldBuilder = m_typeBuilder.DefineField( + literalName, + this, + FieldAttributes.Public | FieldAttributes.Static | FieldAttributes.Literal); + fieldBuilder.SetConstant(literalValue); + return fieldBuilder; + } + + public TypeInfo CreateTypeInfo() + { + BCLDebug.Log("DYNIL", "## DYNIL LOGGING: EnumBuilder.CreateType() "); + return m_typeBuilder.CreateTypeInfo(); + } + + // CreateType cause EnumBuilder to be baked. + public Type CreateType() + { + BCLDebug.Log("DYNIL","## DYNIL LOGGING: EnumBuilder.CreateType() "); + return m_typeBuilder.CreateType(); + } + + // Get the internal metadata token for this class. + public TypeToken TypeToken { + get {return m_typeBuilder.TypeToken; } + } + + + // return the underlying field for the enum + public FieldBuilder UnderlyingField { + get {return m_underlyingField; } + } + + public override String Name { + get { return m_typeBuilder.Name; } + } + + /**************************************************** + * + * abstract methods defined in the base class + * + */ + public override Guid GUID { + get { + return m_typeBuilder.GUID; + } + } + + public override Object InvokeMember( + String name, + BindingFlags invokeAttr, + Binder binder, + Object target, + Object[] args, + ParameterModifier[] modifiers, + CultureInfo culture, + String[] namedParameters) + { + return m_typeBuilder.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters); + } + + public override Module Module { + get {return m_typeBuilder.Module;} + } + + public override Assembly Assembly { + get {return m_typeBuilder.Assembly;} + } + + public override RuntimeTypeHandle TypeHandle { + get {return m_typeBuilder.TypeHandle;} + } + + public override String FullName { + get { return m_typeBuilder.FullName;} + } + + public override String AssemblyQualifiedName { + get { + return m_typeBuilder.AssemblyQualifiedName; + } + } + + public override String Namespace { + get { return m_typeBuilder.Namespace;} + } + + public override Type BaseType { + get{return m_typeBuilder.BaseType;} + } + + protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr,Binder binder, + CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers) + { + return m_typeBuilder.GetConstructor(bindingAttr, binder, callConvention, + types, modifiers); + } + +[System.Runtime.InteropServices.ComVisible(true)] + public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) + { + return m_typeBuilder.GetConstructors(bindingAttr); + } + + protected override MethodInfo GetMethodImpl(String name,BindingFlags bindingAttr,Binder binder, + CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers) + { + if (types == null) + return m_typeBuilder.GetMethod(name, bindingAttr); + else + return m_typeBuilder.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers); + } + + public override MethodInfo[] GetMethods(BindingFlags bindingAttr) + { + return m_typeBuilder.GetMethods(bindingAttr); + } + + public override FieldInfo GetField(String name, BindingFlags bindingAttr) + { + return m_typeBuilder.GetField(name, bindingAttr); + } + + public override FieldInfo[] GetFields(BindingFlags bindingAttr) + { + return m_typeBuilder.GetFields(bindingAttr); + } + + public override Type GetInterface(String name, bool ignoreCase) + { + return m_typeBuilder.GetInterface(name, ignoreCase); + } + + public override Type[] GetInterfaces() + { + return m_typeBuilder.GetInterfaces(); + } + + public override EventInfo GetEvent(String name, BindingFlags bindingAttr) + { + return m_typeBuilder.GetEvent(name, bindingAttr); + } + + public override EventInfo[] GetEvents() + { + return m_typeBuilder.GetEvents(); + } + + protected override PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, + Type returnType, Type[] types, ParameterModifier[] modifiers) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) + { + return m_typeBuilder.GetProperties(bindingAttr); + } + + public override Type[] GetNestedTypes(BindingFlags bindingAttr) + { + return m_typeBuilder.GetNestedTypes(bindingAttr); + } + + public override Type GetNestedType(String name, BindingFlags bindingAttr) + { + return m_typeBuilder.GetNestedType(name,bindingAttr); + } + + public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr) + { + return m_typeBuilder.GetMember(name, type, bindingAttr); + } + + public override MemberInfo[] GetMembers(BindingFlags bindingAttr) + { + return m_typeBuilder.GetMembers(bindingAttr); + } + +[System.Runtime.InteropServices.ComVisible(true)] + public override InterfaceMapping GetInterfaceMap(Type interfaceType) + { + return m_typeBuilder.GetInterfaceMap(interfaceType); + } + + public override EventInfo[] GetEvents(BindingFlags bindingAttr) + { + return m_typeBuilder.GetEvents(bindingAttr); + } + + protected override TypeAttributes GetAttributeFlagsImpl() + { + return m_typeBuilder.Attributes; + } + + protected override bool IsArrayImpl() + { + return false; + } + protected override bool IsPrimitiveImpl() + { + return false; + } + + protected override bool IsValueTypeImpl() + { + return true; + } + + protected override bool IsByRefImpl() + { + return false; + } + + protected override bool IsPointerImpl() + { + return false; + } + + protected override bool IsCOMObjectImpl() + { + return false; + } + + public override bool IsConstructedGenericType + { + get + { + return false; + } + } + + public override Type GetElementType() + { + return m_typeBuilder.GetElementType(); + } + + protected override bool HasElementTypeImpl() + { + return m_typeBuilder.HasElementType; + } + + // About the SuppressMessageAttribute here - CCRewrite wants us to repeat the base type's precondition + // here, but it will always be true. Rather than adding dead code, I'll silence the warning. + [SuppressMessage("Microsoft.Contracts", "CC1055")] + // Legacy: JScript needs it. + public override Type GetEnumUnderlyingType() + { + return m_underlyingField.FieldType; + } + + public override Type UnderlyingSystemType + { + get + { + return GetEnumUnderlyingType(); + } + } + + //ICustomAttributeProvider + public override Object[] GetCustomAttributes(bool inherit) + { + return m_typeBuilder.GetCustomAttributes(inherit); + } + + // Return a custom attribute identified by Type + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + return m_typeBuilder.GetCustomAttributes(attributeType, inherit); + } + + // Use this function if client decides to form the custom attribute blob themselves + +#if FEATURE_CORECLR +[System.Security.SecurityCritical] // auto-generated +#endif +[System.Runtime.InteropServices.ComVisible(true)] + public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + { + m_typeBuilder.SetCustomAttribute(con, binaryAttribute); + } + + // Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder + public void SetCustomAttribute(CustomAttributeBuilder customBuilder) + { + m_typeBuilder.SetCustomAttribute(customBuilder); + } + + // Return the class that declared this Field. + public override Type DeclaringType { + get {return m_typeBuilder.DeclaringType;} + } + + // Return the class that was used to obtain this field. + + public override Type ReflectedType { + get {return m_typeBuilder.ReflectedType;} + } + + + // Returns true if one or more instance of attributeType is defined on this member. + public override bool IsDefined (Type attributeType, bool inherit) + { + return m_typeBuilder.IsDefined(attributeType, inherit); + } + + + internal int MetadataTokenInternal { get { return m_typeBuilder.MetadataTokenInternal; } } + + /***************************************************** + * + * private/protected functions + * + */ + + //******************************* + // Make a private constructor so these cannot be constructed externally. + //******************************* + private EnumBuilder() {} + + public override Type MakePointerType() + { + return SymbolType.FormCompoundType("*", this, 0); + } + + public override Type MakeByRefType() + { + return SymbolType.FormCompoundType("&", this, 0); + } + + public override Type MakeArrayType() + { + return SymbolType.FormCompoundType("[]", this, 0); + } + + public override Type MakeArrayType(int rank) + { + if (rank <= 0) + throw new IndexOutOfRangeException(); + + string szrank = ""; + if (rank == 1) + { + szrank = "*"; + } + else + { + for(int i = 1; i < rank; i++) + szrank += ","; + } + + string s = String.Format(CultureInfo.InvariantCulture, "[{0}]", szrank); // [,,] + return SymbolType.FormCompoundType(s, this, 0); + } + + + // Constructs a EnumBuilder. + // EnumBuilder can only be a top-level (not nested) enum type. + [System.Security.SecurityCritical] // auto-generated + internal EnumBuilder( + String name, // name of type + Type underlyingType, // underlying type for an Enum + TypeAttributes visibility, // any bits on TypeAttributes.VisibilityMask) + ModuleBuilder module) // module containing this type + { + // Client should not set any bits other than the visibility bits. + if ((visibility & ~TypeAttributes.VisibilityMask) != 0) + throw new ArgumentException(Environment.GetResourceString("Argument_ShouldOnlySetVisibilityFlags"), "name"); + m_typeBuilder = new TypeBuilder(name, visibility | TypeAttributes.Sealed, typeof(System.Enum), null, module, PackingSize.Unspecified, TypeBuilder.UnspecifiedTypeSize, null); + + // Define the underlying field for the enum. It will be a non-static, private field with special name bit set. + m_underlyingField = m_typeBuilder.DefineField("value__", underlyingType, FieldAttributes.Public | FieldAttributes.SpecialName | FieldAttributes.RTSpecialName); + } + +#if !FEATURE_CORECLR + void _EnumBuilder.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _EnumBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _EnumBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _EnumBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + + + /***************************************************** + * + * private data members + * + */ + internal TypeBuilder m_typeBuilder; + private FieldBuilder m_underlyingField; + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/EventBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/EventBuilder.cs new file mode 100644 index 0000000000..42a5252102 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/EventBuilder.cs @@ -0,0 +1,174 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** Eventbuilder is for client to define eevnts for a class +** +** +===========================================================*/ +namespace System.Reflection.Emit { + + using System; + using System.Reflection; + using System.Security.Permissions; + using System.Runtime.InteropServices; + using System.Diagnostics.Contracts; + + // + // A EventBuilder is always associated with a TypeBuilder. The TypeBuilder.DefineEvent + // method will return a new EventBuilder to a client. + // + [HostProtection(MayLeakOnAbort = true)] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_EventBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class EventBuilder : _EventBuilder + { + + // Make a private constructor so these cannot be constructed externally. + private EventBuilder() {} + + // Constructs a EventBuilder. + // + internal EventBuilder( + ModuleBuilder mod, // the module containing this EventBuilder + String name, // Event name + EventAttributes attr, // event attribute such as Public, Private, and Protected defined above + //int eventType, // event type + TypeBuilder type, // containing type + EventToken evToken) + { + m_name = name; + m_module = mod; + m_attributes = attr; + m_evToken = evToken; + m_type = type; + } + + // Return the Token for this event within the TypeBuilder that the + // event is defined within. + public EventToken GetEventToken() + { + return m_evToken; + } + + [System.Security.SecurityCritical] // auto-generated + private void SetMethodSemantics(MethodBuilder mdBuilder, MethodSemanticsAttributes semantics) + { + if (mdBuilder == null) + { + throw new ArgumentNullException("mdBuilder"); + } + Contract.EndContractBlock(); + + m_type.ThrowIfCreated(); + TypeBuilder.DefineMethodSemantics( + m_module.GetNativeHandle(), + m_evToken.Token, + semantics, + mdBuilder.GetToken().Token); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void SetAddOnMethod(MethodBuilder mdBuilder) + { + SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.AddOn); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void SetRemoveOnMethod(MethodBuilder mdBuilder) + { + SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.RemoveOn); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void SetRaiseMethod(MethodBuilder mdBuilder) + { + SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.Fire); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void AddOtherMethod(MethodBuilder mdBuilder) + { + SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.Other); + } + + // Use this function if client decides to form the custom attribute blob themselves + +#if FEATURE_CORECLR +[System.Security.SecurityCritical] // auto-generated +#else +[System.Security.SecuritySafeCritical] +#endif +[System.Runtime.InteropServices.ComVisible(true)] + public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + { + if (con == null) + throw new ArgumentNullException("con"); + if (binaryAttribute == null) + throw new ArgumentNullException("binaryAttribute"); + Contract.EndContractBlock(); + m_type.ThrowIfCreated(); + + TypeBuilder.DefineCustomAttribute( + m_module, + m_evToken.Token, + m_module.GetConstructorToken(con).Token, + binaryAttribute, + false, false); + } + + // Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder + [System.Security.SecuritySafeCritical] // auto-generated + public void SetCustomAttribute(CustomAttributeBuilder customBuilder) + { + if (customBuilder == null) + { + throw new ArgumentNullException("customBuilder"); + } + Contract.EndContractBlock(); + m_type.ThrowIfCreated(); + customBuilder.CreateCustomAttribute(m_module, m_evToken.Token); + } + +#if !FEATURE_CORECLR + void _EventBuilder.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _EventBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _EventBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _EventBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + + + // These are package private so that TypeBuilder can access them. + private String m_name; // The name of the event + private EventToken m_evToken; // The token of this event + private ModuleBuilder m_module; + private EventAttributes m_attributes; + private TypeBuilder m_type; + } + + + + +} diff --git a/src/mscorlib/src/System/Reflection/Emit/EventToken.cs b/src/mscorlib/src/System/Reflection/Emit/EventToken.cs new file mode 100644 index 0000000000..0642cec822 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/EventToken.cs @@ -0,0 +1,69 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** Propertybuilder is for client to define properties for a class +** +** +===========================================================*/ +namespace System.Reflection.Emit { + + using System; + using System.Reflection; + using System.Security.Permissions; + [Serializable] +[System.Runtime.InteropServices.ComVisible(true)] + public struct EventToken + { + public static readonly EventToken Empty = new EventToken(); + + internal int m_event; + + internal EventToken(int str) { + m_event=str; + } + + public int Token { + get { return m_event; } + } + + public override int GetHashCode() + { + return m_event; + } + + public override bool Equals(Object obj) + { + if (obj is EventToken) + return Equals((EventToken)obj); + else + return false; + } + + public bool Equals(EventToken obj) + { + return obj.m_event == m_event; + } + + public static bool operator ==(EventToken a, EventToken b) + { + return a.Equals(b); + } + + public static bool operator !=(EventToken a, EventToken b) + { + return !(a == b); + } + + } + + + + +} diff --git a/src/mscorlib/src/System/Reflection/Emit/FieldBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/FieldBuilder.cs new file mode 100644 index 0000000000..0f2de5be43 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/FieldBuilder.cs @@ -0,0 +1,281 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection.Emit +{ + using System.Runtime.InteropServices; + using System; + using CultureInfo = System.Globalization.CultureInfo; + using System.Reflection; + using System.Security.Permissions; + using System.Diagnostics.Contracts; + + [HostProtection(MayLeakOnAbort = true)] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_FieldBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class FieldBuilder : FieldInfo, _FieldBuilder + { + #region Private Data Members + private int m_fieldTok; + private FieldToken m_tkField; + private TypeBuilder m_typeBuilder; + private String m_fieldName; + private FieldAttributes m_Attributes; + private Type m_fieldType; + #endregion + + #region Constructor + [System.Security.SecurityCritical] // auto-generated + internal FieldBuilder(TypeBuilder typeBuilder, String fieldName, Type type, + Type[] requiredCustomModifiers, Type[] optionalCustomModifiers, FieldAttributes attributes) + { + if (fieldName == null) + throw new ArgumentNullException("fieldName"); + + if (fieldName.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "fieldName"); + + if (fieldName[0] == '\0') + throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), "fieldName"); + + if (type == null) + throw new ArgumentNullException("type"); + + if (type == typeof(void)) + throw new ArgumentException(Environment.GetResourceString("Argument_BadFieldType")); + Contract.EndContractBlock(); + + m_fieldName = fieldName; + m_typeBuilder = typeBuilder; + m_fieldType = type; + m_Attributes = attributes & ~FieldAttributes.ReservedMask; + + SignatureHelper sigHelp = SignatureHelper.GetFieldSigHelper(m_typeBuilder.Module); + sigHelp.AddArgument(type, requiredCustomModifiers, optionalCustomModifiers); + + int sigLength; + byte[] signature = sigHelp.InternalGetSignature(out sigLength); + + m_fieldTok = TypeBuilder.DefineField(m_typeBuilder.GetModuleBuilder().GetNativeHandle(), + typeBuilder.TypeToken.Token, fieldName, signature, sigLength, m_Attributes); + + m_tkField = new FieldToken(m_fieldTok, type); + } + + #endregion + + #region Internal Members + [System.Security.SecurityCritical] // auto-generated + internal void SetData(byte[] data, int size) + { + ModuleBuilder.SetFieldRVAContent(m_typeBuilder.GetModuleBuilder().GetNativeHandle(), m_tkField.Token, data, size); + } + + internal TypeBuilder GetTypeBuilder() { return m_typeBuilder; } + #endregion + + #region MemberInfo Overrides + internal int MetadataTokenInternal + { + get { return m_fieldTok; } + } + + public override Module Module + { + get { return m_typeBuilder.Module; } + } + + public override String Name + { + get {return m_fieldName; } + } + + public override Type DeclaringType + { + get + { + if (m_typeBuilder.m_isHiddenGlobalType == true) + return null; + + return m_typeBuilder; + } + } + + public override Type ReflectedType + { + get + { + if (m_typeBuilder.m_isHiddenGlobalType == true) + return null; + + return m_typeBuilder; + } + } + + #endregion + + #region FieldInfo Overrides + public override Type FieldType + { + get { return m_fieldType; } + } + + public override Object GetValue(Object obj) + { + // NOTE!! If this is implemented, make sure that this throws + // a NotSupportedException for Save-only dynamic assemblies. + // Otherwise, it could cause the .cctor to be executed. + + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + public override void SetValue(Object obj,Object val,BindingFlags invokeAttr,Binder binder,CultureInfo culture) + { + // NOTE!! If this is implemented, make sure that this throws + // a NotSupportedException for Save-only dynamic assemblies. + // Otherwise, it could cause the .cctor to be executed. + + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + public override RuntimeFieldHandle FieldHandle + { + get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); } + } + + public override FieldAttributes Attributes + { + get { return m_Attributes; } + } + + #endregion + + #region ICustomAttributeProvider Implementation + public override Object[] GetCustomAttributes(bool inherit) + { + + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + public override bool IsDefined(Type attributeType, bool inherit) + { + + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + #endregion + + #region Public Members + public FieldToken GetToken() + { + return m_tkField; + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #else + [System.Security.SecuritySafeCritical] + #endif + public void SetOffset(int iOffset) + { + m_typeBuilder.ThrowIfCreated(); + + TypeBuilder.SetFieldLayoutOffset(m_typeBuilder.GetModuleBuilder().GetNativeHandle(), GetToken().Token, iOffset); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [Obsolete("An alternate API is available: Emit the MarshalAs custom attribute instead. http://go.microsoft.com/fwlink/?linkid=14202")] + public void SetMarshal(UnmanagedMarshal unmanagedMarshal) + { + if (unmanagedMarshal == null) + throw new ArgumentNullException("unmanagedMarshal"); + Contract.EndContractBlock(); + + m_typeBuilder.ThrowIfCreated(); + + byte[] ubMarshal = unmanagedMarshal.InternalGetBytes(); + + TypeBuilder.SetFieldMarshal(m_typeBuilder.GetModuleBuilder().GetNativeHandle(), GetToken().Token, ubMarshal, ubMarshal.Length); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void SetConstant(Object defaultValue) + { + m_typeBuilder.ThrowIfCreated(); + + TypeBuilder.SetConstantValue(m_typeBuilder.GetModuleBuilder(), GetToken().Token, m_fieldType, defaultValue); + } + + +#if FEATURE_CORECLR +[System.Security.SecurityCritical] // auto-generated +#else +[System.Security.SecuritySafeCritical] +#endif +[System.Runtime.InteropServices.ComVisible(true)] + public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + { + if (con == null) + throw new ArgumentNullException("con"); + + if (binaryAttribute == null) + throw new ArgumentNullException("binaryAttribute"); + Contract.EndContractBlock(); + + ModuleBuilder module = m_typeBuilder.Module as ModuleBuilder; + + m_typeBuilder.ThrowIfCreated(); + + TypeBuilder.DefineCustomAttribute(module, + m_tkField.Token, module.GetConstructorToken(con).Token, binaryAttribute, false, false); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void SetCustomAttribute(CustomAttributeBuilder customBuilder) + { + if (customBuilder == null) + throw new ArgumentNullException("customBuilder"); + Contract.EndContractBlock(); + + m_typeBuilder.ThrowIfCreated(); + + ModuleBuilder module = m_typeBuilder.Module as ModuleBuilder; + + customBuilder.CreateCustomAttribute(module, m_tkField.Token); + } + + #endregion + +#if !FEATURE_CORECLR + void _FieldBuilder.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _FieldBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _FieldBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _FieldBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/FieldToken.cs b/src/mscorlib/src/System/Reflection/Emit/FieldToken.cs new file mode 100644 index 0000000000..42fd684e7c --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/FieldToken.cs @@ -0,0 +1,86 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** Purpose: Represents a Field to the ILGenerator Class +** +** +===========================================================*/ +namespace System.Reflection.Emit { + + using System; + using System.Reflection; + using System.Security.Permissions; + + // The FieldToken class is an opaque representation of the Token returned + // by the Metadata to represent the field. FieldTokens are generated by + // Module.GetFieldToken(). There are no meaningful accessors on this class, + // but it can be passed to ILGenerator which understands it's internals. + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public struct FieldToken + { + public static readonly FieldToken Empty = new FieldToken(); + + internal int m_fieldTok; + internal Object m_class; + + // Creates an empty FieldToken. A publicly visible constructor so that + // it can be created on the stack. + //public FieldToken() { + // m_fieldTok=0; + // m_attributes=0; + // m_class=null; + //} + // The actual constructor. Sets the field, attributes and class + // variables + + internal FieldToken (int field, Type fieldClass) { + m_fieldTok=field; + m_class = fieldClass; + } + + public int Token { + get { return m_fieldTok; } + } + + + // Generates the hash code for this field. + public override int GetHashCode() + { + return (m_fieldTok); + } + + // Returns true if obj is an instance of FieldToken and is + // equal to this instance. + public override bool Equals(Object obj) + { + if (obj is FieldToken) + return Equals((FieldToken)obj); + else + return false; + } + + public bool Equals(FieldToken obj) + { + return obj.m_fieldTok == m_fieldTok && obj.m_class == m_class; + } + + public static bool operator ==(FieldToken a, FieldToken b) + { + return a.Equals(b); + } + + public static bool operator !=(FieldToken a, FieldToken b) + { + return !(a == b); + } + + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/FlowControl.cs b/src/mscorlib/src/System/Reflection/Emit/FlowControl.cs new file mode 100644 index 0000000000..5bfe5bb7bb --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/FlowControl.cs @@ -0,0 +1,37 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +/*============================================================ +** +** +** +** +**Purpose: Exposes FlowControl Attribute of IL . +** +** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND! +** See clrsrcincopcodegen.pl for more information.** +============================================================*/ +namespace System.Reflection.Emit { + +using System; + +[Serializable] +[System.Runtime.InteropServices.ComVisible(true)] +public enum FlowControl +{ + + Branch = 0, + Break = 1, + Call = 2, + Cond_Branch = 3, + Meta = 4, + Next = 5, +#if !FEATURE_CORECLR + /// + [Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")] + Phi = 6, +#endif + Return = 7, + Throw = 8, +} +} diff --git a/src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs new file mode 100644 index 0000000000..bcf70dbe46 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/GenericTypeParameterBuilder.cs @@ -0,0 +1,248 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection.Emit +{ + using System; + using System.Reflection; + using System.Collections; + using System.Collections.Generic; + using System.Globalization; + using System.Diagnostics.Contracts; + +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class GenericTypeParameterBuilder: TypeInfo + { + public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){ + if(typeInfo==null) return false; + return IsAssignableFrom(typeInfo.AsType()); + } + + #region Private Data Mebers + internal TypeBuilder m_type; + #endregion + + #region Constructor + internal GenericTypeParameterBuilder(TypeBuilder type) + { + m_type = type; + } + #endregion + + #region Object Overrides + public override String ToString() + { + return m_type.Name; + } + public override bool Equals(object o) + { + GenericTypeParameterBuilder g = o as GenericTypeParameterBuilder; + + if (g == null) + return false; + + return object.ReferenceEquals(g.m_type, m_type); + } + public override int GetHashCode() { return m_type.GetHashCode(); } + #endregion + + #region MemberInfo Overrides + public override Type DeclaringType { get { return m_type.DeclaringType; } } + + public override Type ReflectedType { get { return m_type.ReflectedType; } } + + public override String Name { get { return m_type.Name; } } + + public override Module Module { get { return m_type.Module; } } + + internal int MetadataTokenInternal { get { return m_type.MetadataTokenInternal; } } + #endregion + + #region Type Overrides + + public override Type MakePointerType() + { + return SymbolType.FormCompoundType("*", this, 0); + } + + public override Type MakeByRefType() + { + return SymbolType.FormCompoundType("&", this, 0); + } + + public override Type MakeArrayType() + { + return SymbolType.FormCompoundType("[]", this, 0); + } + + public override Type MakeArrayType(int rank) + { + if (rank <= 0) + throw new IndexOutOfRangeException(); + Contract.EndContractBlock(); + + string szrank = ""; + if (rank == 1) + { + szrank = "*"; + } + else + { + for(int i = 1; i < rank; i++) + szrank += ","; + } + + string s = String.Format(CultureInfo.InvariantCulture, "[{0}]", szrank); // [,,] + SymbolType st = SymbolType.FormCompoundType(s, this, 0) as SymbolType; + return st; + } + + public override Guid GUID { get { throw new NotSupportedException(); } } + + public override Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters) { throw new NotSupportedException(); } + + public override Assembly Assembly { get { return m_type.Assembly; } } + + public override RuntimeTypeHandle TypeHandle { get { throw new NotSupportedException(); } } + + public override String FullName { get { return null; } } + + public override String Namespace { get { return null; } } + + public override String AssemblyQualifiedName { get { return null; } } + + public override Type BaseType { get { return m_type.BaseType; } } + + protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { throw new NotSupportedException(); } + +[System.Runtime.InteropServices.ComVisible(true)] + public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { throw new NotSupportedException(); } + + protected override MethodInfo GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { throw new NotSupportedException(); } + + public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { throw new NotSupportedException(); } + + public override FieldInfo GetField(String name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + + public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(); } + + public override Type GetInterface(String name, bool ignoreCase) { throw new NotSupportedException(); } + + public override Type[] GetInterfaces() { throw new NotSupportedException(); } + + public override EventInfo GetEvent(String name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + + public override EventInfo[] GetEvents() { throw new NotSupportedException(); } + + protected override PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) { throw new NotSupportedException(); } + + public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { throw new NotSupportedException(); } + + public override Type[] GetNestedTypes(BindingFlags bindingAttr) { throw new NotSupportedException(); } + + public override Type GetNestedType(String name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + + public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr) { throw new NotSupportedException(); } + +[System.Runtime.InteropServices.ComVisible(true)] + public override InterfaceMapping GetInterfaceMap(Type interfaceType) { throw new NotSupportedException(); } + + public override EventInfo[] GetEvents(BindingFlags bindingAttr) { throw new NotSupportedException(); } + + public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { throw new NotSupportedException(); } + + protected override TypeAttributes GetAttributeFlagsImpl() { return TypeAttributes.Public; } + + protected override bool IsArrayImpl() { return false; } + + protected override bool IsByRefImpl() { return false; } + + protected override bool IsPointerImpl() { return false; } + + protected override bool IsPrimitiveImpl() { return false; } + + protected override bool IsCOMObjectImpl() { return false; } + + public override Type GetElementType() { throw new NotSupportedException(); } + + protected override bool HasElementTypeImpl() { return false; } + + public override Type UnderlyingSystemType { get { return this; } } + + public override Type[] GetGenericArguments() { throw new InvalidOperationException(); } + + public override bool IsGenericTypeDefinition { get { return false; } } + + public override bool IsGenericType { get { return false; } } + + public override bool IsGenericParameter { get { return true; } } + + public override bool IsConstructedGenericType { get { return false; } } + + public override int GenericParameterPosition { get { return m_type.GenericParameterPosition; } } + + public override bool ContainsGenericParameters { get { return m_type.ContainsGenericParameters; } } + + public override GenericParameterAttributes GenericParameterAttributes { get { return m_type.GenericParameterAttributes; } } + + public override MethodBase DeclaringMethod { get { return m_type.DeclaringMethod; } } + + public override Type GetGenericTypeDefinition() { throw new InvalidOperationException(); } + + public override Type MakeGenericType(params Type[] typeArguments) { throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericTypeDefinition")); } + + protected override bool IsValueTypeImpl() { return false; } + + public override bool IsAssignableFrom(Type c) { throw new NotSupportedException(); } + + [System.Runtime.InteropServices.ComVisible(true)] + [Pure] + public override bool IsSubclassOf(Type c) { throw new NotSupportedException(); } + #endregion + + #region ICustomAttributeProvider Implementation + public override Object[] GetCustomAttributes(bool inherit) { throw new NotSupportedException(); } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) { throw new NotSupportedException(); } + + public override bool IsDefined(Type attributeType, bool inherit) { throw new NotSupportedException(); } + #endregion + + #region Public Members + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + { + m_type.SetGenParamCustomAttribute(con, binaryAttribute); + } + + public void SetCustomAttribute(CustomAttributeBuilder customBuilder) + { + m_type.SetGenParamCustomAttribute(customBuilder); + } + + public void SetBaseTypeConstraint(Type baseTypeConstraint) + { + m_type.CheckContext(baseTypeConstraint); + m_type.SetParent(baseTypeConstraint); + } + + [System.Runtime.InteropServices.ComVisible(true)] + public void SetInterfaceConstraints(params Type[] interfaceConstraints) + { + m_type.CheckContext(interfaceConstraints); + m_type.SetInterfaces(interfaceConstraints); + } + + public void SetGenericParameterAttributes(GenericParameterAttributes genericParameterAttributes) + { + m_type.SetGenParamAttributes(genericParameterAttributes); + } + #endregion + } +} + diff --git a/src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs b/src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs new file mode 100644 index 0000000000..15dece9fcb --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/ILGenerator.cs @@ -0,0 +1,2012 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection.Emit +{ + using System; + using TextWriter = System.IO.TextWriter; + using System.Diagnostics.SymbolStore; + using System.Runtime.InteropServices; + using System.Reflection; + using System.Security.Permissions; + using System.Globalization; + using System.Diagnostics.Contracts; + + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_ILGenerator))] + [System.Runtime.InteropServices.ComVisible(true)] + public class ILGenerator : _ILGenerator + { + #region Const Members + private const int defaultSize = 16; + private const int DefaultFixupArraySize = 8; + private const int DefaultLabelArraySize = 4; + private const int DefaultExceptionArraySize = 2; + #endregion + + #region Internal Statics + internal static T[] EnlargeArray(T[] incoming) + { + return EnlargeArray(incoming, incoming.Length * 2); + } + + internal static T[] EnlargeArray(T[] incoming, int requiredSize) + { + Contract.Requires(incoming != null); + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result().Length == requiredSize); + + T[] temp = new T[requiredSize]; + Array.Copy(incoming, 0, temp, 0, incoming.Length); + return temp; + } + + private static byte[] EnlargeArray(byte[] incoming) + { + return EnlargeArray(incoming, incoming.Length * 2); + } + + private static byte[] EnlargeArray(byte[] incoming, int requiredSize) + { + Contract.Requires(incoming != null); + Contract.Ensures(Contract.Result() != null); + Contract.Ensures(Contract.Result().Length == requiredSize); + + byte[] temp = new byte[requiredSize]; + Buffer.BlockCopy(incoming, 0, temp, 0, incoming.Length); + return temp; + } + #endregion + + #region Internal Data Members + private int m_length; + private byte[] m_ILStream; + + private int[] m_labelList; + private int m_labelCount; + + private __FixupData[] m_fixupData; + + private int m_fixupCount; + + private int[] m_RelocFixupList; + private int m_RelocFixupCount; + + private int m_exceptionCount; + private int m_currExcStackCount; + private __ExceptionInfo[] m_exceptions; //This is the list of all of the exceptions in this ILStream. + private __ExceptionInfo[] m_currExcStack; //This is the stack of exceptions which we're currently in. + + internal ScopeTree m_ScopeTree; // this variable tracks all debugging scope information + internal LineNumberInfo m_LineNumberInfo; // this variable tracks all line number information + + internal MethodInfo m_methodBuilder; + internal int m_localCount; + internal SignatureHelper m_localSignature; + + private int m_maxStackSize = 0; // Maximum stack size not counting the exceptions. + + private int m_maxMidStack = 0; // Maximum stack size for a given basic block. + private int m_maxMidStackCur = 0; // Running count of the maximum stack size for the current basic block. + + internal int CurrExcStackCount + { + get { return m_currExcStackCount; } + } + + internal __ExceptionInfo[] CurrExcStack + { + get { return m_currExcStack; } + } + #endregion + + #region Constructor + // package private constructor. This code path is used when client create + // ILGenerator through MethodBuilder. + internal ILGenerator(MethodInfo methodBuilder) : this(methodBuilder, 64) + { + } + + internal ILGenerator(MethodInfo methodBuilder, int size) + { + Contract.Requires(methodBuilder != null); + Contract.Requires(methodBuilder is MethodBuilder || methodBuilder is DynamicMethod); + + if (size < defaultSize) + { + m_ILStream = new byte[defaultSize]; + } + else + { + m_ILStream = new byte[size]; + } + + m_length = 0; + + m_labelCount = 0; + m_fixupCount = 0; + m_labelList = null; + + m_fixupData = null; + + m_exceptions = null; + m_exceptionCount = 0; + m_currExcStack = null; + m_currExcStackCount = 0; + + m_RelocFixupList = null; + m_RelocFixupCount = 0; + + // initialize the scope tree + m_ScopeTree = new ScopeTree(); + m_LineNumberInfo = new LineNumberInfo(); + m_methodBuilder = methodBuilder; + + // initialize local signature + m_localCount = 0; + MethodBuilder mb = m_methodBuilder as MethodBuilder; + if (mb == null) + m_localSignature = SignatureHelper.GetLocalVarSigHelper(null); + else + m_localSignature = SignatureHelper.GetLocalVarSigHelper(mb.GetTypeBuilder().Module); + } + + #endregion + + #region Internal Members + internal virtual void RecordTokenFixup() + { + if (m_RelocFixupList == null) + m_RelocFixupList = new int[DefaultFixupArraySize]; + else if (m_RelocFixupList.Length <= m_RelocFixupCount) + m_RelocFixupList = EnlargeArray(m_RelocFixupList); + + m_RelocFixupList[m_RelocFixupCount++] = m_length; + } + + internal void InternalEmit(OpCode opcode) + { + if (opcode.Size != 1) + { + m_ILStream[m_length++] = (byte)(opcode.Value >> 8); + } + + m_ILStream[m_length++] = (byte)opcode.Value; + + UpdateStackSize(opcode, opcode.StackChange()); + + } + + internal void UpdateStackSize(OpCode opcode, int stackchange) + { + // Updates internal variables for keeping track of the stack size + // requirements for the function. stackchange specifies the amount + // by which the stacksize needs to be updated. + + // Special case for the Return. Returns pops 1 if there is a + // non-void return value. + + // Update the running stacksize. m_maxMidStack specifies the maximum + // amount of stack required for the current basic block irrespective of + // where you enter the block. + m_maxMidStackCur += stackchange; + if (m_maxMidStackCur > m_maxMidStack) + m_maxMidStack = m_maxMidStackCur; + else if (m_maxMidStackCur < 0) + m_maxMidStackCur = 0; + + // If the current instruction signifies end of a basic, which basically + // means an unconditional branch, add m_maxMidStack to m_maxStackSize. + // m_maxStackSize will eventually be the sum of the stack requirements for + // each basic block. + if (opcode.EndsUncondJmpBlk()) + { + m_maxStackSize += m_maxMidStack; + m_maxMidStack = 0; + m_maxMidStackCur = 0; + } + } + + [System.Security.SecurityCritical] // auto-generated + private int GetMethodToken(MethodBase method, Type[] optionalParameterTypes, bool useMethodDef) + { + return ((ModuleBuilder)m_methodBuilder.Module).GetMethodTokenInternal(method, optionalParameterTypes, useMethodDef); + } + + [System.Security.SecurityCritical] // auto-generated + internal virtual SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType, + Type[] parameterTypes, Type[] optionalParameterTypes) + { + return GetMemberRefSignature(call, returnType, parameterTypes, optionalParameterTypes, 0); + } + + [System.Security.SecurityCritical] // auto-generated + private SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType, + Type[] parameterTypes, Type[] optionalParameterTypes, int cGenericParameters) + { + return ((ModuleBuilder)m_methodBuilder.Module).GetMemberRefSignature(call, returnType, parameterTypes, optionalParameterTypes, cGenericParameters); + } + + internal byte[] BakeByteArray() + { + // BakeByteArray is an internal function designed to be called by MethodBuilder to do + // all of the fixups and return a new byte array representing the byte stream with labels resolved, etc. + + int newSize; + int updateAddr; + byte[] newBytes; + + if (m_currExcStackCount != 0) + { + throw new ArgumentException(Environment.GetResourceString("Argument_UnclosedExceptionBlock")); + } + if (m_length == 0) + return null; + + //Calculate the size of the new array. + newSize = m_length; + + //Allocate space for the new array. + newBytes = new byte[newSize]; + + //Copy the data from the old array + Buffer.BlockCopy(m_ILStream, 0, newBytes, 0, newSize); + + //Do the fixups. + //This involves iterating over all of the labels and + //replacing them with their proper values. + for (int i =0; i < m_fixupCount; i++) + { + updateAddr = GetLabelPos(m_fixupData[i].m_fixupLabel) - (m_fixupData[i].m_fixupPos + m_fixupData[i].m_fixupInstSize); + + //Handle single byte instructions + //Throw an exception if they're trying to store a jump in a single byte instruction that doesn't fit. + if (m_fixupData[i].m_fixupInstSize == 1) + { + + //Verify that our one-byte arg will fit into a Signed Byte. + if (updateAddr < SByte.MinValue || updateAddr > SByte.MaxValue) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_IllegalOneByteBranch",m_fixupData[i].m_fixupPos, updateAddr)); + } + + //Place the one-byte arg + if (updateAddr < 0) + { + newBytes[m_fixupData[i].m_fixupPos] = (byte)(256 + updateAddr); + } + else + { + newBytes[m_fixupData[i].m_fixupPos] = (byte)updateAddr; + } + } + else + { + //Place the four-byte arg + PutInteger4InArray(updateAddr, m_fixupData[i].m_fixupPos, newBytes); + } + } + return newBytes; + } + + internal __ExceptionInfo[] GetExceptions() + { + __ExceptionInfo []temp; + if (m_currExcStackCount != 0) + { + throw new NotSupportedException(Environment.GetResourceString(ResId.Argument_UnclosedExceptionBlock)); + } + + if (m_exceptionCount == 0) + { + return null; + } + + temp = new __ExceptionInfo[m_exceptionCount]; + Array.Copy(m_exceptions, 0, temp, 0, m_exceptionCount); + SortExceptions(temp); + return temp; + } + + internal void EnsureCapacity(int size) + { + // Guarantees an array capable of holding at least size elements. + if (m_length + size >= m_ILStream.Length) + { + if (m_length + size >= 2 * m_ILStream.Length) + { + m_ILStream = EnlargeArray(m_ILStream, m_length + size); + } + else + { + m_ILStream = EnlargeArray(m_ILStream); + } + } + } + + internal void PutInteger4(int value) + { + m_length = PutInteger4InArray(value, m_length, m_ILStream); + } + + private static int PutInteger4InArray(int value, int startPos, byte []array) + { + // Puts an Int32 onto the stream. This is an internal routine, so it does not do any error checking. + + array[startPos++] = (byte)value; + array[startPos++] = (byte)(value >>8); + array[startPos++] = (byte)(value >>16); + array[startPos++] = (byte)(value >>24); + return startPos; + } + + private int GetLabelPos(Label lbl) + { + // Gets the position in the stream of a particular label. + // Verifies that the label exists and that it has been given a value. + + int index = lbl.GetLabelValue(); + + if (index < 0 || index >= m_labelCount) + throw new ArgumentException(Environment.GetResourceString("Argument_BadLabel")); + + if (m_labelList[index] < 0) + throw new ArgumentException(Environment.GetResourceString("Argument_BadLabelContent")); + + return m_labelList[index]; + } + + private void AddFixup(Label lbl, int pos, int instSize) + { + // Notes the label, position, and instruction size of a new fixup. Expands + // all of the fixup arrays as appropriate. + + if (m_fixupData == null) + { + m_fixupData = new __FixupData[DefaultFixupArraySize]; + } + else if (m_fixupData.Length <= m_fixupCount) + { + m_fixupData = EnlargeArray(m_fixupData); + } + + m_fixupData[m_fixupCount].m_fixupPos = pos; + m_fixupData[m_fixupCount].m_fixupLabel = lbl; + m_fixupData[m_fixupCount].m_fixupInstSize = instSize; + + m_fixupCount++; + } + + internal int GetMaxStackSize() + { + return m_maxStackSize; + } + + private static void SortExceptions(__ExceptionInfo []exceptions) + { + // In order to call exceptions properly we have to sort them in ascending order by their end position. + // Just a cheap insertion sort. We don't expect many exceptions (<10), where InsertionSort beats QuickSort. + // If we have more exceptions than this in real life, we should consider moving to a QuickSort. + + int least; + __ExceptionInfo temp; + int length = exceptions.Length; + for (int i =0; i < length; i++) + { + least = i; + for (int j =i + 1; j < length; j++) + { + if (exceptions[least].IsInner(exceptions[j])) + { + least = j; + } + } + temp = exceptions[i]; + exceptions[i] = exceptions[least]; + exceptions[least] = temp; + } + } + + internal int[] GetTokenFixups() + { + if (m_RelocFixupCount == 0) + { + Contract.Assert(m_RelocFixupList == null); + return null; + } + + int[] narrowTokens = new int[m_RelocFixupCount]; + Array.Copy(m_RelocFixupList, 0, narrowTokens, 0, m_RelocFixupCount); + return narrowTokens; + } + #endregion + + #region Public Members + + #region Emit + public virtual void Emit(OpCode opcode) + { + EnsureCapacity(3); + InternalEmit(opcode); + + } + + public virtual void Emit(OpCode opcode, byte arg) + { + EnsureCapacity(4); + InternalEmit(opcode); + m_ILStream[m_length++]=arg; + } + + [CLSCompliant(false)] + public void Emit(OpCode opcode, sbyte arg) + { + // Puts opcode onto the stream of instructions followed by arg + + EnsureCapacity(4); + InternalEmit(opcode); + if (arg<0) { + m_ILStream[m_length++]=(byte)(256+arg); + } else { + m_ILStream[m_length++]=(byte) arg; + } + } + + public virtual void Emit(OpCode opcode, short arg) + { + // Puts opcode onto the stream of instructions followed by arg + EnsureCapacity(5); + InternalEmit(opcode); + m_ILStream[m_length++]=(byte) arg; + m_ILStream[m_length++]=(byte) (arg>>8); + } + + public virtual void Emit(OpCode opcode, int arg) + { + // Puts opcode onto the stream of instructions followed by arg + EnsureCapacity(7); + InternalEmit(opcode); + PutInteger4(arg); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public virtual void Emit(OpCode opcode, MethodInfo meth) + { + if (meth == null) + throw new ArgumentNullException("meth"); + Contract.EndContractBlock(); + + if (opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj)) + { + EmitCall(opcode, meth, null); + } + else + { + int stackchange = 0; + + // Reflection doesn't distinguish between these two concepts: + // 1. A generic method definition: Foo`1 + // 2. A generic method definition instantiated over its own generic arguments: Foo`1 + // In RefEmit, we always want 1 for Ld* opcodes and 2 for Call* and Newobj. + bool useMethodDef = opcode.Equals(OpCodes.Ldtoken) || opcode.Equals(OpCodes.Ldftn) || opcode.Equals(OpCodes.Ldvirtftn); + int tk = GetMethodToken(meth, null, useMethodDef); + + EnsureCapacity(7); + InternalEmit(opcode); + + UpdateStackSize(opcode, stackchange); + RecordTokenFixup(); + PutInteger4(tk); + } + } + + + [System.Security.SecuritySafeCritical] // auto-generated + public virtual void EmitCalli(OpCode opcode, CallingConventions callingConvention, + Type returnType, Type[] parameterTypes, Type[] optionalParameterTypes) + { + int stackchange = 0; + SignatureHelper sig; + if (optionalParameterTypes != null) + { + if ((callingConvention & CallingConventions.VarArgs) == 0) + { + // Client should not supply optional parameter in default calling convention + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAVarArgCallingConvention")); + } + } + + ModuleBuilder modBuilder = (ModuleBuilder) m_methodBuilder.Module; + sig = GetMemberRefSignature(callingConvention, + returnType, + parameterTypes, + optionalParameterTypes); + + EnsureCapacity(7); + Emit(OpCodes.Calli); + + // If there is a non-void return type, push one. + if (returnType != typeof(void)) + stackchange++; + // Pop off arguments if any. + if (parameterTypes != null) + stackchange -= parameterTypes.Length; + // Pop off vararg arguments. + if (optionalParameterTypes != null) + stackchange -= optionalParameterTypes.Length; + // Pop the this parameter if the method has a this parameter. + if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis) + stackchange--; + // Pop the native function pointer. + stackchange--; + UpdateStackSize(OpCodes.Calli, stackchange); + + RecordTokenFixup(); + PutInteger4(modBuilder.GetSignatureToken(sig).Token); + } + + public virtual void EmitCalli(OpCode opcode, CallingConvention unmanagedCallConv, Type returnType, Type[] parameterTypes) + { + int stackchange = 0; + int cParams = 0; + int i; + SignatureHelper sig; + + ModuleBuilder modBuilder = (ModuleBuilder) m_methodBuilder.Module; + + if (parameterTypes != null) + { + cParams = parameterTypes.Length; + } + + sig = SignatureHelper.GetMethodSigHelper( + modBuilder, + unmanagedCallConv, + returnType); + + if (parameterTypes != null) + { + for (i = 0; i < cParams; i++) + { + sig.AddArgument(parameterTypes[i]); + } + } + + // If there is a non-void return type, push one. + if (returnType != typeof(void)) + stackchange++; + + // Pop off arguments if any. + if (parameterTypes != null) + stackchange -= cParams; + + // Pop the native function pointer. + stackchange--; + UpdateStackSize(OpCodes.Calli, stackchange); + + EnsureCapacity(7); + Emit(OpCodes.Calli); + RecordTokenFixup(); + PutInteger4(modBuilder.GetSignatureToken(sig).Token); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public virtual void EmitCall(OpCode opcode, MethodInfo methodInfo, Type[] optionalParameterTypes) + { + if (methodInfo == null) + throw new ArgumentNullException("methodInfo"); + + if (!(opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj))) + throw new ArgumentException(Environment.GetResourceString("Argument_NotMethodCallOpcode"), "opcode"); + + Contract.EndContractBlock(); + + int stackchange = 0; + int tk = GetMethodToken(methodInfo, optionalParameterTypes, false); + + EnsureCapacity(7); + InternalEmit(opcode); + + // Push the return value if there is one. + if (methodInfo.ReturnType != typeof(void)) + stackchange++; + // Pop the parameters. + Type[] parameters = methodInfo.GetParameterTypes(); + if (parameters != null) + stackchange -= parameters.Length; + + // Pop the this parameter if the method is non-static and the + // instruction is not newobj. + if (!(methodInfo is SymbolMethod) && methodInfo.IsStatic == false && !(opcode.Equals(OpCodes.Newobj))) + stackchange--; + // Pop the optional parameters off the stack. + if (optionalParameterTypes != null) + stackchange -= optionalParameterTypes.Length; + UpdateStackSize(opcode, stackchange); + + RecordTokenFixup(); + PutInteger4(tk); + } + + public virtual void Emit(OpCode opcode, SignatureHelper signature) + { + if (signature == null) + throw new ArgumentNullException("signature"); + Contract.EndContractBlock(); + + int stackchange = 0; + ModuleBuilder modBuilder = (ModuleBuilder)m_methodBuilder.Module; + SignatureToken sig = modBuilder.GetSignatureToken(signature); + + int tempVal = sig.Token; + + EnsureCapacity(7); + InternalEmit(opcode); + + // The only IL instruction that has VarPop behaviour, that takes a + // Signature token as a parameter is calli. Pop the parameters and + // the native function pointer. To be conservative, do not pop the + // this pointer since this information is not easily derived from + // SignatureHelper. + if (opcode.StackBehaviourPop == StackBehaviour.Varpop) + { + Contract.Assert(opcode.Equals(OpCodes.Calli), + "Unexpected opcode encountered for StackBehaviour VarPop."); + // Pop the arguments.. + stackchange -= signature.ArgumentCount; + // Pop native function pointer off the stack. + stackchange--; + UpdateStackSize(opcode, stackchange); + } + + RecordTokenFixup(); + PutInteger4(tempVal); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [System.Runtime.InteropServices.ComVisible(true)] + public virtual void Emit(OpCode opcode, ConstructorInfo con) + { + if (con == null) + throw new ArgumentNullException("con"); + Contract.EndContractBlock(); + + int stackchange = 0; + + // Constructors cannot be generic so the value of UseMethodDef doesn't matter. + int tk = GetMethodToken(con, null, true); + + EnsureCapacity(7); + InternalEmit(opcode); + + // Make a conservative estimate by assuming a return type and no + // this parameter. + if (opcode.StackBehaviourPush == StackBehaviour.Varpush) + { + // Instruction must be one of call or callvirt. + Contract.Assert(opcode.Equals(OpCodes.Call) || + opcode.Equals(OpCodes.Callvirt), + "Unexpected opcode encountered for StackBehaviour of VarPush."); + stackchange++; + } + if (opcode.StackBehaviourPop == StackBehaviour.Varpop) + { + // Instruction must be one of call, callvirt or newobj. + Contract.Assert(opcode.Equals(OpCodes.Call) || + opcode.Equals(OpCodes.Callvirt) || + opcode.Equals(OpCodes.Newobj), + "Unexpected opcode encountered for StackBehaviour of VarPop."); + + Type[] parameters = con.GetParameterTypes(); + if (parameters != null) + stackchange -= parameters.Length; + } + UpdateStackSize(opcode, stackchange); + + RecordTokenFixup(); + PutInteger4(tk); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public virtual void Emit(OpCode opcode, Type cls) + { + // Puts opcode onto the stream and then the metadata token represented + // by cls. The location of cls is recorded so that the token can be + // patched if necessary when persisting the module to a PE. + + int tempVal = 0; + ModuleBuilder modBuilder = (ModuleBuilder) m_methodBuilder.Module; + if (opcode == OpCodes.Ldtoken && cls != null && cls.IsGenericTypeDefinition) + { + // This gets the token for the generic type definition if cls is one. + tempVal = modBuilder.GetTypeToken( cls ).Token; + } + else + { + // This gets the token for the generic type instantiated on the formal parameters + // if cls is a generic type definition. + tempVal = modBuilder.GetTypeTokenInternal(cls).Token; + } + + EnsureCapacity(7); + InternalEmit(opcode); + RecordTokenFixup(); + PutInteger4(tempVal); + } + + public virtual void Emit(OpCode opcode, long arg) { + EnsureCapacity(11); + InternalEmit(opcode); + m_ILStream[m_length++] = (byte) arg; + m_ILStream[m_length++] = (byte) (arg>>8); + m_ILStream[m_length++] = (byte) (arg>>16); + m_ILStream[m_length++] = (byte) (arg>>24); + m_ILStream[m_length++] = (byte) (arg>>32); + m_ILStream[m_length++] = (byte) (arg>>40); + m_ILStream[m_length++] = (byte) (arg>>48); + m_ILStream[m_length++] = (byte) (arg>>56); + } + + [System.Security.SecuritySafeCritical] // auto-generated + unsafe public virtual void Emit(OpCode opcode, float arg) { + EnsureCapacity(7); + InternalEmit(opcode); + uint tempVal = *(uint*)&arg; + m_ILStream[m_length++] = (byte) tempVal; + m_ILStream[m_length++] = (byte) (tempVal>>8); + m_ILStream[m_length++] = (byte) (tempVal>>16); + m_ILStream[m_length++] = (byte) (tempVal>>24); + } + + [System.Security.SecuritySafeCritical] // auto-generated + unsafe public virtual void Emit(OpCode opcode, double arg) { + EnsureCapacity(11); + InternalEmit(opcode); + ulong tempVal = *(ulong*)&arg; + m_ILStream[m_length++] = (byte) tempVal; + m_ILStream[m_length++] = (byte) (tempVal>>8); + m_ILStream[m_length++] = (byte) (tempVal>>16); + m_ILStream[m_length++] = (byte) (tempVal>>24); + m_ILStream[m_length++] = (byte) (tempVal>>32); + m_ILStream[m_length++] = (byte) (tempVal>>40); + m_ILStream[m_length++] = (byte) (tempVal>>48); + m_ILStream[m_length++] = (byte) (tempVal>>56); + } + + public virtual void Emit(OpCode opcode, Label label) + { + // Puts opcode onto the stream and leaves space to include label + // when fixups are done. Labels are created using ILGenerator.DefineLabel and + // their location within the stream is fixed by using ILGenerator.MarkLabel. + // If a single-byte instruction (designated by the _S suffix in OpCodes.cs) is used, + // the label can represent a jump of at most 127 bytes along the stream. + // + // opcode must represent a branch instruction (although we don't explicitly + // verify this). Since branches are relative instructions, label will be replaced with the + // correct offset to branch during the fixup process. + + int tempVal = label.GetLabelValue(); + EnsureCapacity(7); + + + InternalEmit(opcode); + if (OpCodes.TakesSingleByteArgument(opcode)) { + AddFixup(label, m_length, 1); + m_length++; + } else { + AddFixup(label, m_length, 4); + m_length+=4; + } + } + + public virtual void Emit(OpCode opcode, Label[] labels) + { + if (labels == null) + throw new ArgumentNullException("labels"); + Contract.EndContractBlock(); + + // Emitting a switch table + + int i; + int remaining; // number of bytes remaining for this switch instruction to be substracted + // for computing the offset + + int count = labels.Length; + + EnsureCapacity( count * 4 + 7 ); + InternalEmit(opcode); + PutInteger4(count); + for ( remaining = count * 4, i = 0; remaining > 0; remaining -= 4, i++ ) { + AddFixup( labels[i], m_length, remaining ); + m_length += 4; + } + } + + public virtual void Emit(OpCode opcode, FieldInfo field) + { + ModuleBuilder modBuilder = (ModuleBuilder) m_methodBuilder.Module; + int tempVal = modBuilder.GetFieldToken( field ).Token; + EnsureCapacity(7); + InternalEmit(opcode); + RecordTokenFixup(); + PutInteger4(tempVal); + } + + public virtual void Emit(OpCode opcode, String str) + { + // Puts the opcode onto the IL stream followed by the metadata token + // represented by str. The location of str is recorded for future + // fixups if the module is persisted to a PE. + + ModuleBuilder modBuilder = (ModuleBuilder) m_methodBuilder.Module; + int tempVal = modBuilder.GetStringConstant(str).Token; + EnsureCapacity(7); + InternalEmit(opcode); + PutInteger4(tempVal); + } + + public virtual void Emit(OpCode opcode, LocalBuilder local) + { + // Puts the opcode onto the IL stream followed by the information for local variable local. + + if (local == null) + { + throw new ArgumentNullException("local"); + } + Contract.EndContractBlock(); + int tempVal = local.GetLocalIndex(); + if (local.GetMethodBuilder() != m_methodBuilder) + { + throw new ArgumentException(Environment.GetResourceString("Argument_UnmatchedMethodForLocal"), "local"); + } + // If the instruction is a ldloc, ldloca a stloc, morph it to the optimal form. + if (opcode.Equals(OpCodes.Ldloc)) + { + switch(tempVal) + { + case 0: + opcode = OpCodes.Ldloc_0; + break; + case 1: + opcode = OpCodes.Ldloc_1; + break; + case 2: + opcode = OpCodes.Ldloc_2; + break; + case 3: + opcode = OpCodes.Ldloc_3; + break; + default: + if (tempVal <= 255) + opcode = OpCodes.Ldloc_S; + break; + } + } + else if (opcode.Equals(OpCodes.Stloc)) + { + switch(tempVal) + { + case 0: + opcode = OpCodes.Stloc_0; + break; + case 1: + opcode = OpCodes.Stloc_1; + break; + case 2: + opcode = OpCodes.Stloc_2; + break; + case 3: + opcode = OpCodes.Stloc_3; + break; + default: + if (tempVal <= 255) + opcode = OpCodes.Stloc_S; + break; + } + } + else if (opcode.Equals(OpCodes.Ldloca)) + { + if (tempVal <= 255) + opcode = OpCodes.Ldloca_S; + } + + EnsureCapacity(7); + InternalEmit(opcode); + + if (opcode.OperandType == OperandType.InlineNone) + return; + else if (!OpCodes.TakesSingleByteArgument(opcode)) + { + m_ILStream[m_length++]=(byte) tempVal; + m_ILStream[m_length++]=(byte) (tempVal>>8); + } + else + { + //Handle stloc_1, ldloc_1 + if (tempVal > Byte.MaxValue) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadInstructionOrIndexOutOfBound")); + } + m_ILStream[m_length++]=(byte)tempVal; + } + } + #endregion + + #region Exceptions + public virtual Label BeginExceptionBlock() + { + // Begin an Exception block. Creating an Exception block records some information, + // but does not actually emit any IL onto the stream. Exceptions should be created and + // marked in the following form: + // + // Emit Some IL + // BeginExceptionBlock + // Emit the IL which should appear within the "try" block + // BeginCatchBlock + // Emit the IL which should appear within the "catch" block + // Optional: BeginCatchBlock (this can be repeated an arbitrary number of times + // EndExceptionBlock + + // Delay init + if (m_exceptions == null) + { + m_exceptions = new __ExceptionInfo[DefaultExceptionArraySize]; + } + + if (m_currExcStack == null) + { + m_currExcStack = new __ExceptionInfo[DefaultExceptionArraySize]; + } + + if (m_exceptionCount>=m_exceptions.Length) { + m_exceptions=EnlargeArray(m_exceptions); + } + + if (m_currExcStackCount>=m_currExcStack.Length) { + m_currExcStack = EnlargeArray(m_currExcStack); + } + + Label endLabel = DefineLabel(); + __ExceptionInfo exceptionInfo = new __ExceptionInfo(m_length, endLabel); + + // add the exception to the tracking list + m_exceptions[m_exceptionCount++] = exceptionInfo; + + // Make this exception the current active exception + m_currExcStack[m_currExcStackCount++] = exceptionInfo; + return endLabel; + } + + public virtual void EndExceptionBlock() { + if (m_currExcStackCount==0) { + throw new NotSupportedException(Environment.GetResourceString("Argument_NotInExceptionBlock")); + } + + // Pop the current exception block + __ExceptionInfo current = m_currExcStack[m_currExcStackCount-1]; + m_currExcStack[m_currExcStackCount-1] = null; + m_currExcStackCount--; + + Label endLabel = current.GetEndLabel(); + int state = current.GetCurrentState(); + + if (state == __ExceptionInfo.State_Filter || + state == __ExceptionInfo.State_Try) + { + + + throw new InvalidOperationException(Environment.GetResourceString("Argument_BadExceptionCodeGen")); + } + + if (state == __ExceptionInfo.State_Catch) { + this.Emit(OpCodes.Leave, endLabel); + } else if (state == __ExceptionInfo.State_Finally || state == __ExceptionInfo.State_Fault) { + this.Emit(OpCodes.Endfinally); + } + + //Check if we've alredy set this label. + //The only reason why we might have set this is if we have a finally block. + if (m_labelList[endLabel.GetLabelValue()]==-1) { + MarkLabel(endLabel); + } else { + MarkLabel(current.GetFinallyEndLabel()); + } + + current.Done(m_length); + } + + public virtual void BeginExceptFilterBlock() + { + // Begins a eception filter block. Emits a branch instruction to the end of the current exception block. + + if (m_currExcStackCount == 0) + throw new NotSupportedException(Environment.GetResourceString("Argument_NotInExceptionBlock")); + + __ExceptionInfo current = m_currExcStack[m_currExcStackCount-1]; + + Label endLabel = current.GetEndLabel(); + this.Emit(OpCodes.Leave, endLabel); + + current.MarkFilterAddr(m_length); + } + + public virtual void BeginCatchBlock(Type exceptionType) + { + // Begins a catch block. Emits a branch instruction to the end of the current exception block. + + if (m_currExcStackCount==0) { + throw new NotSupportedException(Environment.GetResourceString("Argument_NotInExceptionBlock")); + } + __ExceptionInfo current = m_currExcStack[m_currExcStackCount-1]; + + if (current.GetCurrentState() == __ExceptionInfo.State_Filter) { + if (exceptionType != null) { + throw new ArgumentException(Environment.GetResourceString("Argument_ShouldNotSpecifyExceptionType")); + } + + this.Emit(OpCodes.Endfilter); + } else { + // execute this branch if previous clause is Catch or Fault + if (exceptionType==null) { + throw new ArgumentNullException("exceptionType"); + } + + Label endLabel = current.GetEndLabel(); + this.Emit(OpCodes.Leave, endLabel); + + } + + current.MarkCatchAddr(m_length, exceptionType); + } + + public virtual void BeginFaultBlock() + { + if (m_currExcStackCount==0) { + throw new NotSupportedException(Environment.GetResourceString("Argument_NotInExceptionBlock")); + } + __ExceptionInfo current = m_currExcStack[m_currExcStackCount-1]; + + // emit the leave for the clause before this one. + Label endLabel = current.GetEndLabel(); + this.Emit(OpCodes.Leave, endLabel); + + current.MarkFaultAddr(m_length); + } + + public virtual void BeginFinallyBlock() + { + if (m_currExcStackCount==0) { + throw new NotSupportedException(Environment.GetResourceString("Argument_NotInExceptionBlock")); + } + __ExceptionInfo current = m_currExcStack[m_currExcStackCount-1]; + int state = current.GetCurrentState(); + Label endLabel = current.GetEndLabel(); + int catchEndAddr = 0; + if (state != __ExceptionInfo.State_Try) + { + // generate leave for any preceeding catch clause + this.Emit(OpCodes.Leave, endLabel); + catchEndAddr = m_length; + } + + MarkLabel(endLabel); + + + Label finallyEndLabel = this.DefineLabel(); + current.SetFinallyEndLabel(finallyEndLabel); + + // generate leave for try clause + this.Emit(OpCodes.Leave, finallyEndLabel); + if (catchEndAddr == 0) + catchEndAddr = m_length; + current.MarkFinallyAddr(m_length, catchEndAddr); + } + + #endregion + + #region Labels + public virtual Label DefineLabel() + { + // Declares a new Label. This is just a token and does not yet represent any particular location + // within the stream. In order to set the position of the label within the stream, you must call + // Mark Label. + + // Delay init the lable array in case we dont use it + if (m_labelList == null){ + m_labelList = new int[DefaultLabelArraySize]; + } + + if (m_labelCount>=m_labelList.Length) { + m_labelList = EnlargeArray(m_labelList); + } + m_labelList[m_labelCount]=-1; + return new Label(m_labelCount++); + } + + public virtual void MarkLabel(Label loc) + { + // Defines a label by setting the position where that label is found within the stream. + // Does not allow a label to be defined more than once. + + int labelIndex = loc.GetLabelValue(); + + //This should never happen. + if (labelIndex<0 || labelIndex>=m_labelList.Length) { + throw new ArgumentException (Environment.GetResourceString("Argument_InvalidLabel")); + } + + if (m_labelList[labelIndex]!=-1) { + throw new ArgumentException (Environment.GetResourceString("Argument_RedefinedLabel")); + } + + m_labelList[labelIndex]=m_length; + } + + #endregion + + #region IL Macros + public virtual void ThrowException(Type excType) + { + // Emits the il to throw an exception + + if (excType==null) { + throw new ArgumentNullException("excType"); + } + + if (!excType.IsSubclassOf(typeof(Exception)) && excType!=typeof(Exception)) { + throw new ArgumentException(Environment.GetResourceString("Argument_NotExceptionType")); + } + Contract.EndContractBlock(); + ConstructorInfo con = excType.GetConstructor(Type.EmptyTypes); + if (con==null) { + throw new ArgumentException(Environment.GetResourceString("Argument_MissingDefaultConstructor")); + } + this.Emit(OpCodes.Newobj, con); + this.Emit(OpCodes.Throw); + } + + private static Type GetConsoleType() + { +#if FEATURE_LEGACYSURFACE + return typeof(Console); +#else + return Type.GetType( + "System.Console, System.Console, Version=4.0.0.0, Culture=neutral, PublicKeyToken=" + AssemblyRef.MicrosoftPublicKeyToken, + throwOnError: true); +#endif + } + + public virtual void EmitWriteLine(String value) + { + // Emits the IL to call Console.WriteLine with a string. + + Emit(OpCodes.Ldstr, value); + Type[] parameterTypes = new Type[1]; + parameterTypes[0] = typeof(String); + MethodInfo mi = GetConsoleType().GetMethod("WriteLine", parameterTypes); + Emit(OpCodes.Call, mi); + } + + public virtual void EmitWriteLine(LocalBuilder localBuilder) + { + // Emits the IL necessary to call WriteLine with lcl. It is + // an error to call EmitWriteLine with a lcl which is not of + // one of the types for which Console.WriteLine implements overloads. (e.g. + // we do *not* call ToString on the locals. + + Object cls; + if (m_methodBuilder==null) + { + throw new ArgumentException(Environment.GetResourceString("InvalidOperation_BadILGeneratorUsage")); + } + + MethodInfo prop = GetConsoleType().GetMethod("get_Out"); + Emit(OpCodes.Call, prop); + Emit(OpCodes.Ldloc, localBuilder); + Type[] parameterTypes = new Type[1]; + cls = localBuilder.LocalType; + if (cls is TypeBuilder || cls is EnumBuilder) { + throw new ArgumentException(Environment.GetResourceString("NotSupported_OutputStreamUsingTypeBuilder")); + } + parameterTypes[0] = (Type)cls; + MethodInfo mi = typeof(TextWriter).GetMethod("WriteLine", parameterTypes); + if (mi==null) { + throw new ArgumentException(Environment.GetResourceString("Argument_EmitWriteLineType"), "localBuilder"); + } + + Emit(OpCodes.Callvirt, mi); + } + + public virtual void EmitWriteLine(FieldInfo fld) + { + // Emits the IL necessary to call WriteLine with fld. It is + // an error to call EmitWriteLine with a fld which is not of + // one of the types for which Console.WriteLine implements overloads. (e.g. + // we do *not* call ToString on the fields. + + Object cls; + + if (fld == null) + { + throw new ArgumentNullException("fld"); + } + Contract.EndContractBlock(); + + MethodInfo prop = GetConsoleType().GetMethod("get_Out"); + Emit(OpCodes.Call, prop); + + if ((fld.Attributes & FieldAttributes.Static)!=0) { + Emit(OpCodes.Ldsfld, fld); + } else { + Emit(OpCodes.Ldarg, (short)0); //Load the this ref. + Emit(OpCodes.Ldfld, fld); + } + Type[] parameterTypes = new Type[1]; + cls = fld.FieldType; + if (cls is TypeBuilder || cls is EnumBuilder) { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_OutputStreamUsingTypeBuilder")); + } + parameterTypes[0] = (Type)cls; + MethodInfo mi = typeof(TextWriter).GetMethod("WriteLine", parameterTypes); + if (mi==null) { + throw new ArgumentException(Environment.GetResourceString("Argument_EmitWriteLineType"), "fld"); + } + Emit(OpCodes.Callvirt, mi); + } + + #endregion + + #region Debug API + public virtual LocalBuilder DeclareLocal(Type localType) + { + return DeclareLocal(localType, false); + } + + public virtual LocalBuilder DeclareLocal(Type localType, bool pinned) + { + // Declare a local of type "local". The current active lexical scope + // will be the scope that local will live. + + LocalBuilder localBuilder; + + MethodBuilder methodBuilder = m_methodBuilder as MethodBuilder; + if (methodBuilder == null) + throw new NotSupportedException(); + + if (methodBuilder.IsTypeCreated()) + { + // cannot change method after its containing type has been created + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TypeHasBeenCreated")); + } + + if (localType==null) { + throw new ArgumentNullException("localType"); + } + + if (methodBuilder.m_bIsBaked) { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodBaked")); + } + + // add the localType to local signature + m_localSignature.AddArgument(localType, pinned); + + localBuilder = new LocalBuilder(m_localCount, localType, methodBuilder, pinned); + m_localCount++; + return localBuilder; + } + + public virtual void UsingNamespace(String usingNamespace) + { + // Specifying the namespace to be used in evaluating locals and watches + // for the current active lexical scope. + + if (usingNamespace == null) + throw new ArgumentNullException("usingNamespace"); + + if (usingNamespace.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "usingNamespace"); + Contract.EndContractBlock(); + + int index; + MethodBuilder methodBuilder = m_methodBuilder as MethodBuilder; + if (methodBuilder == null) + throw new NotSupportedException(); + + index = methodBuilder.GetILGenerator().m_ScopeTree.GetCurrentActiveScopeIndex(); + if (index == -1) + { + methodBuilder.m_localSymInfo.AddUsingNamespace(usingNamespace); + } + else + { + m_ScopeTree.AddUsingNamespaceToCurrentScope(usingNamespace); + } + } + + public virtual void MarkSequencePoint( + ISymbolDocumentWriter document, + int startLine, // line number is 1 based + int startColumn, // column is 0 based + int endLine, // line number is 1 based + int endColumn) // column is 0 based + { + if (startLine == 0 || startLine < 0 || endLine == 0 || endLine < 0) + { + throw new ArgumentOutOfRangeException("startLine"); + } + Contract.EndContractBlock(); + m_LineNumberInfo.AddLineNumberInfo(document, m_length, startLine, startColumn, endLine, endColumn); + } + + public virtual void BeginScope() + { + m_ScopeTree.AddScopeInfo(ScopeAction.Open, m_length); + } + + public virtual void EndScope() + { + m_ScopeTree.AddScopeInfo(ScopeAction.Close, m_length); + } + + public virtual int ILOffset + { + get + { + return m_length; + } + } + + #endregion + + #endregion + +#if !FEATURE_CORECLR + void _ILGenerator.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _ILGenerator.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _ILGenerator.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _ILGenerator.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + } + + internal struct __FixupData + { + internal Label m_fixupLabel; + internal int m_fixupPos; + + internal int m_fixupInstSize; + } + + internal sealed class __ExceptionInfo { + + internal const int None = 0x0000; //COR_ILEXCEPTION_CLAUSE_NONE + internal const int Filter = 0x0001; //COR_ILEXCEPTION_CLAUSE_FILTER + internal const int Finally = 0x0002; //COR_ILEXCEPTION_CLAUSE_FINALLY + internal const int Fault = 0x0004; //COR_ILEXCEPTION_CLAUSE_FAULT + internal const int PreserveStack = 0x0004; //COR_ILEXCEPTION_CLAUSE_PRESERVESTACK + + internal const int State_Try = 0; + internal const int State_Filter =1; + internal const int State_Catch = 2; + internal const int State_Finally = 3; + internal const int State_Fault = 4; + internal const int State_Done = 5; + + internal int m_startAddr; + internal int []m_filterAddr; + internal int []m_catchAddr; + internal int []m_catchEndAddr; + internal int []m_type; + internal Type []m_catchClass; + internal Label m_endLabel; + internal Label m_finallyEndLabel; + internal int m_endAddr; + internal int m_endFinally; + internal int m_currentCatch; + + int m_currentState; + + + //This will never get called. The values exist merely to keep the + //compiler happy. + private __ExceptionInfo() { + m_startAddr = 0; + m_filterAddr = null; + m_catchAddr = null; + m_catchEndAddr = null; + m_endAddr = 0; + m_currentCatch = 0; + m_type = null; + m_endFinally = -1; + m_currentState = State_Try; + } + + internal __ExceptionInfo(int startAddr, Label endLabel) { + m_startAddr=startAddr; + m_endAddr=-1; + m_filterAddr=new int[4]; + m_catchAddr=new int[4]; + m_catchEndAddr=new int[4]; + m_catchClass=new Type[4]; + m_currentCatch=0; + m_endLabel=endLabel; + m_type=new int[4]; + m_endFinally=-1; + m_currentState = State_Try; + } + + private void MarkHelper( + int catchorfilterAddr, // the starting address of a clause + int catchEndAddr, // the end address of a previous catch clause. Only use when finally is following a catch + Type catchClass, // catch exception type + int type) // kind of clause + { + if (m_currentCatch>=m_catchAddr.Length) { + m_filterAddr=ILGenerator.EnlargeArray(m_filterAddr); + m_catchAddr=ILGenerator.EnlargeArray(m_catchAddr); + m_catchEndAddr=ILGenerator.EnlargeArray(m_catchEndAddr); + m_catchClass=ILGenerator.EnlargeArray(m_catchClass); + m_type = ILGenerator.EnlargeArray(m_type); + } + if (type == Filter) + { + m_type[m_currentCatch]=type; + m_filterAddr[m_currentCatch] = catchorfilterAddr; + m_catchAddr[m_currentCatch] = -1; + if (m_currentCatch > 0) + { + Contract.Assert(m_catchEndAddr[m_currentCatch-1] == -1,"m_catchEndAddr[m_currentCatch-1] == -1"); + m_catchEndAddr[m_currentCatch-1] = catchorfilterAddr; + } + } + else + { + // catch or Fault clause + m_catchClass[m_currentCatch]=catchClass; + if (m_type[m_currentCatch] != Filter) + { + m_type[m_currentCatch]=type; + } + m_catchAddr[m_currentCatch]=catchorfilterAddr; + if (m_currentCatch > 0) + { + if (m_type[m_currentCatch] != Filter) + { + Contract.Assert(m_catchEndAddr[m_currentCatch-1] == -1,"m_catchEndAddr[m_currentCatch-1] == -1"); + m_catchEndAddr[m_currentCatch-1] = catchEndAddr; + } + } + m_catchEndAddr[m_currentCatch]=-1; + m_currentCatch++; + } + + if (m_endAddr==-1) + { + m_endAddr=catchorfilterAddr; + } + } + + internal void MarkFilterAddr(int filterAddr) + { + m_currentState = State_Filter; + MarkHelper(filterAddr, filterAddr, null, Filter); + } + + internal void MarkFaultAddr(int faultAddr) + { + m_currentState = State_Fault; + MarkHelper(faultAddr, faultAddr, null, Fault); + } + + internal void MarkCatchAddr(int catchAddr, Type catchException) { + m_currentState = State_Catch; + MarkHelper(catchAddr, catchAddr, catchException, None); + } + + internal void MarkFinallyAddr(int finallyAddr, int endCatchAddr) { + if (m_endFinally!=-1) { + throw new ArgumentException(Environment.GetResourceString("Argument_TooManyFinallyClause")); + } else { + m_currentState = State_Finally; + m_endFinally=finallyAddr; + } + MarkHelper(finallyAddr, endCatchAddr, null, Finally); + } + + internal void Done(int endAddr) { + Contract.Assert(m_currentCatch > 0,"m_currentCatch > 0"); + Contract.Assert(m_catchAddr[m_currentCatch-1] > 0,"m_catchAddr[m_currentCatch-1] > 0"); + Contract.Assert(m_catchEndAddr[m_currentCatch-1] == -1,"m_catchEndAddr[m_currentCatch-1] == -1"); + m_catchEndAddr[m_currentCatch-1] = endAddr; + m_currentState = State_Done; + } + + internal int GetStartAddress() { + return m_startAddr; + } + + internal int GetEndAddress() { + return m_endAddr; + } + + internal int GetFinallyEndAddress() { + return m_endFinally; + } + + internal Label GetEndLabel() { + return m_endLabel; + } + + internal int [] GetFilterAddresses() { + return m_filterAddr; + } + + internal int [] GetCatchAddresses() { + return m_catchAddr; + } + + internal int [] GetCatchEndAddresses() { + return m_catchEndAddr; + } + + internal Type [] GetCatchClass() { + return m_catchClass; + } + + internal int GetNumberOfCatches() { + return m_currentCatch; + } + + internal int[] GetExceptionTypes() { + return m_type; + } + + internal void SetFinallyEndLabel(Label lbl) { + m_finallyEndLabel=lbl; + } + + internal Label GetFinallyEndLabel() { + return m_finallyEndLabel; + } + + // Specifies whether exc is an inner exception for "this". The way + // its determined is by comparing the end address for the last catch + // clause for both exceptions. If they're the same, the start address + // for the exception is compared. + // WARNING: This is not a generic function to determine the innerness + // of an exception. This is somewhat of a mis-nomer. This gives a + // random result for cases where the two exceptions being compared do + // not having a nesting relation. + internal bool IsInner(__ExceptionInfo exc) { + Contract.Requires(exc != null); + Contract.Assert(m_currentCatch > 0,"m_currentCatch > 0"); + Contract.Assert(exc.m_currentCatch > 0,"exc.m_currentCatch > 0"); + + int exclast = exc.m_currentCatch - 1; + int last = m_currentCatch - 1; + + if (exc.m_catchEndAddr[exclast] < m_catchEndAddr[last]) + return true; + else if (exc.m_catchEndAddr[exclast] == m_catchEndAddr[last]) + { + Contract.Assert(exc.GetEndAddress() != GetEndAddress(), + "exc.GetEndAddress() != GetEndAddress()"); + if (exc.GetEndAddress() > GetEndAddress()) + return true; + } + return false; + } + + // 0 indicates in a try block + // 1 indicates in a filter block + // 2 indicates in a catch block + // 3 indicates in a finally block + // 4 indicates Done + internal int GetCurrentState() { + return m_currentState; + } + } + + + /*************************** + * + * Scope Tree is a class that track the scope structure within a method body + * It keeps track two parallel array. m_ScopeAction keeps track the action. It can be + * OpenScope or CloseScope. m_iOffset records the offset where the action + * takes place. + * + ***************************/ + [Serializable] + enum ScopeAction + { + Open = 0x0, + Close = 0x1, + } + + internal sealed class ScopeTree + { + internal ScopeTree() + { + // initialize data variables + m_iOpenScopeCount = 0; + m_iCount = 0; + } + + /*************************** + * + * Find the current active lexcial scope. For example, if we have + * "Open Open Open Close", + * we will return 1 as the second BeginScope is currently active. + * + ***************************/ + internal int GetCurrentActiveScopeIndex() + { + int cClose = 0; + int i = m_iCount - 1; + + if (m_iCount == 0) + { + return -1; + } + for (; cClose > 0 || m_ScopeActions[i] == ScopeAction.Close; i--) + { + if (m_ScopeActions[i] == ScopeAction.Open) + { + cClose--; + } + else + cClose++; + } + + return i; + } + + internal void AddLocalSymInfoToCurrentScope( + String strName, + byte[] signature, + int slot, + int startOffset, + int endOffset) + { + int i = GetCurrentActiveScopeIndex(); + if (m_localSymInfos[i] == null) + { + m_localSymInfos[i] = new LocalSymInfo(); + } + m_localSymInfos[i].AddLocalSymInfo(strName, signature, slot, startOffset, endOffset); + } + + internal void AddUsingNamespaceToCurrentScope( + String strNamespace) + { + int i = GetCurrentActiveScopeIndex(); + if (m_localSymInfos[i] == null) + { + m_localSymInfos[i] = new LocalSymInfo(); + } + m_localSymInfos[i].AddUsingNamespace(strNamespace); + } + + internal void AddScopeInfo(ScopeAction sa, int iOffset) + { + if (sa == ScopeAction.Close && m_iOpenScopeCount <=0) + { + throw new ArgumentException(Environment.GetResourceString("Argument_UnmatchingSymScope")); + } + Contract.EndContractBlock(); + + // make sure that arrays are large enough to hold addition info + EnsureCapacity(); + + + m_ScopeActions[m_iCount] = sa; + m_iOffsets[m_iCount] = iOffset; + m_localSymInfos[m_iCount] = null; + checked { m_iCount++; } + if (sa == ScopeAction.Open) + { + m_iOpenScopeCount++; + } + else + m_iOpenScopeCount--; + + } + + /************************** + * + * Helper to ensure arrays are large enough + * + **************************/ + internal void EnsureCapacity() + { + if (m_iCount == 0) + { + // First time. Allocate the arrays. + m_iOffsets = new int[InitialSize]; + m_ScopeActions = new ScopeAction[InitialSize]; + m_localSymInfos = new LocalSymInfo[InitialSize]; + } + else if (m_iCount == m_iOffsets.Length) + { + // the arrays are full. Enlarge the arrays + // It would probably be simpler to just use Lists here. + int newSize = checked(m_iCount * 2); + int[] temp = new int[newSize]; + Array.Copy(m_iOffsets, 0, temp, 0, m_iCount); + m_iOffsets = temp; + + ScopeAction[] tempSA = new ScopeAction[newSize]; + Array.Copy(m_ScopeActions, 0, tempSA, 0, m_iCount); + m_ScopeActions = tempSA; + + LocalSymInfo[] tempLSI = new LocalSymInfo[newSize]; + Array.Copy(m_localSymInfos, 0, tempLSI, 0, m_iCount); + m_localSymInfos = tempLSI; + } + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal void EmitScopeTree(ISymbolWriter symWriter) + { + int i; + for (i = 0; i < m_iCount; i++) + { + if (m_ScopeActions[i] == ScopeAction.Open) + { + symWriter.OpenScope(m_iOffsets[i]); + } + else + { + symWriter.CloseScope(m_iOffsets[i]); + } + if (m_localSymInfos[i] != null) + { + m_localSymInfos[i].EmitLocalSymInfo(symWriter); + } + } + } + + internal int[] m_iOffsets; // array of offsets + internal ScopeAction[] m_ScopeActions; // array of scope actions + internal int m_iCount; // how many entries in the arrays are occupied + internal int m_iOpenScopeCount; // keep track how many scopes are open + internal const int InitialSize = 16; + internal LocalSymInfo[] m_localSymInfos; // keep track debugging local information + } + + + /*************************** + * + * This class tracks the line number info + * + ***************************/ + internal sealed class LineNumberInfo + { + internal LineNumberInfo() + { + // initialize data variables + m_DocumentCount = 0; + m_iLastFound = 0; + } + + internal void AddLineNumberInfo( + ISymbolDocumentWriter document, + int iOffset, + int iStartLine, + int iStartColumn, + int iEndLine, + int iEndColumn) + { + int i; + + // make sure that arrays are large enough to hold addition info + i = FindDocument(document); + + Contract.Assert(i < m_DocumentCount, "Bad document look up!"); + m_Documents[i].AddLineNumberInfo(document, iOffset, iStartLine, iStartColumn, iEndLine, iEndColumn); + } + + // Find a REDocument representing document. If we cannot find one, we will add a new entry into + // the REDocument array. + private int FindDocument(ISymbolDocumentWriter document) + { + int i; + + // This is an optimization. The chance that the previous line is coming from the same + // document is very high. + if (m_iLastFound < m_DocumentCount && m_Documents[m_iLastFound].m_document == document) + return m_iLastFound; + + for (i = 0; i < m_DocumentCount; i++) + { + if (m_Documents[i].m_document == document) + { + m_iLastFound = i; + return m_iLastFound; + } + } + + // cannot find an existing document so add one to the array + EnsureCapacity(); + m_iLastFound = m_DocumentCount; + m_Documents[m_iLastFound] = new REDocument(document); + checked { m_DocumentCount++; } + return m_iLastFound; + } + + /************************** + * + * Helper to ensure arrays are large enough + * + **************************/ + private void EnsureCapacity() + { + if (m_DocumentCount == 0) + { + // First time. Allocate the arrays. + m_Documents = new REDocument[InitialSize]; + } + else if (m_DocumentCount == m_Documents.Length) + { + // the arrays are full. Enlarge the arrays + REDocument[] temp = new REDocument [m_DocumentCount * 2]; + Array.Copy(m_Documents, 0, temp, 0, m_DocumentCount); + m_Documents = temp; + } + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal void EmitLineNumberInfo(ISymbolWriter symWriter) + { + for (int i = 0; i < m_DocumentCount; i++) + m_Documents[i].EmitLineNumberInfo(symWriter); + } + + private int m_DocumentCount; // how many documents that we have right now + private REDocument[] m_Documents; // array of documents + private const int InitialSize = 16; + private int m_iLastFound; + } + + + /*************************** + * + * This class tracks the line number info + * + ***************************/ + internal sealed class REDocument + { + internal REDocument(ISymbolDocumentWriter document) + { + // initialize data variables + m_iLineNumberCount = 0; + m_document = document; + } + + internal void AddLineNumberInfo( + ISymbolDocumentWriter document, + int iOffset, + int iStartLine, + int iStartColumn, + int iEndLine, + int iEndColumn) + { + Contract.Assert(document == m_document, "Bad document look up!"); + + // make sure that arrays are large enough to hold addition info + EnsureCapacity(); + + m_iOffsets[m_iLineNumberCount] = iOffset; + m_iLines[m_iLineNumberCount] = iStartLine; + m_iColumns[m_iLineNumberCount] = iStartColumn; + m_iEndLines[m_iLineNumberCount] = iEndLine; + m_iEndColumns[m_iLineNumberCount] = iEndColumn; + checked { m_iLineNumberCount++; } + } + + /************************** + * + * Helper to ensure arrays are large enough + * + **************************/ + private void EnsureCapacity() + { + if (m_iLineNumberCount == 0) + { + // First time. Allocate the arrays. + m_iOffsets = new int[InitialSize]; + m_iLines = new int[InitialSize]; + m_iColumns = new int[InitialSize]; + m_iEndLines = new int[InitialSize]; + m_iEndColumns = new int[InitialSize]; + } + else if (m_iLineNumberCount == m_iOffsets.Length) + { + // the arrays are full. Enlarge the arrays + // It would probably be simpler to just use Lists here + int newSize = checked(m_iLineNumberCount * 2); + int[] temp = new int [newSize]; + Array.Copy(m_iOffsets, 0, temp, 0, m_iLineNumberCount); + m_iOffsets = temp; + + temp = new int [newSize]; + Array.Copy(m_iLines, 0, temp, 0, m_iLineNumberCount); + m_iLines = temp; + + temp = new int [newSize]; + Array.Copy(m_iColumns, 0, temp, 0, m_iLineNumberCount); + m_iColumns = temp; + + temp = new int [newSize]; + Array.Copy(m_iEndLines, 0, temp, 0, m_iLineNumberCount); + m_iEndLines = temp; + + temp = new int [newSize]; + Array.Copy(m_iEndColumns, 0, temp, 0, m_iLineNumberCount); + m_iEndColumns = temp; + } + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal void EmitLineNumberInfo(ISymbolWriter symWriter) + { + int[] iOffsetsTemp; + int[] iLinesTemp; + int[] iColumnsTemp; + int[] iEndLinesTemp; + int[] iEndColumnsTemp; + + if (m_iLineNumberCount == 0) + return; + // reduce the array size to be exact + iOffsetsTemp = new int [m_iLineNumberCount]; + Array.Copy(m_iOffsets, 0, iOffsetsTemp, 0, m_iLineNumberCount); + + iLinesTemp = new int [m_iLineNumberCount]; + Array.Copy(m_iLines, 0, iLinesTemp, 0, m_iLineNumberCount); + + iColumnsTemp = new int [m_iLineNumberCount]; + Array.Copy(m_iColumns, 0, iColumnsTemp, 0, m_iLineNumberCount); + + iEndLinesTemp = new int [m_iLineNumberCount]; + Array.Copy(m_iEndLines, 0, iEndLinesTemp, 0, m_iLineNumberCount); + + iEndColumnsTemp = new int [m_iLineNumberCount]; + Array.Copy(m_iEndColumns, 0, iEndColumnsTemp, 0, m_iLineNumberCount); + + symWriter.DefineSequencePoints(m_document, iOffsetsTemp, iLinesTemp, iColumnsTemp, iEndLinesTemp, iEndColumnsTemp); + } + + private int[] m_iOffsets; // array of offsets + private int[] m_iLines; // array of offsets + private int[] m_iColumns; // array of offsets + private int[] m_iEndLines; // array of offsets + private int[] m_iEndColumns; // array of offsets + internal ISymbolDocumentWriter m_document; // The ISymbolDocumentWriter that this REDocument is tracking. + private int m_iLineNumberCount; // how many entries in the arrays are occupied + private const int InitialSize = 16; + } // end of REDocument +} diff --git a/src/mscorlib/src/System/Reflection/Emit/ISymWrapperCore.cs b/src/mscorlib/src/System/Reflection/Emit/ISymWrapperCore.cs new file mode 100644 index 0000000000..00fdd00315 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/ISymWrapperCore.cs @@ -0,0 +1,828 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +#if FEATURE_CORECLR + +namespace System.Reflection.Emit +{ + using System; + using System.Security; + using System.Runtime.InteropServices; + using System.Runtime.CompilerServices; + using System.Diagnostics.SymbolStore; + + + //----------------------------------------------------------------------------------- + // On Telesto, we don't ship the ISymWrapper.dll assembly. However, ReflectionEmit + // relies on that assembly to write out managed PDBs. + // + // This file implements the minimum subset of ISymWrapper.dll required to restore + // that functionality. Namely, the SymWriter and SymDocumentWriter objects. + // + // Ideally we wouldn't need ISymWrapper.dll on desktop either - it's an ugly piece + // of legacy. We could just use this (or COM-interop code) everywhere, but we might + // have to worry about compatibility. + // + // We've now got a real implementation even when no debugger is attached. It's + // up to the runtime to ensure it doesn't provide us with an insecure writer + // (eg. diasymreader) in the no-trust scenarios (no debugger, partial-trust code). + //----------------------------------------------------------------------------------- + + + //------------------------------------------------------------------------------ + // SymWrapperCore is never instantiated and is used as an encapsulation class. + // It is our "ISymWrapper.dll" assembly within an assembly. + //------------------------------------------------------------------------------ + class SymWrapperCore + { + //------------------------------------------------------------------------------ + // Block instantiation + //------------------------------------------------------------------------------ + private SymWrapperCore() + { + } + + //------------------------------------------------------------------------------ + // Implements Telesto's version of SymDocumentWriter (in the desktop world, + // this type is exposed from ISymWrapper.dll.) + // + // The only thing user code can do with this wrapper is to receive it from + // SymWriter.DefineDocument and pass it back to SymWriter.DefineSequencePoints. + //------------------------------------------------------------------------------ + private unsafe class SymDocumentWriter : ISymbolDocumentWriter + { + + //------------------------------------------------------------------------------ + // Ctor + //------------------------------------------------------------------------------ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal SymDocumentWriter(PunkSafeHandle pDocumentWriterSafeHandle) + { + m_pDocumentWriterSafeHandle = pDocumentWriterSafeHandle; + // The handle is actually a pointer to a native ISymUnmanagedDocumentWriter. + m_pDocWriter = (ISymUnmanagedDocumentWriter *)m_pDocumentWriterSafeHandle.DangerousGetHandle(); + m_vtable = (ISymUnmanagedDocumentWriterVTable)(Marshal.PtrToStructure(m_pDocWriter->m_unmanagedVTable, typeof(ISymUnmanagedDocumentWriterVTable))); + } + + //------------------------------------------------------------------------------ + // Returns the underlying ISymUnmanagedDocumentWriter* (as a safehandle.) + //------------------------------------------------------------------------------ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal PunkSafeHandle GetUnmanaged() + { + return m_pDocumentWriterSafeHandle; + } + + + //========================================================================================= + // Public interface methods start here. (Well actually, they're all NotSupported + // stubs since that's what they are on the real ISymWrapper.dll.) + //========================================================================================= + + //------------------------------------------------------------------------------ + // SetSource() wrapper + //------------------------------------------------------------------------------ + void ISymbolDocumentWriter.SetSource(byte[] source) + { + throw new NotSupportedException(); // Intentionally not supported to match desktop CLR + } + + //------------------------------------------------------------------------------ + // SetCheckSum() wrapper + //------------------------------------------------------------------------------ + #if FEATURE_CORECLR + [System.Security.SecuritySafeCritical] + #endif + void ISymbolDocumentWriter.SetCheckSum(Guid algorithmId, byte [] checkSum) + { + int hr = m_vtable.SetCheckSum(m_pDocWriter, algorithmId, (uint)checkSum.Length, checkSum); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + } + + [System.Security.SecurityCritical] + private delegate int DSetCheckSum(ISymUnmanagedDocumentWriter * pThis, Guid algorithmId, uint checkSumSize, [In] byte[] checkSum); + + //------------------------------------------------------------------------------ + // This layout must match the unmanaged ISymUnmanagedDocumentWriter* COM vtable + // exactly. If a member is declared as an IntPtr rather than a delegate, it means + // we don't call that particular member. + //------------------------------------------------------------------------------ + [System.Security.SecurityCritical] + [StructLayout(LayoutKind.Sequential)] + private struct ISymUnmanagedDocumentWriterVTable + { + internal IntPtr QueryInterface; + internal IntPtr AddRef; + internal IntPtr Release; + + internal IntPtr SetSource; + #if FEATURE_CORECLR + [System.Security.SecurityCritical] + #endif + internal DSetCheckSum SetCheckSum; + } + + //------------------------------------------------------------------------------ + // This layout must match the (start) of the unmanaged ISymUnmanagedDocumentWriter + // COM object. + //------------------------------------------------------------------------------ + [System.Security.SecurityCritical] + [StructLayout(LayoutKind.Sequential)] + private struct ISymUnmanagedDocumentWriter + { + internal IntPtr m_unmanagedVTable; + } + + //------------------------------------------------------------------------------ + // Stores underlying ISymUnmanagedDocumentWriter* pointer (wrapped in a safehandle.) + //------------------------------------------------------------------------------ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + private PunkSafeHandle m_pDocumentWriterSafeHandle; + + [SecurityCritical] + private ISymUnmanagedDocumentWriter * m_pDocWriter; + + //------------------------------------------------------------------------------ + // Stores the "managed vtable" (actually a structure full of delegates that + // P/Invoke to the corresponding unmanaged COM methods.) + //------------------------------------------------------------------------------ + [SecurityCritical] + private ISymUnmanagedDocumentWriterVTable m_vtable; + + + } // class SymDocumentWriter + + + //------------------------------------------------------------------------------ + // Implements Telesto's version of SymWriter (in the desktop world, + // this type is expored from ISymWrapper.dll.) + //------------------------------------------------------------------------------ + internal unsafe class SymWriter : ISymbolWriter + { + + + //------------------------------------------------------------------------------ + // Creates a SymWriter. The SymWriter is a managed wrapper around the unmanaged + // symbol writer provided by the runtime (ildbsymlib or diasymreader.dll). + //------------------------------------------------------------------------------ + internal static ISymbolWriter CreateSymWriter() + { + return new SymWriter(); + } + + + //------------------------------------------------------------------------------ + // Basic ctor. You'd think this ctor would take the unmanaged symwriter object as an argument + // but to fit in with existing desktop code, the unmanaged writer is passed in + // through a subsequent call to InternalSetUnderlyingWriter + //------------------------------------------------------------------------------ + private SymWriter() + { + } + + //========================================================================================= + // Public interface methods start here. + //========================================================================================= + + + //------------------------------------------------------------------------------ + // Initialize() wrapper + //------------------------------------------------------------------------------ + void ISymbolWriter.Initialize(IntPtr emitter, String filename, bool fFullBuild) + { + int hr = m_vtable.Initialize(m_pWriter, emitter, filename, (IntPtr)0, fFullBuild); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + } + + //------------------------------------------------------------------------------ + // DefineDocument() wrapper + //------------------------------------------------------------------------------ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + ISymbolDocumentWriter ISymbolWriter.DefineDocument(String url, + Guid language, + Guid languageVendor, + Guid documentType) + { + PunkSafeHandle psymUnmanagedDocumentWriter = new PunkSafeHandle(); + + int hr = m_vtable.DefineDocument(m_pWriter, url, ref language, ref languageVendor, ref documentType, out psymUnmanagedDocumentWriter); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + if (psymUnmanagedDocumentWriter.IsInvalid) + { + return null; + } + return new SymDocumentWriter(psymUnmanagedDocumentWriter); + } + + //------------------------------------------------------------------------------ + // SetUserEntryPoint() wrapper + //------------------------------------------------------------------------------ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + void ISymbolWriter.SetUserEntryPoint(SymbolToken entryMethod) + { + int hr = m_vtable.SetUserEntryPoint(m_pWriter, entryMethod.GetToken()); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + } + + //------------------------------------------------------------------------------ + // OpenMethod() wrapper + //------------------------------------------------------------------------------ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + void ISymbolWriter.OpenMethod(SymbolToken method) + { + int hr = m_vtable.OpenMethod(m_pWriter, method.GetToken()); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + } + + //------------------------------------------------------------------------------ + // CloseMethod() wrapper + //------------------------------------------------------------------------------ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + void ISymbolWriter.CloseMethod() + { + int hr = m_vtable.CloseMethod(m_pWriter); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + } + + //------------------------------------------------------------------------------ + // DefineSequencePoints() wrapper + //------------------------------------------------------------------------------ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + void ISymbolWriter.DefineSequencePoints(ISymbolDocumentWriter document, + int[] offsets, + int[] lines, + int[] columns, + int[] endLines, + int[] endColumns) + { + int spCount = 0; + if (offsets != null) + { + spCount = offsets.Length; + } + else if (lines != null) + { + spCount = lines.Length; + } + else if (columns != null) + { + spCount = columns.Length; + } + else if (endLines != null) + { + spCount = endLines.Length; + } + else if (endColumns != null) + { + spCount = endColumns.Length; + } + if (spCount == 0) + { + return; + } + if ( (offsets != null && offsets.Length != spCount) || + (lines != null && lines.Length != spCount) || + (columns != null && columns.Length != spCount) || + (endLines != null && endLines.Length != spCount) || + (endColumns != null && endColumns.Length != spCount) ) + { + throw new ArgumentException(); + } + + // Sure, claim to accept any type that implements ISymbolDocumentWriter but the only one that actually + // works is the one returned by DefineDocument. The desktop ISymWrapper commits the same signature fraud. + // Ideally we'd just return a sealed opaque cookie type, which had an internal accessor to + // get the writer out. + // Regardless, this cast is important for security - we cannot allow our caller to provide + // arbitrary instances of this interface. + SymDocumentWriter docwriter = (SymDocumentWriter)document; + int hr = m_vtable.DefineSequencePoints(m_pWriter, docwriter.GetUnmanaged(), spCount, offsets, lines, columns, endLines, endColumns); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + + } + + //------------------------------------------------------------------------------ + // OpenScope() wrapper + //------------------------------------------------------------------------------ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + int ISymbolWriter.OpenScope(int startOffset) + { + int ret; + int hr = m_vtable.OpenScope(m_pWriter, startOffset, out ret); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + return ret; + } + + //------------------------------------------------------------------------------ + // CloseScope() wrapper + //------------------------------------------------------------------------------ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + void ISymbolWriter.CloseScope(int endOffset) + { + int hr = m_vtable.CloseScope(m_pWriter, endOffset); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + } + + //------------------------------------------------------------------------------ + // SetScopeRange() wrapper + //------------------------------------------------------------------------------ + void ISymbolWriter.SetScopeRange(int scopeID, int startOffset, int endOffset) + { + int hr = m_vtable.SetScopeRange(m_pWriter, scopeID, startOffset, endOffset); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + } + + //------------------------------------------------------------------------------ + // DefineLocalVariable() wrapper + //------------------------------------------------------------------------------ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + void ISymbolWriter.DefineLocalVariable(String name, + FieldAttributes attributes, + byte[] signature, + SymAddressKind addrKind, + int addr1, + int addr2, + int addr3, + int startOffset, + int endOffset) + { + int hr = m_vtable.DefineLocalVariable(m_pWriter, + name, + (int)attributes, + signature.Length, + signature, + (int)addrKind, + addr1, + addr2, + addr3, + startOffset, + endOffset); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + } + + //------------------------------------------------------------------------------ + // DefineParameter() wrapper + //------------------------------------------------------------------------------ + void ISymbolWriter.DefineParameter(String name, + ParameterAttributes attributes, + int sequence, + SymAddressKind addrKind, + int addr1, + int addr2, + int addr3) + { + throw new NotSupportedException(); // Intentionally not supported to match desktop CLR + } + + //------------------------------------------------------------------------------ + // DefineField() wrapper + //------------------------------------------------------------------------------ + void ISymbolWriter.DefineField(SymbolToken parent, + String name, + FieldAttributes attributes, + byte[] signature, + SymAddressKind addrKind, + int addr1, + int addr2, + int addr3) + { + throw new NotSupportedException(); // Intentionally not supported to match desktop CLR + } + + //------------------------------------------------------------------------------ + // DefineGlobalVariable() wrapper + //------------------------------------------------------------------------------ + void ISymbolWriter.DefineGlobalVariable(String name, + FieldAttributes attributes, + byte[] signature, + SymAddressKind addrKind, + int addr1, + int addr2, + int addr3) + { + throw new NotSupportedException(); // Intentionally not supported to match desktop CLR + } + + //------------------------------------------------------------------------------ + // Close() wrapper + //------------------------------------------------------------------------------ + void ISymbolWriter.Close() + { + int hr = m_vtable.Close(m_pWriter); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + } + + //------------------------------------------------------------------------------ + // SetSymAttribute() wrapper + //------------------------------------------------------------------------------ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + void ISymbolWriter.SetSymAttribute(SymbolToken parent, String name, byte[] data) + { + int hr = m_vtable.SetSymAttribute(m_pWriter, parent.GetToken(), name, data.Length, data); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + } + + //------------------------------------------------------------------------------ + // OpenNamespace() wrapper + //------------------------------------------------------------------------------ + void ISymbolWriter.OpenNamespace(String name) + { + int hr = m_vtable.OpenNamespace(m_pWriter, name); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + } + + //------------------------------------------------------------------------------ + // CloseNamespace() wrapper + //------------------------------------------------------------------------------ + void ISymbolWriter.CloseNamespace() + { + int hr = m_vtable.CloseNamespace(m_pWriter); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + } + + //------------------------------------------------------------------------------ + // UsingNamespace() wrapper + //------------------------------------------------------------------------------ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + void ISymbolWriter.UsingNamespace(String name) + { + int hr = m_vtable.UsingNamespace(m_pWriter, name); + if (hr < 0) + { + throw Marshal.GetExceptionForHR(hr); + } + } + + //------------------------------------------------------------------------------ + // SetMethodSourceRange() wrapper + //------------------------------------------------------------------------------ + void ISymbolWriter.SetMethodSourceRange(ISymbolDocumentWriter startDoc, + int startLine, + int startColumn, + ISymbolDocumentWriter endDoc, + int endLine, + int endColumn) + { + throw new NotSupportedException(); // Intentionally not supported to match desktop CLR + } + + //------------------------------------------------------------------------------ + // SetUnderlyingWriter() wrapper. + //------------------------------------------------------------------------------ + void ISymbolWriter.SetUnderlyingWriter(IntPtr ppUnderlyingWriter) + { + throw new NotSupportedException(); // Intentionally not supported on Telesto as it's a very unsafe api + } + + //------------------------------------------------------------------------------ + // InternalSetUnderlyingWriter() wrapper. + // + // Furnishes the native ISymUnmanagedWriter* pointer. + // + // The parameter is actually a pointer to a pointer to an ISymUnmanagedWriter. As + // with the real ISymWrapper.dll, ISymWrapper performs *no* Release (or AddRef) on pointers + // furnished through SetUnderlyingWriter. Lifetime management is entirely up to the caller. + //------------------------------------------------------------------------------ + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal void InternalSetUnderlyingWriter(IntPtr ppUnderlyingWriter) + { + m_pWriter = *((ISymUnmanagedWriter**)ppUnderlyingWriter); + m_vtable = (ISymUnmanagedWriterVTable) (Marshal.PtrToStructure(m_pWriter->m_unmanagedVTable, typeof(ISymUnmanagedWriterVTable))); + } + + //------------------------------------------------------------------------------ + // Define delegates for the unmanaged COM methods we invoke. + //------------------------------------------------------------------------------ + [System.Security.SecurityCritical] + private delegate int DInitialize(ISymUnmanagedWriter* pthis, + IntPtr emitter, //IUnknown* + [MarshalAs(UnmanagedType.LPWStr)] String filename, //WCHAR* + IntPtr pIStream, //IStream* + [MarshalAs(UnmanagedType.Bool)] bool fFullBuild + ); + + [System.Security.SecurityCritical] + private delegate int DDefineDocument(ISymUnmanagedWriter* pthis, + [MarshalAs(UnmanagedType.LPWStr)] String url, + [In] ref Guid language, + [In] ref Guid languageVender, + [In] ref Guid documentType, + [Out] out PunkSafeHandle ppsymUnmanagedDocumentWriter + ); + + [System.Security.SecurityCritical] + private delegate int DSetUserEntryPoint(ISymUnmanagedWriter* pthis, int entryMethod); + [System.Security.SecurityCritical] + private delegate int DOpenMethod(ISymUnmanagedWriter* pthis, int entryMethod); + [System.Security.SecurityCritical] + private delegate int DCloseMethod(ISymUnmanagedWriter* pthis); + + [System.Security.SecurityCritical] + private delegate int DDefineSequencePoints(ISymUnmanagedWriter* pthis, + PunkSafeHandle document, + int spCount, + [In] int[] offsets, + [In] int[] lines, + [In] int[] columns, + [In] int[] endLines, + [In] int[] endColumns); + + [System.Security.SecurityCritical] + private delegate int DOpenScope(ISymUnmanagedWriter* pthis, int startOffset, [Out] out int pretval); + [System.Security.SecurityCritical] + private delegate int DCloseScope(ISymUnmanagedWriter* pthis, int endOffset); + + [System.Security.SecurityCritical] + private delegate int DSetScopeRange(ISymUnmanagedWriter* pthis, int scopeID, int startOffset, int endOffset); + + [System.Security.SecurityCritical] + private delegate int DDefineLocalVariable(ISymUnmanagedWriter* pthis, + [MarshalAs(UnmanagedType.LPWStr)] String name, + int attributes, + int cSig, + [In] byte[] signature, + int addrKind, + int addr1, + int addr2, + int addr3, + int startOffset, + int endOffset + ); + + [System.Security.SecurityCritical] + private delegate int DClose(ISymUnmanagedWriter* pthis); + + [System.Security.SecurityCritical] + private delegate int DSetSymAttribute(ISymUnmanagedWriter* pthis, + int parent, + [MarshalAs(UnmanagedType.LPWStr)] String name, + int cData, + [In] byte[] data + ); + + + [System.Security.SecurityCritical] + private delegate int DOpenNamespace(ISymUnmanagedWriter* pthis, [MarshalAs(UnmanagedType.LPWStr)] String name); + [System.Security.SecurityCritical] + private delegate int DCloseNamespace(ISymUnmanagedWriter* pthis); + [System.Security.SecurityCritical] + private delegate int DUsingNamespace(ISymUnmanagedWriter* pthis, [MarshalAs(UnmanagedType.LPWStr)] String name); + + + + //------------------------------------------------------------------------------ + // This layout must match the unmanaged ISymUnmanagedWriter* COM vtable + // exactly. If a member is declared as an IntPtr rather than a delegate, it means + // we don't call that particular member. + //------------------------------------------------------------------------------ + [StructLayout(LayoutKind.Sequential)] + private struct ISymUnmanagedWriterVTable + { + internal IntPtr QueryInterface; + internal IntPtr AddRef; + internal IntPtr Release; + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal DDefineDocument DefineDocument; + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal DSetUserEntryPoint SetUserEntryPoint; + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal DOpenMethod OpenMethod; + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal DCloseMethod CloseMethod; + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal DOpenScope OpenScope; + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal DCloseScope CloseScope; + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal DSetScopeRange SetScopeRange; + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal DDefineLocalVariable DefineLocalVariable; + internal IntPtr DefineParameter; + internal IntPtr DefineField; + internal IntPtr DefineGlobalVariable; + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal DClose Close; + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal DSetSymAttribute SetSymAttribute; + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal DOpenNamespace OpenNamespace; + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal DCloseNamespace CloseNamespace; + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal DUsingNamespace UsingNamespace; + + internal IntPtr SetMethodSourceRange; + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal DInitialize Initialize; + internal IntPtr GetDebugInfo; + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal DDefineSequencePoints DefineSequencePoints; + + } + + //------------------------------------------------------------------------------ + // This layout must match the (start) of the unmanaged ISymUnmanagedWriter + // COM object. + //------------------------------------------------------------------------------ + [StructLayout(LayoutKind.Sequential)] + private struct ISymUnmanagedWriter + { + internal IntPtr m_unmanagedVTable; + } + + //------------------------------------------------------------------------------ + // Stores native ISymUnmanagedWriter* pointer. + // + // As with the real ISymWrapper.dll, ISymWrapper performs *no* Release (or AddRef) on this pointer. + // Managing lifetime is up to the caller (coreclr.dll). + //------------------------------------------------------------------------------ + [SecurityCritical] + private ISymUnmanagedWriter *m_pWriter; + + //------------------------------------------------------------------------------ + // Stores the "managed vtable" (actually a structure full of delegates that + // P/Invoke to the corresponding unmanaged COM methods.) + //------------------------------------------------------------------------------ + private ISymUnmanagedWriterVTable m_vtable; + + } // class SymWriter + + + + + } //class SymWrapperCore + + + + //-------------------------------------------------------------------------------------- + // SafeHandle for RAW MTA IUnknown's. + // + // ! Because the Release occurs in the finalizer thread, this safehandle really takes + // ! an ostrich approach to apartment issues. We only tolerate this here because we're emulating + // ! the desktop CLR's use of ISymWrapper which also pays lip service to COM apartment rules. + // ! + // ! However, think twice about pulling this safehandle out for other uses. + // + // Had to make this a non-nested class since FCall's don't like to bind to nested classes. + //-------------------------------------------------------------------------------------- + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + sealed class PunkSafeHandle : SafeHandle + { + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal PunkSafeHandle() + : base((IntPtr)0, true) + { + } + + [SecurityCritical] + override protected bool ReleaseHandle() + { + m_Release(handle); + return true; + } + + public override bool IsInvalid + { + [SecurityCritical] + get { return handle == ((IntPtr)0); } + } + + private delegate void DRelease(IntPtr punk); // Delegate type for P/Invoking to coreclr.dll and doing an IUnknown::Release() + private static DRelease m_Release; + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern IntPtr nGetDReleaseTarget(); // FCall gets us the native DRelease target (so we don't need named dllexport from coreclr.dll) + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + static PunkSafeHandle() + { + m_Release = (DRelease)(Marshal.GetDelegateForFunctionPointer(nGetDReleaseTarget(), typeof(DRelease))); + m_Release((IntPtr)0); // make one call to make sure the delegate is fully prepped before we're in the critical finalizer situation. + } + + } // PunkSafeHandle + +} //namespace System.Reflection.Emit + + +#endif //FEATURE_CORECLR + diff --git a/src/mscorlib/src/System/Reflection/Emit/Label.cs b/src/mscorlib/src/System/Reflection/Emit/Label.cs new file mode 100644 index 0000000000..dd248b62fe --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/Label.cs @@ -0,0 +1,74 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** +** Purpose: Represents a Label to the ILGenerator class. +** +** +===========================================================*/ +namespace System.Reflection.Emit { + using System; + using System.Reflection; + using System.Security.Permissions; + using System.Runtime.InteropServices; + + // The Label class is an opaque representation of a label used by the + // ILGenerator class. The token is used to mark where labels occur in the IL + // stream and then the necessary offsets are put back in the code when the ILGenerator + // is passed to the MethodWriter. + // Labels are created by using ILGenerator.CreateLabel and their position is set + // by using ILGenerator.MarkLabel. + [Serializable] + [ComVisible(true)] + public struct Label { + + internal int m_label; + + //public Label() { + // m_label=0; + //} + + internal Label (int label) { + m_label=label; + } + + internal int GetLabelValue() { + return m_label; + } + + public override int GetHashCode() + { + return m_label; + } + + public override bool Equals(Object obj) + { + if (obj is Label) + return Equals((Label)obj); + else + return false; + } + + public bool Equals(Label obj) + { + return obj.m_label == m_label; + } + + public static bool operator ==(Label a, Label b) + { + return a.Equals(b); + } + + public static bool operator !=(Label a, Label b) + { + return !(a == b); + } + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/LocalBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/LocalBuilder.cs new file mode 100644 index 0000000000..4008703ca7 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/LocalBuilder.cs @@ -0,0 +1,151 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Reflection; +using System.Security.Permissions; +using System.Runtime.InteropServices; + +namespace System.Reflection.Emit +{ + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_LocalBuilder))] + [System.Runtime.InteropServices.ComVisible(true)] + public sealed class LocalBuilder : LocalVariableInfo, _LocalBuilder + { + #region Private Data Members + private int m_localIndex; + private Type m_localType; + private MethodInfo m_methodBuilder; + private bool m_isPinned; + #endregion + + #region Constructor + private LocalBuilder() { } + internal LocalBuilder(int localIndex, Type localType, MethodInfo methodBuilder) + : this(localIndex, localType, methodBuilder, false) { } + internal LocalBuilder(int localIndex, Type localType, MethodInfo methodBuilder, bool isPinned) + { + m_isPinned = isPinned; + m_localIndex = localIndex; + m_localType = localType; + m_methodBuilder = methodBuilder; + } + #endregion + + #region Internal Members + internal int GetLocalIndex() + { + return m_localIndex; + } + internal MethodInfo GetMethodBuilder() + { + return m_methodBuilder; + } + #endregion + + #region LocalVariableInfo Override + public override bool IsPinned { get { return m_isPinned; } } + public override Type LocalType + { + get + { + return m_localType; + } + } + public override int LocalIndex { get { return m_localIndex; } } + #endregion + + #region Public Members + public void SetLocalSymInfo(String name) + { + SetLocalSymInfo(name, 0, 0); + } + + public void SetLocalSymInfo(String name, int startOffset, int endOffset) + { + ModuleBuilder dynMod; + SignatureHelper sigHelp; + int sigLength; + byte[] signature; + byte[] mungedSig; + int index; + + MethodBuilder methodBuilder = m_methodBuilder as MethodBuilder; + if (methodBuilder == null) + // it's a light code gen entity + throw new NotSupportedException(); + dynMod = (ModuleBuilder) methodBuilder.Module; + if (methodBuilder.IsTypeCreated()) + { + // cannot change method after its containing type has been created + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TypeHasBeenCreated")); + } + + // set the name and range of offset for the local + if (dynMod.GetSymWriter() == null) + { + // cannot set local name if not debug module + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule")); + } + + sigHelp = SignatureHelper.GetFieldSigHelper(dynMod); + sigHelp.AddArgument(m_localType); + signature = sigHelp.InternalGetSignature(out sigLength); + + // The symbol store doesn't want the calling convention on the + // front of the signature, but InternalGetSignature returns + // the callinging convention. So we strip it off. This is a + // bit unfortunate, since it means that we need to allocate + // yet another array of bytes... + mungedSig = new byte[sigLength - 1]; + Buffer.BlockCopy(signature, 1, mungedSig, 0, sigLength - 1); + + index = methodBuilder.GetILGenerator().m_ScopeTree.GetCurrentActiveScopeIndex(); + if (index == -1) + { + // top level scope information is kept with methodBuilder + methodBuilder.m_localSymInfo.AddLocalSymInfo( + name, + mungedSig, + m_localIndex, + startOffset, + endOffset); + } + else + { + methodBuilder.GetILGenerator().m_ScopeTree.AddLocalSymInfoToCurrentScope( + name, + mungedSig, + m_localIndex, + startOffset, + endOffset); + } + } + #endregion + +#if !FEATURE_CORECLR + void _LocalBuilder.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _LocalBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _LocalBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _LocalBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + } +} + diff --git a/src/mscorlib/src/System/Reflection/Emit/MethodBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/MethodBuilder.cs new file mode 100644 index 0000000000..015a73be09 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/MethodBuilder.cs @@ -0,0 +1,1610 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection.Emit +{ + using System.Text; + using System; + using CultureInfo = System.Globalization.CultureInfo; + using System.Diagnostics.SymbolStore; + using System.Reflection; + using System.Security; + using System.Collections; + using System.Collections.Generic; + using System.Security.Permissions; + using System.Runtime.InteropServices; + using System.Diagnostics.Contracts; + + [HostProtection(MayLeakOnAbort = true)] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_MethodBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class MethodBuilder : MethodInfo, _MethodBuilder + { + #region Private Data Members + // Identity + internal String m_strName; // The name of the method + private MethodToken m_tkMethod; // The token of this method + private ModuleBuilder m_module; + internal TypeBuilder m_containingType; + + // IL + private int[] m_mdMethodFixups; // The location of all of the token fixups. Null means no fixups. + private byte[] m_localSignature; // Local signature if set explicitly via DefineBody. Null otherwise. + internal LocalSymInfo m_localSymInfo; // keep track debugging local information + internal ILGenerator m_ilGenerator; // Null if not used. + private byte[] m_ubBody; // The IL for the method + private ExceptionHandler[] m_exceptions; // Exception handlers or null if there are none. + private const int DefaultMaxStack = 16; + private int m_maxStack = DefaultMaxStack; + + // Flags + internal bool m_bIsBaked; + private bool m_bIsGlobalMethod; + private bool m_fInitLocals; // indicating if the method stack frame will be zero initialized or not. + + // Attributes + private MethodAttributes m_iAttributes; + private CallingConventions m_callingConvention; + private MethodImplAttributes m_dwMethodImplFlags; + + // Parameters + private SignatureHelper m_signature; + internal Type[] m_parameterTypes; + private ParameterBuilder m_retParam; + private Type m_returnType; + private Type[] m_returnTypeRequiredCustomModifiers; + private Type[] m_returnTypeOptionalCustomModifiers; + private Type[][] m_parameterTypeRequiredCustomModifiers; + private Type[][] m_parameterTypeOptionalCustomModifiers; + + // Generics + private GenericTypeParameterBuilder[] m_inst; + private bool m_bIsGenMethDef; + #endregion + + #region Constructor + internal MethodBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention, + Type returnType, Type[] parameterTypes, ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod) + { + Init(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null, mod, type, bIsGlobalMethod); + } + + internal MethodBuilder(String name, MethodAttributes attributes, CallingConventions callingConvention, + Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, + Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers, + ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod) + { + Init(name, attributes, callingConvention, + returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, + parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, + mod, type, bIsGlobalMethod); + } + + private void Init(String name, MethodAttributes attributes, CallingConventions callingConvention, + Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, + Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers, + ModuleBuilder mod, TypeBuilder type, bool bIsGlobalMethod) + { + if (name == null) + throw new ArgumentNullException("name"); + + if (name.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + + if (name[0] == '\0') + throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), "name"); + + if (mod == null) + throw new ArgumentNullException("mod"); + Contract.EndContractBlock(); + + if (parameterTypes != null) + { + foreach(Type t in parameterTypes) + { + if (t == null) + throw new ArgumentNullException("parameterTypes"); + } + } + + m_strName = name; + m_module = mod; + m_containingType = type; + + // + //if (returnType == null) + //{ + // m_returnType = typeof(void); + //} + //else + { + m_returnType = returnType; + } + + if ((attributes & MethodAttributes.Static) == 0) + { + // turn on the has this calling convention + callingConvention = callingConvention | CallingConventions.HasThis; + } + else if ((attributes & MethodAttributes.Virtual) != 0) + { + // A method can't be both static and virtual + throw new ArgumentException(Environment.GetResourceString("Arg_NoStaticVirtual")); + } + + if ((attributes & MethodAttributes.SpecialName) != MethodAttributes.SpecialName) + { + if ((type.Attributes & TypeAttributes.Interface) == TypeAttributes.Interface) + { + // methods on interface have to be abstract + virtual except special name methods such as type initializer + if ((attributes & (MethodAttributes.Abstract | MethodAttributes.Virtual)) != + (MethodAttributes.Abstract | MethodAttributes.Virtual) && + (attributes & MethodAttributes.Static) == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_BadAttributeOnInterfaceMethod")); + } + } + + m_callingConvention = callingConvention; + + if (parameterTypes != null) + { + m_parameterTypes = new Type[parameterTypes.Length]; + Array.Copy(parameterTypes, 0, m_parameterTypes, 0, parameterTypes.Length); + } + else + { + m_parameterTypes = null; + } + + m_returnTypeRequiredCustomModifiers = returnTypeRequiredCustomModifiers; + m_returnTypeOptionalCustomModifiers = returnTypeOptionalCustomModifiers; + m_parameterTypeRequiredCustomModifiers = parameterTypeRequiredCustomModifiers; + m_parameterTypeOptionalCustomModifiers = parameterTypeOptionalCustomModifiers; + +// m_signature = SignatureHelper.GetMethodSigHelper(mod, callingConvention, +// returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, +// parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers); + + m_iAttributes = attributes; + m_bIsGlobalMethod = bIsGlobalMethod; + m_bIsBaked = false; + m_fInitLocals = true; + + m_localSymInfo = new LocalSymInfo(); + m_ubBody = null; + m_ilGenerator = null; + + // Default is managed IL. Manged IL has bit flag 0x0020 set off + m_dwMethodImplFlags = MethodImplAttributes.IL; + } + + #endregion + + #region Internal Members + + internal void CheckContext(params Type[][] typess) + { + m_module.CheckContext(typess); + } + + internal void CheckContext(params Type[] types) + { + m_module.CheckContext(types); + } + + [System.Security.SecurityCritical] // auto-generated + internal void CreateMethodBodyHelper(ILGenerator il) + { + // Sets the IL of the method. An ILGenerator is passed as an argument and the method + // queries this instance to get all of the information which it needs. + if (il == null) + { + throw new ArgumentNullException("il"); + } + Contract.EndContractBlock(); + + __ExceptionInfo[] excp; + int counter=0; + int[] filterAddrs; + int[] catchAddrs; + int[] catchEndAddrs; + Type[] catchClass; + int[] type; + int numCatch; + int start, end; + ModuleBuilder dynMod = (ModuleBuilder) m_module; + + m_containingType.ThrowIfCreated(); + + if (m_bIsBaked) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodHasBody")); + } + + if (il.m_methodBuilder != this && il.m_methodBuilder != null) + { + // you don't need to call DefineBody when you get your ILGenerator + // through MethodBuilder::GetILGenerator. + // + + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadILGeneratorUsage")); + } + + ThrowIfShouldNotHaveBody(); + + if (il.m_ScopeTree.m_iOpenScopeCount != 0) + { + // There are still unclosed local scope + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_OpenLocalVariableScope")); + } + + + m_ubBody = il.BakeByteArray(); + + m_mdMethodFixups = il.GetTokenFixups(); + + //Okay, now the fun part. Calculate all of the exceptions. + excp = il.GetExceptions(); + int numExceptions = CalculateNumberOfExceptions(excp); + if (numExceptions > 0) + { + m_exceptions = new ExceptionHandler[numExceptions]; + + for (int i = 0; i < excp.Length; i++) + { + filterAddrs = excp[i].GetFilterAddresses(); + catchAddrs = excp[i].GetCatchAddresses(); + catchEndAddrs = excp[i].GetCatchEndAddresses(); + catchClass = excp[i].GetCatchClass(); + + numCatch = excp[i].GetNumberOfCatches(); + start = excp[i].GetStartAddress(); + end = excp[i].GetEndAddress(); + type = excp[i].GetExceptionTypes(); + for (int j = 0; j < numCatch; j++) + { + int tkExceptionClass = 0; + if (catchClass[j] != null) + { + tkExceptionClass = dynMod.GetTypeTokenInternal(catchClass[j]).Token; + } + + switch (type[j]) + { + case __ExceptionInfo.None: + case __ExceptionInfo.Fault: + case __ExceptionInfo.Filter: + m_exceptions[counter++] = new ExceptionHandler(start, end, filterAddrs[j], catchAddrs[j], catchEndAddrs[j], type[j], tkExceptionClass); + break; + + case __ExceptionInfo.Finally: + m_exceptions[counter++] = new ExceptionHandler(start, excp[i].GetFinallyEndAddress(), filterAddrs[j], catchAddrs[j], catchEndAddrs[j], type[j], tkExceptionClass); + break; + } + } + + } + } + + + m_bIsBaked=true; + + if (dynMod.GetSymWriter() != null) + { + + // set the debugging information such as scope and line number + // if it is in a debug module + // + SymbolToken tk = new SymbolToken(MetadataTokenInternal); + ISymbolWriter symWriter = dynMod.GetSymWriter(); + + // call OpenMethod to make this method the current method + symWriter.OpenMethod(tk); + + // call OpenScope because OpenMethod no longer implicitly creating + // the top-levelsmethod scope + // + symWriter.OpenScope(0); + + if (m_symCustomAttrs != null) + { + foreach(SymCustomAttr symCustomAttr in m_symCustomAttrs) + dynMod.GetSymWriter().SetSymAttribute( + new SymbolToken (MetadataTokenInternal), + symCustomAttr.m_name, + symCustomAttr.m_data); + } + + if (m_localSymInfo != null) + m_localSymInfo.EmitLocalSymInfo(symWriter); + il.m_ScopeTree.EmitScopeTree(symWriter); + il.m_LineNumberInfo.EmitLineNumberInfo(symWriter); + symWriter.CloseScope(il.ILOffset); + symWriter.CloseMethod(); + } + } + + // This is only called from TypeBuilder.CreateType after the method has been created + internal void ReleaseBakedStructures() + { + if (!m_bIsBaked) + { + // We don't need to do anything here if we didn't baked the method body + return; + } + + m_ubBody = null; + m_localSymInfo = null; + m_mdMethodFixups = null; + m_localSignature = null; + m_exceptions = null; + } + + internal override Type[] GetParameterTypes() + { + if (m_parameterTypes == null) + m_parameterTypes = EmptyArray.Value; + + return m_parameterTypes; + } + + internal static Type GetMethodBaseReturnType(MethodBase method) + { + MethodInfo mi = null; + ConstructorInfo ci = null; + + if ( (mi = method as MethodInfo) != null ) + { + return mi.ReturnType; + } + else if ( (ci = method as ConstructorInfo) != null) + { + return ci.GetReturnType(); + } + else + { + Contract.Assert(false, "We should never get here!"); + return null; + } + } + + internal void SetToken(MethodToken token) + { + m_tkMethod = token; + } + + internal byte[] GetBody() + { + // Returns the il bytes of this method. + // This il is not valid until somebody has called BakeByteArray + return m_ubBody; + } + + internal int[] GetTokenFixups() + { + return m_mdMethodFixups; + } + + [System.Security.SecurityCritical] // auto-generated + internal SignatureHelper GetMethodSignature() + { + if (m_parameterTypes == null) + m_parameterTypes = EmptyArray.Value; + + m_signature = SignatureHelper.GetMethodSigHelper (m_module, m_callingConvention, m_inst != null ? m_inst.Length : 0, + m_returnType == null ? typeof(void) : m_returnType, m_returnTypeRequiredCustomModifiers, m_returnTypeOptionalCustomModifiers, + m_parameterTypes, m_parameterTypeRequiredCustomModifiers, m_parameterTypeOptionalCustomModifiers); + + return m_signature; + } + + // Returns a buffer whose initial signatureLength bytes contain encoded local signature. + internal byte[] GetLocalSignature(out int signatureLength) + { + if (m_localSignature != null) + { + signatureLength = m_localSignature.Length; + return m_localSignature; + } + + if (m_ilGenerator != null) + { + if (m_ilGenerator.m_localCount != 0) + { + // If user is using ILGenerator::DeclareLocal, then get local signaturefrom there. + return m_ilGenerator.m_localSignature.InternalGetSignature(out signatureLength); + } + } + + return SignatureHelper.GetLocalVarSigHelper(m_module).InternalGetSignature(out signatureLength); + } + + internal int GetMaxStack() + { + if (m_ilGenerator != null) + { + return m_ilGenerator.GetMaxStackSize() + ExceptionHandlerCount; + } + else + { + // this is the case when client provide an array of IL byte stream rather than going through ILGenerator. + return m_maxStack; + } + } + + internal ExceptionHandler[] GetExceptionHandlers() + { + return m_exceptions; + } + + internal int ExceptionHandlerCount + { + get { return m_exceptions != null ? m_exceptions.Length : 0; } + } + + internal int CalculateNumberOfExceptions(__ExceptionInfo[] excp) + { + int num=0; + + if (excp==null) + { + return 0; + } + + for (int i=0; i 0 && (m_parameterTypes == null || position > m_parameterTypes.Length)) + throw new ArgumentOutOfRangeException(Environment.GetResourceString("ArgumentOutOfRange_ParamSequence")); + + attributes = attributes & ~ParameterAttributes.ReservedMask; + return new ParameterBuilder(this, position, attributes, strParamName); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [Obsolete("An alternate API is available: Emit the MarshalAs custom attribute instead. http://go.microsoft.com/fwlink/?linkid=14202")] + public void SetMarshal(UnmanagedMarshal unmanagedMarshal) + { + ThrowIfGeneric (); + + // set Marshal info for the return type + + m_containingType.ThrowIfCreated(); + + if (m_retParam == null) + { + m_retParam = new ParameterBuilder(this, 0, 0, null); + } + + m_retParam.SetMarshal(unmanagedMarshal); + } + + private List m_symCustomAttrs; + private struct SymCustomAttr + { + public SymCustomAttr(String name, byte[] data) + { + m_name = name; + m_data = data; + } + public String m_name; + public byte[] m_data; + } + + public void SetSymCustomAttribute(String name, byte[] data) + { + // Note that this API is rarely used. Support for custom attributes in PDB files was added in + // Whidbey and as of 8/2007 the only known user is the C# compiler. There seems to be little + // value to this for Reflection.Emit users since they can always use metadata custom attributes. + // Some versions of the symbol writer used in the CLR will ignore these entirely. This API has + // been removed from the Silverlight API surface area, but we should also consider removing it + // from future desktop product versions as well. + + ThrowIfGeneric (); + + // This is different from CustomAttribute. This is stored into the SymWriter. + m_containingType.ThrowIfCreated(); + + ModuleBuilder dynMod = (ModuleBuilder) m_module; + if ( dynMod.GetSymWriter() == null) + { + // Cannot SetSymCustomAttribute when it is not a debug module + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule")); + } + + if (m_symCustomAttrs == null) + m_symCustomAttrs = new List(); + + m_symCustomAttrs.Add(new SymCustomAttr(name, data)); + } + +#if FEATURE_CAS_POLICY + [System.Security.SecuritySafeCritical] // auto-generated + public void AddDeclarativeSecurity(SecurityAction action, PermissionSet pset) + { + if (pset == null) + throw new ArgumentNullException("pset"); + Contract.EndContractBlock(); + + ThrowIfGeneric (); + +#pragma warning disable 618 + if (!Enum.IsDefined(typeof(SecurityAction), action) || + action == SecurityAction.RequestMinimum || + action == SecurityAction.RequestOptional || + action == SecurityAction.RequestRefuse) + { + throw new ArgumentOutOfRangeException("action"); + } +#pragma warning restore 618 + + // cannot declarative security after type is created + m_containingType.ThrowIfCreated(); + + // Translate permission set into serialized format (uses standard binary serialization format). + byte[] blob = null; + int length = 0; + if (!pset.IsEmpty()) + { + blob = pset.EncodeXml(); + length = blob.Length; + } + + // Write the blob into the metadata. + TypeBuilder.AddDeclarativeSecurity(m_module.GetNativeHandle(), MetadataTokenInternal, action, blob, length); + } +#endif // FEATURE_CAS_POLICY + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + public void SetMethodBody(byte[] il, int maxStack, byte[] localSignature, IEnumerable exceptionHandlers, IEnumerable tokenFixups) + { + if (il == null) + { + throw new ArgumentNullException("il", Environment.GetResourceString("ArgumentNull_Array")); + } + if (maxStack < 0) + { + throw new ArgumentOutOfRangeException("maxStack", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + } + Contract.EndContractBlock(); + + if (m_bIsBaked) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodBaked")); + } + + m_containingType.ThrowIfCreated(); + ThrowIfGeneric(); + + byte[] newLocalSignature = null; + ExceptionHandler[] newHandlers = null; + int[] newTokenFixups = null; + + byte[] newIL = (byte[])il.Clone(); + + if (localSignature != null) + { + newLocalSignature = (byte[])localSignature.Clone(); + } + + if (exceptionHandlers != null) + { + newHandlers = ToArray(exceptionHandlers); + CheckExceptionHandlerRanges(newHandlers, newIL.Length); + + // Note: Fixup entries for type tokens stored in ExceptionHandlers are added by the method body emitter. + } + + if (tokenFixups != null) + { + newTokenFixups = ToArray(tokenFixups); + int maxTokenOffset = newIL.Length - 4; + + for (int i = 0; i < newTokenFixups.Length; i++) + { + // Check that fixups are within the range of this method's IL, otherwise some random memory might get "fixed up". + if (newTokenFixups[i] < 0 || newTokenFixups[i] > maxTokenOffset) + { + throw new ArgumentOutOfRangeException("tokenFixups[" + i + "]", Environment.GetResourceString("ArgumentOutOfRange_Range", 0, maxTokenOffset)); + } + } + } + + m_ubBody = newIL; + m_localSignature = newLocalSignature; + m_exceptions = newHandlers; + m_mdMethodFixups = newTokenFixups; + m_maxStack = maxStack; + + // discard IL generator, all information stored in it is now irrelevant + m_ilGenerator = null; + m_bIsBaked = true; + } + + private static T[] ToArray(IEnumerable sequence) + { + T[] array = sequence as T[]; + if (array != null) + { + return (T[])array.Clone(); + } + + return new List(sequence).ToArray(); + } + + private static void CheckExceptionHandlerRanges(ExceptionHandler[] exceptionHandlers, int maxOffset) + { + // Basic checks that the handler ranges are within the method body (ranges are end-exclusive). + // Doesn't verify that the ranges are otherwise correct - it is very well possible to emit invalid IL. + for (int i = 0; i < exceptionHandlers.Length; i++) + { + var handler = exceptionHandlers[i]; + if (handler.m_filterOffset > maxOffset || handler.m_tryEndOffset > maxOffset || handler.m_handlerEndOffset > maxOffset) + { + throw new ArgumentOutOfRangeException("exceptionHandlers[" + i + "]", Environment.GetResourceString("ArgumentOutOfRange_Range", 0, maxOffset)); + } + + // Type token might be 0 if the ExceptionHandler was created via a default constructor. + // Other tokens migth also be invalid. We only check nil tokens as the implementation (SectEH_Emit in corhlpr.cpp) requires it, + // and we can't check for valid tokens until the module is baked. + if (handler.Kind == ExceptionHandlingClauseOptions.Clause && handler.ExceptionTypeToken == 0) + { + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeToken", handler.ExceptionTypeToken), "exceptionHandlers[" + i + "]"); + } + } + } + + /// + /// Obsolete. + /// + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + public void CreateMethodBody(byte[] il, int count) + { + ThrowIfGeneric(); + + // Note that when user calls this function, there are a few information that client is + // not able to supply: local signature, exception handlers, max stack size, a list of Token fixup, a list of RVA fixup + + if (m_bIsBaked) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_MethodBaked")); + } + + m_containingType.ThrowIfCreated(); + + if (il != null && (count < 0 || count > il.Length)) + { + throw new ArgumentOutOfRangeException("count", Environment.GetResourceString("ArgumentOutOfRange_Index")); + } + + if (il == null) + { + m_ubBody = null; + return; + } + + m_ubBody = new byte[count]; + Buffer.BlockCopy(il, 0, m_ubBody, 0, count); + + m_localSignature = null; + m_exceptions = null; + m_mdMethodFixups = null; + m_maxStack = DefaultMaxStack; + + m_bIsBaked = true; + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void SetImplementationFlags(MethodImplAttributes attributes) + { + ThrowIfGeneric (); + + m_containingType.ThrowIfCreated (); + + m_dwMethodImplFlags = attributes; + + m_canBeRuntimeImpl = true; + + TypeBuilder.SetMethodImpl(m_module.GetNativeHandle(), MetadataTokenInternal, attributes); + } + + public ILGenerator GetILGenerator() { + Contract.Ensures(Contract.Result() != null); + + ThrowIfGeneric(); + ThrowIfShouldNotHaveBody(); + + if (m_ilGenerator == null) + m_ilGenerator = new ILGenerator(this); + return m_ilGenerator; + } + + public ILGenerator GetILGenerator(int size) { + Contract.Ensures(Contract.Result() != null); + + ThrowIfGeneric (); + ThrowIfShouldNotHaveBody(); + + if (m_ilGenerator == null) + m_ilGenerator = new ILGenerator(this, size); + return m_ilGenerator; + } + + private void ThrowIfShouldNotHaveBody() { + if ((m_dwMethodImplFlags & MethodImplAttributes.CodeTypeMask) != MethodImplAttributes.IL || + (m_dwMethodImplFlags & MethodImplAttributes.Unmanaged) != 0 || + (m_iAttributes & MethodAttributes.PinvokeImpl) != 0 || + m_isDllImport) + { + // cannot attach method body if methodimpl is marked not marked as managed IL + // + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ShouldNotHaveMethodBody")); + } + } + + + public bool InitLocals + { + // Property is set to true if user wishes to have zero initialized stack frame for this method. Default to false. + get { ThrowIfGeneric (); return m_fInitLocals; } + set { ThrowIfGeneric (); m_fInitLocals = value; } + } + + public Module GetModule() + { + return GetModuleBuilder(); + } + + public String Signature + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + return GetMethodSignature().ToString(); + } + } + + +#if FEATURE_CORECLR +[System.Security.SecurityCritical] // auto-generated +#else +[System.Security.SecuritySafeCritical] +#endif +[System.Runtime.InteropServices.ComVisible(true)] + public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + { + if (con == null) + throw new ArgumentNullException("con"); + if (binaryAttribute == null) + throw new ArgumentNullException("binaryAttribute"); + Contract.EndContractBlock(); + + ThrowIfGeneric(); + + TypeBuilder.DefineCustomAttribute(m_module, MetadataTokenInternal, + ((ModuleBuilder)m_module).GetConstructorToken(con).Token, + binaryAttribute, + false, false); + + if (IsKnownCA(con)) + ParseCA(con, binaryAttribute); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void SetCustomAttribute(CustomAttributeBuilder customBuilder) + { + if (customBuilder == null) + throw new ArgumentNullException("customBuilder"); + Contract.EndContractBlock(); + + ThrowIfGeneric(); + + customBuilder.CreateCustomAttribute((ModuleBuilder)m_module, MetadataTokenInternal); + + if (IsKnownCA(customBuilder.m_con)) + ParseCA(customBuilder.m_con, customBuilder.m_blob); + } + + // this method should return true for any and every ca that requires more work + // than just setting the ca + private bool IsKnownCA(ConstructorInfo con) + { + Type caType = con.DeclaringType; + if (caType == typeof(System.Runtime.CompilerServices.MethodImplAttribute)) return true; + else if (caType == typeof(DllImportAttribute)) return true; + else return false; + } + + private void ParseCA(ConstructorInfo con, byte[] blob) + { + Type caType = con.DeclaringType; + if (caType == typeof(System.Runtime.CompilerServices.MethodImplAttribute)) + { + // dig through the blob looking for the MethodImplAttributes flag + // that must be in the MethodCodeType field + + // for now we simply set a flag that relaxes the check when saving and + // allows this method to have no body when any kind of MethodImplAttribute is present + m_canBeRuntimeImpl = true; + } + else if (caType == typeof(DllImportAttribute)) { + m_canBeRuntimeImpl = true; + m_isDllImport = true; + } + + } + + internal bool m_canBeRuntimeImpl = false; + internal bool m_isDllImport = false; + + #endregion + +#if !FEATURE_CORECLR + void _MethodBuilder.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _MethodBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _MethodBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _MethodBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + + } + + internal class LocalSymInfo + { + // This class tracks the local variable's debugging information + // and namespace information with a given active lexical scope. + + #region Internal Data Members + internal String[] m_strName; + internal byte[][] m_ubSignature; + internal int[] m_iLocalSlot; + internal int[] m_iStartOffset; + internal int[] m_iEndOffset; + internal int m_iLocalSymCount; // how many entries in the arrays are occupied + internal String[] m_namespace; + internal int m_iNameSpaceCount; + internal const int InitialSize = 16; + #endregion + + #region Constructor + internal LocalSymInfo() + { + // initialize data variables + m_iLocalSymCount = 0; + m_iNameSpaceCount = 0; + } + #endregion + + #region Private Members + private void EnsureCapacityNamespace() + { + if (m_iNameSpaceCount == 0) + { + m_namespace = new String[InitialSize]; + } + else if (m_iNameSpaceCount == m_namespace.Length) + { + String [] strTemp = new String [checked(m_iNameSpaceCount * 2)]; + Array.Copy(m_namespace, 0, strTemp, 0, m_iNameSpaceCount); + m_namespace = strTemp; + } + } + + private void EnsureCapacity() + { + if (m_iLocalSymCount == 0) + { + // First time. Allocate the arrays. + m_strName = new String[InitialSize]; + m_ubSignature = new byte[InitialSize][]; + m_iLocalSlot = new int[InitialSize]; + m_iStartOffset = new int[InitialSize]; + m_iEndOffset = new int[InitialSize]; + } + else if (m_iLocalSymCount == m_strName.Length) + { + // the arrays are full. Enlarge the arrays + // why aren't we just using lists here? + int newSize = checked(m_iLocalSymCount * 2); + int[] temp = new int [newSize]; + Array.Copy(m_iLocalSlot, 0, temp, 0, m_iLocalSymCount); + m_iLocalSlot = temp; + + temp = new int [newSize]; + Array.Copy(m_iStartOffset, 0, temp, 0, m_iLocalSymCount); + m_iStartOffset = temp; + + temp = new int [newSize]; + Array.Copy(m_iEndOffset, 0, temp, 0, m_iLocalSymCount); + m_iEndOffset = temp; + + String [] strTemp = new String [newSize]; + Array.Copy(m_strName, 0, strTemp, 0, m_iLocalSymCount); + m_strName = strTemp; + + byte[][] ubTemp = new byte[newSize][]; + Array.Copy(m_ubSignature, 0, ubTemp, 0, m_iLocalSymCount); + m_ubSignature = ubTemp; + + } + } + + #endregion + + #region Internal Members + internal void AddLocalSymInfo(String strName,byte[] signature,int slot,int startOffset,int endOffset) + { + // make sure that arrays are large enough to hold addition info + EnsureCapacity(); + m_iStartOffset[m_iLocalSymCount] = startOffset; + m_iEndOffset[m_iLocalSymCount] = endOffset; + m_iLocalSlot[m_iLocalSymCount] = slot; + m_strName[m_iLocalSymCount] = strName; + m_ubSignature[m_iLocalSymCount] = signature; + checked {m_iLocalSymCount++; } + } + + internal void AddUsingNamespace(String strNamespace) + { + EnsureCapacityNamespace(); + m_namespace[m_iNameSpaceCount] = strNamespace; + checked { m_iNameSpaceCount++; } + } + + #if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated + #endif + internal virtual void EmitLocalSymInfo(ISymbolWriter symWriter) + { + int i; + + for (i = 0; i < m_iLocalSymCount; i ++) + { + symWriter.DefineLocalVariable( + m_strName[i], + FieldAttributes.PrivateScope, + m_ubSignature[i], + SymAddressKind.ILOffset, + m_iLocalSlot[i], + 0, // addr2 is not used yet + 0, // addr3 is not used + m_iStartOffset[i], + m_iEndOffset[i]); + } + for (i = 0; i < m_iNameSpaceCount; i ++) + { + symWriter.UsingNamespace(m_namespace[i]); + } + } + + #endregion + } + + /// + /// Describes exception handler in a method body. + /// + [StructLayout(LayoutKind.Sequential)] + [ComVisible(false)] + public struct ExceptionHandler : IEquatable + { + // Keep in sync with unmanged structure. + internal readonly int m_exceptionClass; + internal readonly int m_tryStartOffset; + internal readonly int m_tryEndOffset; + internal readonly int m_filterOffset; + internal readonly int m_handlerStartOffset; + internal readonly int m_handlerEndOffset; + internal readonly ExceptionHandlingClauseOptions m_kind; + + public int ExceptionTypeToken + { + get { return m_exceptionClass; } + } + + public int TryOffset + { + get { return m_tryStartOffset; } + } + + public int TryLength + { + get { return m_tryEndOffset - m_tryStartOffset; } + } + + public int FilterOffset + { + get { return m_filterOffset; } + } + + public int HandlerOffset + { + get { return m_handlerStartOffset; } + } + + public int HandlerLength + { + get { return m_handlerEndOffset - m_handlerStartOffset; } + } + + public ExceptionHandlingClauseOptions Kind + { + get { return m_kind; } + } + + #region Constructors + + /// + /// Creates a description of an exception handler. + /// + /// The offset of the first instruction protected by this handler. + /// The number of bytes protected by this handler. + /// The filter code begins at the specified offset and ends at the first instruction of the handler block. Specify 0 if not applicable (this is not a filter handler). + /// The offset of the first instruction of this handler. + /// The number of bytes of the handler. + /// The kind of handler, the handler might be a catch handler, filter handler, fault handler, or finally handler. + /// The token of the exception type handled by this handler. Specify 0 if not applicable (this is finally handler). + /// + /// Some of the instruction offset is negative, + /// the end offset of specified range is less than its start offset, + /// or has an invalid value. + /// + public ExceptionHandler(int tryOffset, int tryLength, int filterOffset, int handlerOffset, int handlerLength, + ExceptionHandlingClauseOptions kind, int exceptionTypeToken) + { + if (tryOffset < 0) + { + throw new ArgumentOutOfRangeException("tryOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + } + + if (tryLength < 0) + { + throw new ArgumentOutOfRangeException("tryLength", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + } + + if (filterOffset < 0) + { + throw new ArgumentOutOfRangeException("filterOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + } + + if (handlerOffset < 0) + { + throw new ArgumentOutOfRangeException("handlerOffset", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + } + + if (handlerLength < 0) + { + throw new ArgumentOutOfRangeException("handlerLength", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); + } + + if ((long)tryOffset + tryLength > Int32.MaxValue) + { + throw new ArgumentOutOfRangeException("tryLength", Environment.GetResourceString("ArgumentOutOfRange_Range", 0, Int32.MaxValue - tryOffset)); + } + + if ((long)handlerOffset + handlerLength > Int32.MaxValue) + { + throw new ArgumentOutOfRangeException("handlerLength", Environment.GetResourceString("ArgumentOutOfRange_Range", 0, Int32.MaxValue - handlerOffset)); + } + + // Other tokens migth also be invalid. We only check nil tokens as the implementation (SectEH_Emit in corhlpr.cpp) requires it, + // and we can't check for valid tokens until the module is baked. + if (kind == ExceptionHandlingClauseOptions.Clause && (exceptionTypeToken & 0x00FFFFFF) == 0) + { + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidTypeToken", exceptionTypeToken), "exceptionTypeToken"); + } + + Contract.EndContractBlock(); + + if (!IsValidKind(kind)) + { + throw new ArgumentOutOfRangeException("kind", Environment.GetResourceString("ArgumentOutOfRange_Enum")); + } + + m_tryStartOffset = tryOffset; + m_tryEndOffset = tryOffset + tryLength; + m_filterOffset = filterOffset; + m_handlerStartOffset = handlerOffset; + m_handlerEndOffset = handlerOffset + handlerLength; + m_kind = kind; + m_exceptionClass = exceptionTypeToken; + } + + internal ExceptionHandler(int tryStartOffset, int tryEndOffset, int filterOffset, int handlerStartOffset, int handlerEndOffset, + int kind, int exceptionTypeToken) + { + Contract.Assert(tryStartOffset >= 0); + Contract.Assert(tryEndOffset >= 0); + Contract.Assert(filterOffset >= 0); + Contract.Assert(handlerStartOffset >= 0); + Contract.Assert(handlerEndOffset >= 0); + Contract.Assert(IsValidKind((ExceptionHandlingClauseOptions)kind)); + Contract.Assert(kind != (int)ExceptionHandlingClauseOptions.Clause || (exceptionTypeToken & 0x00FFFFFF) != 0); + + m_tryStartOffset = tryStartOffset; + m_tryEndOffset = tryEndOffset; + m_filterOffset = filterOffset; + m_handlerStartOffset = handlerStartOffset; + m_handlerEndOffset = handlerEndOffset; + m_kind = (ExceptionHandlingClauseOptions)kind; + m_exceptionClass = exceptionTypeToken; + } + + private static bool IsValidKind(ExceptionHandlingClauseOptions kind) + { + switch (kind) + { + case ExceptionHandlingClauseOptions.Clause: + case ExceptionHandlingClauseOptions.Filter: + case ExceptionHandlingClauseOptions.Finally: + case ExceptionHandlingClauseOptions.Fault: + return true; + + default: + return false; + } + } + + #endregion + + #region Equality + + public override int GetHashCode() + { + return m_exceptionClass ^ m_tryStartOffset ^ m_tryEndOffset ^ m_filterOffset ^ m_handlerStartOffset ^ m_handlerEndOffset ^ (int)m_kind; + } + + public override bool Equals(Object obj) + { + return obj is ExceptionHandler && Equals((ExceptionHandler)obj); + } + + public bool Equals(ExceptionHandler other) + { + return + other.m_exceptionClass == m_exceptionClass && + other.m_tryStartOffset == m_tryStartOffset && + other.m_tryEndOffset == m_tryEndOffset && + other.m_filterOffset == m_filterOffset && + other.m_handlerStartOffset == m_handlerStartOffset && + other.m_handlerEndOffset == m_handlerEndOffset && + other.m_kind == m_kind; + } + + public static bool operator ==(ExceptionHandler left, ExceptionHandler right) + { + return left.Equals(right); + } + + public static bool operator !=(ExceptionHandler left, ExceptionHandler right) + { + return !left.Equals(right); + } + + #endregion + } +} + + + + + + + + + + diff --git a/src/mscorlib/src/System/Reflection/Emit/MethodBuilderInstantiation.cs b/src/mscorlib/src/System/Reflection/Emit/MethodBuilderInstantiation.cs new file mode 100644 index 0000000000..5b69b6e607 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/MethodBuilderInstantiation.cs @@ -0,0 +1,142 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection.Emit +{ + using System; + using System.Reflection; + using System.Collections; + using System.Globalization; + using System.Diagnostics.Contracts; + + internal sealed class MethodBuilderInstantiation : MethodInfo + { + #region Static Members + internal static MethodInfo MakeGenericMethod(MethodInfo method, Type[] inst) + { + if (!method.IsGenericMethodDefinition) + throw new InvalidOperationException(); + Contract.EndContractBlock(); + + return new MethodBuilderInstantiation(method, inst); + } + + #endregion + + #region Private Data Mebers + internal MethodInfo m_method; + private Type[] m_inst; + #endregion + + #region Constructor + internal MethodBuilderInstantiation(MethodInfo method, Type[] inst) + { + m_method = method; + m_inst = inst; + } + #endregion + + internal override Type[] GetParameterTypes() + { + return m_method.GetParameterTypes(); + } + + #region MemberBase + public override MemberTypes MemberType { get { return m_method.MemberType; } } + public override String Name { get { return m_method.Name; } } + public override Type DeclaringType { get { return m_method.DeclaringType; } } + public override Type ReflectedType { get { return m_method.ReflectedType; } } + public override Object[] GetCustomAttributes(bool inherit) { return m_method.GetCustomAttributes(inherit); } + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) { return m_method.GetCustomAttributes(attributeType, inherit); } + public override bool IsDefined(Type attributeType, bool inherit) { return m_method.IsDefined(attributeType, inherit); } + public override Module Module { get { return m_method.Module; } } + public new Type GetType() { return base.GetType(); } + #endregion + + #region MethodBase Members + [Pure] + public override ParameterInfo[] GetParameters() { throw new NotSupportedException(); } + public override MethodImplAttributes GetMethodImplementationFlags() { return m_method.GetMethodImplementationFlags(); } + public override RuntimeMethodHandle MethodHandle { get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); } } + public override MethodAttributes Attributes { get { return m_method.Attributes; } } + public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) + { + throw new NotSupportedException(); + } + public override CallingConventions CallingConvention { get { return m_method.CallingConvention; } } + public override Type[] GetGenericArguments() { return m_inst; } + public override MethodInfo GetGenericMethodDefinition() { return m_method; } + public override bool IsGenericMethodDefinition { get { return false; } } + public override bool ContainsGenericParameters + { + get + { + for (int i = 0; i < m_inst.Length; i++) + { + if (m_inst[i].ContainsGenericParameters) + return true; + } + + if (DeclaringType != null && DeclaringType.ContainsGenericParameters) + return true; + + return false; + } + } + + public override MethodInfo MakeGenericMethod(params Type[] arguments) + { + throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericMethodDefinition")); + } + + public override bool IsGenericMethod { get { return true; } } + + #endregion + + #region Public Abstract\Virtual Members + public override Type ReturnType + { + get + { + return m_method.ReturnType; + } + } + + public override ParameterInfo ReturnParameter { get { throw new NotSupportedException(); } } + public override ICustomAttributeProvider ReturnTypeCustomAttributes { get { throw new NotSupportedException(); } } + public override MethodInfo GetBaseDefinition() { throw new NotSupportedException(); } + #endregion + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mscorlib/src/System/Reflection/Emit/MethodToken.cs b/src/mscorlib/src/System/Reflection/Emit/MethodToken.cs new file mode 100644 index 0000000000..cc28e173d7 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/MethodToken.cs @@ -0,0 +1,65 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** Purpose: Represents a Method to the ILGenerator class. +** +** +===========================================================*/ +namespace System.Reflection.Emit { + + using System; + using System.Reflection; + using System.Security.Permissions; + + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public struct MethodToken + { + public static readonly MethodToken Empty = new MethodToken(); + internal int m_method; + + internal MethodToken(int str) { + m_method=str; + } + + public int Token { + get { return m_method; } + } + + public override int GetHashCode() + { + return m_method; + } + + public override bool Equals(Object obj) + { + if (obj is MethodToken) + return Equals((MethodToken)obj); + else + return false; + } + + public bool Equals(MethodToken obj) + { + return obj.m_method == m_method; + } + + public static bool operator ==(MethodToken a, MethodToken b) + { + return a.Equals(b); + } + + public static bool operator !=(MethodToken a, MethodToken b) + { + return !(a == b); + } + + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs new file mode 100644 index 0000000000..ce2a592ae2 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilder.cs @@ -0,0 +1,2422 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection.Emit +{ + using System.Runtime.InteropServices; + using System; + using System.Collections.Generic; + using System.Diagnostics.SymbolStore; + using System.Globalization; + using System.Reflection; + using System.Diagnostics; + using System.IO; + using System.Resources; + using System.Security; + using System.Security.Permissions; + using System.Runtime.Serialization; + using System.Text; + using System.Threading; + using System.Runtime.Versioning; + using System.Runtime.CompilerServices; + using System.Diagnostics.Contracts; + + internal sealed class InternalModuleBuilder : RuntimeModule + { + #region Private Data Members + // WARNING!! WARNING!! + // InternalModuleBuilder should not contain any data members as its reflectbase is the same as Module. + #endregion + + private InternalModuleBuilder() { } + + #region object overrides + public override bool Equals(object obj) + { + if (obj == null) + return false; + + if (obj is InternalModuleBuilder) + return ((object)this == obj); + + return obj.Equals(this); + } + // Need a dummy GetHashCode to pair with Equals + public override int GetHashCode() { return base.GetHashCode(); } + #endregion + } + + // deliberately not [serializable] + [HostProtection(MayLeakOnAbort = true)] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_ModuleBuilder))] + [System.Runtime.InteropServices.ComVisible(true)] + public class ModuleBuilder : Module, _ModuleBuilder + { + #region FCalls + + [MethodImplAttribute(MethodImplOptions.InternalCall)] + internal static extern IntPtr nCreateISymWriterForDynamicModule(Module module, String filename); + + #endregion + + #region Internal Static Members + static internal String UnmangleTypeName(String typeName) + { + // Gets the original type name, without '+' name mangling. + + int i = typeName.Length - 1; + while (true) + { + i = typeName.LastIndexOf('+', i); + if (i == -1) + break; + + bool evenSlashes = true; + int iSlash = i; + while (typeName[--iSlash] == '\\') + evenSlashes = !evenSlashes; + + // Even number of slashes means this '+' is a name separator + if (evenSlashes) + break; + + i = iSlash; + } + + return typeName.Substring(i + 1); + } + + #endregion + + #region Intenral Data Members + // m_TypeBuilder contains both TypeBuilder and EnumBuilder objects + private Dictionary m_TypeBuilderDict; + private ISymbolWriter m_iSymWriter; + internal ModuleBuilderData m_moduleData; +#if !FEATURE_CORECLR + private MethodToken m_EntryPoint; +#endif //!FEATURE_CORECLR + internal InternalModuleBuilder m_internalModuleBuilder; + // This is the "external" AssemblyBuilder + // only the "external" ModuleBuilder has this set + private AssemblyBuilder m_assemblyBuilder; + internal AssemblyBuilder ContainingAssemblyBuilder { get { return m_assemblyBuilder; } } + #endregion + + #region Constructor + internal ModuleBuilder(AssemblyBuilder assemblyBuilder, InternalModuleBuilder internalModuleBuilder) + { + m_internalModuleBuilder = internalModuleBuilder; + m_assemblyBuilder = assemblyBuilder; + } + #endregion + + #region Private Members + internal void AddType(string name, Type type) + { + m_TypeBuilderDict.Add(name, type); + } + + internal void CheckTypeNameConflict(String strTypeName, Type enclosingType) + { + Type foundType = null; + if (m_TypeBuilderDict.TryGetValue(strTypeName, out foundType) && + object.ReferenceEquals(foundType.DeclaringType, enclosingType)) + { + // Cannot have two types with the same name + throw new ArgumentException(Environment.GetResourceString("Argument_DuplicateTypeName")); + } + } + + private Type GetType(String strFormat, Type baseType) + { + // This function takes a string to describe the compound type, such as "[,][]", and a baseType. + + if (strFormat == null || strFormat.Equals(String.Empty)) + { + return baseType; + } + + // convert the format string to byte array and then call FormCompoundType + return SymbolType.FormCompoundType(strFormat, baseType, 0); + + } + + + internal void CheckContext(params Type[][] typess) + { + ContainingAssemblyBuilder.CheckContext(typess); + } + internal void CheckContext(params Type[] types) + { + ContainingAssemblyBuilder.CheckContext(types); + } + + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static int GetTypeRef(RuntimeModule module, String strFullName, RuntimeModule refedModule, String strRefedModuleFileName, int tkResolution); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static int GetMemberRef(RuntimeModule module, RuntimeModule refedModule, int tr, int defToken); + + [System.Security.SecurityCritical] // auto-generated + private int GetMemberRef(Module refedModule, int tr, int defToken) + { + return GetMemberRef(GetNativeHandle(), GetRuntimeModuleFromModule(refedModule).GetNativeHandle(), tr, defToken); + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static int GetMemberRefFromSignature(RuntimeModule module, int tr, String methodName, byte[] signature, int length); + + [System.Security.SecurityCritical] // auto-generated + private int GetMemberRefFromSignature(int tr, String methodName, byte[] signature, int length) + { + return GetMemberRefFromSignature(GetNativeHandle(), tr, methodName, signature, length); + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static int GetMemberRefOfMethodInfo(RuntimeModule module, int tr, IRuntimeMethodInfo method); + + [System.Security.SecurityCritical] // auto-generated + private int GetMemberRefOfMethodInfo(int tr, RuntimeMethodInfo method) + { + Contract.Assert(method != null); + +#if FEATURE_APPX + if (ContainingAssemblyBuilder.ProfileAPICheck) + { + if ((method.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", method.FullName)); + } +#endif + + return GetMemberRefOfMethodInfo(GetNativeHandle(), tr, method); + } + + [System.Security.SecurityCritical] // auto-generated + private int GetMemberRefOfMethodInfo(int tr, RuntimeConstructorInfo method) + { + Contract.Assert(method != null); + +#if FEATURE_APPX + if (ContainingAssemblyBuilder.ProfileAPICheck) + { + if ((method.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", method.FullName)); + } +#endif + + return GetMemberRefOfMethodInfo(GetNativeHandle(), tr, method); + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static int GetMemberRefOfFieldInfo(RuntimeModule module, int tkType, RuntimeTypeHandle declaringType, int tkField); + + [System.Security.SecurityCritical] // auto-generated + private int GetMemberRefOfFieldInfo(int tkType, RuntimeTypeHandle declaringType, RuntimeFieldInfo runtimeField) + { + Contract.Assert(runtimeField != null); + +#if FEATURE_APPX + if (ContainingAssemblyBuilder.ProfileAPICheck) + { + RtFieldInfo rtField = runtimeField as RtFieldInfo; + if (rtField != null && (rtField.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtField.FullName)); + } +#endif + + return GetMemberRefOfFieldInfo(GetNativeHandle(), tkType, declaringType, runtimeField.MetadataToken); + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static int GetTokenFromTypeSpec(RuntimeModule pModule, byte[] signature, int length); + + [System.Security.SecurityCritical] // auto-generated + private int GetTokenFromTypeSpec(byte[] signature, int length) + { + return GetTokenFromTypeSpec(GetNativeHandle(), signature, length); + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static int GetArrayMethodToken(RuntimeModule module, int tkTypeSpec, String methodName, byte[] signature, int sigLength); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static int GetStringConstant(RuntimeModule module, String str, int length); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static void PreSavePEFile(RuntimeModule module, int portableExecutableKind, int imageFileMachine); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static void SavePEFile(RuntimeModule module, String fileName, int entryPoint, int isExe, bool isManifestFile); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static void AddResource( + RuntimeModule module, String strName, + byte[] resBytes, int resByteCount, int tkFile, int attribute, + int portableExecutableKind, int imageFileMachine); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static void SetModuleName(RuntimeModule module, String strModuleName); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal extern static void SetFieldRVAContent(RuntimeModule module, int fdToken, byte[] data, int length); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static void DefineNativeResourceFile(RuntimeModule module, + String strFilename, + int portableExecutableKind, + int ImageFileMachine); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static void DefineNativeResourceBytes(RuntimeModule module, + byte[] pbResource, int cbResource, + int portableExecutableKind, + int imageFileMachine); + + [System.Security.SecurityCritical] // auto-generated + internal void DefineNativeResource(PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) + { + string strResourceFileName = m_moduleData.m_strResourceFileName; + byte[] resourceBytes = m_moduleData.m_resourceBytes; + + if (strResourceFileName != null) + { + DefineNativeResourceFile(GetNativeHandle(), + strResourceFileName, + (int)portableExecutableKind, (int)imageFileMachine); + } + else + if (resourceBytes != null) + { + DefineNativeResourceBytes(GetNativeHandle(), + resourceBytes, resourceBytes.Length, + (int)portableExecutableKind, (int)imageFileMachine); + } + } + + #endregion + + #region Internal Members + internal virtual Type FindTypeBuilderWithName(String strTypeName, bool ignoreCase) + { + if (ignoreCase) + { + foreach (string name in m_TypeBuilderDict.Keys) + { + if (String.Compare(name, strTypeName, (StringComparison.OrdinalIgnoreCase)) == 0) + return m_TypeBuilderDict[name]; + } + } + else + { + Type foundType; + if (m_TypeBuilderDict.TryGetValue(strTypeName, out foundType)) + return foundType; + } + + return null; + } + +#if !FEATURE_CORECLR + internal void SetEntryPoint(MethodToken entryPoint) + { + // Sets the entry point of the module to be a given method. If no entry point + // is specified, calling EmitPEFile will generate a dll. + // AssemblyBuilder.SetEntryPoint has already demanded required permission + m_EntryPoint = entryPoint; + } +#endif //!FEATURE_CORECLR + + +#if !FEATURE_CORECLR + // This is a helper called by AssemblyBuilder save to presave information for the persistable modules. + // no need to lock here because we have already taken the lock in AssemblyBuilder.Save + [System.Security.SecurityCritical] // auto-generated + internal void PreSave(String fileName, + PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) + { + if (m_moduleData.m_isSaved == true) + { + // can only save once + throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, + Environment.GetResourceString("InvalidOperation_ModuleHasBeenSaved"), + m_moduleData.m_strModuleName)); + } + + if (m_moduleData.m_fGlobalBeenCreated == false && m_moduleData.m_fHasGlobal == true) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_GlobalFunctionNotBaked")); + + TypeBuilder typeBuilder; + foreach (Type item in m_TypeBuilderDict.Values) + { + if (item is TypeBuilder) + { + typeBuilder = (TypeBuilder)item; + } + else + { + EnumBuilder enumBuilder = (EnumBuilder)item; + typeBuilder = enumBuilder.m_typeBuilder; + } + + if (!typeBuilder.IsCreated()) + { + // cannot save to PE file without creating all of the types first + throw new NotSupportedException(String.Format(CultureInfo.InvariantCulture, + Environment.GetResourceString("NotSupported_NotAllTypesAreBaked"), + typeBuilder.FullName)); + } + } + + PreSavePEFile(GetNativeHandle(), (int)portableExecutableKind, (int)imageFileMachine); + } + + // no need to lock here because we have already taken the lock in AssemblyBuilder.Save + [System.Security.SecurityCritical] // auto-generated + internal void Save(String fileName, bool isAssemblyFile, PortableExecutableKinds portableExecutableKind, + ImageFileMachine imageFileMachine) + { + // This is a helper called by AssemblyBuilder save to save information for the persistable modules. + if (m_moduleData.m_embeddedRes != null) + { + // There are embedded resources for this module + ResWriterData resWriter; + + // Add each resource content into the to be saved PE file + for (resWriter = m_moduleData.m_embeddedRes; resWriter != null; resWriter = resWriter.m_nextResWriter) + { + if (resWriter.m_resWriter != null) + resWriter.m_resWriter.Generate(); + + byte[] resBytes = new byte[resWriter.m_memoryStream.Length]; + resWriter.m_memoryStream.Flush(); + resWriter.m_memoryStream.Position = 0; + resWriter.m_memoryStream.Read(resBytes, 0, resBytes.Length); + + AddResource(GetNativeHandle(), + resWriter.m_strName, + resBytes, + resBytes.Length, + m_moduleData.FileToken, + (int)resWriter.m_attribute, + (int)portableExecutableKind, + (int)imageFileMachine); + } + } + + DefineNativeResource(portableExecutableKind, imageFileMachine); + + PEFileKinds pekind = isAssemblyFile ? ContainingAssemblyBuilder.m_assemblyData.m_peFileKind : PEFileKinds.Dll; + + SavePEFile(GetNativeHandle(), fileName, m_EntryPoint.Token, (int)pekind, isAssemblyFile); + + m_moduleData.m_isSaved = true; + } +#endif // !FEATURE_CORECLR + + [System.Security.SecurityCritical] // auto-generated + private int GetTypeRefNested(Type type, Module refedModule, String strRefedModuleFileName) + { + // This function will generate correct TypeRef token for top level type and nested type. + + Type enclosingType = type.DeclaringType; + int tkResolution = 0; + String typeName = type.FullName; + + if (enclosingType != null) + { + tkResolution = GetTypeRefNested(enclosingType, refedModule, strRefedModuleFileName); + typeName = UnmangleTypeName(typeName); + } + + Contract.Assert(!type.IsByRef, "Must not be ByRef."); + Contract.Assert(!type.IsGenericType || type.IsGenericTypeDefinition, "Must not have generic arguments."); + +#if FEATURE_APPX + if (ContainingAssemblyBuilder.ProfileAPICheck) + { + RuntimeType rtType = type as RuntimeType; + if (rtType != null && (rtType.InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", rtType.FullName)); + } + } +#endif + + return GetTypeRef(GetNativeHandle(), typeName, GetRuntimeModuleFromModule(refedModule).GetNativeHandle(), strRefedModuleFileName, tkResolution); + } + + [System.Security.SecurityCritical] // auto-generated + internal MethodToken InternalGetConstructorToken(ConstructorInfo con, bool usingRef) + { + // Helper to get constructor token. If usingRef is true, we will never use the def token + + if (con == null) + throw new ArgumentNullException("con"); + Contract.EndContractBlock(); + + int tr; + int mr = 0; + + ConstructorBuilder conBuilder = null; + ConstructorOnTypeBuilderInstantiation conOnTypeBuilderInst = null; + RuntimeConstructorInfo rtCon = null; + + if ( (conBuilder = con as ConstructorBuilder) != null ) + { + if (usingRef == false && conBuilder.Module.Equals(this)) + return conBuilder.GetToken(); + + // constructor is defined in a different module + tr = GetTypeTokenInternal(con.ReflectedType).Token; + mr = GetMemberRef(con.ReflectedType.Module, tr, conBuilder.GetToken().Token); + } + else if ( (conOnTypeBuilderInst = con as ConstructorOnTypeBuilderInstantiation) != null ) + { + if (usingRef == true) throw new InvalidOperationException(); + + tr = GetTypeTokenInternal(con.DeclaringType).Token; + mr = GetMemberRef(con.DeclaringType.Module, tr, conOnTypeBuilderInst.MetadataTokenInternal); + } + else if ( (rtCon = con as RuntimeConstructorInfo) != null && con.ReflectedType.IsArray == false) + { + // constructor is not a dynamic field + // We need to get the TypeRef tokens + + tr = GetTypeTokenInternal(con.ReflectedType).Token; + mr = GetMemberRefOfMethodInfo(tr, rtCon); + } + else + { + // some user derived ConstructorInfo + // go through the slower code path, i.e. retrieve parameters and form signature helper. + ParameterInfo[] parameters = con.GetParameters(); + if (parameters == null) + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidConstructorInfo")); + + int count = parameters.Length; + Type[] parameterTypes = new Type[count]; + Type[][] requiredCustomModifiers = new Type[count][]; + Type[][] optionalCustomModifiers = new Type[count][]; + + for (int i = 0; i < count; i++) + { + if (parameters[i] == null) + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidConstructorInfo")); + + parameterTypes[i] = parameters[i].ParameterType; + requiredCustomModifiers[i] = parameters[i].GetRequiredCustomModifiers(); + optionalCustomModifiers[i] = parameters[i].GetOptionalCustomModifiers(); + } + + tr = GetTypeTokenInternal(con.ReflectedType).Token; + + SignatureHelper sigHelp = SignatureHelper.GetMethodSigHelper(this, con.CallingConvention, null, null, null, parameterTypes, requiredCustomModifiers, optionalCustomModifiers); + int length; + byte[] sigBytes = sigHelp.InternalGetSignature(out length); + + mr = GetMemberRefFromSignature(tr, con.Name, sigBytes, length); + } + + return new MethodToken( mr ); + } + + [System.Security.SecurityCritical] // auto-generated + internal void Init(String strModuleName, String strFileName, int tkFile) + { + m_moduleData = new ModuleBuilderData(this, strModuleName, strFileName, tkFile); + m_TypeBuilderDict = new Dictionary(); + } + + // This is a method for changing module and file name of the manifest module (created by default for + // each assembly). + [System.Security.SecurityCritical] // auto-generated + internal void ModifyModuleName(string name) + { + // Reset the names in the managed ModuleBuilderData + m_moduleData.ModifyModuleName(name); + + // Reset the name in the underlying metadata + ModuleBuilder.SetModuleName(GetNativeHandle(), name); + } + + internal void SetSymWriter(ISymbolWriter writer) + { + m_iSymWriter = writer; + } + + internal object SyncRoot + { + get + { + return ContainingAssemblyBuilder.SyncRoot; + } + } + + #endregion + + #region Module Overrides + + // m_internalModuleBuilder is null iff this is a "internal" ModuleBuilder + internal InternalModuleBuilder InternalModule + { + get + { + return m_internalModuleBuilder; + } + } + + internal override ModuleHandle GetModuleHandle() + { + return new ModuleHandle(GetNativeHandle()); + } + + internal RuntimeModule GetNativeHandle() + { + return InternalModule.GetNativeHandle(); + } + + private static RuntimeModule GetRuntimeModuleFromModule(Module m) + { + ModuleBuilder mb = m as ModuleBuilder; + if (mb != null) + { + return mb.InternalModule; + } + + return m as RuntimeModule; + } + + [System.Security.SecurityCritical] // auto-generated + private int GetMemberRefToken(MethodBase method, IEnumerable optionalParameterTypes) + { + Type[] parameterTypes; + Type returnType; + int tkParent; + int cGenericParameters = 0; + + if (method.IsGenericMethod) + { + if (!method.IsGenericMethodDefinition) + throw new InvalidOperationException(); + + cGenericParameters = method.GetGenericArguments().Length; + } + + if (optionalParameterTypes != null) + { + if ((method.CallingConvention & CallingConventions.VarArgs) == 0) + { + // Client should not supply optional parameter in default calling convention + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAVarArgCallingConvention")); + } + } + + MethodInfo masmi = method as MethodInfo; + + if (method.DeclaringType.IsGenericType) + { + MethodBase methDef = null; // methodInfo = G.M ==> methDef = G.M + + MethodOnTypeBuilderInstantiation motbi; + ConstructorOnTypeBuilderInstantiation cotbi; + + if ((motbi = method as MethodOnTypeBuilderInstantiation) != null) + { + methDef = motbi.m_method; + } + else if ((cotbi = method as ConstructorOnTypeBuilderInstantiation) != null) + { + methDef = cotbi.m_ctor; + } + else if (method is MethodBuilder || method is ConstructorBuilder) + { + // methodInfo must be GenericMethodDefinition; trying to emit G.M + methDef = method; + } + else + { + Contract.Assert(method is RuntimeMethodInfo || method is RuntimeConstructorInfo); + + if (method.IsGenericMethod) + { + Contract.Assert(masmi != null); + + methDef = masmi.GetGenericMethodDefinition(); + methDef = methDef.Module.ResolveMethod( + method.MetadataToken, + methDef.DeclaringType != null ? methDef.DeclaringType.GetGenericArguments() : null, + methDef.GetGenericArguments()); + } + else + { + methDef = method.Module.ResolveMethod( + method.MetadataToken, + method.DeclaringType != null ? method.DeclaringType.GetGenericArguments() : null, + null); + } + } + + parameterTypes = methDef.GetParameterTypes(); + returnType = MethodBuilder.GetMethodBaseReturnType(methDef); + } + else + { + parameterTypes = method.GetParameterTypes(); + returnType = MethodBuilder.GetMethodBaseReturnType(method); + } + + int sigLength; + byte[] sigBytes = GetMemberRefSignature(method.CallingConvention, returnType, parameterTypes, + optionalParameterTypes, cGenericParameters).InternalGetSignature(out sigLength); + + if (method.DeclaringType.IsGenericType) + { + int length; + byte[] sig = SignatureHelper.GetTypeSigToken(this, method.DeclaringType).InternalGetSignature(out length); + tkParent = GetTokenFromTypeSpec(sig, length); + } + else if (!method.Module.Equals(this)) + { + // Use typeRef as parent because the method's declaringType lives in a different assembly + tkParent = GetTypeToken(method.DeclaringType).Token; + } + else + { + // Use methodDef as parent because the method lives in this assembly and its declaringType has no generic arguments + if (masmi != null) + tkParent = GetMethodToken(masmi).Token; + else + tkParent = GetConstructorToken(method as ConstructorInfo).Token; + } + + return GetMemberRefFromSignature(tkParent, method.Name, sigBytes, sigLength); + } + + [System.Security.SecurityCritical] // auto-generated + internal SignatureHelper GetMemberRefSignature(CallingConventions call, Type returnType, + Type[] parameterTypes, IEnumerable optionalParameterTypes, int cGenericParameters) + { + int cParams = (parameterTypes == null) ? 0 : parameterTypes.Length; + SignatureHelper sig = SignatureHelper.GetMethodSigHelper(this, call, returnType, cGenericParameters); + + for (int i = 0; i < cParams; i++) + { + sig.AddArgument(parameterTypes[i]); + } + + if (optionalParameterTypes != null) { + int i = 0; + foreach (Type type in optionalParameterTypes) + { + // add the sentinel + if (i == 0) + { + sig.AddSentinel(); + } + + sig.AddArgument(type); + i++; + } + } + + return sig; + } + + #endregion + + #region object overrides + public override bool Equals(object obj) + { + return InternalModule.Equals(obj); + } + // Need a dummy GetHashCode to pair with Equals + public override int GetHashCode() { return InternalModule.GetHashCode(); } + #endregion + + #region ICustomAttributeProvider Members + public override Object[] GetCustomAttributes(bool inherit) + { + return InternalModule.GetCustomAttributes(inherit); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + return InternalModule.GetCustomAttributes(attributeType, inherit); + } + + public override bool IsDefined(Type attributeType, bool inherit) + { + return InternalModule.IsDefined(attributeType, inherit); + } + + public override IList GetCustomAttributesData() + { + return InternalModule.GetCustomAttributesData(); + } + #endregion + + #region Module Overrides + + public override Type[] GetTypes() + { + lock(SyncRoot) + { + return GetTypesNoLock(); + } + } + + internal Type[] GetTypesNoLock() + { + int size = m_TypeBuilderDict.Count; + Type[] typeList = new Type[m_TypeBuilderDict.Count]; + int i = 0; + + foreach (Type builder in m_TypeBuilderDict.Values) + { + EnumBuilder enumBldr = builder as EnumBuilder; + TypeBuilder tmpTypeBldr; + + if (enumBldr != null) + tmpTypeBldr = enumBldr.m_typeBuilder; + else + tmpTypeBldr = (TypeBuilder)builder; + + // We should not return TypeBuilders. + // Otherwise anyone can emit code in it. + if (tmpTypeBldr.IsCreated()) + typeList[i++] = tmpTypeBldr.UnderlyingSystemType; + else + typeList[i++] = builder; + } + + return typeList; + } + + [System.Runtime.InteropServices.ComVisible(true)] + public override Type GetType(String className) + { + return GetType(className, false, false); + } + + [System.Runtime.InteropServices.ComVisible(true)] + public override Type GetType(String className, bool ignoreCase) + { + return GetType(className, false, ignoreCase); + } + + [System.Runtime.InteropServices.ComVisible(true)] + public override Type GetType(String className, bool throwOnError, bool ignoreCase) + { + lock(SyncRoot) + { + return GetTypeNoLock(className, throwOnError, ignoreCase); + } + } + + private Type GetTypeNoLock(String className, bool throwOnError, bool ignoreCase) + { + // public API to to a type. The reason that we need this function override from module + // is because clients might need to get foo[] when foo is being built. For example, if + // foo class contains a data member of type foo[]. + // This API first delegate to the Module.GetType implementation. If succeeded, great! + // If not, we have to look up the current module to find the TypeBuilder to represent the base + // type and form the Type object for "foo[,]". + + // Module.GetType() will verify className. + Type baseType = InternalModule.GetType(className, throwOnError, ignoreCase); + if (baseType != null) + return baseType; + + // Now try to see if we contain a TypeBuilder for this type or not. + // Might have a compound type name, indicated via an unescaped + // '[', '*' or '&'. Split the name at this point. + String baseName = null; + String parameters = null; + int startIndex = 0; + + while (startIndex <= className.Length) + { + // Are there any possible special characters left? + int i = className.IndexOfAny(new char[]{'[', '*', '&'}, startIndex); + if (i == -1) + { + // No, type name is simple. + baseName = className; + parameters = null; + break; + } + + // Found a potential special character, but it might be escaped. + int slashes = 0; + for (int j = i - 1; j >= 0 && className[j] == '\\'; j--) + slashes++; + + // Odd number of slashes indicates escaping. + if (slashes % 2 == 1) + { + startIndex = i + 1; + continue; + } + + // Found the end of the base type name. + baseName = className.Substring(0, i); + parameters = className.Substring(i); + break; + } + + // If we didn't find a basename yet, the entire class name is + // the base name and we don't have a composite type. + if (baseName == null) + { + baseName = className; + parameters = null; + } + + baseName = baseName.Replace(@"\\",@"\").Replace(@"\[",@"[").Replace(@"\*",@"*").Replace(@"\&",@"&"); + + if (parameters != null) + { + // try to see if reflection can find the base type. It can be such that reflection + // does not support the complex format string yet! + + baseType = InternalModule.GetType(baseName, false, ignoreCase); + } + + if (baseType == null) + { + // try to find it among the unbaked types. + // starting with the current module first of all. + baseType = FindTypeBuilderWithName(baseName, ignoreCase); + if (baseType == null && Assembly is AssemblyBuilder) + { + // now goto Assembly level to find the type. + int size; + List modList; + + modList = ContainingAssemblyBuilder.m_assemblyData.m_moduleBuilderList; + size = modList.Count; + for (int i = 0; i < size && baseType == null; i++) + { + ModuleBuilder mBuilder = modList[i]; + baseType = mBuilder.FindTypeBuilderWithName(baseName, ignoreCase); + } + } + if (baseType == null) + return null; + } + + if (parameters == null) + return baseType; + + return GetType(parameters, baseType); + } + + public override String FullyQualifiedName + { +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + get + { + String fullyQualifiedName = m_moduleData.m_strFileName; + if (fullyQualifiedName == null) + return null; + if (ContainingAssemblyBuilder.m_assemblyData.m_strDir != null) + { + fullyQualifiedName = Path.Combine(ContainingAssemblyBuilder.m_assemblyData.m_strDir, fullyQualifiedName); + fullyQualifiedName = Path.UnsafeGetFullPath(fullyQualifiedName); + } + + if (ContainingAssemblyBuilder.m_assemblyData.m_strDir != null && fullyQualifiedName != null) + { + new FileIOPermission( FileIOPermissionAccess.PathDiscovery, fullyQualifiedName ).Demand(); + } + + return fullyQualifiedName; + } + } + + public override byte[] ResolveSignature(int metadataToken) + { + return InternalModule.ResolveSignature(metadataToken); + } + + public override MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) + { + return InternalModule.ResolveMethod(metadataToken, genericTypeArguments, genericMethodArguments); + } + + public override FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) + { + return InternalModule.ResolveField(metadataToken, genericTypeArguments, genericMethodArguments); + } + + public override Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) + { + return InternalModule.ResolveType(metadataToken, genericTypeArguments, genericMethodArguments); + } + + public override MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) + { + return InternalModule.ResolveMember(metadataToken, genericTypeArguments, genericMethodArguments); + } + + public override string ResolveString(int metadataToken) + { + return InternalModule.ResolveString(metadataToken); + } + + public override void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine) + { + InternalModule.GetPEKind(out peKind, out machine); + } + + public override int MDStreamVersion + { + get + { + return InternalModule.MDStreamVersion; + } + } + + public override Guid ModuleVersionId + { + get + { + return InternalModule.ModuleVersionId; + } + } + + public override int MetadataToken + { + get + { + return InternalModule.MetadataToken; + } + } + + public override bool IsResource() + { + return InternalModule.IsResource(); + } + + public override FieldInfo[] GetFields(BindingFlags bindingFlags) + { + return InternalModule.GetFields(bindingFlags); + } + + public override FieldInfo GetField(String name, BindingFlags bindingAttr) + { + return InternalModule.GetField(name, bindingAttr); + } + + public override MethodInfo[] GetMethods(BindingFlags bindingFlags) + { + return InternalModule.GetMethods(bindingFlags); + } + + protected override MethodInfo GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder, + CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) + { + // Cannot call InternalModule.GetMethods because it doesn't allow types to be null + return InternalModule.GetMethodInternal(name, bindingAttr, binder, callConvention, types, modifiers); + } + + public override String ScopeName + { + get + { + return InternalModule.ScopeName; + } + } + + public override String Name + { + get + { + return InternalModule.Name; + } + } + + public override Assembly Assembly + { + [Pure] + get + { + return m_assemblyBuilder; + } + } + +#if FEATURE_X509 && FEATURE_CAS_POLICY + public override System.Security.Cryptography.X509Certificates.X509Certificate GetSignerCertificate() + { + return InternalModule.GetSignerCertificate(); + } +#endif // FEATURE_X509 && FEATURE_CAS_POLICY + #endregion + + #region Public Members + + #region Define Type + [System.Security.SecuritySafeCritical] // auto-generated + public TypeBuilder DefineType(String name) + { + Contract.Ensures(Contract.Result() != null); + + lock(SyncRoot) + { + return DefineTypeNoLock(name, TypeAttributes.NotPublic, null, null, PackingSize.Unspecified, TypeBuilder.UnspecifiedTypeSize); + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + public TypeBuilder DefineType(String name, TypeAttributes attr) + { + Contract.Ensures(Contract.Result() != null); + + lock(SyncRoot) + { + return DefineTypeNoLock(name, attr, null, null, PackingSize.Unspecified, TypeBuilder.UnspecifiedTypeSize); + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent) + { + Contract.Ensures(Contract.Result() != null); + + lock(SyncRoot) + { + // Why do we only call CheckContext here? Why don't we call it in the other overloads? + CheckContext(parent); + + return DefineTypeNoLock(name, attr, parent, null, PackingSize.Unspecified, TypeBuilder.UnspecifiedTypeSize); + } + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, int typesize) + { + Contract.Ensures(Contract.Result() != null); + + lock(SyncRoot) + { + return DefineTypeNoLock(name, attr, parent, null, PackingSize.Unspecified, typesize); + } + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, PackingSize packingSize, int typesize) + { + Contract.Ensures(Contract.Result() != null); + + lock (SyncRoot) + { + return DefineTypeNoLock(name, attr, parent, null, packingSize, typesize); + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + [System.Runtime.InteropServices.ComVisible(true)] + public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, Type[] interfaces) + { + Contract.Ensures(Contract.Result() != null); + + lock(SyncRoot) + { + return DefineTypeNoLock(name, attr, parent, interfaces, PackingSize.Unspecified, TypeBuilder.UnspecifiedTypeSize); + } + } + + [System.Security.SecurityCritical] // auto-generated + private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packingSize, int typesize) + { + Contract.Ensures(Contract.Result() != null); + + return new TypeBuilder(name, attr, parent, interfaces, this, packingSize, typesize, null); ; + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public TypeBuilder DefineType(String name, TypeAttributes attr, Type parent, PackingSize packsize) + { + Contract.Ensures(Contract.Result() != null); + + lock(SyncRoot) + { + return DefineTypeNoLock(name, attr, parent, packsize); + } + } + + [System.Security.SecurityCritical] // auto-generated + private TypeBuilder DefineTypeNoLock(String name, TypeAttributes attr, Type parent, PackingSize packsize) + { + Contract.Ensures(Contract.Result() != null); + + return new TypeBuilder(name, attr, parent, null, this, packsize, TypeBuilder.UnspecifiedTypeSize, null); + } + + #endregion + + #region Define Enum + + // This API can only be used to construct a top-level (not nested) enum type. + // Nested enum types can be defined manually using ModuleBuilder.DefineType. + [System.Security.SecuritySafeCritical] // auto-generated + public EnumBuilder DefineEnum(String name, TypeAttributes visibility, Type underlyingType) + { + Contract.Ensures(Contract.Result() != null); + + CheckContext(underlyingType); + lock(SyncRoot) + { + EnumBuilder enumBuilder = DefineEnumNoLock(name, visibility, underlyingType); + + // This enum is not generic, nested, and cannot have any element type. + Contract.Assert(name == enumBuilder.FullName); + + // Replace the TypeBuilder object in m_TypeBuilderDict with this EnumBuilder object. + Contract.Assert(enumBuilder.m_typeBuilder == m_TypeBuilderDict[name]); + m_TypeBuilderDict[name] = enumBuilder; + + return enumBuilder; + } + } + + [System.Security.SecurityCritical] // auto-generated + private EnumBuilder DefineEnumNoLock(String name, TypeAttributes visibility, Type underlyingType) + { + Contract.Ensures(Contract.Result() != null); + + return new EnumBuilder(name, underlyingType, visibility, this); + } + + #endregion + + #region Define Resource +#if !FEATURE_CORECLR + public IResourceWriter DefineResource(String name, String description) + { + // Define embedded managed resource to be stored in this module + Contract.Ensures(Contract.Result() != null); + + return DefineResource(name, description, ResourceAttributes.Public); + } + + public IResourceWriter DefineResource(String name, String description, ResourceAttributes attribute) + { + // Define embedded managed resource to be stored in this module + Contract.Ensures(Contract.Result() != null); + + lock(SyncRoot) + { + return DefineResourceNoLock(name, description, attribute); + } + } + + private IResourceWriter DefineResourceNoLock(String name, String description, ResourceAttributes attribute) + { + // Define embedded managed resource to be stored in this module + + if (IsTransient()) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer")); + + if (name == null) + throw new ArgumentNullException("name"); + if (name.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + Contract.Ensures(Contract.Result() != null); + Contract.EndContractBlock(); + + if (m_assemblyBuilder.IsPersistable()) + { + m_assemblyBuilder.m_assemblyData.CheckResNameConflict(name); + + MemoryStream stream = new MemoryStream(); + ResourceWriter resWriter = new ResourceWriter(stream); + ResWriterData resWriterData = new ResWriterData( resWriter, stream, name, String.Empty, String.Empty, attribute); + + // chain it to the embedded resource list + resWriterData.m_nextResWriter = m_moduleData.m_embeddedRes; + m_moduleData.m_embeddedRes = resWriterData; + return resWriter; + } + else + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer")); + } + } +#endif // !FEATURE_CORECLR + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + public void DefineManifestResource(String name, Stream stream, ResourceAttributes attribute) + { + if (name == null) + throw new ArgumentNullException("name"); + + if (stream == null) + throw new ArgumentNullException("stream"); + Contract.EndContractBlock(); + + // Define embedded managed resource to be stored in this module + + lock(SyncRoot) + { + DefineManifestResourceNoLock(name, stream, attribute); + } + } + + private void DefineManifestResourceNoLock(String name, Stream stream, ResourceAttributes attribute) + { + // Define embedded managed resource to be stored in this module + if (IsTransient()) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer")); + Contract.EndContractBlock(); + +#if !FEATURE_CORECLR + if (name == null) + throw new ArgumentNullException("name"); + if (name.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + + if (m_assemblyBuilder.IsPersistable()) + { + m_assemblyBuilder.m_assemblyData.CheckResNameConflict(name); + + ResWriterData resWriterData = new ResWriterData( null, stream, name, String.Empty, String.Empty, attribute); + + // chain it to the embedded resource list + resWriterData.m_nextResWriter = m_moduleData.m_embeddedRes; + m_moduleData.m_embeddedRes = resWriterData; + } + else + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadResourceContainer")); + } +#endif // !FEATURE_CORECLR + } + + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + public void DefineUnmanagedResource(Byte[] resource) + { + lock(SyncRoot) + { + DefineUnmanagedResourceInternalNoLock(resource); + } + } + + internal void DefineUnmanagedResourceInternalNoLock(Byte[] resource) + { + if (resource == null) + throw new ArgumentNullException("resource"); + Contract.EndContractBlock(); + + if (m_moduleData.m_strResourceFileName != null || m_moduleData.m_resourceBytes != null) + throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined")); + + m_moduleData.m_resourceBytes = new byte[resource.Length]; + Buffer.BlockCopy(resource, 0, m_moduleData.m_resourceBytes, 0, resource.Length); + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public void DefineUnmanagedResource(String resourceFileName) + { + lock(SyncRoot) + { + DefineUnmanagedResourceFileInternalNoLock(resourceFileName); + } + } + + [System.Security.SecurityCritical] // auto-generated + internal void DefineUnmanagedResourceFileInternalNoLock(String resourceFileName) + { + if (resourceFileName == null) + throw new ArgumentNullException("resourceFileName"); + Contract.EndContractBlock(); + + if (m_moduleData.m_resourceBytes != null || m_moduleData.m_strResourceFileName != null) + throw new ArgumentException(Environment.GetResourceString("Argument_NativeResourceAlreadyDefined")); + + // Check caller has the right to read the file. + string strFullFileName; + strFullFileName = Path.UnsafeGetFullPath(resourceFileName); + new FileIOPermission(FileIOPermissionAccess.Read, strFullFileName).Demand(); + + new EnvironmentPermission(PermissionState.Unrestricted).Assert(); + try + { + if (File.UnsafeExists(resourceFileName) == false) + throw new FileNotFoundException(Environment.GetResourceString( + "IO.FileNotFound_FileName", + resourceFileName), resourceFileName); + } + finally + { + CodeAccessPermission.RevertAssert(); + } + + m_moduleData.m_strResourceFileName = strFullFileName; + } + #endregion + + #region Define Global Method + public MethodBuilder DefineGlobalMethod(String name, MethodAttributes attributes, Type returnType, Type[] parameterTypes) + { + Contract.Ensures(Contract.Result() != null); + + return DefineGlobalMethod(name, attributes, CallingConventions.Standard, returnType, parameterTypes); + } + + public MethodBuilder DefineGlobalMethod(String name, MethodAttributes attributes, CallingConventions callingConvention, + Type returnType, Type[] parameterTypes) + { + Contract.Ensures(Contract.Result() != null); + + return DefineGlobalMethod(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null); + } + + public MethodBuilder DefineGlobalMethod(String name, MethodAttributes attributes, CallingConventions callingConvention, + Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, + Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) + { + lock(SyncRoot) + { + return DefineGlobalMethodNoLock(name, attributes, callingConvention, returnType, + requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, + parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers); + } + } + + private MethodBuilder DefineGlobalMethodNoLock(String name, MethodAttributes attributes, CallingConventions callingConvention, + Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, + Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) + { + if (m_moduleData.m_fGlobalBeenCreated == true) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GlobalsHaveBeenCreated")); + + if (name == null) + throw new ArgumentNullException("name"); + + if (name.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + + if ((attributes & MethodAttributes.Static) == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_GlobalFunctionHasToBeStatic")); + Contract.Ensures(Contract.Result() != null); + Contract.EndContractBlock(); + + CheckContext(returnType); + CheckContext(requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, parameterTypes); + CheckContext(requiredParameterTypeCustomModifiers); + CheckContext(optionalParameterTypeCustomModifiers); + + m_moduleData.m_fHasGlobal = true; + + return m_moduleData.m_globalTypeBuilder.DefineMethod(name, attributes, callingConvention, + returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, + parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers); + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + public MethodBuilder DefinePInvokeMethod(String name, String dllName, MethodAttributes attributes, + CallingConventions callingConvention, Type returnType, Type[] parameterTypes, + CallingConvention nativeCallConv, CharSet nativeCharSet) + { + Contract.Ensures(Contract.Result() != null); + + return DefinePInvokeMethod(name, dllName, name, attributes, callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet); + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + public MethodBuilder DefinePInvokeMethod(String name, String dllName, String entryName, MethodAttributes attributes, + CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, + CharSet nativeCharSet) + { + Contract.Ensures(Contract.Result() != null); + + lock(SyncRoot) + { + return DefinePInvokeMethodNoLock(name, dllName, entryName, attributes, callingConvention, + returnType, parameterTypes, nativeCallConv, nativeCharSet); + } + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + private MethodBuilder DefinePInvokeMethodNoLock(String name, String dllName, String entryName, MethodAttributes attributes, + CallingConventions callingConvention, Type returnType, Type[] parameterTypes, CallingConvention nativeCallConv, + CharSet nativeCharSet) + { + //Global methods must be static. + if ((attributes & MethodAttributes.Static) == 0) + { + throw new ArgumentException(Environment.GetResourceString("Argument_GlobalFunctionHasToBeStatic")); + } + Contract.Ensures(Contract.Result() != null); + Contract.EndContractBlock(); + + CheckContext(returnType); + CheckContext(parameterTypes); + + m_moduleData.m_fHasGlobal = true; + return m_moduleData.m_globalTypeBuilder.DefinePInvokeMethod(name, dllName, entryName, attributes, callingConvention, returnType, parameterTypes, nativeCallConv, nativeCharSet); + } + + public void CreateGlobalFunctions() + { + lock(SyncRoot) + { + CreateGlobalFunctionsNoLock(); + } + } + + private void CreateGlobalFunctionsNoLock() + { + if (m_moduleData.m_fGlobalBeenCreated) + { + // cannot create globals twice + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule")); + } + m_moduleData.m_globalTypeBuilder.CreateType(); + m_moduleData.m_fGlobalBeenCreated = true; + } + + #endregion + + #region Define Data + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + public FieldBuilder DefineInitializedData(String name, byte[] data, FieldAttributes attributes) + { + // This method will define an initialized Data in .sdata. + // We will create a fake TypeDef to represent the data with size. This TypeDef + // will be the signature for the Field. + Contract.Ensures(Contract.Result() != null); + + lock(SyncRoot) + { + return DefineInitializedDataNoLock(name, data, attributes); + } + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + private FieldBuilder DefineInitializedDataNoLock(String name, byte[] data, FieldAttributes attributes) + { + // This method will define an initialized Data in .sdata. + // We will create a fake TypeDef to represent the data with size. This TypeDef + // will be the signature for the Field. + if (m_moduleData.m_fGlobalBeenCreated == true) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GlobalsHaveBeenCreated")); + } + Contract.Ensures(Contract.Result() != null); + Contract.EndContractBlock(); + + m_moduleData.m_fHasGlobal = true; + return m_moduleData.m_globalTypeBuilder.DefineInitializedData(name, data, attributes); + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + public FieldBuilder DefineUninitializedData(String name, int size, FieldAttributes attributes) + { + Contract.Ensures(Contract.Result() != null); + + lock(SyncRoot) + { + return DefineUninitializedDataNoLock(name, size, attributes); + } + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + private FieldBuilder DefineUninitializedDataNoLock(String name, int size, FieldAttributes attributes) + { + // This method will define an uninitialized Data in .sdata. + // We will create a fake TypeDef to represent the data with size. This TypeDef + // will be the signature for the Field. + + if (m_moduleData.m_fGlobalBeenCreated == true) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_GlobalsHaveBeenCreated")); + } + Contract.Ensures(Contract.Result() != null); + Contract.EndContractBlock(); + + m_moduleData.m_fHasGlobal = true; + return m_moduleData.m_globalTypeBuilder.DefineUninitializedData(name, size, attributes); + } + + #endregion + + #region GetToken + // For a generic type definition, we should return the token for the generic type definition itself in two cases: + // 1. GetTypeToken + // 2. ldtoken (see ILGenerator) + // For all other occasions we should return the generic type instantiated on its formal parameters. + [System.Security.SecurityCritical] // auto-generated + internal TypeToken GetTypeTokenInternal(Type type) + { + return GetTypeTokenInternal(type, false); + } + + [System.Security.SecurityCritical] // auto-generated + private TypeToken GetTypeTokenInternal(Type type, bool getGenericDefinition) + { + lock(SyncRoot) + { + return GetTypeTokenWorkerNoLock(type, getGenericDefinition); + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + public TypeToken GetTypeToken(Type type) + { + return GetTypeTokenInternal(type, true); + } + + [System.Security.SecurityCritical] // auto-generated + private TypeToken GetTypeTokenWorkerNoLock(Type type, bool getGenericDefinition) + { + if (type == null) + throw new ArgumentNullException("type"); + Contract.EndContractBlock(); + + CheckContext(type); + + // Return a token for the class relative to the Module. Tokens + // are used to indentify objects when the objects are used in IL + // instructions. Tokens are always relative to the Module. For example, + // the token value for System.String is likely to be different from + // Module to Module. Calling GetTypeToken will cause a reference to be + // added to the Module. This reference becomes a perminate part of the Module, + // multiple calles to this method with the same class have no additional side affects. + // This function is optimized to use the TypeDef token if Type is within the same module. + // We should also be aware of multiple dynamic modules and multiple implementation of Type!!! + + if (type.IsByRef) + throw new ArgumentException(Environment.GetResourceString("Argument_CannotGetTypeTokenForByRef")); + + if ((type.IsGenericType && (!type.IsGenericTypeDefinition || !getGenericDefinition)) || + type.IsGenericParameter || + type.IsArray || + type.IsPointer) + { + int length; + byte[] sig = SignatureHelper.GetTypeSigToken(this, type).InternalGetSignature(out length); + return new TypeToken(GetTokenFromTypeSpec(sig, length)); + } + + Module refedModule = type.Module; + + if (refedModule.Equals(this)) + { + // no need to do anything additional other than defining the TypeRef Token + TypeBuilder typeBuilder = null; + GenericTypeParameterBuilder paramBuilder = null; + + EnumBuilder enumBuilder = type as EnumBuilder; + if (enumBuilder != null) + typeBuilder = enumBuilder.m_typeBuilder; + else + typeBuilder = type as TypeBuilder; + + if (typeBuilder != null) + { + // optimization: if the type is defined in this module, + // just return the token + // + return typeBuilder.TypeToken; + } + else if ((paramBuilder = type as GenericTypeParameterBuilder) != null) + { + return new TypeToken(paramBuilder.MetadataTokenInternal); + } + + return new TypeToken(GetTypeRefNested(type, this, String.Empty)); + } + + // After this point, the referenced module is not the same as the referencing + // module. + // + ModuleBuilder refedModuleBuilder = refedModule as ModuleBuilder; + +#if !FEATURE_CORECLR + Contract.Assert(refedModuleBuilder != null || refedModule is RuntimeModule); + bool isRefedModuleTransient = refedModuleBuilder != null ? + refedModuleBuilder.IsTransient() : + ((RuntimeModule)refedModule).IsTransientInternal(); + + // We cannot have a non-transient module referencing to a transient module. + if (IsTransient() == false && isRefedModuleTransient) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadTransientModuleReference")); + } +#endif // !FEATURE_CORECLR + + String strRefedModuleFileName = String.Empty; + if (refedModule.Assembly.Equals(this.Assembly)) + { + // if the referenced module is in the same assembly, the resolution + // scope of the type token will be a module ref, we will need + // the file name of the referenced module for that. + // if the refed module is in a different assembly, the resolution + // scope of the type token will be an assembly ref. We don't need + // the file name of the referenced module. + if (refedModuleBuilder == null) + { + refedModuleBuilder = this.ContainingAssemblyBuilder.GetModuleBuilder((InternalModuleBuilder)refedModule); + } + strRefedModuleFileName = refedModuleBuilder.m_moduleData.m_strFileName; + } + + return new TypeToken(GetTypeRefNested(type, refedModule, strRefedModuleFileName)); + } + + public TypeToken GetTypeToken(String name) + { + // Return a token for the class relative to the Module. + // Module.GetType() verifies name + + // Unfortunately, we will need to load the Type and then call GetTypeToken in + // order to correctly track the assembly reference information. + + return GetTypeToken(InternalModule.GetType(name, false, true)); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public MethodToken GetMethodToken(MethodInfo method) + { + lock(SyncRoot) + { + return GetMethodTokenNoLock(method, true); + } + } + + [System.Security.SecurityCritical] // auto-generated + internal MethodToken GetMethodTokenInternal(MethodInfo method) + { + lock(SyncRoot) + { + return GetMethodTokenNoLock(method, false); + } + } + + // For a method on a generic type, we should return the methoddef token on the generic type definition in two cases + // 1. GetMethodToken + // 2. ldtoken (see ILGenerator) + // For all other occasions we should return the method on the generic type instantiated on the formal parameters. + [System.Security.SecurityCritical] // auto-generated + private MethodToken GetMethodTokenNoLock(MethodInfo method, bool getGenericTypeDefinition) + { + // Return a MemberRef token if MethodInfo is not defined in this module. Or + // return the MethodDef token. + if (method == null) + throw new ArgumentNullException("method"); + Contract.EndContractBlock(); + + int tr; + int mr = 0; + + SymbolMethod symMethod = null; + MethodBuilder methBuilder = null; + + if ( (methBuilder = method as MethodBuilder) != null ) + { + int methodToken = methBuilder.MetadataTokenInternal; + if (method.Module.Equals(this)) + return new MethodToken(methodToken); + + if (method.DeclaringType == null) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule")); + + // method is defined in a different module + tr = getGenericTypeDefinition ? GetTypeToken(method.DeclaringType).Token : GetTypeTokenInternal(method.DeclaringType).Token; + mr = GetMemberRef(method.DeclaringType.Module, tr, methodToken); + } + else if (method is MethodOnTypeBuilderInstantiation) + { + return new MethodToken(GetMemberRefToken(method, null)); + } + else if ((symMethod = method as SymbolMethod) != null) + { + if (symMethod.GetModule() == this) + return symMethod.GetToken(); + + // form the method token + return symMethod.GetToken(this); + } + else + { + Type declaringType = method.DeclaringType; + + // We need to get the TypeRef tokens + if (declaringType == null) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule")); + + RuntimeMethodInfo rtMeth = null; + + if (declaringType.IsArray == true) + { + // use reflection to build signature to work around the E_T_VAR problem in EEClass + ParameterInfo[] paramInfo = method.GetParameters(); + + Type[] tt = new Type[paramInfo.Length]; + + for (int i = 0; i < paramInfo.Length; i++) + tt[i] = paramInfo[i].ParameterType; + + return GetArrayMethodToken(declaringType, method.Name, method.CallingConvention, method.ReturnType, tt); + } + else if ( (rtMeth = method as RuntimeMethodInfo) != null ) + { + tr = getGenericTypeDefinition ? GetTypeToken(method.DeclaringType).Token : GetTypeTokenInternal(method.DeclaringType).Token; + mr = GetMemberRefOfMethodInfo(tr, rtMeth); + } + else + { + // some user derived ConstructorInfo + // go through the slower code path, i.e. retrieve parameters and form signature helper. + ParameterInfo[] parameters = method.GetParameters(); + + Type[] parameterTypes = new Type[parameters.Length]; + Type[][] requiredCustomModifiers = new Type[parameterTypes.Length][]; + Type[][] optionalCustomModifiers = new Type[parameterTypes.Length][]; + + for (int i = 0; i < parameters.Length; i++) + { + parameterTypes[i] = parameters[i].ParameterType; + requiredCustomModifiers[i] = parameters[i].GetRequiredCustomModifiers(); + optionalCustomModifiers[i] = parameters[i].GetOptionalCustomModifiers(); + } + + tr = getGenericTypeDefinition ? GetTypeToken(method.DeclaringType).Token : GetTypeTokenInternal(method.DeclaringType).Token; + + SignatureHelper sigHelp; + + try + { + sigHelp = SignatureHelper.GetMethodSigHelper( + this, method.CallingConvention, method.ReturnType, + method.ReturnParameter.GetRequiredCustomModifiers(), method.ReturnParameter.GetOptionalCustomModifiers(), + parameterTypes, requiredCustomModifiers, optionalCustomModifiers); + } + catch(NotImplementedException) + { + // Legacy code deriving from MethodInfo may not have implemented ReturnParameter. + sigHelp = SignatureHelper.GetMethodSigHelper(this, method.ReturnType, parameterTypes); + } + + int length; + byte[] sigBytes = sigHelp.InternalGetSignature(out length); + mr = GetMemberRefFromSignature(tr, method.Name, sigBytes, length); + } + } + + return new MethodToken(mr); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public MethodToken GetConstructorToken(ConstructorInfo constructor, IEnumerable optionalParameterTypes) + { + if (constructor == null) + { + throw new ArgumentNullException("constructor"); + } + + lock (SyncRoot) + { + // useMethodDef is not applicable - constructors aren't generic + return new MethodToken(GetMethodTokenInternal(constructor, optionalParameterTypes, false)); + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + public MethodToken GetMethodToken(MethodInfo method, IEnumerable optionalParameterTypes) + { + if (method == null) + { + throw new ArgumentNullException("method"); + } + + // useMethodDef flag only affects the result if we pass in a generic method definition. + // If the caller is looking for a token for an ldtoken/ldftn/ldvirtftn instruction and passes in a generic method definition info/builder, + // we correclty return the MethodDef/Ref token of the generic definition that can be used with ldtoken/ldftn/ldvirtftn. + // + // If the caller is looking for a token for a call/callvirt/jmp instruction and passes in a generic method definition info/builder, + // we also return the generic MethodDef/Ref token, which is indeed not acceptable for call/callvirt/jmp instruction. + // But the caller can always instantiate the info/builder and pass it in. Then we build the right MethodSpec. + + lock (SyncRoot) + { + return new MethodToken(GetMethodTokenInternal(method, optionalParameterTypes, true)); + } + } + + [System.Security.SecurityCritical] // auto-generated + internal int GetMethodTokenInternal(MethodBase method, IEnumerable optionalParameterTypes, bool useMethodDef) + { + int tk = 0; + MethodInfo methodInfo = method as MethodInfo; + + if (method.IsGenericMethod) + { + // Constructors cannot be generic. + Contract.Assert(methodInfo != null); + + // Given M unbind to M + MethodInfo methodInfoUnbound = methodInfo; + bool isGenericMethodDef = methodInfo.IsGenericMethodDefinition; + + if (!isGenericMethodDef) + { + methodInfoUnbound = methodInfo.GetGenericMethodDefinition(); + } + + if (!this.Equals(methodInfoUnbound.Module) + || (methodInfoUnbound.DeclaringType != null && methodInfoUnbound.DeclaringType.IsGenericType)) + { + tk = GetMemberRefToken(methodInfoUnbound, null); + } + else + { + tk = GetMethodTokenInternal(methodInfoUnbound).Token; + } + + // For Ldtoken, Ldftn, and Ldvirtftn, we should emit the method def/ref token for a generic method definition. + if (isGenericMethodDef && useMethodDef) + { + return tk; + } + + // Create signature of method instantiation M + int sigLength; + byte[] sigBytes = SignatureHelper.GetMethodSpecSigHelper( + this, methodInfo.GetGenericArguments()).InternalGetSignature(out sigLength); + + // Create MethodSepc M with parent G?.M + tk = TypeBuilder.DefineMethodSpec(this.GetNativeHandle(), tk, sigBytes, sigLength); + } + else + { + if (((method.CallingConvention & CallingConventions.VarArgs) == 0) && + (method.DeclaringType == null || !method.DeclaringType.IsGenericType)) + { + if (methodInfo != null) + { + tk = GetMethodTokenInternal(methodInfo).Token; + } + else + { + tk = GetConstructorToken(method as ConstructorInfo).Token; + } + } + else + { + tk = GetMemberRefToken(method, optionalParameterTypes); + } + } + + return tk; + } + + [System.Security.SecuritySafeCritical] // auto-generated + public MethodToken GetArrayMethodToken(Type arrayClass, String methodName, CallingConventions callingConvention, + Type returnType, Type[] parameterTypes) + { + lock(SyncRoot) + { + return GetArrayMethodTokenNoLock(arrayClass, methodName, callingConvention, returnType, parameterTypes); + } + } + + [System.Security.SecurityCritical] // auto-generated + private MethodToken GetArrayMethodTokenNoLock(Type arrayClass, String methodName, CallingConventions callingConvention, + Type returnType, Type[] parameterTypes) + { + if (arrayClass == null) + throw new ArgumentNullException("arrayClass"); + + if (methodName == null) + throw new ArgumentNullException("methodName"); + + if (methodName.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "methodName"); + + if (arrayClass.IsArray == false) + throw new ArgumentException(Environment.GetResourceString("Argument_HasToBeArrayClass")); + Contract.EndContractBlock(); + + CheckContext(returnType, arrayClass); + CheckContext(parameterTypes); + + // Return a token for the MethodInfo for a method on an Array. This is primarily + // used to get the LoadElementAddress method. + + int length; + + SignatureHelper sigHelp = SignatureHelper.GetMethodSigHelper( + this, callingConvention, returnType, null, null, parameterTypes, null, null); + + byte[] sigBytes = sigHelp.InternalGetSignature(out length); + + TypeToken typeSpec = GetTypeTokenInternal(arrayClass); + + return new MethodToken(GetArrayMethodToken(GetNativeHandle(), + typeSpec.Token, methodName, sigBytes, length)); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public MethodInfo GetArrayMethod(Type arrayClass, String methodName, CallingConventions callingConvention, + Type returnType, Type[] parameterTypes) + { + CheckContext(returnType, arrayClass); + CheckContext(parameterTypes); + + // GetArrayMethod is useful when you have an array of a type whose definition has not been completed and + // you want to access methods defined on Array. For example, you might define a type and want to define a + // method that takes an array of the type as a parameter. In order to access the elements of the array, + // you will need to call methods of the Array class. + + MethodToken token = GetArrayMethodToken(arrayClass, methodName, callingConvention, returnType, parameterTypes); + + return new SymbolMethod(this, token, arrayClass, methodName, callingConvention, returnType, parameterTypes); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [System.Runtime.InteropServices.ComVisible(true)] + public MethodToken GetConstructorToken(ConstructorInfo con) + { + // Return a token for the ConstructorInfo relative to the Module. + return InternalGetConstructorToken(con, false); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public FieldToken GetFieldToken(FieldInfo field) + { + lock(SyncRoot) + { + return GetFieldTokenNoLock(field); + } + } + + [System.Security.SecurityCritical] // auto-generated + private FieldToken GetFieldTokenNoLock(FieldInfo field) + { + if (field == null) { + throw new ArgumentNullException("con"); + } + Contract.EndContractBlock(); + + int tr; + int mr = 0; + + FieldBuilder fdBuilder = null; + RuntimeFieldInfo rtField = null; + FieldOnTypeBuilderInstantiation fOnTB = null; + + if ((fdBuilder = field as FieldBuilder) != null) + { + if (field.DeclaringType != null && field.DeclaringType.IsGenericType) + { + int length; + byte[] sig = SignatureHelper.GetTypeSigToken(this, field.DeclaringType).InternalGetSignature(out length); + tr = GetTokenFromTypeSpec(sig, length); + mr = GetMemberRef(this, tr, fdBuilder.GetToken().Token); + } + else if (fdBuilder.Module.Equals(this)) + { + // field is defined in the same module + return fdBuilder.GetToken(); + } + else + { + // field is defined in a different module + if (field.DeclaringType == null) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule")); + } + tr = GetTypeTokenInternal(field.DeclaringType).Token; + mr = GetMemberRef(field.ReflectedType.Module, tr, fdBuilder.GetToken().Token); + } + } + else if ( (rtField = field as RuntimeFieldInfo) != null) + { + // FieldInfo is not an dynamic field + + // We need to get the TypeRef tokens + if (field.DeclaringType == null) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_CannotImportGlobalFromDifferentModule")); + } + + if (field.DeclaringType != null && field.DeclaringType.IsGenericType) + { + int length; + byte[] sig = SignatureHelper.GetTypeSigToken(this, field.DeclaringType).InternalGetSignature(out length); + tr = GetTokenFromTypeSpec(sig, length); + mr = GetMemberRefOfFieldInfo(tr, field.DeclaringType.GetTypeHandleInternal(), rtField); + } + else + { + tr = GetTypeTokenInternal(field.DeclaringType).Token; + mr = GetMemberRefOfFieldInfo(tr, field.DeclaringType.GetTypeHandleInternal(), rtField); + } + } + else if ( (fOnTB = field as FieldOnTypeBuilderInstantiation) != null) + { + FieldInfo fb = fOnTB.FieldInfo; + int length; + byte[] sig = SignatureHelper.GetTypeSigToken(this, field.DeclaringType).InternalGetSignature(out length); + tr = GetTokenFromTypeSpec(sig, length); + mr = GetMemberRef(fb.ReflectedType.Module, tr, fOnTB.MetadataTokenInternal); + } + else + { + // user defined FieldInfo + tr = GetTypeTokenInternal(field.ReflectedType).Token; + + SignatureHelper sigHelp = SignatureHelper.GetFieldSigHelper(this); + + sigHelp.AddArgument(field.FieldType, field.GetRequiredCustomModifiers(), field.GetOptionalCustomModifiers()); + + int length; + byte[] sigBytes = sigHelp.InternalGetSignature(out length); + + mr = GetMemberRefFromSignature(tr, field.Name, sigBytes, length); + } + + return new FieldToken(mr, field.GetType()); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public StringToken GetStringConstant(String str) + { + if (str == null) + { + throw new ArgumentNullException("str"); + } + Contract.EndContractBlock(); + + // Returns a token representing a String constant. If the string + // value has already been defined, the existing token will be returned. + return new StringToken(GetStringConstant(GetNativeHandle(), str, str.Length)); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public SignatureToken GetSignatureToken(SignatureHelper sigHelper) + { + // Define signature token given a signature helper. This will define a metadata + // token for the signature described by SignatureHelper. + + if (sigHelper == null) + { + throw new ArgumentNullException("sigHelper"); + } + Contract.EndContractBlock(); + + int sigLength; + byte[] sigBytes; + + // get the signature in byte form + sigBytes = sigHelper.InternalGetSignature(out sigLength); + return new SignatureToken(TypeBuilder.GetTokenFromSig(GetNativeHandle(), sigBytes, sigLength), this); + } + [System.Security.SecuritySafeCritical] // auto-generated + public SignatureToken GetSignatureToken(byte[] sigBytes, int sigLength) + { + if (sigBytes == null) + throw new ArgumentNullException("sigBytes"); + Contract.EndContractBlock(); + + byte[] localSigBytes = new byte[sigBytes.Length]; + Buffer.BlockCopy(sigBytes, 0, localSigBytes, 0, sigBytes.Length); + + return new SignatureToken(TypeBuilder.GetTokenFromSig(GetNativeHandle(), localSigBytes, sigLength), this); + } + + #endregion + + #region Other + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + [System.Runtime.InteropServices.ComVisible(true)] + public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + { + if (con == null) + throw new ArgumentNullException("con"); + if (binaryAttribute == null) + throw new ArgumentNullException("binaryAttribute"); + Contract.EndContractBlock(); + + TypeBuilder.DefineCustomAttribute( + this, + 1, // This is hard coding the module token to 1 + this.GetConstructorToken(con).Token, + binaryAttribute, + false, false); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void SetCustomAttribute(CustomAttributeBuilder customBuilder) + { + if (customBuilder == null) + { + throw new ArgumentNullException("customBuilder"); + } + Contract.EndContractBlock(); + + customBuilder.CreateCustomAttribute(this, 1); // This is hard coding the module token to 1 + } + + // This API returns the symbol writer being used to write debug symbols for this + // module (if any). + // + // WARNING: It is unlikely this API can be used correctly by applications in any + // reasonable way. It may be called internally from within TypeBuilder.CreateType. + // + // Specifically: + // 1. The underlying symbol writer (written in unmanaged code) is not necessarily well + // hardenned and fuzz-tested against malicious API calls. The security of partial-trust + // symbol writing is improved by restricting usage of the writer APIs to the well-structured + // uses in ModuleBuilder. + // 2. TypeBuilder.CreateType emits all the symbols for the type. This will effectively + // overwrite anything someone may have written manually about the type (specifically + // ISymbolWriter.OpenMethod is specced to clear anything previously written for the + // specified method) + // 3. Someone could technically update the symbols for a method after CreateType is + // called, but the debugger (which uses these symbols) assumes that they are only + // updated at TypeBuilder.CreateType time. The changes wouldn't be visible (committed + // to the underlying stream) until another type was baked. + // 4. Access to the writer is supposed to be synchronized (the underlying COM API is + // not thread safe, and these are only thin wrappers on top of them). Exposing this + // directly allows the synchronization to be violated. We know that concurrent symbol + // writer access can cause AVs and other problems. The writer APIs should not be callable + // directly by partial-trust code, but if they could this would be a security hole. + // Regardless, this is a reliability bug. + // + // For these reasons, we should consider making this API internal in Arrowhead + // (as it is in Silverlight), and consider validating that we're within a call + // to TypeBuilder.CreateType whenever this is used. + public ISymbolWriter GetSymWriter() + { + return m_iSymWriter; + } + +#if FEATURE_CORECLR + [System.Security.SecuritySafeCritical] +#endif + public ISymbolDocumentWriter DefineDocument(String url, Guid language, Guid languageVendor, Guid documentType) + { + // url cannot be null but can be an empty string + if (url == null) + throw new ArgumentNullException("url"); + Contract.EndContractBlock(); + + lock(SyncRoot) + { + return DefineDocumentNoLock(url, language, languageVendor, documentType); + } + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + private ISymbolDocumentWriter DefineDocumentNoLock(String url, Guid language, Guid languageVendor, Guid documentType) + { + if (m_iSymWriter == null) + { + // Cannot DefineDocument when it is not a debug module + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule")); + } + + return m_iSymWriter.DefineDocument(url, language, languageVendor, documentType); + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public void SetUserEntryPoint(MethodInfo entryPoint) + { + lock(SyncRoot) + { + SetUserEntryPointNoLock(entryPoint); + } + } + + [System.Security.SecurityCritical] // auto-generated + private void SetUserEntryPointNoLock(MethodInfo entryPoint) + { + // Set the user entry point. Compiler may generate startup stub before calling user main. + // The startup stub will be the entry point. While the user "main" will be the user entry + // point so that debugger will not step into the compiler entry point. + + if (entryPoint == null) + { + throw new ArgumentNullException("entryPoint"); + } + Contract.EndContractBlock(); + + if (m_iSymWriter == null) + { + // Cannot set entry point when it is not a debug module + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule")); + } + + if (entryPoint.DeclaringType != null) + { + if (!entryPoint.Module.Equals(this)) + { + // you cannot pass in a MethodInfo that is not contained by this ModuleBuilder + throw new InvalidOperationException(Environment.GetResourceString("Argument_NotInTheSameModuleBuilder")); + } + } + else + { + // unfortunately this check is missing for global function passed in as RuntimeMethodInfo. + // The problem is that Reflection does not + // allow us to get the containing module giving a global function + MethodBuilder mb = entryPoint as MethodBuilder; + if (mb != null && mb.GetModuleBuilder() != this) + { + // you cannot pass in a MethodInfo that is not contained by this ModuleBuilder + throw new InvalidOperationException(Environment.GetResourceString("Argument_NotInTheSameModuleBuilder")); + } + } + + // get the metadata token value and create the SymbolStore's token value class + SymbolToken tkMethod = new SymbolToken(GetMethodTokenInternal(entryPoint).Token); + + // set the UserEntryPoint + m_iSymWriter.SetUserEntryPoint(tkMethod); + } + + public void SetSymCustomAttribute(String name, byte[] data) + { + lock(SyncRoot) + { + SetSymCustomAttributeNoLock(name, data); + } + } + + private void SetSymCustomAttributeNoLock(String name, byte[] data) + { + if (m_iSymWriter == null) + { + // Cannot SetSymCustomAttribute when it is not a debug module + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotADebugModule")); + } + + // This API has never worked. It seems like we might want to call m_iSymWriter.SetSymAttribute, + // but we don't have a metadata token to associate the attribute with. Instead + // MethodBuilder.SetSymCustomAttribute could be used to associate a symbol attribute with a specific method. + } + + [Pure] + public bool IsTransient() + { + return InternalModule.IsTransientInternal(); + } + + #endregion + + #endregion + +#if !FEATURE_CORECLR + void _ModuleBuilder.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _ModuleBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _ModuleBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _ModuleBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs new file mode 100644 index 0000000000..2bec04abe5 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/ModuleBuilderData.cs @@ -0,0 +1,104 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// + +namespace System.Reflection.Emit +{ + using System; + using System.Diagnostics.Contracts; + using System.Globalization; + using System.IO; + using System.Reflection; + using System.Runtime.Versioning; + + // This is a package private class. This class hold all of the managed + // data member for ModuleBuilder. Note that what ever data members added to + // this class cannot be accessed from the EE. + [Serializable] + internal class ModuleBuilderData + { + [System.Security.SecurityCritical] // auto-generated + internal ModuleBuilderData(ModuleBuilder module, String strModuleName, String strFileName, int tkFile) + { + m_globalTypeBuilder = new TypeBuilder(module); + m_module = module; + m_tkFile = tkFile; + + InitNames(strModuleName, strFileName); + } + + // Initialize module and file names. + [System.Security.SecurityCritical] // auto-generated + private void InitNames(String strModuleName, String strFileName) + { + m_strModuleName = strModuleName; + if (strFileName == null) + { + // fake a transient module file name + m_strFileName = strModuleName; + } + else + { + String strExtension = Path.GetExtension(strFileName); + if (strExtension == null || strExtension == String.Empty) + { + // This is required by our loader. It cannot load module file that does not have file extension. + throw new ArgumentException(Environment.GetResourceString("Argument_NoModuleFileExtension", strFileName)); + } + m_strFileName = strFileName; + } + } + + // This is a method for changing module and file name of the manifest module (created by default for + // each assembly). + [System.Security.SecurityCritical] // auto-generated + internal virtual void ModifyModuleName(String strModuleName) + { + Contract.Assert(m_strModuleName == AssemblyBuilder.MANIFEST_MODULE_NAME, "Changing names for non-manifest module"); + InitNames(strModuleName, null /*strFileName*/); + } + + internal int FileToken + { + get + { + // Before save, the scope of m_tkFile is the in-memory assembly manifest + // During save, the scope of m_tkFile is the on-disk assembly manifest + // For transient modules m_tkFile never change. + + // Theoretically no one should emit anything after a dynamic assembly has + // been saved. So m_tkFile shouldn't used when m_isSaved is true. + // But that was never completely enforced: you can still emit everything after + // the assembly has been saved (except for public types in persistent modules). + + return m_tkFile; + } + + set + { + m_tkFile = value; + } + } + + internal String m_strModuleName; // scope name (can be different from file name) + 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; + internal bool m_isSaved; + [NonSerialized] + internal ResWriterData m_embeddedRes; + 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/OpCodes.cs b/src/mscorlib/src/System/Reflection/Emit/OpCodes.cs new file mode 100644 index 0000000000..345694ec80 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/OpCodes.cs @@ -0,0 +1,2552 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. +/*============================================================ +** +** +** +** +**Purpose: Exposes all of the il instructions supported by the runtime. +** +** +============================================================*/ +namespace System.Reflection.Emit { + +using System; +using System.Security.Permissions; + +// +// Internal enums for opcode values. Note that the value names are used to construct +// publicly visible ilasm-compatible opcode names, so their exact form is important! +// +internal enum OpCodeValues { + Nop = 0x00, + Break = 0x01, + Ldarg_0 = 0x02, + Ldarg_1 = 0x03, + Ldarg_2 = 0x04, + Ldarg_3 = 0x05, + Ldloc_0 = 0x06, + Ldloc_1 = 0x07, + Ldloc_2 = 0x08, + Ldloc_3 = 0x09, + Stloc_0 = 0x0a, + Stloc_1 = 0x0b, + Stloc_2 = 0x0c, + Stloc_3 = 0x0d, + Ldarg_S = 0x0e, + Ldarga_S = 0x0f, + Starg_S = 0x10, + Ldloc_S = 0x11, + Ldloca_S = 0x12, + Stloc_S = 0x13, + Ldnull = 0x14, + Ldc_I4_M1 = 0x15, + Ldc_I4_0 = 0x16, + Ldc_I4_1 = 0x17, + Ldc_I4_2 = 0x18, + Ldc_I4_3 = 0x19, + Ldc_I4_4 = 0x1a, + Ldc_I4_5 = 0x1b, + Ldc_I4_6 = 0x1c, + Ldc_I4_7 = 0x1d, + Ldc_I4_8 = 0x1e, + Ldc_I4_S = 0x1f, + Ldc_I4 = 0x20, + Ldc_I8 = 0x21, + Ldc_R4 = 0x22, + Ldc_R8 = 0x23, + Dup = 0x25, + Pop = 0x26, + Jmp = 0x27, + Call = 0x28, + Calli = 0x29, + Ret = 0x2a, + Br_S = 0x2b, + Brfalse_S = 0x2c, + Brtrue_S = 0x2d, + Beq_S = 0x2e, + Bge_S = 0x2f, + Bgt_S = 0x30, + Ble_S = 0x31, + Blt_S = 0x32, + Bne_Un_S = 0x33, + Bge_Un_S = 0x34, + Bgt_Un_S = 0x35, + Ble_Un_S = 0x36, + Blt_Un_S = 0x37, + Br = 0x38, + Brfalse = 0x39, + Brtrue = 0x3a, + Beq = 0x3b, + Bge = 0x3c, + Bgt = 0x3d, + Ble = 0x3e, + Blt = 0x3f, + Bne_Un = 0x40, + Bge_Un = 0x41, + Bgt_Un = 0x42, + Ble_Un = 0x43, + Blt_Un = 0x44, + Switch = 0x45, + Ldind_I1 = 0x46, + Ldind_U1 = 0x47, + Ldind_I2 = 0x48, + Ldind_U2 = 0x49, + Ldind_I4 = 0x4a, + Ldind_U4 = 0x4b, + Ldind_I8 = 0x4c, + Ldind_I = 0x4d, + Ldind_R4 = 0x4e, + Ldind_R8 = 0x4f, + Ldind_Ref = 0x50, + Stind_Ref = 0x51, + Stind_I1 = 0x52, + Stind_I2 = 0x53, + Stind_I4 = 0x54, + Stind_I8 = 0x55, + Stind_R4 = 0x56, + Stind_R8 = 0x57, + Add = 0x58, + Sub = 0x59, + Mul = 0x5a, + Div = 0x5b, + Div_Un = 0x5c, + Rem = 0x5d, + Rem_Un = 0x5e, + And = 0x5f, + Or = 0x60, + Xor = 0x61, + Shl = 0x62, + Shr = 0x63, + Shr_Un = 0x64, + Neg = 0x65, + Not = 0x66, + Conv_I1 = 0x67, + Conv_I2 = 0x68, + Conv_I4 = 0x69, + Conv_I8 = 0x6a, + Conv_R4 = 0x6b, + Conv_R8 = 0x6c, + Conv_U4 = 0x6d, + Conv_U8 = 0x6e, + Callvirt = 0x6f, + Cpobj = 0x70, + Ldobj = 0x71, + Ldstr = 0x72, + Newobj = 0x73, + Castclass = 0x74, + Isinst = 0x75, + Conv_R_Un = 0x76, + Unbox = 0x79, + Throw = 0x7a, + Ldfld = 0x7b, + Ldflda = 0x7c, + Stfld = 0x7d, + Ldsfld = 0x7e, + Ldsflda = 0x7f, + Stsfld = 0x80, + Stobj = 0x81, + Conv_Ovf_I1_Un = 0x82, + Conv_Ovf_I2_Un = 0x83, + Conv_Ovf_I4_Un = 0x84, + Conv_Ovf_I8_Un = 0x85, + Conv_Ovf_U1_Un = 0x86, + Conv_Ovf_U2_Un = 0x87, + Conv_Ovf_U4_Un = 0x88, + Conv_Ovf_U8_Un = 0x89, + Conv_Ovf_I_Un = 0x8a, + Conv_Ovf_U_Un = 0x8b, + Box = 0x8c, + Newarr = 0x8d, + Ldlen = 0x8e, + Ldelema = 0x8f, + Ldelem_I1 = 0x90, + Ldelem_U1 = 0x91, + Ldelem_I2 = 0x92, + Ldelem_U2 = 0x93, + Ldelem_I4 = 0x94, + Ldelem_U4 = 0x95, + Ldelem_I8 = 0x96, + Ldelem_I = 0x97, + Ldelem_R4 = 0x98, + Ldelem_R8 = 0x99, + Ldelem_Ref = 0x9a, + Stelem_I = 0x9b, + Stelem_I1 = 0x9c, + Stelem_I2 = 0x9d, + Stelem_I4 = 0x9e, + Stelem_I8 = 0x9f, + Stelem_R4 = 0xa0, + Stelem_R8 = 0xa1, + Stelem_Ref = 0xa2, + Ldelem = 0xa3, + Stelem = 0xa4, + Unbox_Any = 0xa5, + Conv_Ovf_I1 = 0xb3, + Conv_Ovf_U1 = 0xb4, + Conv_Ovf_I2 = 0xb5, + Conv_Ovf_U2 = 0xb6, + Conv_Ovf_I4 = 0xb7, + Conv_Ovf_U4 = 0xb8, + Conv_Ovf_I8 = 0xb9, + Conv_Ovf_U8 = 0xba, + Refanyval = 0xc2, + Ckfinite = 0xc3, + Mkrefany = 0xc6, + Ldtoken = 0xd0, + Conv_U2 = 0xd1, + Conv_U1 = 0xd2, + Conv_I = 0xd3, + Conv_Ovf_I = 0xd4, + Conv_Ovf_U = 0xd5, + Add_Ovf = 0xd6, + Add_Ovf_Un = 0xd7, + Mul_Ovf = 0xd8, + Mul_Ovf_Un = 0xd9, + Sub_Ovf = 0xda, + Sub_Ovf_Un = 0xdb, + Endfinally = 0xdc, + Leave = 0xdd, + Leave_S = 0xde, + Stind_I = 0xdf, + Conv_U = 0xe0, + Prefix7 = 0xf8, + Prefix6 = 0xf9, + Prefix5 = 0xfa, + Prefix4 = 0xfb, + Prefix3 = 0xfc, + Prefix2 = 0xfd, + Prefix1 = 0xfe, + Prefixref = 0xff, + Arglist = 0xfe00, + Ceq = 0xfe01, + Cgt = 0xfe02, + Cgt_Un = 0xfe03, + Clt = 0xfe04, + Clt_Un = 0xfe05, + Ldftn = 0xfe06, + Ldvirtftn = 0xfe07, + Ldarg = 0xfe09, + Ldarga = 0xfe0a, + Starg = 0xfe0b, + Ldloc = 0xfe0c, + Ldloca = 0xfe0d, + Stloc = 0xfe0e, + Localloc = 0xfe0f, + Endfilter = 0xfe11, + Unaligned_ = 0xfe12, + Volatile_ = 0xfe13, + Tail_ = 0xfe14, + Initobj = 0xfe15, + Constrained_ = 0xfe16, + Cpblk = 0xfe17, + Initblk = 0xfe18, + Rethrow = 0xfe1a, + Sizeof = 0xfe1c, + Refanytype = 0xfe1d, + Readonly_ = 0xfe1e, + + // If you add more opcodes here, modify OpCode.Name to handle them correctly +}; + +[System.Runtime.InteropServices.ComVisible(true)] +public class OpCodes { + +/// +/// +/// The IL instruction opcodes supported by the +/// runtime. The IL Instruction Specification describes each +/// Opcode. +/// +/// +/// + + private OpCodes() { + } + + public static readonly OpCode Nop = new OpCode(OpCodeValues.Nop, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Break = new OpCode(OpCodeValues.Break, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Break << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldarg_0 = new OpCode(OpCodeValues.Ldarg_0, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldarg_1 = new OpCode(OpCodeValues.Ldarg_1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldarg_2 = new OpCode(OpCodeValues.Ldarg_2, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldarg_3 = new OpCode(OpCodeValues.Ldarg_3, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldloc_0 = new OpCode(OpCodeValues.Ldloc_0, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldloc_1 = new OpCode(OpCodeValues.Ldloc_1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldloc_2 = new OpCode(OpCodeValues.Ldloc_2, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldloc_3 = new OpCode(OpCodeValues.Ldloc_3, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stloc_0 = new OpCode(OpCodeValues.Stloc_0, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stloc_1 = new OpCode(OpCodeValues.Stloc_1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stloc_2 = new OpCode(OpCodeValues.Stloc_2, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stloc_3 = new OpCode(OpCodeValues.Stloc_3, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldarg_S = new OpCode(OpCodeValues.Ldarg_S, + ((int)OperandType.ShortInlineVar) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldarga_S = new OpCode(OpCodeValues.Ldarga_S, + ((int)OperandType.ShortInlineVar) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Starg_S = new OpCode(OpCodeValues.Starg_S, + ((int)OperandType.ShortInlineVar) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldloc_S = new OpCode(OpCodeValues.Ldloc_S, + ((int)OperandType.ShortInlineVar) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldloca_S = new OpCode(OpCodeValues.Ldloca_S, + ((int)OperandType.ShortInlineVar) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stloc_S = new OpCode(OpCodeValues.Stloc_S, + ((int)OperandType.ShortInlineVar) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldnull = new OpCode(OpCodeValues.Ldnull, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldc_I4_M1 = new OpCode(OpCodeValues.Ldc_I4_M1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldc_I4_0 = new OpCode(OpCodeValues.Ldc_I4_0, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldc_I4_1 = new OpCode(OpCodeValues.Ldc_I4_1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldc_I4_2 = new OpCode(OpCodeValues.Ldc_I4_2, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldc_I4_3 = new OpCode(OpCodeValues.Ldc_I4_3, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldc_I4_4 = new OpCode(OpCodeValues.Ldc_I4_4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldc_I4_5 = new OpCode(OpCodeValues.Ldc_I4_5, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldc_I4_6 = new OpCode(OpCodeValues.Ldc_I4_6, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldc_I4_7 = new OpCode(OpCodeValues.Ldc_I4_7, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldc_I4_8 = new OpCode(OpCodeValues.Ldc_I4_8, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldc_I4_S = new OpCode(OpCodeValues.Ldc_I4_S, + ((int)OperandType.ShortInlineI) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldc_I4 = new OpCode(OpCodeValues.Ldc_I4, + ((int)OperandType.InlineI) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldc_I8 = new OpCode(OpCodeValues.Ldc_I8, + ((int)OperandType.InlineI8) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldc_R4 = new OpCode(OpCodeValues.Ldc_R4, + ((int)OperandType.ShortInlineR) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushr4 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldc_R8 = new OpCode(OpCodeValues.Ldc_R8, + ((int)OperandType.InlineR) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Dup = new OpCode(OpCodeValues.Dup, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1_push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Pop = new OpCode(OpCodeValues.Pop, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Jmp = new OpCode(OpCodeValues.Jmp, + ((int)OperandType.InlineMethod) | + ((int)FlowControl.Call << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + OpCode.EndsUncondJmpBlkFlag | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Call = new OpCode(OpCodeValues.Call, + ((int)OperandType.InlineMethod) | + ((int)FlowControl.Call << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Varpop << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Varpush << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Calli = new OpCode(OpCodeValues.Calli, + ((int)OperandType.InlineSig) | + ((int)FlowControl.Call << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Varpop << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Varpush << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ret = new OpCode(OpCodeValues.Ret, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Return << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Varpop << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + OpCode.EndsUncondJmpBlkFlag | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Br_S = new OpCode(OpCodeValues.Br_S, + ((int)OperandType.ShortInlineBrTarget) | + ((int)FlowControl.Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + OpCode.EndsUncondJmpBlkFlag | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Brfalse_S = new OpCode(OpCodeValues.Brfalse_S, + ((int)OperandType.ShortInlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Brtrue_S = new OpCode(OpCodeValues.Brtrue_S, + ((int)OperandType.ShortInlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Beq_S = new OpCode(OpCodeValues.Beq_S, + ((int)OperandType.ShortInlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Bge_S = new OpCode(OpCodeValues.Bge_S, + ((int)OperandType.ShortInlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Bgt_S = new OpCode(OpCodeValues.Bgt_S, + ((int)OperandType.ShortInlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ble_S = new OpCode(OpCodeValues.Ble_S, + ((int)OperandType.ShortInlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Blt_S = new OpCode(OpCodeValues.Blt_S, + ((int)OperandType.ShortInlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Bne_Un_S = new OpCode(OpCodeValues.Bne_Un_S, + ((int)OperandType.ShortInlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Bge_Un_S = new OpCode(OpCodeValues.Bge_Un_S, + ((int)OperandType.ShortInlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Bgt_Un_S = new OpCode(OpCodeValues.Bgt_Un_S, + ((int)OperandType.ShortInlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ble_Un_S = new OpCode(OpCodeValues.Ble_Un_S, + ((int)OperandType.ShortInlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Blt_Un_S = new OpCode(OpCodeValues.Blt_Un_S, + ((int)OperandType.ShortInlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Br = new OpCode(OpCodeValues.Br, + ((int)OperandType.InlineBrTarget) | + ((int)FlowControl.Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + OpCode.EndsUncondJmpBlkFlag | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Brfalse = new OpCode(OpCodeValues.Brfalse, + ((int)OperandType.InlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Brtrue = new OpCode(OpCodeValues.Brtrue, + ((int)OperandType.InlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Beq = new OpCode(OpCodeValues.Beq, + ((int)OperandType.InlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Bge = new OpCode(OpCodeValues.Bge, + ((int)OperandType.InlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Bgt = new OpCode(OpCodeValues.Bgt, + ((int)OperandType.InlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ble = new OpCode(OpCodeValues.Ble, + ((int)OperandType.InlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Blt = new OpCode(OpCodeValues.Blt, + ((int)OperandType.InlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Bne_Un = new OpCode(OpCodeValues.Bne_Un, + ((int)OperandType.InlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Bge_Un = new OpCode(OpCodeValues.Bge_Un, + ((int)OperandType.InlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Bgt_Un = new OpCode(OpCodeValues.Bgt_Un, + ((int)OperandType.InlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ble_Un = new OpCode(OpCodeValues.Ble_Un, + ((int)OperandType.InlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Blt_Un = new OpCode(OpCodeValues.Blt_Un, + ((int)OperandType.InlineBrTarget) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Macro << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Switch = new OpCode(OpCodeValues.Switch, + ((int)OperandType.InlineSwitch) | + ((int)FlowControl.Cond_Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldind_I1 = new OpCode(OpCodeValues.Ldind_I1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldind_U1 = new OpCode(OpCodeValues.Ldind_U1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldind_I2 = new OpCode(OpCodeValues.Ldind_I2, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldind_U2 = new OpCode(OpCodeValues.Ldind_U2, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldind_I4 = new OpCode(OpCodeValues.Ldind_I4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldind_U4 = new OpCode(OpCodeValues.Ldind_U4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldind_I8 = new OpCode(OpCodeValues.Ldind_I8, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldind_I = new OpCode(OpCodeValues.Ldind_I, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldind_R4 = new OpCode(OpCodeValues.Ldind_R4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushr4 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldind_R8 = new OpCode(OpCodeValues.Ldind_R8, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldind_Ref = new OpCode(OpCodeValues.Ldind_Ref, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stind_Ref = new OpCode(OpCodeValues.Stind_Ref, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stind_I1 = new OpCode(OpCodeValues.Stind_I1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stind_I2 = new OpCode(OpCodeValues.Stind_I2, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stind_I4 = new OpCode(OpCodeValues.Stind_I4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stind_I8 = new OpCode(OpCodeValues.Stind_I8, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi_popi8 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stind_R4 = new OpCode(OpCodeValues.Stind_R4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi_popr4 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stind_R8 = new OpCode(OpCodeValues.Stind_R8, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi_popr8 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Add = new OpCode(OpCodeValues.Add, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Sub = new OpCode(OpCodeValues.Sub, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Mul = new OpCode(OpCodeValues.Mul, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Div = new OpCode(OpCodeValues.Div, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Div_Un = new OpCode(OpCodeValues.Div_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Rem = new OpCode(OpCodeValues.Rem, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Rem_Un = new OpCode(OpCodeValues.Rem_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode And = new OpCode(OpCodeValues.And, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Or = new OpCode(OpCodeValues.Or, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Xor = new OpCode(OpCodeValues.Xor, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Shl = new OpCode(OpCodeValues.Shl, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Shr = new OpCode(OpCodeValues.Shr, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Shr_Un = new OpCode(OpCodeValues.Shr_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Neg = new OpCode(OpCodeValues.Neg, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Not = new OpCode(OpCodeValues.Not, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_I1 = new OpCode(OpCodeValues.Conv_I1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_I2 = new OpCode(OpCodeValues.Conv_I2, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_I4 = new OpCode(OpCodeValues.Conv_I4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_I8 = new OpCode(OpCodeValues.Conv_I8, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_R4 = new OpCode(OpCodeValues.Conv_R4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushr4 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_R8 = new OpCode(OpCodeValues.Conv_R8, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_U4 = new OpCode(OpCodeValues.Conv_U4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_U8 = new OpCode(OpCodeValues.Conv_U8, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Callvirt = new OpCode(OpCodeValues.Callvirt, + ((int)OperandType.InlineMethod) | + ((int)FlowControl.Call << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Varpop << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Varpush << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Cpobj = new OpCode(OpCodeValues.Cpobj, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldobj = new OpCode(OpCodeValues.Ldobj, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldstr = new OpCode(OpCodeValues.Ldstr, + ((int)OperandType.InlineString) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Newobj = new OpCode(OpCodeValues.Newobj, + ((int)OperandType.InlineMethod) | + ((int)FlowControl.Call << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Varpop << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + [System.Runtime.InteropServices.ComVisible(true)] + public static readonly OpCode Castclass = new OpCode(OpCodeValues.Castclass, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Isinst = new OpCode(OpCodeValues.Isinst, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_R_Un = new OpCode(OpCodeValues.Conv_R_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Unbox = new OpCode(OpCodeValues.Unbox, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Throw = new OpCode(OpCodeValues.Throw, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Throw << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + OpCode.EndsUncondJmpBlkFlag | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldfld = new OpCode(OpCodeValues.Ldfld, + ((int)OperandType.InlineField) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldflda = new OpCode(OpCodeValues.Ldflda, + ((int)OperandType.InlineField) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stfld = new OpCode(OpCodeValues.Stfld, + ((int)OperandType.InlineField) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldsfld = new OpCode(OpCodeValues.Ldsfld, + ((int)OperandType.InlineField) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldsflda = new OpCode(OpCodeValues.Ldsflda, + ((int)OperandType.InlineField) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stsfld = new OpCode(OpCodeValues.Stsfld, + ((int)OperandType.InlineField) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stobj = new OpCode(OpCodeValues.Stobj, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_I1_Un = new OpCode(OpCodeValues.Conv_Ovf_I1_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_I2_Un = new OpCode(OpCodeValues.Conv_Ovf_I2_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_I4_Un = new OpCode(OpCodeValues.Conv_Ovf_I4_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_I8_Un = new OpCode(OpCodeValues.Conv_Ovf_I8_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_U1_Un = new OpCode(OpCodeValues.Conv_Ovf_U1_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_U2_Un = new OpCode(OpCodeValues.Conv_Ovf_U2_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_U4_Un = new OpCode(OpCodeValues.Conv_Ovf_U4_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_U8_Un = new OpCode(OpCodeValues.Conv_Ovf_U8_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_I_Un = new OpCode(OpCodeValues.Conv_Ovf_I_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_U_Un = new OpCode(OpCodeValues.Conv_Ovf_U_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Box = new OpCode(OpCodeValues.Box, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Newarr = new OpCode(OpCodeValues.Newarr, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldlen = new OpCode(OpCodeValues.Ldlen, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldelema = new OpCode(OpCodeValues.Ldelema, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldelem_I1 = new OpCode(OpCodeValues.Ldelem_I1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldelem_U1 = new OpCode(OpCodeValues.Ldelem_U1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldelem_I2 = new OpCode(OpCodeValues.Ldelem_I2, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldelem_U2 = new OpCode(OpCodeValues.Ldelem_U2, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldelem_I4 = new OpCode(OpCodeValues.Ldelem_I4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldelem_U4 = new OpCode(OpCodeValues.Ldelem_U4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldelem_I8 = new OpCode(OpCodeValues.Ldelem_I8, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldelem_I = new OpCode(OpCodeValues.Ldelem_I, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldelem_R4 = new OpCode(OpCodeValues.Ldelem_R4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushr4 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldelem_R8 = new OpCode(OpCodeValues.Ldelem_R8, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldelem_Ref = new OpCode(OpCodeValues.Ldelem_Ref, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushref << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stelem_I = new OpCode(OpCodeValues.Stelem_I, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-3 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stelem_I1 = new OpCode(OpCodeValues.Stelem_I1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-3 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stelem_I2 = new OpCode(OpCodeValues.Stelem_I2, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-3 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stelem_I4 = new OpCode(OpCodeValues.Stelem_I4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-3 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stelem_I8 = new OpCode(OpCodeValues.Stelem_I8, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi_popi8 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-3 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stelem_R4 = new OpCode(OpCodeValues.Stelem_R4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi_popr4 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-3 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stelem_R8 = new OpCode(OpCodeValues.Stelem_R8, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi_popr8 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-3 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stelem_Ref = new OpCode(OpCodeValues.Stelem_Ref, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi_popref << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-3 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldelem = new OpCode(OpCodeValues.Ldelem, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stelem = new OpCode(OpCodeValues.Stelem, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref_popi_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Unbox_Any = new OpCode(OpCodeValues.Unbox_Any, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_I1 = new OpCode(OpCodeValues.Conv_Ovf_I1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_U1 = new OpCode(OpCodeValues.Conv_Ovf_U1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_I2 = new OpCode(OpCodeValues.Conv_Ovf_I2, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_U2 = new OpCode(OpCodeValues.Conv_Ovf_U2, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_I4 = new OpCode(OpCodeValues.Conv_Ovf_I4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_U4 = new OpCode(OpCodeValues.Conv_Ovf_U4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_I8 = new OpCode(OpCodeValues.Conv_Ovf_I8, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_U8 = new OpCode(OpCodeValues.Conv_Ovf_U8, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi8 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Refanyval = new OpCode(OpCodeValues.Refanyval, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ckfinite = new OpCode(OpCodeValues.Ckfinite, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushr8 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Mkrefany = new OpCode(OpCodeValues.Mkrefany, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldtoken = new OpCode(OpCodeValues.Ldtoken, + ((int)OperandType.InlineTok) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_U2 = new OpCode(OpCodeValues.Conv_U2, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_U1 = new OpCode(OpCodeValues.Conv_U1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_I = new OpCode(OpCodeValues.Conv_I, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_I = new OpCode(OpCodeValues.Conv_Ovf_I, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_Ovf_U = new OpCode(OpCodeValues.Conv_Ovf_U, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Add_Ovf = new OpCode(OpCodeValues.Add_Ovf, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Add_Ovf_Un = new OpCode(OpCodeValues.Add_Ovf_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Mul_Ovf = new OpCode(OpCodeValues.Mul_Ovf, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Mul_Ovf_Un = new OpCode(OpCodeValues.Mul_Ovf_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Sub_Ovf = new OpCode(OpCodeValues.Sub_Ovf, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Sub_Ovf_Un = new OpCode(OpCodeValues.Sub_Ovf_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Endfinally = new OpCode(OpCodeValues.Endfinally, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Return << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + OpCode.EndsUncondJmpBlkFlag | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Leave = new OpCode(OpCodeValues.Leave, + ((int)OperandType.InlineBrTarget) | + ((int)FlowControl.Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + OpCode.EndsUncondJmpBlkFlag | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Leave_S = new OpCode(OpCodeValues.Leave_S, + ((int)OperandType.ShortInlineBrTarget) | + ((int)FlowControl.Branch << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + OpCode.EndsUncondJmpBlkFlag | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stind_I = new OpCode(OpCodeValues.Stind_I, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (-2 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Conv_U = new OpCode(OpCodeValues.Conv_U, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Prefix7 = new OpCode(OpCodeValues.Prefix7, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Meta << OpCode.FlowControlShift) | + ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Prefix6 = new OpCode(OpCodeValues.Prefix6, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Meta << OpCode.FlowControlShift) | + ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Prefix5 = new OpCode(OpCodeValues.Prefix5, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Meta << OpCode.FlowControlShift) | + ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Prefix4 = new OpCode(OpCodeValues.Prefix4, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Meta << OpCode.FlowControlShift) | + ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Prefix3 = new OpCode(OpCodeValues.Prefix3, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Meta << OpCode.FlowControlShift) | + ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Prefix2 = new OpCode(OpCodeValues.Prefix2, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Meta << OpCode.FlowControlShift) | + ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Prefix1 = new OpCode(OpCodeValues.Prefix1, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Meta << OpCode.FlowControlShift) | + ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Prefixref = new OpCode(OpCodeValues.Prefixref, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Meta << OpCode.FlowControlShift) | + ((int)OpCodeType.Nternal << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (1 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Arglist = new OpCode(OpCodeValues.Arglist, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ceq = new OpCode(OpCodeValues.Ceq, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Cgt = new OpCode(OpCodeValues.Cgt, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Cgt_Un = new OpCode(OpCodeValues.Cgt_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Clt = new OpCode(OpCodeValues.Clt, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Clt_Un = new OpCode(OpCodeValues.Clt_Un, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1_pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldftn = new OpCode(OpCodeValues.Ldftn, + ((int)OperandType.InlineMethod) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldvirtftn = new OpCode(OpCodeValues.Ldvirtftn, + ((int)OperandType.InlineMethod) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popref << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldarg = new OpCode(OpCodeValues.Ldarg, + ((int)OperandType.InlineVar) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldarga = new OpCode(OpCodeValues.Ldarga, + ((int)OperandType.InlineVar) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Starg = new OpCode(OpCodeValues.Starg, + ((int)OperandType.InlineVar) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldloc = new OpCode(OpCodeValues.Ldloc, + ((int)OperandType.InlineVar) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push1 << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Ldloca = new OpCode(OpCodeValues.Ldloca, + ((int)OperandType.InlineVar) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Stloc = new OpCode(OpCodeValues.Stloc, + ((int)OperandType.InlineVar) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Localloc = new OpCode(OpCodeValues.Localloc, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Endfilter = new OpCode(OpCodeValues.Endfilter, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Return << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + OpCode.EndsUncondJmpBlkFlag | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Unaligned = new OpCode(OpCodeValues.Unaligned_, + ((int)OperandType.ShortInlineI) | + ((int)FlowControl.Meta << OpCode.FlowControlShift) | + ((int)OpCodeType.Prefix << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Volatile = new OpCode(OpCodeValues.Volatile_, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Meta << OpCode.FlowControlShift) | + ((int)OpCodeType.Prefix << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Tailcall = new OpCode(OpCodeValues.Tail_, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Meta << OpCode.FlowControlShift) | + ((int)OpCodeType.Prefix << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Initobj = new OpCode(OpCodeValues.Initobj, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (-1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Constrained = new OpCode(OpCodeValues.Constrained_, + ((int)OperandType.InlineType) | + ((int)FlowControl.Meta << OpCode.FlowControlShift) | + ((int)OpCodeType.Prefix << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Cpblk = new OpCode(OpCodeValues.Cpblk, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi_popi_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (-3 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Initblk = new OpCode(OpCodeValues.Initblk, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Popi_popi_popi << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (-3 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Rethrow = new OpCode(OpCodeValues.Rethrow, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Throw << OpCode.FlowControlShift) | + ((int)OpCodeType.Objmodel << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + OpCode.EndsUncondJmpBlkFlag | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Sizeof = new OpCode(OpCodeValues.Sizeof, + ((int)OperandType.InlineType) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (1 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Refanytype = new OpCode(OpCodeValues.Refanytype, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Next << OpCode.FlowControlShift) | + ((int)OpCodeType.Primitive << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop1 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Pushi << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + public static readonly OpCode Readonly = new OpCode(OpCodeValues.Readonly_, + ((int)OperandType.InlineNone) | + ((int)FlowControl.Meta << OpCode.FlowControlShift) | + ((int)OpCodeType.Prefix << OpCode.OpCodeTypeShift) | + ((int)StackBehaviour.Pop0 << OpCode.StackBehaviourPopShift) | + ((int)StackBehaviour.Push0 << OpCode.StackBehaviourPushShift) | + (2 << OpCode.SizeShift) | + (0 << OpCode.StackChangeShift) + ); + + + public static bool TakesSingleByteArgument(OpCode inst) + { + switch (inst.OperandType) + { + case OperandType.ShortInlineBrTarget : + case OperandType.ShortInlineI : + case OperandType.ShortInlineVar : + return true; + }; + return false; + } +} +} diff --git a/src/mscorlib/src/System/Reflection/Emit/Opcode.cs b/src/mscorlib/src/System/Reflection/Emit/Opcode.cs new file mode 100644 index 0000000000..cae4f0564e --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/Opcode.cs @@ -0,0 +1,312 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Reflection.Emit { +using System; +using System.Threading; +using System.Security.Permissions; +using System.Diagnostics.Contracts; + +[System.Runtime.InteropServices.ComVisible(true)] +public struct OpCode +{ + // + // Use packed bitfield for flags to avoid code bloat + // + + internal const int OperandTypeMask = 0x1F; // 000000000000000000000000000XXXXX + + internal const int FlowControlShift = 5; // 00000000000000000000000XXXX00000 + internal const int FlowControlMask = 0x0F; + + internal const int OpCodeTypeShift = 9; // 00000000000000000000XXX000000000 + internal const int OpCodeTypeMask = 0x07; + + internal const int StackBehaviourPopShift = 12; // 000000000000000XXXXX000000000000 + internal const int StackBehaviourPushShift = 17; // 0000000000XXXXX00000000000000000 + internal const int StackBehaviourMask = 0x1F; + + internal const int SizeShift = 22; // 00000000XX0000000000000000000000 + internal const int SizeMask = 0x03; + + internal const int EndsUncondJmpBlkFlag = 0x01000000; // 0000000X000000000000000000000000 + + // unused // 0000XXX0000000000000000000000000 + + internal const int StackChangeShift = 28; // XXXX0000000000000000000000000000 + +#if FEATURE_CORECLR + private OpCodeValues m_value; + private int m_flags; + + internal OpCode(OpCodeValues value, int flags) + { + m_value = value; + m_flags = flags; + } + + internal bool EndsUncondJmpBlk() + { + return (m_flags & EndsUncondJmpBlkFlag) != 0; + } + + internal int StackChange() + { + return (m_flags >> StackChangeShift); + } + + public OperandType OperandType + { + get + { + return (OperandType)(m_flags & OperandTypeMask); + } + } + + public FlowControl FlowControl + { + get + { + return (FlowControl)((m_flags >> FlowControlShift) & FlowControlMask); + } + } + + public OpCodeType OpCodeType + { + get + { + return (OpCodeType)((m_flags >> OpCodeTypeShift) & OpCodeTypeMask); + } + } + + + public StackBehaviour StackBehaviourPop + { + get + { + return (StackBehaviour)((m_flags >> StackBehaviourPopShift) & StackBehaviourMask); + } + } + + public StackBehaviour StackBehaviourPush + { + get + { + return (StackBehaviour)((m_flags >> StackBehaviourPushShift) & StackBehaviourMask); + } + } + + public int Size + { + get + { + return (m_flags >> SizeShift) & SizeMask; + } + } + + public short Value + { + get + { + return (short)m_value; + } + } +#else // FEATURE_CORECLR + // + // The exact layout is part of the legacy COM mscorlib surface, so it is + // pretty much set in stone for desktop CLR. Ideally, we would use the packed + // bit field like for CoreCLR, but that would be a breaking change. + // + +// disable csharp compiler warning #0414: field assigned unused value +#pragma warning disable 0414 + private String m_stringname; // not used - computed lazily +#pragma warning restore 0414 + private StackBehaviour m_pop; + private StackBehaviour m_push; + private OperandType m_operand; + private OpCodeType m_type; + private int m_size; + private byte m_s1; + private byte m_s2; + private FlowControl m_ctrl; + + // Specifies whether the current instructions causes the control flow to + // change unconditionally. + private bool m_endsUncondJmpBlk; + + + // Specifies the stack change that the current instruction causes not + // taking into account the operand dependant stack changes. + private int m_stackChange; + + + internal OpCode(OpCodeValues value, int flags) + { + m_stringname = null; // computed lazily + m_pop = (StackBehaviour)((flags >> StackBehaviourPopShift) & StackBehaviourMask); + m_push = (StackBehaviour)((flags >> StackBehaviourPushShift) & StackBehaviourMask); + m_operand = (OperandType)(flags & OperandTypeMask); + m_type = (OpCodeType)((flags >> OpCodeTypeShift) & OpCodeTypeMask); + m_size = (flags >> SizeShift) & SizeMask; + m_s1 = (byte)((int)value >> 8); + m_s2 = (byte)(int)value; + m_ctrl = (FlowControl)((flags >> FlowControlShift) & FlowControlMask); + m_endsUncondJmpBlk = (flags & EndsUncondJmpBlkFlag) != 0; + m_stackChange = (flags >> StackChangeShift); + } + + internal bool EndsUncondJmpBlk() + { + return m_endsUncondJmpBlk; + } + + internal int StackChange() + { + return m_stackChange; + } + + public OperandType OperandType + { + get + { + return (m_operand); + } + } + + public FlowControl FlowControl + { + get + { + return (m_ctrl); + } + } + + public OpCodeType OpCodeType + { + get + { + return (m_type); + } + } + + + public StackBehaviour StackBehaviourPop + { + get + { + return (m_pop); + } + } + + public StackBehaviour StackBehaviourPush + { + get + { + return (m_push); + } + } + + public int Size + { + get + { + return (m_size); + } + } + + public short Value + { + get + { + if (m_size == 2) + return (short)(m_s1 << 8 | m_s2); + return (short)m_s2; + } + } +#endif // FEATURE_CORECLR + + + private static volatile string[] g_nameCache; + + public String Name + { + get + { + if (Size == 0) + return null; + + // Create and cache the opcode names lazily. They should be rarely used (only for logging, etc.) + // Note that we do not any locks here because of we always get the same names. The last one wins. + string[] nameCache = g_nameCache; + if (nameCache == null) { + nameCache = new String[0x11f]; + g_nameCache = nameCache; + } + + OpCodeValues opCodeValue = (OpCodeValues)(ushort)Value; + + int idx = (int)opCodeValue; + if (idx > 0xFF) { + if (idx >= 0xfe00 && idx <= 0xfe1e) { + // Transform two byte opcode value to lower range that's suitable + // for array index + idx = 0x100 + (idx - 0xfe00); + } + else { + // Unknown opcode + return null; + } + } + + String name = Volatile.Read(ref nameCache[idx]); + if (name != null) + return name; + + // Create ilasm style name from the enum value name. + name = Enum.GetName(typeof(OpCodeValues), opCodeValue).ToLowerInvariant().Replace("_", "."); + Volatile.Write(ref nameCache[idx], name); + return name; + } + } + + [Pure] + public override bool Equals(Object obj) + { + if (obj is OpCode) + return Equals((OpCode)obj); + else + return false; + } + + [Pure] + public bool Equals(OpCode obj) + { + return obj.Value == Value; + } + + [Pure] + public static bool operator ==(OpCode a, OpCode b) + { + return a.Equals(b); + } + + [Pure] + public static bool operator !=(OpCode a, OpCode b) + { + return !(a == b); + } + + public override int GetHashCode() + { + return Value; + } + + public override String ToString() + { + return Name; + } +} + +} diff --git a/src/mscorlib/src/System/Reflection/Emit/OpcodeType.cs b/src/mscorlib/src/System/Reflection/Emit/OpcodeType.cs new file mode 100644 index 0000000000..5ef5f80b15 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/OpcodeType.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +**Purpose: Exposes OpCodeType Attribute of IL . +** +** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND! +** See opcodegen.pl for more information.** +============================================================*/ +namespace System.Reflection.Emit { + +using System; + +[Serializable] +[System.Runtime.InteropServices.ComVisible(true)] +public enum OpCodeType +{ + +#if !FEATURE_CORECLR + /// + [Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")] + Annotation = 0, +#endif + Macro = 1, + Nternal = 2, + Objmodel = 3, + Prefix = 4, + Primitive = 5, +} +} diff --git a/src/mscorlib/src/System/Reflection/Emit/OperandType.cs b/src/mscorlib/src/System/Reflection/Emit/OperandType.cs new file mode 100644 index 0000000000..fdde19a73e --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/OperandType.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +**Purpose: Exposes OperandType Attribute of IL . +** +** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND! +** See opcodegen.pl for more information.** +============================================================*/ +namespace System.Reflection.Emit { + +using System; + +[Serializable] +[System.Runtime.InteropServices.ComVisible(true)] +public enum OperandType +{ + + InlineBrTarget = 0, + InlineField = 1, + InlineI = 2, + InlineI8 = 3, + InlineMethod = 4, + InlineNone = 5, +#if !FEATURE_CORECLR + /// + [Obsolete("This API has been deprecated. http://go.microsoft.com/fwlink/?linkid=14202")] + InlinePhi = 6, +#endif + InlineR = 7, + InlineSig = 9, + InlineString = 10, + InlineSwitch = 11, + InlineTok = 12, + InlineType = 13, + InlineVar = 14, + ShortInlineBrTarget = 15, + ShortInlineI = 16, + ShortInlineR = 17, + ShortInlineVar = 18, +} +} diff --git a/src/mscorlib/src/System/Reflection/Emit/PEFileKinds.cs b/src/mscorlib/src/System/Reflection/Emit/PEFileKinds.cs new file mode 100644 index 0000000000..d9c9c0327c --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/PEFileKinds.cs @@ -0,0 +1,17 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Reflection.Emit { + + using System; + // This Enum matchs the CorFieldAttr defined in CorHdr.h + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public enum PEFileKinds + { + Dll = 0x0001, + ConsoleApplication = 0x0002, + WindowApplication = 0x0003, + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/ParameterBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/ParameterBuilder.cs new file mode 100644 index 0000000000..693e2d3660 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/ParameterBuilder.cs @@ -0,0 +1,172 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** ParameterBuilder is used to create/associate parameter information +** +** +===========================================================*/ +namespace System.Reflection.Emit { + using System.Runtime.InteropServices; + using System; + using System.Reflection; + using System.Security.Permissions; + using System.Diagnostics.Contracts; + + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_ParameterBuilder))] +[System.Runtime.InteropServices.ComVisible(true)] + public class ParameterBuilder : _ParameterBuilder + { + // set ParamMarshal + [System.Security.SecuritySafeCritical] // auto-generated + [Obsolete("An alternate API is available: Emit the MarshalAs custom attribute instead. http://go.microsoft.com/fwlink/?linkid=14202")] + public virtual void SetMarshal(UnmanagedMarshal unmanagedMarshal) + { + if (unmanagedMarshal == null) + { + throw new ArgumentNullException("unmanagedMarshal"); + } + Contract.EndContractBlock(); + + byte [] ubMarshal = unmanagedMarshal.InternalGetBytes(); + TypeBuilder.SetFieldMarshal( + m_methodBuilder.GetModuleBuilder().GetNativeHandle(), + m_pdToken.Token, + ubMarshal, + ubMarshal.Length); + } + + // Set the default value of the parameter + [System.Security.SecuritySafeCritical] // auto-generated + public virtual void SetConstant(Object defaultValue) + { + TypeBuilder.SetConstantValue( + m_methodBuilder.GetModuleBuilder(), + m_pdToken.Token, + m_iPosition == 0 ? m_methodBuilder.ReturnType : m_methodBuilder.m_parameterTypes[m_iPosition - 1], + defaultValue); + } + + // Use this function if client decides to form the custom attribute blob themselves + + [System.Security.SecuritySafeCritical] + [System.Runtime.InteropServices.ComVisible(true)] + public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + { + if (con == null) + throw new ArgumentNullException("con"); + if (binaryAttribute == null) + throw new ArgumentNullException("binaryAttribute"); + Contract.EndContractBlock(); + + TypeBuilder.DefineCustomAttribute( + m_methodBuilder.GetModuleBuilder(), + m_pdToken.Token, + ((ModuleBuilder )m_methodBuilder.GetModule()).GetConstructorToken(con).Token, + binaryAttribute, + false, false); + } + + // Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder + [System.Security.SecuritySafeCritical] // auto-generated + public void SetCustomAttribute(CustomAttributeBuilder customBuilder) + { + if (customBuilder == null) + { + throw new ArgumentNullException("customBuilder"); + } + Contract.EndContractBlock(); + customBuilder.CreateCustomAttribute((ModuleBuilder) (m_methodBuilder .GetModule()), m_pdToken.Token); + } + + //******************************* + // Make a private constructor so these cannot be constructed externally. + //******************************* + private ParameterBuilder() {} + + + [System.Security.SecurityCritical] // auto-generated + internal ParameterBuilder( + MethodBuilder methodBuilder, + int sequence, + ParameterAttributes attributes, + String strParamName) // can be NULL string + { + m_iPosition = sequence; + m_strParamName = strParamName; + m_methodBuilder = methodBuilder; + m_strParamName = strParamName; + m_attributes = attributes; + m_pdToken = new ParameterToken( TypeBuilder.SetParamInfo( + m_methodBuilder.GetModuleBuilder().GetNativeHandle(), + m_methodBuilder.GetToken().Token, + sequence, + attributes, + strParamName)); + } + + public virtual ParameterToken GetToken() + { + return m_pdToken; + } + +#if !FEATURE_CORECLR + void _ParameterBuilder.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _ParameterBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _ParameterBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _ParameterBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + + internal int MetadataTokenInternal { get { return m_pdToken.Token; } } + + public virtual String Name { + get {return m_strParamName;} + } + + public virtual int Position { + get {return m_iPosition;} + } + + public virtual int Attributes { + get {return (int) m_attributes;} + } + + public bool IsIn { + get {return ((m_attributes & ParameterAttributes.In) != 0);} + } + public bool IsOut { + get {return ((m_attributes & ParameterAttributes.Out) != 0);} + } + public bool IsOptional { + get {return ((m_attributes & ParameterAttributes.Optional) != 0);} + } + + private String m_strParamName; + private int m_iPosition; + private ParameterAttributes m_attributes; + private MethodBuilder m_methodBuilder; + private ParameterToken m_pdToken; + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/ParameterToken.cs b/src/mscorlib/src/System/Reflection/Emit/ParameterToken.cs new file mode 100644 index 0000000000..d65368bf0d --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/ParameterToken.cs @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** Purpose: metadata tokens for a parameter +** +** +===========================================================*/ +namespace System.Reflection.Emit { + + using System; + using System.Reflection; + using System.Security.Permissions; + + // The ParameterToken class is an opaque representation of the Token returned + // by the Metadata to represent the parameter. + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public struct ParameterToken { + + public static readonly ParameterToken Empty = new ParameterToken(); + internal int m_tkParameter; + +#if false + public ParameterToken() { + m_tkParameter=0; + } +#endif + + internal ParameterToken(int tkParam) { + m_tkParameter = tkParam; + } + + public int Token { + get { return m_tkParameter; } + } + + public override int GetHashCode() + { + return m_tkParameter; + } + + public override bool Equals(Object obj) + { + if (obj is ParameterToken) + return Equals((ParameterToken)obj); + else + return false; + } + + public bool Equals(ParameterToken obj) + { + return obj.m_tkParameter == m_tkParameter; + } + + public static bool operator ==(ParameterToken a, ParameterToken b) + { + return a.Equals(b); + } + + public static bool operator !=(ParameterToken a, ParameterToken b) + { + return !(a == b); + } + + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/PropertyBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/PropertyBuilder.cs new file mode 100644 index 0000000000..5ac69f205f --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/PropertyBuilder.cs @@ -0,0 +1,306 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** Propertybuilder is for client to define properties for a class +** +** +===========================================================*/ +namespace System.Reflection.Emit { + + using System; + using System.Reflection; + using CultureInfo = System.Globalization.CultureInfo; + using System.Security.Permissions; + using System.Runtime.InteropServices; + using System.Diagnostics.Contracts; + + // + // A PropertyBuilder is always associated with a TypeBuilder. The TypeBuilder.DefineProperty + // method will return a new PropertyBuilder to a client. + // + [HostProtection(MayLeakOnAbort = true)] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_PropertyBuilder))] + [System.Runtime.InteropServices.ComVisible(true)] + public sealed class PropertyBuilder : PropertyInfo, _PropertyBuilder + { + + // Make a private constructor so these cannot be constructed externally. + private PropertyBuilder() {} + + // Constructs a PropertyBuilder. + // + internal PropertyBuilder( + ModuleBuilder mod, // the module containing this PropertyBuilder + String name, // property name + SignatureHelper sig, // property signature descriptor info + PropertyAttributes attr, // property attribute such as DefaultProperty, Bindable, DisplayBind, etc + Type returnType, // return type of the property. + PropertyToken prToken, // the metadata token for this property + TypeBuilder containingType) // the containing type + { + if (name == null) + throw new ArgumentNullException("name"); + if (name.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + if (name[0] == '\0') + throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), "name"); + Contract.EndContractBlock(); + + m_name = name; + m_moduleBuilder = mod; + m_signature = sig; + m_attributes = attr; + m_returnType = returnType; + m_prToken = prToken; + m_tkProperty = prToken.Token; + m_containingType = containingType; + } + + //************************************************ + // Set the default value of the Property + //************************************************ + [System.Security.SecuritySafeCritical] // auto-generated + public void SetConstant(Object defaultValue) + { + m_containingType.ThrowIfCreated(); + + TypeBuilder.SetConstantValue( + m_moduleBuilder, + m_prToken.Token, + m_returnType, + defaultValue); + } + + + // Return the Token for this property within the TypeBuilder that the + // property is defined within. + public PropertyToken PropertyToken + { + get {return m_prToken;} + } + + internal int MetadataTokenInternal + { + get + { + return m_tkProperty; + } + } + + public override Module Module + { + get + { + return m_containingType.Module; + } + } + + [System.Security.SecurityCritical] // auto-generated + private void SetMethodSemantics(MethodBuilder mdBuilder, MethodSemanticsAttributes semantics) + { + if (mdBuilder == null) + { + throw new ArgumentNullException("mdBuilder"); + } + + m_containingType.ThrowIfCreated(); + TypeBuilder.DefineMethodSemantics( + m_moduleBuilder.GetNativeHandle(), + m_prToken.Token, + semantics, + mdBuilder.GetToken().Token); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void SetGetMethod(MethodBuilder mdBuilder) + { + SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.Getter); + m_getMethod = mdBuilder; + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void SetSetMethod(MethodBuilder mdBuilder) + { + SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.Setter); + m_setMethod = mdBuilder; + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void AddOtherMethod(MethodBuilder mdBuilder) + { + SetMethodSemantics(mdBuilder, MethodSemanticsAttributes.Other); + } + + // Use this function if client decides to form the custom attribute blob themselves + +#if FEATURE_CORECLR +[System.Security.SecurityCritical] // auto-generated +#else +[System.Security.SecuritySafeCritical] +#endif +[System.Runtime.InteropServices.ComVisible(true)] + public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + { + if (con == null) + throw new ArgumentNullException("con"); + if (binaryAttribute == null) + throw new ArgumentNullException("binaryAttribute"); + + m_containingType.ThrowIfCreated(); + TypeBuilder.DefineCustomAttribute( + m_moduleBuilder, + m_prToken.Token, + m_moduleBuilder.GetConstructorToken(con).Token, + binaryAttribute, + false, false); + } + + // Use this function if client wishes to build CustomAttribute using CustomAttributeBuilder + [System.Security.SecuritySafeCritical] // auto-generated + public void SetCustomAttribute(CustomAttributeBuilder customBuilder) + { + if (customBuilder == null) + { + throw new ArgumentNullException("customBuilder"); + } + m_containingType.ThrowIfCreated(); + customBuilder.CreateCustomAttribute(m_moduleBuilder, m_prToken.Token); + } + + // Not supported functions in dynamic module. + public override Object GetValue(Object obj,Object[] index) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + public override Object GetValue(Object obj,BindingFlags invokeAttr,Binder binder,Object[] index,CultureInfo culture) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + public override void SetValue(Object obj,Object value,Object[] index) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + public override void SetValue(Object obj,Object value,BindingFlags invokeAttr,Binder binder,Object[] index,CultureInfo culture) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + public override MethodInfo[] GetAccessors(bool nonPublic) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + public override MethodInfo GetGetMethod(bool nonPublic) + { + if (nonPublic || m_getMethod == null) + return m_getMethod; + // now check to see if m_getMethod is public + if ((m_getMethod.Attributes & MethodAttributes.Public) == MethodAttributes.Public) + return m_getMethod; + return null; + } + + public override MethodInfo GetSetMethod(bool nonPublic) + { + if (nonPublic || m_setMethod == null) + return m_setMethod; + // now check to see if m_setMethod is public + if ((m_setMethod.Attributes & MethodAttributes.Public) == MethodAttributes.Public) + return m_setMethod; + return null; + } + + public override ParameterInfo[] GetIndexParameters() + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + public override Type PropertyType { + get { return m_returnType; } + } + + public override PropertyAttributes Attributes { + get { return m_attributes;} + } + + public override bool CanRead { + get { if (m_getMethod != null) return true; else return false; } } + + public override bool CanWrite { + get { if (m_setMethod != null) return true; else return false; } + } + + public override Object[] GetCustomAttributes(bool inherit) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + public override bool IsDefined (Type attributeType, bool inherit) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + +#if !FEATURE_CORECLR + void _PropertyBuilder.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _PropertyBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _PropertyBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _PropertyBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + + public override String Name { + get { return m_name; } + } + + public override Type DeclaringType { + get { return m_containingType; } + } + + public override Type ReflectedType { + get { return m_containingType; } + } + + // These are package private so that TypeBuilder can access them. + private String m_name; // The name of the property + private PropertyToken m_prToken; // The token of this property + private int m_tkProperty; + private ModuleBuilder m_moduleBuilder; + private SignatureHelper m_signature; + private PropertyAttributes m_attributes; // property's attribute flags + private Type m_returnType; // property's return type + private MethodInfo m_getMethod; + private MethodInfo m_setMethod; + private TypeBuilder m_containingType; + } + +} diff --git a/src/mscorlib/src/System/Reflection/Emit/PropertyToken.cs b/src/mscorlib/src/System/Reflection/Emit/PropertyToken.cs new file mode 100644 index 0000000000..d70cad057a --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/PropertyToken.cs @@ -0,0 +1,70 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** Propertybuilder is for client to define properties for a class +** +** +===========================================================*/ +namespace System.Reflection.Emit { + + using System; + using System.Reflection; + using System.Security.Permissions; + + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public struct PropertyToken { + + public static readonly PropertyToken Empty = new PropertyToken(); + + internal int m_property; + + internal PropertyToken(int str) { + m_property=str; + } + + public int Token { + get { return m_property; } + } + + // Satisfy value class requirements + public override int GetHashCode() + { + return m_property; + } + + // Satisfy value class requirements + public override bool Equals(Object obj) + { + if (obj is PropertyToken) + return Equals((PropertyToken)obj); + else + return false; + } + + public bool Equals(PropertyToken obj) + { + return obj.m_property == m_property; + } + + public static bool operator ==(PropertyToken a, PropertyToken b) + { + return a.Equals(b); + } + + public static bool operator !=(PropertyToken a, PropertyToken b) + { + return !(a == b); + } + + } + + +} diff --git a/src/mscorlib/src/System/Reflection/Emit/SignatureHelper.cs b/src/mscorlib/src/System/Reflection/Emit/SignatureHelper.cs new file mode 100644 index 0000000000..35e8cc7e31 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/SignatureHelper.cs @@ -0,0 +1,1019 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection.Emit +{ + using System.Text; + using System; + using System.Diagnostics.Contracts; + using System.Reflection; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + using System.Runtime.Versioning; + using System.Security.Permissions; + + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_SignatureHelper))] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class SignatureHelper : _SignatureHelper + { + #region Consts Fields + private const int NO_SIZE_IN_SIG = -1; + #endregion + + #region Static Members + [System.Security.SecuritySafeCritical] // auto-generated + public static SignatureHelper GetMethodSigHelper(Module mod, Type returnType, Type[] parameterTypes) + { + return GetMethodSigHelper(mod, CallingConventions.Standard, returnType, null, null, parameterTypes, null, null); + } + + [System.Security.SecurityCritical] // auto-generated + internal static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType, int cGenericParam) + { + return GetMethodSigHelper(mod, callingConvention, cGenericParam, returnType, null, null, null, null, null); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public static SignatureHelper GetMethodSigHelper(Module mod, CallingConventions callingConvention, Type returnType) + { + return GetMethodSigHelper(mod, callingConvention, returnType, null, null, null, null, null); + } + + internal static SignatureHelper GetMethodSpecSigHelper(Module scope, Type[] inst) + { + SignatureHelper sigHelp = new SignatureHelper(scope, MdSigCallingConvention.GenericInst); + sigHelp.AddData(inst.Length); + foreach(Type t in inst) + sigHelp.AddArgument(t); + return sigHelp; + } + + [System.Security.SecurityCritical] // auto-generated + internal static SignatureHelper GetMethodSigHelper( + Module scope, CallingConventions callingConvention, + Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, + Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) + { + return GetMethodSigHelper(scope, callingConvention, 0, returnType, requiredReturnTypeCustomModifiers, + optionalReturnTypeCustomModifiers, parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers); + } + + [System.Security.SecurityCritical] // auto-generated + internal static SignatureHelper GetMethodSigHelper( + Module scope, CallingConventions callingConvention, int cGenericParam, + Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, + Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) + { + SignatureHelper sigHelp; + MdSigCallingConvention intCall; + + if (returnType == null) + { + returnType = typeof(void); + } + + intCall = MdSigCallingConvention.Default; + + if ((callingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) + intCall = MdSigCallingConvention.Vararg; + + if (cGenericParam > 0) + { + intCall |= MdSigCallingConvention.Generic; + } + + if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis) + intCall |= MdSigCallingConvention.HasThis; + + sigHelp = new SignatureHelper(scope, intCall, cGenericParam, returnType, + requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers); + sigHelp.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers); + + return sigHelp; + } + + [System.Security.SecuritySafeCritical] // auto-generated + public static SignatureHelper GetMethodSigHelper(Module mod, CallingConvention unmanagedCallConv, Type returnType) + { + SignatureHelper sigHelp; + MdSigCallingConvention intCall; + + if (returnType == null) + returnType = typeof(void); + + if (unmanagedCallConv == CallingConvention.Cdecl) + { + intCall = MdSigCallingConvention.C; + } + else if (unmanagedCallConv == CallingConvention.StdCall || unmanagedCallConv == CallingConvention.Winapi) + { + intCall = MdSigCallingConvention.StdCall; + } + else if (unmanagedCallConv == CallingConvention.ThisCall) + { + intCall = MdSigCallingConvention.ThisCall; + } + else if (unmanagedCallConv == CallingConvention.FastCall) + { + intCall = MdSigCallingConvention.FastCall; + } + else + { + throw new ArgumentException(Environment.GetResourceString("Argument_UnknownUnmanagedCallConv"), "unmanagedCallConv"); + } + + sigHelp = new SignatureHelper(mod, intCall, returnType, null, null); + + return sigHelp; + } + + public static SignatureHelper GetLocalVarSigHelper() + { + return GetLocalVarSigHelper(null); + } + + public static SignatureHelper GetMethodSigHelper(CallingConventions callingConvention, Type returnType) + { + return GetMethodSigHelper(null, callingConvention, returnType); + } + + public static SignatureHelper GetMethodSigHelper(CallingConvention unmanagedCallingConvention, Type returnType) + { + return GetMethodSigHelper(null, unmanagedCallingConvention, returnType); + } + + public static SignatureHelper GetLocalVarSigHelper(Module mod) + { + return new SignatureHelper(mod, MdSigCallingConvention.LocalSig); + } + + public static SignatureHelper GetFieldSigHelper(Module mod) + { + return new SignatureHelper(mod, MdSigCallingConvention.Field); + } + + public static SignatureHelper GetPropertySigHelper(Module mod, Type returnType, Type[] parameterTypes) + { + return GetPropertySigHelper(mod, returnType, null, null, parameterTypes, null, null); + } + + public static SignatureHelper GetPropertySigHelper(Module mod, + Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, + Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) + { + return GetPropertySigHelper(mod, (CallingConventions)0, returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers, + parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers); + } + [System.Security.SecuritySafeCritical] // auto-generated + public static SignatureHelper GetPropertySigHelper(Module mod, CallingConventions callingConvention, + Type returnType, Type[] requiredReturnTypeCustomModifiers, Type[] optionalReturnTypeCustomModifiers, + Type[] parameterTypes, Type[][] requiredParameterTypeCustomModifiers, Type[][] optionalParameterTypeCustomModifiers) + { + SignatureHelper sigHelp; + + if (returnType == null) + { + returnType = typeof(void); + } + + MdSigCallingConvention intCall = MdSigCallingConvention.Property; + + if ((callingConvention & CallingConventions.HasThis) == CallingConventions.HasThis) + intCall |= MdSigCallingConvention.HasThis; + + sigHelp = new SignatureHelper(mod, intCall, + returnType, requiredReturnTypeCustomModifiers, optionalReturnTypeCustomModifiers); + sigHelp.AddArguments(parameterTypes, requiredParameterTypeCustomModifiers, optionalParameterTypeCustomModifiers); + + return sigHelp; + } + + [System.Security.SecurityCritical] // auto-generated + internal static SignatureHelper GetTypeSigToken(Module mod, Type type) + { + if (mod == null) + throw new ArgumentNullException("module"); + + if (type == null) + throw new ArgumentNullException("type"); + + return new SignatureHelper(mod, type); + } + #endregion + + #region Private Data Members + private byte[] m_signature; + private int m_currSig; // index into m_signature buffer for next available byte + private int m_sizeLoc; // index into m_signature buffer to put m_argCount (will be NO_SIZE_IN_SIG if no arg count is needed) + private ModuleBuilder m_module; + private bool m_sigDone; + private int m_argCount; // tracking number of arguments in the signature + #endregion + + #region Constructor + private SignatureHelper(Module mod, MdSigCallingConvention callingConvention) + { + // Use this constructor to instantiate a local var sig or Field where return type is not applied. + Init(mod, callingConvention); + } + + [System.Security.SecurityCritical] // auto-generated + private SignatureHelper(Module mod, MdSigCallingConvention callingConvention, int cGenericParameters, + Type returnType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) + { + // Use this constructor to instantiate a any signatures that will require a return type. + Init(mod, callingConvention, cGenericParameters); + + if (callingConvention == MdSigCallingConvention.Field) + throw new ArgumentException(Environment.GetResourceString("Argument_BadFieldSig")); + + AddOneArgTypeHelper(returnType, requiredCustomModifiers, optionalCustomModifiers); + } + + [System.Security.SecurityCritical] // auto-generated + private SignatureHelper(Module mod, MdSigCallingConvention callingConvention, + Type returnType, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) + : this(mod, callingConvention, 0, returnType, requiredCustomModifiers, optionalCustomModifiers) + { + } + + [System.Security.SecurityCritical] // auto-generated + private SignatureHelper(Module mod, Type type) + { + Init(mod); + + AddOneArgTypeHelper(type); + } + + private void Init(Module mod) + { + m_signature = new byte[32]; + m_currSig = 0; + m_module = mod as ModuleBuilder; + m_argCount = 0; + m_sigDone = false; + m_sizeLoc = NO_SIZE_IN_SIG; + + if (m_module == null && mod != null) + throw new ArgumentException(Environment.GetResourceString("NotSupported_MustBeModuleBuilder")); + } + + private void Init(Module mod, MdSigCallingConvention callingConvention) + { + Init(mod, callingConvention, 0); + } + + private void Init(Module mod, MdSigCallingConvention callingConvention, int cGenericParam) + { + Init(mod); + + AddData((byte)callingConvention); + + if (callingConvention == MdSigCallingConvention.Field || + callingConvention == MdSigCallingConvention.GenericInst) + { + m_sizeLoc = NO_SIZE_IN_SIG; + } + else + { + if (cGenericParam > 0) + AddData(cGenericParam); + + m_sizeLoc = m_currSig++; + } + } + + #endregion + + #region Private Members + [System.Security.SecurityCritical] // auto-generated + private void AddOneArgTypeHelper(Type argument, bool pinned) + { + if (pinned) + AddElementType(CorElementType.Pinned); + + AddOneArgTypeHelper(argument); + } + + [System.Security.SecurityCritical] // auto-generated + private void AddOneArgTypeHelper(Type clsArgument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) + { + // This function will not increase the argument count. It only fills in bytes + // in the signature based on clsArgument. This helper is called for return type. + + Contract.Requires(clsArgument != null); + Contract.Requires((optionalCustomModifiers == null && requiredCustomModifiers == null) || !clsArgument.ContainsGenericParameters); + + if (optionalCustomModifiers != null) + { + for (int i = 0; i < optionalCustomModifiers.Length; i++) + { + Type t = optionalCustomModifiers[i]; + + if (t == null) + throw new ArgumentNullException("optionalCustomModifiers"); + + if (t.HasElementType) + throw new ArgumentException(Environment.GetResourceString("Argument_ArraysInvalid"), "optionalCustomModifiers"); + + if (t.ContainsGenericParameters) + throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "optionalCustomModifiers"); + + AddElementType(CorElementType.CModOpt); + + int token = m_module.GetTypeToken(t).Token; + Contract.Assert(!MetadataToken.IsNullToken(token)); + AddToken(token); + } + } + + if (requiredCustomModifiers != null) + { + for (int i = 0; i < requiredCustomModifiers.Length; i++) + { + Type t = requiredCustomModifiers[i]; + + if (t == null) + throw new ArgumentNullException("requiredCustomModifiers"); + + if (t.HasElementType) + throw new ArgumentException(Environment.GetResourceString("Argument_ArraysInvalid"), "requiredCustomModifiers"); + + if (t.ContainsGenericParameters) + throw new ArgumentException(Environment.GetResourceString("Argument_GenericsInvalid"), "requiredCustomModifiers"); + + AddElementType(CorElementType.CModReqd); + + int token = m_module.GetTypeToken(t).Token; + Contract.Assert(!MetadataToken.IsNullToken(token)); + AddToken(token); + } + } + + AddOneArgTypeHelper(clsArgument); + } + + [System.Security.SecurityCritical] // auto-generated + private void AddOneArgTypeHelper(Type clsArgument) { AddOneArgTypeHelperWorker(clsArgument, false); } + [System.Security.SecurityCritical] // auto-generated + private void AddOneArgTypeHelperWorker(Type clsArgument, bool lastWasGenericInst) + { + if (clsArgument.IsGenericParameter) + { + if (clsArgument.DeclaringMethod != null) + AddElementType(CorElementType.MVar); + else + AddElementType(CorElementType.Var); + + AddData(clsArgument.GenericParameterPosition); + } + else if (clsArgument.IsGenericType && (!clsArgument.IsGenericTypeDefinition || !lastWasGenericInst)) + { + AddElementType(CorElementType.GenericInst); + + AddOneArgTypeHelperWorker(clsArgument.GetGenericTypeDefinition(), true); + + Type[] args = clsArgument.GetGenericArguments(); + + AddData(args.Length); + + foreach (Type t in args) + AddOneArgTypeHelper(t); + } + else if (clsArgument is TypeBuilder) + { + TypeBuilder clsBuilder = (TypeBuilder)clsArgument; + TypeToken tkType; + + if (clsBuilder.Module.Equals(m_module)) + { + tkType = clsBuilder.TypeToken; + } + else + { + tkType = m_module.GetTypeToken(clsArgument); + } + + if (clsArgument.IsValueType) + { + InternalAddTypeToken(tkType, CorElementType.ValueType); + } + else + { + InternalAddTypeToken(tkType, CorElementType.Class); + } + } + else if (clsArgument is EnumBuilder) + { + TypeBuilder clsBuilder = ((EnumBuilder)clsArgument).m_typeBuilder; + TypeToken tkType; + + if (clsBuilder.Module.Equals(m_module)) + { + tkType = clsBuilder.TypeToken; + } + else + { + tkType = m_module.GetTypeToken(clsArgument); + } + + if (clsArgument.IsValueType) + { + InternalAddTypeToken(tkType, CorElementType.ValueType); + } + else + { + InternalAddTypeToken(tkType, CorElementType.Class); + } + } + else if (clsArgument.IsByRef) + { + AddElementType(CorElementType.ByRef); + clsArgument = clsArgument.GetElementType(); + AddOneArgTypeHelper(clsArgument); + } + else if (clsArgument.IsPointer) + { + AddElementType(CorElementType.Ptr); + AddOneArgTypeHelper(clsArgument.GetElementType()); + } + else if (clsArgument.IsArray) + { + if (clsArgument.IsSzArray) + { + AddElementType(CorElementType.SzArray); + + AddOneArgTypeHelper(clsArgument.GetElementType()); + } + else + { + AddElementType(CorElementType.Array); + + AddOneArgTypeHelper(clsArgument.GetElementType()); + + // put the rank information + int rank = clsArgument.GetArrayRank(); + AddData(rank); // rank + AddData(0); // upper bounds + AddData(rank); // lower bound + for (int i = 0; i < rank; i++) + AddData(0); + } + } + else + { + CorElementType type = CorElementType.Max; + + if (clsArgument is RuntimeType) + { + type = RuntimeTypeHandle.GetCorElementType((RuntimeType)clsArgument); + + //GetCorElementType returns CorElementType.Class for both object and string + if (type == CorElementType.Class) + { + if (clsArgument == typeof(object)) + type = CorElementType.Object; + else if (clsArgument == typeof(string)) + type = CorElementType.String; + } + } + + if (IsSimpleType(type)) + { + AddElementType(type); + } + else if (m_module == null) + { + InternalAddRuntimeType(clsArgument); + } + else if (clsArgument.IsValueType) + { + InternalAddTypeToken(m_module.GetTypeToken(clsArgument), CorElementType.ValueType); + } + else + { + InternalAddTypeToken(m_module.GetTypeToken(clsArgument), CorElementType.Class); + } + } + } + + private void AddData(int data) + { + // A managed representation of CorSigCompressData; + + if (m_currSig + 4 > m_signature.Length) + { + m_signature = ExpandArray(m_signature); + } + + if (data <= 0x7F) + { + m_signature[m_currSig++] = (byte)(data & 0xFF); + } + else if (data <= 0x3FFF) + { + m_signature[m_currSig++] = (byte)((data >>8) | 0x80); + m_signature[m_currSig++] = (byte)(data & 0xFF); + } + else if (data <= 0x1FFFFFFF) + { + m_signature[m_currSig++] = (byte)((data >>24) | 0xC0); + m_signature[m_currSig++] = (byte)((data >>16) & 0xFF); + m_signature[m_currSig++] = (byte)((data >>8) & 0xFF); + m_signature[m_currSig++] = (byte)((data) & 0xFF); + } + else + { + throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger")); + } + + } + + private void AddData(uint data) + { + if (m_currSig + 4 > m_signature.Length) + { + m_signature = ExpandArray(m_signature); + } + + m_signature[m_currSig++] = (byte)((data) & 0xFF); + m_signature[m_currSig++] = (byte)((data>>8) & 0xFF); + m_signature[m_currSig++] = (byte)((data>>16) & 0xFF); + m_signature[m_currSig++] = (byte)((data>>24) & 0xFF); + } + + private void AddData(ulong data) + { + if (m_currSig + 8 > m_signature.Length) + { + m_signature = ExpandArray(m_signature); + } + + m_signature[m_currSig++] = (byte)((data) & 0xFF); + m_signature[m_currSig++] = (byte)((data>>8) & 0xFF); + m_signature[m_currSig++] = (byte)((data>>16) & 0xFF); + m_signature[m_currSig++] = (byte)((data>>24) & 0xFF); + m_signature[m_currSig++] = (byte)((data>>32) & 0xFF); + m_signature[m_currSig++] = (byte)((data>>40) & 0xFF); + m_signature[m_currSig++] = (byte)((data>>48) & 0xFF); + m_signature[m_currSig++] = (byte)((data>>56) & 0xFF); + } + + private void AddElementType(CorElementType cvt) + { + // Adds an element to the signature. A managed represenation of CorSigCompressElement + if (m_currSig + 1 > m_signature.Length) + m_signature = ExpandArray(m_signature); + + m_signature[m_currSig++] = (byte)cvt; + } + + private void AddToken(int token) + { + // A managed represenation of CompressToken + // Pulls the token appart to get a rid, adds some appropriate bits + // to the token and then adds this to the signature. + + int rid = (token & 0x00FFFFFF); //This is RidFromToken; + MetadataTokenType type = (MetadataTokenType)(token & unchecked((int)0xFF000000)); //This is TypeFromToken; + + if (rid > 0x3FFFFFF) + { + // token is too big to be compressed + throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger")); + } + + rid = (rid << 2); + + // TypeDef is encoded with low bits 00 + // TypeRef is encoded with low bits 01 + // TypeSpec is encoded with low bits 10 + if (type == MetadataTokenType.TypeRef) + { + //if type is mdtTypeRef + rid|=0x1; + } + else if (type == MetadataTokenType.TypeSpec) + { + //if type is mdtTypeSpec + rid|=0x2; + } + + AddData(rid); + } + + private void InternalAddTypeToken(TypeToken clsToken, CorElementType CorType) + { + // Add a type token into signature. CorType will be either CorElementType.Class or CorElementType.ValueType + AddElementType(CorType); + AddToken(clsToken.Token); + } + + [System.Security.SecurityCritical] // auto-generated + private unsafe void InternalAddRuntimeType(Type type) + { + // Add a runtime type into the signature. + + AddElementType(CorElementType.Internal); + + IntPtr handle = type.GetTypeHandleInternal().Value; + + // Internal types must have their pointer written into the signature directly (we don't + // want to convert to little-endian format on big-endian machines because the value is + // going to be extracted and used directly as a pointer (and only within this process)). + + if (m_currSig + sizeof(void*) > m_signature.Length) + m_signature = ExpandArray(m_signature); + + byte *phandle = (byte*)&handle; + for (int i = 0; i < sizeof(void*); i++) + m_signature[m_currSig++] = phandle[i]; + } + + private byte[] ExpandArray(byte[] inArray) + { + // Expand the signature buffer size + return ExpandArray(inArray, inArray.Length * 2); + } + + private byte[] ExpandArray(byte[] inArray, int requiredLength) + { + // Expand the signature buffer size + + if (requiredLength < inArray.Length) + requiredLength = inArray.Length*2; + + byte[] outArray = new byte[requiredLength]; + Buffer.BlockCopy(inArray, 0, outArray, 0, inArray.Length); + return outArray; + } + + private void IncrementArgCounts() + { + if (m_sizeLoc == NO_SIZE_IN_SIG) + { + //We don't have a size if this is a field. + return; + } + + m_argCount++; + } + + private void SetNumberOfSignatureElements(bool forceCopy) + { + // For most signatures, this will set the number of elements in a byte which we have reserved for it. + // However, if we have a field signature, we don't set the length and return. + // If we have a signature with more than 128 arguments, we can't just set the number of elements, + // we actually have to allocate more space (e.g. shift everything in the array one or more spaces to the + // right. We do this by making a copy of the array and leaving the correct number of blanks. This new + // array is now set to be m_signature and we use the AddData method to set the number of elements properly. + // The forceCopy argument can be used to force SetNumberOfSignatureElements to make a copy of + // the array. This is useful for GetSignature which promises to trim the array to be the correct size anyway. + + byte[] temp; + int newSigSize; + int currSigHolder = m_currSig; + + if (m_sizeLoc == NO_SIZE_IN_SIG) + return; + + //If we have fewer than 128 arguments and we haven't been told to copy the + //array, we can just set the appropriate bit and return. + if (m_argCount < 0x80 && !forceCopy) + { + m_signature[m_sizeLoc] = (byte)m_argCount; + return; + } + + //We need to have more bytes for the size. Figure out how many bytes here. + //Since we need to copy anyway, we're just going to take the cost of doing a + //new allocation. + if (m_argCount < 0x80) + { + newSigSize = 1; + } + else if (m_argCount < 0x4000) + { + newSigSize = 2; + } + else + { + newSigSize = 4; + } + + //Allocate the new array. + temp = new byte[m_currSig + newSigSize - 1]; + + //Copy the calling convention. The calling convention is always just one byte + //so we just copy that byte. Then copy the rest of the array, shifting everything + //to make room for the new number of elements. + temp[0] = m_signature[0]; + Buffer.BlockCopy(m_signature, m_sizeLoc + 1, temp, m_sizeLoc + newSigSize, currSigHolder - (m_sizeLoc + 1)); + m_signature = temp; + + //Use the AddData method to add the number of elements appropriately compressed. + m_currSig = m_sizeLoc; + AddData(m_argCount); + m_currSig = currSigHolder + (newSigSize - 1); + } + + #endregion + + #region Internal Members + internal int ArgumentCount + { + get + { + return m_argCount; + } + } + + internal static bool IsSimpleType(CorElementType type) + { + if (type <= CorElementType.String) + return true; + + if (type == CorElementType.TypedByRef || type == CorElementType.I || type == CorElementType.U || type == CorElementType.Object) + return true; + + return false; + } + + internal byte[] InternalGetSignature(out int length) + { + // An internal method to return the signature. Does not trim the + // array, but passes out the length of the array in an out parameter. + // This is the actual array -- not a copy -- so the callee must agree + // to not copy it. + // + // param length : an out param indicating the length of the array. + // return : A reference to the internal ubyte array. + + if (!m_sigDone) + { + m_sigDone = true; + + // If we have more than 128 variables, we can't just set the length, we need + // to compress it. Unfortunately, this means that we need to copy the entire + // array. Bummer, eh? + SetNumberOfSignatureElements(false); + } + + length = m_currSig; + return m_signature; + } + + + + + internal byte[] InternalGetSignatureArray() + { + int argCount = m_argCount; + int currSigLength = m_currSig; + int newSigSize = currSigLength; + + //Allocate the new array. + if (argCount < 0x7F) + newSigSize += 1; + else if (argCount < 0x3FFF) + newSigSize += 2; + else + newSigSize += 4; + byte[] temp = new byte[newSigSize]; + + // copy the sig + int sigCopyIndex = 0; + // calling convention + temp[sigCopyIndex++] = m_signature[0]; + // arg size + if (argCount <= 0x7F) + temp[sigCopyIndex++] = (byte)(argCount & 0xFF); + else if (argCount <= 0x3FFF) + { + temp[sigCopyIndex++] = (byte)((argCount >>8) | 0x80); + temp[sigCopyIndex++] = (byte)(argCount & 0xFF); + } + else if (argCount <= 0x1FFFFFFF) + { + temp[sigCopyIndex++] = (byte)((argCount >>24) | 0xC0); + temp[sigCopyIndex++] = (byte)((argCount >>16) & 0xFF); + temp[sigCopyIndex++] = (byte)((argCount >>8) & 0xFF); + temp[sigCopyIndex++] = (byte)((argCount) & 0xFF); + } + else + throw new ArgumentException(Environment.GetResourceString("Argument_LargeInteger")); + // copy the sig part of the sig + Buffer.BlockCopy(m_signature, 2, temp, sigCopyIndex, currSigLength - 2); + // mark the end of sig + temp[newSigSize - 1] = (byte)CorElementType.End; + + return temp; + } + + #endregion + + #region Public Methods + public void AddArgument(Type clsArgument) + { + AddArgument(clsArgument, null, null); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void AddArgument(Type argument, bool pinned) + { + if (argument == null) + throw new ArgumentNullException("argument"); + + IncrementArgCounts(); + AddOneArgTypeHelper(argument, pinned); + } + + public void AddArguments(Type[] arguments, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers) + { + if (requiredCustomModifiers != null && (arguments == null || requiredCustomModifiers.Length != arguments.Length)) + throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", "requiredCustomModifiers", "arguments")); + + if (optionalCustomModifiers != null && (arguments == null || optionalCustomModifiers.Length != arguments.Length)) + throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", "optionalCustomModifiers", "arguments")); + + if (arguments != null) + { + for (int i =0; i < arguments.Length; i++) + { + AddArgument(arguments[i], + requiredCustomModifiers == null ? null : requiredCustomModifiers[i], + optionalCustomModifiers == null ? null : optionalCustomModifiers[i]); + } + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void AddArgument(Type argument, Type[] requiredCustomModifiers, Type[] optionalCustomModifiers) + { + if (m_sigDone) + throw new ArgumentException(Environment.GetResourceString("Argument_SigIsFinalized")); + + if (argument == null) + throw new ArgumentNullException("argument"); + + IncrementArgCounts(); + + // Add an argument to the signature. Takes a Type and determines whether it + // is one of the primitive types of which we have special knowledge or a more + // general class. In the former case, we only add the appropriate short cut encoding, + // otherwise we will calculate proper description for the type. + AddOneArgTypeHelper(argument, requiredCustomModifiers, optionalCustomModifiers); + } + + public void AddSentinel() + { + AddElementType(CorElementType.Sentinel); + } + + public override bool Equals(Object obj) + { + if (!(obj is SignatureHelper)) + { + return false; + } + + SignatureHelper temp = (SignatureHelper)obj; + + if ( !temp.m_module.Equals(m_module) || temp.m_currSig!=m_currSig || temp.m_sizeLoc!=m_sizeLoc || temp.m_sigDone !=m_sigDone ) + { + return false; + } + + for (int i=0; i m_currSig) + { + byte[] temp = new byte[m_currSig]; + Array.Copy(m_signature, 0, temp, 0, m_currSig); + m_signature = temp; + } + + return m_signature; + } + + public override String ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append("Length: " + m_currSig + Environment.NewLine); + + if (m_sizeLoc != -1) + { + sb.Append("Arguments: " + m_signature[m_sizeLoc] + Environment.NewLine); + } + else + { + sb.Append("Field Signature" + Environment.NewLine); + } + + sb.Append("Signature: " + Environment.NewLine); + for (int i=0; i<=m_currSig; i++) + { + sb.Append(m_signature[i] + " "); + } + + sb.Append(Environment.NewLine); + return sb.ToString(); + } + + #endregion + +#if !FEATURE_CORECLR + void _SignatureHelper.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _SignatureHelper.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _SignatureHelper.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _SignatureHelper.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + + } +} + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mscorlib/src/System/Reflection/Emit/SignatureToken.cs b/src/mscorlib/src/System/Reflection/Emit/SignatureToken.cs new file mode 100644 index 0000000000..0a87ac1398 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/SignatureToken.cs @@ -0,0 +1,68 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** Signature: SignatureToken +** +** +** +** +** Purpose: Represents a Signature to the ILGenerator signature. +** +** +===========================================================*/ +namespace System.Reflection.Emit { + + using System; + using System.Reflection; + using System.Security.Permissions; + + [System.Runtime.InteropServices.ComVisible(true)] + public struct SignatureToken { + + public static readonly SignatureToken Empty = new SignatureToken(); + + internal int m_signature; + internal ModuleBuilder m_moduleBuilder; + + internal SignatureToken(int str, ModuleBuilder mod) { + m_signature=str; + m_moduleBuilder = mod; + } + + public int Token { + get { return m_signature; } + } + + public override int GetHashCode() + { + return m_signature; + } + + public override bool Equals(Object obj) + { + if (obj is SignatureToken) + return Equals((SignatureToken)obj); + else + return false; + } + + public bool Equals(SignatureToken obj) + { + return obj.m_signature == m_signature; + } + + public static bool operator ==(SignatureToken a, SignatureToken b) + { + return a.Equals(b); + } + + public static bool operator !=(SignatureToken a, SignatureToken b) + { + return !(a == b); + } + + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/StackBehaviour.cs b/src/mscorlib/src/System/Reflection/Emit/StackBehaviour.cs new file mode 100644 index 0000000000..2d2c35ef26 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/StackBehaviour.cs @@ -0,0 +1,54 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +**Purpose: Exposes StackBehaviour Attribute of IL . +** +** THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT BY HAND! +** See clr\src\inc\opcodegen.pl for more information.** +============================================================*/ +namespace System.Reflection.Emit { + +using System; + +[Serializable] +[System.Runtime.InteropServices.ComVisible(true)] +public enum StackBehaviour +{ + + Pop0 = 0, + Pop1 = 1, + Pop1_pop1 = 2, + Popi = 3, + Popi_pop1 = 4, + Popi_popi = 5, + Popi_popi8 = 6, + Popi_popi_popi = 7, + Popi_popr4 = 8, + Popi_popr8 = 9, + Popref = 10, + Popref_pop1 = 11, + Popref_popi = 12, + Popref_popi_popi = 13, + Popref_popi_popi8 = 14, + Popref_popi_popr4 = 15, + Popref_popi_popr8 = 16, + Popref_popi_popref = 17, + Push0 = 18, + Push1 = 19, + Push1_push1 = 20, + Pushi = 21, + Pushi8 = 22, + Pushr4 = 23, + Pushr8 = 24, + Pushref = 25, + Varpop = 26, + Varpush = 27, + Popref_popi_pop1 = 28, +} +} diff --git a/src/mscorlib/src/System/Reflection/Emit/StringToken.cs b/src/mscorlib/src/System/Reflection/Emit/StringToken.cs new file mode 100644 index 0000000000..cb0e979a7a --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/StringToken.cs @@ -0,0 +1,79 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** Purpose: Represents a String to the ILGenerator class. +** +** +===========================================================*/ +namespace System.Reflection.Emit { + + using System; + using System.Reflection; + using System.Security.Permissions; + + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public struct StringToken { + + internal int m_string; + + //public StringToken() { + // m_string=0; + //} + + internal StringToken(int str) { + m_string=str; + } + + // Returns the metadata token for this particular string. + // Generated by a call to Module.GetStringConstant(). + // + public int Token { + get { return m_string; } + } + + public override int GetHashCode() + { + return m_string; + } + + public override bool Equals(Object obj) + { + if (obj is StringToken) + return Equals((StringToken)obj); + else + return false; + } + + public bool Equals(StringToken obj) + { + return obj.m_string == m_string; + } + + public static bool operator ==(StringToken a, StringToken b) + { + return a.Equals(b); + } + + public static bool operator !=(StringToken a, StringToken b) + { + return !(a == b); + } + + } + + + + + + + + +} diff --git a/src/mscorlib/src/System/Reflection/Emit/SymbolMethod.cs b/src/mscorlib/src/System/Reflection/Emit/SymbolMethod.cs new file mode 100644 index 0000000000..62780f4e3a --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/SymbolMethod.cs @@ -0,0 +1,184 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection.Emit +{ + using System.Runtime.InteropServices; + using System; + using System.Reflection; + using System.Diagnostics.Contracts; + using CultureInfo = System.Globalization.CultureInfo; + + internal sealed class SymbolMethod : MethodInfo + { + #region Private Data Members + private ModuleBuilder m_module; + private Type m_containingType; + private String m_name; + private CallingConventions m_callingConvention; + private Type m_returnType; + private MethodToken m_mdMethod; + private Type[] m_parameterTypes; + private SignatureHelper m_signature; + #endregion + + #region Constructor + [System.Security.SecurityCritical] // auto-generated + internal SymbolMethod(ModuleBuilder mod, MethodToken token, Type arrayClass, String methodName, + CallingConventions callingConvention, Type returnType, Type[] parameterTypes) + { + // This is a kind of MethodInfo to represent methods for array type of unbaked type + + // Another way to look at this class is as a glorified MethodToken wrapper. At the time of this comment + // this class is only constructed inside ModuleBuilder.GetArrayMethod and the only interesting thing + // passed into it is this MethodToken. The MethodToken was forged using a TypeSpec for an Array type and + // the name of the method on Array. + // As none of the methods on Array have CustomModifiers their is no need to pass those around in here. + m_mdMethod = token; + + // The ParameterTypes are also a bit interesting in that they may be unbaked TypeBuilders. + m_returnType = returnType; + if (parameterTypes != null) + { + m_parameterTypes = new Type[parameterTypes.Length]; + Array.Copy(parameterTypes, 0, m_parameterTypes, 0, parameterTypes.Length); + } + else + { + m_parameterTypes = EmptyArray.Value; + } + + m_module = mod; + m_containingType = arrayClass; + m_name = methodName; + m_callingConvention = callingConvention; + + m_signature = SignatureHelper.GetMethodSigHelper( + mod, callingConvention, returnType, null, null, parameterTypes, null, null); + } + #endregion + + #region Internal Members + internal override Type[] GetParameterTypes() + { + return m_parameterTypes; + } + + internal MethodToken GetToken(ModuleBuilder mod) + { + return mod.GetArrayMethodToken(m_containingType, m_name, m_callingConvention, m_returnType, m_parameterTypes); + } + + #endregion + + #region MemberInfo Overrides + public override Module Module + { + get { return m_module; } + } + + public override Type ReflectedType + { + get { return m_containingType as Type; } + } + + public override String Name + { + get { return m_name; } + } + + public override Type DeclaringType + { + get {return m_containingType;} + } + #endregion + + #region MethodBase Overrides + [Pure] + public override ParameterInfo[] GetParameters() + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod")); + } + + public override MethodImplAttributes GetMethodImplementationFlags() + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod")); + } + + public override MethodAttributes Attributes + { + get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod")); } + } + + public override CallingConventions CallingConvention + { + get { return m_callingConvention; } + } + + public override RuntimeMethodHandle MethodHandle + { + get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod")); } + } + + #endregion + + #region MethodInfo Overrides + public override Type ReturnType + { + get + { + return m_returnType; + } + } + + public override ICustomAttributeProvider ReturnTypeCustomAttributes + { + get { return null; } + } + + public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod")); + } + + public override MethodInfo GetBaseDefinition() + { + return this; + } + #endregion + + #region ICustomAttributeProvider Implementation + public override Object[] GetCustomAttributes(bool inherit) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod")); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod")); + } + + public override bool IsDefined(Type attributeType, bool inherit) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_SymbolMethod")); + } + + #endregion + + #region Public Members + public Module GetModule() + { + return m_module; + } + + public MethodToken GetToken() + { + return m_mdMethod; + } + + #endregion + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/SymbolType.cs b/src/mscorlib/src/System/Reflection/Emit/SymbolType.cs new file mode 100644 index 0000000000..633a2bffb4 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/SymbolType.cs @@ -0,0 +1,606 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection.Emit +{ + using System.Runtime.InteropServices; + using System; + using System.Reflection; + using System.Diagnostics.Contracts; + using CultureInfo = System.Globalization.CultureInfo; + + [Serializable] + internal enum TypeKind + { + IsArray = 1, + IsPointer = 2, + IsByRef = 3, + } + + // This is a kind of Type object that will represent the compound expression of a parameter type or field type. + internal sealed class SymbolType : TypeInfo + { + public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){ + if(typeInfo==null) return false; + return IsAssignableFrom(typeInfo.AsType()); + } + + #region Static Members + internal static Type FormCompoundType(string format, Type baseType, int curIndex) + { + // This function takes a string to describe the compound type, such as "[,][]", and a baseType. + // + // Example: [2..4] - one dimension array with lower bound 2 and size of 3 + // Example: [3, 5, 6] - three dimension array with lower bound 3, 5, 6 + // Example: [-3, ] [] - one dimensional array of two dimensional array (with lower bound -3 for + // the first dimension) + // Example: []* - pointer to a one dimensional array + // Example: *[] - one dimensional array. The element type is a pointer to the baseType + // Example: []& - ByRef of a single dimensional array. Only one & is allowed and it must appear the last! + // Example: [?] - Array with unknown bound + + SymbolType symbolType; + int iLowerBound; + int iUpperBound; + + if (format == null || curIndex == format.Length) + { + // we have consumed all of the format string + return baseType; + } + + + + + if (format[curIndex] == '&') + { + // ByRef case + + symbolType = new SymbolType(TypeKind.IsByRef); + symbolType.SetFormat(format, curIndex, 1); + curIndex++; + + if (curIndex != format.Length) + // ByRef has to be the last char!! + throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat")); + + symbolType.SetElementType(baseType); + return symbolType; + } + + if (format[curIndex] == '[') + { + // Array type. + symbolType = new SymbolType(TypeKind.IsArray); + int startIndex = curIndex; + curIndex++; + + iLowerBound = 0; + iUpperBound = -1; + + // Example: [2..4] - one dimension array with lower bound 2 and size of 3 + // Example: [3, 5, 6] - three dimension array with lower bound 3, 5, 6 + // Example: [-3, ] [] - one dimensional array of two dimensional array (with lower bound -3 sepcified) + + while (format[curIndex] != ']') + { + if (format[curIndex] == '*') + { + symbolType.m_isSzArray = false; + curIndex++; + } + // consume, one dimension at a time + if ((format[curIndex] >= '0' && format[curIndex] <= '9') || format[curIndex] == '-') + { + bool isNegative = false; + if (format[curIndex] == '-') + { + isNegative = true; + curIndex++; + } + + // lower bound is specified. Consume the low bound + while (format[curIndex] >= '0' && format[curIndex] <= '9') + { + iLowerBound = iLowerBound * 10; + iLowerBound += format[curIndex] - '0'; + curIndex++; + } + + if (isNegative) + { + iLowerBound = 0 - iLowerBound; + } + + // set the upper bound to be less than LowerBound to indicate that upper bound it not specified yet! + iUpperBound = iLowerBound - 1; + + } + if (format[curIndex] == '.') + { + // upper bound is specified + + // skip over ".." + curIndex++; + if (format[curIndex] != '.') + { + // bad format!! Throw exception + throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat")); + } + + curIndex++; + // consume the upper bound + if ((format[curIndex] >= '0' && format[curIndex] <= '9') || format[curIndex] == '-') + { + bool isNegative = false; + iUpperBound = 0; + if (format[curIndex] == '-') + { + isNegative = true; + curIndex++; + } + + // lower bound is specified. Consume the low bound + while (format[curIndex] >= '0' && format[curIndex] <= '9') + { + iUpperBound = iUpperBound * 10; + iUpperBound += format[curIndex] - '0'; + curIndex++; + } + if (isNegative) + { + iUpperBound = 0 - iUpperBound; + } + if (iUpperBound < iLowerBound) + { + // User specified upper bound less than lower bound, this is an error. + // Throw error exception. + throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat")); + } + } + } + + if (format[curIndex] == ',') + { + // We have more dimension to deal with. + // now set the lower bound, the size, and increase the dimension count! + curIndex++; + symbolType.SetBounds(iLowerBound, iUpperBound); + + // clear the lower and upper bound information for next dimension + iLowerBound = 0; + iUpperBound = -1; + } + else if (format[curIndex] != ']') + { + throw new ArgumentException(Environment.GetResourceString("Argument_BadSigFormat")); + } + } + + // The last dimension information + symbolType.SetBounds(iLowerBound, iUpperBound); + + // skip over ']' + curIndex++; + + symbolType.SetFormat(format, startIndex, curIndex - startIndex); + + // set the base type of array + symbolType.SetElementType(baseType); + return FormCompoundType(format, symbolType, curIndex); + } + else if (format[curIndex] == '*') + { + // pointer type. + + symbolType = new SymbolType(TypeKind.IsPointer); + symbolType.SetFormat(format, curIndex, 1); + curIndex++; + symbolType.SetElementType(baseType); + return FormCompoundType(format, symbolType, curIndex); + } + + return null; + } + + #endregion + + #region Data Members + internal TypeKind m_typeKind; + internal Type m_baseType; + internal int m_cRank; // count of dimension + // If LowerBound and UpperBound is equal, that means one element. + // If UpperBound is less than LowerBound, then the size is not specified. + internal int[] m_iaLowerBound; + internal int[] m_iaUpperBound; // count of dimension + private string m_format; // format string to form the full name. + private bool m_isSzArray = true; + #endregion + + #region Constructor + internal SymbolType(TypeKind typeKind) + { + m_typeKind = typeKind; + m_iaLowerBound = new int[4]; + m_iaUpperBound = new int[4]; + } + + #endregion + + #region Internal Members + internal void SetElementType(Type baseType) + { + if (baseType == null) + throw new ArgumentNullException("baseType"); + Contract.EndContractBlock(); + + m_baseType = baseType; + } + + private void SetBounds(int lower, int upper) + { + // Increase the rank, set lower and upper bound + + if (lower != 0 || upper != -1) + m_isSzArray = false; + + if (m_iaLowerBound.Length <= m_cRank) + { + // resize the bound array + int[] iaTemp = new int[m_cRank * 2]; + Array.Copy(m_iaLowerBound, 0, iaTemp, 0, m_cRank); + m_iaLowerBound = iaTemp; + Array.Copy(m_iaUpperBound, 0, iaTemp, 0, m_cRank); + m_iaUpperBound = iaTemp; + } + + m_iaLowerBound[m_cRank] = lower; + m_iaUpperBound[m_cRank] = upper; + m_cRank++; + } + + internal void SetFormat(string format, int curIndex, int length) + { + // Cache the text display format for this SymbolType + + m_format = format.Substring(curIndex, length); + } + #endregion + + #region Type Overrides + internal override bool IsSzArray + { + get + { + if (m_cRank > 1) + return false; + + return m_isSzArray; + } + } + + public override Type MakePointerType() + { + return SymbolType.FormCompoundType(m_format + "*", m_baseType, 0); + } + + public override Type MakeByRefType() + { + return SymbolType.FormCompoundType(m_format + "&", m_baseType, 0); + } + + public override Type MakeArrayType() + { + return SymbolType.FormCompoundType(m_format + "[]", m_baseType, 0); + } + + public override Type MakeArrayType(int rank) + { + if (rank <= 0) + throw new IndexOutOfRangeException(); + Contract.EndContractBlock(); + + string szrank = ""; + if (rank == 1) + { + szrank = "*"; + } + else + { + for(int i = 1; i < rank; i++) + szrank += ","; + } + + string s = String.Format(CultureInfo.InvariantCulture, "[{0}]", szrank); // [,,] + SymbolType st = SymbolType.FormCompoundType(m_format + s, m_baseType, 0) as SymbolType; + return st; + } + + public override int GetArrayRank() + { + if (!IsArray) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); + Contract.EndContractBlock(); + + return m_cRank; + } + + public override Guid GUID + { + get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + } + + public override Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, + Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override Module Module + { + get + { + Type baseType; + + for (baseType = m_baseType; baseType is SymbolType; baseType = ((SymbolType) baseType).m_baseType); + + return baseType.Module; + } + } + public override Assembly Assembly + { + get + { + Type baseType; + + for (baseType = m_baseType; baseType is SymbolType; baseType = ((SymbolType) baseType).m_baseType); + + return baseType.Assembly; + } + } + + public override RuntimeTypeHandle TypeHandle + { + get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); } + } + + public override String Name + { + get + { + Type baseType; + String sFormat = m_format; + + for (baseType = m_baseType; baseType is SymbolType; baseType = ((SymbolType)baseType).m_baseType) + sFormat = ((SymbolType)baseType).m_format + sFormat; + + return baseType.Name + sFormat; + } + } + + public override String FullName + { + get + { + return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.FullName); + } + } + + public override String AssemblyQualifiedName + { + get + { + return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.AssemblyQualifiedName); + } + } + + public override String ToString() + { + return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.ToString); + } + + public override String Namespace + { + get { return m_baseType.Namespace; } + } + + public override Type BaseType + { + + get { return typeof(System.Array); } + } + + protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr,Binder binder, + CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + +[System.Runtime.InteropServices.ComVisible(true)] + public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + protected override MethodInfo GetMethodImpl(String name,BindingFlags bindingAttr,Binder binder, + CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override MethodInfo[] GetMethods(BindingFlags bindingAttr) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override FieldInfo GetField(String name, BindingFlags bindingAttr) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override FieldInfo[] GetFields(BindingFlags bindingAttr) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override Type GetInterface(String name,bool ignoreCase) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override Type[] GetInterfaces() + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override EventInfo GetEvent(String name,BindingFlags bindingAttr) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override EventInfo[] GetEvents() + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + protected override PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, + Type returnType, Type[] types, ParameterModifier[] modifiers) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override Type[] GetNestedTypes(BindingFlags bindingAttr) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override Type GetNestedType(String name, BindingFlags bindingAttr) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override MemberInfo[] GetMembers(BindingFlags bindingAttr) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + +[System.Runtime.InteropServices.ComVisible(true)] + public override InterfaceMapping GetInterfaceMap(Type interfaceType) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override EventInfo[] GetEvents(BindingFlags bindingAttr) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + protected override TypeAttributes GetAttributeFlagsImpl() + { + // Return the attribute flags of the base type? + Type baseType; + for (baseType = m_baseType; baseType is SymbolType; baseType = ((SymbolType)baseType).m_baseType); + return baseType.Attributes; + } + + protected override bool IsArrayImpl() + { + return m_typeKind == TypeKind.IsArray; + } + + protected override bool IsPointerImpl() + { + return m_typeKind == TypeKind.IsPointer; + } + + protected override bool IsByRefImpl() + { + return m_typeKind == TypeKind.IsByRef; + } + + protected override bool IsPrimitiveImpl() + { + return false; + } + + protected override bool IsValueTypeImpl() + { + return false; + } + + protected override bool IsCOMObjectImpl() + { + return false; + } + + public override bool IsConstructedGenericType + { + get + { + return false; + } + } + + public override Type GetElementType() + { + return m_baseType; + } + + protected override bool HasElementTypeImpl() + { + return m_baseType != null; + } + + public override Type UnderlyingSystemType + { + + get { return this; } + } + + public override Object[] GetCustomAttributes(bool inherit) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + + public override bool IsDefined (Type attributeType, bool inherit) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NonReflectedType")); + } + #endregion + } +} + + + + + + + + + + + + + + + + + diff --git a/src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs b/src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs new file mode 100644 index 0000000000..6db04717b5 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/TypeBuilder.cs @@ -0,0 +1,2620 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + + +// + +namespace System.Reflection.Emit { + using System; + using System.Reflection; + using System.Security; + using System.Security.Permissions; + using System.Diagnostics; + using System.Runtime.InteropServices; + using System.Runtime.CompilerServices; + using System.Collections.Generic; + using CultureInfo = System.Globalization.CultureInfo; + using System.Threading; + using System.Runtime.Versioning; + using System.Diagnostics.Contracts; + + + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public enum PackingSize + { + Unspecified = 0, + Size1 = 1, + Size2 = 2, + Size4 = 4, + Size8 = 8, + Size16 = 16, + Size32 = 32, + Size64 = 64, + Size128 = 128, + } + + [HostProtection(MayLeakOnAbort = true)] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_TypeBuilder))] + [System.Runtime.InteropServices.ComVisible(true)] + public sealed class TypeBuilder : TypeInfo, _TypeBuilder + { + public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){ + if(typeInfo==null) return false; + return IsAssignableFrom(typeInfo.AsType()); + } + + #region Declarations + private class CustAttr + { + private ConstructorInfo m_con; + private byte[] m_binaryAttribute; + private CustomAttributeBuilder m_customBuilder; + + public CustAttr(ConstructorInfo con, byte[] binaryAttribute) + { + if (con == null) + throw new ArgumentNullException("con"); + + if (binaryAttribute == null) + throw new ArgumentNullException("binaryAttribute"); + Contract.EndContractBlock(); + + m_con = con; + m_binaryAttribute = binaryAttribute; + } + + public CustAttr(CustomAttributeBuilder customBuilder) + { + if (customBuilder == null) + throw new ArgumentNullException("customBuilder"); + Contract.EndContractBlock(); + + m_customBuilder = customBuilder; + } + + [System.Security.SecurityCritical] // auto-generated + public void Bake(ModuleBuilder module, int token) + { + if (m_customBuilder == null) + { + TypeBuilder.DefineCustomAttribute(module, token, module.GetConstructorToken(m_con).Token, + m_binaryAttribute, false, false); + } + else + { + m_customBuilder.CreateCustomAttribute(module, token); + } + } + } + #endregion + + #region Public Static Methods + public static MethodInfo GetMethod(Type type, MethodInfo method) + { + if (!(type is TypeBuilder) && !(type is TypeBuilderInstantiation)) + throw new ArgumentException(Environment.GetResourceString("Argument_MustBeTypeBuilder")); + + // The following checks establishes invariants that more simply put require type to be generic and + // method to be a generic method definition declared on the generic type definition of type. + // To create generic method G.M these invariants require that G.M be created by calling + // this function followed by MakeGenericMethod on the resulting MethodInfo to finally get G.M. + // We could also allow G.M to be created before G.M (BindGenParm followed by this method) + // if we wanted to but that just complicates things so these checks are designed to prevent that scenario. + + if (method.IsGenericMethod && !method.IsGenericMethodDefinition) + throw new ArgumentException(Environment.GetResourceString("Argument_NeedGenericMethodDefinition"), "method"); + + if (method.DeclaringType == null || !method.DeclaringType.IsGenericTypeDefinition) + throw new ArgumentException(Environment.GetResourceString("Argument_MethodNeedGenericDeclaringType"), "method"); + + if (type.GetGenericTypeDefinition() != method.DeclaringType) + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidMethodDeclaringType"), "type"); + Contract.EndContractBlock(); + + // The following converts from Type or TypeBuilder of G to TypeBuilderInstantiation G. These types + // both logically represent the same thing. The runtime displays a similar convention by having + // G.M() be encoded by a typeSpec whose parent is the typeDef for G and whose instantiation is also G. + if (type.IsGenericTypeDefinition) + type = type.MakeGenericType(type.GetGenericArguments()); + + if (!(type is TypeBuilderInstantiation)) + throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "type"); + + return MethodOnTypeBuilderInstantiation.GetMethod(method, type as TypeBuilderInstantiation); + } + public static ConstructorInfo GetConstructor(Type type, ConstructorInfo constructor) + { + if (!(type is TypeBuilder) && !(type is TypeBuilderInstantiation)) + throw new ArgumentException(Environment.GetResourceString("Argument_MustBeTypeBuilder")); + + if (!constructor.DeclaringType.IsGenericTypeDefinition) + throw new ArgumentException(Environment.GetResourceString("Argument_ConstructorNeedGenericDeclaringType"), "constructor"); + Contract.EndContractBlock(); + + if (!(type is TypeBuilderInstantiation)) + throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "type"); + + // TypeBuilder G ==> TypeBuilderInstantiation G + if (type is TypeBuilder && type.IsGenericTypeDefinition) + type = type.MakeGenericType(type.GetGenericArguments()); + + if (type.GetGenericTypeDefinition() != constructor.DeclaringType) + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidConstructorDeclaringType"), "type"); + + return ConstructorOnTypeBuilderInstantiation.GetConstructor(constructor, type as TypeBuilderInstantiation); + } + public static FieldInfo GetField(Type type, FieldInfo field) + { + if (!(type is TypeBuilder) && !(type is TypeBuilderInstantiation)) + throw new ArgumentException(Environment.GetResourceString("Argument_MustBeTypeBuilder")); + + if (!field.DeclaringType.IsGenericTypeDefinition) + throw new ArgumentException(Environment.GetResourceString("Argument_FieldNeedGenericDeclaringType"), "field"); + Contract.EndContractBlock(); + + if (!(type is TypeBuilderInstantiation)) + throw new ArgumentException(Environment.GetResourceString("Argument_NeedNonGenericType"), "type"); + + // TypeBuilder G ==> TypeBuilderInstantiation G + if (type is TypeBuilder && type.IsGenericTypeDefinition) + type = type.MakeGenericType(type.GetGenericArguments()); + + if (type.GetGenericTypeDefinition() != field.DeclaringType) + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidFieldDeclaringType"), "type"); + + return FieldOnTypeBuilderInstantiation.GetField(field, type as TypeBuilderInstantiation); + } + #endregion + + #region Public Const + public const int UnspecifiedTypeSize = 0; + #endregion + + #region Private Static FCalls + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void SetParentType(RuntimeModule module, int tdTypeDef, int tkParent); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void AddInterfaceImpl(RuntimeModule module, int tdTypeDef, int tkInterface); + #endregion + + #region Internal Static FCalls + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal static extern int DefineMethod(RuntimeModule module, int tkParent, String name, byte[] signature, int sigLength, + MethodAttributes attributes); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal static extern int DefineMethodSpec(RuntimeModule module, int tkParent, byte[] signature, int sigLength); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal static extern int DefineField(RuntimeModule module, int tkParent, String name, byte[] signature, int sigLength, + FieldAttributes attributes); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void SetMethodIL(RuntimeModule module, int tk, bool isInitLocals, + byte[] body, int bodyLength, + byte[] LocalSig, int sigLength, + int maxStackSize, + ExceptionHandler[] exceptions, int numExceptions, + int [] tokenFixups, int numTokenFixups); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void DefineCustomAttribute(RuntimeModule module, int tkAssociate, int tkConstructor, + byte[] attr, int attrLength, bool toDisk, bool updateCompilerFlags); + + [System.Security.SecurityCritical] // auto-generated + internal static void DefineCustomAttribute(ModuleBuilder module, int tkAssociate, int tkConstructor, + byte[] attr, bool toDisk, bool updateCompilerFlags) + { + byte[] localAttr = null; + + if (attr != null) + { + localAttr = new byte[attr.Length]; + Buffer.BlockCopy(attr, 0, localAttr, 0, attr.Length); + } + + DefineCustomAttribute(module.GetNativeHandle(), tkAssociate, tkConstructor, + localAttr, (localAttr != null) ? localAttr.Length : 0, toDisk, updateCompilerFlags); + } + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal static extern void SetPInvokeData(RuntimeModule module, String DllName, String name, int token, int linkFlags); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal static extern int DefineProperty(RuntimeModule module, int tkParent, String name, PropertyAttributes attributes, + byte[] signature, int sigLength); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal static extern int DefineEvent(RuntimeModule module, int tkParent, String name, EventAttributes attributes, int tkEventType); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal static extern void DefineMethodSemantics(RuntimeModule module, int tkAssociation, + MethodSemanticsAttributes semantics, int tkMethod); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal static extern void DefineMethodImpl(RuntimeModule module, int tkType, int tkBody, int tkDecl); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal static extern void SetMethodImpl(RuntimeModule module, int tkMethod, MethodImplAttributes MethodImplAttributes); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal static extern int SetParamInfo(RuntimeModule module, int tkMethod, int iSequence, + ParameterAttributes iParamAttributes, String strParamName); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal static extern int GetTokenFromSig(RuntimeModule module, byte[] signature, int sigLength); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal static extern void SetFieldLayoutOffset(RuntimeModule module, int fdToken, int iOffset); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal static extern void SetClassLayout(RuntimeModule module, int tk, PackingSize iPackingSize, int iTypeSize); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal static extern void SetFieldMarshal(RuntimeModule module, int tk, byte[] ubMarshal, int ubSize); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern unsafe void SetConstantValue(RuntimeModule module, int tk, int corType, void* pValue); + +#if FEATURE_CAS_POLICY + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + internal static extern void AddDeclarativeSecurity(RuntimeModule module, int parent, SecurityAction action, byte[] blob, int cb); +#endif + #endregion + + #region Internal\Private Static Members + private static bool IsPublicComType(Type type) + { + // Internal Helper to determine if a type should be added to ComType table. + // A top level type should be added if it is Public. + // A nested type should be added if the top most enclosing type is Public + // and all the enclosing types are NestedPublic + + Type enclosingType = type.DeclaringType; + if (enclosingType != null) + { + if (IsPublicComType(enclosingType)) + { + if ((type.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic) + { + return true; + } + } + } + else + { + if ((type.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public) + { + return true; + } + } + + return false; + } + + [Pure] + internal static bool IsTypeEqual(Type t1, Type t2) + { + // Maybe we are lucky that they are equal in the first place + if (t1 == t2) + return true; + TypeBuilder tb1 = null; + TypeBuilder tb2 = null; + Type runtimeType1 = null; + Type runtimeType2 = null; + + // set up the runtimeType and TypeBuilder type corresponding to t1 and t2 + if (t1 is TypeBuilder) + { + tb1 =(TypeBuilder)t1; + // This will be null if it is not baked. + runtimeType1 = tb1.m_bakedRuntimeType; + } + else + { + runtimeType1 = t1; + } + + if (t2 is TypeBuilder) + { + tb2 =(TypeBuilder)t2; + // This will be null if it is not baked. + runtimeType2 = tb2.m_bakedRuntimeType; + } + else + { + runtimeType2 = t2; + } + + // If the type builder view is eqaul then it is equal + if (tb1 != null && tb2 != null && Object.ReferenceEquals(tb1, tb2)) + return true; + + // if the runtimetype view is eqaul than it is equal + if (runtimeType1 != null && runtimeType2 != null && runtimeType1 == runtimeType2) + return true; + + return false; + } + + [System.Security.SecurityCritical] // auto-generated + internal static unsafe void SetConstantValue(ModuleBuilder module, int tk, Type destType, Object value) + { + // This is a helper function that is used by ParameterBuilder, PropertyBuilder, + // and FieldBuilder to validate a default value and save it in the meta-data. + + if (value != null) + { + Type type = value.GetType(); + + // We should allow setting a constant value on a ByRef parameter + if (destType.IsByRef) + destType = destType.GetElementType(); + + if (destType.IsEnum) + { + // | UnderlyingSystemType | Enum.GetUnderlyingType() | IsEnum + // ----------------------------------|---------------------------|---------------------------|--------- + // runtime Enum Type | self | underlying type of enum | TRUE + // EnumBuilder | underlying type of enum | underlying type of enum* | TRUE + // TypeBuilder of enum types** | underlying type of enum | Exception | TRUE + // TypeBuilder of enum types (baked) | runtime enum type | Exception | TRUE + + // *: the behavior of Enum.GetUnderlyingType(EnumBuilder) might change in the future + // so let's not depend on it. + // **: created with System.Enum as the parent type. + + // The above behaviors might not be the most consistent but we have to live with them. + + Type underlyingType; + EnumBuilder enumBldr; + TypeBuilder typeBldr; + if ((enumBldr = destType as EnumBuilder) != null) + { + underlyingType = enumBldr.GetEnumUnderlyingType(); + + // The constant value supplied should match either the baked enum type or its underlying type + // we don't need to compare it with the EnumBuilder itself because you can never have an object of that type + if (type != enumBldr.m_typeBuilder.m_bakedRuntimeType && type != underlyingType) + throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch")); + } + else if ((typeBldr = destType as TypeBuilder) != null) + { + underlyingType = typeBldr.m_enumUnderlyingType; + + // The constant value supplied should match either the baked enum type or its underlying type + // typeBldr.m_enumUnderlyingType is null if the user hasn't created a "value__" field on the enum + if (underlyingType == null || (type != typeBldr.UnderlyingSystemType && type != underlyingType)) + throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch")); + } + else // must be a runtime Enum Type + { + Contract.Assert(destType is RuntimeType, "destType is not a runtime type, an EnumBuilder, or a TypeBuilder."); + + underlyingType = Enum.GetUnderlyingType(destType); + + // The constant value supplied should match either the enum itself or its underlying type + if (type != destType && type != underlyingType) + throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch")); + } + + type = underlyingType; + } + else + { + // Note that it is non CLS compliant if destType != type. But RefEmit never guarantees CLS-Compliance. + if (!destType.IsAssignableFrom(type)) + throw new ArgumentException(Environment.GetResourceString("Argument_ConstantDoesntMatch")); + } + + CorElementType corType = RuntimeTypeHandle.GetCorElementType((RuntimeType)type); + + switch (corType) + { + case CorElementType.I1: + case CorElementType.U1: + case CorElementType.Boolean: + case CorElementType.I2: + case CorElementType.U2: + case CorElementType.Char: + case CorElementType.I4: + case CorElementType.U4: + case CorElementType.R4: + case CorElementType.I8: + case CorElementType.U8: + case CorElementType.R8: + fixed (byte* pData = &JitHelpers.GetPinningHelper(value).m_data) + SetConstantValue(module.GetNativeHandle(), tk, (int)corType, pData); + break; + + default: + if (type == typeof(String)) + { + fixed (char* pString = (string)value) + SetConstantValue(module.GetNativeHandle(), tk, (int)CorElementType.String, pString); + } + else if (type == typeof(DateTime)) + { + //date is a I8 representation + long ticks = ((DateTime)value).Ticks; + SetConstantValue(module.GetNativeHandle(), tk, (int)CorElementType.I8, &ticks); + } + else + { + throw new ArgumentException(Environment.GetResourceString("Argument_ConstantNotSupported", type.ToString())); + } + break; + } + } + else + { + if (destType.IsValueType) + { + // nullable types can hold null value. + if (!(destType.IsGenericType && destType.GetGenericTypeDefinition() == typeof(Nullable<>))) + throw new ArgumentException(Environment.GetResourceString("Argument_ConstantNull")); + } + + SetConstantValue(module.GetNativeHandle(), tk, (int)CorElementType.Class, null); + } + } + + #endregion + + #region Private Data Members + private List m_ca; + private TypeToken m_tdType; + private ModuleBuilder m_module; + private String m_strName; + private String m_strNameSpace; + private String m_strFullQualName; + private Type m_typeParent; + private List m_typeInterfaces; + private TypeAttributes m_iAttr; + private GenericParameterAttributes m_genParamAttributes; + internal List m_listMethods; + internal int m_lastTokenizedMethod; + private int m_constructorCount; + private int m_iTypeSize; + private PackingSize m_iPackingSize; + private TypeBuilder m_DeclaringType; + + // We cannot store this on EnumBuilder because users can define enum types manually using TypeBuilder. + private Type m_enumUnderlyingType; + internal bool m_isHiddenGlobalType; + private bool m_hasBeenCreated; + private RuntimeType m_bakedRuntimeType; + + private int m_genParamPos; + private GenericTypeParameterBuilder[] m_inst; + private bool m_bIsGenParam; + private MethodBuilder m_declMeth; + private TypeBuilder m_genTypeDef; + #endregion + + #region Constructor + // ctor for the global (module) type + internal TypeBuilder(ModuleBuilder module) + { + m_tdType = new TypeToken((int)MetadataTokenType.TypeDef); + m_isHiddenGlobalType = true; + m_module = (ModuleBuilder)module; + m_listMethods = new List(); + // No token has been created so let's initialize it to -1 + // The first time we call MethodBuilder.GetToken this will incremented. + m_lastTokenizedMethod = -1; + } + + // ctor for generic method parameter + internal TypeBuilder(string szName, int genParamPos, MethodBuilder declMeth) + { + Contract.Requires(declMeth != null); + m_declMeth = declMeth; + m_DeclaringType =m_declMeth.GetTypeBuilder(); + m_module =declMeth.GetModuleBuilder(); + InitAsGenericParam(szName, genParamPos); + } + + // ctor for generic type parameter + private TypeBuilder(string szName, int genParamPos, TypeBuilder declType) + { + Contract.Requires(declType != null); + m_DeclaringType = declType; + m_module =declType.GetModuleBuilder(); + InitAsGenericParam(szName, genParamPos); + } + + private void InitAsGenericParam(string szName, int genParamPos) + { + m_strName = szName; + m_genParamPos = genParamPos; + m_bIsGenParam = true; + m_typeInterfaces = new List(); + } + + [System.Security.SecurityCritical] // auto-generated + internal TypeBuilder( + String name, + TypeAttributes attr, + Type parent, + Type[] interfaces, + ModuleBuilder module, + PackingSize iPackingSize, + int iTypeSize, + TypeBuilder enclosingType) + { + Init(name, attr, parent, interfaces, module, iPackingSize, iTypeSize, enclosingType); + } + + [System.Security.SecurityCritical] // auto-generated + private void Init(String fullname, TypeAttributes attr, Type parent, Type[] interfaces, ModuleBuilder module, + PackingSize iPackingSize, int iTypeSize, TypeBuilder enclosingType) + { + if (fullname == null) + throw new ArgumentNullException("fullname"); + + if (fullname.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "fullname"); + + if (fullname[0] == '\0') + throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), "fullname"); + + + if (fullname.Length > 1023) + throw new ArgumentException(Environment.GetResourceString("Argument_TypeNameTooLong"), "fullname"); + Contract.EndContractBlock(); + + int i; + m_module = module; + m_DeclaringType = enclosingType; + AssemblyBuilder containingAssem = m_module.ContainingAssemblyBuilder; + + // cannot have two types within the same assembly of the same name + containingAssem.m_assemblyData.CheckTypeNameConflict(fullname, enclosingType); + + if (enclosingType != null) + { + // Nested Type should have nested attribute set. + // If we are renumbering TypeAttributes' bit, we need to change the logic here. + if (((attr & TypeAttributes.VisibilityMask) == TypeAttributes.Public) ||((attr & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic)) + throw new ArgumentException(Environment.GetResourceString("Argument_BadNestedTypeFlags"), "attr"); + } + + int[] interfaceTokens = null; + if (interfaces != null) + { + for(i = 0; i < interfaces.Length; i++) + { + if (interfaces[i] == null) + { + // cannot contain null in the interface list + throw new ArgumentNullException("interfaces"); + } + } + interfaceTokens = new int[interfaces.Length + 1]; + for(i = 0; i < interfaces.Length; i++) + { + interfaceTokens[i] = m_module.GetTypeTokenInternal(interfaces[i]).Token; + } + } + + int iLast = fullname.LastIndexOf('.'); + if (iLast == -1 || iLast == 0) + { + // no name space + m_strNameSpace = String.Empty; + m_strName = fullname; + } + else + { + // split the name space + m_strNameSpace = fullname.Substring(0, iLast); + m_strName = fullname.Substring(iLast + 1); + } + + VerifyTypeAttributes(attr); + + m_iAttr = attr; + + SetParent(parent); + + m_listMethods = new List(); + m_lastTokenizedMethod = -1; + + SetInterfaces(interfaces); + + int tkParent = 0; + if (m_typeParent != null) + tkParent = m_module.GetTypeTokenInternal(m_typeParent).Token; + + int tkEnclosingType = 0; + if (enclosingType != null) + { + tkEnclosingType = enclosingType.m_tdType.Token; + } + + m_tdType = new TypeToken(DefineType(m_module.GetNativeHandle(), + fullname, tkParent, m_iAttr, tkEnclosingType, interfaceTokens)); + + m_iPackingSize = iPackingSize; + m_iTypeSize = iTypeSize; + if ((m_iPackingSize != 0) ||(m_iTypeSize != 0)) + SetClassLayout(GetModuleBuilder().GetNativeHandle(), m_tdType.Token, m_iPackingSize, m_iTypeSize); + +#if !FEATURE_CORECLR + // If the type is public and it is contained in a assemblyBuilder, + // update the public COMType list. + if (IsPublicComType(this)) + { + if (containingAssem.IsPersistable() && m_module.IsTransient() == false) + { + // This will throw InvalidOperationException if the assembly has been saved + // Ideally we should reject all emit operations if the assembly has been saved, + // but that would be a breaking change for some. Currently you cannot define + // modules and public types, but you can still define private types and global methods. + containingAssem.m_assemblyData.AddPublicComType(this); + } + + // Now add the type to the ExportedType table + if (!m_module.Equals(containingAssem.ManifestModule)) + containingAssem.DefineExportedTypeInMemory(this, m_module.m_moduleData.FileToken, m_tdType.Token); + } +#endif + m_module.AddType(FullName, this); + } + + #endregion + + #region Private Members + [System.Security.SecurityCritical] // auto-generated + private MethodBuilder DefinePInvokeMethodHelper( + String name, String dllName, String importName, MethodAttributes attributes, CallingConventions callingConvention, + Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, + Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers, + CallingConvention nativeCallConv, CharSet nativeCharSet) + { + CheckContext(returnType); + CheckContext(returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes); + CheckContext(parameterTypeRequiredCustomModifiers); + CheckContext(parameterTypeOptionalCustomModifiers); + + AppDomain.CheckDefinePInvokeSupported(); + + lock (SyncRoot) + { + return DefinePInvokeMethodHelperNoLock(name, dllName, importName, attributes, callingConvention, + returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, + parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, + nativeCallConv, nativeCharSet); + } + } + + [System.Security.SecurityCritical] // auto-generated + private MethodBuilder DefinePInvokeMethodHelperNoLock( + String name, String dllName, String importName, MethodAttributes attributes, CallingConventions callingConvention, + Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, + Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers, + CallingConvention nativeCallConv, CharSet nativeCharSet) + { + if (name == null) + throw new ArgumentNullException("name"); + + if (name.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + + if (dllName == null) + throw new ArgumentNullException("dllName"); + + if (dllName.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "dllName"); + + if (importName == null) + throw new ArgumentNullException("importName"); + + if (importName.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "importName"); + + if ((attributes & MethodAttributes.Abstract) != 0) + throw new ArgumentException(Environment.GetResourceString("Argument_BadPInvokeMethod")); + Contract.EndContractBlock(); + + if ((m_iAttr & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface) + throw new ArgumentException(Environment.GetResourceString("Argument_BadPInvokeOnInterface")); + + ThrowIfCreated(); + + attributes = attributes | MethodAttributes.PinvokeImpl; + MethodBuilder method = new MethodBuilder(name, attributes, callingConvention, + returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, + parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, + m_module, this, false); + + //The signature grabbing code has to be up here or the signature won't be finished + //and our equals check won't work. + int sigLength; + byte[] sigBytes = method.GetMethodSignature().InternalGetSignature(out sigLength); + + if (m_listMethods.Contains(method)) + { + throw new ArgumentException(Environment.GetResourceString("Argument_MethodRedefined")); + } + m_listMethods.Add(method); + + MethodToken token = method.GetToken(); + + int linkFlags = 0; + switch(nativeCallConv) + { + case CallingConvention.Winapi: + linkFlags =(int)PInvokeMap.CallConvWinapi; + break; + case CallingConvention.Cdecl: + linkFlags =(int)PInvokeMap.CallConvCdecl; + break; + case CallingConvention.StdCall: + linkFlags =(int)PInvokeMap.CallConvStdcall; + break; + case CallingConvention.ThisCall: + linkFlags =(int)PInvokeMap.CallConvThiscall; + break; + case CallingConvention.FastCall: + linkFlags =(int)PInvokeMap.CallConvFastcall; + break; + } + switch(nativeCharSet) + { + case CharSet.None: + linkFlags |=(int)PInvokeMap.CharSetNotSpec; + break; + case CharSet.Ansi: + linkFlags |=(int)PInvokeMap.CharSetAnsi; + break; + case CharSet.Unicode: + linkFlags |=(int)PInvokeMap.CharSetUnicode; + break; + case CharSet.Auto: + linkFlags |=(int)PInvokeMap.CharSetAuto; + break; + } + + SetPInvokeData(m_module.GetNativeHandle(), + dllName, + importName, + token.Token, + linkFlags); + method.SetToken(token); + + return method; + } + + [System.Security.SecurityCritical] // auto-generated + private FieldBuilder DefineDataHelper(String name, byte[] data, int size, FieldAttributes attributes) + { + String strValueClassName; + TypeBuilder valueClassType; + FieldBuilder fdBuilder; + TypeAttributes typeAttributes; + + if (name == null) + throw new ArgumentNullException("name"); + + if (name.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + + if (size <= 0 || size >= 0x003f0000) + throw new ArgumentException(Environment.GetResourceString("Argument_BadSizeForData")); + Contract.EndContractBlock(); + + ThrowIfCreated(); + + // form the value class name + strValueClassName = ModuleBuilderData.MULTI_BYTE_VALUE_CLASS + size.ToString(); + + // Is this already defined in this module? + Type temp = m_module.FindTypeBuilderWithName(strValueClassName, false); + valueClassType = temp as TypeBuilder; + + if (valueClassType == null) + { + typeAttributes = TypeAttributes.Public | TypeAttributes.ExplicitLayout | TypeAttributes.Class | TypeAttributes.Sealed | TypeAttributes.AnsiClass; + + // Define the backing value class + valueClassType = m_module.DefineType(strValueClassName, typeAttributes, typeof(System.ValueType), PackingSize.Size1, size); + valueClassType.CreateType(); + } + + fdBuilder = DefineField(name, valueClassType,(attributes | FieldAttributes.Static)); + + // now we need to set the RVA + fdBuilder.SetData(data, size); + return fdBuilder; + } + + private void VerifyTypeAttributes(TypeAttributes attr) + { + // Verify attr consistency for Nesting or otherwise. + if (DeclaringType == null) + { + // Not a nested class. + if (((attr & TypeAttributes.VisibilityMask) != TypeAttributes.NotPublic) &&((attr & TypeAttributes.VisibilityMask) != TypeAttributes.Public)) + { + throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeAttrNestedVisibilityOnNonNestedType")); + } + } + else + { + // Nested class. + if (((attr & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic) ||((attr & TypeAttributes.VisibilityMask) == TypeAttributes.Public)) + { + throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeAttrNonNestedVisibilityNestedType")); + } + } + + // Verify that the layout mask is valid. + if (((attr & TypeAttributes.LayoutMask) != TypeAttributes.AutoLayout) &&((attr & TypeAttributes.LayoutMask) != TypeAttributes.SequentialLayout) &&((attr & TypeAttributes.LayoutMask) != TypeAttributes.ExplicitLayout)) + { + throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeAttrInvalidLayout")); + } + + // Check if the user attempted to set any reserved bits. + if ((attr & TypeAttributes.ReservedMask) != 0) + { + throw new ArgumentException(Environment.GetResourceString("Argument_BadTypeAttrReservedBitsSet")); + } + } + + [Pure] + public bool IsCreated() + { + return m_hasBeenCreated; + } + + #endregion + + #region FCalls + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static int DefineType(RuntimeModule module, + String fullname, int tkParent, TypeAttributes attributes, int tkEnclosingType, int[] interfaceTokens); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private extern static int DefineGenericParam(RuntimeModule module, + String name, int tkParent, GenericParameterAttributes attributes, int position, int[] constraints); + + [System.Security.SecurityCritical] // auto-generated + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + [SuppressUnmanagedCodeSecurity] + private static extern void TermCreateClass(RuntimeModule module, int tk, ObjectHandleOnStack type); + #endregion + + #region Internal Methods + internal void ThrowIfCreated() + { + if (IsCreated()) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_TypeHasBeenCreated")); + } + + internal object SyncRoot + { + get + { + return m_module.SyncRoot; + } + } + + internal ModuleBuilder GetModuleBuilder() + { + return m_module; + } + + internal RuntimeType BakedRuntimeType + { + get + { + return m_bakedRuntimeType; + } + } + + internal void SetGenParamAttributes(GenericParameterAttributes genericParameterAttributes) + { + m_genParamAttributes = genericParameterAttributes; + } + + internal void SetGenParamCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + { + CustAttr ca = new CustAttr(con, binaryAttribute); + + lock(SyncRoot) + { + SetGenParamCustomAttributeNoLock(ca); + } + } + + internal void SetGenParamCustomAttribute(CustomAttributeBuilder customBuilder) + { + CustAttr ca = new CustAttr(customBuilder); + + lock(SyncRoot) + { + SetGenParamCustomAttributeNoLock(ca); + } + } + + private void SetGenParamCustomAttributeNoLock(CustAttr ca) + { + if (m_ca == null) + m_ca = new List(); + + m_ca.Add(ca); + } + #endregion + + #region Object Overrides + public override String ToString() + { + return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.ToString); + } + + #endregion + + #region MemberInfo Overrides + public override Type DeclaringType + { + get { return m_DeclaringType; } + } + + public override Type ReflectedType + { + // Return the class that was used to obtain this field. + + get { return m_DeclaringType; } + } + + public override String Name + { + get { return m_strName; } + } + + public override Module Module + { + get { return GetModuleBuilder(); } + } + + internal int MetadataTokenInternal + { + get { return m_tdType.Token; } + } + + #endregion + + #region Type Overrides + public override Guid GUID + { + get + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GUID; + } + } + + public override Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, + Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters); + } + + public override Assembly Assembly + { + get { return m_module.Assembly; } + } + + public override RuntimeTypeHandle TypeHandle + { + + get { throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); } + } + + public override String FullName + { + get + { + if (m_strFullQualName == null) + m_strFullQualName = TypeNameBuilder.ToString(this, TypeNameBuilder.Format.FullName); + + return m_strFullQualName; + } + } + + public override String Namespace + { + get { return m_strNameSpace; } + } + + public override String AssemblyQualifiedName + { + get + { + return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.AssemblyQualifiedName); + } + } + + public override Type BaseType + { + get{ return m_typeParent; } + } + + protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr,Binder binder, + CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GetConstructor(bindingAttr, binder, callConvention, types, modifiers); + } + + [System.Runtime.InteropServices.ComVisible(true)] + public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GetConstructors(bindingAttr); + } + + protected override MethodInfo GetMethodImpl(String name,BindingFlags bindingAttr,Binder binder, + CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + if (types == null) + { + return m_bakedRuntimeType.GetMethod(name, bindingAttr); + } + else + { + return m_bakedRuntimeType.GetMethod(name, bindingAttr, binder, callConvention, types, modifiers); + } + } + + public override MethodInfo[] GetMethods(BindingFlags bindingAttr) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GetMethods(bindingAttr); + } + + public override FieldInfo GetField(String name, BindingFlags bindingAttr) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GetField(name, bindingAttr); + } + + public override FieldInfo[] GetFields(BindingFlags bindingAttr) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GetFields(bindingAttr); + } + + public override Type GetInterface(String name,bool ignoreCase) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GetInterface(name, ignoreCase); + } + + public override Type[] GetInterfaces() + { + if (m_bakedRuntimeType != null) + { + return m_bakedRuntimeType.GetInterfaces(); + } + + if (m_typeInterfaces == null) + { + return EmptyArray.Value; + } + + return m_typeInterfaces.ToArray(); + } + + public override EventInfo GetEvent(String name,BindingFlags bindingAttr) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GetEvent(name, bindingAttr); + } + + public override EventInfo[] GetEvents() + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GetEvents(); + } + + protected override PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, + Type returnType, Type[] types, ParameterModifier[] modifiers) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GetProperties(bindingAttr); + } + + public override Type[] GetNestedTypes(BindingFlags bindingAttr) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GetNestedTypes(bindingAttr); + } + + public override Type GetNestedType(String name, BindingFlags bindingAttr) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GetNestedType(name,bindingAttr); + } + + public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GetMember(name, type, bindingAttr); + } + + [System.Runtime.InteropServices.ComVisible(true)] + public override InterfaceMapping GetInterfaceMap(Type interfaceType) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GetInterfaceMap(interfaceType); + } + + public override EventInfo[] GetEvents(BindingFlags bindingAttr) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GetEvents(bindingAttr); + } + + public override MemberInfo[] GetMembers(BindingFlags bindingAttr) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.GetMembers(bindingAttr); + } + + public override bool IsAssignableFrom(Type c) + { + if (TypeBuilder.IsTypeEqual(c, this)) + return true; + + Type fromRuntimeType = null; + TypeBuilder fromTypeBuilder = c as TypeBuilder; + + if (fromTypeBuilder != null) + fromRuntimeType = fromTypeBuilder.m_bakedRuntimeType; + else + fromRuntimeType = c; + + if (fromRuntimeType != null && fromRuntimeType is RuntimeType) + { + // fromType is baked. So if this type is not baked, it cannot be assignable to! + if (m_bakedRuntimeType == null) + return false; + + // since toType is also baked, delegate to the base + return m_bakedRuntimeType.IsAssignableFrom(fromRuntimeType); + } + + // So if c is not a runtimeType nor TypeBuilder. We don't know how to deal with it. + // return false then. + if (fromTypeBuilder == null) + return false; + + // If fromTypeBuilder is a subclass of this class, then c can be cast to this type. + if (fromTypeBuilder.IsSubclassOf(this)) + return true; + + if (this.IsInterface == false) + return false; + + // now is This type a base type on one of the interface impl? + Type[] interfaces = fromTypeBuilder.GetInterfaces(); + for(int i = 0; i < interfaces.Length; i++) + { + // unfortunately, IsSubclassOf does not cover the case when they are the same type. + if (TypeBuilder.IsTypeEqual(interfaces[i], this)) + return true; + + if (interfaces[i].IsSubclassOf(this)) + return true; + } + return false; + } + + protected override TypeAttributes GetAttributeFlagsImpl() + { + return m_iAttr; + } + + protected override bool IsArrayImpl() + { + return false; + } + protected override bool IsByRefImpl() + { + return false; + } + protected override bool IsPointerImpl() + { + return false; + } + protected override bool IsPrimitiveImpl() + { + return false; + } + + protected override bool IsCOMObjectImpl() + { + return((GetAttributeFlagsImpl() & TypeAttributes.Import) != 0) ? true : false; + } + + public override Type GetElementType() + { + + // You will never have to deal with a TypeBuilder if you are just referring to arrays. + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + } + + protected override bool HasElementTypeImpl() + { + return false; + } + + public override bool IsSecurityCritical + { + get + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.IsSecurityCritical; + } + } + + public override bool IsSecuritySafeCritical + { + get + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.IsSecuritySafeCritical; + } + } + + public override bool IsSecurityTransparent + { + get + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return m_bakedRuntimeType.IsSecurityTransparent; + } + } + + [System.Runtime.InteropServices.ComVisible(true)] + [Pure] + public override bool IsSubclassOf(Type c) + { + Type p = this; + + if (TypeBuilder.IsTypeEqual(p, c)) + return false; + + p = p.BaseType; + + while(p != null) + { + if (TypeBuilder.IsTypeEqual(p, c)) + return true; + + p = p.BaseType; + } + + return false; + } + + public override Type UnderlyingSystemType + { + get + { + if (m_bakedRuntimeType != null) + return m_bakedRuntimeType; + + if (IsEnum) + { + if (m_enumUnderlyingType == null) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoUnderlyingTypeOnEnum")); + + return m_enumUnderlyingType; + } + else + { + return this; + } + } + } + + public override Type MakePointerType() + { + return SymbolType.FormCompoundType("*", this, 0); + } + + public override Type MakeByRefType() + { + return SymbolType.FormCompoundType("&", this, 0); + } + + public override Type MakeArrayType() + { + return SymbolType.FormCompoundType("[]", this, 0); + } + + public override Type MakeArrayType(int rank) + { + if (rank <= 0) + throw new IndexOutOfRangeException(); + Contract.EndContractBlock(); + + string szrank = ""; + if (rank == 1) + { + szrank = "*"; + } + else + { + for(int i = 1; i < rank; i++) + szrank += ","; + } + + string s = String.Format(CultureInfo.InvariantCulture, "[{0}]", szrank); // [,,] + return SymbolType.FormCompoundType(s, this, 0); + } + + #endregion + + #region ICustomAttributeProvider Implementation + [System.Security.SecuritySafeCritical] // auto-generated + public override Object[] GetCustomAttributes(bool inherit) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + Contract.EndContractBlock(); + + return CustomAttribute.GetCustomAttributes(m_bakedRuntimeType, typeof(object) as RuntimeType, inherit); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType"); + + return CustomAttribute.GetCustomAttributes(m_bakedRuntimeType, attributeRuntimeType, inherit); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public override bool IsDefined(Type attributeType, bool inherit) + { + if (!IsCreated()) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_TypeNotYetCreated")); + + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"caType"); + + return CustomAttribute.IsDefined(m_bakedRuntimeType, attributeRuntimeType, inherit); + } + + #endregion + + #region Public Member + + #region DefineType + public override GenericParameterAttributes GenericParameterAttributes { get { return m_genParamAttributes; } } + + internal void SetInterfaces(params Type[] interfaces) + { + ThrowIfCreated(); + + m_typeInterfaces = new List(); + if (interfaces != null) + { + m_typeInterfaces.AddRange(interfaces); + } + } + + + public GenericTypeParameterBuilder[] DefineGenericParameters(params string[] names) + { + if (names == null) + throw new ArgumentNullException("names"); + + if (names.Length == 0) + throw new ArgumentException(); + Contract.EndContractBlock(); + + for (int i = 0; i < names.Length; i ++) + if (names[i] == null) + throw new ArgumentNullException("names"); + + if (m_inst != null) + throw new InvalidOperationException(); + + m_inst = new GenericTypeParameterBuilder[names.Length]; + for(int i = 0; i < names.Length; i ++) + m_inst[i] = new GenericTypeParameterBuilder(new TypeBuilder(names[i], i, this)); + + return m_inst; + } + + + public override Type MakeGenericType(params Type[] typeArguments) + { + CheckContext(typeArguments); + + return TypeBuilderInstantiation.MakeGenericType(this, typeArguments); + } + + public override Type[] GetGenericArguments() { return m_inst; } + // If a TypeBuilder is generic, it must be a generic type definition + // All instantiated generic types are TypeBuilderInstantiation. + public override bool IsGenericTypeDefinition { get { return IsGenericType; } } + public override bool IsGenericType { get { return m_inst != null; } } + public override bool IsGenericParameter { get { return m_bIsGenParam; } } + public override bool IsConstructedGenericType { get { return false; } } + + public override int GenericParameterPosition { get { return m_genParamPos; } } + public override MethodBase DeclaringMethod { get { return m_declMeth; } } + public override Type GetGenericTypeDefinition() { if (IsGenericTypeDefinition) return this; if (m_genTypeDef == null) throw new InvalidOperationException(); return m_genTypeDef; } + #endregion + + #region Define Method + [System.Security.SecuritySafeCritical] // auto-generated + public void DefineMethodOverride(MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration) + { + lock(SyncRoot) + { + DefineMethodOverrideNoLock(methodInfoBody, methodInfoDeclaration); + } + } + + [System.Security.SecurityCritical] // auto-generated + private void DefineMethodOverrideNoLock(MethodInfo methodInfoBody, MethodInfo methodInfoDeclaration) + { + if (methodInfoBody == null) + throw new ArgumentNullException("methodInfoBody"); + + if (methodInfoDeclaration == null) + throw new ArgumentNullException("methodInfoDeclaration"); + Contract.EndContractBlock(); + + ThrowIfCreated(); + + if (!object.ReferenceEquals(methodInfoBody.DeclaringType, this)) + // Loader restriction: body method has to be from this class + throw new ArgumentException(Environment.GetResourceString("ArgumentException_BadMethodImplBody")); + + MethodToken tkBody; + MethodToken tkDecl; + + tkBody = m_module.GetMethodTokenInternal(methodInfoBody); + tkDecl = m_module.GetMethodTokenInternal(methodInfoDeclaration); + + DefineMethodImpl(m_module.GetNativeHandle(), m_tdType.Token, tkBody.Token, tkDecl.Token); + } + + public MethodBuilder DefineMethod(String name, MethodAttributes attributes, Type returnType, Type[] parameterTypes) + { + Contract.Ensures(Contract.Result() != null); + + return DefineMethod(name, attributes, CallingConventions.Standard, returnType, parameterTypes); + } + + public MethodBuilder DefineMethod(String name, MethodAttributes attributes) + { + Contract.Ensures(Contract.Result() != null); + + return DefineMethod(name, attributes, CallingConventions.Standard, null, null); + } + + public MethodBuilder DefineMethod(String name, MethodAttributes attributes, CallingConventions callingConvention) + { + Contract.Ensures(Contract.Result() != null); + + return DefineMethod(name, attributes, callingConvention, null, null); + } + + public MethodBuilder DefineMethod(String name, MethodAttributes attributes, CallingConventions callingConvention, + Type returnType, Type[] parameterTypes) + { + Contract.Ensures(Contract.Result() != null); + + return DefineMethod(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null); + } + + public MethodBuilder DefineMethod(String name, MethodAttributes attributes, CallingConventions callingConvention, + Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, + Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) + { + Contract.Ensures(Contract.Result() != null); + + lock(SyncRoot) + { + return DefineMethodNoLock(name, attributes, callingConvention, returnType, returnTypeRequiredCustomModifiers, + returnTypeOptionalCustomModifiers, parameterTypes, parameterTypeRequiredCustomModifiers, + parameterTypeOptionalCustomModifiers); + } + } + + private MethodBuilder DefineMethodNoLock(String name, MethodAttributes attributes, CallingConventions callingConvention, + Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, + Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) + { + if (name == null) + throw new ArgumentNullException("name"); + + if (name.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + Contract.Ensures(Contract.Result() != null); + Contract.EndContractBlock(); + + CheckContext(returnType); + CheckContext(returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes); + CheckContext(parameterTypeRequiredCustomModifiers); + CheckContext(parameterTypeOptionalCustomModifiers); + + if (parameterTypes != null) + { + if (parameterTypeOptionalCustomModifiers != null && parameterTypeOptionalCustomModifiers.Length != parameterTypes.Length) + throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", "parameterTypeOptionalCustomModifiers", "parameterTypes")); + + if (parameterTypeRequiredCustomModifiers != null && parameterTypeRequiredCustomModifiers.Length != parameterTypes.Length) + throw new ArgumentException(Environment.GetResourceString("Argument_MismatchedArrays", "parameterTypeRequiredCustomModifiers", "parameterTypes")); + } + + ThrowIfCreated(); + + if (!m_isHiddenGlobalType) + { + if (((m_iAttr & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface) && + (attributes & MethodAttributes.Abstract) == 0 &&(attributes & MethodAttributes.Static) == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_BadAttributeOnInterfaceMethod")); + } + + // pass in Method attributes + MethodBuilder method = new MethodBuilder( + name, attributes, callingConvention, + returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, + parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, + m_module, this, false); + + if (!m_isHiddenGlobalType) + { + //If this method is declared to be a constructor, increment our constructor count. + if ((method.Attributes & MethodAttributes.SpecialName) != 0 && method.Name.Equals(ConstructorInfo.ConstructorName)) + { + m_constructorCount++; + } + } + + m_listMethods.Add(method); + + return method; + } + + #endregion + + #region Define Constructor + [System.Security.SecuritySafeCritical] // auto-generated + [System.Runtime.InteropServices.ComVisible(true)] + public ConstructorBuilder DefineTypeInitializer() + { + lock(SyncRoot) + { + return DefineTypeInitializerNoLock(); + } + } + + [System.Security.SecurityCritical] // auto-generated + private ConstructorBuilder DefineTypeInitializerNoLock() + { + ThrowIfCreated(); + + // change the attributes and the class constructor's name + MethodAttributes attr = MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.SpecialName; + + ConstructorBuilder constBuilder = new ConstructorBuilder( + ConstructorInfo.TypeConstructorName, attr, CallingConventions.Standard, null, m_module, this); + + return constBuilder; + } + + [System.Runtime.InteropServices.ComVisible(true)] + public ConstructorBuilder DefineDefaultConstructor(MethodAttributes attributes) + { + if ((m_iAttr & TypeAttributes.Interface) == TypeAttributes.Interface) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ConstructorNotAllowedOnInterface")); + } + + lock(SyncRoot) + { + return DefineDefaultConstructorNoLock(attributes); + } + } + + private ConstructorBuilder DefineDefaultConstructorNoLock(MethodAttributes attributes) + { + ConstructorBuilder constBuilder; + + // get the parent class's default constructor + // We really don't want(BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic) here. We really want + // constructors visible from the subclass, but that is not currently + // available in BindingFlags. This more open binding is open to + // runtime binding failures(like if we resolve to a private + // constructor). + ConstructorInfo con = null; + + if (m_typeParent is TypeBuilderInstantiation) + { + Type genericTypeDefinition = m_typeParent.GetGenericTypeDefinition(); + + if (genericTypeDefinition is TypeBuilder) + genericTypeDefinition = ((TypeBuilder)genericTypeDefinition).m_bakedRuntimeType; + + if (genericTypeDefinition == null) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_DynamicModule")); + + Type inst = genericTypeDefinition.MakeGenericType(m_typeParent.GetGenericArguments()); + + if (inst is TypeBuilderInstantiation) + con = TypeBuilder.GetConstructor(inst, genericTypeDefinition.GetConstructor( + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null)); + else + con = inst.GetConstructor( + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); + } + + if (con == null) + { + con = m_typeParent.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null); + } + + if (con == null) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_NoParentDefaultConstructor")); + + // Define the constructor Builder + constBuilder = DefineConstructor(attributes, CallingConventions.Standard, null); + m_constructorCount++; + + // generate the code to call the parent's default constructor + ILGenerator il = constBuilder.GetILGenerator(); + il.Emit(OpCodes.Ldarg_0); + il.Emit(OpCodes.Call,con); + il.Emit(OpCodes.Ret); + + constBuilder.m_isDefaultConstructor = true; + return constBuilder; + } + + [System.Runtime.InteropServices.ComVisible(true)] + public ConstructorBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, Type[] parameterTypes) + { + return DefineConstructor(attributes, callingConvention, parameterTypes, null, null); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [System.Runtime.InteropServices.ComVisible(true)] + public ConstructorBuilder DefineConstructor(MethodAttributes attributes, CallingConventions callingConvention, + Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers) + { + if ((m_iAttr & TypeAttributes.Interface) == TypeAttributes.Interface && (attributes & MethodAttributes.Static) != MethodAttributes.Static) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_ConstructorNotAllowedOnInterface")); + } + + lock(SyncRoot) + { + return DefineConstructorNoLock(attributes, callingConvention, parameterTypes, requiredCustomModifiers, optionalCustomModifiers); + } + } + + [System.Security.SecurityCritical] // auto-generated + private ConstructorBuilder DefineConstructorNoLock(MethodAttributes attributes, CallingConventions callingConvention, + Type[] parameterTypes, Type[][] requiredCustomModifiers, Type[][] optionalCustomModifiers) + { + CheckContext(parameterTypes); + CheckContext(requiredCustomModifiers); + CheckContext(optionalCustomModifiers); + + ThrowIfCreated(); + + String name; + + if ((attributes & MethodAttributes.Static) == 0) + { + name = ConstructorInfo.ConstructorName; + } + else + { + name = ConstructorInfo.TypeConstructorName; + } + + attributes = attributes | MethodAttributes.SpecialName; + + ConstructorBuilder constBuilder = + new ConstructorBuilder(name, attributes, callingConvention, + parameterTypes, requiredCustomModifiers, optionalCustomModifiers, m_module, this); + + m_constructorCount++; + + return constBuilder; + } + + #endregion + + #region Define PInvoke +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public MethodBuilder DefinePInvokeMethod(String name, String dllName, MethodAttributes attributes, + CallingConventions callingConvention, Type returnType, Type[] parameterTypes, + CallingConvention nativeCallConv, CharSet nativeCharSet) + { + MethodBuilder method = DefinePInvokeMethodHelper( + name, dllName, name, attributes, callingConvention, returnType, null, null, + parameterTypes, null, null, nativeCallConv, nativeCharSet); + return method; + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public MethodBuilder DefinePInvokeMethod(String name, String dllName, String entryName, MethodAttributes attributes, + CallingConventions callingConvention, Type returnType, Type[] parameterTypes, + CallingConvention nativeCallConv, CharSet nativeCharSet) + { + MethodBuilder method = DefinePInvokeMethodHelper( + name, dllName, entryName, attributes, callingConvention, returnType, null, null, + parameterTypes, null, null, nativeCallConv, nativeCharSet); + return method; + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public MethodBuilder DefinePInvokeMethod(String name, String dllName, String entryName, MethodAttributes attributes, + CallingConventions callingConvention, + Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, + Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers, + CallingConvention nativeCallConv, CharSet nativeCharSet) + { + MethodBuilder method = DefinePInvokeMethodHelper( + name, dllName, entryName, attributes, callingConvention, returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, + parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers, nativeCallConv, nativeCharSet); + return method; + } + + #endregion + + #region Define Nested Type + [System.Security.SecuritySafeCritical] // auto-generated + public TypeBuilder DefineNestedType(String name) + { + lock(SyncRoot) + { + return DefineNestedTypeNoLock(name, TypeAttributes.NestedPrivate, null, null, PackingSize.Unspecified, UnspecifiedTypeSize); + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + [System.Runtime.InteropServices.ComVisible(true)] + public TypeBuilder DefineNestedType(String name, TypeAttributes attr, Type parent, Type[] interfaces) + { + lock(SyncRoot) + { + // Why do we only call CheckContext here? Why don't we call it in the other overloads? + CheckContext(parent); + CheckContext(interfaces); + + return DefineNestedTypeNoLock(name, attr, parent, interfaces, PackingSize.Unspecified, UnspecifiedTypeSize); + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + public TypeBuilder DefineNestedType(String name, TypeAttributes attr, Type parent) + { + lock(SyncRoot) + { + return DefineNestedTypeNoLock(name, attr, parent, null, PackingSize.Unspecified, UnspecifiedTypeSize); + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + public TypeBuilder DefineNestedType(String name, TypeAttributes attr) + { + lock(SyncRoot) + { + return DefineNestedTypeNoLock(name, attr, null, null, PackingSize.Unspecified, UnspecifiedTypeSize); + } + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public TypeBuilder DefineNestedType(String name, TypeAttributes attr, Type parent, int typeSize) + { + lock(SyncRoot) + { + return DefineNestedTypeNoLock(name, attr, parent, null, PackingSize.Unspecified, typeSize); + } + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public TypeBuilder DefineNestedType(String name, TypeAttributes attr, Type parent, PackingSize packSize) + { + lock(SyncRoot) + { + return DefineNestedTypeNoLock(name, attr, parent, null, packSize, UnspecifiedTypeSize); + } + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public TypeBuilder DefineNestedType(String name, TypeAttributes attr, Type parent, PackingSize packSize, int typeSize) + { + lock (SyncRoot) + { + return DefineNestedTypeNoLock(name, attr, parent, null, packSize, typeSize); + } + } + + [System.Security.SecurityCritical] // auto-generated + private TypeBuilder DefineNestedTypeNoLock(String name, TypeAttributes attr, Type parent, Type[] interfaces, PackingSize packSize, int typeSize) + { + return new TypeBuilder(name, attr, parent, interfaces, m_module, packSize, typeSize, this); + } + + #endregion + + #region Define Field + public FieldBuilder DefineField(String fieldName, Type type, FieldAttributes attributes) + { + return DefineField(fieldName, type, null, null, attributes); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public FieldBuilder DefineField(String fieldName, Type type, Type[] requiredCustomModifiers, + Type[] optionalCustomModifiers, FieldAttributes attributes) + { + lock(SyncRoot) + { + return DefineFieldNoLock(fieldName, type, requiredCustomModifiers, optionalCustomModifiers, attributes); + } + } + + [System.Security.SecurityCritical] // auto-generated + private FieldBuilder DefineFieldNoLock(String fieldName, Type type, Type[] requiredCustomModifiers, + Type[] optionalCustomModifiers, FieldAttributes attributes) + { + ThrowIfCreated(); + CheckContext(type); + CheckContext(requiredCustomModifiers); + + if (m_enumUnderlyingType == null && IsEnum == true) + { + if ((attributes & FieldAttributes.Static) == 0) + { + // remember the underlying type for enum type + m_enumUnderlyingType = type; + } + } + + return new FieldBuilder(this, fieldName, type, requiredCustomModifiers, optionalCustomModifiers, attributes); + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public FieldBuilder DefineInitializedData(String name, byte[] data, FieldAttributes attributes) + { + lock(SyncRoot) + { + return DefineInitializedDataNoLock(name, data, attributes); + } + } + + [System.Security.SecurityCritical] // auto-generated + private FieldBuilder DefineInitializedDataNoLock(String name, byte[] data, FieldAttributes attributes) + { + if (data == null) + throw new ArgumentNullException("data"); + Contract.EndContractBlock(); + + // This method will define an initialized Data in .sdata. + // We will create a fake TypeDef to represent the data with size. This TypeDef + // will be the signature for the Field. + + return DefineDataHelper(name, data, data.Length, attributes); + } + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + public FieldBuilder DefineUninitializedData(String name, int size, FieldAttributes attributes) + { + lock(SyncRoot) + { + return DefineUninitializedDataNoLock(name, size, attributes); + } + } + + [System.Security.SecurityCritical] // auto-generated + private FieldBuilder DefineUninitializedDataNoLock(String name, int size, FieldAttributes attributes) + { + // This method will define an uninitialized Data in .sdata. + // We will create a fake TypeDef to represent the data with size. This TypeDef + // will be the signature for the Field. + return DefineDataHelper(name, null, size, attributes); + } + + #endregion + + #region Define Properties and Events + public PropertyBuilder DefineProperty(String name, PropertyAttributes attributes, Type returnType, Type[] parameterTypes) + { + return DefineProperty(name, attributes, returnType, null, null, parameterTypes, null, null); + } + + public PropertyBuilder DefineProperty(String name, PropertyAttributes attributes, + CallingConventions callingConvention, Type returnType, Type[] parameterTypes) + { + return DefineProperty(name, attributes, callingConvention, returnType, null, null, parameterTypes, null, null); + } + + + public PropertyBuilder DefineProperty(String name, PropertyAttributes attributes, + Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, + Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) + { + return DefineProperty(name, attributes, (CallingConventions)0, returnType, + returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, + parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public PropertyBuilder DefineProperty(String name, PropertyAttributes attributes, CallingConventions callingConvention, + Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, + Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) + { + lock(SyncRoot) + { + return DefinePropertyNoLock(name, attributes, callingConvention, returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, + parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers); + } + } + + [System.Security.SecurityCritical] // auto-generated + private PropertyBuilder DefinePropertyNoLock(String name, PropertyAttributes attributes, CallingConventions callingConvention, + Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, + Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers) + { + if (name == null) + throw new ArgumentNullException("name"); + if (name.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + Contract.EndContractBlock(); + + CheckContext(returnType); + CheckContext(returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, parameterTypes); + CheckContext(parameterTypeRequiredCustomModifiers); + CheckContext(parameterTypeOptionalCustomModifiers); + + SignatureHelper sigHelper; + int sigLength; + byte[] sigBytes; + + ThrowIfCreated(); + + // get the signature in SignatureHelper form + sigHelper = SignatureHelper.GetPropertySigHelper( + m_module, callingConvention, + returnType, returnTypeRequiredCustomModifiers, returnTypeOptionalCustomModifiers, + parameterTypes, parameterTypeRequiredCustomModifiers, parameterTypeOptionalCustomModifiers); + + // get the signature in byte form + sigBytes = sigHelper.InternalGetSignature(out sigLength); + + PropertyToken prToken = new PropertyToken(DefineProperty( + m_module.GetNativeHandle(), + m_tdType.Token, + name, + attributes, + sigBytes, + sigLength)); + + // create the property builder now. + return new PropertyBuilder( + m_module, + name, + sigHelper, + attributes, + returnType, + prToken, + this); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public EventBuilder DefineEvent(String name, EventAttributes attributes, Type eventtype) + { + lock(SyncRoot) + { + return DefineEventNoLock(name, attributes, eventtype); + } + } + + [System.Security.SecurityCritical] // auto-generated + private EventBuilder DefineEventNoLock(String name, EventAttributes attributes, Type eventtype) + { + if (name == null) + throw new ArgumentNullException("name"); + if (name.Length == 0) + throw new ArgumentException(Environment.GetResourceString("Argument_EmptyName"), "name"); + if (name[0] == '\0') + throw new ArgumentException(Environment.GetResourceString("Argument_IllegalName"), "name"); + Contract.EndContractBlock(); + + int tkType; + EventToken evToken; + + CheckContext(eventtype); + + ThrowIfCreated(); + + tkType = m_module.GetTypeTokenInternal( eventtype ).Token; + + // Internal helpers to define property records + evToken = new EventToken(DefineEvent( + m_module.GetNativeHandle(), + m_tdType.Token, + name, + attributes, + tkType)); + + // create the property builder now. + return new EventBuilder( + m_module, + name, + attributes, + //tkType, + this, + evToken); + } + + #endregion + + #region Create Type + + [System.Security.SecuritySafeCritical] // auto-generated + public TypeInfo CreateTypeInfo() + { + lock (SyncRoot) + { + return CreateTypeNoLock(); + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + public Type CreateType() + { + lock (SyncRoot) + { + return CreateTypeNoLock(); + } + } + + internal void CheckContext(params Type[][] typess) + { + m_module.CheckContext(typess); + } + internal void CheckContext(params Type[] types) + { + m_module.CheckContext(types); + } + + [System.Security.SecurityCritical] // auto-generated + private TypeInfo CreateTypeNoLock() + { + if (IsCreated()) + return m_bakedRuntimeType; + + ThrowIfCreated(); + + if (m_typeInterfaces == null) + m_typeInterfaces = new List(); + + int[] interfaceTokens = new int[m_typeInterfaces.Count]; + for(int i = 0; i < m_typeInterfaces.Count; i++) + { + interfaceTokens[i] = m_module.GetTypeTokenInternal(m_typeInterfaces[i]).Token; + } + + int tkParent = 0; + if (m_typeParent != null) + tkParent = m_module.GetTypeTokenInternal(m_typeParent).Token; + + if (IsGenericParameter) + { + int[] constraints; // Array of token constrains terminated by null token + + if (m_typeParent != null) + { + constraints = new int[m_typeInterfaces.Count + 2]; + constraints[constraints.Length - 2] = tkParent; + } + else + { + constraints = new int[m_typeInterfaces.Count + 1]; + } + + for (int i = 0; i < m_typeInterfaces.Count; i++) + { + constraints[i] = m_module.GetTypeTokenInternal(m_typeInterfaces[i]).Token; + } + + int declMember = m_declMeth == null ? m_DeclaringType.m_tdType.Token : m_declMeth.GetToken().Token; + m_tdType = new TypeToken(DefineGenericParam(m_module.GetNativeHandle(), + m_strName, declMember, m_genParamAttributes, m_genParamPos, constraints)); + + if (m_ca != null) + { + foreach (CustAttr ca in m_ca) + ca.Bake(m_module, MetadataTokenInternal); + } + + m_hasBeenCreated = true; + + // Baking a generic parameter does not put sufficient information into the metadata to actually be able to load it as a type, + // the associated generic type/method needs to be baked first. So we return this rather than the baked type. + return this; + } + else + { + // Check for global typebuilder + if (((m_tdType.Token & 0x00FFFFFF) != 0) && ((tkParent & 0x00FFFFFF) != 0)) + SetParentType(m_module.GetNativeHandle(), m_tdType.Token, tkParent); + + if (m_inst != null) + foreach (Type tb in m_inst) + if (tb is GenericTypeParameterBuilder) + ((GenericTypeParameterBuilder)tb).m_type.CreateType(); + } + + byte [] body; + MethodAttributes methodAttrs; + + if (!m_isHiddenGlobalType) + { + // create a public default constructor if this class has no constructor. + // except if the type is Interface, ValueType, Enum, or a static class. + if (m_constructorCount == 0 && ((m_iAttr & TypeAttributes.Interface) == 0) && !IsValueType && ((m_iAttr & (TypeAttributes.Abstract | TypeAttributes.Sealed)) != (TypeAttributes.Abstract | TypeAttributes.Sealed))) + { + DefineDefaultConstructor(MethodAttributes.Public); + } + } + + int size = m_listMethods.Count; + + for(int i = 0; i < size; i++) + { + MethodBuilder meth = m_listMethods[i]; + + + if (meth.IsGenericMethodDefinition) + meth.GetToken(); // Doubles as "CreateMethod" for MethodBuilder -- analagous to CreateType() + + methodAttrs = meth.Attributes; + + // Any of these flags in the implemenation flags is set, we will not attach the IL method body + if (((meth.GetMethodImplementationFlags() &(MethodImplAttributes.CodeTypeMask|MethodImplAttributes.PreserveSig|MethodImplAttributes.Unmanaged)) != MethodImplAttributes.IL) || + ((methodAttrs & MethodAttributes.PinvokeImpl) !=(MethodAttributes) 0)) + { + continue; + } + + int sigLength; + byte[] localSig = meth.GetLocalSignature(out sigLength); + + // Check that they haven't declared an abstract method on a non-abstract class + if (((methodAttrs & MethodAttributes.Abstract) != 0) &&((m_iAttr & TypeAttributes.Abstract) == 0)) + { + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadTypeAttributesNotAbstract")); + } + + body = meth.GetBody(); + + // If this is an abstract method or an interface, we don't need to set the IL. + + if ((methodAttrs & MethodAttributes.Abstract) != 0) + { + // We won't check on Interface because we can have class static initializer on interface. + // We will just let EE or validator to catch the problem. + + //((m_iAttr & TypeAttributes.ClassSemanticsMask) == TypeAttributes.Interface)) + + if (body != null) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadMethodBody")); + } + else if (body == null || body.Length == 0) + { + // If it's not an abstract or an interface, set the IL. + if (meth.m_ilGenerator != null) + { + // we need to bake the method here. + meth.CreateMethodBodyHelper(meth.GetILGenerator()); + } + + body = meth.GetBody(); + + if ((body == null || body.Length == 0) && !meth.m_canBeRuntimeImpl) + throw new InvalidOperationException( + Environment.GetResourceString("InvalidOperation_BadEmptyMethodBody", meth.Name) ); + } + + int maxStack = meth.GetMaxStack(); + + ExceptionHandler[] exceptions = meth.GetExceptionHandlers(); + int[] tokenFixups = meth.GetTokenFixups(); + + SetMethodIL(m_module.GetNativeHandle(), meth.GetToken().Token, meth.InitLocals, + body, (body != null) ? body.Length : 0, + localSig, sigLength, maxStack, + exceptions, (exceptions != null) ? exceptions.Length : 0, + tokenFixups, (tokenFixups != null) ? tokenFixups.Length : 0); + + if (m_module.ContainingAssemblyBuilder.m_assemblyData.m_access == AssemblyBuilderAccess.Run) + { + // if we don't need the data structures to build the method any more + // throw them away. + meth.ReleaseBakedStructures(); + } + } + + m_hasBeenCreated = true; + + // Terminate the process. + RuntimeType cls = null; + TermCreateClass(m_module.GetNativeHandle(), m_tdType.Token, JitHelpers.GetObjectHandleOnStack(ref cls)); + + if (!m_isHiddenGlobalType) + { + m_bakedRuntimeType = cls; + + // if this type is a nested type, we need to invalidate the cached nested runtime type on the nesting type + if (m_DeclaringType != null && m_DeclaringType.m_bakedRuntimeType != null) + { + m_DeclaringType.m_bakedRuntimeType.InvalidateCachedNestedType(); + } + + return cls; + } + else + { + return null; + } + } + + #endregion + + #region Misc + public int Size + { + get { return m_iTypeSize; } + } + + public PackingSize PackingSize + { + get { return m_iPackingSize; } + } + + public void SetParent(Type parent) + { + ThrowIfCreated(); + + if (parent != null) + { + CheckContext(parent); + + if (parent.IsInterface) + throw new ArgumentException(Environment.GetResourceString("Argument_CannotSetParentToInterface")); + + m_typeParent = parent; + } + else + { + if ((m_iAttr & TypeAttributes.Interface) != TypeAttributes.Interface) + { + m_typeParent = typeof(Object); + } + else + { + if ((m_iAttr & TypeAttributes.Abstract) == 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_BadInterfaceNotAbstract")); + + // there is no extends for interface class + m_typeParent = null; + } + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + [System.Runtime.InteropServices.ComVisible(true)] + public void AddInterfaceImplementation(Type interfaceType) + { + if (interfaceType == null) + { + throw new ArgumentNullException("interfaceType"); + } + Contract.EndContractBlock(); + + CheckContext(interfaceType); + + ThrowIfCreated(); + + TypeToken tkInterface = m_module.GetTypeTokenInternal(interfaceType); + AddInterfaceImpl(m_module.GetNativeHandle(), m_tdType.Token, tkInterface.Token); + + m_typeInterfaces.Add(interfaceType); + } + +#if FEATURE_CAS_POLICY + [System.Security.SecuritySafeCritical] // auto-generated + public void AddDeclarativeSecurity(SecurityAction action, PermissionSet pset) + { + lock(SyncRoot) + { + AddDeclarativeSecurityNoLock(action, pset); + } + } + + [System.Security.SecurityCritical] // auto-generated + private void AddDeclarativeSecurityNoLock(SecurityAction action, PermissionSet pset) + { + if (pset == null) + throw new ArgumentNullException("pset"); + +#pragma warning disable 618 + if (!Enum.IsDefined(typeof(SecurityAction), action) || + action == SecurityAction.RequestMinimum || + action == SecurityAction.RequestOptional || + action == SecurityAction.RequestRefuse) + { + throw new ArgumentOutOfRangeException("action"); + } +#pragma warning restore 618 + + Contract.EndContractBlock(); + + ThrowIfCreated(); + + // Translate permission set into serialized format(uses standard binary serialization format). + byte[] blob = null; + int length = 0; + if (!pset.IsEmpty()) + { + blob = pset.EncodeXml(); + length = blob.Length; + } + + // Write the blob into the metadata. + AddDeclarativeSecurity(m_module.GetNativeHandle(), m_tdType.Token, action, blob, length); + } +#endif // FEATURE_CAS_POLICY + +public TypeToken TypeToken + { + get + { + if (IsGenericParameter) + ThrowIfCreated(); + + return m_tdType; + } + } + + +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + [System.Runtime.InteropServices.ComVisible(true)] + public void SetCustomAttribute(ConstructorInfo con, byte[] binaryAttribute) + { + if (con == null) + throw new ArgumentNullException("con"); + + if (binaryAttribute == null) + throw new ArgumentNullException("binaryAttribute"); + Contract.EndContractBlock(); + + TypeBuilder.DefineCustomAttribute(m_module, m_tdType.Token, ((ModuleBuilder)m_module).GetConstructorToken(con).Token, + binaryAttribute, false, false); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public void SetCustomAttribute(CustomAttributeBuilder customBuilder) + { + if (customBuilder == null) + throw new ArgumentNullException("customBuilder"); + Contract.EndContractBlock(); + + customBuilder.CreateCustomAttribute((ModuleBuilder)m_module, m_tdType.Token); + } + + #endregion + + #endregion + +#if !FEATURE_CORECLR + void _TypeBuilder.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _TypeBuilder.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _TypeBuilder.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _TypeBuilder.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs b/src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs new file mode 100644 index 0000000000..13b98b6543 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/TypeBuilderInstantiation.cs @@ -0,0 +1,276 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection.Emit +{ + using System; + using System.Reflection; + using System.Collections; + using System.Globalization; + using System.Diagnostics.Contracts; + + internal sealed class TypeBuilderInstantiation : TypeInfo + { + public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){ + if(typeInfo==null) return false; + return IsAssignableFrom(typeInfo.AsType()); + } + + #region Static Members + internal static Type MakeGenericType(Type type, Type[] typeArguments) + { + Contract.Requires(type != null, "this is only called from RuntimeType.MakeGenericType and TypeBuilder.MakeGenericType so 'type' cannot be null"); + + if (!type.IsGenericTypeDefinition) + throw new InvalidOperationException(); + + if (typeArguments == null) + throw new ArgumentNullException("typeArguments"); + Contract.EndContractBlock(); + + foreach (Type t in typeArguments) + { + if (t == null) + throw new ArgumentNullException("typeArguments"); + } + + return new TypeBuilderInstantiation(type, typeArguments); + } + + #endregion + + #region Private Data Mebers + private Type m_type; + private Type[] m_inst; + private string m_strFullQualName; + internal Hashtable m_hashtable = new Hashtable(); + + #endregion + + #region Constructor + private TypeBuilderInstantiation(Type type, Type[] inst) + { + m_type = type; + m_inst = inst; + m_hashtable = new Hashtable(); + } + #endregion + + #region Object Overrides + public override String ToString() + { + return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.ToString); + } + #endregion + + #region MemberInfo Overrides + public override Type DeclaringType { get { return m_type.DeclaringType; } } + + public override Type ReflectedType { get { return m_type.ReflectedType; } } + + public override String Name { get { return m_type.Name; } } + + public override Module Module { get { return m_type.Module; } } + #endregion + + #region Type Overrides + public override Type MakePointerType() + { + return SymbolType.FormCompoundType("*", this, 0); + } + public override Type MakeByRefType() + { + return SymbolType.FormCompoundType("&", this, 0); + } + public override Type MakeArrayType() + { + return SymbolType.FormCompoundType("[]", this, 0); + } + public override Type MakeArrayType(int rank) + { + if (rank <= 0) + throw new IndexOutOfRangeException(); + Contract.EndContractBlock(); + + string comma = ""; + for(int i = 1; i < rank; i++) + comma += ","; + + string s = String.Format(CultureInfo.InvariantCulture, "[{0}]", comma); + return SymbolType.FormCompoundType(s, this, 0); + } + public override Guid GUID { get { throw new NotSupportedException(); } } + public override Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters) { throw new NotSupportedException(); } + public override Assembly Assembly { get { return m_type.Assembly; } } + public override RuntimeTypeHandle TypeHandle { get { throw new NotSupportedException(); } } + public override String FullName + { + get + { + if (m_strFullQualName == null) + m_strFullQualName = TypeNameBuilder.ToString(this, TypeNameBuilder.Format.FullName); + return m_strFullQualName; + } + } + public override String Namespace { get { return m_type.Namespace; } } + public override String AssemblyQualifiedName { get { return TypeNameBuilder.ToString(this, TypeNameBuilder.Format.AssemblyQualifiedName); } } + private Type Substitute(Type[] substitutes) + { + Type[] inst = GetGenericArguments(); + Type[] instSubstituted = new Type[inst.Length]; + + for (int i = 0; i < instSubstituted.Length; i++) + { + Type t = inst[i]; + + if (t is TypeBuilderInstantiation) + { + instSubstituted[i] = (t as TypeBuilderInstantiation).Substitute(substitutes); + } + else if (t is GenericTypeParameterBuilder) + { + // Substitute + instSubstituted[i] = substitutes[t.GenericParameterPosition]; + } + else + { + instSubstituted[i] = t; + } + } + + return GetGenericTypeDefinition().MakeGenericType(instSubstituted); + } + public override Type BaseType + { + // B + // D : B,char> + + // D : B,char> + // D : B,char> + // D : B,char> + get + { + Type typeBldrBase = m_type.BaseType; + + if (typeBldrBase == null) + return null; + + TypeBuilderInstantiation typeBldrBaseAs = typeBldrBase as TypeBuilderInstantiation; + + if (typeBldrBaseAs == null) + return typeBldrBase; + + return typeBldrBaseAs.Substitute(GetGenericArguments()); + } + } + protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { throw new NotSupportedException(); } + + [System.Runtime.InteropServices.ComVisible(true)] + public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) { throw new NotSupportedException(); } + protected override MethodInfo GetMethodImpl(String name, BindingFlags bindingAttr, Binder binder, CallingConventions callConvention, Type[] types, ParameterModifier[] modifiers) { throw new NotSupportedException(); } + public override MethodInfo[] GetMethods(BindingFlags bindingAttr) { throw new NotSupportedException(); } + public override FieldInfo GetField(String name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + public override FieldInfo[] GetFields(BindingFlags bindingAttr) { throw new NotSupportedException(); } + public override Type GetInterface(String name, bool ignoreCase) { throw new NotSupportedException(); } + public override Type[] GetInterfaces() { throw new NotSupportedException(); } + public override EventInfo GetEvent(String name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + public override EventInfo[] GetEvents() { throw new NotSupportedException(); } + protected override PropertyInfo GetPropertyImpl(String name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) { throw new NotSupportedException(); } + public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) { throw new NotSupportedException(); } + public override Type[] GetNestedTypes(BindingFlags bindingAttr) { throw new NotSupportedException(); } + public override Type GetNestedType(String name, BindingFlags bindingAttr) { throw new NotSupportedException(); } + public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr) { throw new NotSupportedException(); } + + [System.Runtime.InteropServices.ComVisible(true)] + public override InterfaceMapping GetInterfaceMap(Type interfaceType) { throw new NotSupportedException(); } + public override EventInfo[] GetEvents(BindingFlags bindingAttr) { throw new NotSupportedException(); } + public override MemberInfo[] GetMembers(BindingFlags bindingAttr) { throw new NotSupportedException(); } + protected override TypeAttributes GetAttributeFlagsImpl() { return m_type.Attributes; } + protected override bool IsArrayImpl() { return false; } + protected override bool IsByRefImpl() { return false; } + protected override bool IsPointerImpl() { return false; } + protected override bool IsPrimitiveImpl() { return false; } + protected override bool IsCOMObjectImpl() { return false; } + public override Type GetElementType() { throw new NotSupportedException(); } + protected override bool HasElementTypeImpl() { return false; } + public override Type UnderlyingSystemType { get { return this; } } + public override Type[] GetGenericArguments() { return m_inst; } + public override bool IsGenericTypeDefinition { get { return false; } } + public override bool IsGenericType { get { return true; } } + public override bool IsConstructedGenericType { get { return true; } } + public override bool IsGenericParameter { get { return false; } } + public override int GenericParameterPosition { get { throw new InvalidOperationException(); } } + protected override bool IsValueTypeImpl() { return m_type.IsValueType; } + public override bool ContainsGenericParameters + { + get + { + for (int i = 0; i < m_inst.Length; i++) + { + if (m_inst[i].ContainsGenericParameters) + return true; + } + + return false; + } + } + public override MethodBase DeclaringMethod { get { return null; } } + public override Type GetGenericTypeDefinition() { return m_type; } + public override Type MakeGenericType(params Type[] inst) { throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericTypeDefinition")); } + public override bool IsAssignableFrom(Type c) { throw new NotSupportedException(); } + + [System.Runtime.InteropServices.ComVisible(true)] + [Pure] + public override bool IsSubclassOf(Type c) + { + throw new NotSupportedException(); + } + #endregion + + #region ICustomAttributeProvider Implementation + public override Object[] GetCustomAttributes(bool inherit) { throw new NotSupportedException(); } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) { throw new NotSupportedException(); } + + public override bool IsDefined(Type attributeType, bool inherit) { throw new NotSupportedException(); } + #endregion + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mscorlib/src/System/Reflection/Emit/TypeToken.cs b/src/mscorlib/src/System/Reflection/Emit/TypeToken.cs new file mode 100644 index 0000000000..228755641c --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/TypeToken.cs @@ -0,0 +1,74 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** Purpose: Represents a Class to the ILGenerator class. +** +** +===========================================================*/ +namespace System.Reflection.Emit { + + using System; + using System.Reflection; + using System.Threading; + using System.Security.Permissions; + + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public struct TypeToken { + + public static readonly TypeToken Empty = new TypeToken(); + + internal int m_class; + +#if false + public TypeToken() { + m_class=0; + } +#endif + + internal TypeToken(int str) { + m_class=str; + } + + public int Token { + get { return m_class; } + } + + public override int GetHashCode() + { + return m_class; + } + + public override bool Equals(Object obj) + { + if (obj is TypeToken) + return Equals((TypeToken)obj); + else + return false; + } + + public bool Equals(TypeToken obj) + { + return obj.m_class == m_class; + } + + public static bool operator ==(TypeToken a, TypeToken b) + { + return a.Equals(b); + } + + public static bool operator !=(TypeToken a, TypeToken b) + { + return !(a == b); + } + + } +} + diff --git a/src/mscorlib/src/System/Reflection/Emit/UnmanagedMarshal.cs b/src/mscorlib/src/System/Reflection/Emit/UnmanagedMarshal.cs new file mode 100644 index 0000000000..09eac3a272 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/UnmanagedMarshal.cs @@ -0,0 +1,184 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Reflection.Emit +{ + using System.Runtime.InteropServices; + using System; + using System.Security.Permissions; + + // This class is describing the fieldmarshal. + [Serializable] + [HostProtection(MayLeakOnAbort = true)] + [System.Runtime.InteropServices.ComVisible(true)] + [Obsolete("An alternate API is available: Emit the MarshalAs custom attribute instead. http://go.microsoft.com/fwlink/?linkid=14202")] + public sealed class UnmanagedMarshal + { + /****************************** +[System.Runtime.InteropServices.ComVisible(true)] + * public static constructors. You can only construct + * UnmanagedMarshal using these static constructors. + ******************************/ + public static UnmanagedMarshal DefineUnmanagedMarshal(UnmanagedType unmanagedType) + { + if (unmanagedType == UnmanagedType.ByValTStr || + unmanagedType == UnmanagedType.SafeArray || + unmanagedType == UnmanagedType.CustomMarshaler || + unmanagedType == UnmanagedType.ByValArray || + unmanagedType == UnmanagedType.LPArray) + { + // not a simple native marshal + throw new ArgumentException(Environment.GetResourceString("Argument_NotASimpleNativeType")); + } + return new UnmanagedMarshal(unmanagedType, Guid.Empty, 0, (UnmanagedType) 0); + } + public static UnmanagedMarshal DefineByValTStr(int elemCount) + { + return new UnmanagedMarshal(UnmanagedType.ByValTStr, Guid.Empty, elemCount, (UnmanagedType) 0); + } + + public static UnmanagedMarshal DefineSafeArray(UnmanagedType elemType) + { + return new UnmanagedMarshal(UnmanagedType.SafeArray, Guid.Empty, 0, elemType); + } + + public static UnmanagedMarshal DefineByValArray(int elemCount) + { + return new UnmanagedMarshal(UnmanagedType.ByValArray, Guid.Empty, elemCount, (UnmanagedType) 0); + } + + public static UnmanagedMarshal DefineLPArray(UnmanagedType elemType) + { + return new UnmanagedMarshal(UnmanagedType.LPArray, Guid.Empty, 0, elemType); + } + + + + + + + // accessor function for the native type + public UnmanagedType GetUnmanagedType + { + get { return m_unmanagedType; } + } + + public Guid IIDGuid + { + get + { + if (m_unmanagedType == UnmanagedType.CustomMarshaler) + return m_guid; + + // throw exception here. There is Guid only if CustomMarshaler + throw new ArgumentException(Environment.GetResourceString("Argument_NotACustomMarshaler")); + } + } + public int ElementCount + { + get + { + if (m_unmanagedType != UnmanagedType.ByValArray && + m_unmanagedType != UnmanagedType.ByValTStr) + { + // throw exception here. There is NumElement only if NativeTypeFixedArray + throw new ArgumentException(Environment.GetResourceString("Argument_NoUnmanagedElementCount")); + } + return m_numElem; + } + } + public UnmanagedType BaseType + { + get + { + if (m_unmanagedType != UnmanagedType.LPArray && m_unmanagedType != UnmanagedType.SafeArray) + { + // throw exception here. There is NestedUnmanagedType only if LPArray or SafeArray + throw new ArgumentException(Environment.GetResourceString("Argument_NoNestedMarshal")); + } + return m_baseType; + } + } + + private UnmanagedMarshal(UnmanagedType unmanagedType, Guid guid, int numElem, UnmanagedType type) + { + m_unmanagedType = unmanagedType; + m_guid = guid; + m_numElem = numElem; + m_baseType = type; + } + + /************************ + * + * Data member + * + *************************/ + internal UnmanagedType m_unmanagedType; + internal Guid m_guid; + internal int m_numElem; + internal UnmanagedType m_baseType; + + + /************************ + * this function return the byte representation of the marshal info. + *************************/ + internal byte[] InternalGetBytes() + { + byte[] buf; + if (m_unmanagedType == UnmanagedType.SafeArray || m_unmanagedType == UnmanagedType.LPArray) + { + + // syntax for NativeTypeSafeArray is + // + // + int cBuf = 2; + buf = new byte[cBuf]; + buf[0] = (byte) (m_unmanagedType); + buf[1] = (byte) (m_baseType); + return buf; + } + else + if (m_unmanagedType == UnmanagedType.ByValArray || + m_unmanagedType == UnmanagedType.ByValTStr) + { + // + // + int cBuf; + int iBuf = 0; + + if (m_numElem <= 0x7f) + cBuf = 1; + else if (m_numElem <= 0x3FFF) + cBuf = 2; + else + cBuf = 4; + + // the total buffer size is the one byte + encoded integer size + cBuf = cBuf + 1; + buf = new byte[cBuf]; + + + buf[iBuf++] = (byte) (m_unmanagedType); + if (m_numElem <= 0x7F) + { + buf[iBuf++] = (byte)(m_numElem & 0xFF); + } else if (m_numElem <= 0x3FFF) + { + buf[iBuf++] = (byte)((m_numElem >> 8) | 0x80); + buf[iBuf++] = (byte)(m_numElem & 0xFF); + } else if (m_numElem <= 0x1FFFFFFF) + { + buf[iBuf++] = (byte)((m_numElem >> 24) | 0xC0); + buf[iBuf++] = (byte)((m_numElem >> 16) & 0xFF); + buf[iBuf++] = (byte)((m_numElem >> 8) & 0xFF); + buf[iBuf++] = (byte)((m_numElem) & 0xFF); + } + return buf; + } + buf = new byte[1]; + buf[0] = (byte) (m_unmanagedType); + return buf; + } + } +} diff --git a/src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs b/src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs new file mode 100644 index 0000000000..5b36e0e372 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Emit/XXXOnTypeBuilderInstantiation.cs @@ -0,0 +1,331 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection.Emit +{ + using System; + using System.Reflection; + using System.Collections; + using System.Collections.Generic; + using System.Globalization; + using System.Diagnostics.Contracts; + + internal sealed class MethodOnTypeBuilderInstantiation : MethodInfo + { + #region Private Static Members + internal static MethodInfo GetMethod(MethodInfo method, TypeBuilderInstantiation type) + { + return new MethodOnTypeBuilderInstantiation(method, type); + } + #endregion + + #region Private Data Mebers + internal MethodInfo m_method; + private TypeBuilderInstantiation m_type; + #endregion + + #region Constructor + internal MethodOnTypeBuilderInstantiation(MethodInfo method, TypeBuilderInstantiation type) + { + Contract.Assert(method is MethodBuilder || method is RuntimeMethodInfo); + + m_method = method; + m_type = type; + } + #endregion + + internal override Type[] GetParameterTypes() + { + return m_method.GetParameterTypes(); + } + + #region MemberInfo Overrides + public override MemberTypes MemberType { get { return m_method.MemberType; } } + public override String Name { get { return m_method.Name; } } + public override Type DeclaringType { get { return m_type; } } + public override Type ReflectedType { get { return m_type; } } + public override Object[] GetCustomAttributes(bool inherit) { return m_method.GetCustomAttributes(inherit); } + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) { return m_method.GetCustomAttributes(attributeType, inherit); } + public override bool IsDefined(Type attributeType, bool inherit) { return m_method.IsDefined(attributeType, inherit); } + internal int MetadataTokenInternal + { + get + { + MethodBuilder mb = m_method as MethodBuilder; + + if (mb != null) + return mb.MetadataTokenInternal; + else + { + Contract.Assert(m_method is RuntimeMethodInfo); + return m_method.MetadataToken; + } + } + } + public override Module Module { get { return m_method.Module; } } + public new Type GetType() { return base.GetType(); } + #endregion + + #region MethodBase Members + [Pure] + public override ParameterInfo[] GetParameters() { return m_method.GetParameters(); } + public override MethodImplAttributes GetMethodImplementationFlags() { return m_method.GetMethodImplementationFlags(); } + public override RuntimeMethodHandle MethodHandle { get { return m_method.MethodHandle; } } + public override MethodAttributes Attributes { get { return m_method.Attributes; } } + public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) + { + throw new NotSupportedException(); + } + public override CallingConventions CallingConvention { get { return m_method.CallingConvention; } } + public override Type [] GetGenericArguments() { return m_method.GetGenericArguments(); } + public override MethodInfo GetGenericMethodDefinition() { return m_method; } + public override bool IsGenericMethodDefinition { get { return m_method.IsGenericMethodDefinition; } } + public override bool ContainsGenericParameters { get { return m_method.ContainsGenericParameters; } } + public override MethodInfo MakeGenericMethod(params Type[] typeArgs) + { + if (!IsGenericMethodDefinition) + throw new InvalidOperationException(Environment.GetResourceString("Arg_NotGenericMethodDefinition")); + Contract.EndContractBlock(); + + return MethodBuilderInstantiation.MakeGenericMethod(this, typeArgs); + } + + public override bool IsGenericMethod { get { return m_method.IsGenericMethod; } } + + #endregion + + #region Public Abstract\Virtual Members + public override Type ReturnType { get { return m_method.ReturnType; } } + public override ParameterInfo ReturnParameter { get { throw new NotSupportedException(); } } + public override ICustomAttributeProvider ReturnTypeCustomAttributes { get { throw new NotSupportedException(); } } + public override MethodInfo GetBaseDefinition() { throw new NotSupportedException(); } + #endregion + } + + internal sealed class ConstructorOnTypeBuilderInstantiation : ConstructorInfo + { + #region Private Static Members + internal static ConstructorInfo GetConstructor(ConstructorInfo Constructor, TypeBuilderInstantiation type) + { + return new ConstructorOnTypeBuilderInstantiation(Constructor, type); + } + #endregion + + #region Private Data Mebers + internal ConstructorInfo m_ctor; + private TypeBuilderInstantiation m_type; + #endregion + + #region Constructor + internal ConstructorOnTypeBuilderInstantiation(ConstructorInfo constructor, TypeBuilderInstantiation type) + { + Contract.Assert(constructor is ConstructorBuilder || constructor is RuntimeConstructorInfo); + + m_ctor = constructor; + m_type = type; + } + #endregion + + internal override Type[] GetParameterTypes() + { + return m_ctor.GetParameterTypes(); + } + + internal override Type GetReturnType() + { + return DeclaringType; + } + + #region MemberInfo Overrides + public override MemberTypes MemberType { get { return m_ctor.MemberType; } } + public override String Name { get { return m_ctor.Name; } } + public override Type DeclaringType { get { return m_type; } } + public override Type ReflectedType { get { return m_type; } } + public override Object[] GetCustomAttributes(bool inherit) { return m_ctor.GetCustomAttributes(inherit); } + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) { return m_ctor.GetCustomAttributes(attributeType, inherit); } + public override bool IsDefined(Type attributeType, bool inherit) { return m_ctor.IsDefined(attributeType, inherit); } + internal int MetadataTokenInternal + { + get + { + ConstructorBuilder cb = m_ctor as ConstructorBuilder; + + if (cb != null) + return cb.MetadataTokenInternal; + else + { + Contract.Assert(m_ctor is RuntimeConstructorInfo); + return m_ctor.MetadataToken; + } + } + } + public override Module Module { get { return m_ctor.Module; } } + public new Type GetType() { return base.GetType(); } + #endregion + + #region MethodBase Members + [Pure] + public override ParameterInfo[] GetParameters() { return m_ctor.GetParameters(); } + public override MethodImplAttributes GetMethodImplementationFlags() { return m_ctor.GetMethodImplementationFlags(); } + public override RuntimeMethodHandle MethodHandle { get { return m_ctor.MethodHandle; } } + public override MethodAttributes Attributes { get { return m_ctor.Attributes; } } + public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) + { + throw new NotSupportedException(); + } + public override CallingConventions CallingConvention { get { return m_ctor.CallingConvention; } } + public override Type[] GetGenericArguments() { return m_ctor.GetGenericArguments(); } + public override bool IsGenericMethodDefinition { get { return false; } } + public override bool ContainsGenericParameters { get { return false; } } + + public override bool IsGenericMethod { get { return false; } } + #endregion + + #region ConstructorInfo Members + public override Object Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) + { + throw new InvalidOperationException(); + } + #endregion + } + + internal sealed class FieldOnTypeBuilderInstantiation : FieldInfo + { + #region Private Static Members + internal static FieldInfo GetField(FieldInfo Field, TypeBuilderInstantiation type) + { + FieldInfo m = null; + + // This ifdef was introduced when non-generic collections were pulled from + // silverlight. See code:Dictionary#DictionaryVersusHashtableThreadSafety + // for information about this change. + // + // There is a pre-existing race condition in this code with the side effect + // that the second thread's value clobbers the first in the hashtable. This is + // an acceptable race condition since we make no guarantees that this will return the + // same object. + // + // We're not entirely sure if this cache helps any specific scenarios, so + // long-term, one could investigate whether it's needed. In any case, this + // method isn't expected to be on any critical paths for performance. + if (type.m_hashtable.Contains(Field)) { + m = type.m_hashtable[Field] as FieldInfo; + } + else { + m = new FieldOnTypeBuilderInstantiation(Field, type); + type.m_hashtable[Field] = m; + } + + return m; + } + #endregion + + #region Private Data Members + private FieldInfo m_field; + private TypeBuilderInstantiation m_type; + #endregion + + #region Constructor + internal FieldOnTypeBuilderInstantiation(FieldInfo field, TypeBuilderInstantiation type) + { + Contract.Assert(field is FieldBuilder || field is RuntimeFieldInfo); + + m_field = field; + m_type = type; + } + #endregion + + internal FieldInfo FieldInfo { get { return m_field; } } + + #region MemberInfo Overrides + public override MemberTypes MemberType { get { return System.Reflection.MemberTypes.Field; } } + public override String Name { get { return m_field.Name; } } + public override Type DeclaringType { get { return m_type; } } + public override Type ReflectedType { get { return m_type; } } + public override Object[] GetCustomAttributes(bool inherit) { return m_field.GetCustomAttributes(inherit); } + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) { return m_field.GetCustomAttributes(attributeType, inherit); } + public override bool IsDefined(Type attributeType, bool inherit) { return m_field.IsDefined(attributeType, inherit); } + internal int MetadataTokenInternal + { + get + { + FieldBuilder fb = m_field as FieldBuilder; + + if (fb != null) + return fb.MetadataTokenInternal; + else + { + Contract.Assert(m_field is RuntimeFieldInfo); + return m_field.MetadataToken; + } + } + } + public override Module Module { get { return m_field.Module; } } + public new Type GetType() { return base.GetType(); } + #endregion + + #region Public Abstract\Virtual Members + public override Type[] GetRequiredCustomModifiers() { return m_field.GetRequiredCustomModifiers(); } + public override Type[] GetOptionalCustomModifiers() { return m_field.GetOptionalCustomModifiers(); } + public override void SetValueDirect(TypedReference obj, Object value) + { + throw new NotImplementedException(); + } + public override Object GetValueDirect(TypedReference obj) + { + throw new NotImplementedException(); + } + public override RuntimeFieldHandle FieldHandle + { + get { throw new NotImplementedException(); } + } + public override Type FieldType { get { throw new NotImplementedException(); } } + public override Object GetValue(Object obj) { throw new InvalidOperationException(); } + public override void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture) { throw new InvalidOperationException(); } + public override FieldAttributes Attributes { get { return m_field.Attributes; } } + #endregion + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/mscorlib/src/System/Reflection/EventAttributes.cs b/src/mscorlib/src/System/Reflection/EventAttributes.cs new file mode 100644 index 0000000000..c0285652ff --- /dev/null +++ b/src/mscorlib/src/System/Reflection/EventAttributes.cs @@ -0,0 +1,30 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// EventAttributes are an enum defining the attributes associated with +// +// and Event. These are defined in CorHdr.h and are a combination of +// bits and enums. +// +// +namespace System.Reflection { + + using System; + [Serializable] + [Flags] + [System.Runtime.InteropServices.ComVisible(true)] + public enum EventAttributes { + None = 0x0000, + + // This Enum matchs the CorEventAttr defined in CorHdr.h + SpecialName = 0x0200, // event is special. Name describes how. + + // Reserved flags for Runtime use only. + ReservedMask = 0x0400, + RTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding. + } +} diff --git a/src/mscorlib/src/System/Reflection/EventInfo.cs b/src/mscorlib/src/System/Reflection/EventInfo.cs new file mode 100644 index 0000000000..3fd1951b6c --- /dev/null +++ b/src/mscorlib/src/System/Reflection/EventInfo.cs @@ -0,0 +1,443 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Diagnostics.Contracts; + using System.Runtime.InteropServices; + using System.Runtime.Serialization; + using System.Runtime.ConstrainedExecution; + using System.Security.Permissions; + using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache; + + [Serializable] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_EventInfo))] +#pragma warning disable 618 + [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")] +#pragma warning restore 618 + [System.Runtime.InteropServices.ComVisible(true)] + public abstract class EventInfo : MemberInfo, _EventInfo + { + #region Constructor + protected EventInfo() { } + #endregion + + public static bool operator ==(EventInfo left, EventInfo right) + { + if (ReferenceEquals(left, right)) + return true; + + if ((object)left == null || (object)right == null || + left is RuntimeEventInfo || right is RuntimeEventInfo) + { + return false; + } + return left.Equals(right); + } + + public static bool operator !=(EventInfo left, EventInfo right) + { + return !(left == right); + } + + public override bool Equals(object obj) + { + return base.Equals(obj); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + #region MemberInfo Overrides + public override MemberTypes MemberType { get { return MemberTypes.Event; } } + #endregion + + #region Public Abstract\Virtual Members + public virtual MethodInfo[] GetOtherMethods(bool nonPublic) + { + throw new NotImplementedException(); + } + + public abstract MethodInfo GetAddMethod(bool nonPublic); + + public abstract MethodInfo GetRemoveMethod(bool nonPublic); + + public abstract MethodInfo GetRaiseMethod(bool nonPublic); + + public abstract EventAttributes Attributes { get; } + #endregion + + #region Public Members + public virtual MethodInfo AddMethod + { + get + { + return GetAddMethod(true); + } + } + + public virtual MethodInfo RemoveMethod + { + get + { + return GetRemoveMethod(true); + } + } + + public virtual MethodInfo RaiseMethod + { + get + { + return GetRaiseMethod(true); + } + } + + public MethodInfo[] GetOtherMethods() { return GetOtherMethods(false); } + + public MethodInfo GetAddMethod() { return GetAddMethod(false); } + + public MethodInfo GetRemoveMethod() { return GetRemoveMethod(false); } + + public MethodInfo GetRaiseMethod() { return GetRaiseMethod(false); } + + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public virtual void AddEventHandler(Object target, Delegate handler) + { + MethodInfo addMethod = GetAddMethod(); + + if (addMethod == null) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoPublicAddMethod")); + +#if FEATURE_COMINTEROP + if (addMethod.ReturnType == typeof(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken)) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotSupportedOnWinRTEvent")); + + // Must be a normal non-WinRT event + Contract.Assert(addMethod.ReturnType == typeof(void)); +#endif // FEATURE_COMINTEROP + + addMethod.Invoke(target, new object[] { handler }); + } + + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public virtual void RemoveEventHandler(Object target, Delegate handler) + { + MethodInfo removeMethod = GetRemoveMethod(); + + if (removeMethod == null) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoPublicRemoveMethod")); + +#if FEATURE_COMINTEROP + ParameterInfo[] parameters = removeMethod.GetParametersNoCopy(); + Contract.Assert(parameters != null && parameters.Length == 1); + + if (parameters[0].ParameterType == typeof(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken)) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotSupportedOnWinRTEvent")); + + // Must be a normal non-WinRT event + Contract.Assert(parameters[0].ParameterType.BaseType == typeof(MulticastDelegate)); +#endif // FEATURE_COMINTEROP + + removeMethod.Invoke(target, new object[] { handler }); + } + + public virtual Type EventHandlerType + { + get + { + MethodInfo m = GetAddMethod(true); + + ParameterInfo[] p = m.GetParametersNoCopy(); + + Type del = typeof(Delegate); + + for (int i = 0; i < p.Length; i++) + { + Type c = p[i].ParameterType; + + if (c.IsSubclassOf(del)) + return c; + } + return null; + } + } + public bool IsSpecialName + { + get + { + return(Attributes & EventAttributes.SpecialName) != 0; + } + } + + public virtual bool IsMulticast + { + get + { + Type cl = EventHandlerType; + Type mc = typeof(MulticastDelegate); + return mc.IsAssignableFrom(cl); + } + } + #endregion + +#if !FEATURE_CORECLR + Type _EventInfo.GetType() + { + return base.GetType(); + } + + void _EventInfo.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _EventInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _EventInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + // If you implement this method, make sure to include _EventInfo.Invoke in VM\DangerousAPIs.h and + // include _EventInfo in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp. + void _EventInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + } + + [Serializable] + internal unsafe sealed class RuntimeEventInfo : EventInfo, ISerializable + { + #region Private Data Members + private int m_token; + private EventAttributes m_flags; + private string m_name; + [System.Security.SecurityCritical] + private void* m_utf8name; + private RuntimeTypeCache m_reflectedTypeCache; + private RuntimeMethodInfo m_addMethod; + private RuntimeMethodInfo m_removeMethod; + private RuntimeMethodInfo m_raiseMethod; + private MethodInfo[] m_otherMethod; + private RuntimeType m_declaringType; + private BindingFlags m_bindingFlags; + #endregion + + #region Constructor + internal RuntimeEventInfo() + { + // Used for dummy head node during population + } + [System.Security.SecurityCritical] // auto-generated + internal RuntimeEventInfo(int tkEvent, RuntimeType declaredType, RuntimeTypeCache reflectedTypeCache, out bool isPrivate) + { + Contract.Requires(declaredType != null); + Contract.Requires(reflectedTypeCache != null); + Contract.Assert(!reflectedTypeCache.IsGlobal); + + MetadataImport scope = declaredType.GetRuntimeModule().MetadataImport; + + m_token = tkEvent; + m_reflectedTypeCache = reflectedTypeCache; + m_declaringType = declaredType; + + + RuntimeType reflectedType = reflectedTypeCache.GetRuntimeType(); + + scope.GetEventProps(tkEvent, out m_utf8name, out m_flags); + + RuntimeMethodInfo dummy; + Associates.AssignAssociates(scope, tkEvent, declaredType, reflectedType, + out m_addMethod, out m_removeMethod, out m_raiseMethod, + out dummy, out dummy, out m_otherMethod, out isPrivate, out m_bindingFlags); + } + #endregion + + #region Internal Members + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + internal override bool CacheEquals(object o) + { + RuntimeEventInfo m = o as RuntimeEventInfo; + + if ((object)m == null) + return false; + + return m.m_token == m_token && + RuntimeTypeHandle.GetModule(m_declaringType).Equals( + RuntimeTypeHandle.GetModule(m.m_declaringType)); + } + + internal BindingFlags BindingFlags { get { return m_bindingFlags; } } + #endregion + + #region Object Overrides + public override String ToString() + { + if (m_addMethod == null || m_addMethod.GetParametersNoCopy().Length == 0) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NoPublicAddMethod")); + + return m_addMethod.GetParametersNoCopy()[0].ParameterType.FormatTypeName() + " " + Name; + } + #endregion + + #region ICustomAttributeProvider + public override Object[] GetCustomAttributes(bool inherit) + { + return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType"); + + return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public override bool IsDefined(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType"); + + return CustomAttribute.IsDefined(this, attributeRuntimeType); + } + + public override IList GetCustomAttributesData() + { + return CustomAttributeData.GetCustomAttributesInternal(this); + } + #endregion + + #region MemberInfo Overrides + public override MemberTypes MemberType { get { return MemberTypes.Event; } } + public override String Name + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + if (m_name == null) + m_name = new Utf8String(m_utf8name).ToString(); + + return m_name; + } + } + public override Type DeclaringType { get { return m_declaringType; } } + public override Type ReflectedType + { + get + { + return ReflectedTypeInternal; + } + } + + private RuntimeType ReflectedTypeInternal + { + get + { + return m_reflectedTypeCache.GetRuntimeType(); + } + } + + public override int MetadataToken { get { return m_token; } } + public override Module Module { get { return GetRuntimeModule(); } } + internal RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); } + #endregion + + #region ISerializable + [System.Security.SecurityCritical] // auto-generated_required + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException("info"); + Contract.EndContractBlock(); + + MemberInfoSerializationHolder.GetSerializationInfo( + info, + Name, + ReflectedTypeInternal, + null, + MemberTypes.Event); + } + #endregion + + #region EventInfo Overrides + public override MethodInfo[] GetOtherMethods(bool nonPublic) + { + List ret = new List(); + + if ((object)m_otherMethod == null) + return new MethodInfo[0]; + + for(int i = 0; i < m_otherMethod.Length; i ++) + { + if (Associates.IncludeAccessor((MethodInfo)m_otherMethod[i], nonPublic)) + ret.Add(m_otherMethod[i]); + } + + return ret.ToArray(); + } + + public override MethodInfo GetAddMethod(bool nonPublic) + { + if (!Associates.IncludeAccessor(m_addMethod, nonPublic)) + return null; + + return m_addMethod; + } + + public override MethodInfo GetRemoveMethod(bool nonPublic) + { + if (!Associates.IncludeAccessor(m_removeMethod, nonPublic)) + return null; + + return m_removeMethod; + } + + public override MethodInfo GetRaiseMethod(bool nonPublic) + { + if (!Associates.IncludeAccessor(m_raiseMethod, nonPublic)) + return null; + + return m_raiseMethod; + } + + public override EventAttributes Attributes + { + get + { + return m_flags; + } + } + #endregion + } + +} diff --git a/src/mscorlib/src/System/Reflection/FieldAttributes.cs b/src/mscorlib/src/System/Reflection/FieldAttributes.cs new file mode 100644 index 0000000000..48c90a1a38 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/FieldAttributes.cs @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Reflection +{ + using System; + // This Enum matchs the CorFieldAttr defined in CorHdr.h + [Serializable] + [Flags()] + [System.Runtime.InteropServices.ComVisible(true)] + public enum FieldAttributes + { + // member access mask - Use this mask to retrieve accessibility information. + FieldAccessMask = 0x0007, + PrivateScope = 0x0000, // Member not referenceable. + Private = 0x0001, // Accessible only by the parent type. + FamANDAssem = 0x0002, // Accessible by sub-types only in this Assembly. + Assembly = 0x0003, // Accessibly by anyone in the Assembly. + Family = 0x0004, // Accessible only by type and sub-types. + FamORAssem = 0x0005, // Accessibly by sub-types anywhere, plus anyone in assembly. + Public = 0x0006, // Accessibly by anyone who has visibility to this scope. + // end member access mask + + // field contract attributes. + Static = 0x0010, // Defined on type, else per instance. + InitOnly = 0x0020, // Field may only be initialized, not written to after init. + Literal = 0x0040, // Value is compile time constant. + NotSerialized = 0x0080, // Field does not have to be serialized when type is remoted. + + SpecialName = 0x0200, // field is special. Name describes how. + + // interop attributes + PinvokeImpl = 0x2000, // Implementation is forwarded through pinvoke. + + // Reserved flags for runtime use only. + ReservedMask = 0x9500, + RTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding. + HasFieldMarshal = 0x1000, // Field has marshalling information. + HasDefault = 0x8000, // Field has default. + HasFieldRVA = 0x0100, // Field has RVA. + } +} diff --git a/src/mscorlib/src/System/Reflection/FieldInfo.cs b/src/mscorlib/src/System/Reflection/FieldInfo.cs new file mode 100644 index 0000000000..c6a44d412b --- /dev/null +++ b/src/mscorlib/src/System/Reflection/FieldInfo.cs @@ -0,0 +1,955 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Diagnostics.Contracts; + using System.Globalization; + using System.Runtime; + using System.Runtime.CompilerServices; + using System.Runtime.ConstrainedExecution; + using System.Runtime.InteropServices; +#if FEATURE_REMOTING + using System.Runtime.Remoting.Metadata; +#endif //FEATURE_REMOTING + using System.Runtime.Serialization; + using System.Security.Permissions; + using System.Threading; + using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache; + + [Serializable] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_FieldInfo))] +#pragma warning disable 618 + [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")] +#pragma warning restore 618 + [System.Runtime.InteropServices.ComVisible(true)] + public abstract class FieldInfo : MemberInfo, _FieldInfo + { + #region Static Members + public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle handle) + { + if (handle.IsNullHandle()) + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHandle"), "handle"); + + FieldInfo f = RuntimeType.GetFieldInfo(handle.GetRuntimeFieldInfo()); + + Type declaringType = f.DeclaringType; + if (declaringType != null && declaringType.IsGenericType) + throw new ArgumentException(String.Format( + CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_FieldDeclaringTypeGeneric"), + f.Name, declaringType.GetGenericTypeDefinition())); + + return f; + } + + [System.Runtime.InteropServices.ComVisible(false)] + public static FieldInfo GetFieldFromHandle(RuntimeFieldHandle handle, RuntimeTypeHandle declaringType) + { + if (handle.IsNullHandle()) + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHandle")); + + return RuntimeType.GetFieldInfo(declaringType.GetRuntimeType(), handle.GetRuntimeFieldInfo()); + } + #endregion + + #region Constructor + protected FieldInfo() { } + #endregion + + public static bool operator ==(FieldInfo left, FieldInfo right) + { + if (ReferenceEquals(left, right)) + return true; + + if ((object)left == null || (object)right == null || + left is RuntimeFieldInfo || right is RuntimeFieldInfo) + { + return false; + } + return left.Equals(right); + } + + public static bool operator !=(FieldInfo left, FieldInfo right) + { + return !(left == right); + } + + public override bool Equals(object obj) + { + return base.Equals(obj); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + #region MemberInfo Overrides + public override MemberTypes MemberType { get { return System.Reflection.MemberTypes.Field; } } + #endregion + + #region Public Abstract\Virtual Members + + public virtual Type[] GetRequiredCustomModifiers() + { + throw new NotImplementedException(); + } + + public virtual Type[] GetOptionalCustomModifiers() + { + throw new NotImplementedException(); + } + + [CLSCompliant(false)] + public virtual void SetValueDirect(TypedReference obj, Object value) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_AbstractNonCLS")); + } + + [CLSCompliant(false)] + public virtual Object GetValueDirect(TypedReference obj) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_AbstractNonCLS")); + } + + public abstract RuntimeFieldHandle FieldHandle { get; } + + public abstract Type FieldType { get; } + + public abstract Object GetValue(Object obj); + + public virtual Object GetRawConstantValue() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_AbstractNonCLS")); } + + public abstract void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture); + + public abstract FieldAttributes Attributes { get; } + #endregion + + #region Public Members + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public void SetValue(Object obj, Object value) + { + // Theoretically we should set up a LookForMyCaller stack mark here and pass that along. + // But to maintain backward compatibility we can't switch to calling an + // internal overload that takes a stack mark. + // Fortunately the stack walker skips all the reflection invocation frames including this one. + // So this method will never be returned by the stack walker as the caller. + // See SystemDomain::CallersMethodCallbackWithStackMark in AppDomain.cpp. + SetValue(obj, value, BindingFlags.Default, Type.DefaultBinder, null); + } + + public bool IsPublic { get { return(Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public; } } + + public bool IsPrivate { get { return(Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Private; } } + + public bool IsFamily { get { return(Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Family; } } + + public bool IsAssembly { get { return(Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Assembly; } } + + public bool IsFamilyAndAssembly { get { return(Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamANDAssem; } } + + public bool IsFamilyOrAssembly { get { return(Attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamORAssem; } } + + public bool IsStatic { get { return(Attributes & FieldAttributes.Static) != 0; } } + + public bool IsInitOnly { get { return(Attributes & FieldAttributes.InitOnly) != 0; } } + + public bool IsLiteral { get { return(Attributes & FieldAttributes.Literal) != 0; } } + + public bool IsNotSerialized { get { return(Attributes & FieldAttributes.NotSerialized) != 0; } } + + public bool IsSpecialName { get { return(Attributes & FieldAttributes.SpecialName) != 0; } } + + public bool IsPinvokeImpl { get { return(Attributes & FieldAttributes.PinvokeImpl) != 0; } } + + public virtual bool IsSecurityCritical + { + get { return FieldHandle.IsSecurityCritical(); } + } + + public virtual bool IsSecuritySafeCritical + { + get { return FieldHandle.IsSecuritySafeCritical(); } + } + + public virtual bool IsSecurityTransparent + { + get { return FieldHandle.IsSecurityTransparent(); } + } + + #endregion + +#if !FEATURE_CORECLR + Type _FieldInfo.GetType() + { + return base.GetType(); + } + + void _FieldInfo.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _FieldInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _FieldInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + // If you implement this method, make sure to include _FieldInfo.Invoke in VM\DangerousAPIs.h and + // include _FieldInfo in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp. + void _FieldInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + } + + [Serializable] + internal abstract class RuntimeFieldInfo : FieldInfo, ISerializable + { + #region Private Data Members + private BindingFlags m_bindingFlags; + protected RuntimeTypeCache m_reflectedTypeCache; + protected RuntimeType m_declaringType; + #endregion + + #region Constructor + protected RuntimeFieldInfo() + { + // Used for dummy head node during population + } + protected RuntimeFieldInfo(RuntimeTypeCache reflectedTypeCache, RuntimeType declaringType, BindingFlags bindingFlags) + { + m_bindingFlags = bindingFlags; + m_declaringType = declaringType; + m_reflectedTypeCache = reflectedTypeCache; + } + #endregion + +#if FEATURE_REMOTING + #region Legacy Remoting Cache + // The size of CachedData is accounted for by BaseObjectWithCachedData in object.h. + // This member is currently being used by Remoting for caching remoting data. If you + // need to cache data here, talk to the Remoting team to work out a mechanism, so that + // both caching systems can happily work together. + private RemotingFieldCachedData m_cachedData; + + internal RemotingFieldCachedData RemotingCache + { + get + { + // This grabs an internal copy of m_cachedData and uses + // that instead of looking at m_cachedData directly because + // the cache may get cleared asynchronously. This prevents + // us from having to take a lock. + RemotingFieldCachedData cache = m_cachedData; + if (cache == null) + { + cache = new RemotingFieldCachedData(this); + RemotingFieldCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null); + if (ret != null) + cache = ret; + } + return cache; + } + } + #endregion +#endif //FEATURE_REMOTING + + #region NonPublic Members + internal BindingFlags BindingFlags { get { return m_bindingFlags; } } + private RuntimeType ReflectedTypeInternal + { + get + { + return m_reflectedTypeCache.GetRuntimeType(); + } + } + + internal RuntimeType GetDeclaringTypeInternal() + { + return m_declaringType; + } + + internal RuntimeType GetRuntimeType() { return m_declaringType; } + internal abstract RuntimeModule GetRuntimeModule(); + #endregion + + #region MemberInfo Overrides + public override MemberTypes MemberType { get { return MemberTypes.Field; } } + public override Type ReflectedType + { + get + { + return m_reflectedTypeCache.IsGlobal ? null : ReflectedTypeInternal; + } + } + + public override Type DeclaringType + { + get + { + return m_reflectedTypeCache.IsGlobal ? null : m_declaringType; + } + } + + public override Module Module { get { return GetRuntimeModule(); } } + #endregion + + #region Object Overrides + public unsafe override String ToString() + { + return FieldType.FormatTypeName() + " " + Name; + } + #endregion + + #region ICustomAttributeProvider + public override Object[] GetCustomAttributes(bool inherit) + { + return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType"); + + return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public override bool IsDefined(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType"); + + return CustomAttribute.IsDefined(this, attributeRuntimeType); + } + + public override IList GetCustomAttributesData() + { + return CustomAttributeData.GetCustomAttributesInternal(this); + } + #endregion + + #region FieldInfo Overrides + // All implemented on derived classes + #endregion + + #region ISerializable Implementation + [System.Security.SecurityCritical] // auto-generated + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException("info"); + Contract.EndContractBlock(); + MemberInfoSerializationHolder.GetSerializationInfo( + info, + Name, + ReflectedTypeInternal, + ToString(), + MemberTypes.Field); + } + #endregion + } + + [Serializable] + internal unsafe sealed class RtFieldInfo : RuntimeFieldInfo, IRuntimeFieldInfo + { + #region FCalls + [System.Security.SecurityCritical] // auto-generated + [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; + private FieldAttributes m_fieldAttributes; + // lazy caching + private string m_name; + private RuntimeType m_fieldType; + private INVOCATION_FLAGS m_invocationFlags; + +#if FEATURE_APPX + private bool IsNonW8PFrameworkAPI() + { + if (GetRuntimeType().IsNonW8PFrameworkAPI()) + return true; + + // Allow "value__" + if (m_declaringType.IsEnum) + return false; + + RuntimeAssembly rtAssembly = GetRuntimeAssembly(); + if (rtAssembly.IsFrameworkAssembly()) + { + int ctorToken = rtAssembly.InvocableAttributeCtorToken; + if (System.Reflection.MetadataToken.IsNullToken(ctorToken) || + !CustomAttribute.IsAttributeDefined(GetRuntimeModule(), MetadataToken, ctorToken)) + return true; + } + + return false; + } +#endif + + internal INVOCATION_FLAGS InvocationFlags + { + get + { + if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0) + { + Type declaringType = DeclaringType; + bool fIsReflectionOnlyType = (declaringType is ReflectionOnlyType); + + INVOCATION_FLAGS invocationFlags = 0; + + // first take care of all the NO_INVOKE cases + if ( + (declaringType != null && declaringType.ContainsGenericParameters) || + (declaringType == null && Module.Assembly.ReflectionOnly) || + (fIsReflectionOnlyType) + ) + { + invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE; + } + + // If the invocationFlags are still 0, then + // this should be an usable field, determine the other flags + if (invocationFlags == 0) + { + if ((m_fieldAttributes & FieldAttributes.InitOnly) != (FieldAttributes)0) + invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_SPECIAL_FIELD; + + 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) + invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_FIELD_SPECIAL_CAST; + } + +#if FEATURE_APPX + if (AppDomain.ProfileAPICheck && IsNonW8PFrameworkAPI()) + invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API; +#endif // FEATURE_APPX + + // must be last to avoid threading problems + m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED; + } + + return m_invocationFlags; + } + } + #endregion + + private RuntimeAssembly GetRuntimeAssembly() { return m_declaringType.GetRuntimeAssembly(); } + + #region Constructor + [System.Security.SecurityCritical] // auto-generated + internal RtFieldInfo( + RuntimeFieldHandleInternal handle, RuntimeType declaringType, RuntimeTypeCache reflectedTypeCache, BindingFlags bindingFlags) + : base(reflectedTypeCache, declaringType, bindingFlags) + { + m_fieldHandle = handle.Value; + m_fieldAttributes = RuntimeFieldHandle.GetAttributes(handle); + } + #endregion + + #region Private Members + RuntimeFieldHandleInternal IRuntimeFieldInfo.Value + { + [System.Security.SecuritySafeCritical] + get + { + return new RuntimeFieldHandleInternal(m_fieldHandle); + } + } + + #endregion + + #region Internal Members + internal void CheckConsistency(Object target) + { + // only test instance fields + if ((m_fieldAttributes & FieldAttributes.Static) != FieldAttributes.Static) + { + if (!m_declaringType.IsInstanceOfType(target)) + { + if (target == null) + { + throw new TargetException(Environment.GetResourceString("RFLCT.Targ_StatFldReqTarg")); + } + else + { + throw new ArgumentException( + String.Format(CultureInfo.CurrentUICulture, Environment.GetResourceString("Arg_FieldDeclTarget"), + Name, m_declaringType, target.GetType())); + } + } + } + } + + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + internal override bool CacheEquals(object o) + { + RtFieldInfo m = o as RtFieldInfo; + + if ((object)m == null) + return false; + + return m.m_fieldHandle == m_fieldHandle; + } + + [System.Security.SecurityCritical] + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + internal void InternalSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture, ref StackCrawlMark stackMark) + { + INVOCATION_FLAGS invocationFlags = InvocationFlags; + RuntimeType declaringType = DeclaringType as RuntimeType; + + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE) != 0) + { + if (declaringType != null && declaringType.ContainsGenericParameters) + throw new InvalidOperationException(Environment.GetResourceString("Arg_UnboundGenField")); + + if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType) + throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyField")); + + throw new FieldAccessException(); + } + + CheckConsistency(obj); + + RuntimeType fieldType = (RuntimeType)FieldType; + value = fieldType.CheckValue(value, binder, culture, invokeAttr); + + #region Security Check +#if FEATURE_APPX + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + { + RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark); + if (caller != null && !caller.IsSafeForReflection()) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", FullName)); + } +#endif + + 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) + { + RuntimeFieldHandle.SetValue(this, obj, value, fieldType, m_fieldAttributes, null, ref domainInitialized); + } + else + { + domainInitialized = declaringType.DomainInitialized; + RuntimeFieldHandle.SetValue(this, obj, value, fieldType, m_fieldAttributes, declaringType, ref domainInitialized); + declaringType.DomainInitialized = domainInitialized; + } + } + + // UnsafeSetValue doesn't perform any consistency or visibility check. + // It is the caller's responsibility to ensure the operation is safe. + // When the caller needs to perform visibility checks they should call + // InternalSetValue() instead. When the caller needs to perform + // consistency checks they should call CheckConsistency() before + // calling this method. + [System.Security.SecurityCritical] // auto-generated + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + internal void UnsafeSetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture) + { + RuntimeType declaringType = DeclaringType as RuntimeType; + RuntimeType fieldType = (RuntimeType)FieldType; + value = fieldType.CheckValue(value, binder, culture, invokeAttr); + + bool domainInitialized = false; + if (declaringType == null) + { + RuntimeFieldHandle.SetValue(this, obj, value, fieldType, m_fieldAttributes, null, ref domainInitialized); + } + else + { + domainInitialized = declaringType.DomainInitialized; + RuntimeFieldHandle.SetValue(this, obj, value, fieldType, m_fieldAttributes, declaringType, ref domainInitialized); + declaringType.DomainInitialized = domainInitialized; + } + } + + [System.Security.SecuritySafeCritical] + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + internal Object InternalGetValue(Object obj, ref StackCrawlMark stackMark) + { + INVOCATION_FLAGS invocationFlags = InvocationFlags; + RuntimeType declaringType = DeclaringType as RuntimeType; + + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE) != 0) + { + if (declaringType != null && DeclaringType.ContainsGenericParameters) + throw new InvalidOperationException(Environment.GetResourceString("Arg_UnboundGenField")); + + if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType) + throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyField")); + + throw new FieldAccessException(); + } + + CheckConsistency(obj); + +#if FEATURE_APPX + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + { + RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark); + if (caller != null && !caller.IsSafeForReflection()) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", FullName)); + } +#endif + + 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); + } + + // UnsafeGetValue doesn't perform any consistency or visibility check. + // It is the caller's responsibility to ensure the operation is safe. + // When the caller needs to perform visibility checks they should call + // InternalGetValue() instead. When the caller needs to perform + // consistency checks they should call CheckConsistency() before + // calling this method. + [System.Security.SecurityCritical] + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + internal Object UnsafeGetValue(Object obj) + { + RuntimeType declaringType = DeclaringType as RuntimeType; + + RuntimeType fieldType = (RuntimeType)FieldType; + + bool domainInitialized = false; + if (declaringType == null) + { + return RuntimeFieldHandle.GetValue(this, obj, fieldType, null, ref domainInitialized); + } + else + { + domainInitialized = declaringType.DomainInitialized; + object retVal = RuntimeFieldHandle.GetValue(this, obj, fieldType, declaringType, ref domainInitialized); + declaringType.DomainInitialized = domainInitialized; + return retVal; + } + } + + #endregion + + #region MemberInfo Overrides + public override String Name + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + if (m_name == null) + m_name = RuntimeFieldHandle.GetName(this); + + return m_name; + } + } + + internal String FullName + { + get + { + return String.Format("{0}.{1}", DeclaringType.FullName, Name); + } + } + + public override int MetadataToken + { + [System.Security.SecuritySafeCritical] // auto-generated + get { return RuntimeFieldHandle.GetToken(this); } + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal override RuntimeModule GetRuntimeModule() + { + return RuntimeTypeHandle.GetModule(RuntimeFieldHandle.GetApproxDeclaringType(this)); + } + + #endregion + + #region FieldInfo Overrides + public override Object GetValue(Object obj) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return InternalGetValue(obj, ref stackMark); + } + + public override object GetRawConstantValue() { throw new InvalidOperationException(); } + + [System.Security.SecuritySafeCritical] // auto-generated + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public override Object GetValueDirect(TypedReference obj) + { + if (obj.IsNull) + throw new ArgumentException(Environment.GetResourceString("Arg_TypedReference_Null")); + Contract.EndContractBlock(); + + unsafe + { + // Passing TypedReference by reference is easier to make correct in native code + return RuntimeFieldHandle.GetValueDirect(this, (RuntimeType)FieldType, &obj, (RuntimeType)DeclaringType); + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public override void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + InternalSetValue(obj, value, invokeAttr, binder, culture, ref stackMark); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public override void SetValueDirect(TypedReference obj, Object value) + { + if (obj.IsNull) + throw new ArgumentException(Environment.GetResourceString("Arg_TypedReference_Null")); + Contract.EndContractBlock(); + + unsafe + { + // Passing TypedReference by reference is easier to make correct in native code + RuntimeFieldHandle.SetValueDirect(this, (RuntimeType)FieldType, &obj, value, (RuntimeType)DeclaringType); + } + } + + public override RuntimeFieldHandle FieldHandle + { + get + { + Type declaringType = DeclaringType; + if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly")); + return new RuntimeFieldHandle(this); + } + } + + internal IntPtr GetFieldHandle() + { + return m_fieldHandle; + } + + public override FieldAttributes Attributes + { + get + { + return m_fieldAttributes; + } + } + + public override Type FieldType + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + if (m_fieldType == null) + m_fieldType = new Signature(this, m_declaringType).FieldType; + + return m_fieldType; + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + public override Type[] GetRequiredCustomModifiers() + { + return new Signature(this, m_declaringType).GetCustomModifiers(1, true); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public override Type[] GetOptionalCustomModifiers() + { + return new Signature(this, m_declaringType).GetCustomModifiers(1, false); + } + + #endregion + } + + [Serializable] + internal sealed unsafe class MdFieldInfo : RuntimeFieldInfo, ISerializable + { + #region Private Data Members + private int m_tkField; + private string m_name; + private RuntimeType m_fieldType; + private FieldAttributes m_fieldAttributes; + #endregion + + #region Constructor + internal MdFieldInfo( + int tkField, FieldAttributes fieldAttributes, RuntimeTypeHandle declaringTypeHandle, RuntimeTypeCache reflectedTypeCache, BindingFlags bindingFlags) + : base(reflectedTypeCache, declaringTypeHandle.GetRuntimeType(), bindingFlags) + { + m_tkField = tkField; + m_name = null; + m_fieldAttributes = fieldAttributes; + } + #endregion + + #region Internal Members + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + internal override bool CacheEquals(object o) + { + MdFieldInfo m = o as MdFieldInfo; + + if ((object)m == null) + return false; + + return m.m_tkField == m_tkField && + m_declaringType.GetTypeHandleInternal().GetModuleHandle().Equals( + m.m_declaringType.GetTypeHandleInternal().GetModuleHandle()); + } + #endregion + + #region MemberInfo Overrides + public override String Name + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + if (m_name == null) + m_name = GetRuntimeModule().MetadataImport.GetName(m_tkField).ToString(); + + return m_name; + } + } + + public override int MetadataToken { get { return m_tkField; } } + internal override RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); } + #endregion + + #region FieldInfo Overrides + public override RuntimeFieldHandle FieldHandle { get { throw new NotSupportedException(); } } + public override FieldAttributes Attributes { get { return m_fieldAttributes; } } + + public override bool IsSecurityCritical { get { return DeclaringType.IsSecurityCritical; } } + public override bool IsSecuritySafeCritical { get { return DeclaringType.IsSecuritySafeCritical; } } + public override bool IsSecurityTransparent { get { return DeclaringType.IsSecurityTransparent; } } + + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public override Object GetValueDirect(TypedReference obj) + { + return GetValue(null); + } + + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public override void SetValueDirect(TypedReference obj,Object value) + { + throw new FieldAccessException(Environment.GetResourceString("Acc_ReadOnly")); + } + + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public unsafe override Object GetValue(Object obj) + { + return GetValue(false); + } + + public unsafe override Object GetRawConstantValue() { return GetValue(true); } + + [System.Security.SecuritySafeCritical] // auto-generated + private unsafe Object GetValue(bool raw) + { + // Cannot cache these because they could be user defined non-agile enumerations + + Object value = MdConstant.GetValue(GetRuntimeModule().MetadataImport, m_tkField, FieldType.GetTypeHandleInternal(), raw); + + if (value == DBNull.Value) + throw new NotSupportedException(Environment.GetResourceString("Arg_EnumLitValueNotFound")); + + return value; + } + + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public override void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture) + { + throw new FieldAccessException(Environment.GetResourceString("Acc_ReadOnly")); + } + + public override Type FieldType + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + if (m_fieldType == null) + { + ConstArray fieldMarshal = GetRuntimeModule().MetadataImport.GetSigOfFieldDef(m_tkField); + + m_fieldType = new Signature(fieldMarshal.Signature.ToPointer(), + (int)fieldMarshal.Length, m_declaringType).FieldType; + } + + return m_fieldType; + } + } + + public override Type[] GetRequiredCustomModifiers() + { + return EmptyArray.Value; + } + + public override Type[] GetOptionalCustomModifiers() + { + return EmptyArray.Value; + } + + #endregion + } + +} diff --git a/src/mscorlib/src/System/Reflection/GenericParameterAttributes.cs b/src/mscorlib/src/System/Reflection/GenericParameterAttributes.cs new file mode 100644 index 0000000000..d954b2e0f2 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/GenericParameterAttributes.cs @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection +{ + [Flags()] + public enum GenericParameterAttributes + { + None = 0x0000, + VarianceMask = 0x0003, + Covariant = 0x0001, + Contravariant = 0x0002, + SpecialConstraintMask = 0x001C, + ReferenceTypeConstraint = 0x0004, + NotNullableValueTypeConstraint = 0x0008, + DefaultConstructorConstraint = 0x0010, + } +} + diff --git a/src/mscorlib/src/System/Reflection/ICustomAttributeProvider.cs b/src/mscorlib/src/System/Reflection/ICustomAttributeProvider.cs new file mode 100644 index 0000000000..1fd361c889 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/ICustomAttributeProvider.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// ICustomAttributeProvider is an interface that is implemented by reflection +// +// objects which support custom attributes. +// +// +namespace System.Reflection { + + using System; + + // Interface does not need to be marked with the serializable attribute +[System.Runtime.InteropServices.ComVisible(true)] + public interface ICustomAttributeProvider + { + + // Return an array of custom attributes identified by Type + Object[] GetCustomAttributes(Type attributeType, bool inherit); + + + // Return an array of all of the custom attributes (named attributes are not included) + Object[] GetCustomAttributes(bool inherit); + + + // Returns true if one or more instance of attributeType is defined on this member. + bool IsDefined (Type attributeType, bool inherit); + + } +} diff --git a/src/mscorlib/src/System/Reflection/IReflect.cs b/src/mscorlib/src/System/Reflection/IReflect.cs new file mode 100644 index 0000000000..92ce3412fc --- /dev/null +++ b/src/mscorlib/src/System/Reflection/IReflect.cs @@ -0,0 +1,117 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// IReflect is an interface that defines a subset of the Type reflection methods. +// +// This interface is used to access and invoke members of a Type. It can be either +// type based (like Type) or instance based (like Expando). This interface is used in +// combination with IExpando to model the IDispatchEx expando capibilities in +// the interop layer. +// +// +namespace System.Reflection { + using System; + using System.Runtime.InteropServices; + using CultureInfo = System.Globalization.CultureInfo; + + // Interface does not need to be marked with the serializable attribute + [Guid("AFBF15E5-C37C-11d2-B88E-00A0C9B471B8")] +[System.Runtime.InteropServices.ComVisible(true)] + public interface IReflect + { + // Return the requested method if it is implemented by the Reflection object. The + // match is based upon the name and DescriptorInfo which describes the signature + // of the method. + MethodInfo GetMethod(String name,BindingFlags bindingAttr,Binder binder, + Type[] types,ParameterModifier[] modifiers); + + // Return the requested method if it is implemented by the Reflection object. The + // match is based upon the name of the method. If the object implementes multiple methods + // with the same name an AmbiguousMatchException is thrown. + MethodInfo GetMethod(String name,BindingFlags bindingAttr); + + MethodInfo[] GetMethods(BindingFlags bindingAttr); + + // Return the requestion field if it is implemented by the Reflection object. The + // match is based upon a name. There cannot be more than a single field with + // a name. + FieldInfo GetField( + String name, + BindingFlags bindingAttr); + + FieldInfo[] GetFields( + BindingFlags bindingAttr); + + // Return the property based upon name. If more than one property has the given + // name an AmbiguousMatchException will be thrown. Returns null if no property + // is found. + PropertyInfo GetProperty( + String name, + BindingFlags bindingAttr); + + // Return the property based upon the name and Descriptor info describing the property + // indexing. Return null if no property is found. + PropertyInfo GetProperty( + String name, + BindingFlags bindingAttr, + Binder binder, + Type returnType, + Type[] types, + ParameterModifier[] modifiers); + + // Returns an array of PropertyInfos for all the properties defined on + // the Reflection object. + PropertyInfo[] GetProperties( + BindingFlags bindingAttr); + + // Return an array of members which match the passed in name. + MemberInfo[] GetMember( + String name, + BindingFlags bindingAttr); + + // Return an array of all of the members defined for this object. + MemberInfo[] GetMembers( + BindingFlags bindingAttr); + + // Description of the Binding Process. + // We must invoke a method that is accessable and for which the provided + // parameters have the most specific match. A method may be called if + // 1. The number of parameters in the method declaration equals the number of + // arguments provided to the invocation + // 2. The type of each argument can be converted by the binder to the + // type of the type of the parameter. + // + // The binder will find all of the matching methods. These method are found based + // upon the type of binding requested (MethodInvoke, Get/Set Properties). The set + // of methods is filtered by the name, number of arguments and a set of search modifiers + // defined in the Binder. + // + // After the method is selected, it will be invoked. Accessability is checked + // at that point. The search may be control which set of methods are searched based + // upon the accessibility attribute associated with the method. + // + // The BindToMethod method is responsible for selecting the method to be invoked. + // For the default binder, the most specific method will be selected. + // + // This will invoke a specific member... + Object InvokeMember( + String name, + BindingFlags invokeAttr, + Binder binder, + Object target, + Object[] args, + ParameterModifier[] modifiers, + CultureInfo culture, + String[] namedParameters); + + // Return the underlying Type that represents the IReflect Object. For expando object, + // this is the (Object) IReflectInstance.GetType(). For Type object it is this. + Type UnderlyingSystemType { + get; + } + } +} diff --git a/src/mscorlib/src/System/Reflection/IReflectableType.cs b/src/mscorlib/src/System/Reflection/IReflectableType.cs new file mode 100644 index 0000000000..7d4936868b --- /dev/null +++ b/src/mscorlib/src/System/Reflection/IReflectableType.cs @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// IReflectableType is an interface that is implemented by a Type produced +// by a ReflectionContext +// + +// +namespace System.Reflection { + + using System; + + public interface IReflectableType { + TypeInfo GetTypeInfo(); + } +} diff --git a/src/mscorlib/src/System/Reflection/InterfaceMapping.cs b/src/mscorlib/src/System/Reflection/InterfaceMapping.cs new file mode 100644 index 0000000000..488ef4484d --- /dev/null +++ b/src/mscorlib/src/System/Reflection/InterfaceMapping.cs @@ -0,0 +1,27 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// +// Interface Map. This struct returns the mapping of an interface into the actual methods on a class +// that implement that interface. +// +// +namespace System.Reflection { + using System; + +[System.Runtime.InteropServices.ComVisible(true)] + public struct InterfaceMapping { +[System.Runtime.InteropServices.ComVisible(true)] + public Type TargetType; // The type implementing the interface +[System.Runtime.InteropServices.ComVisible(true)] + public Type InterfaceType; // The type representing the interface +[System.Runtime.InteropServices.ComVisible(true)] + public MethodInfo[] TargetMethods; // The methods implementing the interface +[System.Runtime.InteropServices.ComVisible(true)] + public MethodInfo[] InterfaceMethods; // The methods defined on the interface + } +} diff --git a/src/mscorlib/src/System/Reflection/IntrospectionExtensions.cs b/src/mscorlib/src/System/Reflection/IntrospectionExtensions.cs new file mode 100644 index 0000000000..ce2630a908 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/IntrospectionExtensions.cs @@ -0,0 +1,35 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================================= +** +** +** +** +** +** Purpose: go from type to type info +** +** +=============================================================================*/ + +namespace System.Reflection +{ + using System.Reflection; + + public static class IntrospectionExtensions + { + public static TypeInfo GetTypeInfo(this Type type){ + if(type == null){ + throw new ArgumentNullException("type"); + } + var rcType=(IReflectableType)type; + if(rcType==null){ + return null; + }else{ + return rcType.GetTypeInfo(); + } + } + } +} + diff --git a/src/mscorlib/src/System/Reflection/InvalidFilterCriteriaException.cs b/src/mscorlib/src/System/Reflection/InvalidFilterCriteriaException.cs new file mode 100644 index 0000000000..7c980da379 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/InvalidFilterCriteriaException.cs @@ -0,0 +1,44 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// InvalidFilterCriteriaException is thrown in FindMembers when the +// +// filter criteria is not valid for the type of filter being used. +// +// +// +// +namespace System.Reflection { + + using System; + using System.Runtime.Serialization; + using ApplicationException = System.ApplicationException; + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] +#if FEATURE_CORECLR + public class InvalidFilterCriteriaException : Exception { +#else + public class InvalidFilterCriteriaException : ApplicationException { +#endif // FEATURE_CORECLR + public InvalidFilterCriteriaException() + : base(Environment.GetResourceString("Arg_InvalidFilterCriteriaException")) { + SetErrorCode(__HResults.COR_E_INVALIDFILTERCRITERIA); + } + + public InvalidFilterCriteriaException(String message) : base(message) { + SetErrorCode(__HResults.COR_E_INVALIDFILTERCRITERIA); + } + + public InvalidFilterCriteriaException(String message, Exception inner) : base(message, inner) { + SetErrorCode(__HResults.COR_E_INVALIDFILTERCRITERIA); + } + + protected InvalidFilterCriteriaException(SerializationInfo info, StreamingContext context) : base(info, context) { + } + + } +} diff --git a/src/mscorlib/src/System/Reflection/LoaderAllocator.cs b/src/mscorlib/src/System/Reflection/LoaderAllocator.cs new file mode 100644 index 0000000000..a8b4b0c3a0 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/LoaderAllocator.cs @@ -0,0 +1,86 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Reflection; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; +using System.Security; +using System.Collections.Generic; + + +namespace System.Reflection +{ + // + // We can destroy the unmanaged part of collectible type only after the managed part is definitely gone and thus + // nobody can call/allocate/reference anything related to the collectible assembly anymore. A call to finalizer + // alone does not guarantee that the managed part is gone. A malicious code can keep a reference to some object + // in a way that that survives finalization, or we can be running during shutdown where everything is finalized. + // + // The unmanaged LoaderAllocator keeps a reference to the managed LoaderAllocator in long weak handle. If the long + // weak handle is null, we can be sure that the managed part of the LoaderAllocator is definitely gone and that it + // is safe to destroy the unmanaged part. Unfortunately, we can not perform the above check in a finalizer on the + // LoaderAllocator, but it can be performed on a helper object. + // + // The finalization does not have to be done using CriticalFinalizerObject. We have to go over all LoaderAllocators + // during AppDomain shutdown anyway to avoid leaks e.g. if somebody stores reference to LoaderAllocator in a static. + // + internal sealed class LoaderAllocatorScout + { + // This field is set by the VM to atomically transfer the ownership to the managed loader allocator + internal IntPtr m_nativeLoaderAllocator; + + [SuppressUnmanagedCodeSecurity] + [SecurityCritical] + [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)] + private static extern bool Destroy(IntPtr nativeLoaderAllocator); + + [SecuritySafeCritical] + ~LoaderAllocatorScout() + { + if (m_nativeLoaderAllocator.IsNull()) + return; + + // Assemblies and LoaderAllocators will be cleaned up during AppDomain shutdown in + // unmanaged code + // So it is ok to skip reregistration and cleanup for finalization during appdomain shutdown. + // We also avoid early finalization of LoaderAllocatorScout due to AD unload when the object was inside DelayedFinalizationList. + if (!Environment.HasShutdownStarted && + !AppDomain.CurrentDomain.IsFinalizingForUnload()) + { + + // Destroy returns false if the managed LoaderAllocator is still alive. + if (!Destroy(m_nativeLoaderAllocator)) + { + // Somebody might have been holding a reference on us via weak handle. + // We will keep trying. It will be hopefully released eventually. + GC.ReRegisterForFinalize(this); + } + } + } + } + + internal sealed class LoaderAllocator + { + LoaderAllocator() + { + m_slots = new object [5]; + // m_slotsUsed = 0; + + m_scout = new LoaderAllocatorScout(); + } + +#pragma warning disable 169 +#pragma warning disable 414 + LoaderAllocatorScout m_scout; + object [] m_slots; + internal CerHashtable m_methodInstantiations; + int m_slotsUsed; +#pragma warning restore 414 +#pragma warning restore 169 + } +} + diff --git a/src/mscorlib/src/System/Reflection/ManifestResourceInfo.cs b/src/mscorlib/src/System/Reflection/ManifestResourceInfo.cs new file mode 100644 index 0000000000..a53d32abdb --- /dev/null +++ b/src/mscorlib/src/System/Reflection/ManifestResourceInfo.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================================= +** +** +** +** +** +** Purpose: For info regarding a manifest resource's topology. +** +** +=============================================================================*/ + +namespace System.Reflection { + using System; + +[System.Runtime.InteropServices.ComVisible(true)] + public class ManifestResourceInfo { + private Assembly _containingAssembly; + private String _containingFileName; + private ResourceLocation _resourceLocation; + + public ManifestResourceInfo(Assembly containingAssembly, + String containingFileName, + ResourceLocation resourceLocation) + { + _containingAssembly = containingAssembly; + _containingFileName = containingFileName; + _resourceLocation = resourceLocation; + } + + public virtual Assembly ReferencedAssembly + { + get { + return _containingAssembly; + } + } + + public virtual String FileName + { + get { + return _containingFileName; + } + } + + public virtual ResourceLocation ResourceLocation + { + get { + return _resourceLocation; + } + } + } + + // The ResourceLocation is a combination of these flags, set or not. + // Linked means not Embedded. +[Serializable] + [Flags] +[System.Runtime.InteropServices.ComVisible(true)] + public enum ResourceLocation + { + Embedded = 0x1, + ContainedInAnotherAssembly = 0x2, + ContainedInManifestFile = 0x4 + } +} diff --git a/src/mscorlib/src/System/Reflection/MdConstant.cs b/src/mscorlib/src/System/Reflection/MdConstant.cs new file mode 100644 index 0000000000..1941736787 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/MdConstant.cs @@ -0,0 +1,169 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection +{ + using System; + + internal static class MdConstant + { + [System.Security.SecurityCritical] // auto-generated + public static unsafe Object GetValue(MetadataImport scope, int token, RuntimeTypeHandle fieldTypeHandle, bool raw) + { + CorElementType corElementType = 0; + long buffer = 0; + int length; + String stringVal; + + stringVal = scope.GetDefaultValue(token, out buffer, out length, out corElementType); + + RuntimeType fieldType = fieldTypeHandle.GetRuntimeType(); + + if (fieldType.IsEnum && raw == false) + { + long defaultValue = 0; + + switch (corElementType) + { + #region Switch + + case CorElementType.Void: + return DBNull.Value; + + case CorElementType.Char: + defaultValue = *(char*)&buffer; + break; + + case CorElementType.I1: + defaultValue = *(sbyte*)&buffer; + break; + + case CorElementType.U1: + defaultValue = *(byte*)&buffer; + break; + + case CorElementType.I2: + defaultValue = *(short*)&buffer; + break; + + case CorElementType.U2: + defaultValue = *(ushort*)&buffer; + break; + + case CorElementType.I4: + defaultValue = *(int*)&buffer; + break; + + case CorElementType.U4: + defaultValue = *(uint*)&buffer; + break; + + case CorElementType.I8: + defaultValue = buffer; + break; + + case CorElementType.U8: + defaultValue = buffer; + break; + + default: + throw new FormatException(Environment.GetResourceString("Arg_BadLiteralFormat")); + #endregion + } + + return RuntimeType.CreateEnum(fieldType, defaultValue); + } + else if (fieldType == typeof(DateTime)) + { + long defaultValue = 0; + + switch (corElementType) + { + #region Switch + + case CorElementType.Void: + return DBNull.Value; + + case CorElementType.I8: + defaultValue = buffer; + break; + + case CorElementType.U8: + defaultValue = buffer; + break; + + default: + throw new FormatException(Environment.GetResourceString("Arg_BadLiteralFormat")); + #endregion + } + + return new DateTime(defaultValue); + } + else + { + switch (corElementType) + { + #region Switch + + case CorElementType.Void: + return DBNull.Value; + + case CorElementType.Char: + return *(char*)&buffer; + + case CorElementType.I1: + return *(sbyte*)&buffer; + + case CorElementType.U1: + return *(byte*)&buffer; + + case CorElementType.I2: + return *(short*)&buffer; + + case CorElementType.U2: + return *(ushort*)&buffer; + + case CorElementType.I4: + return *(int*)&buffer; + + case CorElementType.U4: + return *(uint*)&buffer; + + case CorElementType.I8: + return buffer; + + case CorElementType.U8: + return (ulong)buffer; + + case CorElementType.Boolean : + // The boolean value returned from the metadata engine is stored as a + // BOOL, which actually maps to an int. We need to read it out as an int + // to avoid problems on big-endian machines. + return (*(int*)&buffer != 0); + + case CorElementType.R4 : + return *(float*)&buffer; + + case CorElementType.R8: + return *(double*)&buffer; + + case CorElementType.String: + // A string constant can be empty but never null. + // A nullref constant can only be type CorElementType.Class. + return stringVal == null ? String.Empty : stringVal; + + case CorElementType.Class: + return null; + + default: + throw new FormatException(Environment.GetResourceString("Arg_BadLiteralFormat")); + #endregion + } + } + } + } + +} diff --git a/src/mscorlib/src/System/Reflection/MdImport.cs b/src/mscorlib/src/System/Reflection/MdImport.cs new file mode 100644 index 0000000000..3bf8eddbcc --- /dev/null +++ b/src/mscorlib/src/System/Reflection/MdImport.cs @@ -0,0 +1,736 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Reflection; +using System.Globalization; +using System.Threading; +using System.Diagnostics; +using System.Security.Permissions; +using System.Collections; +using System.Runtime.CompilerServices; +using System.Security; +using System.Text; +using System.Runtime.InteropServices; +using System.Configuration.Assemblies; +using System.Runtime.Versioning; +using System.Diagnostics.Contracts; + +namespace System.Reflection +{ + [Serializable] + internal enum CorElementType : byte + { + End = 0x00, + Void = 0x01, + Boolean = 0x02, + Char = 0x03, + I1 = 0x04, + U1 = 0x05, + I2 = 0x06, + U2 = 0x07, + I4 = 0x08, + U4 = 0x09, + I8 = 0x0A, + U8 = 0x0B, + R4 = 0x0C, + R8 = 0x0D, + String = 0x0E, + Ptr = 0x0F, + ByRef = 0x10, + ValueType = 0x11, + Class = 0x12, + Var = 0x13, + Array = 0x14, + GenericInst = 0x15, + TypedByRef = 0x16, + I = 0x18, + U = 0x19, + FnPtr = 0x1B, + Object = 0x1C, + SzArray = 0x1D, + MVar = 0x1E, + CModReqd = 0x1F, + CModOpt = 0x20, + Internal = 0x21, + Max = 0x22, + Modifier = 0x40, + Sentinel = 0x41, + Pinned = 0x45, + } + +[Serializable] +[Flags()] + internal enum MdSigCallingConvention: byte + { + CallConvMask = 0x0f, // Calling convention is bottom 4 bits + + Default = 0x00, + C = 0x01, + StdCall = 0x02, + ThisCall = 0x03, + FastCall = 0x04, + Vararg = 0x05, + Field = 0x06, + LocalSig = 0x07, + Property = 0x08, + Unmgd = 0x09, + GenericInst = 0x0a, // generic method instantiation + + Generic = 0x10, // Generic method sig with explicit number of type arguments (precedes ordinary parameter count) + HasThis = 0x20, // Top bit indicates a 'this' parameter + ExplicitThis = 0x40, // This parameter is explicitly in the signature + } + + +[Serializable] +[Flags()] + internal enum PInvokeAttributes + { + NoMangle = 0x0001, + + + CharSetMask = 0x0006, + CharSetNotSpec = 0x0000, + CharSetAnsi = 0x0002, + CharSetUnicode = 0x0004, + CharSetAuto = 0x0006, + + + BestFitUseAssem = 0x0000, + BestFitEnabled = 0x0010, + BestFitDisabled = 0x0020, + BestFitMask = 0x0030, + + ThrowOnUnmappableCharUseAssem = 0x0000, + ThrowOnUnmappableCharEnabled = 0x1000, + ThrowOnUnmappableCharDisabled = 0x2000, + ThrowOnUnmappableCharMask = 0x3000, + + SupportsLastError = 0x0040, + + CallConvMask = 0x0700, + CallConvWinapi = 0x0100, + CallConvCdecl = 0x0200, + CallConvStdcall = 0x0300, + CallConvThiscall = 0x0400, + CallConvFastcall = 0x0500, + + MaxValue = 0xFFFF, + } + + +[Serializable] +[Flags()] + internal enum MethodSemanticsAttributes + { + Setter = 0x0001, + Getter = 0x0002, + Other = 0x0004, + AddOn = 0x0008, + RemoveOn = 0x0010, + Fire = 0x0020, + } + + + [Serializable] + internal enum MetadataTokenType + { + Module = 0x00000000, + TypeRef = 0x01000000, + TypeDef = 0x02000000, + FieldDef = 0x04000000, + MethodDef = 0x06000000, + ParamDef = 0x08000000, + InterfaceImpl = 0x09000000, + MemberRef = 0x0a000000, + CustomAttribute = 0x0c000000, + Permission = 0x0e000000, + Signature = 0x11000000, + Event = 0x14000000, + Property = 0x17000000, + ModuleRef = 0x1a000000, + TypeSpec = 0x1b000000, + Assembly = 0x20000000, + AssemblyRef = 0x23000000, + File = 0x26000000, + ExportedType = 0x27000000, + ManifestResource = 0x28000000, + GenericPar = 0x2a000000, + MethodSpec = 0x2b000000, + String = 0x70000000, + Name = 0x71000000, + BaseType = 0x72000000, + Invalid = 0x7FFFFFFF, + } + + [Serializable] + internal struct ConstArray + { + public IntPtr Signature { get { return m_constArray; } } + public int Length { get { return m_length; } } + public byte this[int index] + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + if (index < 0 || index >= m_length) + throw new IndexOutOfRangeException(); + Contract.EndContractBlock(); + + unsafe + { + return ((byte*)m_constArray.ToPointer())[index]; + } + } + } + + // Keep the definition in sync with vm\ManagedMdImport.hpp + internal int m_length; + internal IntPtr m_constArray; + } + + [Serializable] + internal struct MetadataToken + { + #region Implicit Cast Operators + public static implicit operator int(MetadataToken token) { return token.Value; } + public static implicit operator MetadataToken(int token) { return new MetadataToken(token); } + #endregion + + #region Public Static Members + public static bool IsTokenOfType(int token, params MetadataTokenType[] types) + { + for (int i = 0; i < types.Length; i++) + { + if ((int)(token & 0xFF000000) == (int)types[i]) + return true; + } + + return false; + } + + public static bool IsNullToken(int token) + { + return (token & 0x00FFFFFF) == 0; + } + #endregion + + #region Public Data Members + public int Value; + #endregion + + #region Constructor + public MetadataToken(int token) { Value = token; } + #endregion + + #region Public Members + public bool IsGlobalTypeDefToken { get { return (Value == 0x02000001); } } + public MetadataTokenType TokenType { get { return (MetadataTokenType)(Value & 0xFF000000); } } + public bool IsTypeRef { get { return TokenType == MetadataTokenType.TypeRef; } } + public bool IsTypeDef { get { return TokenType == MetadataTokenType.TypeDef; } } + public bool IsFieldDef { get { return TokenType == MetadataTokenType.FieldDef; } } + public bool IsMethodDef { get { return TokenType == MetadataTokenType.MethodDef; } } + public bool IsMemberRef { get { return TokenType == MetadataTokenType.MemberRef; } } + public bool IsEvent { get { return TokenType == MetadataTokenType.Event; } } + public bool IsProperty { get { return TokenType == MetadataTokenType.Property; } } + public bool IsParamDef { get { return TokenType == MetadataTokenType.ParamDef; } } + public bool IsTypeSpec { get { return TokenType == MetadataTokenType.TypeSpec; } } + public bool IsMethodSpec { get { return TokenType == MetadataTokenType.MethodSpec; } } + public bool IsString { get { return TokenType == MetadataTokenType.String; } } + public bool IsSignature { get { return TokenType == MetadataTokenType.Signature; } } + public bool IsModule { get { return TokenType == MetadataTokenType.Module; } } + public bool IsAssembly { get { return TokenType == MetadataTokenType.Assembly; } } + public bool IsGenericPar { get { return TokenType == MetadataTokenType.GenericPar; } } + #endregion + + #region Object Overrides + public override string ToString() { return String.Format(CultureInfo.InvariantCulture, "0x{0:x8}", Value); } + #endregion + } + + internal unsafe struct MetadataEnumResult + { + // Keep the definition in sync with vm\ManagedMdImport.hpp + private int[] largeResult; + private int length; + private fixed int smallResult[16]; + + public int Length + { + get + { + return length; + } + } + + public int this[int index] + { + [System.Security.SecurityCritical] + get + { + Contract.Requires(0 <= index && index < Length); + if (largeResult != null) + return largeResult[index]; + + fixed (int* p = smallResult) + return p[index]; + } + } + } + + internal struct MetadataImport + { + #region Private Data Members + private IntPtr m_metadataImport2; + private object m_keepalive; + #endregion + + #region Override methods from Object + internal static readonly MetadataImport EmptyImport = new MetadataImport((IntPtr)0, null); + + public override int GetHashCode() + { + return ValueType.GetHashCodeOfPtr(m_metadataImport2); + } + + public override bool Equals(object obj) + { + if(!(obj is MetadataImport)) + return false; + return Equals((MetadataImport)obj); + } + + private bool Equals(MetadataImport import) + { + return import.m_metadataImport2 == m_metadataImport2; + } + + #endregion + + #region Static Members + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern void _GetMarshalAs(IntPtr pNativeType, int cNativeType, out int unmanagedType, out int safeArraySubType, out string safeArrayUserDefinedSubType, + out int arraySubType, out int sizeParamIndex, out int sizeConst, out string marshalType, out string marshalCookie, + out int iidParamIndex); + [System.Security.SecurityCritical] // auto-generated + internal static void GetMarshalAs(ConstArray nativeType, + out UnmanagedType unmanagedType, out VarEnum safeArraySubType, out string safeArrayUserDefinedSubType, + out UnmanagedType arraySubType, out int sizeParamIndex, out int sizeConst, out string marshalType, out string marshalCookie, + out int iidParamIndex) + { + int _unmanagedType, _safeArraySubType, _arraySubType; + + _GetMarshalAs(nativeType.Signature, (int)nativeType.Length, + out _unmanagedType, out _safeArraySubType, out safeArrayUserDefinedSubType, + out _arraySubType, out sizeParamIndex, out sizeConst, out marshalType, out marshalCookie, + out iidParamIndex); + unmanagedType = (UnmanagedType)_unmanagedType; + safeArraySubType = (VarEnum)_safeArraySubType; + arraySubType = (UnmanagedType)_arraySubType; + } + #endregion + + #region Internal Static Members + internal static void ThrowError(int hResult) + { + throw new MetadataException(hResult); + } + #endregion + + #region Constructor + internal MetadataImport(IntPtr metadataImport2, object keepalive) + { + m_metadataImport2 = metadataImport2; + m_keepalive = keepalive; + } + #endregion + + #region FCalls + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute (MethodImplOptions.InternalCall)] + private unsafe static extern void _Enum(IntPtr scope, int type, int parent, out MetadataEnumResult result); + + [System.Security.SecurityCritical] // auto-generated + public unsafe void Enum(MetadataTokenType type, int parent, out MetadataEnumResult result) + { + _Enum(m_metadataImport2, (int)type, parent, out result); + } + + [System.Security.SecurityCritical] // auto-generated + public unsafe void EnumNestedTypes(int mdTypeDef, out MetadataEnumResult result) + { + Enum(MetadataTokenType.TypeDef, mdTypeDef, out result); + } + + [System.Security.SecurityCritical] // auto-generated + public unsafe void EnumCustomAttributes(int mdToken, out MetadataEnumResult result) + { + Enum(MetadataTokenType.CustomAttribute, mdToken, out result); + } + + [System.Security.SecurityCritical] // auto-generated + public unsafe void EnumParams(int mdMethodDef, out MetadataEnumResult result) + { + Enum(MetadataTokenType.ParamDef, mdMethodDef, out result); + } + + [System.Security.SecurityCritical] // auto-generated + public unsafe void EnumFields(int mdTypeDef, out MetadataEnumResult result) + { + Enum(MetadataTokenType.FieldDef, mdTypeDef, out result); + } + + [System.Security.SecurityCritical] // auto-generated + public unsafe void EnumProperties(int mdTypeDef, out MetadataEnumResult result) + { + Enum(MetadataTokenType.Property, mdTypeDef, out result); + } + + [System.Security.SecurityCritical] // auto-generated + public unsafe void EnumEvents(int mdTypeDef, out MetadataEnumResult result) + { + Enum(MetadataTokenType.Event, mdTypeDef, out result); + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute (MethodImplOptions.InternalCall)] + private static extern String _GetDefaultValue(IntPtr scope, int mdToken, out long value, out int length, out int corElementType); + [System.Security.SecurityCritical] // auto-generated + public String GetDefaultValue(int mdToken, out long value, out int length, out CorElementType corElementType) + { + int _corElementType; + String stringVal; + stringVal = _GetDefaultValue(m_metadataImport2, mdToken, out value, out length, out _corElementType); + corElementType = (CorElementType)_corElementType; + return stringVal; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute (MethodImplOptions.InternalCall)] + private static unsafe extern void _GetUserString(IntPtr scope, int mdToken, void** name, out int length); + [System.Security.SecurityCritical] // auto-generated + public unsafe String GetUserString(int mdToken) + { + void* name; + int length; + _GetUserString(m_metadataImport2, mdToken, &name, out length); + + if (name == null) + return null; + + char[] c = new char[length]; + for (int i = 0; i < length; i ++) + { +#if ALIGN_ACCESS + c[i] = (char)Marshal.ReadInt16( (IntPtr) (((char*)name) + i) ); +#else + c[i] = ((char*)name)[i]; +#endif + } + + return new String(c); + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute (MethodImplOptions.InternalCall)] + private static unsafe extern void _GetName(IntPtr scope, int mdToken, void** name); + [System.Security.SecurityCritical] // auto-generated + public unsafe Utf8String GetName(int mdToken) + { + void* name; + _GetName(m_metadataImport2, mdToken, &name); + + return new Utf8String(name); + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute (MethodImplOptions.InternalCall)] + private static unsafe extern void _GetNamespace(IntPtr scope, int mdToken, void** namesp); + [System.Security.SecurityCritical] // auto-generated + public unsafe Utf8String GetNamespace(int mdToken) + { + void* namesp; + _GetNamespace(m_metadataImport2, mdToken, &namesp); + + return new Utf8String(namesp); + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute (MethodImplOptions.InternalCall)] + private unsafe static extern void _GetEventProps(IntPtr scope, int mdToken, void** name, out int eventAttributes); + [System.Security.SecurityCritical] // auto-generated + public unsafe void GetEventProps(int mdToken, out void* name, out EventAttributes eventAttributes) + { + int _eventAttributes; + void* _name; + _GetEventProps(m_metadataImport2, mdToken, &_name, out _eventAttributes); + name = _name; + eventAttributes = (EventAttributes)_eventAttributes; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute (MethodImplOptions.InternalCall)] + private static extern void _GetFieldDefProps(IntPtr scope, int mdToken, out int fieldAttributes); + [System.Security.SecurityCritical] // auto-generated + public void GetFieldDefProps(int mdToken, out FieldAttributes fieldAttributes) + { + int _fieldAttributes; + _GetFieldDefProps(m_metadataImport2, mdToken, out _fieldAttributes); + fieldAttributes = (FieldAttributes)_fieldAttributes; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute (MethodImplOptions.InternalCall)] + private unsafe static extern void _GetPropertyProps(IntPtr scope, + int mdToken, void** name, out int propertyAttributes, out ConstArray signature); + [System.Security.SecurityCritical] // auto-generated + public unsafe void GetPropertyProps(int mdToken, out void* name, out PropertyAttributes propertyAttributes, out ConstArray signature) + { + int _propertyAttributes; + void* _name; + _GetPropertyProps(m_metadataImport2, mdToken, &_name, out _propertyAttributes, out signature); + name = _name; + propertyAttributes = (PropertyAttributes)_propertyAttributes; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute (MethodImplOptions.InternalCall)] + private static extern void _GetParentToken(IntPtr scope, + int mdToken, out int tkParent); + [System.Security.SecurityCritical] // auto-generated + public int GetParentToken(int tkToken) + { + int tkParent; + _GetParentToken(m_metadataImport2, tkToken, out tkParent); + return tkParent; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern void _GetParamDefProps(IntPtr scope, + int parameterToken, out int sequence, out int attributes); + [System.Security.SecurityCritical] // auto-generated + public void GetParamDefProps(int parameterToken, out int sequence, out ParameterAttributes attributes) + { + int _attributes; + + _GetParamDefProps(m_metadataImport2, parameterToken, out sequence, out _attributes); + + attributes = (ParameterAttributes)_attributes; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern void _GetGenericParamProps(IntPtr scope, + int genericParameter, + out int flags); + + [System.Security.SecurityCritical] // auto-generated + public void GetGenericParamProps( + int genericParameter, + out GenericParameterAttributes attributes) + { + int _attributes; + _GetGenericParamProps(m_metadataImport2, genericParameter, out _attributes); + attributes = (GenericParameterAttributes)_attributes; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern void _GetScopeProps(IntPtr scope, + out Guid mvid); + + [System.Security.SecurityCritical] // auto-generated + public void GetScopeProps( + out Guid mvid) + { + _GetScopeProps(m_metadataImport2, out mvid); + } + + + [System.Security.SecurityCritical] // auto-generated + public ConstArray GetMethodSignature(MetadataToken token) + { + if (token.IsMemberRef) + return GetMemberRefProps(token); + + return GetSigOfMethodDef(token); + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern void _GetSigOfMethodDef(IntPtr scope, + int methodToken, + ref ConstArray signature); + + [System.Security.SecurityCritical] // auto-generated + public ConstArray GetSigOfMethodDef(int methodToken) + { + ConstArray signature = new ConstArray(); + + _GetSigOfMethodDef(m_metadataImport2, methodToken, ref signature); + + return signature; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern void _GetSignatureFromToken(IntPtr scope, + int methodToken, + ref ConstArray signature); + + [System.Security.SecurityCritical] // auto-generated + public ConstArray GetSignatureFromToken(int token) + { + ConstArray signature = new ConstArray(); + + _GetSignatureFromToken(m_metadataImport2, token, ref signature); + + return signature; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern void _GetMemberRefProps(IntPtr scope, + int memberTokenRef, + out ConstArray signature); + + [System.Security.SecurityCritical] // auto-generated + public ConstArray GetMemberRefProps(int memberTokenRef) + { + ConstArray signature = new ConstArray(); + + _GetMemberRefProps(m_metadataImport2, memberTokenRef, out signature); + + return signature; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern void _GetCustomAttributeProps(IntPtr scope, + int customAttributeToken, + out int constructorToken, + out ConstArray signature); + + [System.Security.SecurityCritical] // auto-generated + public void GetCustomAttributeProps( + int customAttributeToken, + out int constructorToken, + out ConstArray signature) + { + _GetCustomAttributeProps(m_metadataImport2, customAttributeToken, + out constructorToken, out signature); + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern void _GetClassLayout(IntPtr scope, + int typeTokenDef, out int packSize, out int classSize); + [System.Security.SecurityCritical] // auto-generated + public void GetClassLayout( + int typeTokenDef, + out int packSize, + out int classSize) + { + _GetClassLayout(m_metadataImport2, typeTokenDef, out packSize, out classSize); + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern bool _GetFieldOffset(IntPtr scope, + int typeTokenDef, int fieldTokenDef, out int offset); + [System.Security.SecurityCritical] // auto-generated + public bool GetFieldOffset( + int typeTokenDef, + int fieldTokenDef, + out int offset) + { + return _GetFieldOffset(m_metadataImport2, typeTokenDef, fieldTokenDef, out offset); + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern void _GetSigOfFieldDef(IntPtr scope, + int fieldToken, + ref ConstArray fieldMarshal); + + [System.Security.SecurityCritical] // auto-generated + public ConstArray GetSigOfFieldDef(int fieldToken) + { + ConstArray fieldMarshal = new ConstArray(); + + _GetSigOfFieldDef(m_metadataImport2, fieldToken, ref fieldMarshal); + + return fieldMarshal; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern void _GetFieldMarshal(IntPtr scope, + int fieldToken, + ref ConstArray fieldMarshal); + + [System.Security.SecurityCritical] // auto-generated + public ConstArray GetFieldMarshal(int fieldToken) + { + ConstArray fieldMarshal = new ConstArray(); + + _GetFieldMarshal(m_metadataImport2, fieldToken, ref fieldMarshal); + + return fieldMarshal; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private unsafe static extern void _GetPInvokeMap(IntPtr scope, + int token, + out int attributes, + void** importName, + void** importDll); + + [System.Security.SecurityCritical] // auto-generated + public unsafe void GetPInvokeMap( + int token, + out PInvokeAttributes attributes, + out String importName, + out String importDll) + { + int _attributes; + void* _importName, _importDll; + _GetPInvokeMap(m_metadataImport2, token, out _attributes, &_importName, &_importDll); + importName = new Utf8String(_importName).ToString(); + importDll = new Utf8String(_importDll).ToString(); + + attributes = (PInvokeAttributes)_attributes; + } + + [System.Security.SecurityCritical] // auto-generated + [MethodImplAttribute(MethodImplOptions.InternalCall)] + private static extern bool _IsValidToken(IntPtr scope, int token); + [System.Security.SecurityCritical] // auto-generated + public bool IsValidToken(int token) + { + return _IsValidToken(m_metadataImport2, token); + } + #endregion + } + + + internal class MetadataException : Exception + { + private int m_hr; + internal MetadataException(int hr) { m_hr = hr; } + + public override string ToString() + { + return String.Format(CultureInfo.CurrentCulture, "MetadataException HResult = {0:x}.", m_hr); + } + } +} + + diff --git a/src/mscorlib/src/System/Reflection/MemberFilter.cs b/src/mscorlib/src/System/Reflection/MemberFilter.cs new file mode 100644 index 0000000000..b476409d5d --- /dev/null +++ b/src/mscorlib/src/System/Reflection/MemberFilter.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// MemberFilter is a delegate used to filter Members. This delegate is used +// +// as a callback from Type.FindMembers. +// +// +namespace System.Reflection { + + // Define the delegate + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public delegate bool MemberFilter(MemberInfo m, Object filterCriteria); +} diff --git a/src/mscorlib/src/System/Reflection/MemberInfo.cs b/src/mscorlib/src/System/Reflection/MemberInfo.cs new file mode 100644 index 0000000000..248c78bf70 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/MemberInfo.cs @@ -0,0 +1,148 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection +{ + using System; + using System.Collections.Generic; + using System.Diagnostics.Contracts; + using System.Runtime; + using System.Runtime.InteropServices; + using System.Security.Permissions; + + [Serializable] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_MemberInfo))] +#pragma warning disable 618 + [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")] +#pragma warning restore 618 + [System.Runtime.InteropServices.ComVisible(true)] + public abstract class MemberInfo : ICustomAttributeProvider, _MemberInfo + { + #region Constructor + protected MemberInfo() { } + #endregion + + #region Internal Methods + internal virtual bool CacheEquals(object o) { throw new NotImplementedException(); } + #endregion + + #region Public Abstract\Virtual Members + public abstract MemberTypes MemberType { get; } + + public abstract String Name { get; } + + public abstract Type DeclaringType { get; } + + public abstract Type ReflectedType { get; } + + public virtual IEnumerable CustomAttributes + { + get + { + return GetCustomAttributesData(); + } + } + public abstract Object[] GetCustomAttributes(bool inherit); + + public abstract Object[] GetCustomAttributes(Type attributeType, bool inherit); + + public abstract bool IsDefined(Type attributeType, bool inherit); + + public virtual IList GetCustomAttributesData() + { + throw new NotImplementedException(); + } + + public virtual int MetadataToken { get { throw new InvalidOperationException(); } } + + public virtual Module Module + { + get + { + if (this is Type) + return ((Type)this).Module; + + throw new NotImplementedException(); + } + } + + + + #endregion + + public static bool operator ==(MemberInfo left, MemberInfo right) + { + if (ReferenceEquals(left, right)) + return true; + + if ((object)left == null || (object)right == null) + return false; + + Type type1, type2; + MethodBase method1, method2; + FieldInfo field1, field2; + EventInfo event1, event2; + PropertyInfo property1, property2; + + if ((type1 = left as Type) != null && (type2 = right as Type) != null) + return type1 == type2; + else if ((method1 = left as MethodBase) != null && (method2 = right as MethodBase) != null) + return method1 == method2; + else if ((field1 = left as FieldInfo) != null && (field2 = right as FieldInfo) != null) + return field1 == field2; + else if ((event1 = left as EventInfo) != null && (event2 = right as EventInfo) != null) + return event1 == event2; + else if ((property1 = left as PropertyInfo) != null && (property2 = right as PropertyInfo) != null) + return property1 == property2; + + return false; + } + + public static bool operator !=(MemberInfo left, MemberInfo right) + { + return !(left == right); + } + + public override bool Equals(object obj) + { + return base.Equals(obj); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + +#if !FEATURE_CORECLR + // this method is required so Object.GetType is not made final virtual by the compiler + Type _MemberInfo.GetType() + { + return base.GetType(); + } + + void _MemberInfo.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _MemberInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _MemberInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _MemberInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + } +} diff --git a/src/mscorlib/src/System/Reflection/MemberInfoSerializationHolder.cs b/src/mscorlib/src/System/Reflection/MemberInfoSerializationHolder.cs new file mode 100644 index 0000000000..c1b4ee5fe1 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/MemberInfoSerializationHolder.cs @@ -0,0 +1,287 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Runtime.Remoting; +using System.Runtime.Serialization; +using System.Globalization; +using System.Diagnostics.Contracts; + +namespace System.Reflection +{ + [Serializable] + internal class MemberInfoSerializationHolder : ISerializable, IObjectReference + { + #region Staitc Public Members + public static void GetSerializationInfo(SerializationInfo info, String name, RuntimeType reflectedClass, String signature, MemberTypes type) + { + GetSerializationInfo(info, name, reflectedClass, signature, null, type, null); + } + + public static void GetSerializationInfo( + SerializationInfo info, + String name, + RuntimeType reflectedClass, + String signature, + String signature2, + MemberTypes type, + Type[] genericArguments) + { + if (info == null) + throw new ArgumentNullException("info"); + Contract.EndContractBlock(); + + String assemblyName = reflectedClass.Module.Assembly.FullName; + String typeName = reflectedClass.FullName; + + info.SetType(typeof(MemberInfoSerializationHolder)); + info.AddValue("Name", name, typeof(String)); + info.AddValue("AssemblyName", assemblyName, typeof(String)); + info.AddValue("ClassName", typeName, typeof(String)); + info.AddValue("Signature", signature, typeof(String)); + info.AddValue("Signature2", signature2, typeof(String)); + info.AddValue("MemberType", (int)type); + info.AddValue("GenericArguments", genericArguments, typeof(Type[])); + } + #endregion + + #region Private Data Members + private String m_memberName; + private RuntimeType m_reflectedType; + // m_signature stores the ToString() representation of the member which is sometimes ambiguous. + // Mulitple overloads of the same methods or properties can identical ToString(). + // m_signature2 stores the SerializationToString() representation which should be unique for each member. + // It is only written and used by post 4.0 CLR versions. + private String m_signature; + private String m_signature2; + private MemberTypes m_memberType; + private SerializationInfo m_info; + #endregion + + #region Constructor + internal MemberInfoSerializationHolder(SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException("info"); + Contract.EndContractBlock(); + + String assemblyName = info.GetString("AssemblyName"); + String typeName = info.GetString("ClassName"); + + if (assemblyName == null || typeName == null) + throw new SerializationException(Environment.GetResourceString("Serialization_InsufficientState")); + + Assembly assem = FormatterServices.LoadAssemblyFromString(assemblyName); + m_reflectedType = assem.GetType(typeName, true, false) as RuntimeType; + m_memberName = info.GetString("Name"); + m_signature = info.GetString("Signature"); + // Only v4.0 and later generates and consumes Signature2 + m_signature2 = (string)info.GetValueNoThrow("Signature2", typeof(string)); + m_memberType = (MemberTypes)info.GetInt32("MemberType"); + m_info = info; + } + #endregion + + #region ISerializable + [System.Security.SecurityCritical] // auto-generated + public virtual void GetObjectData(SerializationInfo info, StreamingContext context) + { + throw new NotSupportedException(Environment.GetResourceString(ResId.NotSupported_Method)); + } + #endregion + + #region IObjectReference + [System.Security.SecurityCritical] // auto-generated + public virtual Object GetRealObject(StreamingContext context) + { + if (m_memberName == null || m_reflectedType == null || m_memberType == 0) + throw new SerializationException(Environment.GetResourceString(ResId.Serialization_InsufficientState)); + + BindingFlags bindingFlags = + BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | + BindingFlags.Static | BindingFlags.OptionalParamBinding; + + switch (m_memberType) + { + #region case MemberTypes.Field: + case MemberTypes.Field: + { + FieldInfo[] fields = m_reflectedType.GetMember(m_memberName, MemberTypes.Field, bindingFlags) as FieldInfo[]; + + if (fields.Length == 0) + throw new SerializationException(Environment.GetResourceString("Serialization_UnknownMember", m_memberName)); + + return fields[0]; + } + #endregion + + #region case MemberTypes.Event: + case MemberTypes.Event: + { + EventInfo[] events = m_reflectedType.GetMember(m_memberName, MemberTypes.Event, bindingFlags) as EventInfo[]; + + if (events.Length == 0) + throw new SerializationException(Environment.GetResourceString("Serialization_UnknownMember", m_memberName)); + + return events[0]; + } + #endregion + + #region case MemberTypes.Property: + case MemberTypes.Property: + { + PropertyInfo[] properties = m_reflectedType.GetMember(m_memberName, MemberTypes.Property, bindingFlags) as PropertyInfo[]; + + if (properties.Length == 0) + throw new SerializationException(Environment.GetResourceString("Serialization_UnknownMember", m_memberName)); + + if (properties.Length == 1) + return properties[0]; + + if (properties.Length > 1) + { + for (int i = 0; i < properties.Length; i++) + { + if (m_signature2 != null) + { + if (((RuntimePropertyInfo)properties[i]).SerializationToString().Equals(m_signature2)) + return properties[i]; + } + else + { + if ((properties[i]).ToString().Equals(m_signature)) + return properties[i]; + } + } + } + + throw new SerializationException(Environment.GetResourceString(ResId.Serialization_UnknownMember, m_memberName)); + } + #endregion + + #region case MemberTypes.Constructor: + case MemberTypes.Constructor: + { + if (m_signature == null) + throw new SerializationException(Environment.GetResourceString(ResId.Serialization_NullSignature)); + + ConstructorInfo[] constructors = m_reflectedType.GetMember(m_memberName, MemberTypes.Constructor, bindingFlags) as ConstructorInfo[]; + + if (constructors.Length == 1) + return constructors[0]; + + if (constructors.Length > 1) + { + for (int i = 0; i < constructors.Length; i++) + { + if (m_signature2 != null) + { + if (((RuntimeConstructorInfo)constructors[i]).SerializationToString().Equals(m_signature2)) + return constructors[i]; + } + else + { + if (constructors[i].ToString().Equals(m_signature)) + return constructors[i]; + } + } + } + + throw new SerializationException(Environment.GetResourceString(ResId.Serialization_UnknownMember, m_memberName)); + } + #endregion + + #region case MemberTypes.Method: + case MemberTypes.Method: + { + MethodInfo methodInfo = null; + + if (m_signature == null) + throw new SerializationException(Environment.GetResourceString(ResId.Serialization_NullSignature)); + + Type[] genericArguments = m_info.GetValueNoThrow("GenericArguments", typeof(Type[])) as Type[]; + + MethodInfo[] methods = m_reflectedType.GetMember(m_memberName, MemberTypes.Method, bindingFlags) as MethodInfo[]; + + if (methods.Length == 1) + methodInfo = methods[0]; + + else if (methods.Length > 1) + { + for (int i = 0; i < methods.Length; i++) + { + if (m_signature2 != null) + { + if (((RuntimeMethodInfo)methods[i]).SerializationToString().Equals(m_signature2)) + { + methodInfo = methods[i]; + break; + } + } + else + { + + if (methods[i].ToString().Equals(m_signature)) + { + methodInfo = methods[i]; + break; + } + } + + // Handle generic methods specially since the signature match above probably won't work (the candidate + // method info hasn't been instantiated). If our target method is generic as well we can skip this. + if (genericArguments != null && methods[i].IsGenericMethod) + { + if (methods[i].GetGenericArguments().Length == genericArguments.Length) + { + MethodInfo candidateMethod = methods[i].MakeGenericMethod(genericArguments); + + if (m_signature2 != null) + { + if (((RuntimeMethodInfo)candidateMethod).SerializationToString().Equals(m_signature2)) + { + methodInfo = candidateMethod; + break; + } + } + else + { + if (candidateMethod.ToString().Equals(m_signature)) + { + methodInfo = candidateMethod; + break; + } + } + } + } + } + } + + if (methodInfo == null) + throw new SerializationException(Environment.GetResourceString(ResId.Serialization_UnknownMember, m_memberName)); + + if (!methodInfo.IsGenericMethodDefinition) + return methodInfo; + + if (genericArguments == null) + return methodInfo; + + if (genericArguments[0] == null) + return null; + + return methodInfo.MakeGenericMethod(genericArguments); + } + #endregion + + default: + throw new ArgumentException(Environment.GetResourceString("Serialization_MemberTypeNotRecognized")); + } + } + #endregion + } + + +} diff --git a/src/mscorlib/src/System/Reflection/MemberTypes.cs b/src/mscorlib/src/System/Reflection/MemberTypes.cs new file mode 100644 index 0000000000..352a80244e --- /dev/null +++ b/src/mscorlib/src/System/Reflection/MemberTypes.cs @@ -0,0 +1,34 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// MemberTypes is an bit mask marking each type of Member that is defined as +// +// a subclass of MemberInfo. These are returned by MemberInfo.MemberType and +// are useful in switch statements. +// +// +namespace System.Reflection { + + using System; + // This Enum matchs the CorTypeAttr defined in CorHdr.h + [Serializable] + [Flags()] + [System.Runtime.InteropServices.ComVisible(true)] + public enum MemberTypes + { + // The following are the known classes which extend MemberInfo + Constructor = 0x01, + Event = 0x02, + Field = 0x04, + Method = 0x08, + Property = 0x10, + TypeInfo = 0x20, + Custom = 0x40, + NestedType = 0x80, + All = Constructor | Event | Field | Method | Property | TypeInfo | NestedType, + } +} diff --git a/src/mscorlib/src/System/Reflection/Metadata/AssemblyExtensions.cs b/src/mscorlib/src/System/Reflection/Metadata/AssemblyExtensions.cs new file mode 100644 index 0000000000..dd5d69b1fb --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Metadata/AssemblyExtensions.cs @@ -0,0 +1,47 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; + +namespace System.Reflection.Metadata +{ + public static class AssemblyExtensions + { + [DllImport(JitHelpers.QCall)] + [SecurityCritical] // unsafe method + [SuppressUnmanagedCodeSecurity] + [return: MarshalAs(UnmanagedType.Bool)] + private unsafe static extern bool InternalTryGetRawMetadata(RuntimeAssembly assembly, ref byte* blob, ref int length); + + // Retrieves the metadata section of the assembly, for use with System.Reflection.Metadata.MetadataReader. + // - Returns false upon failure. Metadata might not be available for some assemblies, such as AssemblyBuilder, .NET + // native images, etc. + // - Callers should not write to the metadata blob + // - The metadata blob pointer will remain valid as long as the AssemblyLoadContext with which the assembly is + // associated, is alive. The caller is responsible for keeping the assembly object alive while accessing the + // metadata blob. + [CLSCompliant(false)] // out byte* blob + [SecurityCritical] // unsafe method + public unsafe static bool TryGetRawMetadata(this Assembly assembly, out byte* blob, out int length) + { + if (assembly == null) + { + throw new ArgumentNullException("assembly"); + } + + blob = null; + length = 0; + + var runtimeAssembly = assembly as RuntimeAssembly; + if (runtimeAssembly == null) + { + return false; + } + + return InternalTryGetRawMetadata(runtimeAssembly, ref blob, ref length); + } + } +} diff --git a/src/mscorlib/src/System/Reflection/MethodAttributes.cs b/src/mscorlib/src/System/Reflection/MethodAttributes.cs new file mode 100644 index 0000000000..92b637b9c0 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/MethodAttributes.cs @@ -0,0 +1,56 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +// + +namespace System.Reflection +{ + using System; + [Serializable] + [Flags] + [System.Runtime.InteropServices.ComVisible(true)] + public enum MethodAttributes + { + // NOTE: This Enum matchs the CorMethodAttr defined in CorHdr.h + + // member access mask - Use this mask to retrieve accessibility information. + MemberAccessMask = 0x0007, + PrivateScope = 0x0000, // Member not referenceable. + Private = 0x0001, // Accessible only by the parent type. + FamANDAssem = 0x0002, // Accessible by sub-types only in this Assembly. + Assembly = 0x0003, // Accessibly by anyone in the Assembly. + Family = 0x0004, // Accessible only by type and sub-types. + FamORAssem = 0x0005, // Accessibly by sub-types anywhere, plus anyone in assembly. + Public = 0x0006, // Accessibly by anyone who has visibility to this scope. + // end member access mask + + // method contract attributes. + Static = 0x0010, // Defined on type, else per instance. + Final = 0x0020, // Method may not be overridden. + Virtual = 0x0040, // Method virtual. + HideBySig = 0x0080, // Method hides by name+sig, else just by name. + CheckAccessOnOverride= 0x0200, + + // vtable layout mask - Use this mask to retrieve vtable attributes. + VtableLayoutMask = 0x0100, + ReuseSlot = 0x0000, // The default. + NewSlot = 0x0100, // Method always gets a new slot in the vtable. + // end vtable layout mask + + // method implementation attributes. + Abstract = 0x0400, // Method does not provide an implementation. + SpecialName = 0x0800, // Method is special. Name describes how. + + // interop attributes + PinvokeImpl = 0x2000, // Implementation is forwarded through pinvoke. + UnmanagedExport = 0x0008, // Managed method exported via thunk to unmanaged code. + RTSpecialName = 0x1000, // Runtime should check name encoding. + + // Reserved flags for runtime use only. + ReservedMask = 0xd000, + HasSecurity = 0x4000, // Method has security associate with it. + RequireSecObject = 0x8000, // Method calls another method containing security code. + } +} diff --git a/src/mscorlib/src/System/Reflection/MethodBase.cs b/src/mscorlib/src/System/Reflection/MethodBase.cs new file mode 100644 index 0000000000..68363bf1e0 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/MethodBase.cs @@ -0,0 +1,402 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection +{ + using System; + using System.Diagnostics; + using System.Globalization; + using System.Runtime.CompilerServices; + using System.Runtime.InteropServices; + using System.Security.Permissions; + using System.Text; + using System.Threading; + + // + // Invocation cached flags. Those are used in unmanaged code as well + // so be careful if you change them + // + [Flags] + internal enum INVOCATION_FLAGS : uint + { + INVOCATION_FLAGS_UNKNOWN = 0x00000000, + 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, + // 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, + // because field and method are different we can reuse the same bits + // method + INVOCATION_FLAGS_IS_CTOR = 0x00000010, + INVOCATION_FLAGS_RISKY_METHOD = 0x00000020, + INVOCATION_FLAGS_NON_W8P_FX_API = 0x00000040, + INVOCATION_FLAGS_IS_DELEGATE_CTOR = 0x00000080, + INVOCATION_FLAGS_CONTAINS_STACK_POINTERS = 0x00000100, + // field + INVOCATION_FLAGS_SPECIAL_FIELD = 0x00000010, + INVOCATION_FLAGS_FIELD_SPECIAL_CAST = 0x00000020, + + // temporary flag used for flagging invocation of method vs ctor + // this flag never appears on the instance m_invocationFlag and is simply + // passed down from within ConstructorInfo.Invoke() + INVOCATION_FLAGS_CONSTRUCTOR_INVOKE = 0x10000000, + } + + [Serializable] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_MethodBase))] +#pragma warning disable 618 + [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")] +#pragma warning restore 618 + [System.Runtime.InteropServices.ComVisible(true)] + public abstract class MethodBase : MemberInfo, _MethodBase + { + #region Static Members + public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle) + { + if (handle.IsNullHandle()) + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHandle")); + + MethodBase m = RuntimeType.GetMethodBase(handle.GetMethodInfo()); + + Type declaringType = m.DeclaringType; + if (declaringType != null && declaringType.IsGenericType) + throw new ArgumentException(String.Format( + CultureInfo.CurrentCulture, Environment.GetResourceString("Argument_MethodDeclaringTypeGeneric"), + m, declaringType.GetGenericTypeDefinition())); + + return m; + } + + [System.Runtime.InteropServices.ComVisible(false)] + public static MethodBase GetMethodFromHandle(RuntimeMethodHandle handle, RuntimeTypeHandle declaringType) + { + if (handle.IsNullHandle()) + throw new ArgumentException(Environment.GetResourceString("Argument_InvalidHandle")); + + return RuntimeType.GetMethodBase(declaringType.GetRuntimeType(), handle.GetMethodInfo()); + } + + [System.Security.DynamicSecurityMethod] // Specify DynamicSecurityMethod attribute to prevent inlining of the caller. + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public static MethodBase GetCurrentMethod() + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + return RuntimeMethodInfo.InternalGetCurrentMethod(ref stackMark); + } + #endregion + + #region Constructor + protected MethodBase() { } + #endregion + + public static bool operator ==(MethodBase left, MethodBase right) + { + if (ReferenceEquals(left, right)) + return true; + + if ((object)left == null || (object)right == null) + return false; + + MethodInfo method1, method2; + ConstructorInfo constructor1, constructor2; + + if ((method1 = left as MethodInfo) != null && (method2 = right as MethodInfo) != null) + return method1 == method2; + else if ((constructor1 = left as ConstructorInfo) != null && (constructor2 = right as ConstructorInfo) != null) + return constructor1 == constructor2; + + return false; + } + + public static bool operator !=(MethodBase left, MethodBase right) + { + return !(left == right); + } + + public override bool Equals(object obj) + { + return base.Equals(obj); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + #region Internal Members + // used by EE + [System.Security.SecurityCritical] + private IntPtr GetMethodDesc() { return MethodHandle.Value; } + +#if FEATURE_APPX + + // The C# dynamic and VB late bound binders need to call this API. Since we don't have time to make this + // public in Dev11, the C# and VB binders currently call this through a delegate. + // When we make this API public (hopefully) in Dev12 we need to change the C# and VB binders to call this + // probably statically. The code is located in: + // C#: ndp\fx\src\CSharp\Microsoft\CSharp\SymbolTable.cs - Microsoft.CSharp.RuntimeBinder.SymbolTable..cctor + // VB: vb\runtime\msvbalib\helpers\Symbols.vb - Microsoft.VisualBasic.CompilerServices.Symbols..cctor + internal virtual bool IsDynamicallyInvokable + { + get + { + return true; + } + } +#endif + #endregion + + #region Public Abstract\Virtual Members + internal virtual ParameterInfo[] GetParametersNoCopy() { return GetParameters (); } + + [System.Diagnostics.Contracts.Pure] + public abstract ParameterInfo[] GetParameters(); + + public virtual MethodImplAttributes MethodImplementationFlags + { + get + { + return GetMethodImplementationFlags(); + } + } + + public abstract MethodImplAttributes GetMethodImplementationFlags(); + + public abstract RuntimeMethodHandle MethodHandle { get; } + + public abstract MethodAttributes Attributes { get; } + + public abstract Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture); + + public virtual CallingConventions CallingConvention { get { return CallingConventions.Standard; } } + + [System.Runtime.InteropServices.ComVisible(true)] + public virtual Type[] GetGenericArguments() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); } + + public virtual bool IsGenericMethodDefinition { get { return false; } } + + public virtual bool ContainsGenericParameters { get { return false; } } + + public virtual bool IsGenericMethod { get { return false; } } + + public virtual bool IsSecurityCritical { get { throw new NotImplementedException(); } } + + public virtual bool IsSecuritySafeCritical { get { throw new NotImplementedException(); } } + + public virtual bool IsSecurityTransparent { get { throw new NotImplementedException(); } } + + #endregion + + #region Public Members + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public Object Invoke(Object obj, Object[] parameters) + { + // Theoretically we should set up a LookForMyCaller stack mark here and pass that along. + // But to maintain backward compatibility we can't switch to calling an + // internal overload that takes a stack mark. + // Fortunately the stack walker skips all the reflection invocation frames including this one. + // So this method will never be returned by the stack walker as the caller. + // See SystemDomain::CallersMethodCallbackWithStackMark in AppDomain.cpp. + return Invoke(obj, BindingFlags.Default, null, parameters, null); + } + + public bool IsPublic { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public; } } + + public bool IsPrivate { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private; } } + + public bool IsFamily { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family; } } + + public bool IsAssembly { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly; } } + + public bool IsFamilyAndAssembly { get { return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem; } } + + public bool IsFamilyOrAssembly { get {return(Attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem; } } + + public bool IsStatic { get { return(Attributes & MethodAttributes.Static) != 0; } } + + public bool IsFinal { get { return(Attributes & MethodAttributes.Final) != 0; } + } + public bool IsVirtual { get { return(Attributes & MethodAttributes.Virtual) != 0; } + } + public bool IsHideBySig { get { return(Attributes & MethodAttributes.HideBySig) != 0; } } + + public bool IsAbstract { get { return(Attributes & MethodAttributes.Abstract) != 0; } } + + public bool IsSpecialName { get { return(Attributes & MethodAttributes.SpecialName) != 0; } } + + [System.Runtime.InteropServices.ComVisible(true)] + public bool IsConstructor + { + get + { + // To be backward compatible we only return true for instance RTSpecialName ctors. + return (this is ConstructorInfo && + !IsStatic && + ((Attributes & MethodAttributes.RTSpecialName) == MethodAttributes.RTSpecialName)); + } + } + + [System.Security.SecuritySafeCritical] +#pragma warning disable 618 + [ReflectionPermissionAttribute(SecurityAction.Demand, Flags=ReflectionPermissionFlag.MemberAccess)] +#pragma warning restore 618 + public virtual MethodBody GetMethodBody() + { + throw new InvalidOperationException(); + } + #endregion + + #region Internal Methods + // helper method to construct the string representation of the parameter list + + internal static string ConstructParameters(Type[] parameterTypes, CallingConventions callingConvention, bool serialization) + { + StringBuilder sbParamList = new StringBuilder(); + string comma = ""; + + for (int i = 0; i < parameterTypes.Length; i++) + { + Type t = parameterTypes[i]; + + sbParamList.Append(comma); + + string typeName = t.FormatTypeName(serialization); + + // Legacy: Why use "ByRef" for by ref parameters? What language is this? + // VB uses "ByRef" but it should precede (not follow) the parameter name. + // Why don't we just use "&"? + if (t.IsByRef && !serialization) + { + sbParamList.Append(typeName.TrimEnd(new char[] { '&' })); + sbParamList.Append(" ByRef"); + } + else + { + sbParamList.Append(typeName); + } + + comma = ", "; + } + + if ((callingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) + { + sbParamList.Append(comma); + sbParamList.Append("..."); + } + + return sbParamList.ToString(); + } + + internal string FullName + { + get + { + return String.Format("{0}.{1}", DeclaringType.FullName, FormatNameAndSig()); + } + } + internal string FormatNameAndSig() + { + return FormatNameAndSig(false); + } + + internal virtual string FormatNameAndSig(bool serialization) + { + // Serialization uses ToString to resolve MethodInfo overloads. + StringBuilder sbName = new StringBuilder(Name); + + sbName.Append("("); + sbName.Append(ConstructParameters(GetParameterTypes(), CallingConvention, serialization)); + sbName.Append(")"); + + return sbName.ToString(); + } + + internal virtual Type[] GetParameterTypes() + { + ParameterInfo[] paramInfo = GetParametersNoCopy(); + + Type[] parameterTypes = new Type[paramInfo.Length]; + for (int i = 0; i < paramInfo.Length; i++) + parameterTypes[i] = paramInfo[i].ParameterType; + + return parameterTypes; + } + + [System.Security.SecuritySafeCritical] + internal Object[] CheckArguments(Object[] parameters, Binder binder, + BindingFlags invokeAttr, CultureInfo culture, Signature sig) + { + // copy the arguments in a different array so we detach from any user changes + Object[] copyOfParameters = new Object[parameters.Length]; + + ParameterInfo[] p = null; + for (int i = 0; i < parameters.Length; i++) + { + Object arg = parameters[i]; + RuntimeType argRT = sig.Arguments[i]; + + if (arg == Type.Missing) + { + if (p == null) + p = GetParametersNoCopy(); + if (p[i].DefaultValue == System.DBNull.Value) + throw new ArgumentException(Environment.GetResourceString("Arg_VarMissNull"),"parameters"); + arg = p[i].DefaultValue; + } + copyOfParameters[i] = argRT.CheckValue(arg, binder, culture, invokeAttr); + } + + return copyOfParameters; + } + #endregion + + #region _MethodBase Implementation +#if !FEATURE_CORECLR + Type _MethodBase.GetType() { return base.GetType(); } + bool _MethodBase.IsPublic { get { return IsPublic; } } + bool _MethodBase.IsPrivate { get { return IsPrivate; } } + bool _MethodBase.IsFamily { get { return IsFamily; } } + bool _MethodBase.IsAssembly { get { return IsAssembly; } } + bool _MethodBase.IsFamilyAndAssembly { get { return IsFamilyAndAssembly; } } + bool _MethodBase.IsFamilyOrAssembly { get { return IsFamilyOrAssembly; } } + bool _MethodBase.IsStatic { get { return IsStatic; } } + bool _MethodBase.IsFinal { get { return IsFinal; } } + bool _MethodBase.IsVirtual { get { return IsVirtual; } } + bool _MethodBase.IsHideBySig { get { return IsHideBySig; } } + bool _MethodBase.IsAbstract { get { return IsAbstract; } } + bool _MethodBase.IsSpecialName { get { return IsSpecialName; } } + bool _MethodBase.IsConstructor { get { return IsConstructor; } } + + void _MethodBase.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _MethodBase.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _MethodBase.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + // If you implement this method, make sure to include _MethodBase.Invoke in VM\DangerousAPIs.h and + // include _MethodBase in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp. + void _MethodBase.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + #endregion + } + +} diff --git a/src/mscorlib/src/System/Reflection/MethodBody.cs b/src/mscorlib/src/System/Reflection/MethodBody.cs new file mode 100644 index 0000000000..81d7a9ea0e --- /dev/null +++ b/src/mscorlib/src/System/Reflection/MethodBody.cs @@ -0,0 +1,169 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Globalization; +using System.Collections.Generic; +using System.Diagnostics.Contracts; + +namespace System.Reflection +{ + [Flags()] + [System.Runtime.InteropServices.ComVisible(true)] + public enum ExceptionHandlingClauseOptions: int + { + Clause = 0x0, + Filter = 0x1, + Finally = 0x2, + Fault = 0x4, + } + + [System.Runtime.InteropServices.ComVisible(true)] + public class ExceptionHandlingClause + { + #region costructor + // This class can only be created from inside the EE. + protected ExceptionHandlingClause() { } + #endregion + + #region Private Data Members + private MethodBody m_methodBody; + [ContractPublicPropertyName("Flags")] + private ExceptionHandlingClauseOptions m_flags; + private int m_tryOffset; + private int m_tryLength; + private int m_handlerOffset; + private int m_handlerLength; + private int m_catchMetadataToken; + private int m_filterOffset; + #endregion + + #region Public Members + public virtual ExceptionHandlingClauseOptions Flags { get { return m_flags; } } + public virtual int TryOffset { get { return m_tryOffset; } } + public virtual int TryLength { get { return m_tryLength; } } + public virtual int HandlerOffset { get { return m_handlerOffset; } } + public virtual int HandlerLength { get { return m_handlerLength; } } + + public virtual int FilterOffset + { + get + { + if (m_flags != ExceptionHandlingClauseOptions.Filter) + throw new InvalidOperationException(Environment.GetResourceString("Arg_EHClauseNotFilter")); + + return m_filterOffset; + } + } + + public virtual Type CatchType + { + get + { + if (m_flags != ExceptionHandlingClauseOptions.Clause) + throw new InvalidOperationException(Environment.GetResourceString("Arg_EHClauseNotClause")); + + Type type = null; + + if (!MetadataToken.IsNullToken(m_catchMetadataToken)) + { + Type declaringType = m_methodBody.m_methodBase.DeclaringType; + Module module = (declaringType == null) ? m_methodBody.m_methodBase.Module : declaringType.Module; + type = module.ResolveType(m_catchMetadataToken, (declaringType == null) ? null : declaringType.GetGenericArguments(), + m_methodBody.m_methodBase is MethodInfo ? m_methodBody.m_methodBase.GetGenericArguments() : null); + } + + return type; + } + } + #endregion + + #region Object Overrides + public override string ToString() + { + if (Flags == ExceptionHandlingClauseOptions.Clause) + { + return String.Format(CultureInfo.CurrentUICulture, + "Flags={0}, TryOffset={1}, TryLength={2}, HandlerOffset={3}, HandlerLength={4}, CatchType={5}", + Flags, TryOffset, TryLength, HandlerOffset, HandlerLength, CatchType); + } + + if (Flags == ExceptionHandlingClauseOptions.Filter) + { + return String.Format(CultureInfo.CurrentUICulture, + "Flags={0}, TryOffset={1}, TryLength={2}, HandlerOffset={3}, HandlerLength={4}, FilterOffset={5}", + Flags, TryOffset, TryLength, HandlerOffset, HandlerLength, FilterOffset); + } + + return String.Format(CultureInfo.CurrentUICulture, + "Flags={0}, TryOffset={1}, TryLength={2}, HandlerOffset={3}, HandlerLength={4}", + Flags, TryOffset, TryLength, HandlerOffset, HandlerLength); + + } + #endregion + } + + [System.Runtime.InteropServices.ComVisible(true)] + public class MethodBody + { + #region costructor + // This class can only be created from inside the EE. + protected MethodBody() { } + #endregion + + #region Private Data Members + private byte[] m_IL; + private ExceptionHandlingClause[] m_exceptionHandlingClauses; + private LocalVariableInfo[] m_localVariables; + internal MethodBase m_methodBase; + private int m_localSignatureMetadataToken; + private int m_maxStackSize; + private bool m_initLocals; + #endregion + + #region Public Members + public virtual int LocalSignatureMetadataToken { get { return m_localSignatureMetadataToken; } } + public virtual IList LocalVariables { get { return Array.AsReadOnly(m_localVariables); } } + public virtual int MaxStackSize { get { return m_maxStackSize; } } + public virtual bool InitLocals { get { return m_initLocals; } } + public virtual byte[] GetILAsByteArray() { return m_IL; } + public virtual IList ExceptionHandlingClauses { get { return Array.AsReadOnly(m_exceptionHandlingClauses); } } + #endregion + } + + [System.Runtime.InteropServices.ComVisible(true)] + public class LocalVariableInfo + { + #region Private Data Members + private RuntimeType m_type; + private int m_isPinned; + private int m_localIndex; + #endregion + + #region Constructor + protected LocalVariableInfo() { } + #endregion + + #region Object Overrides + public override string ToString() + { + string toString = LocalType.ToString() + " (" + LocalIndex + ")"; + + if (IsPinned) + toString += " (pinned)"; + + return toString; + } + #endregion + + #region Public Members + public virtual Type LocalType { get { Contract.Assert(m_type != null, "type must be set!"); return m_type; } } + public virtual bool IsPinned { get { return m_isPinned != 0; } } + public virtual int LocalIndex { get { return m_localIndex; } } + #endregion + } +} + diff --git a/src/mscorlib/src/System/Reflection/MethodImplAttributes.cs b/src/mscorlib/src/System/Reflection/MethodImplAttributes.cs new file mode 100644 index 0000000000..0fa4d00f19 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/MethodImplAttributes.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection +{ + + using System; + // This Enum matchs the CorMethodImpl defined in CorHdr.h + [Serializable] +[System.Runtime.InteropServices.ComVisible(true)] + public enum MethodImplAttributes + { + // code impl mask + CodeTypeMask = 0x0003, // Flags about code type. + IL = 0x0000, // Method impl is IL. + Native = 0x0001, // Method impl is native. + /// + OPTIL = 0x0002, // Method impl is OPTIL + Runtime = 0x0003, // Method impl is provided by the runtime. + // end code impl mask + + // managed mask + ManagedMask = 0x0004, // Flags specifying whether the code is managed or unmanaged. + Unmanaged = 0x0004, // Method impl is unmanaged, otherwise managed. + Managed = 0x0000, // Method impl is managed. + // end managed mask + + // implementation info and interop + ForwardRef = 0x0010, // Indicates method is not defined; used primarily in merge scenarios. + PreserveSig = 0x0080, // Indicates method sig is exported exactly as declared. + + InternalCall = 0x1000, // Internal Call... + + Synchronized = 0x0020, // Method is single threaded through the body. + NoInlining = 0x0008, // Method may not be inlined. + [System.Runtime.InteropServices.ComVisible(false)] + AggressiveInlining = 0x0100, // Method should be inlined if possible. + NoOptimization = 0x0040, // Method may not be optimized. + + MaxMethodImplVal = 0xFFFF, // Range check value + } +} diff --git a/src/mscorlib/src/System/Reflection/MethodInfo.cs b/src/mscorlib/src/System/Reflection/MethodInfo.cs new file mode 100644 index 0000000000..eeb5a815a4 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/MethodInfo.cs @@ -0,0 +1,1061 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Diagnostics.Contracts; + using System.Globalization; + using System.Runtime; + using System.Runtime.InteropServices; + using System.Runtime.ConstrainedExecution; +#if FEATURE_REMOTING + using System.Runtime.Remoting.Metadata; +#endif //FEATURE_REMOTING + using System.Runtime.Serialization; + using System.Security; + using System.Security.Permissions; + using System.Text; + using System.Threading; + using MemberListType = System.RuntimeType.MemberListType; + using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache; + using System.Runtime.CompilerServices; + + [Serializable] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_MethodInfo))] +#pragma warning disable 618 + [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")] +#pragma warning restore 618 + [System.Runtime.InteropServices.ComVisible(true)] + public abstract class MethodInfo : MethodBase, _MethodInfo + { + #region Constructor + protected MethodInfo() { } + #endregion + + public static bool operator ==(MethodInfo left, MethodInfo right) + { + if (ReferenceEquals(left, right)) + return true; + + if ((object)left == null || (object)right == null || + left is RuntimeMethodInfo || right is RuntimeMethodInfo) + { + return false; + } + return left.Equals(right); + } + + public static bool operator !=(MethodInfo left, MethodInfo right) + { + return !(left == right); + } + + public override bool Equals(object obj) + { + return base.Equals(obj); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + #region MemberInfo Overrides + public override MemberTypes MemberType { get { return System.Reflection.MemberTypes.Method; } } + #endregion + + #region Public Abstract\Virtual Members + public virtual Type ReturnType { get { throw new NotImplementedException(); } } + + public virtual ParameterInfo ReturnParameter { get { throw new NotImplementedException(); } } + + public abstract ICustomAttributeProvider ReturnTypeCustomAttributes { get; } + + public abstract MethodInfo GetBaseDefinition(); + + [System.Runtime.InteropServices.ComVisible(true)] + public override Type[] GetGenericArguments() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); } + + [System.Runtime.InteropServices.ComVisible(true)] + public virtual MethodInfo GetGenericMethodDefinition() { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); } + + public virtual MethodInfo MakeGenericMethod(params Type[] typeArguments) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); } + + public virtual Delegate CreateDelegate(Type delegateType) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); } + public virtual Delegate CreateDelegate(Type delegateType, Object target) { throw new NotSupportedException(Environment.GetResourceString("NotSupported_SubclassOverride")); } + #endregion + +#if !FEATURE_CORECLR + Type _MethodInfo.GetType() + { + return base.GetType(); + } + + void _MethodInfo.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _MethodInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _MethodInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + // If you implement this method, make sure to include _MethodInfo.Invoke in VM\DangerousAPIs.h and + // include _MethodInfo in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp. + void _MethodInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + } + + [Serializable] + internal sealed class RuntimeMethodInfo : MethodInfo, ISerializable, IRuntimeMethodInfo + { + #region Private Data Members + private IntPtr m_handle; + private RuntimeTypeCache m_reflectedTypeCache; + private string m_name; + private string m_toString; + private ParameterInfo[] m_parameters; + private ParameterInfo m_returnParameter; + private BindingFlags m_bindingFlags; + private MethodAttributes m_methodAttributes; + private Signature m_signature; + private RuntimeType m_declaringType; + private object m_keepalive; + private INVOCATION_FLAGS m_invocationFlags; + +#if FEATURE_APPX + private bool IsNonW8PFrameworkAPI() + { + if (m_declaringType.IsArray && IsPublic && !IsStatic) + return false; + + RuntimeAssembly rtAssembly = GetRuntimeAssembly(); + if (rtAssembly.IsFrameworkAssembly()) + { + int ctorToken = rtAssembly.InvocableAttributeCtorToken; + if (System.Reflection.MetadataToken.IsNullToken(ctorToken) || + !CustomAttribute.IsAttributeDefined(GetRuntimeModule(), MetadataToken, ctorToken)) + return true; + } + + if (GetRuntimeType().IsNonW8PFrameworkAPI()) + return true; + + if (IsGenericMethod && !IsGenericMethodDefinition) + { + foreach (Type t in GetGenericArguments()) + { + if (((RuntimeType)t).IsNonW8PFrameworkAPI()) + return true; + } + } + + return false; + } + + internal override bool IsDynamicallyInvokable + { + get + { + return !AppDomain.ProfileAPICheck || !IsNonW8PFrameworkAPI(); + } + } +#endif + + internal INVOCATION_FLAGS InvocationFlags + { + [System.Security.SecuritySafeCritical] + get + { + if ((m_invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED) == 0) + { + INVOCATION_FLAGS invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_UNKNOWN; + + Type declaringType = DeclaringType; + + // + // first take care of all the NO_INVOKE cases. + if (ContainsGenericParameters || + ReturnType.IsByRef || + (declaringType != null && declaringType.ContainsGenericParameters) || + ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) || + ((Attributes & MethodAttributes.RequireSecObject) == MethodAttributes.RequireSecObject)) + { + // We don't need other flags if this method cannot be invoked + invocationFlags = INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE; + } + else + { + // 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; + } + } + } + } + } + +#if FEATURE_APPX + if (AppDomain.ProfileAPICheck && IsNonW8PFrameworkAPI()) + invocationFlags |= INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API; +#endif // FEATURE_APPX + + m_invocationFlags = invocationFlags | INVOCATION_FLAGS.INVOCATION_FLAGS_INITIALIZED; + } + + return m_invocationFlags; + } + } + #endregion + + #region Constructor + [System.Security.SecurityCritical] // auto-generated + internal RuntimeMethodInfo( + RuntimeMethodHandleInternal handle, RuntimeType declaringType, + RuntimeTypeCache reflectedTypeCache, MethodAttributes methodAttributes, BindingFlags bindingFlags, object keepalive) + { + Contract.Ensures(!m_handle.IsNull()); + + Contract.Assert(!handle.IsNullHandle()); + Contract.Assert(methodAttributes == RuntimeMethodHandle.GetAttributes(handle)); + + m_bindingFlags = bindingFlags; + m_declaringType = declaringType; + m_keepalive = keepalive; + m_handle = handle.Value; + m_reflectedTypeCache = reflectedTypeCache; + m_methodAttributes = methodAttributes; + } + #endregion + +#if FEATURE_REMOTING + #region Legacy Remoting Cache + // The size of CachedData is accounted for by BaseObjectWithCachedData in object.h. + // This member is currently being used by Remoting for caching remoting data. If you + // need to cache data here, talk to the Remoting team to work out a mechanism, so that + // both caching systems can happily work together. + private RemotingMethodCachedData m_cachedData; + + internal RemotingMethodCachedData RemotingCache + { + get + { + // This grabs an internal copy of m_cachedData and uses + // that instead of looking at m_cachedData directly because + // the cache may get cleared asynchronously. This prevents + // us from having to take a lock. + RemotingMethodCachedData cache = m_cachedData; + if (cache == null) + { + cache = new RemotingMethodCachedData(this); + RemotingMethodCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null); + if (ret != null) + cache = ret; + } + return cache; + } + } + #endregion +#endif //FEATURE_REMOTING + + #region Private Methods + RuntimeMethodHandleInternal IRuntimeMethodInfo.Value + { + [System.Security.SecuritySafeCritical] + get + { + return new RuntimeMethodHandleInternal(m_handle); + } + } + + private RuntimeType ReflectedTypeInternal + { + get + { + return m_reflectedTypeCache.GetRuntimeType(); + } + } + + [System.Security.SecurityCritical] // auto-generated + private ParameterInfo[] FetchNonReturnParameters() + { + if (m_parameters == null) + m_parameters = RuntimeParameterInfo.GetParameters(this, this, Signature); + + return m_parameters; + } + + [System.Security.SecurityCritical] // auto-generated + private ParameterInfo FetchReturnParameter() + { + if (m_returnParameter == null) + m_returnParameter = RuntimeParameterInfo.GetReturnParameter(this, this, Signature); + + return m_returnParameter; + } + #endregion + + #region Internal Members + internal override string FormatNameAndSig(bool serialization) + { + // Serialization uses ToString to resolve MethodInfo overloads. + StringBuilder sbName = new StringBuilder(Name); + + // serialization == true: use unambiguous (except for assembly name) type names to distinguish between overloads. + // serialization == false: use basic format to maintain backward compatibility of MethodInfo.ToString(). + TypeNameFormatFlags format = serialization ? TypeNameFormatFlags.FormatSerialization : TypeNameFormatFlags.FormatBasic; + + if (IsGenericMethod) + sbName.Append(RuntimeMethodHandle.ConstructInstantiation(this, format)); + + sbName.Append("("); + sbName.Append(ConstructParameters(GetParameterTypes(), CallingConvention, serialization)); + sbName.Append(")"); + + return sbName.ToString(); + } + + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + internal override bool CacheEquals(object o) + { + RuntimeMethodInfo m = o as RuntimeMethodInfo; + + if ((object)m == null) + return false; + + return m.m_handle == m_handle; + } + + internal Signature Signature + { + get + { + if (m_signature == null) + m_signature = new Signature(this, m_declaringType); + + return m_signature; + } + } + + internal BindingFlags BindingFlags { get { return m_bindingFlags; } } + + // Differs from MethodHandle in that it will return a valid handle even for reflection only loaded types + internal RuntimeMethodHandle GetMethodHandle() + { + return new RuntimeMethodHandle(this); + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal RuntimeMethodInfo GetParentDefinition() + { + if (!IsVirtual || m_declaringType.IsInterface) + return null; + + RuntimeType parent = (RuntimeType)m_declaringType.BaseType; + + if (parent == null) + return null; + + int slot = RuntimeMethodHandle.GetSlot(this); + + if (RuntimeTypeHandle.GetNumVirtuals(parent) <= slot) + return null; + + return (RuntimeMethodInfo)RuntimeType.GetMethodBase(parent, RuntimeTypeHandle.GetMethodAt(parent, slot)); + } + + // Unlike DeclaringType, this will return a valid type even for global methods + internal RuntimeType GetDeclaringTypeInternal() + { + return m_declaringType; + } + + #endregion + + #region Object Overrides + public override String ToString() + { + if (m_toString == null) + m_toString = ReturnType.FormatTypeName() + " " + FormatNameAndSig(); + + return m_toString; + } + + public override int GetHashCode() + { + // See RuntimeMethodInfo.Equals() below. + if (IsGenericMethod) + return ValueType.GetHashCodeOfPtr(m_handle); + else + return base.GetHashCode(); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public override bool Equals(object obj) + { + if (!IsGenericMethod) + return obj == (object)this; + + // We cannot do simple object identity comparisons for generic methods. + // Equals will be called in CerHashTable when RuntimeType+RuntimeTypeCache.GetGenericMethodInfo() + // retrieve items from and insert items into s_methodInstantiations which is a CerHashtable. + + RuntimeMethodInfo mi = obj as RuntimeMethodInfo; + + if (mi == null || !mi.IsGenericMethod) + return false; + + // now we know that both operands are generic methods + + IRuntimeMethodInfo handle1 = RuntimeMethodHandle.StripMethodInstantiation(this); + IRuntimeMethodInfo handle2 = RuntimeMethodHandle.StripMethodInstantiation(mi); + if (handle1.Value.Value != handle2.Value.Value) + return false; + + Type[] lhs = GetGenericArguments(); + Type[] rhs = mi.GetGenericArguments(); + + if (lhs.Length != rhs.Length) + return false; + + for (int i = 0; i < lhs.Length; i++) + { + if (lhs[i] != rhs[i]) + return false; + } + + if (DeclaringType != mi.DeclaringType) + return false; + + if (ReflectedType != mi.ReflectedType) + return false; + + return true; + } + #endregion + + #region ICustomAttributeProvider + [System.Security.SecuritySafeCritical] // auto-generated + public override Object[] GetCustomAttributes(bool inherit) + { + return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType as RuntimeType, inherit); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType"); + + return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType, inherit); + } + + public override bool IsDefined(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType"); + + return CustomAttribute.IsDefined(this, attributeRuntimeType, inherit); + } + + public override IList GetCustomAttributesData() + { + return CustomAttributeData.GetCustomAttributesInternal(this); + } + #endregion + + #region MemberInfo Overrides + public override String Name + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + if (m_name == null) + m_name = RuntimeMethodHandle.GetName(this); + + return m_name; + } + } + + public override Type DeclaringType + { + get + { + if (m_reflectedTypeCache.IsGlobal) + return null; + + return m_declaringType; + } + } + + public override Type ReflectedType + { + get + { + if (m_reflectedTypeCache.IsGlobal) + return null; + + return m_reflectedTypeCache.GetRuntimeType(); + } + } + + public override MemberTypes MemberType { get { return MemberTypes.Method; } } + public override int MetadataToken + { + [System.Security.SecuritySafeCritical] // auto-generated + get { return RuntimeMethodHandle.GetMethodDef(this); } + } + public override Module Module { get { return GetRuntimeModule(); } } + internal RuntimeType GetRuntimeType() { return m_declaringType; } + internal RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); } + internal RuntimeAssembly GetRuntimeAssembly() { return GetRuntimeModule().GetRuntimeAssembly(); } + + public override bool IsSecurityCritical + { + get { return RuntimeMethodHandle.IsSecurityCritical(this); } + } + public override bool IsSecuritySafeCritical + { + get { return RuntimeMethodHandle.IsSecuritySafeCritical(this); } + } + public override bool IsSecurityTransparent + { + get { return RuntimeMethodHandle.IsSecurityTransparent(this); } + } + #endregion + + #region MethodBase Overrides + [System.Security.SecuritySafeCritical] // auto-generated + internal override ParameterInfo[] GetParametersNoCopy() + { + FetchNonReturnParameters(); + + return m_parameters; + } + + [System.Security.SecuritySafeCritical] // auto-generated + [System.Diagnostics.Contracts.Pure] + public override ParameterInfo[] GetParameters() + { + FetchNonReturnParameters(); + + if (m_parameters.Length == 0) + return m_parameters; + + ParameterInfo[] ret = new ParameterInfo[m_parameters.Length]; + + Array.Copy(m_parameters, ret, m_parameters.Length); + + return ret; + } + + public override MethodImplAttributes GetMethodImplementationFlags() + { + return RuntimeMethodHandle.GetImplAttributes(this); + } + + internal bool IsOverloaded + { + get + { + return m_reflectedTypeCache.GetMethodList(MemberListType.CaseSensitive, Name).Length > 1; + } + } + + public override RuntimeMethodHandle MethodHandle + { + get + { + Type declaringType = DeclaringType; + if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_NotAllowedInReflectionOnly")); + return new RuntimeMethodHandle(this); + } + } + + public override MethodAttributes Attributes { get { return m_methodAttributes; } } + + public override CallingConventions CallingConvention + { + get + { + return Signature.CallingConvention; + } + } + + [System.Security.SecuritySafeCritical] // overrides SafeCritical member +#if !FEATURE_CORECLR +#pragma warning disable 618 + [ReflectionPermissionAttribute(SecurityAction.Demand, Flags = ReflectionPermissionFlag.MemberAccess)] +#pragma warning restore 618 +#endif + public override MethodBody GetMethodBody() + { + MethodBody mb = RuntimeMethodHandle.GetMethodBody(this, ReflectedTypeInternal); + if (mb != null) + mb.m_methodBase = this; + return mb; + } + #endregion + + #region Invocation Logic(On MemberBase) + private void CheckConsistency(Object target) + { + // only test instance methods + if ((m_methodAttributes & MethodAttributes.Static) != MethodAttributes.Static) + { + if (!m_declaringType.IsInstanceOfType(target)) + { + if (target == null) + throw new TargetException(Environment.GetResourceString("RFLCT.Targ_StatMethReqTarg")); + else + throw new TargetException(Environment.GetResourceString("RFLCT.Targ_ITargMismatch")); + } + } + } + + [System.Security.SecuritySafeCritical] + private void ThrowNoInvokeException() + { + // method is ReflectionOnly + Type declaringType = DeclaringType; + if ((declaringType == null && Module.Assembly.ReflectionOnly) || declaringType is ReflectionOnlyType) + { + throw new InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyInvoke")); + } + // method is on a class that contains stack pointers + else if ((InvocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_CONTAINS_STACK_POINTERS) != 0) + { + throw new NotSupportedException(); + } + // method is vararg + else if ((CallingConvention & CallingConventions.VarArgs) == CallingConventions.VarArgs) + { + throw new NotSupportedException(); + } + // method is generic or on a generic class + else if (DeclaringType.ContainsGenericParameters || ContainsGenericParameters) + { + throw new InvalidOperationException(Environment.GetResourceString("Arg_UnboundGenParam")); + } + // method is abstract class + else if (IsAbstract) + { + throw new MemberAccessException(); + } + // ByRef return are not allowed in reflection + else if (ReturnType.IsByRef) + { + throw new NotSupportedException(Environment.GetResourceString("NotSupported_ByRefReturn")); + } + + throw new TargetException(); + } + + [System.Security.SecuritySafeCritical] + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable + public override Object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) + { + object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture); + + #region Security Check + INVOCATION_FLAGS invocationFlags = InvocationFlags; + +#if FEATURE_APPX + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NON_W8P_FX_API) != 0) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + RuntimeAssembly caller = RuntimeAssembly.GetExecutingAssembly(ref stackMark); + if (caller != null && !caller.IsSafeForReflection()) + throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_APIInvalidForCurrentContext", FullName)); + } +#endif + +#if !FEATURE_CORECLR + if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD | INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY)) != 0) + { + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_RISKY_METHOD) != 0) + CodeAccessPermission.Demand(PermissionType.ReflectionMemberAccess); + + if ((invocationFlags & INVOCATION_FLAGS.INVOCATION_FLAGS_NEED_SECURITY) != 0) + RuntimeMethodHandle.PerformSecurityCheck(obj, this, m_declaringType, (uint)m_invocationFlags); + } +#endif // !FEATURE_CORECLR + #endregion + + return UnsafeInvokeInternal(obj, parameters, arguments); + } + + [System.Security.SecurityCritical] + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + internal object UnsafeInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) + { + object[] arguments = InvokeArgumentsCheck(obj, invokeAttr, binder, parameters, culture); + + return UnsafeInvokeInternal(obj, parameters, arguments); + } + + [System.Security.SecurityCritical] + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + private object UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) + { + if (arguments == null || arguments.Length == 0) + return RuntimeMethodHandle.InvokeMethod(obj, null, Signature, false); + else + { + Object retValue = RuntimeMethodHandle.InvokeMethod(obj, arguments, Signature, false); + + // 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; + } + } + + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + private object[] InvokeArgumentsCheck(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) + { + Signature sig = Signature; + + // get the signature + int formalCount = sig.Arguments.Length; + int actualCount = (parameters != null) ? parameters.Length : 0; + + INVOCATION_FLAGS invocationFlags = InvocationFlags; + + // INVOCATION_FLAGS_CONTAINS_STACK_POINTERS means that the struct (either the declaring type or the return type) + // contains pointers that point to the stack. This is either a ByRef or a TypedReference. These structs cannot + // be boxed and thus cannot be invoked through reflection which only deals with boxed value type objects. + if ((invocationFlags & (INVOCATION_FLAGS.INVOCATION_FLAGS_NO_INVOKE | INVOCATION_FLAGS.INVOCATION_FLAGS_CONTAINS_STACK_POINTERS)) != 0) + ThrowNoInvokeException(); + + // check basic method consistency. This call will throw if there are problems in the target/method relationship + CheckConsistency(obj); + + if (formalCount != actualCount) + throw new TargetParameterCountException(Environment.GetResourceString("Arg_ParmCnt")); + + if (actualCount != 0) + return CheckArguments(parameters, binder, invokeAttr, culture, sig); + else + return null; + } + + #endregion + + #region MethodInfo Overrides + public override Type ReturnType + { + get { return Signature.ReturnType; } + } + + public override ICustomAttributeProvider ReturnTypeCustomAttributes + { + get { return ReturnParameter; } + } + + public override ParameterInfo ReturnParameter + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + Contract.Ensures(m_returnParameter != null); + + FetchReturnParameter(); + return m_returnParameter as ParameterInfo; + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + public override MethodInfo GetBaseDefinition() + { + if (!IsVirtual || IsStatic || m_declaringType == null || m_declaringType.IsInterface) + return this; + + int slot = RuntimeMethodHandle.GetSlot(this); + RuntimeType declaringType = (RuntimeType)DeclaringType; + RuntimeType baseDeclaringType = declaringType; + RuntimeMethodHandleInternal baseMethodHandle = new RuntimeMethodHandleInternal(); + + do { + int cVtblSlots = RuntimeTypeHandle.GetNumVirtuals(declaringType); + + if (cVtblSlots <= slot) + break; + + baseMethodHandle = RuntimeTypeHandle.GetMethodAt(declaringType, slot); + baseDeclaringType = declaringType; + + declaringType = (RuntimeType)declaringType.BaseType; + } while (declaringType != null); + + return(MethodInfo)RuntimeType.GetMethodBase(baseDeclaringType, baseMethodHandle); + } + + [System.Security.SecuritySafeCritical] + public override Delegate CreateDelegate(Type delegateType) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + + // This API existed in v1/v1.1 and only expected to create closed + // instance delegates. Constrain the call to BindToMethodInfo to + // open delegates only for backwards compatibility. But we'll allow + // relaxed signature checking and open static delegates because + // there's no ambiguity there (the caller would have to explicitly + // pass us a static method or a method with a non-exact signature + // and the only change in behavior from v1.1 there is that we won't + // fail the call). + return CreateDelegateInternal( + delegateType, + null, + DelegateBindingFlags.OpenDelegateOnly | DelegateBindingFlags.RelaxedSignature, + ref stackMark); + } + + [System.Security.SecuritySafeCritical] + public override Delegate CreateDelegate(Type delegateType, Object target) + { + StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller; + + // This API is new in Whidbey and allows the full range of delegate + // flexability (open or closed delegates binding to static or + // instance methods with relaxed signature checking). The delegate + // can also be closed over null. There's no ambiguity with all these + // options since the caller is providing us a specific MethodInfo. + return CreateDelegateInternal( + delegateType, + target, + DelegateBindingFlags.RelaxedSignature, + ref stackMark); + } + + [System.Security.SecurityCritical] + private Delegate CreateDelegateInternal(Type delegateType, Object firstArgument, DelegateBindingFlags bindingFlags, ref StackCrawlMark stackMark) + { + // Validate the parameters. + if (delegateType == null) + throw new ArgumentNullException("delegateType"); + Contract.EndContractBlock(); + + RuntimeType rtType = delegateType as RuntimeType; + if (rtType == null) + throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType"), "delegateType"); + + if (!rtType.IsDelegate()) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeDelegate"), "delegateType"); + + Delegate d = Delegate.CreateDelegateInternal(rtType, this, firstArgument, bindingFlags, ref stackMark); + if (d == null) + { + throw new ArgumentException(Environment.GetResourceString("Arg_DlgtTargMeth")); + } + + return d; + } + + #endregion + + #region Generics + [System.Security.SecuritySafeCritical] // auto-generated + public override MethodInfo MakeGenericMethod(params Type[] methodInstantiation) + { + if (methodInstantiation == null) + throw new ArgumentNullException("methodInstantiation"); + Contract.EndContractBlock(); + + RuntimeType[] methodInstantionRuntimeType = new RuntimeType[methodInstantiation.Length]; + + if (!IsGenericMethodDefinition) + throw new InvalidOperationException( + Environment.GetResourceString("Arg_NotGenericMethodDefinition", this)); + + for (int i = 0; i < methodInstantiation.Length; i++) + { + Type methodInstantiationElem = methodInstantiation[i]; + + if (methodInstantiationElem == null) + throw new ArgumentNullException(); + + RuntimeType rtMethodInstantiationElem = methodInstantiationElem as RuntimeType; + + if (rtMethodInstantiationElem == null) + { + Type[] methodInstantiationCopy = new Type[methodInstantiation.Length]; + for (int iCopy = 0; iCopy < methodInstantiation.Length; iCopy++) + methodInstantiationCopy[iCopy] = methodInstantiation[iCopy]; + methodInstantiation = methodInstantiationCopy; + return System.Reflection.Emit.MethodBuilderInstantiation.MakeGenericMethod(this, methodInstantiation); + } + + methodInstantionRuntimeType[i] = rtMethodInstantiationElem; + } + + RuntimeType[] genericParameters = GetGenericArgumentsInternal(); + + RuntimeType.SanityCheckGenericArguments(methodInstantionRuntimeType, genericParameters); + + MethodInfo ret = null; + + try + { + ret = RuntimeType.GetMethodBase(ReflectedTypeInternal, + RuntimeMethodHandle.GetStubIfNeeded(new RuntimeMethodHandleInternal(this.m_handle), m_declaringType, methodInstantionRuntimeType)) as MethodInfo; + } + catch (VerificationException e) + { + RuntimeType.ValidateGenericArguments(this, methodInstantionRuntimeType, e); + throw; + } + + return ret; + } + + internal RuntimeType[] GetGenericArgumentsInternal() + { + return RuntimeMethodHandle.GetMethodInstantiationInternal(this); + } + + public override Type[] GetGenericArguments() + { + Type[] types = RuntimeMethodHandle.GetMethodInstantiationPublic(this); + + if (types == null) + { + types = EmptyArray.Value; + } + return types; + } + + public override MethodInfo GetGenericMethodDefinition() + { + if (!IsGenericMethod) + throw new InvalidOperationException(); + Contract.EndContractBlock(); + + return RuntimeType.GetMethodBase(m_declaringType, RuntimeMethodHandle.StripMethodInstantiation(this)) as MethodInfo; + } + + public override bool IsGenericMethod + { + get { return RuntimeMethodHandle.HasMethodInstantiation(this); } + } + + public override bool IsGenericMethodDefinition + { + get { return RuntimeMethodHandle.IsGenericMethodDefinition(this); } + } + + public override bool ContainsGenericParameters + { + get + { + if (DeclaringType != null && DeclaringType.ContainsGenericParameters) + return true; + + if (!IsGenericMethod) + return false; + + Type[] pis = GetGenericArguments(); + for (int i = 0; i < pis.Length; i++) + { + if (pis[i].ContainsGenericParameters) + return true; + } + + return false; + } + } + #endregion + + #region ISerializable Implementation + [System.Security.SecurityCritical] // auto-generated + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException("info"); + Contract.EndContractBlock(); + + if (m_reflectedTypeCache.IsGlobal) + throw new NotSupportedException(Environment.GetResourceString("NotSupported_GlobalMethodSerialization")); + + MemberInfoSerializationHolder.GetSerializationInfo( + info, + Name, + ReflectedTypeInternal, + ToString(), + SerializationToString(), + MemberTypes.Method, + IsGenericMethod & !IsGenericMethodDefinition ? GetGenericArguments() : null); + } + + internal string SerializationToString() + { + return ReturnType.FormatTypeName(true) + " " + FormatNameAndSig(true); + } + #endregion + + #region Legacy Internal + internal static MethodBase InternalGetCurrentMethod(ref StackCrawlMark stackMark) + { + IRuntimeMethodInfo method = RuntimeMethodHandle.GetCurrentMethod(ref stackMark); + + if (method == null) + return null; + + return RuntimeType.GetMethodBase(method); + } + #endregion + } +} diff --git a/src/mscorlib/src/System/Reflection/Missing.cs b/src/mscorlib/src/System/Reflection/Missing.cs new file mode 100644 index 0000000000..8289193191 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Missing.cs @@ -0,0 +1,38 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection +{ + using System; + using System.Runtime.Remoting; + using System.Runtime.Serialization; + using System.Security.Permissions; + using System.Diagnostics.Contracts; + + // This is not serializable because it is a reflection command. + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public sealed class Missing : ISerializable + { + public static readonly Missing Value = new Missing(); + + #region Constructor + private Missing() { } + #endregion + + #region ISerializable + [System.Security.SecurityCritical] // auto-generated_required + void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException("info"); + Contract.EndContractBlock(); + + UnitySerializationHolder.GetUnitySerializationInfo(info, this); + } + #endregion + } +} diff --git a/src/mscorlib/src/System/Reflection/Module.cs b/src/mscorlib/src/System/Reflection/Module.cs new file mode 100644 index 0000000000..34705a4211 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Module.cs @@ -0,0 +1,1230 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +// + +namespace System.Reflection +{ + using System; + using System.Diagnostics.SymbolStore; + using System.Runtime.Remoting; + using System.Runtime.InteropServices; + using System.Runtime.Serialization; + using System.Collections; + using System.Collections.Generic; + using System.Threading; + using System.Runtime.CompilerServices; + using System.Security; + using System.Security.Permissions; + using System.IO; + using System.Globalization; + using System.Runtime.Versioning; + using System.Diagnostics.Contracts; + + [Serializable] + [Flags] + [System.Runtime.InteropServices.ComVisible(true)] + public enum PortableExecutableKinds + { + NotAPortableExecutableImage = 0x0, + + ILOnly = 0x1, + + Required32Bit = 0x2, + + PE32Plus = 0x4, + + Unmanaged32Bit = 0x8, + + [ComVisible(false)] + Preferred32Bit = 0x10, + } + + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public enum ImageFileMachine + { + I386 = 0x014c, + + IA64 = 0x0200, + + AMD64 = 0x8664, + + ARM = 0x01c4, + } + + [Serializable] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_Module))] + [System.Runtime.InteropServices.ComVisible(true)] +#pragma warning disable 618 + [PermissionSetAttribute(SecurityAction.InheritanceDemand, Unrestricted = true)] +#pragma warning restore 618 + public abstract class Module : _Module, ISerializable, ICustomAttributeProvider + { + #region Static Constructor + static Module() + { + __Filters _fltObj; + _fltObj = new __Filters(); + FilterTypeName = new TypeFilter(_fltObj.FilterTypeName); + FilterTypeNameIgnoreCase = new TypeFilter(_fltObj.FilterTypeNameIgnoreCase); + } + #endregion + + #region Constructor + protected Module() + { + } + #endregion + + #region Public Statics + public static readonly TypeFilter FilterTypeName; + public static readonly TypeFilter FilterTypeNameIgnoreCase; + + public static bool operator ==(Module left, Module right) + { + if (ReferenceEquals(left, right)) + return true; + + if ((object)left == null || (object)right == null || + left is RuntimeModule || right is RuntimeModule) + { + return false; + } + + return left.Equals(right); + } + + public static bool operator !=(Module left, Module right) + { + return !(left == right); + } + + public override bool Equals(object o) + { + return base.Equals(o); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + #endregion + + #region Literals + private const BindingFlags DefaultLookup = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public; + #endregion + + #region object overrides + public override String ToString() + { + return ScopeName; + } + #endregion + + public virtual IEnumerable CustomAttributes + { + get + { + return GetCustomAttributesData(); + } + } + #region ICustomAttributeProvider Members + public virtual Object[] GetCustomAttributes(bool inherit) + { + throw new NotImplementedException(); + } + + public virtual Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + throw new NotImplementedException(); + } + + public virtual bool IsDefined(Type attributeType, bool inherit) + { + throw new NotImplementedException(); + } + + public virtual IList GetCustomAttributesData() + { + throw new NotImplementedException(); + } + #endregion + + #region public instances members + public MethodBase ResolveMethod(int metadataToken) + { + return ResolveMethod(metadataToken, null, null); + } + + public virtual MethodBase ResolveMethod(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) + { + // This API was made virtual in V4. Code compiled against V2 might use + // "call" rather than "callvirt" to call it. + // This makes sure those code still works. + RuntimeModule rtModule = this as RuntimeModule; + if (rtModule != null) + return rtModule.ResolveMethod(metadataToken, genericTypeArguments, genericMethodArguments); + + throw new NotImplementedException(); + } + + public FieldInfo ResolveField(int metadataToken) + { + return ResolveField(metadataToken, null, null); + } + + public virtual FieldInfo ResolveField(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) + { + // This API was made virtual in V4. Code compiled against V2 might use + // "call" rather than "callvirt" to call it. + // This makes sure those code still works. + RuntimeModule rtModule = this as RuntimeModule; + if (rtModule != null) + return rtModule.ResolveField(metadataToken, genericTypeArguments, genericMethodArguments); + + throw new NotImplementedException(); + } + + public Type ResolveType(int metadataToken) + { + return ResolveType(metadataToken, null, null); + } + + public virtual Type ResolveType(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) + { + // This API was made virtual in V4. Code compiled against V2 might use + // "call" rather than "callvirt" to call it. + // This makes sure those code still works. + RuntimeModule rtModule = this as RuntimeModule; + if (rtModule != null) + return rtModule.ResolveType(metadataToken, genericTypeArguments, genericMethodArguments); + + throw new NotImplementedException(); + } + + public MemberInfo ResolveMember(int metadataToken) + { + return ResolveMember(metadataToken, null, null); + } + + public virtual MemberInfo ResolveMember(int metadataToken, Type[] genericTypeArguments, Type[] genericMethodArguments) + { + // This API was made virtual in V4. Code compiled against V2 might use + // "call" rather than "callvirt" to call it. + // This makes sure those code still works. + RuntimeModule rtModule = this as RuntimeModule; + if (rtModule != null) + return rtModule.ResolveMember(metadataToken, genericTypeArguments, genericMethodArguments); + + throw new NotImplementedException(); + } + + public virtual byte[] ResolveSignature(int metadataToken) + { + // This API was made virtual in V4. Code compiled against V2 might use + // "call" rather than "callvirt" to call it. + // This makes sure those code still works. + RuntimeModule rtModule = this as RuntimeModule; + if (rtModule != null) + return rtModule.ResolveSignature(metadataToken); + + throw new NotImplementedException(); + } + + public virtual string ResolveString(int metadataToken) + { + // This API was made virtual in V4. Code compiled against V2 might use + // "call" rather than "callvirt" to call it. + // This makes sure those code still works. + RuntimeModule rtModule = this as RuntimeModule; + if (rtModule != null) + return rtModule.ResolveString(metadataToken); + + throw new NotImplementedException(); + } + + public virtual void GetPEKind(out PortableExecutableKinds peKind, out ImageFileMachine machine) + { + // This API was made virtual in V4. Code compiled against V2 might use + // "call" rather than "callvirt" to call it. + // This makes sure those code still works. + RuntimeModule rtModule = this as RuntimeModule; + if (rtModule != null) + rtModule.GetPEKind(out peKind, out machine); + + throw new NotImplementedException(); + } + + public virtual int MDStreamVersion + { + get + { + // This API was made virtual in V4. Code compiled against V2 might use + // "call" rather than "callvirt" to call it. + // This makes sure those code still works. + RuntimeModule rtModule = this as RuntimeModule; + if (rtModule != null) + return rtModule.MDStreamVersion; + + throw new NotImplementedException(); + } + } + + [System.Security.SecurityCritical] // auto-generated_required + public virtual void GetObjectData(SerializationInfo info, StreamingContext context) + { + throw new NotImplementedException(); + } + + [System.Runtime.InteropServices.ComVisible(true)] + public virtual Type GetType(String className, bool ignoreCase) + { + return GetType(className, false, ignoreCase); + } + + [System.Runtime.InteropServices.ComVisible(true)] + public virtual Type GetType(String className) { + return GetType(className, false, false); + } + + [System.Runtime.InteropServices.ComVisible(true)] + public virtual Type GetType(String className, bool throwOnError, bool ignoreCase) + { + throw new NotImplementedException(); + } + + public virtual String FullyQualifiedName + { +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#endif + get + { + throw new NotImplementedException(); + } + } + + public virtual Type[] FindTypes(TypeFilter filter,Object filterCriteria) + { + Type[] c = GetTypes(); + int cnt = 0; + for (int i = 0;i GetCustomAttributesData() + { + return CustomAttributeData.GetCustomAttributesInternal(this); + } + #endregion + + #region Public Virtuals + [System.Security.SecurityCritical] // auto-generated_required + public override void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + { + throw new ArgumentNullException("info"); + } + Contract.EndContractBlock(); + UnitySerializationHolder.GetUnitySerializationInfo(info, UnitySerializationHolder.ModuleUnity, this.ScopeName, this.GetRuntimeAssembly()); + } + + [System.Security.SecuritySafeCritical] // auto-generated + [System.Runtime.InteropServices.ComVisible(true)] + public override Type GetType(String className, bool throwOnError, bool ignoreCase) + { + // throw on null strings regardless of the value of "throwOnError" + if (className == null) + throw new ArgumentNullException("className"); + + RuntimeType retType = null; + Object keepAlive = null; + GetType(GetNativeHandle(), className, throwOnError, ignoreCase, JitHelpers.GetObjectHandleOnStack(ref retType), JitHelpers.GetObjectHandleOnStack(ref keepAlive)); + GC.KeepAlive(keepAlive); + return retType; + } + + [System.Security.SecurityCritical] // auto-generated + internal string GetFullyQualifiedName() + { + String fullyQualifiedName = null; + GetFullyQualifiedName(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref fullyQualifiedName)); + return fullyQualifiedName; + } + + public override String FullyQualifiedName + { +#if FEATURE_CORECLR + [System.Security.SecurityCritical] // auto-generated +#else + [System.Security.SecuritySafeCritical] +#endif + get + { + String fullyQualifiedName = GetFullyQualifiedName(); + + if (fullyQualifiedName != null) { + bool checkPermission = true; + try { + Path.GetFullPathInternal(fullyQualifiedName); + } + catch(ArgumentException) { + checkPermission = false; + } + if (checkPermission) { + new FileIOPermission( FileIOPermissionAccess.PathDiscovery, fullyQualifiedName ).Demand(); + } + } + + return fullyQualifiedName; + } + } + + [System.Security.SecuritySafeCritical] // auto-generated + public override Type[] GetTypes() + { + return GetTypes(GetNativeHandle()); + } + + #endregion + + #region Public Members + + public override Guid ModuleVersionId + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + unsafe + { + Guid mvid; + MetadataImport.GetScopeProps(out mvid); + return mvid; + } + } + } + + public override int MetadataToken + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + return ModuleHandle.GetToken(GetNativeHandle()); + } + } + + public override bool IsResource() + { + return IsResource(GetNativeHandle()); + } + + public override FieldInfo[] GetFields(BindingFlags bindingFlags) + { + if (RuntimeType == null) + return new FieldInfo[0]; + + return RuntimeType.GetFields(bindingFlags); + } + + public override FieldInfo GetField(String name, BindingFlags bindingAttr) + { + if (name == null) + throw new ArgumentNullException("name"); + + if (RuntimeType == null) + return null; + + return RuntimeType.GetField(name, bindingAttr); + } + + public override MethodInfo[] GetMethods(BindingFlags bindingFlags) + { + if (RuntimeType == null) + return new MethodInfo[0]; + + return RuntimeType.GetMethods(bindingFlags); + } + + public override String ScopeName + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + string scopeName = null; + GetScopeName(GetNativeHandle(), JitHelpers.GetStringHandleOnStack(ref scopeName)); + return scopeName; + } + } + + public override String Name + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + String s = GetFullyQualifiedName(); + +#if !FEATURE_PAL + int i = s.LastIndexOf('\\'); +#else + int i = s.LastIndexOf(System.IO.Path.DirectorySeparatorChar); +#endif + if (i == -1) + return s; + + return s.Substring(i + 1); + } + } + + public override Assembly Assembly + { + [Pure] + get + { + return GetRuntimeAssembly(); + } + } + + internal RuntimeAssembly GetRuntimeAssembly() + { + return m_runtimeAssembly; + } + + + internal override ModuleHandle GetModuleHandle() + { + return new ModuleHandle(this); + } + + internal RuntimeModule GetNativeHandle() + { + return this; + } + +#if FEATURE_X509 && FEATURE_CAS_POLICY + [System.Security.SecuritySafeCritical] // auto-generated + public override System.Security.Cryptography.X509Certificates.X509Certificate GetSignerCertificate() + { + byte[] data = null; + GetSignerCertificate(GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref data)); + return (data != null) ? new System.Security.Cryptography.X509Certificates.X509Certificate(data) : null; + } +#endif // FEATURE_X509 && FEATURE_CAS_POLICY + #endregion + } +} diff --git a/src/mscorlib/src/System/Reflection/ObfuscateAssemblyAttribute.cs b/src/mscorlib/src/System/Reflection/ObfuscateAssemblyAttribute.cs new file mode 100644 index 0000000000..b852e5a4c2 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/ObfuscateAssemblyAttribute.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Reflection; + + +namespace System.Reflection +{ + [AttributeUsage (AttributeTargets.Assembly, AllowMultiple=false, Inherited=false)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class ObfuscateAssemblyAttribute : Attribute + { + private bool m_assemblyIsPrivate; + private bool m_strip = true; + + public ObfuscateAssemblyAttribute(bool assemblyIsPrivate) + { + m_assemblyIsPrivate = assemblyIsPrivate; + } + + public bool AssemblyIsPrivate + { + get + { + return m_assemblyIsPrivate; + } + } + + public bool StripAfterObfuscation + { + get + { + return m_strip; + } + set + { + m_strip = value; + } + } + } +} + diff --git a/src/mscorlib/src/System/Reflection/ObfuscationAttribute.cs b/src/mscorlib/src/System/Reflection/ObfuscationAttribute.cs new file mode 100644 index 0000000000..0b987ce06d --- /dev/null +++ b/src/mscorlib/src/System/Reflection/ObfuscationAttribute.cs @@ -0,0 +1,75 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Reflection; + +namespace System.Reflection +{ + [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Enum | AttributeTargets.Delegate, + AllowMultiple = true, Inherited = false)] +[System.Runtime.InteropServices.ComVisible(true)] + public sealed class ObfuscationAttribute: Attribute + { + private bool m_strip = true; + private bool m_exclude = true; + private bool m_applyToMembers = true; + private string m_feature = "all"; + + public ObfuscationAttribute() + { + } + + public bool StripAfterObfuscation + { + get + { + return m_strip; + } + set + { + m_strip = value; + } + } + + public bool Exclude + { + get + { + return m_exclude; + } + set + { + m_exclude = value; + } + } + + public bool ApplyToMembers + { + get + { + return m_applyToMembers; + } + set + { + m_applyToMembers = value; + } + } + + public string Feature + { + get + { + return m_feature; + } + set + { + m_feature = value; + } + } + } +} + diff --git a/src/mscorlib/src/System/Reflection/ParameterAttributes.cs b/src/mscorlib/src/System/Reflection/ParameterAttributes.cs new file mode 100644 index 0000000000..12f8145ddd --- /dev/null +++ b/src/mscorlib/src/System/Reflection/ParameterAttributes.cs @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// ParameterAttributes is an enum defining the attributes that may be +// +// associated with a Parameter. These are defined in CorHdr.h. +// +// +namespace System.Reflection { + + using System; + // This Enum matchs the CorParamAttr defined in CorHdr.h +[Serializable] + [Flags] + [System.Runtime.InteropServices.ComVisible(true)] + public enum ParameterAttributes + { + None = 0x0000, // no flag is specified + In = 0x0001, // Param is [In] + Out = 0x0002, // Param is [Out] + Lcid = 0x0004, // Param is [lcid] + Retval = 0x0008, // Param is [Retval] + Optional = 0x0010, // Param is optional + + // Reserved flags for Runtime use only. + ReservedMask = 0xf000, + HasDefault = 0x1000, // Param has default value. + HasFieldMarshal = 0x2000, // Param has FieldMarshal. + Reserved3 = 0x4000, // reserved bit + Reserved4 = 0x8000 // reserved bit + } +} diff --git a/src/mscorlib/src/System/Reflection/ParameterInfo.cs b/src/mscorlib/src/System/Reflection/ParameterInfo.cs new file mode 100644 index 0000000000..63c6330b0a --- /dev/null +++ b/src/mscorlib/src/System/Reflection/ParameterInfo.cs @@ -0,0 +1,795 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection +{ + using System; + using System.Collections.Generic; + using System.Diagnostics.Contracts; + using System.Runtime.InteropServices; + using System.Runtime.Serialization; + using System.Runtime.CompilerServices; +#if FEATURE_REMOTING + using System.Runtime.Remoting.Metadata; +#endif //FEATURE_REMOTING + using System.Security.Permissions; + using System.Threading; + using MdToken = System.Reflection.MetadataToken; + + [Serializable] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_ParameterInfo))] + [System.Runtime.InteropServices.ComVisible(true)] + public class ParameterInfo : _ParameterInfo, ICustomAttributeProvider, IObjectReference + { + #region Legacy Protected Members + protected String NameImpl; + protected Type ClassImpl; + protected int PositionImpl; + protected ParameterAttributes AttrsImpl; + protected Object DefaultValueImpl; // cannot cache this as it may be non agile user defined enum + protected MemberInfo MemberImpl; + #endregion + + #region Legacy Private Members + // These are here only for backwards compatibility -- they are not set + // until this instance is serialized, so don't rely on their values from + // arbitrary code. +#pragma warning disable 169 + [OptionalField] + private IntPtr _importer; + [OptionalField] + private int _token; + [OptionalField] + private bool bExtraConstChecked; +#pragma warning restore 169 + #endregion + + #region Constructor + protected ParameterInfo() + { + } + #endregion + + #region Internal Members + // this is an internal api for DynamicMethod. A better solution is to change the relationship + // between ParameterInfo and ParameterBuilder so that a ParameterBuilder can be seen as a writer + // api over a ParameterInfo. However that is a possible breaking change so it needs to go through some process first + internal void SetName(String name) + { + NameImpl = name; + } + + internal void SetAttributes(ParameterAttributes attributes) + { + AttrsImpl = attributes; + } + #endregion + + #region Public Methods + public virtual Type ParameterType + { + get + { + return ClassImpl; + } + } + + public virtual String Name + { + get + { + return NameImpl; + } + } + + public virtual bool HasDefaultValue { get { throw new NotImplementedException(); } } + + public virtual Object DefaultValue { get { throw new NotImplementedException(); } } + public virtual Object RawDefaultValue { get { throw new NotImplementedException(); } } + + public virtual int Position { get { return PositionImpl; } } + public virtual ParameterAttributes Attributes { get { return AttrsImpl; } } + + public virtual MemberInfo Member { + get { + Contract.Ensures(Contract.Result() != null); + return MemberImpl; + } + } + + public bool IsIn { get { return((Attributes & ParameterAttributes.In) != 0); } } + public bool IsOut { get { return((Attributes & ParameterAttributes.Out) != 0); } } + public bool IsLcid { get { return((Attributes & ParameterAttributes.Lcid) != 0); } } + public bool IsRetval { get { return((Attributes & ParameterAttributes.Retval) != 0); } } + public bool IsOptional { get { return((Attributes & ParameterAttributes.Optional) != 0); } } + + public virtual int MetadataToken + { + get + { + // This API was made virtual in V4. Code compiled against V2 might use + // "call" rather than "callvirt" to call it. + // This makes sure those code still works. + RuntimeParameterInfo rtParam = this as RuntimeParameterInfo; + if (rtParam != null) + return rtParam.MetadataToken; + + // return a null token + return (int)MetadataTokenType.ParamDef; + } + } + + public virtual Type[] GetRequiredCustomModifiers() + { + return EmptyArray.Value; + } + + public virtual Type[] GetOptionalCustomModifiers() + { + return EmptyArray.Value; + } + #endregion + + #region Object Overrides + public override String ToString() + { + return ParameterType.FormatTypeName() + " " + Name; + } + #endregion + + public virtual IEnumerable CustomAttributes + { + get + { + return GetCustomAttributesData(); + } + } + #region ICustomAttributeProvider + public virtual Object[] GetCustomAttributes(bool inherit) + { + return EmptyArray.Value; + } + + public virtual Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + return EmptyArray.Value; + } + + public virtual bool IsDefined(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + return false; + } + + public virtual IList GetCustomAttributesData() + { + throw new NotImplementedException(); + } + #endregion + + #region _ParameterInfo implementation + +#if !FEATURE_CORECLR + void _ParameterInfo.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _ParameterInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _ParameterInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + void _ParameterInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + + #endregion + + #region IObjectReference + // In V4 RuntimeParameterInfo is introduced. + // To support deserializing ParameterInfo instances serialized in earlier versions + // we need to implement IObjectReference. + [System.Security.SecurityCritical] + public object GetRealObject(StreamingContext context) + { + Contract.Ensures(Contract.Result() != null); + + // Once all the serializable fields have come in we can set up the real + // instance based on just two of them (MemberImpl and PositionImpl). + + if (MemberImpl == null) + throw new SerializationException(Environment.GetResourceString(ResId.Serialization_InsufficientState)); + + ParameterInfo[] args = null; + + switch (MemberImpl.MemberType) + { + case MemberTypes.Constructor: + case MemberTypes.Method: + if (PositionImpl == -1) + { + if (MemberImpl.MemberType == MemberTypes.Method) + return ((MethodInfo)MemberImpl).ReturnParameter; + else + throw new SerializationException(Environment.GetResourceString(ResId.Serialization_BadParameterInfo)); + } + else + { + args = ((MethodBase)MemberImpl).GetParametersNoCopy(); + + if (args != null && PositionImpl < args.Length) + return args[PositionImpl]; + else + throw new SerializationException(Environment.GetResourceString(ResId.Serialization_BadParameterInfo)); + } + + case MemberTypes.Property: + args = ((RuntimePropertyInfo)MemberImpl).GetIndexParametersNoCopy(); + + if (args != null && PositionImpl > -1 && PositionImpl < args.Length) + return args[PositionImpl]; + else + throw new SerializationException(Environment.GetResourceString(ResId.Serialization_BadParameterInfo)); + + default: + throw new SerializationException(Environment.GetResourceString(ResId.Serialization_NoParameterInfo)); + } + } + #endregion + } + + [Serializable] + internal unsafe sealed class RuntimeParameterInfo : ParameterInfo, ISerializable + { + #region Static Members + [System.Security.SecurityCritical] // auto-generated + internal unsafe static ParameterInfo[] GetParameters(IRuntimeMethodInfo method, MemberInfo member, Signature sig) + { + Contract.Assert(method is RuntimeMethodInfo || method is RuntimeConstructorInfo); + + ParameterInfo dummy; + return GetParameters(method, member, sig, out dummy, false); + } + + [System.Security.SecurityCritical] // auto-generated + internal unsafe static ParameterInfo GetReturnParameter(IRuntimeMethodInfo method, MemberInfo member, Signature sig) + { + Contract.Assert(method is RuntimeMethodInfo || method is RuntimeConstructorInfo); + + ParameterInfo returnParameter; + GetParameters(method, member, sig, out returnParameter, true); + return returnParameter; + } + + [System.Security.SecurityCritical] // auto-generated + internal unsafe static ParameterInfo[] GetParameters( + IRuntimeMethodInfo methodHandle, MemberInfo member, Signature sig, out ParameterInfo returnParameter, bool fetchReturnParameter) + { + returnParameter = null; + int sigArgCount = sig.Arguments.Length; + ParameterInfo[] args = fetchReturnParameter ? null : new ParameterInfo[sigArgCount]; + + int tkMethodDef = RuntimeMethodHandle.GetMethodDef(methodHandle); + int cParamDefs = 0; + + // Not all methods have tokens. Arrays, pointers and byRef types do not have tokens as they + // are generated on the fly by the runtime. + if (!MdToken.IsNullToken(tkMethodDef)) + { + MetadataImport scope = RuntimeTypeHandle.GetMetadataImport(RuntimeMethodHandle.GetDeclaringType(methodHandle)); + + MetadataEnumResult tkParamDefs; + scope.EnumParams(tkMethodDef, out tkParamDefs); + + cParamDefs = tkParamDefs.Length; + + // Not all parameters have tokens. Parameters may have no token + // if they have no name and no attributes. + if (cParamDefs > sigArgCount + 1 /* return type */) + throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ParameterSignatureMismatch")); + + for (int i = 0; i < cParamDefs; i++) + { + #region Populate ParameterInfos + ParameterAttributes attr; + int position, tkParamDef = tkParamDefs[i]; + + scope.GetParamDefProps(tkParamDef, out position, out attr); + + position--; + + if (fetchReturnParameter == true && position == -1) + { + // more than one return parameter? + if (returnParameter != null) + throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ParameterSignatureMismatch")); + + returnParameter = new RuntimeParameterInfo(sig, scope, tkParamDef, position, attr, member); + } + else if (fetchReturnParameter == false && position >= 0) + { + // position beyong sigArgCount? + if (position >= sigArgCount) + throw new BadImageFormatException(Environment.GetResourceString("BadImageFormat_ParameterSignatureMismatch")); + + args[position] = new RuntimeParameterInfo(sig, scope, tkParamDef, position, attr, member); + } + #endregion + } + } + + // Fill in empty ParameterInfos for those without tokens + if (fetchReturnParameter) + { + if (returnParameter == null) + { + returnParameter = new RuntimeParameterInfo(sig, MetadataImport.EmptyImport, 0, -1, (ParameterAttributes)0, member); + } + } + else + { + if (cParamDefs < args.Length + 1) + { + for (int i = 0; i < args.Length; i++) + { + if (args[i] != null) + continue; + + args[i] = new RuntimeParameterInfo(sig, MetadataImport.EmptyImport, 0, i, (ParameterAttributes)0, member); + } + } + } + + return args; + } + #endregion + + #region Private Statics + private static readonly Type s_DecimalConstantAttributeType = typeof(DecimalConstantAttribute); + private static readonly Type s_CustomConstantAttributeType = typeof(CustomConstantAttribute); + #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 + + #region Internal Properties + internal MethodBase DefiningMethod + { + get + { + MethodBase result = m_originalMember != null ? m_originalMember : MemberImpl as MethodBase; + Contract.Assert(result != null); + return result; + } + } + #endregion + + #region VTS magic to serialize/deserialized to/from pre-Whidbey endpoints. + [System.Security.SecurityCritical] + public void GetObjectData(SerializationInfo info, StreamingContext context) + { + if (info == null) + throw new ArgumentNullException("info"); + Contract.EndContractBlock(); + + // We could be serializing for consumption by a pre-Whidbey + // endpoint. Therefore we set up all the serialized fields to look + // just like a v1.0/v1.1 instance. + + // Need to set the type to ParameterInfo so that pre-Whidbey and Whidbey code + // can deserialize this. This is also why we cannot simply use [OnSerializing]. + info.SetType(typeof(ParameterInfo)); + + // Use the properties intead of the fields in case the fields haven't been et + // _importer, bExtraConstChecked, and m_cachedData don't need to be set + + // Now set the legacy fields that the current implementation doesn't + // use any more. Note that _importer is a raw pointer that should + // never have been serialized in V1. We set it to zero here; if the + // deserializer uses it (by calling GetCustomAttributes() on this + // instance) they'll AV, but at least it will be a well defined + // exception and not a random AV. + + info.AddValue("AttrsImpl", Attributes); + info.AddValue("ClassImpl", ParameterType); + info.AddValue("DefaultValueImpl", DefaultValue); + info.AddValue("MemberImpl", Member); + info.AddValue("NameImpl", Name); + info.AddValue("PositionImpl", Position); + info.AddValue("_token", m_tkParamDef); + } + #endregion + + #region Constructor + // used by RuntimePropertyInfo + internal RuntimeParameterInfo(RuntimeParameterInfo accessor, RuntimePropertyInfo property) + : this(accessor, (MemberInfo)property) + { + m_signature = property.Signature; + } + + private RuntimeParameterInfo(RuntimeParameterInfo accessor, MemberInfo member) + { + // Change ownership + MemberImpl = member; + + // The original owner should always be a method, because this method is only used to + // change the owner from a method to a property. + m_originalMember = accessor.MemberImpl as MethodBase; + Contract.Assert(m_originalMember != null); + + // Populate all the caches -- we inherit this behavior from RTM + NameImpl = accessor.Name; + m_nameIsCached = true; + ClassImpl = accessor.ParameterType; + PositionImpl = accessor.Position; + AttrsImpl = accessor.Attributes; + + // Strictly speeking, property's don't contain paramter tokens + // However we need this to make ca's work... oh well... + m_tkParamDef = MdToken.IsNullToken(accessor.MetadataToken) ? (int)MetadataTokenType.ParamDef : accessor.MetadataToken; + m_scope = accessor.m_scope; + } + + private RuntimeParameterInfo( + Signature signature, MetadataImport scope, int tkParamDef, + int position, ParameterAttributes attributes, MemberInfo member) + { + Contract.Requires(member != null); + Contract.Assert(MdToken.IsNullToken(tkParamDef) == scope.Equals(MetadataImport.EmptyImport)); + Contract.Assert(MdToken.IsNullToken(tkParamDef) || MdToken.IsTokenOfType(tkParamDef, MetadataTokenType.ParamDef)); + + PositionImpl = position; + MemberImpl = member; + m_signature = signature; + m_tkParamDef = MdToken.IsNullToken(tkParamDef) ? (int)MetadataTokenType.ParamDef : tkParamDef; + m_scope = scope; + AttrsImpl = attributes; + + ClassImpl = null; + NameImpl = null; + } + + // ctor for no metadata MethodInfo in the DynamicMethod and RuntimeMethodInfo cases + internal RuntimeParameterInfo(MethodInfo owner, String name, Type parameterType, int position) + { + MemberImpl = owner; + NameImpl = name; + m_nameIsCached = true; + m_noMetadata = true; + ClassImpl = parameterType; + PositionImpl = position; + AttrsImpl = ParameterAttributes.None; + m_tkParamDef = (int)MetadataTokenType.ParamDef; + m_scope = MetadataImport.EmptyImport; + } + #endregion + + #region Public Methods + public override Type ParameterType + { + get + { + // only instance of ParameterInfo has ClassImpl, all its subclasses don't + if (ClassImpl == null) + { + RuntimeType parameterType; + if (PositionImpl == -1) + parameterType = m_signature.ReturnType; + else + parameterType = m_signature.Arguments[PositionImpl]; + + Contract.Assert(parameterType != null); + // different thread could only write ClassImpl to the same value, so a race condition is not a problem here + ClassImpl = parameterType; + } + + return ClassImpl; + } + } + + public override String Name + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + if (!m_nameIsCached) + { + if (!MdToken.IsNullToken(m_tkParamDef)) + { + string name; + name = m_scope.GetName(m_tkParamDef).ToString(); + NameImpl = name; + } + + // other threads could only write it to true, so a race condition is OK + // this field is volatile, so the write ordering is guaranteed + m_nameIsCached = true; + } + + // name may be null + return NameImpl; + } + } + + public override bool HasDefaultValue + { + get + { + if (m_noMetadata || m_noDefaultValue) + return false; + + object defaultValue = GetDefaultValueInternal(false); + + return (defaultValue != DBNull.Value); + } + } + + public override Object DefaultValue { get { return GetDefaultValue(false); } } + public override Object RawDefaultValue { get { return GetDefaultValue(true); } } + + private Object GetDefaultValue(bool raw) + { + // OLD COMMENT (Is this even true?) + // Cannot cache because default value could be non-agile user defined enumeration. + // OLD COMMENT ends + if (m_noMetadata) + return null; + + // for dynamic method we pretend to have cached the value so we do not go to metadata + object defaultValue = GetDefaultValueInternal(raw); + + if (defaultValue == DBNull.Value) + { + #region Handle case if no default value was found + if (IsOptional) + { + // If the argument is marked as optional then the default value is Missing.Value. + defaultValue = Type.Missing; + } + #endregion + } + + return defaultValue; + } + + // returns DBNull.Value if the parameter doesn't have a default value + [System.Security.SecuritySafeCritical] + private Object GetDefaultValueInternal(bool raw) + { + Contract.Assert(!m_noMetadata); + + if (m_noDefaultValue) + return DBNull.Value; + + object defaultValue = null; + + // Why check the parameter type only for DateTime and only for the ctor arguments? + // No check on the parameter type is done for named args and for Decimal. + + // We should move this after MdToken.IsNullToken(m_tkParamDef) and combine it + // with the other custom attribute logic. But will that be a breaking change? + // For a DateTime parameter on which both an md constant and a ca constant are set, + // which one should win? + if (ParameterType == typeof(DateTime)) + { + if (raw) + { + CustomAttributeTypedArgument value = + CustomAttributeData.Filter( + CustomAttributeData.GetCustomAttributes(this), typeof(DateTimeConstantAttribute), 0); + + if (value.ArgumentType != null) + return new DateTime((long)value.Value); + } + else + { + object[] dt = GetCustomAttributes(typeof(DateTimeConstantAttribute), false); + if (dt != null && dt.Length != 0) + return ((DateTimeConstantAttribute)dt[0]).Value; + } + } + + #region Look for a default value in metadata + if (!MdToken.IsNullToken(m_tkParamDef)) + { + // This will return DBNull.Value if no constant value is defined on m_tkParamDef in the metadata. + defaultValue = MdConstant.GetValue(m_scope, m_tkParamDef, ParameterType.GetTypeHandleInternal(), raw); + } + #endregion + + if (defaultValue == DBNull.Value) + { + #region Look for a default value in the custom attributes + if (raw) + { + foreach (CustomAttributeData attr in CustomAttributeData.GetCustomAttributes(this)) + { + Type attrType = attr.Constructor.DeclaringType; + + if (attrType == typeof(DateTimeConstantAttribute)) + { + defaultValue = DateTimeConstantAttribute.GetRawDateTimeConstant(attr); + } + else if (attrType == typeof(DecimalConstantAttribute)) + { + defaultValue = DecimalConstantAttribute.GetRawDecimalConstant(attr); + } + else if (attrType.IsSubclassOf(s_CustomConstantAttributeType)) + { + defaultValue = CustomConstantAttribute.GetRawConstant(attr); + } + } + } + else + { + Object[] CustomAttrs = GetCustomAttributes(s_CustomConstantAttributeType, false); + if (CustomAttrs.Length != 0) + { + defaultValue = ((CustomConstantAttribute)CustomAttrs[0]).Value; + } + else + { + CustomAttrs = GetCustomAttributes(s_DecimalConstantAttributeType, false); + if (CustomAttrs.Length != 0) + { + defaultValue = ((DecimalConstantAttribute)CustomAttrs[0]).Value; + } + } + } + #endregion + } + + if (defaultValue == DBNull.Value) + m_noDefaultValue = true; + + return defaultValue; + } + + internal RuntimeModule GetRuntimeModule() + { + RuntimeMethodInfo method = Member as RuntimeMethodInfo; + RuntimeConstructorInfo constructor = Member as RuntimeConstructorInfo; + RuntimePropertyInfo property = Member as RuntimePropertyInfo; + + if (method != null) + return method.GetRuntimeModule(); + else if (constructor != null) + return constructor.GetRuntimeModule(); + else if (property != null) + return property.GetRuntimeModule(); + else + return null; + } + + public override int MetadataToken + { + get + { + return m_tkParamDef; + } + } + + public override Type[] GetRequiredCustomModifiers() + { + return m_signature.GetCustomModifiers(PositionImpl + 1, true); + } + + public override Type[] GetOptionalCustomModifiers() + { + return m_signature.GetCustomModifiers(PositionImpl + 1, false); + } + + #endregion + + #region ICustomAttributeProvider + public override Object[] GetCustomAttributes(bool inherit) + { + if (MdToken.IsNullToken(m_tkParamDef)) + return EmptyArray.Value; + + return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + if (MdToken.IsNullToken(m_tkParamDef)) + return EmptyArray.Value; + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "attributeType"); + + return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public override bool IsDefined(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + if (MdToken.IsNullToken(m_tkParamDef)) + return false; + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"), "attributeType"); + + return CustomAttribute.IsDefined(this, attributeRuntimeType); + } + + public override IList GetCustomAttributesData() + { + return CustomAttributeData.GetCustomAttributesInternal(this); + } + #endregion + +#if FEATURE_REMOTING + #region Remoting Cache + private RemotingParameterCachedData m_cachedData; + + internal RemotingParameterCachedData RemotingCache + { + get + { + // This grabs an internal copy of m_cachedData and uses + // that instead of looking at m_cachedData directly because + // the cache may get cleared asynchronously. This prevents + // us from having to take a lock. + RemotingParameterCachedData cache = m_cachedData; + if (cache == null) + { + cache = new RemotingParameterCachedData(this); + RemotingParameterCachedData ret = Interlocked.CompareExchange(ref m_cachedData, cache, null); + if (ret != null) + cache = ret; + } + return cache; + } + } + #endregion +#endif //FEATURE_REMOTING + } +} diff --git a/src/mscorlib/src/System/Reflection/ParameterModifier.cs b/src/mscorlib/src/System/Reflection/ParameterModifier.cs new file mode 100644 index 0000000000..97da1b9e00 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/ParameterModifier.cs @@ -0,0 +1,46 @@ +// Licensed to the .NET Foundation under one or more agreements. +// 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.Diagnostics.Contracts; +namespace System.Reflection +{ + using System; + + [Serializable] +[System.Runtime.InteropServices.ComVisible(true)] + public struct ParameterModifier + { + #region Private Data Members + private bool[] _byRef; + #endregion + + #region Constructor + public ParameterModifier(int parameterCount) + { + if (parameterCount <= 0) + throw new ArgumentException(Environment.GetResourceString("Arg_ParmArraySize")); + Contract.EndContractBlock(); + + _byRef = new bool[parameterCount]; + } + #endregion + + #region Internal Members + internal bool[] IsByRefArray { get { return _byRef; } } + #endregion + + #region Public Members + public bool this[int index] + { + get + { + return _byRef[index]; + } + set + { + _byRef[index] = value; + } + } + #endregion + } +} diff --git a/src/mscorlib/src/System/Reflection/Pointer.cs b/src/mscorlib/src/System/Reflection/Pointer.cs new file mode 100644 index 0000000000..8105208288 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/Pointer.cs @@ -0,0 +1,82 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +// +// This is a wrapper class for Pointers +// +// +// +// +// +namespace System.Reflection { + using System; + using CultureInfo = System.Globalization.CultureInfo; + using System.Runtime.Serialization; + using System.Security; + using System.Diagnostics.Contracts; + + [CLSCompliant(false)] + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public sealed class Pointer : ISerializable + { + [SecurityCritical] + unsafe private void* _ptr; + private RuntimeType _ptrType; + + private Pointer() {} + + [System.Security.SecurityCritical] // auto-generated + private unsafe Pointer(SerializationInfo info, StreamingContext context) + { + _ptr = ((IntPtr)(info.GetValue("_ptr", typeof(IntPtr)))).ToPointer(); + _ptrType = (RuntimeType)info.GetValue("_ptrType", typeof(RuntimeType)); + } + + // This method will box an pointer. We save both the + // value and the type so we can access it from the native code + // during an Invoke. + [System.Security.SecurityCritical] // auto-generated + public static unsafe Object Box(void *ptr,Type type) { + if (type == null) + throw new ArgumentNullException("type"); + if (!type.IsPointer) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBePointer"),"ptr"); + Contract.EndContractBlock(); + + RuntimeType rt = type as RuntimeType; + if (rt == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBePointer"), "ptr"); + + Pointer x = new Pointer(); + x._ptr = ptr; + x._ptrType = rt; + return x; + } + + // Returned the stored pointer. + [System.Security.SecurityCritical] // auto-generated + public static unsafe void* Unbox(Object ptr) { + if (!(ptr is Pointer)) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBePointer"),"ptr"); + return ((Pointer)ptr)._ptr; + } + + internal RuntimeType GetPointerType() { + return _ptrType; + } + + [System.Security.SecurityCritical] // auto-generated + internal unsafe Object GetPointerValue() { + return (IntPtr)_ptr; + } + + [System.Security.SecurityCritical] + unsafe void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) { + info.AddValue("_ptr", new IntPtr(_ptr)); + info.AddValue("_ptrType", _ptrType); + } + } +} diff --git a/src/mscorlib/src/System/Reflection/PropertyAttributes.cs b/src/mscorlib/src/System/Reflection/PropertyAttributes.cs new file mode 100644 index 0000000000..d7c3d79b6a --- /dev/null +++ b/src/mscorlib/src/System/Reflection/PropertyAttributes.cs @@ -0,0 +1,33 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// PropertyAttributes is an enum which defines the attributes that may be associated +// +// with a property. The values here are defined in Corhdr.h. +// +// +namespace System.Reflection { + + using System; + // This Enum matchs the CorPropertyAttr defined in CorHdr.h +[Serializable] +[Flags] +[System.Runtime.InteropServices.ComVisible(true)] + public enum PropertyAttributes + { + None = 0x0000, + SpecialName = 0x0200, // property is special. Name describes how. + + // Reserved flags for Runtime use only. + ReservedMask = 0xf400, + RTSpecialName = 0x0400, // Runtime(metadata internal APIs) should check name encoding. + HasDefault = 0x1000, // Property has default + Reserved2 = 0x2000, // reserved bit + Reserved3 = 0x4000, // reserved bit + Reserved4 = 0x8000 // reserved bit + } +} diff --git a/src/mscorlib/src/System/Reflection/PropertyInfo.cs b/src/mscorlib/src/System/Reflection/PropertyInfo.cs new file mode 100644 index 0000000000..3e451b15b6 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/PropertyInfo.cs @@ -0,0 +1,657 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// + +namespace System.Reflection +{ + using System; + using System.Collections.Generic; + using System.Diagnostics; + using System.Diagnostics.Contracts; + using System.Globalization; + using System.Runtime; + using System.Runtime.ConstrainedExecution; + using System.Runtime.InteropServices; + using System.Runtime.Serialization; + using System.Security.Permissions; + using System.Text; + using RuntimeTypeCache = System.RuntimeType.RuntimeTypeCache; + + [Serializable] + [ClassInterface(ClassInterfaceType.None)] + [ComDefaultInterface(typeof(_PropertyInfo))] +#pragma warning disable 618 + [PermissionSetAttribute(SecurityAction.InheritanceDemand, Name = "FullTrust")] +#pragma warning restore 618 + [System.Runtime.InteropServices.ComVisible(true)] + public abstract class PropertyInfo : MemberInfo, _PropertyInfo + { + #region Constructor + protected PropertyInfo() { } + #endregion + + public static bool operator ==(PropertyInfo left, PropertyInfo right) + { + if (ReferenceEquals(left, right)) + return true; + + if ((object)left == null || (object)right == null || + left is RuntimePropertyInfo || right is RuntimePropertyInfo) + { + return false; + } + return left.Equals(right); + } + + public static bool operator !=(PropertyInfo left, PropertyInfo right) + { + return !(left == right); + } + + public override bool Equals(object obj) + { + return base.Equals(obj); + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + + #region MemberInfo Overrides + public override MemberTypes MemberType { get { return System.Reflection.MemberTypes.Property; } } + #endregion + + #region Public Abstract\Virtual Members + public virtual object GetConstantValue() + { + throw new NotImplementedException(); + } + + public virtual object GetRawConstantValue() + { + throw new NotImplementedException(); + } + + public abstract Type PropertyType { get; } + + public abstract void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture); + + public abstract MethodInfo[] GetAccessors(bool nonPublic); + + public abstract MethodInfo GetGetMethod(bool nonPublic); + + public abstract MethodInfo GetSetMethod(bool nonPublic); + + public abstract ParameterInfo[] GetIndexParameters(); + + public abstract PropertyAttributes Attributes { get; } + + public abstract bool CanRead { get; } + + public abstract bool CanWrite { get; } + + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public Object GetValue(Object obj) + { + return GetValue(obj, null); + } + + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public virtual Object GetValue(Object obj,Object[] index) + { + return GetValue(obj, BindingFlags.Default, null, index, null); + } + + public abstract Object GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture); + + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public void SetValue(Object obj, Object value) + { + SetValue(obj, value, null); + } + + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public virtual void SetValue(Object obj, Object value, Object[] index) + { + SetValue(obj, value, BindingFlags.Default, null, index, null); + } + #endregion + + #region Public Members + public virtual Type[] GetRequiredCustomModifiers() { return EmptyArray.Value; } + + public virtual Type[] GetOptionalCustomModifiers() { return EmptyArray.Value; } + + public MethodInfo[] GetAccessors() { return GetAccessors(false); } + + public virtual MethodInfo GetMethod + { + get + { + return GetGetMethod(true); + } + } + + public virtual MethodInfo SetMethod + { + get + { + return GetSetMethod(true); + } + } + + public MethodInfo GetGetMethod() { return GetGetMethod(false); } + + public MethodInfo GetSetMethod() { return GetSetMethod(false); } + + public bool IsSpecialName { get { return(Attributes & PropertyAttributes.SpecialName) != 0; } } + #endregion + +#if !FEATURE_CORECLR + Type _PropertyInfo.GetType() + { + return base.GetType(); + } + + void _PropertyInfo.GetTypeInfoCount(out uint pcTInfo) + { + throw new NotImplementedException(); + } + + void _PropertyInfo.GetTypeInfo(uint iTInfo, uint lcid, IntPtr ppTInfo) + { + throw new NotImplementedException(); + } + + void _PropertyInfo.GetIDsOfNames([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) + { + throw new NotImplementedException(); + } + + // If you implement this method, make sure to include _PropertyInfo.Invoke in VM\DangerousAPIs.h and + // include _PropertyInfo in SystemDomain::IsReflectionInvocationMethod in AppDomain.cpp. + void _PropertyInfo.Invoke(uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) + { + throw new NotImplementedException(); + } +#endif + } + + [Serializable] + internal unsafe sealed class RuntimePropertyInfo : PropertyInfo, ISerializable + { + #region Private Data Members + private int m_token; + private string m_name; + [System.Security.SecurityCritical] + private void* m_utf8name; + private PropertyAttributes m_flags; + private RuntimeTypeCache m_reflectedTypeCache; + private RuntimeMethodInfo m_getterMethod; + private RuntimeMethodInfo m_setterMethod; + private MethodInfo[] m_otherMethod; + private RuntimeType m_declaringType; + private BindingFlags m_bindingFlags; + private Signature m_signature; + private ParameterInfo[] m_parameters; + #endregion + + #region Constructor + [System.Security.SecurityCritical] // auto-generated + internal RuntimePropertyInfo( + int tkProperty, RuntimeType declaredType, RuntimeTypeCache reflectedTypeCache, out bool isPrivate) + { + Contract.Requires(declaredType != null); + Contract.Requires(reflectedTypeCache != null); + Contract.Assert(!reflectedTypeCache.IsGlobal); + + MetadataImport scope = declaredType.GetRuntimeModule().MetadataImport; + + m_token = tkProperty; + m_reflectedTypeCache = reflectedTypeCache; + m_declaringType = declaredType; + + ConstArray sig; + scope.GetPropertyProps(tkProperty, out m_utf8name, out m_flags, out sig); + + RuntimeMethodInfo dummy; + Associates.AssignAssociates(scope, tkProperty, declaredType, reflectedTypeCache.GetRuntimeType(), + out dummy, out dummy, out dummy, + out m_getterMethod, out m_setterMethod, out m_otherMethod, + out isPrivate, out m_bindingFlags); + } + #endregion + + #region Internal Members + [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] + internal override bool CacheEquals(object o) + { + RuntimePropertyInfo m = o as RuntimePropertyInfo; + + if ((object)m == null) + return false; + + return m.m_token == m_token && + RuntimeTypeHandle.GetModule(m_declaringType).Equals( + RuntimeTypeHandle.GetModule(m.m_declaringType)); + } + + internal Signature Signature + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + if (m_signature == null) + { + PropertyAttributes flags; + ConstArray sig; + + void* name; + GetRuntimeModule().MetadataImport.GetPropertyProps( + m_token, out name, out flags, out sig); + + m_signature = new Signature(sig.Signature.ToPointer(), (int)sig.Length, m_declaringType); + } + + return m_signature; + } + } + internal bool EqualsSig(RuntimePropertyInfo target) + { + //@Asymmetry - Legacy policy is to remove duplicate properties, including hidden properties. + // The comparison is done by name and by sig. The EqualsSig comparison is expensive + // but forutnetly it is only called when an inherited property is hidden by name or + // when an interfaces declare properies with the same signature. + // Note that we intentionally don't resolve generic arguments so that we don't treat + // signatures that only match in certain instantiations as duplicates. This has the + // down side of treating overriding and overriden properties as different properties + // in some cases. But PopulateProperties in rttype.cs should have taken care of that + // by comparing VTable slots. + // + // Class C1(Of T, Y) + // Property Prop1(ByVal t1 As T) As Integer + // Get + // ... ... + // End Get + // End Property + // Property Prop1(ByVal y1 As Y) As Integer + // Get + // ... ... + // End Get + // End Property + // End Class + // + + Contract.Requires(Name.Equals(target.Name)); + Contract.Requires(this != target); + Contract.Requires(this.ReflectedType == target.ReflectedType); + + return Signature.CompareSig(this.Signature, target.Signature); + } + internal BindingFlags BindingFlags { get { return m_bindingFlags; } } + #endregion + + #region Object Overrides + public override String ToString() + { + return FormatNameAndSig(false); + } + + private string FormatNameAndSig(bool serialization) + { + StringBuilder sbName = new StringBuilder(PropertyType.FormatTypeName(serialization)); + + sbName.Append(" "); + sbName.Append(Name); + + RuntimeType[] arguments = Signature.Arguments; + if (arguments.Length > 0) + { + sbName.Append(" ["); + sbName.Append(MethodBase.ConstructParameters(arguments, Signature.CallingConvention, serialization)); + sbName.Append("]"); + } + + return sbName.ToString(); + } + #endregion + + #region ICustomAttributeProvider + public override Object[] GetCustomAttributes(bool inherit) + { + return CustomAttribute.GetCustomAttributes(this, typeof(object) as RuntimeType); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType"); + + return CustomAttribute.GetCustomAttributes(this, attributeRuntimeType); + } + + [System.Security.SecuritySafeCritical] // auto-generated + public override bool IsDefined(Type attributeType, bool inherit) + { + if (attributeType == null) + throw new ArgumentNullException("attributeType"); + Contract.EndContractBlock(); + + RuntimeType attributeRuntimeType = attributeType.UnderlyingSystemType as RuntimeType; + + if (attributeRuntimeType == null) + throw new ArgumentException(Environment.GetResourceString("Arg_MustBeType"),"attributeType"); + + return CustomAttribute.IsDefined(this, attributeRuntimeType); + } + + public override IList GetCustomAttributesData() + { + return CustomAttributeData.GetCustomAttributesInternal(this); + } + #endregion + + #region MemberInfo Overrides + public override MemberTypes MemberType { get { return MemberTypes.Property; } } + public override String Name + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + if (m_name == null) + m_name = new Utf8String(m_utf8name).ToString(); + + return m_name; + } + } + public override Type DeclaringType + { + get + { + return m_declaringType; + } + } + + public override Type ReflectedType + { + get + { + return ReflectedTypeInternal; + } + } + + private RuntimeType ReflectedTypeInternal + { + get + { + return m_reflectedTypeCache.GetRuntimeType(); + } + } + + public override int MetadataToken { get { return m_token; } } + + public override Module Module { get { return GetRuntimeModule(); } } + internal RuntimeModule GetRuntimeModule() { return m_declaringType.GetRuntimeModule(); } + #endregion + + #region PropertyInfo Overrides + + #region Non Dynamic + + public override Type[] GetRequiredCustomModifiers() + { + return Signature.GetCustomModifiers(0, true); + } + + public override Type[] GetOptionalCustomModifiers() + { + return Signature.GetCustomModifiers(0, false); + } + + [System.Security.SecuritySafeCritical] // auto-generated + internal object GetConstantValue(bool raw) + { + Object defaultValue = MdConstant.GetValue(GetRuntimeModule().MetadataImport, m_token, PropertyType.GetTypeHandleInternal(), raw); + + if (defaultValue == DBNull.Value) + // Arg_EnumLitValueNotFound -> "Literal value was not found." + throw new InvalidOperationException(Environment.GetResourceString("Arg_EnumLitValueNotFound")); + + return defaultValue; + } + + public override object GetConstantValue() { return GetConstantValue(false); } + + public override object GetRawConstantValue() { return GetConstantValue(true); } + + public override MethodInfo[] GetAccessors(bool nonPublic) + { + List accessorList = new List(); + + if (Associates.IncludeAccessor(m_getterMethod, nonPublic)) + accessorList.Add(m_getterMethod); + + if (Associates.IncludeAccessor(m_setterMethod, nonPublic)) + accessorList.Add(m_setterMethod); + + if ((object)m_otherMethod != null) + { + for(int i = 0; i < m_otherMethod.Length; i ++) + { + if (Associates.IncludeAccessor(m_otherMethod[i] as MethodInfo, nonPublic)) + accessorList.Add(m_otherMethod[i]); + } + } + return accessorList.ToArray(); + } + + public override Type PropertyType + { + get { return Signature.ReturnType; } + } + + public override MethodInfo GetGetMethod(bool nonPublic) + { + if (!Associates.IncludeAccessor(m_getterMethod, nonPublic)) + return null; + + return m_getterMethod; + } + + public override MethodInfo GetSetMethod(bool nonPublic) + { + if (!Associates.IncludeAccessor(m_setterMethod, nonPublic)) + return null; + + return m_setterMethod; + } + + public override ParameterInfo[] GetIndexParameters() + { + ParameterInfo[] indexParams = GetIndexParametersNoCopy(); + + int numParams = indexParams.Length; + + if (numParams == 0) + return indexParams; + + ParameterInfo[] ret = new ParameterInfo[numParams]; + + Array.Copy(indexParams, ret, numParams); + + return ret; + } + + internal ParameterInfo[] GetIndexParametersNoCopy() + { + // @History - Logic ported from RTM + + // No need to lock because we don't guarantee the uniqueness of ParameterInfo objects + if (m_parameters == null) + { + int numParams = 0; + ParameterInfo[] methParams = null; + + // First try to get the Get method. + MethodInfo m = GetGetMethod(true); + if (m != null) + { + // There is a Get method so use it. + methParams = m.GetParametersNoCopy(); + numParams = methParams.Length; + } + else + { + // If there is no Get method then use the Set method. + m = GetSetMethod(true); + + if (m != null) + { + methParams = m.GetParametersNoCopy(); + numParams = methParams.Length - 1; + } + } + + // Now copy over the parameter info's and change their + // owning member info to the current property info. + + ParameterInfo[] propParams = new ParameterInfo[numParams]; + + for (int i = 0; i < numParams; i++) + propParams[i] = new RuntimeParameterInfo((RuntimeParameterInfo)methParams[i], this); + + m_parameters = propParams; + } + + return m_parameters; + } + + public override PropertyAttributes Attributes + { + get + { + return m_flags; + } + } + + public override bool CanRead + { + get + { + return m_getterMethod != null; + } + } + + public override bool CanWrite + { + get + { + return m_setterMethod != null; + } + } + #endregion + + #region Dynamic + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public override Object GetValue(Object obj,Object[] index) + { + return GetValue(obj, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, + null, index, null); + } + + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public override Object GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture) + { + + MethodInfo m = GetGetMethod(true); + if (m == null) + throw new ArgumentException(System.Environment.GetResourceString("Arg_GetMethNotFnd")); + return m.Invoke(obj, invokeAttr, binder, index, null); + } + + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public override void SetValue(Object obj, Object value, Object[] index) + { + SetValue(obj, + value, + BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static, + null, + index, + null); + } + + [DebuggerStepThroughAttribute] + [Diagnostics.DebuggerHidden] + public override void SetValue(Object obj, Object value, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture) + { + + MethodInfo m = GetSetMethod(true); + + if (m == null) + throw new ArgumentException(System.Environment.GetResourceString("Arg_SetMethNotFnd")); + + Object[] args = null; + + if (index != null) + { + args = new Object[index.Length + 1]; + + for(int i=0;i GetRuntimeProperties(this Type type) + { + CheckAndThrow(type); + return type.GetProperties(everything); + } + public static IEnumerable GetRuntimeEvents(this Type type) + { + CheckAndThrow(type); + return type.GetEvents(everything); + } + + public static IEnumerable GetRuntimeMethods(this Type type) + { + CheckAndThrow(type); + return type.GetMethods(everything); + } + + public static IEnumerable GetRuntimeFields(this Type type) + { + CheckAndThrow(type); + return type.GetFields(everything); + } + + public static PropertyInfo GetRuntimeProperty(this Type type, string name) + { + CheckAndThrow(type); + return type.GetProperty(name); + } + public static EventInfo GetRuntimeEvent(this Type type, string name) + { + CheckAndThrow(type); + return type.GetEvent(name); + } + public static MethodInfo GetRuntimeMethod(this Type type, string name, Type[] parameters) + { + CheckAndThrow(type); + return type.GetMethod(name, parameters); + } + public static FieldInfo GetRuntimeField(this Type type, string name) + { + CheckAndThrow(type); + return type.GetField(name); + } + public static MethodInfo GetRuntimeBaseDefinition(this MethodInfo method){ + CheckAndThrow(method); + return method.GetBaseDefinition(); + } + + public static InterfaceMapping GetRuntimeInterfaceMap(this TypeInfo typeInfo, Type interfaceType) + { + if (typeInfo == null) throw new ArgumentNullException("typeInfo"); + if (!(typeInfo is RuntimeType)) throw new ArgumentException(Environment.GetResourceString("Argument_MustBeRuntimeType")); + + return typeInfo.GetInterfaceMap(interfaceType); + } + + public static MethodInfo GetMethodInfo(this Delegate del) + { + if (del == null) throw new ArgumentNullException("del"); + + return del.Method; + } + } +} diff --git a/src/mscorlib/src/System/Reflection/StrongNameKeyPair.cs b/src/mscorlib/src/System/Reflection/StrongNameKeyPair.cs new file mode 100644 index 0000000000..e8a441ca8f --- /dev/null +++ b/src/mscorlib/src/System/Reflection/StrongNameKeyPair.cs @@ -0,0 +1,194 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================ +** +** +** +** +** +** Purpose: Encapsulate access to a public/private key pair +** used to sign strong name assemblies. +** +** +===========================================================*/ +namespace System.Reflection +{ + using System; + using System.IO; + using System.Runtime.CompilerServices; + using System.Runtime.ConstrainedExecution; + using System.Runtime.InteropServices; + using System.Runtime.Serialization; + using System.Security; + using System.Security.Permissions; + using System.Runtime.Versioning; + using Microsoft.Win32; + using System.Diagnostics.Contracts; +#if !FEATURE_CORECLR + using Microsoft.Runtime.Hosting; +#endif + +#if FEATURE_CORECLR + // Dummy type to avoid ifdefs in signature definitions + public class StrongNameKeyPair + { + private StrongNameKeyPair() + { + throw new NotSupportedException(); + } + } +#else + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public class StrongNameKeyPair : IDeserializationCallback, ISerializable + { + private bool _keyPairExported; + private byte[] _keyPairArray; + private String _keyPairContainer; + private byte[] _publicKey; + + // Build key pair from file. + [System.Security.SecuritySafeCritical] // auto-generated +#pragma warning disable 618 + [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)] +#pragma warning restore 618 + public StrongNameKeyPair(FileStream keyPairFile) + { + if (keyPairFile == null) + throw new ArgumentNullException("keyPairFile"); + Contract.EndContractBlock(); + + int length = (int)keyPairFile.Length; + _keyPairArray = new byte[length]; + keyPairFile.Read(_keyPairArray, 0, length); + + _keyPairExported = true; + } + + // Build key pair from byte array in memory. + [System.Security.SecuritySafeCritical] // auto-generated +#pragma warning disable 618 + [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)] +#pragma warning restore 618 + public StrongNameKeyPair(byte[] keyPairArray) + { + if (keyPairArray == null) + throw new ArgumentNullException("keyPairArray"); + Contract.EndContractBlock(); + + _keyPairArray = new byte[keyPairArray.Length]; + Array.Copy(keyPairArray, _keyPairArray, keyPairArray.Length); + + _keyPairExported = true; + } + + // Reference key pair in named key container. + [System.Security.SecuritySafeCritical] // auto-generated +#pragma warning disable 618 + [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)] +#pragma warning restore 618 + public StrongNameKeyPair(String keyPairContainer) + { + if (keyPairContainer == null) + throw new ArgumentNullException("keyPairContainer"); + Contract.EndContractBlock(); + + _keyPairContainer = keyPairContainer; + + _keyPairExported = false; + } + + [System.Security.SecuritySafeCritical] // auto-generated +#pragma warning disable 618 + [SecurityPermissionAttribute(SecurityAction.Demand, Flags=SecurityPermissionFlag.UnmanagedCode)] +#pragma warning restore 618 + protected StrongNameKeyPair (SerializationInfo info, StreamingContext context) { + _keyPairExported = (bool) info.GetValue("_keyPairExported", typeof(bool)); + _keyPairArray = (byte[]) info.GetValue("_keyPairArray", typeof(byte[])); + _keyPairContainer = (string) info.GetValue("_keyPairContainer", typeof(string)); + _publicKey = (byte[]) info.GetValue("_publicKey", typeof(byte[])); + } + + // Get the public portion of the key pair. + public byte[] PublicKey + { + [System.Security.SecuritySafeCritical] // auto-generated + get + { + if (_publicKey == null) + { + _publicKey = ComputePublicKey(); + } + + byte[] publicKey = new byte[_publicKey.Length]; + Array.Copy(_publicKey, publicKey, _publicKey.Length); + + return publicKey; + } + } + + [System.Security.SecurityCritical] // auto-generated + private unsafe byte[] ComputePublicKey() + { + byte[] publicKey = null; + + // Make sure pbPublicKey is not leaked with async exceptions + RuntimeHelpers.PrepareConstrainedRegions(); + try { + } + finally + { + IntPtr pbPublicKey = IntPtr.Zero; + int cbPublicKey = 0; + + try + { + bool result; + if (_keyPairExported) + { + result = StrongNameHelpers.StrongNameGetPublicKey(null, _keyPairArray, _keyPairArray.Length, + out pbPublicKey, out cbPublicKey); + } + else + { + result = StrongNameHelpers.StrongNameGetPublicKey(_keyPairContainer, null, 0, + out pbPublicKey, out cbPublicKey); + } + if (!result) + throw new ArgumentException(Environment.GetResourceString("Argument_StrongNameGetPublicKey")); + + publicKey = new byte[cbPublicKey]; + Buffer.Memcpy(publicKey, 0, (byte*)(pbPublicKey.ToPointer()), 0, cbPublicKey); + } + finally + { + if (pbPublicKey != IntPtr.Zero) + StrongNameHelpers.StrongNameFreeBuffer(pbPublicKey); + } + } + return publicKey; + } + + /// + [System.Security.SecurityCritical] + void ISerializable.GetObjectData (SerializationInfo info, StreamingContext context) { + info.AddValue("_keyPairExported", _keyPairExported); + info.AddValue("_keyPairArray", _keyPairArray); + info.AddValue("_keyPairContainer", _keyPairContainer); + info.AddValue("_publicKey", _publicKey); + } + + /// + void IDeserializationCallback.OnDeserialization (Object sender) {} + + // Internal routine used to retrieve key pair info from unmanaged code. + private bool GetKeyPair(out Object arrayOrContainer) + { + arrayOrContainer = _keyPairExported ? (Object)_keyPairArray : (Object)_keyPairContainer; + return _keyPairExported; + } + } +#endif // FEATURE_CORECLR +} diff --git a/src/mscorlib/src/System/Reflection/TargetException.cs b/src/mscorlib/src/System/Reflection/TargetException.cs new file mode 100644 index 0000000000..02772f763f --- /dev/null +++ b/src/mscorlib/src/System/Reflection/TargetException.cs @@ -0,0 +1,42 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// TargetException is thrown when the target to an Invoke is invalid. This may +// +// occur because the caller doesn't have access to the member, or the target doesn't +// define the member, etc. +// +// +// +// +namespace System.Reflection { + + using System; + using System.Runtime.Serialization; + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] +#if FEATURE_CORECLR + public class TargetException : Exception { +#else + public class TargetException : ApplicationException { +#endif //FEATURE_CORECLR + public TargetException() : base() { + SetErrorCode(__HResults.COR_E_TARGET); + } + + public TargetException(String message) : base(message) { + SetErrorCode(__HResults.COR_E_TARGET); + } + + public TargetException(String message, Exception inner) : base(message, inner) { + SetErrorCode(__HResults.COR_E_TARGET); + } + + protected TargetException(SerializationInfo info, StreamingContext context) : base (info, context) { + } + } +} diff --git a/src/mscorlib/src/System/Reflection/TargetInvocationException.cs b/src/mscorlib/src/System/Reflection/TargetInvocationException.cs new file mode 100644 index 0000000000..70de4227dd --- /dev/null +++ b/src/mscorlib/src/System/Reflection/TargetInvocationException.cs @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// TargetInvocationException is used to report an exception that was thrown +// +// by the target of an invocation. +// +// +// +// +namespace System.Reflection { + + + using System; + using System.Runtime.Serialization; + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] +#if FEATURE_CORECLR + public sealed class TargetInvocationException : Exception { +#else + public sealed class TargetInvocationException : ApplicationException { +#endif //FEATURE_CORECLR + // This exception is not creatable without specifying the + // inner exception. + private TargetInvocationException() + : base(Environment.GetResourceString("Arg_TargetInvocationException")) { + SetErrorCode(__HResults.COR_E_TARGETINVOCATION); + } + + // This is called from within the runtime. + private TargetInvocationException(String message) : base(message) { + SetErrorCode(__HResults.COR_E_TARGETINVOCATION); + } + + public TargetInvocationException(System.Exception inner) + : base(Environment.GetResourceString("Arg_TargetInvocationException"), inner) { + SetErrorCode(__HResults.COR_E_TARGETINVOCATION); + } + + public TargetInvocationException(String message, Exception inner) : base(message, inner) { + SetErrorCode(__HResults.COR_E_TARGETINVOCATION); + } + + internal TargetInvocationException(SerializationInfo info, StreamingContext context) : base (info, context) { + } + } +} diff --git a/src/mscorlib/src/System/Reflection/TargetParameterCountException.cs b/src/mscorlib/src/System/Reflection/TargetParameterCountException.cs new file mode 100644 index 0000000000..4f95b09c40 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/TargetParameterCountException.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// TargetParameterCountException is thrown when the number of parameter to an +// +// invocation doesn't match the number expected. +// +// +// +// +namespace System.Reflection { + + using System; + using SystemException = System.SystemException; + using System.Runtime.Serialization; + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] +#if FEATURE_CORECLR + public sealed class TargetParameterCountException : Exception { +#else + public sealed class TargetParameterCountException : ApplicationException { +#endif //FEATURE_CORECLR + public TargetParameterCountException() + : base(Environment.GetResourceString("Arg_TargetParameterCountException")) { + SetErrorCode(__HResults.COR_E_TARGETPARAMCOUNT); + } + + public TargetParameterCountException(String message) + : base(message) { + SetErrorCode(__HResults.COR_E_TARGETPARAMCOUNT); + } + + public TargetParameterCountException(String message, Exception inner) + : base(message, inner) { + SetErrorCode(__HResults.COR_E_TARGETPARAMCOUNT); + } + + internal TargetParameterCountException(SerializationInfo info, StreamingContext context) : base (info, context) { + } + } +} diff --git a/src/mscorlib/src/System/Reflection/TypeAttributes.cs b/src/mscorlib/src/System/Reflection/TypeAttributes.cs new file mode 100644 index 0000000000..4fa6fb06ba --- /dev/null +++ b/src/mscorlib/src/System/Reflection/TypeAttributes.cs @@ -0,0 +1,66 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace System.Reflection { + using System.Runtime.InteropServices; + using System; + // This Enum matchs the CorTypeAttr defined in CorHdr.h +[Serializable] +[Flags] +[System.Runtime.InteropServices.ComVisible(true)] + public enum TypeAttributes + { + VisibilityMask = 0x00000007, + NotPublic = 0x00000000, // Class is not public scope. + Public = 0x00000001, // Class is public scope. + NestedPublic = 0x00000002, // Class is nested with public visibility. + NestedPrivate = 0x00000003, // Class is nested with private visibility. + NestedFamily = 0x00000004, // Class is nested with family visibility. + NestedAssembly = 0x00000005, // Class is nested with assembly visibility. + NestedFamANDAssem = 0x00000006, // Class is nested with family and assembly visibility. + NestedFamORAssem = 0x00000007, // Class is nested with family or assembly visibility. + + // Use this mask to retrieve class layout informaiton + // 0 is AutoLayout, 0x2 is SequentialLayout, 4 is ExplicitLayout + LayoutMask = 0x00000018, + AutoLayout = 0x00000000, // Class fields are auto-laid out + SequentialLayout = 0x00000008, // Class fields are laid out sequentially + ExplicitLayout = 0x00000010, // Layout is supplied explicitly + // end layout mask + + // Use this mask to distinguish whether a type declaration is an interface. (Class vs. ValueType done based on whether it subclasses S.ValueType) + ClassSemanticsMask= 0x00000020, + Class = 0x00000000, // Type is a class (or a value type). + Interface = 0x00000020, // Type is an interface. + + // Special semantics in addition to class semantics. + Abstract = 0x00000080, // Class is abstract + Sealed = 0x00000100, // Class is concrete and may not be extended + SpecialName = 0x00000400, // Class name is special. Name describes how. + + // Implementation attributes. + Import = 0x00001000, // Class / interface is imported + Serializable = 0x00002000, // The class is Serializable. + + [ComVisible(false)] + WindowsRuntime = 0x00004000, // Type is a Windows Runtime type. + + // Use tdStringFormatMask to retrieve string information for native interop + StringFormatMask = 0x00030000, + AnsiClass = 0x00000000, // LPTSTR is interpreted as ANSI in this class + UnicodeClass = 0x00010000, // LPTSTR is interpreted as UNICODE + AutoClass = 0x00020000, // LPTSTR is interpreted automatically + CustomFormatClass = 0x00030000, // A non-standard encoding specified by CustomFormatMask + CustomFormatMask = 0x00C00000, // Use this mask to retrieve non-standard encoding information for native interop. The meaning of the values of these 2 bits is unspecified. + + // end string format mask + + BeforeFieldInit = 0x00100000, // Initialize the class any time before first static field access. + + // Flags reserved for runtime use. + ReservedMask = 0x00040800, + RTSpecialName = 0x00000800, // Runtime should check name encoding. + HasSecurity = 0x00040000, // Class has security associate with it. + } +} diff --git a/src/mscorlib/src/System/Reflection/TypeDelegator.cs b/src/mscorlib/src/System/Reflection/TypeDelegator.cs new file mode 100644 index 0000000000..cad4a4295a --- /dev/null +++ b/src/mscorlib/src/System/Reflection/TypeDelegator.cs @@ -0,0 +1,263 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +// TypeDelegator +// +// This class wraps a Type object and delegates all methods to that Type. + +namespace System.Reflection { + + using System; + using System.Runtime.InteropServices; + using System.Diagnostics.Contracts; + using CultureInfo = System.Globalization.CultureInfo; + + [Serializable] +[System.Runtime.InteropServices.ComVisible(true)] + public class TypeDelegator : TypeInfo + { + public override bool IsAssignableFrom(System.Reflection.TypeInfo typeInfo){ + if(typeInfo==null) return false; + return IsAssignableFrom(typeInfo.AsType()); + } + + protected Type typeImpl; + + #if FEATURE_CORECLR + [System.Security.SecuritySafeCritical] // auto-generated + #endif + protected TypeDelegator() {} + + public TypeDelegator(Type delegatingType) { + if (delegatingType == null) + throw new ArgumentNullException("delegatingType"); + Contract.EndContractBlock(); + + typeImpl = delegatingType; + } + + public override Guid GUID { + get {return typeImpl.GUID;} + } + + public override int MetadataToken { get { return typeImpl.MetadataToken; } } + + public override Object InvokeMember(String name,BindingFlags invokeAttr,Binder binder,Object target, + Object[] args,ParameterModifier[] modifiers,CultureInfo culture,String[] namedParameters) + { + return typeImpl.InvokeMember(name,invokeAttr,binder,target,args,modifiers,culture,namedParameters); + } + + public override Module Module { + get {return typeImpl.Module;} + } + + public override Assembly Assembly { + get {return typeImpl.Assembly;} + } + + public override RuntimeTypeHandle TypeHandle { + get{return typeImpl.TypeHandle;} + } + + public override String Name { + get{return typeImpl.Name;} + } + + public override String FullName { + get{return typeImpl.FullName;} + } + + public override String Namespace { + get{return typeImpl.Namespace;} + } + + public override String AssemblyQualifiedName { + get { + return typeImpl.AssemblyQualifiedName; + } + } + + public override Type BaseType { + get{return typeImpl.BaseType;} + } + + protected override ConstructorInfo GetConstructorImpl(BindingFlags bindingAttr,Binder binder, + CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers) + { + return typeImpl.GetConstructor(bindingAttr,binder,callConvention,types,modifiers); + } + +[System.Runtime.InteropServices.ComVisible(true)] + public override ConstructorInfo[] GetConstructors(BindingFlags bindingAttr) + { + return typeImpl.GetConstructors(bindingAttr); + } + + protected override MethodInfo GetMethodImpl(String name,BindingFlags bindingAttr,Binder binder, + CallingConventions callConvention, Type[] types,ParameterModifier[] modifiers) + { + // This is interesting there are two paths into the impl. One that validates + // type as non-null and one where type may be null. + if (types == null) + return typeImpl.GetMethod(name,bindingAttr); + else + return typeImpl.GetMethod(name,bindingAttr,binder,callConvention,types,modifiers); + } + + public override MethodInfo[] GetMethods(BindingFlags bindingAttr) + { + return typeImpl.GetMethods(bindingAttr); + } + + public override FieldInfo GetField(String name, BindingFlags bindingAttr) + { + return typeImpl.GetField(name,bindingAttr); + } + + public override FieldInfo[] GetFields(BindingFlags bindingAttr) + { + return typeImpl.GetFields(bindingAttr); + } + + public override Type GetInterface(String name, bool ignoreCase) + { + return typeImpl.GetInterface(name,ignoreCase); + } + + public override Type[] GetInterfaces() + { + return typeImpl.GetInterfaces(); + } + + public override EventInfo GetEvent(String name,BindingFlags bindingAttr) + { + return typeImpl.GetEvent(name,bindingAttr); + } + + public override EventInfo[] GetEvents() + { + return typeImpl.GetEvents(); + } + + protected override PropertyInfo GetPropertyImpl(String name,BindingFlags bindingAttr,Binder binder, + Type returnType, Type[] types, ParameterModifier[] modifiers) + { + if (returnType == null && types == null) + return typeImpl.GetProperty(name,bindingAttr); + else + return typeImpl.GetProperty(name,bindingAttr,binder,returnType,types,modifiers); + } + + public override PropertyInfo[] GetProperties(BindingFlags bindingAttr) + { + return typeImpl.GetProperties(bindingAttr); + } + + public override EventInfo[] GetEvents(BindingFlags bindingAttr) + { + return typeImpl.GetEvents(bindingAttr); + } + + public override Type[] GetNestedTypes(BindingFlags bindingAttr) + { + return typeImpl.GetNestedTypes(bindingAttr); + } + + public override Type GetNestedType(String name, BindingFlags bindingAttr) + { + return typeImpl.GetNestedType(name,bindingAttr); + } + + public override MemberInfo[] GetMember(String name, MemberTypes type, BindingFlags bindingAttr) + { + return typeImpl.GetMember(name,type,bindingAttr); + } + + public override MemberInfo[] GetMembers(BindingFlags bindingAttr) + { + return typeImpl.GetMembers(bindingAttr); + } + + protected override TypeAttributes GetAttributeFlagsImpl() + { + return typeImpl.Attributes; + } + + protected override bool IsArrayImpl() + { + return typeImpl.IsArray; + } + + protected override bool IsPrimitiveImpl() + { + return typeImpl.IsPrimitive; + } + + protected override bool IsByRefImpl() + { + return typeImpl.IsByRef; + } + + protected override bool IsPointerImpl() + { + return typeImpl.IsPointer; + } + + protected override bool IsValueTypeImpl() + { + return typeImpl.IsValueType; + } + + protected override bool IsCOMObjectImpl() + { + return typeImpl.IsCOMObject; + } + + public override bool IsConstructedGenericType + { + get + { + return typeImpl.IsConstructedGenericType; + } + } + + public override Type GetElementType() + { + return typeImpl.GetElementType(); + } + + protected override bool HasElementTypeImpl() + { + return typeImpl.HasElementType; + } + + public override Type UnderlyingSystemType + { + get {return typeImpl.UnderlyingSystemType;} + } + + // ICustomAttributeProvider + public override Object[] GetCustomAttributes(bool inherit) + { + return typeImpl.GetCustomAttributes(inherit); + } + + public override Object[] GetCustomAttributes(Type attributeType, bool inherit) + { + return typeImpl.GetCustomAttributes(attributeType, inherit); + } + + public override bool IsDefined(Type attributeType, bool inherit) + { + return typeImpl.IsDefined(attributeType, inherit); + } + +[System.Runtime.InteropServices.ComVisible(true)] + public override InterfaceMapping GetInterfaceMap(Type interfaceType) + { + return typeImpl.GetInterfaceMap(interfaceType); + } + } +} diff --git a/src/mscorlib/src/System/Reflection/TypeFilter.cs b/src/mscorlib/src/System/Reflection/TypeFilter.cs new file mode 100644 index 0000000000..560618ff79 --- /dev/null +++ b/src/mscorlib/src/System/Reflection/TypeFilter.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// TypeFilter defines a delegate that is as a callback function for filtering +// +// a list of Types. +// +// +namespace System.Reflection { + + // Define the delegate + [Serializable] + [System.Runtime.InteropServices.ComVisible(true)] + public delegate bool TypeFilter(Type m, Object filterCriteria); +} diff --git a/src/mscorlib/src/System/Reflection/TypeInfo.cs b/src/mscorlib/src/System/Reflection/TypeInfo.cs new file mode 100644 index 0000000000..706fb0a61a --- /dev/null +++ b/src/mscorlib/src/System/Reflection/TypeInfo.cs @@ -0,0 +1,195 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +/*============================================================================= +** +** +** +** +** +** Purpose: Notion of a type definition +** +** +=============================================================================*/ + +namespace System.Reflection +{ + using System; + using System.Runtime.CompilerServices; + using System.Collections.Generic; + using System.Diagnostics.Contracts; + + //all today's runtime Type derivations derive now from TypeInfo + //we make TypeInfo implement IRCT - simplifies work + [System.Runtime.InteropServices.ComVisible(true)] + [Serializable] + public abstract class TypeInfo:Type,IReflectableType + { + [FriendAccessAllowed] + internal TypeInfo() { } + + TypeInfo IReflectableType.GetTypeInfo(){ + return this; + } + public virtual Type AsType(){ + return (Type)this; + } + + public virtual Type[] GenericTypeParameters{ + get{ + if(IsGenericTypeDefinition){ + return GetGenericArguments(); + } + else{ + return Type.EmptyTypes; + } + + } + } + //a re-implementation of ISAF from Type, skipping the use of UnderlyingType + [Pure] + public virtual bool IsAssignableFrom(TypeInfo typeInfo) + { + if (typeInfo == null) + return false; + + if (this == typeInfo) + return true; + + // If c is a subclass of this class, then c can be cast to this type. + if (typeInfo.IsSubclassOf(this)) + return true; + + if (this.IsInterface) + { + return typeInfo.ImplementInterface(this); + } + else if (IsGenericParameter) + { + Type[] constraints = GetGenericParameterConstraints(); + for (int i = 0; i < constraints.Length; i++) + if (!constraints[i].IsAssignableFrom(typeInfo)) + return false; + + return true; + } + + return false; + } +#region moved over from Type + // Fields + + public virtual EventInfo GetDeclaredEvent(String name) + { + return GetEvent(name, Type.DeclaredOnlyLookup); + } + public virtual FieldInfo GetDeclaredField(String name) + { + return GetField(name, Type.DeclaredOnlyLookup); + } + public virtual MethodInfo GetDeclaredMethod(String name) + { + return GetMethod(name, Type.DeclaredOnlyLookup); + } + + public virtual IEnumerable GetDeclaredMethods(String name) + { + foreach (MethodInfo method in GetMethods(Type.DeclaredOnlyLookup)) + { + if (method.Name == name) + yield return method; + } + } + public virtual System.Reflection.TypeInfo GetDeclaredNestedType(String name) + { + var nt=GetNestedType(name, Type.DeclaredOnlyLookup); + if(nt == null){ + return null; //the extension method GetTypeInfo throws for null + }else{ + return nt.GetTypeInfo(); + } + } + public virtual PropertyInfo GetDeclaredProperty(String name) + { + return GetProperty(name, Type.DeclaredOnlyLookup); + } + + + + + + // Properties + + public virtual IEnumerable DeclaredConstructors + { + get + { + return GetConstructors(Type.DeclaredOnlyLookup); + } + } + + public virtual IEnumerable DeclaredEvents + { + get + { + return GetEvents(Type.DeclaredOnlyLookup); + } + } + + public virtual IEnumerable DeclaredFields + { + get + { + return GetFields(Type.DeclaredOnlyLookup); + } + } + + public virtual IEnumerable DeclaredMembers + { + get + { + return GetMembers(Type.DeclaredOnlyLookup); + } + } + + public virtual IEnumerable DeclaredMethods + { + get + { + return GetMethods(Type.DeclaredOnlyLookup); + } + } + public virtual IEnumerable DeclaredNestedTypes + { + get + { + foreach (var t in GetNestedTypes(Type.DeclaredOnlyLookup)){ + yield return t.GetTypeInfo(); + } + } + } + + public virtual IEnumerable DeclaredProperties + { + get + { + return GetProperties(Type.DeclaredOnlyLookup); + } + } + + + public virtual IEnumerable ImplementedInterfaces + { + get + { + return GetInterfaces(); + } + } + + +#endregion + + } +} + diff --git a/src/mscorlib/src/System/Reflection/__Filters.cs b/src/mscorlib/src/System/Reflection/__Filters.cs new file mode 100644 index 0000000000..8edcd0d7cb --- /dev/null +++ b/src/mscorlib/src/System/Reflection/__Filters.cs @@ -0,0 +1,67 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// +// +// +// This class defines the delegate methods for the COM+ implemented filters. +// This is the reflection version of these. There is also a _Filters class in +// runtime which is related to this. +// +// +// +// +namespace System.Reflection { + using System; + using System.Globalization; + + [Serializable] + internal class __Filters { + + // FilterTypeName + // This method will filter the class based upon the name. It supports + // a trailing wild card. + public virtual bool FilterTypeName(Type cls,Object filterCriteria) + { + // Check that the criteria object is a String object + if (filterCriteria == null || !(filterCriteria is String)) + throw new InvalidFilterCriteriaException(System.Environment.GetResourceString("RFLCT.FltCritString")); + + String str = (String) filterCriteria; + //str = str.Trim(); + + // Check to see if this is a prefix or exact match requirement + if (str.Length > 0 && str[str.Length - 1] == '*') { + str = str.Substring(0, str.Length - 1); + return cls.Name.StartsWith(str, StringComparison.Ordinal); + } + + return cls.Name.Equals(str); + } + + // FilterFieldNameIgnoreCase + // This method filter the Type based upon name, it ignores case. + public virtual bool FilterTypeNameIgnoreCase(Type cls, Object filterCriteria) + { + // Check that the criteria object is a String object + if(filterCriteria == null || !(filterCriteria is String)) + throw new InvalidFilterCriteriaException(System.Environment.GetResourceString("RFLCT.FltCritString")); + + String str = (String) filterCriteria; + //str = str.Trim(); + + // Check to see if this is a prefix or exact match requirement + if (str.Length > 0 && str[str.Length - 1] == '*') { + str = str.Substring(0, str.Length - 1); + String name = cls.Name; + if (name.Length >= str.Length) + return (String.Compare(name,0,str,0,str.Length, StringComparison.OrdinalIgnoreCase)==0); + else + return false; + } + return (String.Compare(str,cls.Name, StringComparison.OrdinalIgnoreCase) == 0); + } + } +} -- cgit v1.2.3