Merge remote-tracking branch 'dotnet/master' into merge-master-nullable
authorSantiago Fernandez Madero <safern@microsoft.com>
Thu, 11 Apr 2019 22:45:02 +0000 (15:45 -0700)
committerSantiago Fernandez Madero <safern@microsoft.com>
Thu, 11 Apr 2019 22:45:02 +0000 (15:45 -0700)
14 files changed:
1  2 
src/System.Private.CoreLib/shared/System/Activator.RuntimeType.cs
src/System.Private.CoreLib/shared/System/Environment.Win32.cs
src/System.Private.CoreLib/shared/System/Environment.WinRT.cs
src/System.Private.CoreLib/shared/System/Range.cs
src/System.Private.CoreLib/shared/System/Reflection/AssemblyName.cs
src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeHelpers.cs
src/System.Private.CoreLib/shared/System/Runtime/Loader/AssemblyLoadContext.cs
src/System.Private.CoreLib/shared/System/Threading/TimerQueue.Windows.cs
src/System.Private.CoreLib/src/System/Environment.CoreCLR.cs
src/System.Private.CoreLib/src/System/GC.cs
src/System.Private.CoreLib/src/System/Reflection/Assembly.CoreCLR.cs
src/System.Private.CoreLib/src/System/Reflection/AssemblyName.CoreCLR.cs
src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs
src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs

@@@ -2,9 -2,9 +2,10 @@@
  // The .NET Foundation licenses this file to you under the MIT license.
  // See the LICENSE file in the project root for more information.
  
 +#nullable enable
  using System.Reflection;
  using System.Globalization;
+ using System.Runtime.Loader;
  using System.Runtime.Remoting;
  using System.Threading;
  
