Skip to content

Commit

Permalink
Switch CoreLib over to using shared Environment from corefx (dotnet/c…
Browse files Browse the repository at this point in the history
…oreclr#22106)

This requires merging/adapting the implementation with EnvironmentAugments (which goes away completely), the shared files, what corert has, etc.

Commit migrated from dotnet/coreclr@91e1ffc
  • Loading branch information
stephentoub authored Jan 30, 2019
1 parent 0acfc90 commit d4aaf64
Show file tree
Hide file tree
Showing 18 changed files with 692 additions and 910 deletions.
9 changes: 9 additions & 0 deletions src/coreclr/src/System.Private.CoreLib/Resources/Strings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -496,6 +496,9 @@
<data name="Arg_MustBeDouble" xml:space="preserve">
<value>Object must be of type Double.</value>
</data>
<data name="Arg_MustBeDriveLetterOrRootDir" xml:space="preserve">
<value>Drive name must be a root directory (i.e. 'C:\') or a drive letter ('C').</value>
</data>
<data name="Arg_MustBeEnum" xml:space="preserve">
<value>Type provided must be an Enum.</value>
</data>
Expand Down Expand Up @@ -2464,6 +2467,9 @@
<data name="InvalidOperation_CollectionCorrupted" xml:space="preserve">
<value>A prior operation on this collection was interrupted by an exception. Collection's state is no longer trusted.</value>
</data>
<data name="InvalidOperation_ComputerName" xml:space="preserve">
<value>Computer name could not be obtained.</value>
</data>
<data name="InvalidOperation_ConcurrentOperationsNotSupported" xml:space="preserve">
<value>Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.</value>
</data>
Expand Down Expand Up @@ -3190,6 +3196,9 @@
<data name="PreconditionFailed_Cnd" xml:space="preserve">
<value>Precondition failed: {0}</value>
</data>
<data name="PersistedFiles_NoHomeDirectory" xml:space="preserve">
<value>The home directory of the current user could not be determined.</value>
</data>
<data name="Rank_MultiDimNotSupported" xml:space="preserve">
<value>Only single dimension arrays are supported here.</value>
</data>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\SymbolStore\SymAddressKind.cs" />
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\SymbolStore\Token.cs" />
<Compile Include="$(BclSourcesRoot)\System\Enum.cs" />
<Compile Include="$(BclSourcesRoot)\System\Environment.cs" />
<Compile Include="$(BclSourcesRoot)\System\Environment.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Exception.cs" />
<Compile Include="$(BclSourcesRoot)\System\GC.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\GlobalizationMode.cs" />
Expand Down Expand Up @@ -371,7 +371,6 @@
<Compile Include="$(BclSourcesRoot)\System\ApplicationModel.Windows.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\GlobalizationMode.Windows.cs" />
<Compile Include="$(BclSourcesRoot)\System\Threading\ClrThreadPoolBoundHandle.Windows.cs" />
<Compile Include="$(BclSourcesRoot)\System\Environment.Windows.cs" />
</ItemGroup>
<ItemGroup>
<!--
Expand Down Expand Up @@ -444,4 +443,4 @@
</ItemGroup>
<Import Project="ILLink.targets" />
<Import Project="GenerateCompilerResponseFile.targets" />
</Project>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
// See the LICENSE file in the project root for more information.

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;

namespace Internal.Runtime.Augments
{
/// <summary>For internal use only. Exposes runtime functionality to the Environments implementation in corefx.</summary>
// TODO: Delete this file once corefx has consumed https://github.com/dotnet/coreclr/pull/22106
// and its corresponding mirrored build from corert, and then the resulting corefx builds
// have been consumed back here, such that the CI tests which currently expect to find
// EnvironmentAugments have been updated to no longer need it.

public static class EnvironmentAugments
{
public static int CurrentManagedThreadId => Environment.CurrentManagedThreadId;
Expand All @@ -21,20 +24,25 @@ public static class EnvironmentAugments
public static int TickCount => Environment.TickCount;
public static string GetEnvironmentVariable(string variable) => Environment.GetEnvironmentVariable(variable);
public static string GetEnvironmentVariable(string variable, EnvironmentVariableTarget target) => Environment.GetEnvironmentVariable(variable, target);
public static IEnumerable<KeyValuePair<string, string>> EnumerateEnvironmentVariables() => Environment.EnumerateEnvironmentVariables();
public static IEnumerable<KeyValuePair<string, string>> EnumerateEnvironmentVariables(EnvironmentVariableTarget target) => Environment.EnumerateEnvironmentVariables(target);
public static int ProcessorCount => Environment.ProcessorCount;

public static void SetEnvironmentVariable(string variable, string value) => Environment.SetEnvironmentVariable(variable, value);
public static void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target) => Environment.SetEnvironmentVariable(variable, value, target);

public static string StackTrace
public static IEnumerable<KeyValuePair<string, string>> EnumerateEnvironmentVariables()
{
[MethodImpl(MethodImplOptions.NoInlining)] // Prevent inlining from affecting where the stacktrace starts
get
IDictionaryEnumerator de = Environment.GetEnvironmentVariables().GetEnumerator();
while (de.MoveNext())
{
return new StackTrace(1 /* skip this one frame */, true).ToString(System.Diagnostics.StackTrace.TraceFormat.Normal);
yield return new KeyValuePair<string, string>((string)de.Key, (string)de.Value);
}
}
public static IEnumerable<KeyValuePair<string, string>> EnumerateEnvironmentVariables(EnvironmentVariableTarget target)
{
IDictionaryEnumerator de = Environment.GetEnvironmentVariables(target).GetEnumerator();
while (de.MoveNext())
{
yield return new KeyValuePair<string, string>((string)de.Key, (string)de.Value);
}
}
public static int ProcessorCount => Environment.ProcessorCount;
public static void SetEnvironmentVariable(string variable, string value) => Environment.SetEnvironmentVariable(variable, value);
public static void SetEnvironmentVariable(string variable, string value, EnvironmentVariableTarget target) => Environment.SetEnvironmentVariable(variable, value, target);
public static string StackTrace => Environment.StackTrace; // this will temporarily result in an extra frame in Environment.StackTrace calls
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -154,26 +154,6 @@ internal unsafe struct OSVERSIONINFOEX
[DllImport(Interop.Libraries.Kernel32, SetLastError = true)]
internal static extern IntPtr GetStdHandle(int nStdHandle); // param is NOT a handle, but it returns one!

[DllImport(Interop.Libraries.Kernel32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)]
internal static extern bool SetEnvironmentVariable(string lpName, string lpValue);

[DllImport(Interop.Libraries.Kernel32, CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false)]
private static extern unsafe int GetEnvironmentVariable(string lpName, char* lpValue, int size);

internal static unsafe int GetEnvironmentVariable(string lpName, Span<char> lpValue)
{
fixed (char* lpValuePtr = &MemoryMarshal.GetReference(lpValue))
{
return GetEnvironmentVariable(lpName, lpValuePtr, lpValue.Length);
}
}

[DllImport(Interop.Libraries.Kernel32, CharSet = CharSet.Unicode)]
internal static extern unsafe char* GetEnvironmentStrings();

[DllImport(Interop.Libraries.Kernel32, CharSet = CharSet.Unicode)]
internal static extern unsafe bool FreeEnvironmentStrings(char* pStrings);

[DllImport(Interop.Libraries.Kernel32, CharSet = CharSet.Auto)]
internal static extern int GetCurrentThreadId();

Expand All @@ -189,9 +169,6 @@ internal static unsafe int GetEnvironmentVariable(string lpName, Span<char> lpVa
[DllImport(Interop.Libraries.Ole32)]
internal static extern IntPtr CoTaskMemRealloc(IntPtr pv, UIntPtr cb);

[DllImport(Interop.Libraries.Kernel32, CharSet = CharSet.Unicode, SetLastError = true, BestFitMapping = false)]
internal static extern uint ExpandEnvironmentStringsW(string lpSrc, ref char lpDst, uint nSize);

[DllImport(Interop.Libraries.Kernel32, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool QueryUnbiasedInterruptTime(out ulong UnbiasedTime);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ internal static bool GetBoolValueWithFallbacks(string switchName, string environ
// abstractions where reasonably possible.

Span<char> buffer = stackalloc char[32];

int length = Win32Native.GetEnvironmentVariable(environmentName, buffer);
int length = Interop.Kernel32.GetEnvironmentVariable(environmentName, buffer);
switch (length)
{
case 1:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
// 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.Buffers;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using Microsoft.Win32;

namespace System
{
public static partial class Environment
{
public static int CurrentManagedThreadId => Thread.CurrentThread.ManagedThreadId;

// Terminates this process with the given exit code.
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern void _Exit(int exitCode);

public static void Exit(int exitCode) => _Exit(exitCode);

public static extern int ExitCode
{
[MethodImpl(MethodImplOptions.InternalCall)]
get;
[MethodImpl(MethodImplOptions.InternalCall)]
set;
}

// Note: The CLR's Watson bucketization code looks at the caller of the FCALL method
// to assign blame for crashes. Don't mess with this, such as by making it call
// another managed helper method, unless you consult with some CLR Watson experts.
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void FailFast(string message);

// This overload of FailFast will allow you to specify the exception object
// whose bucket details *could* be used when undergoing the failfast process.
// To be specific:
//
// 1) When invoked from within a managed EH clause (fault/finally/catch),
// if the exception object is preallocated, the runtime will try to find its buckets
// and use them. If the exception object is not preallocated, it will use the bucket
// details contained in the object (if any).
//
// 2) When invoked from outside the managed EH clauses (fault/finally/catch),
// if the exception object is preallocated, the runtime will use the callsite's
// IP for bucketing. If the exception object is not preallocated, it will use the bucket
// details contained in the object (if any).
[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void FailFast(string message, Exception exception);

[MethodImpl(MethodImplOptions.InternalCall)]
public static extern void FailFast(string message, Exception exception, string errorMessage);

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern string[] GetCommandLineArgsNative();

public static string[] GetCommandLineArgs()
{
// There are multiple entry points to a hosted app. The host could
// use ::ExecuteAssembly() or ::CreateDelegate option:
//
// ::ExecuteAssembly() -> In this particular case, the runtime invokes the main
// method based on the arguments set by the host, and we return those arguments
//
// ::CreateDelegate() -> In this particular case, the host is asked to create a
// delegate based on the appDomain, assembly and methodDesc passed to it.
// which the caller uses to invoke the method. In this particular case we do not have
// any information on what arguments would be passed to the delegate.
// So our best bet is to simply use the commandLine that was used to invoke the process.
// in case it is present.

return s_commandLineArgs != null ?
(string[])s_commandLineArgs.Clone() :
GetCommandLineArgsNative();
}

public static extern bool HasShutdownStarted
{
[MethodImpl(MethodImplOptions.InternalCall)]
get;
}

public static int ProcessorCount => GetProcessorCount();

[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
private static extern int GetProcessorCount();

// If you change this method's signature then you must change the code that calls it
// in excep.cpp and probably you will have to visit mscorlib.h to add the new signature
// as well as metasig.h to create the new signature type
internal static string GetResourceStringLocal(string key) => SR.GetResourceString(key);

public static string StackTrace
{
[MethodImpl(MethodImplOptions.NoInlining)] // Prevent inlining from affecting where the stacktrace starts
get => new StackTrace(true).ToString(System.Diagnostics.StackTrace.TraceFormat.Normal);
}

public static extern int TickCount
{
[MethodImpl(MethodImplOptions.InternalCall)]
get;
}

#if !FEATURE_PAL
internal static bool IsWindows8OrAbove => WindowsVersion.IsWindows8OrAbove;

// Seperate type so a .cctor is not created for Enviroment which then would be triggered during startup
private static class WindowsVersion
{
// Cache the value in readonly static that can be optimized out by the JIT
internal readonly static bool IsWindows8OrAbove = GetIsWindows8OrAbove();

private static bool GetIsWindows8OrAbove()
{
ulong conditionMask = Win32Native.VerSetConditionMask(0, Win32Native.VER_MAJORVERSION, Win32Native.VER_GREATER_EQUAL);
conditionMask = Win32Native.VerSetConditionMask(conditionMask, Win32Native.VER_MINORVERSION, Win32Native.VER_GREATER_EQUAL);
conditionMask = Win32Native.VerSetConditionMask(conditionMask, Win32Native.VER_SERVICEPACKMAJOR, Win32Native.VER_GREATER_EQUAL);
conditionMask = Win32Native.VerSetConditionMask(conditionMask, Win32Native.VER_SERVICEPACKMINOR, Win32Native.VER_GREATER_EQUAL);

// Windows 8 version is 6.2
var version = new Win32Native.OSVERSIONINFOEX();
unsafe
{
version.dwOSVersionInfoSize = sizeof(Win32Native.OSVERSIONINFOEX);
}
version.dwMajorVersion = 6;
version.dwMinorVersion = 2;
version.wServicePackMajor = 0;
version.wServicePackMinor = 0;

return Win32Native.VerifyVersionInfoW(ref version,
Win32Native.VER_MAJORVERSION | Win32Native.VER_MINORVERSION | Win32Native.VER_SERVICEPACKMAJOR | Win32Native.VER_SERVICEPACKMINOR,
conditionMask);
}
}
#endif

#if FEATURE_COMINTEROP
// Seperate type so a .cctor is not created for Enviroment which then would be triggered during startup
private static class WinRT
{
// Cache the value in readonly static that can be optimized out by the JIT
public readonly static bool IsSupported = WinRTSupported();
}

// Does the current version of Windows have Windows Runtime suppport?
internal static bool IsWinRTSupported => WinRT.IsSupported;

[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool WinRTSupported();
#endif // FEATURE_COMINTEROP
}
}

This file was deleted.

Loading

0 comments on commit d4aaf64

Please sign in to comment.