@@@ -15,7 -14,9 +15,9 @@@ namespace Syste
  {
      public static partial class Environment
      {
 -        private static string GetEnvironmentVariableFromRegistry(string variable, bool fromMachine)
+         internal static bool IsWindows8OrAbove => WindowsVersion.IsWindows8OrAbove;
 +        private static string? GetEnvironmentVariableFromRegistry(string variable, bool fromMachine)
          {
              Debug.Assert(variable != null);
  
@@@ -2,10 -2,8 +2,9 @@@
  // The .NET Foundation licenses this file to you under the MIT license.
  // See the LICENSE file in the project root for more information.
  
 +#nullable enable
  using System.Configuration.Assemblies;
  using System.IO;
- using System.Runtime.CompilerServices;
  using System.Runtime.Serialization;
  using System.Text;
  using CultureInfo = System.Globalization.CultureInfo;
@@@ -171,17 -158,10 +159,10 @@@ namespace System.Reflectio
              if (assemblyFile == null)
                  throw new ArgumentNullException(nameof(assemblyFile));
  
-             // Assembly.GetNameInternal() will not demand path discovery 
-             //  permission, so do that first.
-             string fullPath = Path.GetFullPath(assemblyFile);
-             return nGetFileInformation(fullPath);
+             return GetFileInformationCore(assemblyFile);
          }
  
-         // 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()
 +        public byte[]? GetPublicKey()
          {
              return _publicKey;
          }
              return refName.Equals(defName, StringComparison.OrdinalIgnoreCase);
          }
  
-         [MethodImplAttribute(MethodImplOptions.InternalCall)]
-         internal extern void nInit(out RuntimeAssembly? assembly, bool raiseResolveEvent);
-         internal void nInit()
-         {
-             RuntimeAssembly? dummy = null;
-             nInit(out dummy, 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, 0, _publicKey, 0, publicKey.Length);
-             }
-             if (publicKeyToken != null)
-             {
-                 _publicKeyToken = new byte[publicKeyToken.Length];
-                 Array.Copy(publicKeyToken, 0, _publicKeyToken, 0, publicKeyToken.Length);
-             }
-             if (version != null)
-                 _version = (Version)version.Clone();
-             _cultureInfo = cultureInfo;
-             _hashAlgorithm = hashAlgorithm;
-             _versionCompatibility = versionCompatibility;
-             _codeBase = codeBase;
-             _flags = flags;
-             _strongNameKeyPair = keyPair;
-         }
-         // This call opens and closes the file, but does not add the
-         // assembly to the domain.
-         [MethodImplAttribute(MethodImplOptions.InternalCall)]
-         internal static extern AssemblyName nGetFileInformation(string s);
-         [MethodImplAttribute(MethodImplOptions.InternalCall)]
-         private extern byte[] nGetPublicKeyToken();
 -        internal static string EscapeCodeBase(string codebase)
 +        internal static string EscapeCodeBase(string? codebase)
          {
              if (codebase == null)
                  return string.Empty;
@@@ -2,19 -2,19 +2,20 @@@
  // The .NET Foundation licenses this file to you under the MIT license.
  // See the LICENSE file in the project root for more information.
  
 +#nullable enable
  using System.Runtime.Serialization;
+ using Internal.Runtime.CompilerServices;
  
  namespace System.Runtime.CompilerServices
  {
      public static partial class RuntimeHelpers
      {
 -        public delegate void TryCode(object userData);
 +        public delegate void TryCode(object? userData);
  
 -        public delegate void CleanupCode(object userData, bool exceptionThrown);
 +        public delegate void CleanupCode(object? userData, bool exceptionThrown);
  
          /// <summary>
-         /// GetSubArray helper method for the compiler to slice an array using a range.
+         /// Slices the specified array using the specified range.
          /// </summary>
          public static T[] GetSubArray<T>(T[] array, Range range)
          {
@@@ -2,8 -2,8 +2,9 @@@
  // The .NET Foundation licenses this file to you under the MIT license.
  // See the LICENSE file in the project root for more information.
  
 +#nullable enable
  using System.Collections.Generic;
+ using System.ComponentModel;
  using System.Diagnostics;
  using System.IO;
  using System.Reflection;
@@@ -41,6 -39,14 +40,14 @@@ namespace System.Runtime.Loade
          // synchronization primitive to protect against usage of this instance while unloading
          private readonly object _unloadLock;
  
 -        private readonly string _name;
+         private event Func<Assembly, string, IntPtr> _resolvingUnmanagedDll;
+         private event Func<AssemblyLoadContext, AssemblyName, Assembly> _resolving;
+         private event Action<AssemblyLoadContext> _unloading;
++        private readonly string? _name;
          // Contains the reference to VM's representation of the AssemblyLoadContext
          private readonly IntPtr _nativeAssemblyLoadContext;
  
          {
          }
  
 -        private protected AssemblyLoadContext(bool representsTPALoadContext, bool isCollectible, string name)
 +        private protected AssemblyLoadContext(bool representsTPALoadContext, bool isCollectible, string? name)
          {
              // Initialize the VM side of AssemblyLoadContext if not already done.
-             IsCollectible = isCollectible;
+             _isCollectible = isCollectible;
  
-             Name = name;
+             _name = name;
  
              // The _unloadLock needs to be assigned after the IsCollectible to ensure proper behavior of the finalizer
              // even in case the following allocation fails or the thread is aborted between these two lines.
          private void RaiseUnloadEvent()
          {
              // Ensure that we raise the Unload event only once
-             Interlocked.Exchange(ref Unloading, null!)?.Invoke(this); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
 -            Interlocked.Exchange(ref _unloading, null)?.Invoke(this);
++            Interlocked.Exchange(ref _unloading, null!)?.Invoke(this); // TODO-NULLABLE: https://github.com/dotnet/roslyn/issues/26761
          }
  
          private void InitiateUnload()
  
          public static AssemblyLoadContext Default => DefaultAssemblyLoadContext.s_loadContext;
  
-         public bool IsCollectible { get; }
+         public bool IsCollectible { get { return _isCollectible;} }
  
-         public string? Name { get; }
 -        public string Name { get { return _name;} }
++        public string? Name { get { return _name;} }
  
          public override string ToString() => "\"" + Name + "\" " + GetType().ToString() + " #" + _id;
  
index 0000000,0bd0cc4..923add5
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,40 +1,41 @@@
 -                        Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error());
+ // 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.
++#nullable enable
+ using System.Runtime.InteropServices;
+ namespace System.Threading
+ {
+     internal partial class TimerQueue
+     {
+         private static int TickCount
+         {
+             get
+             {
+                 // We need to keep our notion of time synchronized with the calls to SleepEx that drive
+                 // the underlying native timer.  In Win8, SleepEx does not count the time the machine spends
+                 // sleeping/hibernating.  Environment.TickCount (GetTickCount) *does* count that time,
+                 // so we will get out of sync with SleepEx if we use that method.
+                 //
+                 // So, on Win8, we use QueryUnbiasedInterruptTime instead; this does not count time spent
+                 // in sleep/hibernate mode.
+                 if (Environment.IsWindows8OrAbove)
+                 {
+                     ulong time100ns;
+                     bool result = Interop.Kernel32.QueryUnbiasedInterruptTime(out time100ns);
+                     if (!result)
++                        Marshal.ThrowExceptionForHR(Marshal.GetLastWin32Error())!;
+                     // convert to 100ns to milliseconds, and truncate to 32 bits.
+                     return (int)(uint)(time100ns / 10000);
+                 }
+                 else
+                 {
+                     return Environment.TickCount;
+                 }
+             }
+         }
+     }
+ }
@@@ -35,9 -38,9 +35,9 @@@ namespace System.Reflectio
  
          // Locate an assembly by its name. The name can be strong or
          // weak. The assembly is loaded into the domain of the caller.
-         internal static Assembly Load(AssemblyName assemblyRef, ref StackCrawlMark stackMark, IntPtr ptrLoadContextBinder)
+         internal static Assembly Load(AssemblyName assemblyRef, ref StackCrawlMark stackMark, AssemblyLoadContext assemblyLoadContext)
          {
 -            AssemblyName modifiedAssemblyRef = null;
 +            AssemblyName? modifiedAssemblyRef = null;
              if (assemblyRef.CodeBase != null)
              {
                  modifiedAssemblyRef = (AssemblyName)assemblyRef.Clone();
index 0000000,1f1c6f0..7b6e5b9
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,111 +1,112 @@@
 -        internal AssemblyName(string name,
 -            byte[] publicKey,
 -            byte[] publicKeyToken,
 -            Version version,
 -            CultureInfo cultureInfo,
+ // 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.
++#nullable enable
+ using System.Configuration.Assemblies;
+ using System.Globalization;
+ using System.IO;
+ using System.Runtime.CompilerServices;
+ using System.Runtime.Serialization;
+ namespace System.Reflection
+ {
+     public sealed partial class AssemblyName : ICloneable, IDeserializationCallback, ISerializable
+     {
+         public AssemblyName(string assemblyName)
+         {
+             if (assemblyName == null)
+                 throw new ArgumentNullException(nameof(assemblyName));
+             if ((assemblyName.Length == 0) ||
+                 (assemblyName[0] == '\0'))
+                 throw new ArgumentException(SR.Format_StringZeroLength);
+             _name = assemblyName;
+             nInit(out RuntimeAssembly dummy, false);
+         }
 -            string codeBase,
++        internal AssemblyName(string? name,
++            byte[]? publicKey,
++            byte[]? publicKeyToken,
++            Version? version,
++            CultureInfo? cultureInfo,
+             AssemblyHashAlgorithm hashAlgorithm,
+             AssemblyVersionCompatibility versionCompatibility,
 -            StrongNameKeyPair keyPair) // Null if ref, matching Assembly if def
++            string? codeBase,
+             AssemblyNameFlags flags,
 -        internal extern void nInit(out RuntimeAssembly assembly, bool raiseResolveEvent);
++            StrongNameKeyPair? keyPair) // Null if ref, matching Assembly if def
+         {
+             _name = name;
+             _publicKey = publicKey;
+             _publicKeyToken = publicKeyToken;
+             _version = version;
+             _cultureInfo = cultureInfo;
+             _hashAlgorithm = hashAlgorithm;
+             _versionCompatibility = versionCompatibility;
+             _codeBase = codeBase;
+             _flags = flags;
+             _strongNameKeyPair = keyPair;
+         }
+         [MethodImpl(MethodImplOptions.InternalCall)]
++        internal extern void nInit(out RuntimeAssembly? assembly, bool raiseResolveEvent);
+         
+         // This call opens and closes the file, but does not add the
+         // assembly to the domain.
+         [MethodImpl(MethodImplOptions.InternalCall)]
+         internal static extern AssemblyName nGetFileInformation(string s);
+         internal static AssemblyName GetFileInformationCore(string assemblyFile)
+         {
+             string fullPath = Path.GetFullPath(assemblyFile);
+             return nGetFileInformation(fullPath);
+         }
+         [MethodImpl(MethodImplOptions.InternalCall)]
+         private extern byte[] ComputePublicKeyToken();
+         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 & PortableExecutableKinds.PE32Plus) == PortableExecutableKinds.PE32Plus)
+             {
+                 switch (ifm)
+                 {
+                     case ImageFileMachine.IA64:
+                         return ProcessorArchitecture.IA64;
+                     case ImageFileMachine.AMD64:
+                         return ProcessorArchitecture.Amd64;
+                     case ImageFileMachine.I386:
+                         if ((pek & PortableExecutableKinds.ILOnly) == PortableExecutableKinds.ILOnly)
+                             return ProcessorArchitecture.MSIL;
+                         break;
+                 }
+             }
+             else
+             {
+                 if (ifm == ImageFileMachine.I386)
+                 {
+                     if ((pek & PortableExecutableKinds.Required32Bit) == PortableExecutableKinds.Required32Bit)
+                         return ProcessorArchitecture.X86;
+                     if ((pek & PortableExecutableKinds.ILOnly) == PortableExecutableKinds.ILOnly)
+                         return ProcessorArchitecture.MSIL;
+                     return ProcessorArchitecture.X86;
+                 }
+                 if (ifm == ImageFileMachine.ARM)
+                 {
+                     return ProcessorArchitecture.Arm;
+                 }
+             }
+             return ProcessorArchitecture.None;
+         }
+     }
+ }
@@@ -6,9 -5,12 +6,10 @@@
  using System.Collections.Generic;
  using System.Diagnostics;
  using CultureInfo = System.Globalization.CultureInfo;
 -using System.Security;
  using System.IO;
 -using StringBuilder = System.Text.StringBuilder;
  using System.Configuration.Assemblies;
  using StackCrawlMark = System.Threading.StackCrawlMark;
+ using System.Runtime.Loader;
  using System.Runtime.InteropServices;
  using System.Runtime.CompilerServices;
  using System.Runtime.Serialization;
@@@ -85,11 -87,9 +86,9 @@@ namespace System.Reflectio
          // is returned.
          public override AssemblyName GetName(bool copiedName)
          {
-             AssemblyName an = new AssemblyName();
 -            string codeBase = GetCodeBase(copiedName);
 +            string? codeBase = GetCodeBase(copiedName);
  
-             an.Init(GetSimpleName(),
+             var an = new AssemblyName(GetSimpleName(),
                      GetPublicKey(),
                      null, // public key token
                      GetVersion(),
  
          [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
          private static extern void GetType(RuntimeAssembly assembly,
-                                                         string name,
-                                                         bool throwOnError,
-                                                         bool ignoreCase,
-                                                         ObjectHandleOnStack type,
-                                                         ObjectHandleOnStack keepAlive);
+                                             string name,
+                                             bool throwOnError,
+                                             bool ignoreCase,
+                                             ObjectHandleOnStack type,
+                                             ObjectHandleOnStack keepAlive,
+                                             ObjectHandleOnStack assemblyLoadContext);
  
 -        public override Type GetType(string name, bool throwOnError, bool ignoreCase)
 +        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(nameof(name));
  
 -            RuntimeType type = null;
 -            object keepAlive = null;
 +            RuntimeType? type = null;
 +            object? keepAlive = null;
-             GetType(GetNativeHandle(), name, throwOnError, ignoreCase, JitHelpers.GetObjectHandleOnStack(ref type), JitHelpers.GetObjectHandleOnStack(ref keepAlive));
+             AssemblyLoadContext assemblyLoadContextStack = AssemblyLoadContext.CurrentContextualReflectionContext;
+             GetType(GetNativeHandle(),
+                     name,
+                     throwOnError,
+                     ignoreCase,
+                     JitHelpers.GetObjectHandleOnStack(ref type),
+                     JitHelpers.GetObjectHandleOnStack(ref keepAlive),
+                     JitHelpers.GetObjectHandleOnStack(ref assemblyLoadContextStack));
              GC.KeepAlive(keepAlive);
  
              return type;
              return CustomAttributeData.GetCustomAttributesInternal(this);
          }
  
-         internal static RuntimeAssembly InternalLoad(string assemblyString, ref StackCrawlMark stackMark)
+         internal static RuntimeAssembly InternalLoad(string assemblyString, ref StackCrawlMark stackMark, AssemblyLoadContext assemblyLoadContext = null)
          {
 -            RuntimeAssembly assembly;
 +            RuntimeAssembly? assembly;
              AssemblyName an = CreateAssemblyName(assemblyString, out assembly);
  
              if (assembly != null)
                  assemblyRef.ProcessorArchitecture = ProcessorArchitecture.None;
              }
  
 -            string codeBase = VerifyCodeBase(assemblyRef.CodeBase);
 +            string? codeBase = VerifyCodeBase(assemblyRef.CodeBase);
  
-             return nLoad(assemblyRef, codeBase, null, ref stackMark, true, ptrLoadContextBinder);
+             return nLoad(assemblyRef, codeBase, null, ref stackMark, true, assemblyLoadContext);
          }
  
          [MethodImplAttribute(MethodImplOptions.InternalCall)]
          private static extern RuntimeAssembly nLoad(AssemblyName fileName,
 -                                                    string codeBase,
 -                                                    RuntimeAssembly assemblyContext,
 +                                                    string? codeBase,
 +                                                    RuntimeAssembly? assemblyContext,
                                                      ref StackCrawlMark stackMark,
                                                      bool throwOnFileNotFound,
-                                                     IntPtr ptrLoadContextBinder);
+                                                     AssemblyLoadContext assemblyLoadContext = null);
  
          public override bool ReflectionOnly
          {
              // This stack crawl mark is never used because the requesting assembly is explicitly specified,
              // so the value could be anything.
              StackCrawlMark unused = default;
-             RuntimeAssembly? retAssembly = nLoad(an, null, this, ref unused, throwOnFileNotFound, IntPtr.Zero);
 -            RuntimeAssembly retAssembly = nLoad(an, null, this, ref unused, throwOnFileNotFound);
++            RuntimeAssembly? retAssembly = nLoad(an, null, this, ref unused, throwOnFileNotFound);
  
              if (retAssembly == this)
              {
@@@ -101,11 -100,11 +101,11 @@@ namespace System.Runtime.Loade
              return context.ResolveUsingEvent(assemblyName);
          }
  
 -        private Assembly GetFirstResolvedAssembly(AssemblyName assemblyName)
 +        private Assembly? GetFirstResolvedAssembly(AssemblyName assemblyName)
          {
 -            Assembly resolvedAssembly = null;
 +            Assembly? resolvedAssembly = null;
  
-             Func<AssemblyLoadContext, AssemblyName, Assembly> assemblyResolveHandler = Resolving;
+             Func<AssemblyLoadContext, AssemblyName, Assembly> assemblyResolveHandler = _resolving;
  
              if (assemblyResolveHandler != null)
              {