summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/System.Private.CoreLib/Common/System/SR.cs17
-rw-r--r--src/System.Private.CoreLib/System.Private.CoreLib.csproj6
-rw-r--r--src/System.Private.CoreLib/shared/Interop/Unix/Interop.Errors.cs4
-rw-r--r--src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetHostName.cs4
-rw-r--r--src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetPid.cs17
-rw-r--r--src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Stat.cs1
-rw-r--r--src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetCurrentProcessId.cs2
-rw-r--r--src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Globalization.cs16
-rw-r--r--src/System.Private.CoreLib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs9
-rw-r--r--src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems14
-rw-r--r--src/System.Private.CoreLib/shared/System/ArgumentOutOfRangeException.cs2
-rw-r--r--src/System.Private.CoreLib/shared/System/Buffer.cs (renamed from src/System.Private.CoreLib/src/System/Buffer.cs)45
-rw-r--r--src/System.Private.CoreLib/shared/System/Collections/ObjectModel/Collection.cs79
-rw-r--r--src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs2
-rw-r--r--src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/StubEnvironment.cs2
-rw-r--r--src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs2
-rw-r--r--src/System.Private.CoreLib/shared/System/Environment.Variables.Windows.cs2
-rw-r--r--src/System.Private.CoreLib/shared/System/Environment.WinRT.cs1
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs4
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Windows.cs8
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/CharUnicodeInfo.cs177
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.cs552
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/CompareOptions.cs20
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/CultureData.Unix.cs41
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/CultureData.Windows.cs82
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/CultureData.cs832
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.Windows.cs8
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.cs585
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs9
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfo.cs1349
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/DateTimeParse.cs4
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/EastAsianLunisolarCalendar.cs2
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs21
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/HebrewCalendar.cs2
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.cs2
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/NumberFormatInfo.cs498
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/NumberStyles.cs57
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/RegionInfo.cs405
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/SortKey.cs149
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/SortVersion.cs24
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/StringInfo.cs231
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/TextElementEnumerator.cs57
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/TextInfo.cs261
-rw-r--r--src/System.Private.CoreLib/shared/System/Globalization/UmAlQuraCalendar.cs2
-rw-r--r--src/System.Private.CoreLib/shared/System/IO/FileStream.Unix.cs5
-rw-r--r--src/System.Private.CoreLib/shared/System/Number.Formatting.cs8
-rw-r--r--src/System.Private.CoreLib/shared/System/Number.NumberToFloatingPointBits.cs3
-rw-r--r--src/System.Private.CoreLib/shared/System/Number.Parsing.cs47
-rw-r--r--src/System.Private.CoreLib/shared/System/Resources/ManifestBasedResourceGroveler.cs23
-rw-r--r--src/System.Private.CoreLib/shared/System/Resources/ResourceManager.cs2
-rw-r--r--src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeHelpers.cs66
-rw-r--r--src/System.Private.CoreLib/shared/System/Security/CryptographicException.cs2
-rw-r--r--src/System.Private.CoreLib/shared/System/Security/SecurityElement.cs18
-rw-r--r--src/System.Private.CoreLib/shared/System/String.cs4
-rw-r--r--src/System.Private.CoreLib/shared/System/Text/ASCIIEncoding.cs1128
-rw-r--r--src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs76
-rw-r--r--src/System.Private.CoreLib/shared/System/Text/DecoderFallback.cs104
-rw-r--r--src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs198
-rw-r--r--src/System.Private.CoreLib/shared/System/Text/EncoderFallback.cs185
-rw-r--r--src/System.Private.CoreLib/shared/System/Text/EncoderNLS.cs167
-rw-r--r--src/System.Private.CoreLib/shared/System/Text/Encoding.Internal.cs1277
-rw-r--r--src/System.Private.CoreLib/shared/System/Text/Encoding.cs50
-rw-r--r--src/System.Private.CoreLib/shared/System/Text/EncodingNLS.cs2
-rw-r--r--src/System.Private.CoreLib/shared/System/Text/ValueStringBuilder.cs17
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs87
-rw-r--r--src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskScheduler.cs21
-rw-r--r--src/System.Private.CoreLib/shared/System/ThrowHelper.cs32
-rw-r--r--src/System.Private.CoreLib/shared/System/Tuple.cs16
-rw-r--r--src/System.Private.CoreLib/shared/System/Type.Enum.cs4
-rw-r--r--src/System.Private.CoreLib/shared/System/ValueTuple.cs36
-rw-r--r--src/System.Private.CoreLib/src/System/Buffer.CoreCLR.cs62
-rw-r--r--src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs4
-rw-r--r--src/System.Private.CoreLib/src/System/Enum.cs6
-rw-r--r--src/System.Private.CoreLib/src/System/GC.cs6
-rw-r--r--src/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs2
-rw-r--r--src/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs35
-rw-r--r--src/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs4
-rw-r--r--src/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs3
-rw-r--r--src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs2
-rw-r--r--src/System.Private.CoreLib/src/System/Reflection/FieldInfo.CoreCLR.cs4
-rw-r--r--src/System.Private.CoreLib/src/System/Reflection/MdImport.cs2
-rw-r--r--src/System.Private.CoreLib/src/System/Reflection/MethodBase.CoreCLR.cs4
-rw-r--r--src/System.Private.CoreLib/src/System/Reflection/RtFieldInfo.cs4
-rw-r--r--src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs2
-rw-r--r--src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs6
-rw-r--r--src/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs8
-rw-r--r--src/System.Private.CoreLib/src/System/RtType.cs54
-rw-r--r--src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs78
-rw-r--r--src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs5
-rw-r--r--src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyDependencyResolver.cs2
-rw-r--r--src/System.Private.CoreLib/src/System/Runtime/Serialization/FormatterServices.cs64
-rw-r--r--src/System.Private.CoreLib/src/System/RuntimeHandles.cs5
-rw-r--r--src/System.Private.CoreLib/src/System/StubHelpers.cs2
-rw-r--r--src/System.Private.CoreLib/src/System/TypeLoadException.cs2
-rw-r--r--src/debug/createdump/createdump.h2
-rw-r--r--src/debug/di/process.cpp46
-rw-r--r--src/debug/di/rspriv.h3
-rw-r--r--src/debug/di/shimcallback.cpp12
-rw-r--r--src/debug/ee/debugger.cpp19
-rw-r--r--src/debug/ee/debugger.h7
-rw-r--r--src/dlls/mscorrc/mscorrc.rc2
-rw-r--r--src/gc/env/gcenv.ee.h1
-rw-r--r--src/gc/gc.cpp13
-rw-r--r--src/gc/gcenv.ee.standalone.inl8
-rw-r--r--src/gc/gceventstatus.h29
-rw-r--r--src/gc/gcinterface.ee.h3
-rw-r--r--src/gc/gcinterface.h10
-rw-r--r--src/inc/CMakeLists.txt1
-rw-r--r--src/inc/MSCOREE.IDL732
-rw-r--r--src/inc/clrconfigvalues.h3
-rw-r--r--src/inc/corhost.h146
-rw-r--r--src/inc/dacvars.h4
-rw-r--r--src/inc/gchost.idl55
-rw-r--r--src/inc/metahost.idl561
-rw-r--r--src/inc/mscoreepriv.h21
-rw-r--r--src/inc/switches.h7
-rw-r--r--src/inc/utilcode.h5
-rw-r--r--src/jit/assertionprop.cpp14
-rw-r--r--src/jit/codegen.h4
-rw-r--r--src/jit/codegenarm64.cpp310
-rw-r--r--src/jit/codegenarmarch.cpp10
-rw-r--r--src/jit/codegencommon.cpp63
-rw-r--r--src/jit/compiler.cpp12
-rw-r--r--src/jit/compiler.h11
-rw-r--r--src/jit/ee_il_dll.cpp2
-rw-r--r--src/jit/emitarm64.cpp5
-rw-r--r--src/jit/gentree.cpp4
-rw-r--r--src/jit/gentree.h4
-rw-r--r--src/jit/hwintrinsicArm64.cpp64
-rw-r--r--src/jit/hwintrinsiccodegenxarch.cpp22
-rw-r--r--src/jit/hwintrinsiclistxarch.h4
-rw-r--r--src/jit/hwintrinsicxarch.cpp19
-rw-r--r--src/jit/jit.h2
-rw-r--r--src/jit/liveness.cpp113
-rw-r--r--src/jit/lsraarm64.cpp3
-rw-r--r--src/jit/register_arg_convention.cpp6
-rw-r--r--src/jit/register_arg_convention.h2
-rw-r--r--src/jit/scopeinfo.cpp20
-rw-r--r--src/jit/simd.cpp32
-rw-r--r--src/jit/ssabuilder.cpp104
-rw-r--r--src/jit/ssabuilder.h16
-rw-r--r--src/jit/ssarenamestate.cpp243
-rw-r--r--src/jit/ssarenamestate.h186
-rw-r--r--src/md/compiler/classfactory.cpp2
-rw-r--r--src/pal/prebuilt/idl/gchost_i.cpp73
-rw-r--r--src/pal/prebuilt/inc/gchost.h166
-rw-r--r--src/pal/prebuilt/inc/metahost.h961
-rw-r--r--src/pal/prebuilt/inc/mscoree.h2241
-rwxr-xr-xsrc/pal/tools/gen-buildsys-clang.sh19
-rw-r--r--src/utilcode/util.cpp15
-rw-r--r--src/vm/ceeload.cpp5
-rw-r--r--src/vm/ceemain.cpp10
-rw-r--r--src/vm/ceemain.h4
-rw-r--r--src/vm/comcallablewrapper.cpp39
-rw-r--r--src/vm/comcallablewrapper.h3
-rw-r--r--src/vm/commtmemberinfomap.cpp62
-rw-r--r--src/vm/corhost.cpp1116
-rw-r--r--src/vm/crossgencompile.cpp4
-rw-r--r--src/vm/dbginterface.h3
-rw-r--r--src/vm/dwbucketmanager.hpp12
-rw-r--r--src/vm/ecalllist.h7
-rw-r--r--src/vm/eeconfig.cpp18
-rw-r--r--src/vm/eeconfig.h13
-rw-r--r--src/vm/eepolicy.cpp14
-rw-r--r--src/vm/eventpipe.cpp1
-rw-r--r--src/vm/eventpipe.h1
-rw-r--r--src/vm/eventpipebuffer.cpp22
-rw-r--r--src/vm/eventpipeconfiguration.cpp1
-rw-r--r--src/vm/eventpipeeventinstance.cpp22
-rw-r--r--src/vm/eventpipeeventinstance.h13
-rw-r--r--src/vm/excep.cpp31
-rw-r--r--src/vm/excep.h2
-rw-r--r--src/vm/fieldmarshaler.cpp127
-rw-r--r--src/vm/fieldmarshaler.h19
-rw-r--r--src/vm/gcenv.ee.cpp47
-rw-r--r--src/vm/gcenv.ee.h15
-rw-r--r--src/vm/hosting.cpp196
-rw-r--r--src/vm/jithelpers.cpp11
-rw-r--r--src/vm/jitinterface.cpp20
-rw-r--r--src/vm/methodtablebuilder.cpp88
-rw-r--r--src/vm/reflectioninvocation.cpp4
-rw-r--r--src/vm/runtimehandles.cpp19
-rw-r--r--src/vm/runtimehandles.h2
-rw-r--r--src/vm/sampleprofiler.h1
-rw-r--r--src/vm/stdinterfaces.cpp1
-rw-r--r--src/vm/stdinterfaces.h11
-rw-r--r--src/vm/stdinterfaces_wrapper.cpp1
-rw-r--r--src/vm/threads.cpp63
-rw-r--r--src/vm/tlbexport.h484
-rw-r--r--src/vm/typeparse.cpp263
-rw-r--r--src/vm/typeparse.h45
-rw-r--r--src/vm/typestring.cpp215
-rw-r--r--src/vm/typestring.h34
-rw-r--r--src/vm/util.hpp4
194 files changed, 6575 insertions, 12491 deletions
diff --git a/src/System.Private.CoreLib/Common/System/SR.cs b/src/System.Private.CoreLib/Common/System/SR.cs
index c94ad7f3b2..eb0713fb9e 100644
--- a/src/System.Private.CoreLib/Common/System/SR.cs
+++ b/src/System.Private.CoreLib/Common/System/SR.cs
@@ -149,13 +149,28 @@ namespace System
}
}
+ internal static string Format(IFormatProvider provider, string resourceFormat, params object[] args)
+ {
+ if (args != null)
+ {
+ if (UsingResourceKeys())
+ {
+ return resourceFormat + ", " + string.Join(", ", args);
+ }
+
+ return string.Format(provider, resourceFormat, args);
+ }
+
+ return resourceFormat;
+ }
+
internal static string Format(string resourceFormat, params object[] args)
{
if (args != null)
{
if (UsingResourceKeys())
{
- return resourceFormat + string.Join(", ", args);
+ return resourceFormat + ", " + string.Join(", ", args);
}
return string.Format(resourceFormat, args);
diff --git a/src/System.Private.CoreLib/System.Private.CoreLib.csproj b/src/System.Private.CoreLib/System.Private.CoreLib.csproj
index 306053300f..384babf674 100644
--- a/src/System.Private.CoreLib/System.Private.CoreLib.csproj
+++ b/src/System.Private.CoreLib/System.Private.CoreLib.csproj
@@ -25,7 +25,7 @@
<CLSCompliant>true</CLSCompliant>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
- <NoWarn>649,1573,1591,0419</NoWarn>
+ <NoWarn>649,1573,1591,0419,BCL0020</NoWarn> <!-- Remove BCL0020 once https://github.com/dotnet/arcade/pull/2158 is available -->
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
<SignAssembly>true</SignAssembly>
<DelaySign>true</DelaySign>
@@ -122,7 +122,7 @@
<Compile Include="$(BclSourcesRoot)\System\Array.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\Attribute.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\BadImageFormatException.CoreCLR.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Buffer.cs" />
+ <Compile Include="$(BclSourcesRoot)\System\Buffer.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\CLRConfig.cs" />
<Compile Include="$(BclSourcesRoot)\System\Collections\EmptyReadOnlyDictionaryInternal.cs" />
<Compile Include="$(BclSourcesRoot)\System\Collections\Generic\ArraySortHelper.CoreCLR.cs" />
@@ -239,7 +239,6 @@
<Compile Include="$(BclSourcesRoot)\System\Runtime\InteropServices\NativeLibrary.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\Loader\AssemblyDependencyResolver.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\Loader\AssemblyLoadContext.CoreCLR.cs" />
- <Compile Include="$(BclSourcesRoot)\System\Runtime\Serialization\FormatterServices.cs" />
<Compile Include="$(BclSourcesRoot)\System\Runtime\Versioning\CompatibilitySwitch.cs" />
<Compile Include="$(BclSourcesRoot)\System\RuntimeArgumentHandle.cs" />
<Compile Include="$(BclSourcesRoot)\System\RuntimeHandles.cs" />
@@ -267,7 +266,6 @@
<Compile Include="$(BclSourcesRoot)\System\ValueType.cs" />
<Compile Include="$(BclSourcesRoot)\System\WeakReference.cs" />
<Compile Include="$(BclSourcesRoot)\System\WeakReferenceOfT.cs" />
- <Compile Include="shared\Interop\Windows\Kernel32\Interop.GetCurrentProcessId.cs" />
<Compile Include="shared\Interop\Windows\Kernel32\Interop.GetStdHandle.cs" />
<Compile Include="shared\Interop\Windows\Kernel32\Interop.LocalAlloc.cs" />
<Compile Include="shared\Interop\Windows\Kernel32\Interop.QueryUnbiasedInterruptTime.cs" />
diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/Interop.Errors.cs b/src/System.Private.CoreLib/shared/Interop/Unix/Interop.Errors.cs
index cfe0d227c8..554d0659ae 100644
--- a/src/System.Private.CoreLib/shared/Interop/Unix/Interop.Errors.cs
+++ b/src/System.Private.CoreLib/shared/Interop/Unix/Interop.Errors.cs
@@ -147,9 +147,7 @@ internal static partial class Interop
public override string ToString()
{
- return string.Format(
- "RawErrno: {0} Error: {1} GetErrorMessage: {2}", // No localization required; text is member names used for debugging purposes
- RawErrno, Error, GetErrorMessage());
+ return $"RawErrno: {RawErrno} Error: {Error} GetErrorMessage: {GetErrorMessage()}"; // No localization required; text is member names used for debugging purposes
}
}
diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetHostName.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetHostName.cs
index 3858b495a1..1ecade65ee 100644
--- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetHostName.cs
+++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetHostName.cs
@@ -27,8 +27,8 @@ internal static partial class Interop
// which should only happen if the buffer we supply isn't big
// enough, and we're using a buffer size that the man page
// says is the max for POSIX (and larger than the max for Linux).
- Debug.Fail("gethostname failed");
- throw new InvalidOperationException(string.Format("gethostname returned {0}", err));
+ Debug.Fail($"GetHostName failed with error {err}");
+ throw new InvalidOperationException($"{nameof(GetHostName)}: {err}");
}
// If the hostname is truncated, it is unspecified whether the returned buffer includes a terminating null byte.
diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetPid.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetPid.cs
new file mode 100644
index 0000000000..02d259db7d
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.GetPid.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.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+ internal static partial class Sys
+ {
+ [DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_GetPid")]
+ internal static extern int GetPid();
+ }
+
+ internal static uint GetCurrentProcessId() => (uint)Sys.GetPid();
+}
diff --git a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Stat.cs b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Stat.cs
index 0ca199b70d..cb0f4284f0 100644
--- a/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Stat.cs
+++ b/src/System.Private.CoreLib/shared/Interop/Unix/System.Native/Interop.Stat.cs
@@ -33,6 +33,7 @@ internal static partial class Interop
internal long BirthTimeNsec;
internal long Dev;
internal long Ino;
+ internal uint UserFlags;
}
internal static class FileTypes
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetCurrentProcessId.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetCurrentProcessId.cs
index a042bfeccf..3a1a353d86 100644
--- a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetCurrentProcessId.cs
+++ b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.GetCurrentProcessId.cs
@@ -11,4 +11,6 @@ internal partial class Interop
[DllImport(Libraries.Kernel32)]
internal extern static uint GetCurrentProcessId();
}
+
+ internal static uint GetCurrentProcessId() => Kernel32.GetCurrentProcessId();
}
diff --git a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Globalization.cs b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Globalization.cs
index 644230c7b4..80b52e6ab9 100644
--- a/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Globalization.cs
+++ b/src/System.Private.CoreLib/shared/Interop/Windows/Kernel32/Interop.Globalization.cs
@@ -10,12 +10,28 @@ internal static partial class Interop
internal static unsafe partial class Kernel32
{
internal const uint LOCALE_ALLOW_NEUTRAL_NAMES = 0x08000000; // Flag to allow returning neutral names/lcids for name conversion
+ internal const uint LOCALE_ILANGUAGE = 0x00000001;
internal const uint LOCALE_SUPPLEMENTAL = 0x00000002;
internal const uint LOCALE_REPLACEMENT = 0x00000008;
internal const uint LOCALE_NEUTRALDATA = 0x00000010;
internal const uint LOCALE_SPECIFICDATA = 0x00000020;
+ internal const uint LOCALE_SISO3166CTRYNAME = 0x0000005A;
+ internal const uint LOCALE_SNAME = 0x0000005C;
+ internal const uint LOCALE_INEUTRAL = 0x00000071;
+ internal const uint LOCALE_SSHORTTIME = 0x00000079;
+ internal const uint LOCALE_STIMEFORMAT = 0x00001003;
+ internal const uint LOCALE_IFIRSTDAYOFWEEK = 0x0000100C;
+ internal const uint LOCALE_RETURN_NUMBER = 0x20000000;
+ internal const uint LOCALE_NOUSEROVERRIDE = 0x80000000;
+
internal const int COMPARE_STRING = 0x0001;
+ internal const uint TIME_NOSECONDS = 0x00000002;
+
+ internal const string LOCALE_NAME_USER_DEFAULT = null;
+ internal const string LOCALE_NAME_SYSTEM_DEFAULT = "!x-sys-default-locale";
+
+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
internal static extern unsafe int LCIDToLocaleName(int locale, char *pLocaleName, int cchName, uint dwFlags);
diff --git a/src/System.Private.CoreLib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs b/src/System.Private.CoreLib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
index 52973f2abb..3b5347dba3 100644
--- a/src/System.Private.CoreLib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
+++ b/src/System.Private.CoreLib/shared/Microsoft/Win32/SafeHandles/SafeFileHandle.Unix.cs
@@ -122,14 +122,7 @@ namespace Microsoft.Win32.SafeHandles
// to retry, as the descriptor could actually have been closed, been subsequently reassigned, and
// be in use elsewhere in the process. Instead, we simply check whether the call was successful.
int result = Interop.Sys.Close(handle);
-#if DEBUG
- if (result != 0)
- {
- Debug.Fail(string.Format(
- "Close failed with result {0} and error {1}",
- result, Interop.Sys.GetLastErrorInfo()));
- }
-#endif
+ Debug.Assert(result == 0, $"Close failed with result {result} and error {Interop.Sys.GetLastErrorInfo()}");
return result == 0;
}
diff --git a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
index 3e1fce676a..ce0f102587 100644
--- a/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
+++ b/src/System.Private.CoreLib/shared/System.Private.CoreLib.Shared.projitems
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project>
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
<HasSharedItems>true</HasSharedItems>
@@ -55,6 +54,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\BadImageFormatException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\BitConverter.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Boolean.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Buffer.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\ArrayPool.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\ArrayPoolEventSource.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Buffers\ConfigurableArrayPool.cs" />
@@ -244,6 +244,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\ChineseLunisolarCalendar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CompareInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CompareInfo.Invariant.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CompareOptions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureNotFoundException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\CultureTypes.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Globalization\DateTimeFormat.cs" />
@@ -575,6 +576,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\ReferenceAssemblyAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\RuntimeCompatibilityAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\RuntimeFeature.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\RuntimeHelpers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\RuntimeWrappedException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\SpecialNameAttribute.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\CompilerServices\StateMachineAttribute.cs" />
@@ -679,7 +681,6 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\UnmanagedType.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\VarEnum.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\VariantWrapper.cs" />
- <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\WindowsRuntime\EventRegistrationToken.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\Vector64.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\Vector64_1.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\Intrinsics\Vector64DebugView_1.cs" />
@@ -760,6 +761,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\StringSplitOptions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\SystemException.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\ASCIIEncoding.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Text\ASCIIUtility.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\StringBuilderCache.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\CodePageDataItem.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\Decoder.cs" />
@@ -775,6 +777,7 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Text\EncoderFallback.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\EncoderReplacementFallback.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\Encoding.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)System\Text\Encoding.Internal.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\EncodingData.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\EncodingInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)System\Text\EncodingNLS.cs" />
@@ -988,6 +991,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.FlushFileBuffers.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetComputerName.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetCPInfo.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetCurrentProcessId.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetCurrentProcess_IntPtr.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetCurrentDirectory.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.GetFileAttributesEx.cs" />
@@ -1069,6 +1073,9 @@
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\Marshal.NoCom.cs" Condition="'$(TargetsCoreRT)' != 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\ComEventsHelpers.NoCom.cs" Condition="'$(TargetsCoreRT)' != 'true'" />
</ItemGroup>
+ <ItemGroup Condition="'$(FeatureCominterop)' == 'true'">
+ <Compile Include="$(MSBuildThisFileDirectory)System\Runtime\InteropServices\WindowsRuntime\EventRegistrationToken.cs" />
+ </ItemGroup>
<ItemGroup Condition="$(TargetsWindows) and '$(EnableWinRT)' != 'true'">
<Compile Include="$(MSBuildThisFileDirectory)Internal\Win32\RegistryKey.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Advapi32\Interop.RegCloseKey.cs" />
@@ -1158,6 +1165,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.GetCwd.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.GetEUid.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.GetHostName.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.GetPid.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.GetPwUid.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.GetRandomBytes.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Unix\System.Native\Interop.GetSystemTimeAsTicks.cs" />
diff --git a/src/System.Private.CoreLib/shared/System/ArgumentOutOfRangeException.cs b/src/System.Private.CoreLib/shared/System/ArgumentOutOfRangeException.cs
index 8d91561ce4..2c1941b62b 100644
--- a/src/System.Private.CoreLib/shared/System/ArgumentOutOfRangeException.cs
+++ b/src/System.Private.CoreLib/shared/System/ArgumentOutOfRangeException.cs
@@ -79,7 +79,7 @@ namespace System
string s = base.Message;
if (_actualValue != null)
{
- string valueMessage = SR.Format(SR.ArgumentOutOfRange_ActualValue, _actualValue.ToString());
+ string valueMessage = SR.Format(SR.ArgumentOutOfRange_ActualValue, _actualValue);
if (s == null)
return valueMessage;
return s + Environment.NewLine + valueMessage;
diff --git a/src/System.Private.CoreLib/src/System/Buffer.cs b/src/System.Private.CoreLib/shared/System/Buffer.cs
index af94e8e08d..dda25b827f 100644
--- a/src/System.Private.CoreLib/src/System/Buffer.cs
+++ b/src/System.Private.CoreLib/shared/System/Buffer.cs
@@ -23,30 +23,8 @@ using nuint = System.UInt32;
namespace System
{
- public static class Buffer
+ public static partial class Buffer
{
- // Copies from one primitive array to another primitive array without
- // respecting types. This calls memmove internally. The count and
- // offset parameters here are in bytes. If you want to use traditional
- // array element indices and counts, use Array.Copy.
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- public static extern void BlockCopy(Array src, int srcOffset,
- Array dst, int dstOffset, int count);
-
- // Returns a bool to indicate if the array is of primitive data types
- // or not.
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern bool IsPrimitiveTypeArray(Array array);
-
- // Gets the length of the array in bytes. The array must be an
- // array of primitives.
- //
- // This essentially does the following:
- // return array.length * sizeof(array.UnderlyingElementType).
- //
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern int _ByteLength(Array array);
-
public static int ByteLength(Array array)
{
// Is the array present?
@@ -161,24 +139,6 @@ namespace System
}
}
- // This method has a slightly different behavior on arm and other platforms.
- // On arm this method behaves like memcpy and does not handle overlapping buffers.
- // While on other platforms it behaves like memmove and handles overlapping buffers.
- // This behavioral difference is unfortunate but intentional because
- // 1. This method is given access to other internal dlls and this close to release we do not want to change it.
- // 2. It is difficult to get this right for arm and again due to release dates we would like to visit it later.
-#if ARM
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern unsafe void Memcpy(byte* dest, byte* src, int len);
-#else // ARM
- [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
- internal static unsafe void Memcpy(byte* dest, byte* src, int len)
- {
- Debug.Assert(len >= 0, "Negative length in memcpy!");
- Memmove(dest, src, (nuint)len);
- }
-#endif // ARM
-
// This method has different signature for x64 and other platforms and is done for performance reasons.
internal static unsafe void Memmove(byte* dest, byte* src, nuint len)
{
@@ -615,9 +575,6 @@ namespace System
__Memmove(pDest, pSrc, len);
}
- [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
- private static extern unsafe void __Memmove(byte* dest, byte* src, nuint len);
-
#if HAS_CUSTOM_BLOCKS
[StructLayout(LayoutKind.Sequential, Size = 16)]
private struct Block16 { }
diff --git a/src/System.Private.CoreLib/shared/System/Collections/ObjectModel/Collection.cs b/src/System.Private.CoreLib/shared/System/Collections/ObjectModel/Collection.cs
index c96a1576f3..40c8ed8dba 100644
--- a/src/System.Private.CoreLib/shared/System/Collections/ObjectModel/Collection.cs
+++ b/src/System.Private.CoreLib/shared/System/Collections/ObjectModel/Collection.cs
@@ -69,6 +69,8 @@ namespace System.Collections.ObjectModel
InsertItem(index, item);
}
+ public void AddRange(IEnumerable<T> collection) => InsertItemsRange(items.Count, collection);
+
public void Clear()
{
if (items.IsReadOnly)
@@ -114,6 +116,8 @@ namespace System.Collections.ObjectModel
InsertItem(index, item);
}
+ public void InsertRange(int index, IEnumerable<T> collection) => InsertItemsRange(index, collection);
+
public bool Remove(T item)
{
if (items.IsReadOnly)
@@ -127,6 +131,10 @@ namespace System.Collections.ObjectModel
return true;
}
+ public void RemoveRange(int index, int count) => RemoveItemsRange(index, count);
+
+ public void ReplaceRange(int index, int count, IEnumerable<T> collection) => ReplaceItemsRange(index, count, collection);
+
public void RemoveAt(int index)
{
if (items.IsReadOnly)
@@ -162,6 +170,77 @@ namespace System.Collections.ObjectModel
items[index] = item;
}
+ protected virtual void InsertItemsRange(int index, IEnumerable<T> collection)
+ {
+ if (items.IsReadOnly)
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ }
+
+ if (collection == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.list);
+ }
+
+ if ((uint)index > (uint)items.Count)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_ListInsert);
+ }
+
+ if (GetType() == typeof(Collection<T>) && items is List<T> list)
+ {
+ list.InsertRange(index, collection);
+ }
+ else
+ {
+ foreach (T item in collection)
+ {
+ InsertItem(index++, item);
+ }
+ }
+ }
+
+ protected virtual void RemoveItemsRange(int index, int count)
+ {
+ if (items.IsReadOnly)
+ {
+ ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
+ }
+
+ if ((uint)index > (uint)items.Count)
+ {
+ ThrowHelper.ThrowArgumentOutOfRange_IndexException();
+ }
+
+ if (count < 0)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ }
+
+ if (index > items.Count - count)
+ {
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_InvalidOffLen);
+ }
+
+ if (GetType() == typeof(Collection<T>) && items is List<T> list)
+ {
+ list.RemoveRange(index, count);
+ }
+ else
+ {
+ for (int i = 0; i < count; i++)
+ {
+ RemoveItem(index);
+ }
+ }
+ }
+
+ protected virtual void ReplaceItemsRange(int index, int count, IEnumerable<T> collection)
+ {
+ RemoveItemsRange(index, count);
+ InsertItemsRange(index, collection);
+ }
+
bool ICollection<T>.IsReadOnly
{
get
diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs
index de94f4f3c7..3a18dce13f 100644
--- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs
+++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/EventSource.cs
@@ -2698,7 +2698,7 @@ namespace System.Diagnostics.Tracing
// for non-BCL EventSource we must assert SecurityPermission
new SecurityPermission(PermissionState.Unrestricted).Assert();
#endif
- s_currentPid = Interop.Kernel32.GetCurrentProcessId();
+ s_currentPid = Interop.GetCurrentProcessId();
}
}
diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/StubEnvironment.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/StubEnvironment.cs
index 4a054c9810..d376389043 100644
--- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/StubEnvironment.cs
+++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/StubEnvironment.cs
@@ -377,5 +377,7 @@ internal static partial class Interop
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
internal static extern uint GetCurrentProcessId();
}
+
+ internal static uint GetCurrentProcessId() => Kernel32.GetCurrentProcessId();
}
#endif
diff --git a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs
index 3febe6ff96..22abdbef19 100644
--- a/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs
+++ b/src/System.Private.CoreLib/shared/System/Diagnostics/Tracing/TraceLogging/EventPayload.cs
@@ -54,7 +54,7 @@ namespace System.Diagnostics.Tracing
position++;
}
- throw new System.Collections.Generic.KeyNotFoundException(SR.Format(SR.Arg_KeyNotFoundWithKey, key.ToString()));
+ throw new System.Collections.Generic.KeyNotFoundException(SR.Format(SR.Arg_KeyNotFoundWithKey, key));
}
set
{
diff --git a/src/System.Private.CoreLib/shared/System/Environment.Variables.Windows.cs b/src/System.Private.CoreLib/shared/System/Environment.Variables.Windows.cs
index 7e8bcce6ad..92be84b1fb 100644
--- a/src/System.Private.CoreLib/shared/System/Environment.Variables.Windows.cs
+++ b/src/System.Private.CoreLib/shared/System/Environment.Variables.Windows.cs
@@ -61,7 +61,7 @@ namespace System
case Interop.Errors.ERROR_FILENAME_EXCED_RANGE:
// The error message from Win32 is "The filename or extension is too long",
// which is not accurate.
- throw new ArgumentException(SR.Format(SR.Argument_LongEnvVarValue));
+ throw new ArgumentException(SR.Argument_LongEnvVarValue);
case Interop.Errors.ERROR_NOT_ENOUGH_MEMORY:
case Interop.Errors.ERROR_NO_SYSTEM_RESOURCES:
diff --git a/src/System.Private.CoreLib/shared/System/Environment.WinRT.cs b/src/System.Private.CoreLib/shared/System/Environment.WinRT.cs
index 3d868299e2..a8e3dbced8 100644
--- a/src/System.Private.CoreLib/shared/System/Environment.WinRT.cs
+++ b/src/System.Private.CoreLib/shared/System/Environment.WinRT.cs
@@ -3,6 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.IO;
+using Internal.Runtime.Augments;
namespace System
{
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs b/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs
index db34cdeeb6..31217020bc 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Unix.cs
@@ -312,9 +312,7 @@ namespace System.Globalization
default:
const string unsupportedDateFieldSymbols = "YuUrQqwWDFg";
Debug.Assert(!unsupportedDateFieldSymbols.Contains(input[index]),
- string.Format(CultureInfo.InvariantCulture,
- "Encountered an unexpected date field symbol '{0}' from ICU which has no known corresponding .NET equivalent.",
- input[index]));
+ $"Encountered an unexpected date field symbol '{input[index]}' from ICU which has no known corresponding .NET equivalent.");
destination.Append(input[index++]);
break;
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Windows.cs b/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Windows.cs
index de50374412..3702ee431f 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Windows.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/CalendarData.Windows.cs
@@ -455,13 +455,9 @@ namespace System.Globalization
{
Debug.Assert(!GlobalizationMode.Invariant);
- const int LOCALE_NAME_MAX_LENGTH = 85;
- const uint LOCALE_SNAME = 0x0000005c;
- const string LOCALE_NAME_USER_DEFAULT = null;
-
int result;
- char* localeName = stackalloc char[LOCALE_NAME_MAX_LENGTH];
- result = CultureData.GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME, localeName, LOCALE_NAME_MAX_LENGTH);
+ char* localeName = stackalloc char[Interop.Kernel32.LOCALE_NAME_MAX_LENGTH];
+ result = CultureData.GetLocaleInfoEx(Interop.Kernel32.LOCALE_NAME_USER_DEFAULT, Interop.Kernel32.LOCALE_SNAME, localeName, Interop.Kernel32.LOCALE_NAME_MAX_LENGTH);
return result <= 0 ? "" : new string(localeName, 0, result - 1); // exclude the null termination
}
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CharUnicodeInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/CharUnicodeInfo.cs
index 4f51269cd3..e627cc7483 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/CharUnicodeInfo.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/CharUnicodeInfo.cs
@@ -2,16 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-////////////////////////////////////////////////////////////////////////////
-//
-//
-// Purpose: This class implements a set of methods for retrieving
-// character type information. Character type information is
-// independent of culture and region.
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
using System.Buffers.Binary;
using System.Diagnostics;
using System.Text;
@@ -19,15 +9,13 @@ using Internal.Runtime.CompilerServices;
namespace System.Globalization
{
+ /// <summary>
+ /// This class implements a set of methods for retrieving character type
+ /// information. Character type information is independent of culture
+ /// and region.
+ /// </summary>
public static partial class CharUnicodeInfo
{
- //--------------------------------------------------------------------//
- // Internal Information //
- //--------------------------------------------------------------------//
-
- //
- // Native methods to access the Unicode category data tables in charinfo.nlp.
- //
internal const char HIGH_SURROGATE_START = '\ud800';
internal const char HIGH_SURROGATE_END = '\udbff';
internal const char LOW_SURROGATE_START = '\udc00';
@@ -40,19 +28,14 @@ namespace System.Globalization
// The starting codepoint for Unicode plane 1. Plane 1 contains 0x010000 ~ 0x01ffff.
internal const int UNICODE_PLANE01_START = 0x10000;
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Actions:
- // Convert the BMP character or surrogate pointed by index to a UTF32 value.
- // This is similar to char.ConvertToUTF32, but the difference is that
- // it does not throw exceptions when invalid surrogate characters are passed in.
- //
- // WARNING: since it doesn't throw an exception it CAN return a value
- // in the surrogate range D800-DFFF, which are not legal unicode values.
- //
- ////////////////////////////////////////////////////////////////////////
-
+ /// <summary>
+ /// Convert the BMP character or surrogate pointed by index to a UTF32 value.
+ /// This is similar to char.ConvertToUTF32, but the difference is that
+ /// it does not throw exceptions when invalid surrogate characters are passed in.
+ ///
+ /// WARNING: since it doesn't throw an exception it CAN return a value
+ /// in the surrogate range D800-DFFF, which are not legal unicode values.
+ /// </summary>
internal static int InternalConvertToUtf32(string s, int index)
{
Debug.Assert(s != null, "s != null");
@@ -70,7 +53,7 @@ namespace System.Globalization
}
}
}
- return ((int)s[index]);
+ return (int)s[index];
}
internal static int InternalConvertToUtf32(StringBuilder s, int index)
@@ -88,35 +71,19 @@ namespace System.Globalization
if ((uint)temp2 <= HIGH_SURROGATE_RANGE)
{
// Convert the surrogate to UTF32 and get the result.
- return ((temp1 * 0x400) + temp2 + UNICODE_PLANE01_START);
+ return (temp1 * 0x400) + temp2 + UNICODE_PLANE01_START;
}
}
}
return c;
}
- ////////////////////////////////////////////////////////////////////////
- //
- // Convert a character or a surrogate pair starting at index of string s
- // to UTF32 value.
- //
- // Parameters:
- // s The string
- // index The starting index. It can point to a BMP character or
- // a surrogate pair.
- // len The length of the string.
- // charLength [out] If the index points to a BMP char, charLength
- // will be 1. If the index points to a surrogate pair,
- // charLength will be 2.
- //
- // WARNING: since it doesn't throw an exception it CAN return a value
- // in the surrogate range D800-DFFF, which are not legal unicode values.
- //
- // Returns:
- // The UTF32 value
- //
- ////////////////////////////////////////////////////////////////////////
-
+ /// <summary>
+ /// Convert a character or a surrogate pair starting at index of string s
+ /// to UTF32 value.
+ /// WARNING: since it doesn't throw an exception it CAN return a value
+ /// in the surrogate range D800-DFFF, which are not legal unicode values.
+ /// </summary>
internal static int InternalConvertToUtf32(string s, int index, out int charLength)
{
Debug.Assert(s != null, "s != null");
@@ -140,10 +107,11 @@ namespace System.Globalization
return ((int)s[index]);
}
- //
- // This is called by the public char and string, index versions
- //
- // Note that for ch in the range D800-DFFF we just treat it as any other non-numeric character
+ /// <summary>
+ /// This is called by the public char and string, index versions
+ /// Note that for ch in the range D800-DFFF we just treat it as any
+ /// other non-numeric character
+ /// </summary>
internal static double InternalGetNumericValue(int ch)
{
Debug.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range.");
@@ -159,7 +127,10 @@ namespace System.Globalization
ref var value = ref Unsafe.AsRef(in NumericValues[index * 8]);
if (BitConverter.IsLittleEndian)
+ {
return Unsafe.ReadUnaligned<double>(ref value);
+ }
+
return BitConverter.Int64BitsToDouble(BinaryPrimitives.ReverseEndianness(Unsafe.ReadUnaligned<long>(ref value)));
}
return -1;
@@ -182,28 +153,17 @@ namespace System.Globalization
return 0xff;
}
- ////////////////////////////////////////////////////////////////////////
- //
- //Returns the numeric value associated with the character c. If the character is a fraction,
- // the return value will not be an integer. If the character does not have a numeric value, the return value is -1.
- //
- //Returns:
- // the numeric value for the specified Unicode character. If the character does not have a numeric value, the return value is -1.
- //Arguments:
- // ch a Unicode character
- //Exceptions:
- // ArgumentNullException
- // ArgumentOutOfRangeException
- //
- ////////////////////////////////////////////////////////////////////////
-
-
+ /// <summary>
+ /// Returns the numeric value associated with the character c.
+ /// If the character is a fraction, the return value will not be an
+ /// integer. If the character does not have a numeric value, the return
+ /// value is -1.
+ /// </summary>
public static double GetNumericValue(char ch)
{
- return (InternalGetNumericValue(ch));
+ return InternalGetNumericValue(ch);
}
-
public static double GetNumericValue(string s, int index)
{
if (s == null)
@@ -214,7 +174,8 @@ namespace System.Globalization
{
throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
}
- return (InternalGetNumericValue(InternalConvertToUtf32(s, index)));
+
+ return InternalGetNumericValue(InternalConvertToUtf32(s, index));
}
public static int GetDecimalDigitValue(char ch)
@@ -228,7 +189,6 @@ namespace System.Globalization
{
throw new ArgumentNullException(nameof(s));
}
-
if (index < 0 || index >= s.Length)
{
throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
@@ -248,7 +208,6 @@ namespace System.Globalization
{
throw new ArgumentNullException(nameof(s));
}
-
if (index < 0 || index >= s.Length)
{
throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
@@ -259,40 +218,32 @@ namespace System.Globalization
public static UnicodeCategory GetUnicodeCategory(char ch)
{
- return (GetUnicodeCategory((int)ch));
+ return GetUnicodeCategory((int)ch);
}
public static UnicodeCategory GetUnicodeCategory(string s, int index)
{
if (s == null)
+ {
throw new ArgumentNullException(nameof(s));
+ }
if (((uint)index) >= ((uint)s.Length))
{
throw new ArgumentOutOfRangeException(nameof(index));
}
+
return InternalGetUnicodeCategory(s, index);
}
public static UnicodeCategory GetUnicodeCategory(int codePoint)
{
- return ((UnicodeCategory)InternalGetCategoryValue(codePoint, UNICODE_CATEGORY_OFFSET));
+ return (UnicodeCategory)InternalGetCategoryValue(codePoint, UNICODE_CATEGORY_OFFSET);
}
-
- ////////////////////////////////////////////////////////////////////////
- //
- //Action: Returns the Unicode Category property for the character c.
- //Returns:
- // an value in UnicodeCategory enum
- //Arguments:
- // ch a Unicode character
- //Exceptions:
- // None
- //
- //Note that this API will return values for D800-DF00 surrogate halves.
- //
- ////////////////////////////////////////////////////////////////////////
-
+ /// <summary>
+ /// Returns the Unicode Category property for the character c.
+ /// Note that this API will return values for D800-DF00 surrogate halves.
+ /// </summary>
internal static byte InternalGetCategoryValue(int ch, int offset)
{
Debug.Assert(ch >= 0 && ch <= 0x10ffff, "ch is not in valid Unicode range.");
@@ -302,26 +253,18 @@ namespace System.Globalization
// Note that & has the lower precedence than addition, so don't forget the parathesis.
index = Unsafe.ReadUnaligned<ushort>(ref Unsafe.AsRef(in CategoryLevel2Index[(index << 6) + ((ch >> 3) & 0b111110)]));
if (!BitConverter.IsLittleEndian)
+ {
index = BinaryPrimitives.ReverseEndianness((ushort)index);
+ }
// Get the result from the 0 -3 bit of ch.
index = CategoryLevel3Index[(index << 4) + (ch & 0x000f)];
return CategoriesValue[index * 2 + offset];
}
- ////////////////////////////////////////////////////////////////////////
- //
- //Action: Returns the Unicode Category property for the character c.
- //Returns:
- // an value in UnicodeCategory enum
- //Arguments:
- // value a Unicode String
- // index Index for the specified string.
- //Exceptions:
- // None
- //
- ////////////////////////////////////////////////////////////////////////
-
+ /// <summary>
+ /// Returns the Unicode Category property for the character c.
+ /// </summary>
internal static UnicodeCategory InternalGetUnicodeCategory(string value, int index)
{
Debug.Assert(value != null, "value can not be null");
@@ -333,8 +276,9 @@ namespace System.Globalization
internal static BidiCategory GetBidiCategory(string s, int index)
{
if (s == null)
+ {
throw new ArgumentNullException(nameof(s));
-
+ }
if (((uint)index) >= ((uint)s.Length))
{
throw new ArgumentOutOfRangeException(nameof(index));
@@ -351,20 +295,17 @@ namespace System.Globalization
return ((BidiCategory) InternalGetCategoryValue(InternalConvertToUtf32(s, index), BIDI_CATEGORY_OFFSET));
}
- ////////////////////////////////////////////////////////////////////////
- //
- // Get the Unicode category of the character starting at index. If the character is in BMP, charLength will return 1.
- // If the character is a valid surrogate pair, charLength will return 2.
- //
- ////////////////////////////////////////////////////////////////////////
-
+ /// <summary>
+ /// Get the Unicode category of the character starting at index. If the character is in BMP, charLength will return 1.
+ /// If the character is a valid surrogate pair, charLength will return 2.
+ /// </summary>
internal static UnicodeCategory InternalGetUnicodeCategory(string str, int index, out int charLength)
{
Debug.Assert(str != null, "str can not be null");
Debug.Assert(str.Length > 0, "str.Length > 0"); ;
Debug.Assert(index >= 0 && index < str.Length, "index >= 0 && index < str.Length");
- return (GetUnicodeCategory(InternalConvertToUtf32(str, index, out charLength)));
+ return GetUnicodeCategory(InternalConvertToUtf32(str, index, out charLength));
}
internal static bool IsCombiningCategory(UnicodeCategory uc)
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.cs
index 9f7669edcc..97bb90f977 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/CompareInfo.cs
@@ -2,18 +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.
-////////////////////////////////////////////////////////////////////////////
-//
-//
-//
-// Purpose: This class implements a set of methods for comparing
-// strings.
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
-using System.Reflection;
using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Text;
@@ -21,22 +12,11 @@ using Internal.Runtime.CompilerServices;
namespace System.Globalization
{
- [Flags]
- public enum CompareOptions
- {
- None = 0x00000000,
- IgnoreCase = 0x00000001,
- IgnoreNonSpace = 0x00000002,
- IgnoreSymbols = 0x00000004,
- IgnoreKanaType = 0x00000008, // ignore kanatype
- IgnoreWidth = 0x00000010, // ignore width
- OrdinalIgnoreCase = 0x10000000, // This flag can not be used with other flags.
- StringSort = 0x20000000, // use string sort method
- Ordinal = 0x40000000, // This flag can not be used with other flags.
- }
-
+ /// <summary>
+ /// This class implements a set of methods for comparing strings.
+ /// </summary>
[Serializable]
- [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
+ [TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public partial class CompareInfo : IDeserializationCallback
{
// Mask used to check if IndexOf()/LastIndexOf()/IsPrefix()/IsPostfix() has the right flags.
@@ -62,7 +42,6 @@ namespace System.Globalization
// Cache the invariant CompareInfo
internal static readonly CompareInfo Invariant = CultureInfo.InvariantCulture.CompareInfo;
- //
// CompareInfos have an interesting identity. They are attached to the locale that created them,
// ie: en-US would have an en-US sort. For haw-US (custom), then we serialize it as haw-US.
// The interesting part is that since haw-US doesn't have its own sort, it has to point at another
@@ -84,18 +63,11 @@ namespace System.Globalization
InitSort(culture);
}
- /*=================================GetCompareInfo==========================
- **Action: Get the CompareInfo constructed from the data table in the specified assembly for the specified culture.
- ** Warning: The assembly versioning mechanism is dead!
- **Returns: The CompareInfo for the specified culture.
- **Arguments:
- ** culture the ID of the culture
- ** assembly the assembly which contains the sorting table.
- **Exceptions:
- ** ArgumentNullException when the assembly is null
- ** ArgumentException if culture is invalid.
- ============================================================================*/
- // Assembly constructor should be deprecated, we don't act on the assembly information any more
+ /// <summary>
+ /// Get the CompareInfo constructed from the data table in the specified
+ /// assembly for the specified culture.
+ /// Warning: The assembly versioning mechanism is dead!
+ /// </summary>
public static CompareInfo GetCompareInfo(int culture, Assembly assembly)
{
// Parameter checking.
@@ -105,69 +77,52 @@ namespace System.Globalization
}
if (assembly != typeof(object).Module.Assembly)
{
- throw new ArgumentException(SR.Argument_OnlyMscorlib);
+ throw new ArgumentException(SR.Argument_OnlyMscorlib, nameof(assembly));
}
return GetCompareInfo(culture);
}
- /*=================================GetCompareInfo==========================
- **Action: Get the CompareInfo constructed from the data table in the specified assembly for the specified culture.
- ** The purpose of this method is to provide version for CompareInfo tables.
- **Returns: The CompareInfo for the specified culture.
- **Arguments:
- ** name the name of the culture
- ** assembly the assembly which contains the sorting table.
- **Exceptions:
- ** ArgumentNullException when the assembly is null
- ** ArgumentException if name is invalid.
- ============================================================================*/
- // Assembly constructor should be deprecated, we don't act on the assembly information any more
+ /// <summary>
+ /// Get the CompareInfo constructed from the data table in the specified
+ /// assembly for the specified culture.
+ /// The purpose of this method is to provide version for CompareInfo tables.
+ /// </summary>
public static CompareInfo GetCompareInfo(string name, Assembly assembly)
{
- if (name == null || assembly == null)
+ if (name == null)
{
- throw new ArgumentNullException(name == null ? nameof(name) : nameof(assembly));
+ throw new ArgumentNullException(nameof(name));
+ }
+ if (assembly == null)
+ {
+ throw new ArgumentNullException(nameof(assembly));
}
-
if (assembly != typeof(object).Module.Assembly)
{
- throw new ArgumentException(SR.Argument_OnlyMscorlib);
+ throw new ArgumentException(SR.Argument_OnlyMscorlib, nameof(assembly));
}
return GetCompareInfo(name);
}
- /*=================================GetCompareInfo==========================
- **Action: Get the CompareInfo for the specified culture.
- ** This method is provided for ease of integration with NLS-based software.
- **Returns: The CompareInfo for the specified culture.
- **Arguments:
- ** culture the ID of the culture.
- **Exceptions:
- ** ArgumentException if culture is invalid.
- ============================================================================*/
- // People really shouldn't be calling LCID versions, no custom support
+ /// <summary>
+ /// Get the CompareInfo for the specified culture.
+ /// This method is provided for ease of integration with NLS-based software.
+ /// </summary>
public static CompareInfo GetCompareInfo(int culture)
{
if (CultureData.IsCustomCultureId(culture))
{
- // Customized culture cannot be created by the LCID.
throw new ArgumentException(SR.Argument_CustomCultureCannotBePassedByNumber, nameof(culture));
}
return CultureInfo.GetCultureInfo(culture).CompareInfo;
}
- /*=================================GetCompareInfo==========================
- **Action: Get the CompareInfo for the specified culture.
- **Returns: The CompareInfo for the specified culture.
- **Arguments:
- ** name the name of the culture.
- **Exceptions:
- ** ArgumentException if name is invalid.
- ============================================================================*/
-
+ /// <summary>
+ /// Get the CompareInfo for the specified culture.
+ /// </summary>
public static CompareInfo GetCompareInfo(string name)
{
if (name == null)
@@ -184,6 +139,7 @@ namespace System.Globalization
{
return true;
}
+
char *pChar = &ch;
return IsSortable(pChar, 1);
}
@@ -192,14 +148,12 @@ namespace System.Globalization
{
if (text == null)
{
- // A null param is invalid here.
throw new ArgumentNullException(nameof(text));
}
if (text.Length == 0)
{
- // A zero length string is not invalid, but it is also not sortable.
- return (false);
+ return false;
}
if (GlobalizationMode.Invariant)
@@ -236,8 +190,7 @@ namespace System.Globalization
if (m_name == null)
{
// From whidbey, didn't have a name
- CultureInfo ci = CultureInfo.GetCultureInfo(this.culture);
- m_name = ci._name;
+ m_name = CultureInfo.GetCultureInfo(culture)._name;
}
else
{
@@ -249,22 +202,20 @@ namespace System.Globalization
private void OnSerializing(StreamingContext ctx)
{
// This is merely for serialization compatibility with Whidbey/Orcas, it can go away when we don't want that compat any more.
- culture = CultureInfo.GetCultureInfo(this.Name).LCID; // This is the lcid of the constructing culture (still have to dereference to get target sort)
+ culture = CultureInfo.GetCultureInfo(Name).LCID; // This is the lcid of the constructing culture (still have to dereference to get target sort)
Debug.Assert(m_name != null, "CompareInfo.OnSerializing - expected m_name to be set already");
}
- ///////////////////////////----- Name -----/////////////////////////////////
- //
- // Returns the name of the culture (well actually, of the sort).
- // Very important for providing a non-LCID way of identifying
- // what the sort is.
- //
- // Note that this name isn't dereferenced in case the CompareInfo is a different locale
- // which is consistent with the behaviors of earlier versions. (so if you ask for a sort
- // and the locale's changed behavior, then you'll get changed behavior, which is like
- // what happens for a version update)
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Returns the name of the culture (well actually, of the sort).
+ /// Very important for providing a non-LCID way of identifying
+ /// what the sort is.
+ ///
+ /// Note that this name isn't dereferenced in case the CompareInfo is a different locale
+ /// which is consistent with the behaviors of earlier versions. (so if you ask for a sort
+ /// and the locale's changed behavior, then you'll get changed behavior, which is like
+ /// what happens for a version update)
+ /// </summary>
public virtual string Name
{
@@ -280,17 +231,12 @@ namespace System.Globalization
}
}
- ////////////////////////////////////////////////////////////////////////
- //
- // Compare
- //
- // Compares the two strings with the given options. Returns 0 if the
- // two strings are equal, a number less than 0 if string1 is less
- // than string2, and a number greater than 0 if string1 is greater
- // than string2.
- //
- ////////////////////////////////////////////////////////////////////////
-
+ /// <summary>
+ /// Compares the two strings with the given options. Returns 0 if the
+ /// two strings are equal, a number less than 0 if string1 is less
+ /// than string2, and a number greater than 0 if string1 is greater
+ /// than string2.
+ /// </summary>
public virtual int Compare(string string1, string string2)
{
return Compare(string1, string2, CompareOptions.None);
@@ -319,25 +265,27 @@ namespace System.Globalization
throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
}
- //Our paradigm is that null sorts less than any other string and
- //that two nulls sort as equal.
+ // Our paradigm is that null sorts less than any other string and
+ // that two nulls sort as equal.
if (string1 == null)
{
if (string2 == null)
{
- return (0); // Equal
+ return 0;
}
- return (-1); // null < non-null
+ return -1; // null < non-null
}
if (string2 == null)
{
- return (1); // non-null > null
+ return 1; // non-null > null
}
if (GlobalizationMode.Invariant)
{
if ((options & CompareOptions.IgnoreCase) != 0)
+ {
return CompareOrdinalIgnoreCase(string1, string2);
+ }
return string.CompareOrdinal(string1, string2);
}
@@ -391,7 +339,9 @@ namespace System.Globalization
{
// Check for empty span or span from a null string
if (string1.Length == 0 || string2.Length == 0)
+ {
return string1.Length - string2.Length;
+ }
return GlobalizationMode.Invariant ?
string.CompareOrdinal(string1, string2) :
@@ -402,56 +352,51 @@ namespace System.Globalization
{
// Check for empty span or span from a null string
if (string1.Length == 0 || string2.Length == 0)
+ {
return string1.Length - string2.Length;
+ }
return GlobalizationMode.Invariant ?
CompareOrdinalIgnoreCase(string1, string2) :
CompareString(string1, string2, CompareOptions.IgnoreCase);
}
- ////////////////////////////////////////////////////////////////////////
- //
- // Compare
- //
- // Compares the specified regions of the two strings with the given
- // options.
- // Returns 0 if the two strings are equal, a number less than 0 if
- // string1 is less than string2, and a number greater than 0 if
- // string1 is greater than string2.
- //
- ////////////////////////////////////////////////////////////////////////
-
-
+ /// <summary>
+ /// Compares the specified regions of the two strings with the given
+ /// options.
+ /// Returns 0 if the two strings are equal, a number less than 0 if
+ /// string1 is less than string2, and a number greater than 0 if
+ /// string1 is greater than string2.
+ /// </summary>
public virtual int Compare(string string1, int offset1, int length1, string string2, int offset2, int length2)
{
return Compare(string1, offset1, length1, string2, offset2, length2, 0);
}
-
public virtual int Compare(string string1, int offset1, string string2, int offset2, CompareOptions options)
{
return Compare(string1, offset1, string1 == null ? 0 : string1.Length - offset1,
string2, offset2, string2 == null ? 0 : string2.Length - offset2, options);
}
-
public virtual int Compare(string string1, int offset1, string string2, int offset2)
{
return Compare(string1, offset1, string2, offset2, 0);
}
-
public virtual int Compare(string string1, int offset1, int length1, string string2, int offset2, int length2, CompareOptions options)
{
if (options == CompareOptions.OrdinalIgnoreCase)
{
int result = string.Compare(string1, offset1, string2, offset2, length1 < length2 ? length1 : length2, StringComparison.OrdinalIgnoreCase);
if ((length1 != length2) && result == 0)
- return (length1 > length2 ? 1 : -1);
- return (result);
+ {
+ return length1 > length2 ? 1 : -1;
+ }
+
+ return result;
}
- // Verify inputs
if (length1 < 0 || length2 < 0)
{
throw new ArgumentOutOfRangeException((length1 < 0) ? nameof(length1) : nameof(length2), SR.ArgumentOutOfRange_NeedPosNum);
@@ -481,20 +426,17 @@ namespace System.Globalization
throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
}
- //
- // Check for the null case.
- //
if (string1 == null)
{
if (string2 == null)
{
- return (0);
+ return 0;
}
- return (-1);
+ return -1;
}
if (string2 == null)
{
- return (1);
+ return 1;
}
ReadOnlySpan<char> span1 = string1.AsSpan(offset1, length1);
@@ -508,7 +450,9 @@ namespace System.Globalization
if (GlobalizationMode.Invariant)
{
if ((options & CompareOptions.IgnoreCase) != 0)
+ {
return CompareOrdinalIgnoreCase(span1, span2);
+ }
return string.CompareOrdinal(span1, span2);
}
@@ -516,11 +460,11 @@ namespace System.Globalization
return CompareString(span1, span2, options);
}
- //
- // CompareOrdinalIgnoreCase compare two string ordinally with ignoring the case.
- // it assumes the strings are Ascii string till we hit non Ascii character in strA or strB and then we continue the comparison by
- // calling the OS.
- //
+ /// <summary>
+ /// CompareOrdinalIgnoreCase compare two string ordinally with ignoring the case.
+ /// it assumes the strings are Ascii string till we hit non Ascii character in strA or strB and then we continue the comparison by
+ /// calling the OS.
+ /// </summary>
internal static int CompareOrdinalIgnoreCase(string strA, int indexA, int lengthA, string strB, int indexB, int lengthB)
{
Debug.Assert(indexA + lengthA <= strA.Length);
@@ -571,9 +515,13 @@ namespace System.Globalization
// Uppercase both chars if needed
if ((uint)(charA - 'a') <= 'z' - 'a')
+ {
currentA -= 0x20;
+ }
if ((uint)(charB - 'a') <= 'z' - 'a')
+ {
currentB -= 0x20;
+ }
// Return the (case-insensitive) difference between them.
return currentA - currentB;
@@ -581,7 +529,9 @@ namespace System.Globalization
}
if (length == 0)
+ {
return lengthA - lengthB;
+ }
Debug.Assert(!GlobalizationMode.Invariant);
@@ -730,27 +680,25 @@ namespace System.Globalization
}
}
- ////////////////////////////////////////////////////////////////////////
- //
- // IsPrefix
- //
- // Determines whether prefix is a prefix of string. If prefix equals
- // string.Empty, true is returned.
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Determines whether prefix is a prefix of string. If prefix equals
+ /// string.Empty, true is returned.
+ /// </summary>
public virtual bool IsPrefix(string source, string prefix, CompareOptions options)
{
- if (source == null || prefix == null)
+ if (source == null)
+ {
+ throw new ArgumentNullException(nameof(source));
+ }
+ if (prefix == null)
{
- throw new ArgumentNullException((source == null ? nameof(source) : nameof(prefix)),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(prefix));
}
if (prefix.Length == 0)
{
- return (true);
+ return true;
}
-
if (source.Length == 0)
{
return false;
@@ -792,30 +740,28 @@ namespace System.Globalization
public virtual bool IsPrefix(string source, string prefix)
{
- return (IsPrefix(source, prefix, 0));
+ return IsPrefix(source, prefix, 0);
}
- ////////////////////////////////////////////////////////////////////////
- //
- // IsSuffix
- //
- // Determines whether suffix is a suffix of string. If suffix equals
- // string.Empty, true is returned.
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Determines whether suffix is a suffix of string. If suffix equals
+ /// string.Empty, true is returned.
+ /// </summary>
public virtual bool IsSuffix(string source, string suffix, CompareOptions options)
{
- if (source == null || suffix == null)
+ if (source == null)
{
- throw new ArgumentNullException((source == null ? nameof(source) : nameof(suffix)),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(source));
+ }
+ if (suffix == null)
+ {
+ throw new ArgumentNullException(nameof(suffix));
}
if (suffix.Length == 0)
{
- return (true);
+ return true;
}
-
if (source.Length == 0)
{
return false;
@@ -855,35 +801,29 @@ namespace System.Globalization
return EndsWith(source, suffix, options);
}
-
public virtual bool IsSuffix(string source, string suffix)
{
- return (IsSuffix(source, suffix, 0));
+ return IsSuffix(source, suffix, 0);
}
- ////////////////////////////////////////////////////////////////////////
- //
- // IndexOf
- //
- // Returns the first index where value is found in string. The
- // search starts from startIndex and ends at endIndex. Returns -1 if
- // the specified value is not found. If value equals string.Empty,
- // startIndex is returned. Throws IndexOutOfRange if startIndex or
- // endIndex is less than zero or greater than the length of string.
- // Throws ArgumentException if value is null.
- //
- ////////////////////////////////////////////////////////////////////////
-
-
+ /// <summary>
+ /// Returns the first index where value is found in string. The
+ /// search starts from startIndex and ends at endIndex. Returns -1 if
+ /// the specified value is not found. If value equals string.Empty,
+ /// startIndex is returned. Throws IndexOutOfRange if startIndex or
+ /// endIndex is less than zero or greater than the length of string.
+ /// Throws ArgumentException if value is null.
+ /// </summary>
public virtual int IndexOf(string source, char value)
{
if (source == null)
+ {
throw new ArgumentNullException(nameof(source));
+ }
return IndexOf(source, value, 0, source.Length, CompareOptions.None);
}
-
public virtual int IndexOf(string source, string value)
{
if (source == null)
@@ -892,20 +832,22 @@ namespace System.Globalization
return IndexOf(source, value, 0, source.Length, CompareOptions.None);
}
-
public virtual int IndexOf(string source, char value, CompareOptions options)
{
if (source == null)
+ {
throw new ArgumentNullException(nameof(source));
+ }
return IndexOf(source, value, 0, source.Length, options);
}
-
public virtual int IndexOf(string source, string value, CompareOptions options)
{
if (source == null)
+ {
throw new ArgumentNullException(nameof(source));
+ }
return IndexOf(source, value, 0, source.Length, options);
}
@@ -913,7 +855,9 @@ namespace System.Globalization
public virtual int IndexOf(string source, char value, int startIndex)
{
if (source == null)
+ {
throw new ArgumentNullException(nameof(source));
+ }
return IndexOf(source, value, startIndex, source.Length - startIndex, CompareOptions.None);
}
@@ -929,21 +873,23 @@ namespace System.Globalization
public virtual int IndexOf(string source, char value, int startIndex, CompareOptions options)
{
if (source == null)
+ {
throw new ArgumentNullException(nameof(source));
+ }
return IndexOf(source, value, startIndex, source.Length - startIndex, options);
}
-
public virtual int IndexOf(string source, string value, int startIndex, CompareOptions options)
{
if (source == null)
+ {
throw new ArgumentNullException(nameof(source));
+ }
return IndexOf(source, value, startIndex, source.Length - startIndex, options);
}
-
public virtual int IndexOf(string source, char value, int startIndex, int count)
{
return IndexOf(source, value, startIndex, count, CompareOptions.None);
@@ -957,15 +903,18 @@ namespace System.Globalization
public unsafe virtual int IndexOf(string source, char value, int startIndex, int count, CompareOptions options)
{
- // Validate inputs
if (source == null)
+ {
throw new ArgumentNullException(nameof(source));
-
+ }
if (startIndex < 0 || startIndex > source.Length)
+ {
throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
-
+ }
if (count < 0 || startIndex > source.Length - count)
+ {
throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
+ }
if (source.Length == 0)
{
@@ -975,19 +924,23 @@ namespace System.Globalization
// Validate CompareOptions
// Ordinal can't be selected with other flags
if ((options & ValidIndexMaskOffFlags) != 0 && (options != CompareOptions.Ordinal && options != CompareOptions.OrdinalIgnoreCase))
+ {
throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
+ }
return IndexOf(source, char.ToString(value), startIndex, count, options, null);
}
public unsafe virtual int IndexOf(string source, string value, int startIndex, int count, CompareOptions options)
{
- // Validate inputs
if (source == null)
+ {
throw new ArgumentNullException(nameof(source));
+ }
if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
-
+ }
if (startIndex > source.Length)
{
throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
@@ -1010,12 +963,16 @@ namespace System.Globalization
}
if (count < 0 || startIndex > source.Length - count)
+ {
throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
+ }
// Validate CompareOptions
// Ordinal can't be selected with other flags
if ((options & ValidIndexMaskOffFlags) != 0 && (options != CompareOptions.Ordinal && options != CompareOptions.OrdinalIgnoreCase))
+ {
throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
+ }
return IndexOf(source, value, startIndex, count, options, null);
}
@@ -1053,8 +1010,10 @@ namespace System.Globalization
return IndexOfCore(source, value, options, null, fromBeginning: false);
}
- // The following IndexOf overload is mainly used by String.Replace. This overload assumes the parameters are already validated
- // and the caller is passing a valid matchLengthPtr pointer.
+ /// <summary>
+ /// The following IndexOf overload is mainly used by String.Replace. This overload assumes the parameters are already validated
+ /// and the caller is passing a valid matchLengthPtr pointer.
+ /// </summary>
internal unsafe int IndexOf(string source, string value, int startIndex, int count, CompareOptions options, int* matchLengthPtr)
{
Debug.Assert(source != null);
@@ -1108,7 +1067,9 @@ namespace System.Globalization
{
retValue += startIndex;
if (matchLengthPtr != null)
+ {
*matchLengthPtr = value.Length;
+ }
}
return retValue;
@@ -1140,24 +1101,20 @@ namespace System.Globalization
return IndexOfOrdinalCore(source, value, startIndex, count, ignoreCase);
}
- ////////////////////////////////////////////////////////////////////////
- //
- // LastIndexOf
- //
- // Returns the last index where value is found in string. The
- // search starts from startIndex and ends at endIndex. Returns -1 if
- // the specified value is not found. If value equals string.Empty,
- // endIndex is returned. Throws IndexOutOfRange if startIndex or
- // endIndex is less than zero or greater than the length of string.
- // Throws ArgumentException if value is null.
- //
- ////////////////////////////////////////////////////////////////////////
-
-
+ /// <summary>
+ /// Returns the last index where value is found in string. The
+ /// search starts from startIndex and ends at endIndex. Returns -1 if
+ /// the specified value is not found. If value equals string.Empty,
+ /// endIndex is returned. Throws IndexOutOfRange if startIndex or
+ /// endIndex is less than zero or greater than the length of string.
+ /// Throws ArgumentException if value is null.
+ /// </summary>
public virtual int LastIndexOf(string source, char value)
{
if (source == null)
+ {
throw new ArgumentNullException(nameof(source));
+ }
// Can't start at negative index, so make sure we check for the length == 0 case.
return LastIndexOf(source, value, source.Length - 1, source.Length, CompareOptions.None);
@@ -1167,7 +1124,9 @@ namespace System.Globalization
public virtual int LastIndexOf(string source, string value)
{
if (source == null)
+ {
throw new ArgumentNullException(nameof(source));
+ }
// Can't start at negative index, so make sure we check for the length == 0 case.
return LastIndexOf(source, value, source.Length - 1,
@@ -1178,17 +1137,20 @@ namespace System.Globalization
public virtual int LastIndexOf(string source, char value, CompareOptions options)
{
if (source == null)
+ {
throw new ArgumentNullException(nameof(source));
+ }
// Can't start at negative index, so make sure we check for the length == 0 case.
- return LastIndexOf(source, value, source.Length - 1,
- source.Length, options);
+ return LastIndexOf(source, value, source.Length - 1, source.Length, options);
}
public virtual int LastIndexOf(string source, string value, CompareOptions options)
{
if (source == null)
+ {
throw new ArgumentNullException(nameof(source));
+ }
// Can't start at negative index, so make sure we check for the length == 0 case.
return LastIndexOf(source, value, source.Length - 1, source.Length, options);
@@ -1199,7 +1161,6 @@ namespace System.Globalization
return LastIndexOf(source, value, startIndex, startIndex + 1, CompareOptions.None);
}
-
public virtual int LastIndexOf(string source, string value, int startIndex)
{
return LastIndexOf(source, value, startIndex, startIndex + 1, CompareOptions.None);
@@ -1210,57 +1171,63 @@ namespace System.Globalization
return LastIndexOf(source, value, startIndex, startIndex + 1, options);
}
-
public virtual int LastIndexOf(string source, string value, int startIndex, CompareOptions options)
{
return LastIndexOf(source, value, startIndex, startIndex + 1, options);
}
-
public virtual int LastIndexOf(string source, char value, int startIndex, int count)
{
return LastIndexOf(source, value, startIndex, count, CompareOptions.None);
}
-
public virtual int LastIndexOf(string source, string value, int startIndex, int count)
{
return LastIndexOf(source, value, startIndex, count, CompareOptions.None);
}
-
public virtual int LastIndexOf(string source, char value, int startIndex, int count, CompareOptions options)
{
- // Verify Arguments
if (source == null)
+ {
throw new ArgumentNullException(nameof(source));
-
+ }
// Validate CompareOptions
// Ordinal can't be selected with other flags
if ((options & ValidIndexMaskOffFlags) != 0 &&
(options != CompareOptions.Ordinal) &&
(options != CompareOptions.OrdinalIgnoreCase))
+ {
throw new ArgumentException(SR.Argument_InvalidFlag, nameof(options));
+ }
// Special case for 0 length input strings
if (source.Length == 0 && (startIndex == -1 || startIndex == 0))
+ {
return -1;
+ }
// Make sure we're not out of range
if (startIndex < 0 || startIndex > source.Length)
+ {
throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
+ }
// Make sure that we allow startIndex == source.Length
if (startIndex == source.Length)
{
startIndex--;
if (count > 0)
+ {
count--;
+ }
}
// 2nd have of this also catches when startIndex == MAXINT, so MAXINT - 0 + 1 == -1, which is < 0.
if (count < 0 || startIndex - count + 1 < 0)
+ {
throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
+ }
if (options == CompareOptions.OrdinalIgnoreCase)
{
@@ -1268,19 +1235,23 @@ namespace System.Globalization
}
if (GlobalizationMode.Invariant)
+ {
return InvariantLastIndexOf(source, char.ToString(value), startIndex, count, (options & (CompareOptions.IgnoreCase | CompareOptions.OrdinalIgnoreCase)) != 0);
+ }
return LastIndexOfCore(source, value.ToString(), startIndex, count, options);
}
-
public virtual int LastIndexOf(string source, string value, int startIndex, int count, CompareOptions options)
{
- // Verify Arguments
if (source == null)
+ {
throw new ArgumentNullException(nameof(source));
+ }
if (value == null)
+ {
throw new ArgumentNullException(nameof(value));
+ }
// Validate CompareOptions
// Ordinal can't be selected with other flags
@@ -1291,27 +1262,37 @@ namespace System.Globalization
// Special case for 0 length input strings
if (source.Length == 0 && (startIndex == -1 || startIndex == 0))
+ {
return (value.Length == 0) ? 0 : -1;
+ }
// Make sure we're not out of range
if (startIndex < 0 || startIndex > source.Length)
+ {
throw new ArgumentOutOfRangeException(nameof(startIndex), SR.ArgumentOutOfRange_Index);
+ }
// Make sure that we allow startIndex == source.Length
if (startIndex == source.Length)
{
startIndex--;
if (count > 0)
+ {
count--;
+ }
// If we are looking for nothing, just return 0
if (value.Length == 0 && count >= 0 && startIndex - count + 1 >= 0)
+ {
return startIndex;
+ }
}
// 2nd half of this also catches when startIndex == MAXINT, so MAXINT - 0 + 1 == -1, which is < 0.
if (count < 0 || startIndex - count + 1 < 0)
+ {
throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_Count);
+ }
if (options == CompareOptions.OrdinalIgnoreCase)
{
@@ -1334,17 +1315,15 @@ namespace System.Globalization
return LastIndexOfOrdinalCore(source, value, startIndex, count, ignoreCase);
}
- ////////////////////////////////////////////////////////////////////////
- //
- // GetSortKey
- //
- // Gets the SortKey for the given string with the given options.
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Gets the SortKey for the given string with the given options.
+ /// </summary>
public virtual SortKey GetSortKey(string source, CompareOptions options)
{
if (GlobalizationMode.Invariant)
+ {
return InvariantCreateSortKey(source, options);
+ }
return CreateSortKey(source, options);
}
@@ -1353,86 +1332,50 @@ namespace System.Globalization
public virtual SortKey GetSortKey(string source)
{
if (GlobalizationMode.Invariant)
+ {
return InvariantCreateSortKey(source, CompareOptions.None);
+ }
return CreateSortKey(source, CompareOptions.None);
}
- ////////////////////////////////////////////////////////////////////////
- //
- // Equals
- //
- // Implements Object.Equals(). Returns a boolean indicating whether
- // or not object refers to the same CompareInfo as the current
- // instance.
- //
- ////////////////////////////////////////////////////////////////////////
-
-
public override bool Equals(object value)
{
- if (value is CompareInfo that)
- {
- return this.Name == that.Name;
- }
-
- return (false);
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetHashCode
- //
- // Implements Object.GetHashCode(). Returns the hash code for the
- // CompareInfo. The hash code is guaranteed to be the same for
- // CompareInfo A and B where A.Equals(B) is true.
- //
- ////////////////////////////////////////////////////////////////////////
-
-
- public override int GetHashCode()
- {
- return (this.Name.GetHashCode());
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetHashCodeOfString
- //
- // This internal method allows a method that allows the equivalent of creating a Sortkey for a
- // string from CompareInfo, and generate a hashcode value from it. It is not very convenient
- // to use this method as is and it creates an unnecessary Sortkey object that will be GC'ed.
- //
- // The hash code is guaranteed to be the same for string A and B where A.Equals(B) is true and both
- // the CompareInfo and the CompareOptions are the same. If two different CompareInfo objects
- // treat the string the same way, this implementation will treat them differently (the same way that
- // Sortkey does at the moment).
- //
- // This method will never be made public itself, but public consumers of it could be created, e.g.:
- //
- // string.GetHashCode(CultureInfo)
- // string.GetHashCode(CompareInfo)
- // string.GetHashCode(CultureInfo, CompareOptions)
- // string.GetHashCode(CompareInfo, CompareOptions)
- // etc.
- //
- // (the methods above that take a CultureInfo would use CultureInfo.CompareInfo)
- //
- ////////////////////////////////////////////////////////////////////////
+ return value is CompareInfo otherCompareInfo
+ && Name == otherCompareInfo.Name;
+ }
+
+ public override int GetHashCode() => Name.GetHashCode();
+
+ /// <summary>
+ /// This internal method allows a method that allows the equivalent of creating a Sortkey for a
+ /// string from CompareInfo, and generate a hashcode value from it. It is not very convenient
+ /// to use this method as is and it creates an unnecessary Sortkey object that will be GC'ed.
+ ///
+ /// The hash code is guaranteed to be the same for string A and B where A.Equals(B) is true and both
+ /// the CompareInfo and the CompareOptions are the same. If two different CompareInfo objects
+ /// treat the string the same way, this implementation will treat them differently (the same way that
+ /// Sortkey does at the moment).
+ ///
+ /// This method will never be made public itself, but public consumers of it could be created, e.g.:
+ ///
+ /// string.GetHashCode(CultureInfo)
+ /// string.GetHashCode(CompareInfo)
+ /// string.GetHashCode(CultureInfo, CompareOptions)
+ /// string.GetHashCode(CompareInfo, CompareOptions)
+ /// etc.
+ ///
+ /// (the methods above that take a CultureInfo would use CultureInfo.CompareInfo)
+ /// </summary>
internal int GetHashCodeOfString(string source, CompareOptions options)
{
- //
- // Parameter validation
- //
- if (null == source)
+ if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if ((options & ValidHashCodeOfStringMaskOffFlags) == 0)
{
// No unsupported flags are set - continue on with the regular logic
-
if (GlobalizationMode.Invariant)
{
return ((options & CompareOptions.IgnoreCase) != 0) ? source.GetHashCodeOrdinalIgnoreCase() : source.GetHashCode();
@@ -1465,13 +1408,9 @@ namespace System.Globalization
public int GetHashCode(ReadOnlySpan<char> source, CompareOptions options)
{
- //
- // Parameter validation
- //
if ((options & ValidHashCodeOfStringMaskOffFlags) == 0)
{
// No unsupported flags are set - continue on with the regular logic
-
if (GlobalizationMode.Invariant)
{
return ((options & CompareOptions.IgnoreCase) != 0) ? string.GetHashCodeOrdinalIgnoreCase(source) : string.GetHashCode(source);
@@ -1496,18 +1435,7 @@ namespace System.Globalization
}
}
- ////////////////////////////////////////////////////////////////////////
- //
- // ToString
- //
- // Implements Object.ToString(). Returns a string describing the
- // CompareInfo.
- //
- ////////////////////////////////////////////////////////////////////////
- public override string ToString()
- {
- return ("CompareInfo - " + this.Name);
- }
+ public override string ToString() => "CompareInfo - " + Name;
public SortVersion Version
{
@@ -1533,12 +1461,6 @@ namespace System.Globalization
}
}
- public int LCID
- {
- get
- {
- return CultureInfo.GetCultureInfo(Name).LCID;
- }
- }
+ public int LCID => CultureInfo.GetCultureInfo(Name).LCID;
}
}
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CompareOptions.cs b/src/System.Private.CoreLib/shared/System/Globalization/CompareOptions.cs
new file mode 100644
index 0000000000..366ece403c
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/System/Globalization/CompareOptions.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.
+
+namespace System.Globalization
+{
+ [Flags]
+ public enum CompareOptions
+ {
+ None = 0x00000000,
+ IgnoreCase = 0x00000001,
+ IgnoreNonSpace = 0x00000002,
+ IgnoreSymbols = 0x00000004,
+ IgnoreKanaType = 0x00000008,
+ IgnoreWidth = 0x00000010,
+ OrdinalIgnoreCase = 0x10000000, // This flag can not be used with other flags.
+ StringSort = 0x20000000,
+ Ordinal = 0x40000000, // This flag can not be used with other flags.
+ }
+}
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Unix.cs b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Unix.cs
index c800c48eb5..57226ff752 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Unix.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Unix.cs
@@ -69,18 +69,18 @@ namespace System.Globalization
}
_sRealName = _sName;
- _iLanguage = this.ILANGUAGE;
+ _iLanguage = LCID;
if (_iLanguage == 0)
{
_iLanguage = CultureInfo.LOCALE_CUSTOM_UNSPECIFIED;
}
- _bNeutral = (this.SISO3166CTRYNAME.Length == 0);
+ _bNeutral = TwoLetterISOCountryName.Length == 0;
_sSpecificCulture = _bNeutral ? LocaleData.GetSpecificCultureName(_sRealName) : _sRealName;
// Remove the sort from sName unless custom culture
- if (index>0 && !_bNeutral && !IsCustomCultureId(_iLanguage))
+ if (index > 0 && !_bNeutral && !IsCustomCultureId(_iLanguage))
{
_sName = _sWindowsName.Substring(0, index);
}
@@ -196,10 +196,7 @@ namespace System.Globalization
return new int[] { primaryGroupingSize, secondaryGroupingSize };
}
- private string GetTimeFormatString()
- {
- return GetTimeFormatString(false);
- }
+ private string GetTimeFormatString() => GetTimeFormatString(shortFormat: false);
private unsafe string GetTimeFormatString(bool shortFormat)
{
@@ -219,10 +216,7 @@ namespace System.Globalization
return ConvertIcuTimeFormatString(span.Slice(0, span.IndexOf('\0')));
}
- private int GetFirstDayOfWeek()
- {
- return this.GetLocaleInfo(LocaleNumberData.FirstDayOfWeek);
- }
+ private int GetFirstDayOfWeek() => GetLocaleInfo(LocaleNumberData.FirstDayOfWeek);
private string[] GetTimeFormats()
{
@@ -318,31 +312,31 @@ namespace System.Globalization
private static int GetAnsiCodePage(string cultureName)
{
int ansiCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.AnsiCodePage);
- return ansiCodePage == -1 ? CultureData.Invariant.IDEFAULTANSICODEPAGE : ansiCodePage;
+ return ansiCodePage == -1 ? CultureData.Invariant.ANSICodePage : ansiCodePage;
}
private static int GetOemCodePage(string cultureName)
{
int oemCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.OemCodePage);
- return oemCodePage == -1 ? CultureData.Invariant.IDEFAULTOEMCODEPAGE : oemCodePage;
+ return oemCodePage == -1 ? CultureData.Invariant.OEMCodePage : oemCodePage;
}
private static int GetMacCodePage(string cultureName)
{
int macCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.MacCodePage);
- return macCodePage == -1 ? CultureData.Invariant.IDEFAULTMACCODEPAGE : macCodePage;
+ return macCodePage == -1 ? CultureData.Invariant.MacCodePage : macCodePage;
}
private static int GetEbcdicCodePage(string cultureName)
{
int ebcdicCodePage = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.EbcdicCodePage);
- return ebcdicCodePage == -1 ? CultureData.Invariant.IDEFAULTEBCDICCODEPAGE : ebcdicCodePage;
+ return ebcdicCodePage == -1 ? CultureData.Invariant.EBCDICCodePage : ebcdicCodePage;
}
private static int GetGeoId(string cultureName)
{
int geoId = LocaleData.GetLocaleDataNumericPart(cultureName, LocaleDataParts.GeoId);
- return geoId == -1 ? CultureData.Invariant.IGEOID : geoId;
+ return geoId == -1 ? CultureData.Invariant.GeoId : geoId;
}
private static int GetDigitSubstitution(string cultureName)
@@ -413,19 +407,10 @@ namespace System.Globalization
return LocaleData.GetConsoleUICulture(cultureName);
}
- internal bool IsFramework // not applicable on Linux based systems
- {
- get { return false; }
- }
+ internal bool IsFramework => false;
- internal bool IsWin32Installed // not applicable on Linux based systems
- {
- get { return false; }
- }
+ internal bool IsWin32Installed => false;
- internal bool IsReplacementCulture // not applicable on Linux based systems
- {
- get { return false; }
- }
+ internal bool IsReplacementCulture => false;
}
}
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Windows.cs b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Windows.cs
index 75f78620d5..151f771f93 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Windows.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.Windows.cs
@@ -17,12 +17,6 @@ namespace System.Globalization
{
internal partial class CultureData
{
- private const uint LOCALE_NOUSEROVERRIDE = 0x80000000;
- private const uint LOCALE_RETURN_NUMBER = 0x20000000;
- private const uint LOCALE_SISO3166CTRYNAME = 0x0000005A;
-
- private const uint TIME_NOSECONDS = 0x00000002;
-
/// <summary>
/// Check with the OS to see if this is a valid culture.
/// If so we populate a limited number of fields. If its not valid we return false.
@@ -60,15 +54,11 @@ namespace System.Globalization
{
Debug.Assert(!GlobalizationMode.Invariant);
- const uint LOCALE_ILANGUAGE = 0x00000001;
- const uint LOCALE_INEUTRAL = 0x00000071;
- const uint LOCALE_SNAME = 0x0000005c;
-
int result;
string realNameBuffer = _sRealName;
- char* pBuffer = stackalloc char[LOCALE_NAME_MAX_LENGTH];
+ char* pBuffer = stackalloc char[Interop.Kernel32.LOCALE_NAME_MAX_LENGTH];
- result = GetLocaleInfoEx(realNameBuffer, LOCALE_SNAME, pBuffer, LOCALE_NAME_MAX_LENGTH);
+ result = GetLocaleInfoEx(realNameBuffer, Interop.Kernel32.LOCALE_SNAME, pBuffer, Interop.Kernel32.LOCALE_NAME_MAX_LENGTH);
// Did it fail?
if (result == 0)
@@ -85,7 +75,7 @@ namespace System.Globalization
// Check for neutrality, don't expect to fail
// (buffer has our name in it, so we don't have to do the gc. stuff)
- result = GetLocaleInfoEx(realNameBuffer, LOCALE_INEUTRAL | LOCALE_RETURN_NUMBER, pBuffer, sizeof(int) / sizeof(char));
+ result = GetLocaleInfoEx(realNameBuffer, Interop.Kernel32.LOCALE_INEUTRAL | Interop.Kernel32.LOCALE_RETURN_NUMBER, pBuffer, sizeof(int) / sizeof(char));
if (result == 0)
{
return false;
@@ -110,7 +100,7 @@ namespace System.Globalization
// Specific locale name is whatever ResolveLocaleName (win7+) returns.
// (Buffer has our name in it, and we can recycle that because windows resolves it before writing to the buffer)
- result = Interop.Kernel32.ResolveLocaleName(realNameBuffer, pBuffer, LOCALE_NAME_MAX_LENGTH);
+ result = Interop.Kernel32.ResolveLocaleName(realNameBuffer, pBuffer, Interop.Kernel32.LOCALE_NAME_MAX_LENGTH);
// 0 is failure, 1 is invariant (""), which we expect
if (result < 1)
@@ -138,7 +128,7 @@ namespace System.Globalization
// If we are an alt sort locale then this is the same as the part before the _ in the windows name
// This is for like de-DE_phoneb and es-ES_tradnl that hsouldn't have the _ part
- result = GetLocaleInfoEx(realNameBuffer, LOCALE_ILANGUAGE | LOCALE_RETURN_NUMBER, pBuffer, sizeof(int) / sizeof(char));
+ result = GetLocaleInfoEx(realNameBuffer, Interop.Kernel32.LOCALE_ILANGUAGE | Interop.Kernel32.LOCALE_RETURN_NUMBER, pBuffer, sizeof(int) / sizeof(char));
if (result == 0)
{
return false;
@@ -180,8 +170,7 @@ namespace System.Globalization
internal static unsafe int GetLocaleInfoExInt(string localeName, uint field)
{
- const uint LOCALE_RETURN_NUMBER = 0x20000000;
- field |= LOCALE_RETURN_NUMBER;
+ field |= Interop.Kernel32.LOCALE_RETURN_NUMBER;
int value = 0;
GetLocaleInfoEx(localeName, field, (char*) &value, sizeof(int));
return value;
@@ -216,7 +205,7 @@ namespace System.Globalization
// Fix lctype if we don't want overrides
if (!UseUserOverride)
{
- lctype |= LOCALE_NOUSEROVERRIDE;
+ lctype |= Interop.Kernel32.LOCALE_NOUSEROVERRIDE;
}
// Ask OS for data, note that we presume it returns success, so we have to know that
@@ -232,18 +221,14 @@ namespace System.Globalization
private string GetTimeFormatString()
{
- const uint LOCALE_STIMEFORMAT = 0x00001003;
-
- return ReescapeWin32String(GetLocaleInfoFromLCType(_sWindowsName, LOCALE_STIMEFORMAT, UseUserOverride));
+ return ReescapeWin32String(GetLocaleInfoFromLCType(_sWindowsName, Interop.Kernel32.LOCALE_STIMEFORMAT, UseUserOverride));
}
private int GetFirstDayOfWeek()
{
Debug.Assert(_sWindowsName != null, "[CultureData.DoGetLocaleInfoInt] Expected _sWindowsName to be populated by already");
- const uint LOCALE_IFIRSTDAYOFWEEK = 0x0000100C;
-
- int result = GetLocaleInfoExInt(_sWindowsName, LOCALE_IFIRSTDAYOFWEEK | (!UseUserOverride ? LOCALE_NOUSEROVERRIDE : 0));
+ int result = GetLocaleInfoExInt(_sWindowsName, Interop.Kernel32.LOCALE_IFIRSTDAYOFWEEK | (!UseUserOverride ? Interop.Kernel32.LOCALE_NOUSEROVERRIDE : 0));
// Win32 and .NET disagree on the numbering for days of the week, so we have to convert.
return ConvertFirstDayOfWeekMonToSun(result);
@@ -262,7 +247,7 @@ namespace System.Globalization
{
// Note that this gets overrides for us all the time
Debug.Assert(_sWindowsName != null, "[CultureData.DoEnumShortTimeFormats] Expected _sWindowsName to be populated by already");
- string[] result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, TIME_NOSECONDS, UseUserOverride));
+ string[] result = ReescapeWin32Strings(nativeEnumTimeFormats(_sWindowsName, Interop.Kernel32.TIME_NOSECONDS, UseUserOverride));
return result;
}
@@ -274,16 +259,13 @@ namespace System.Globalization
Debug.Assert(!GlobalizationMode.Invariant);
Debug.Assert(regionName != null);
- const uint LOCALE_SUPPLEMENTAL = 0x00000002;
- const uint LOCALE_SPECIFICDATA = 0x00000020;
-
EnumLocaleData context = new EnumLocaleData();
context.cultureName = null;
context.regionName = regionName;
unsafe
{
- Interop.Kernel32.EnumSystemLocalesEx(EnumSystemLocalesProc, LOCALE_SPECIFICDATA | LOCALE_SUPPLEMENTAL, Unsafe.AsPointer(ref context), IntPtr.Zero);
+ Interop.Kernel32.EnumSystemLocalesEx(EnumSystemLocalesProc, Interop.Kernel32.LOCALE_SPECIFICDATA | Interop.Kernel32.LOCALE_SUPPLEMENTAL, Unsafe.AsPointer(ref context), IntPtr.Zero);
}
if (context.cultureName != null)
@@ -308,7 +290,7 @@ namespace System.Globalization
((ci = GetUserDefaultCulture()) != null) &&
!CultureInfo.DefaultThreadCurrentUICulture.Name.Equals(ci.Name))
{
- return SNATIVEDISPLAYNAME;
+ return NativeName;
}
else
{
@@ -329,7 +311,7 @@ namespace System.Globalization
return GetLocaleInfo(LocaleStringData.LocalizedCountryName);
}
- return SNATIVECOUNTRY;
+ return NativeCountryName;
#endif // ENABLE_WINRT
}
@@ -351,7 +333,7 @@ namespace System.Globalization
// Fix lctype if we don't want overrides
if (!useUserOveride)
{
- lctype |= LOCALE_NOUSEROVERRIDE;
+ lctype |= Interop.Kernel32.LOCALE_NOUSEROVERRIDE;
}
// Ask OS for data
@@ -365,25 +347,26 @@ namespace System.Globalization
return result;
}
- ////////////////////////////////////////////////////////////////////////////
- //
- // Reescape a Win32 style quote string as a NLS+ style quoted string
- //
- // This is also the escaping style used by custom culture data files
- //
- // NLS+ uses \ to escape the next character, whether in a quoted string or
- // not, so we always have to change \ to \\.
- //
- // NLS+ uses \' to escape a quote inside a quoted string so we have to change
- // '' to \' (if inside a quoted string)
- //
- // We don't build the stringbuilder unless we find something to change
- ////////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Reescape a Win32 style quote string as a NLS+ style quoted string
+ ///
+ /// This is also the escaping style used by custom culture data files
+ ///
+ /// NLS+ uses \ to escape the next character, whether in a quoted string or
+ /// not, so we always have to change \ to \\.
+ ///
+ /// NLS+ uses \' to escape a quote inside a quoted string so we have to change
+ /// '' to \' (if inside a quoted string)
+ ///
+ /// We don't build the stringbuilder unless we find something to change
+ /// </summary>
internal static string ReescapeWin32String(string str)
{
// If we don't have data, then don't try anything
if (str == null)
+ {
return null;
+ }
StringBuilder result = null;
@@ -531,7 +514,7 @@ namespace System.Globalization
try
{
string cultureName = new string(lpLocaleString);
- string regionName = GetLocaleInfoEx(cultureName, LOCALE_SISO3166CTRYNAME);
+ string regionName = GetLocaleInfoEx(cultureName, Interop.Kernel32.LOCALE_SISO3166CTRYNAME);
if (regionName != null && regionName.Equals(context.regionName, StringComparison.OrdinalIgnoreCase))
{
context.cultureName = cultureName;
@@ -586,9 +569,6 @@ namespace System.Globalization
private static unsafe string[] nativeEnumTimeFormats(string localeName, uint dwFlags, bool useUserOverride)
{
- const uint LOCALE_SSHORTTIME = 0x00000079;
- const uint LOCALE_STIMEFORMAT = 0x00001003;
-
EnumData data = new EnumData();
data.strings = new List<string>();
@@ -608,7 +588,7 @@ namespace System.Globalization
// If we do have an override, we don't know if it is a user defined override or if the
// user has just selected one of the predefined formats so we can't just remove it
// but we can move it down.
- uint lcType = (dwFlags == TIME_NOSECONDS) ? LOCALE_SSHORTTIME : LOCALE_STIMEFORMAT;
+ uint lcType = (dwFlags == Interop.Kernel32.TIME_NOSECONDS) ? Interop.Kernel32.LOCALE_SSHORTTIME : Interop.Kernel32.LOCALE_STIMEFORMAT;
string timeFormatNoUserOverride = GetLocaleInfoFromLCType(localeName, lcType, useUserOverride);
if (timeFormatNoUserOverride != "")
{
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.cs b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.cs
index 48e020636b..1280119912 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/CultureData.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/CultureData.cs
@@ -19,40 +19,39 @@ namespace System.Globalization
using LcidToCultureNameDictionary = Dictionary<int, string>;
#endif
- //
- // List of culture data
- // Note the we cache overrides.
- // Note that localized names (resource names) aren't available from here.
- //
-
- //
- // Our names are a tad confusing.
- //
- // sWindowsName -- The name that windows thinks this culture is, ie:
- // en-US if you pass in en-US
- // de-DE_phoneb if you pass in de-DE_phoneb
- // fj-FJ if you pass in fj (neutral, on a pre-Windows 7 machine)
- // fj if you pass in fj (neutral, post-Windows 7 machine)
- //
- // sRealName -- The name you used to construct the culture, in pretty form
- // en-US if you pass in EN-us
- // en if you pass in en
- // de-DE_phoneb if you pass in de-DE_phoneb
- //
- // sSpecificCulture -- The specific culture for this culture
- // en-US for en-US
- // en-US for en
- // de-DE_phoneb for alt sort
- // fj-FJ for fj (neutral)
- //
- // sName -- The IETF name of this culture (ie: no sort info, could be neutral)
- // en-US if you pass in en-US
- // en if you pass in en
- // de-DE if you pass in de-DE_phoneb
- //
+ /// <summary>
+ /// List of culture data
+ /// Note the we cache overrides.
+ /// Note that localized names (resource names) aren't available from here.
+ /// </summary>
+ /// <remarks>
+ /// Our names are a tad confusing.
+ ///
+ /// sWindowsName -- The name that windows thinks this culture is, ie:
+ /// en-US if you pass in en-US
+ /// de-DE_phoneb if you pass in de-DE_phoneb
+ /// fj-FJ if you pass in fj (neutral, on a pre-Windows 7 machine)
+ /// fj if you pass in fj (neutral, post-Windows 7 machine)
+ ///
+ /// sRealName -- The name you used to construct the culture, in pretty form
+ /// en-US if you pass in EN-us
+ /// en if you pass in en
+ /// de-DE_phoneb if you pass in de-DE_phoneb
+ ///
+ /// sSpecificCulture -- The specific culture for this culture
+ /// en-US for en-US
+ /// en-US for en
+ /// de-DE_phoneb for alt sort
+ /// fj-FJ for fj (neutral)
+ ///
+ /// sName -- The IETF name of this culture (ie: no sort info, could be neutral)
+ /// en-US if you pass in en-US
+ /// en if you pass in en
+ /// de-DE if you pass in de-DE_phoneb
+ /// </remarks>
internal partial class CultureData
{
- private const int LOCALE_NAME_MAX_LENGTH = 85;
+ private const int LocaleNameMaxLength = 85;
private const int undef = -1;
// Override flag
@@ -156,15 +155,17 @@ namespace System.Globalization
private bool _bUseOverrides; // use user overrides?
private bool _bNeutral; // Flags for the culture (ie: neutral or not right now)
- // Region Name to Culture Name mapping table
- // (In future would be nice to be in registry or something)
-
- //Using a property so we avoid creating the dictionary until we need it
+ /// <summary>
+ /// Region Name to Culture Name mapping table
+ /// </summary>
+ /// <remarks>
+ /// Using a property so we avoid creating the dictionary until we need it
+ /// </remarks>
private static StringStringDictionary RegionNames
{
get
{
- if (s_RegionNames == null)
+ if (s_regionNames == null)
{
StringStringDictionary regionNames = new StringStringDictionary(211 /* prime */);
@@ -297,16 +298,16 @@ namespace System.Globalization
regionNames.Add("ZA", "af-ZA");
regionNames.Add("ZW", "en-ZW");
- s_RegionNames = regionNames;
+ s_regionNames = regionNames;
}
- return s_RegionNames;
+ return s_regionNames;
}
}
// Cache of regions we've already looked up
private static volatile StringCultureDataDictionary s_cachedRegions;
- private static volatile StringStringDictionary s_RegionNames;
+ private static volatile StringStringDictionary s_regionNames;
internal static CultureData GetCultureDataForRegion(string cultureName, bool useUserOverride)
{
@@ -316,16 +317,15 @@ namespace System.Globalization
return CultureData.Invariant;
}
- //
// First check if GetCultureData() can find it (ie: its a real culture)
- //
CultureData retVal = GetCultureData(cultureName, useUserOverride);
- if (retVal != null && (retVal.IsNeutralCulture == false)) return retVal;
+ if (retVal != null && !retVal.IsNeutralCulture)
+ {
+ return retVal;
+ }
- //
// Not a specific culture, perhaps it's region-only name
// (Remember this isn't a core clr path where that's not supported)
- //
// If it was neutral remember that so that RegionInfo() can throw the right exception
CultureData neutral = retVal;
@@ -351,9 +351,7 @@ namespace System.Globalization
}
}
- //
// Not found in the hash table, look it up the hard way
- //
// If not a valid mapping from the registry we'll have to try the hard coded table
if (retVal == null || (retVal.IsNeutralCulture == true))
@@ -432,7 +430,7 @@ namespace System.Globalization
if (GlobalizationMode.Invariant)
{
// in invariant mode we always return invariant culture only from the enumeration
- return new CultureInfo[1] { new CultureInfo("") };
+ return new CultureInfo[] { new CultureInfo("") };
}
#pragma warning restore 618
@@ -548,11 +546,10 @@ namespace System.Globalization
return invariant;
}
- /////////////////////////////////////////////////////////////////////////
- // Build our invariant information
- //
- // We need an invariant instance, which we build hard-coded
- /////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Build our invariant information
+ /// We need an invariant instance, which we build hard-coded
+ /// </summary>
internal static CultureData Invariant
{
get
@@ -567,9 +564,6 @@ namespace System.Globalization
}
private volatile static CultureData s_Invariant;
- ///////////////
- // Constructors //
- ///////////////
// Cache of cultures we've already looked up
private static volatile StringCultureDataDictionary s_cachedCultures;
private static readonly object s_lock = new object();
@@ -630,7 +624,7 @@ namespace System.Globalization
isNeutralName = true;
int i = 0;
- if (name.Length > LOCALE_NAME_MAX_LENGTH)
+ if (name.Length > LocaleNameMaxLength)
{
// Theoretically we shouldn't hit this exception.
throw new ArgumentException(SR.Format(SR.Argument_InvalidId, nameof(name)));
@@ -676,7 +670,9 @@ namespace System.Globalization
}
if (changed)
+ {
return new string(normalizedName);
+ }
return name;
}
@@ -685,7 +681,7 @@ namespace System.Globalization
{
if (GlobalizationMode.Invariant)
{
- if (cultureName.Length > LOCALE_NAME_MAX_LENGTH || !CultureInfo.VerifyCultureName(cultureName, false))
+ if (cultureName.Length > LocaleNameMaxLength || !CultureInfo.VerifyCultureName(cultureName, false))
{
return null;
}
@@ -704,12 +700,9 @@ namespace System.Globalization
culture._sRealName = cultureName;
// Ask native code if that one's real
- if (culture.InitCultureData() == false)
+ if (!culture.InitCultureData() && !culture.InitCompatibilityCultureData())
{
- if (culture.InitCompatibilityCultureData() == false)
- {
- return null;
- }
+ return null;
}
return culture;
@@ -737,10 +730,11 @@ namespace System.Globalization
}
_sRealName = fallbackCultureName;
- if (InitCultureData() == false)
+ if (!InitCultureData())
{
return false;
}
+
// fixup our data
_sName = realCultureName; // the name that goes back to the user
_sParent = fallbackCultureName;
@@ -748,14 +742,16 @@ namespace System.Globalization
return true;
}
- // We'd rather people use the named version since this doesn't allow custom locales
+ /// We'd rather people use the named version since this doesn't allow custom locales
internal static CultureData GetCultureData(int culture, bool bUseUserOverride)
{
string localeName = null;
CultureData retVal = null;
if (culture == CultureInfo.LOCALE_INVARIANT)
+ {
return Invariant;
+ }
if (GlobalizationMode.Invariant)
{
@@ -775,25 +771,17 @@ namespace System.Globalization
// If not successful, throw
if (retVal == null)
+ {
throw new CultureNotFoundException(nameof(culture), culture, SR.Argument_CultureNotSupported);
+ }
// Return the one we found
return retVal;
}
- ////////////////////////////////////////////////////////////////////////
- //
- // All the accessors
- //
- // Accessors for our data object items
- //
- ////////////////////////////////////////////////////////////////////////
-
- ///////////
- // Identity //
- ///////////
-
- // The real name used to construct the locale (ie: de-DE_phoneb)
+ /// <summary>
+ /// The real name used to construct the locale (ie: de-DE_phoneb)
+ /// </summary>
internal string CultureName
{
get
@@ -812,30 +800,18 @@ namespace System.Globalization
}
}
- // Are overrides enabled?
- internal bool UseUserOverride
- {
- get
- {
- return _bUseOverrides;
- }
- }
+ /// <summary>
+ /// Are overrides enabled?
+ /// </summary>
+ internal bool UseUserOverride => _bUseOverrides;
- // locale name (ie: de-DE, NO sort information)
- internal string SNAME
- {
- get
- {
- if (_sName == null)
- {
- _sName = string.Empty;
- }
- return _sName;
- }
- }
+ /// <summary>
+ /// locale name (ie: de-DE, NO sort information)
+ /// </summary>
+ internal string Name => _sName ?? string.Empty;
// Parent name (which may be a custom locale/culture)
- internal string SPARENT
+ internal string ParentName
{
get
{
@@ -849,21 +825,21 @@ namespace System.Globalization
}
// Localized pretty name for this locale (ie: Inglis (estados Unitos))
- internal string SLOCALIZEDDISPLAYNAME
+ internal string DisplayName
{
get
{
if (_sLocalizedDisplayName == null)
{
- if (this.IsSupplementalCustomCulture)
+ if (IsSupplementalCustomCulture)
{
- if (this.IsNeutralCulture)
+ if (IsNeutralCulture)
{
- _sLocalizedDisplayName = this.SNATIVELANGUAGE;
+ _sLocalizedDisplayName = NativeLanguageName;
}
else
{
- _sLocalizedDisplayName = this.SNATIVEDISPLAYNAME;
+ _sLocalizedDisplayName = NativeName;
}
}
else
@@ -873,17 +849,17 @@ namespace System.Globalization
const string ZH_CHT = "zh-CHT";
const string ZH_CHS = "zh-CHS";
- if (SNAME.Equals(ZH_CHT, StringComparison.OrdinalIgnoreCase))
+ if (Name.Equals(ZH_CHT, StringComparison.OrdinalIgnoreCase))
{
_sLocalizedDisplayName = GetLanguageDisplayName("zh-Hant");
}
- else if (SNAME.Equals(ZH_CHS, StringComparison.OrdinalIgnoreCase))
+ else if (Name.Equals(ZH_CHS, StringComparison.OrdinalIgnoreCase))
{
_sLocalizedDisplayName = GetLanguageDisplayName("zh-Hans");
}
else
{
- _sLocalizedDisplayName = GetLanguageDisplayName(SNAME);
+ _sLocalizedDisplayName = GetLanguageDisplayName(Name);
}
}
catch (Exception)
@@ -895,9 +871,9 @@ namespace System.Globalization
if (string.IsNullOrEmpty(_sLocalizedDisplayName))
{
// If its neutral use the language name
- if (this.IsNeutralCulture)
+ if (IsNeutralCulture)
{
- _sLocalizedDisplayName = this.SLOCALIZEDLANGUAGE;
+ _sLocalizedDisplayName = LocalizedLanguageName;
}
else
{
@@ -909,7 +885,7 @@ namespace System.Globalization
((ci = GetUserDefaultCulture()) != null) &&
!CultureInfo.DefaultThreadCurrentUICulture.Name.Equals(ci.Name))
{
- _sLocalizedDisplayName = this.SNATIVEDISPLAYNAME;
+ _sLocalizedDisplayName = NativeName;
}
else
{
@@ -923,17 +899,19 @@ namespace System.Globalization
}
}
- // English pretty name for this locale (ie: English (United States))
- internal string SENGDISPLAYNAME
+ /// <summary>
+ /// English pretty name for this locale (ie: English (United States))
+ /// </summary>
+ internal string EnglishName
{
get
{
if (_sEnglishDisplayName == null)
{
// If its neutral use the language name
- if (this.IsNeutralCulture)
+ if (IsNeutralCulture)
{
- _sEnglishDisplayName = this.SENGLISHLANGUAGE;
+ _sEnglishDisplayName = EnglishLanguageName;
// differentiate the legacy display names
switch (_sName)
{
@@ -953,19 +931,19 @@ namespace System.Globalization
// Our existing names mostly look like:
// "English" + "United States" -> "English (United States)"
// "Azeri (Latin)" + "Azerbaijan" -> "Azeri (Latin, Azerbaijan)"
- if (this.SENGLISHLANGUAGE[this.SENGLISHLANGUAGE.Length - 1] == ')')
+ if (EnglishLanguageName[EnglishLanguageName.Length - 1] == ')')
{
// "Azeri (Latin)" + "Azerbaijan" -> "Azeri (Latin, Azerbaijan)"
_sEnglishDisplayName = string.Concat(
- this.SENGLISHLANGUAGE.AsSpan(0, _sEnglishLanguage.Length - 1),
+ EnglishLanguageName.AsSpan(0, _sEnglishLanguage.Length - 1),
", ",
- this.SENGCOUNTRY,
+ EnglishCountryName,
")");
}
else
{
// "English" + "United States" -> "English (United States)"
- _sEnglishDisplayName = this.SENGLISHLANGUAGE + " (" + this.SENGCOUNTRY + ")";
+ _sEnglishDisplayName = EnglishLanguageName + " (" + EnglishCountryName + ")";
}
}
}
@@ -974,17 +952,19 @@ namespace System.Globalization
}
}
- // Native pretty name for this locale (ie: Deutsch (Deutschland))
- internal string SNATIVEDISPLAYNAME
+ /// <summary>
+ /// Native pretty name for this locale (ie: Deutsch (Deutschland))
+ /// </summary>
+ internal string NativeName
{
get
{
if (_sNativeDisplayName == null)
{
// If its neutral use the language name
- if (this.IsNeutralCulture)
+ if (IsNeutralCulture)
{
- _sNativeDisplayName = this.SNATIVELANGUAGE;
+ _sNativeDisplayName = NativeLanguageName;
// differentiate the legacy display names
switch (_sName)
{
@@ -1004,7 +984,7 @@ namespace System.Globalization
if (string.IsNullOrEmpty(_sNativeDisplayName))
{
// These should primarily be "Deutsch (Deutschland)" type names
- _sNativeDisplayName = this.SNATIVELANGUAGE + " (" + this.SNATIVECOUNTRY + ")";
+ _sNativeDisplayName = NativeLanguageName + " (" + NativeCountryName + ")";
}
}
}
@@ -1012,23 +992,23 @@ namespace System.Globalization
}
}
- // The culture name to be used in CultureInfo.CreateSpecificCulture()
- internal string SSPECIFICCULTURE
+ /// <summary>
+ /// The culture name to be used in CultureInfo.CreateSpecificCulture()
+ /// </summary>
+ internal string SpecificCultureName
{
get
{
// This got populated during the culture initialization
- Debug.Assert(_sSpecificCulture != null, "[CultureData.SSPECIFICCULTURE] Expected this.sSpecificCulture to be populated by culture data initialization already");
+ Debug.Assert(_sSpecificCulture != null, "[CultureData.SpecificCultureName] Expected this.sSpecificCulture to be populated by culture data initialization already");
return _sSpecificCulture;
}
}
- /////////////
- // Language //
- /////////////
-
- // iso 639 language name, ie: en
- internal string SISO639LANGNAME
+ /// <summary>
+ /// iso 639 language name, ie: en
+ /// </summary>
+ internal string TwoLetterISOLanguageName
{
get
{
@@ -1040,8 +1020,10 @@ namespace System.Globalization
}
}
- // iso 639 language name, ie: eng
- internal string SISO639LANGNAME2
+ /// <summary>
+ /// iso 639 language name, ie: eng
+ /// </summary>
+ internal string ThreeLetterISOLanguageName
{
get
{
@@ -1053,8 +1035,10 @@ namespace System.Globalization
}
}
- // abbreviated windows language name (ie: enu) (non-standard, avoid this)
- internal string SABBREVLANGNAME
+ /// <summary>
+ /// abbreviated windows language name (ie: enu) (non-standard, avoid this)
+ /// </summary>
+ internal string ThreeLetterWindowsLanguageName
{
get
{
@@ -1066,9 +1050,11 @@ namespace System.Globalization
}
}
- // Localized name for this language (Windows Only) ie: Inglis
- // This is only valid for Windows 8 and higher neutrals:
- internal string SLOCALIZEDLANGUAGE
+ /// <summary>
+ /// Localized name for this language (Windows Only) ie: Inglis
+ /// This is only valid for Windows 8 and higher neutrals:
+ /// </summary>
+ private string LocalizedLanguageName
{
get
{
@@ -1082,7 +1068,7 @@ namespace System.Globalization
((ci = GetUserDefaultCulture()) != null) &&
!CultureInfo.DefaultThreadCurrentUICulture.Name.Equals(ci.Name))
{
- _sLocalizedLanguage = SNATIVELANGUAGE;
+ _sLocalizedLanguage = NativeLanguageName;
}
else
{
@@ -1094,8 +1080,10 @@ namespace System.Globalization
}
}
- // English name for this language (Windows Only) ie: German
- internal string SENGLISHLANGUAGE
+ /// <summary>
+ /// English name for this language (Windows Only) ie: German
+ /// </summary>
+ private string EnglishLanguageName
{
get
{
@@ -1107,8 +1095,10 @@ namespace System.Globalization
}
}
- // Native name of this language (Windows Only) ie: Deutsch
- internal string SNATIVELANGUAGE
+ /// <summary>
+ /// Native name of this language (Windows Only) ie: Deutsch
+ /// </summary>
+ private string NativeLanguageName
{
get
{
@@ -1120,12 +1110,10 @@ namespace System.Globalization
}
}
- ///////////
- // Region //
- ///////////
-
- // region name (eg US)
- internal string SREGIONNAME
+ /// <summary>
+ /// region name (eg US)
+ /// </summary>
+ internal string RegionName
{
get
{
@@ -1137,7 +1125,7 @@ namespace System.Globalization
}
}
- internal int IGEOID
+ internal int GeoId
{
get
{
@@ -1149,8 +1137,10 @@ namespace System.Globalization
}
}
- // localized name for the country
- internal string SLOCALIZEDCOUNTRY
+ /// <summary>
+ /// localized name for the country
+ /// </summary>
+ internal string LocalizedCountryName
{
get
{
@@ -1158,7 +1148,7 @@ namespace System.Globalization
{
try
{
- _sLocalizedCountry = GetRegionDisplayName(SISO3166CTRYNAME);
+ _sLocalizedCountry = GetRegionDisplayName(TwoLetterISOCountryName);
}
catch (Exception)
{
@@ -1167,15 +1157,17 @@ namespace System.Globalization
if (_sLocalizedCountry == null)
{
- _sLocalizedCountry = SNATIVECOUNTRY;
+ _sLocalizedCountry = NativeCountryName;
}
}
return _sLocalizedCountry;
}
}
- // english country name (RegionInfo) ie: Germany
- internal string SENGCOUNTRY
+ /// <summary>
+ /// english country name (RegionInfo) ie: Germany
+ /// </summary>
+ internal string EnglishCountryName
{
get
{
@@ -1187,8 +1179,10 @@ namespace System.Globalization
}
}
- // native country name (RegionInfo) ie: Deutschland
- internal string SNATIVECOUNTRY
+ /// <summary>
+ /// native country name (RegionInfo) ie: Deutschland
+ /// </summary>
+ internal string NativeCountryName
{
get
{
@@ -1200,8 +1194,10 @@ namespace System.Globalization
}
}
- // ISO 3166 Country Name
- internal string SISO3166CTRYNAME
+ /// <summary>
+ /// ISO 3166 Country Name
+ /// </summary>
+ internal string TwoLetterISOCountryName
{
get
{
@@ -1213,8 +1209,10 @@ namespace System.Globalization
}
}
- // 3 letter ISO 3166 country code
- internal string SISO3166CTRYNAME2
+ /// <summary>
+ /// 3 letter ISO 3166 country code
+ /// </summary>
+ internal string ThreeLetterISOCountryName
{
get
{
@@ -1226,7 +1224,7 @@ namespace System.Globalization
}
}
- internal int IINPUTLANGUAGEHANDLE
+ internal int KeyboardLayoutId
{
get
{
@@ -1239,14 +1237,16 @@ namespace System.Globalization
else
{
// Input Language is same as LCID for built-in cultures
- _iInputLanguageHandle = this.ILANGUAGE;
+ _iInputLanguageHandle = LCID;
}
}
return _iInputLanguageHandle;
}
}
- // Console fallback name (ie: locale to use for console apps for unicode-only locales)
+ /// <summary>
+ /// Console fallback name (ie: locale to use for console apps for unicode-only locales)
+ /// </summary>
internal string SCONSOLEFALLBACKNAME
{
get
@@ -1259,8 +1259,10 @@ namespace System.Globalization
}
}
- // (user can override) grouping of digits
- internal int[] WAGROUPING
+ /// <summary>
+ /// (user can override) grouping of digits
+ /// </summary>
+ internal int[] NumberGroupSizes
{
get
{
@@ -1272,12 +1274,10 @@ namespace System.Globalization
}
}
-
- // internal string _sDecimalSeparator ; // (user can override) decimal separator
- // internal string _sThousandSeparator ; // (user can override) thousands separator
-
- // Not a Number
- internal string SNAN
+ /// <summary>
+ /// Not a Number
+ /// </summary>
+ private string NaNSymbol
{
get
{
@@ -1289,8 +1289,10 @@ namespace System.Globalization
}
}
- // + Infinity
- internal string SPOSINFINITY
+ /// <summary>
+ /// + Infinity
+ /// </summary>
+ private string PositiveInfinitySymbol
{
get
{
@@ -1302,8 +1304,10 @@ namespace System.Globalization
}
}
- // - Infinity
- internal string SNEGINFINITY
+ /// <summary>
+ /// - Infinity
+ /// </summary>
+ private string NegativeInfinitySymbol
{
get
{
@@ -1315,13 +1319,10 @@ namespace System.Globalization
}
}
-
- ////////////
- // Percent //
- ///////////
-
- // Negative Percent (0-3)
- internal int INEGATIVEPERCENT
+ /// <summary>
+ /// Negative Percent (0-3)
+ /// </summary>
+ private int PercentNegativePattern
{
get
{
@@ -1334,8 +1335,10 @@ namespace System.Globalization
}
}
- // Positive Percent (0-11)
- internal int IPOSITIVEPERCENT
+ /// <summary>
+ /// Positive Percent (0-11)
+ /// </summary>
+ private int PercentPositivePattern
{
get
{
@@ -1348,8 +1351,10 @@ namespace System.Globalization
}
}
- // Percent (%) symbol
- internal string SPERCENT
+ /// <summary>
+ /// Percent (%) symbol
+ /// </summary>
+ private string PercentSymbol
{
get
{
@@ -1361,8 +1366,10 @@ namespace System.Globalization
}
}
- // PerMille symbol
- internal string SPERMILLE
+ /// <summary>
+ /// PerMille symbol
+ /// </summary>
+ private string PerMilleSymbol
{
get
{
@@ -1374,12 +1381,10 @@ namespace System.Globalization
}
}
- /////////////
- // Currency //
- /////////////
-
- // (user can override) local monetary symbol, eg: $
- internal string SCURRENCY
+ /// <summary>
+ /// (user can override) local monetary symbol, eg: $
+ /// </summary>
+ internal string CurrencySymbol
{
get
{
@@ -1391,8 +1396,10 @@ namespace System.Globalization
}
}
- // international monetary symbol (RegionInfo), eg: USD
- internal string SINTLSYMBOL
+ /// <summary>
+ /// international monetary symbol (RegionInfo), eg: USD
+ /// </summary>
+ internal string ISOCurrencySymbol
{
get
{
@@ -1404,8 +1411,10 @@ namespace System.Globalization
}
}
- // English name for this currency (RegionInfo), eg: US Dollar
- internal string SENGLISHCURRENCY
+ /// <summary>
+ /// English name for this currency (RegionInfo), eg: US Dollar
+ /// </summary>
+ internal string CurrencyEnglishName
{
get
{
@@ -1417,8 +1426,10 @@ namespace System.Globalization
}
}
- // Native name for this currency (RegionInfo), eg: Schweiz Frank
- internal string SNATIVECURRENCY
+ /// <summary>
+ /// Native name for this currency (RegionInfo), eg: Schweiz Frank
+ /// </summary>
+ internal string CurrencyNativeName
{
get
{
@@ -1430,12 +1441,11 @@ namespace System.Globalization
}
}
- // internal int iCurrencyDigits ; // (user can override) # local monetary fractional digits
- // internal int iCurrency ; // (user can override) positive currency format
- // internal int iNegativeCurrency ; // (user can override) negative currency format
- // (user can override) monetary grouping of digits
- internal int[] WAMONGROUPING
+ /// <summary>
+ /// (user can override) monetary grouping of digits
+ /// </summary>
+ internal int[] CurrencyGroupSizes
{
get
{
@@ -1447,8 +1457,10 @@ namespace System.Globalization
}
}
- // (user can override) system of measurement 0=metric, 1=US (RegionInfo)
- internal int IMEASURE
+ /// <summary>
+ /// (user can override) system of measurement 0=metric, 1=US (RegionInfo)
+ /// </summary>
+ internal int MeasurementSystem
{
get
{
@@ -1460,8 +1472,10 @@ namespace System.Globalization
}
}
- // (user can override) list Separator
- internal string SLIST
+ /// <summary>
+ /// (user can override) list Separator
+ /// </summary>
+ internal string ListSeparator
{
get
{
@@ -1473,13 +1487,10 @@ namespace System.Globalization
}
}
-
- ////////////////////////////
- // Calendar/Time (Gregorian) //
- ////////////////////////////
-
- // (user can override) AM designator
- internal string SAM1159
+ /// <summary>
+ /// (user can override) AM designator
+ /// </summary>
+ internal string AMDesignator
{
get
{
@@ -1491,8 +1502,10 @@ namespace System.Globalization
}
}
- // (user can override) PM designator
- internal string SPM2359
+ /// <summary>
+ /// (user can override) PM designator
+ /// </summary>
+ internal string PMDesignator
{
get
{
@@ -1504,7 +1517,9 @@ namespace System.Globalization
}
}
- // (user can override) time format
+ /// <summary>
+ /// (user can override) time format
+ /// </summary>
internal string[] LongTimes
{
get
@@ -1527,9 +1542,10 @@ namespace System.Globalization
}
}
- // short time format
- // Short times (derived from long times format)
- // TODO: NLS Arrowhead - On Windows 7 we should have short times so this isn't necessary
+ /// <summary>
+ /// short time format
+ /// Short times (derived from long times format)
+ /// </summary>
internal string[] ShortTimes
{
get
@@ -1661,14 +1677,14 @@ namespace System.Globalization
private static int GetIndexOfNextTokenAfterSeconds(string time, int index, out bool containsSpace)
{
- bool bEscape = false;
+ bool shouldEscape = false;
containsSpace = false;
for (; index < time.Length; index++)
{
switch (time[index])
{
case '\'':
- bEscape = !bEscape;
+ shouldEscape = !shouldEscape;
continue;
case '\\':
index++;
@@ -1684,7 +1700,7 @@ namespace System.Globalization
case 'm':
case 'H':
case 'h':
- if (bEscape)
+ if (shouldEscape)
{
continue;
}
@@ -1696,7 +1712,7 @@ namespace System.Globalization
}
// (user can override) first day of week
- internal int IFIRSTDAYOFWEEK
+ internal int FirstDayOfWeek
{
get
{
@@ -1709,7 +1725,7 @@ namespace System.Globalization
}
// (user can override) first week of year
- internal int IFIRSTWEEKOFYEAR
+ internal int CalendarWeekRule
{
get
{
@@ -1721,88 +1737,82 @@ namespace System.Globalization
}
}
- // (user can override default only) short date format
+ /// <summary>
+ /// (user can override default only) short date format
+ /// </summary>
internal string[] ShortDates(CalendarId calendarId)
{
return GetCalendar(calendarId).saShortDates;
}
- // (user can override default only) long date format
+ /// <summary>
+ /// (user can override default only) long date format
+ /// </summary>
internal string[] LongDates(CalendarId calendarId)
{
return GetCalendar(calendarId).saLongDates;
}
- // (user can override) date year/month format.
+ /// <summary>
+ /// (user can override) date year/month format.
+ /// </summary>
internal string[] YearMonths(CalendarId calendarId)
{
return GetCalendar(calendarId).saYearMonths;
}
- // day names
internal string[] DayNames(CalendarId calendarId)
{
return GetCalendar(calendarId).saDayNames;
}
- // abbreviated day names
internal string[] AbbreviatedDayNames(CalendarId calendarId)
{
- // Get abbreviated day names for this calendar from the OS if necessary
return GetCalendar(calendarId).saAbbrevDayNames;
}
- // The super short day names
internal string[] SuperShortDayNames(CalendarId calendarId)
{
return GetCalendar(calendarId).saSuperShortDayNames;
}
- // month names
internal string[] MonthNames(CalendarId calendarId)
{
return GetCalendar(calendarId).saMonthNames;
}
- // Genitive month names
internal string[] GenitiveMonthNames(CalendarId calendarId)
{
return GetCalendar(calendarId).saMonthGenitiveNames;
}
- // month names
internal string[] AbbreviatedMonthNames(CalendarId calendarId)
{
return GetCalendar(calendarId).saAbbrevMonthNames;
}
- // Genitive month names
internal string[] AbbreviatedGenitiveMonthNames(CalendarId calendarId)
{
return GetCalendar(calendarId).saAbbrevMonthGenitiveNames;
}
- // Leap year month names
- // Note: This only applies to Hebrew, and it basically adds a "1" to the 6th month name
- // the non-leap names skip the 7th name in the normal month name array
+ /// <remarks>>
+ /// Note: This only applies to Hebrew, and it basically adds a "1" to the 6th month name
+ /// the non-leap names skip the 7th name in the normal month name array
+ /// </remarks>
internal string[] LeapYearMonthNames(CalendarId calendarId)
{
return GetCalendar(calendarId).saLeapYearMonthNames;
}
- // month/day format (single string, no override)
internal string MonthDay(CalendarId calendarId)
{
return GetCalendar(calendarId).sMonthDay;
}
-
-
- /////////////
- // Calendars //
- /////////////
-
- // all available calendar type(s), The first one is the default calendar.
+ /// <summary>
+ /// All available calendar type(s). The first one is the default calendar.
+ /// </summary>
internal CalendarId[] CalendarIds
{
get
@@ -1876,10 +1886,12 @@ namespace System.Globalization
}
}
- // Native calendar names. index of optional calendar - 1, empty if no optional calendar at that number
+ /// <summary>
+ /// Native calendar names. Index of optional calendar - 1, empty if
+ /// no optional calendar at that number
+ /// </summary>
internal string CalendarName(CalendarId calendarId)
{
- // Get the calendar
return GetCalendar(calendarId).sNativeName;
}
@@ -1905,18 +1917,13 @@ namespace System.Globalization
if (calendarData == null)
{
Debug.Assert(_sWindowsName != null, "[CultureData.GetCalendar] Expected _sWindowsName to be populated by already");
- calendarData = new CalendarData(_sWindowsName, calendarId, this.UseUserOverride);
+ calendarData = new CalendarData(_sWindowsName, calendarId, UseUserOverride);
_calendars[calendarIndex] = calendarData;
}
return calendarData;
}
- ///////////////////
- // Text Information //
- ///////////////////
-
- // IsRightToLeft
internal bool IsRightToLeft
{
get
@@ -1926,19 +1933,18 @@ namespace System.Globalization
// 1 - Right to left (eg arabic locales)
// 2 - Vertical top to bottom with columns to the left and also left to right (ja-JP locales)
// 3 - Vertical top to bottom with columns proceeding to the right
- return (this.IREADINGLAYOUT == 1);
+ return ReadingLayout == 1;
}
}
- // IREADINGLAYOUT
- // Returns one of the following 4 reading layout values:
- // 0 - Left to right (eg en-US)
- // 1 - Right to left (eg arabic locales)
- // 2 - Vertical top to bottom with columns to the left and also left to right (ja-JP locales)
- // 3 - Vertical top to bottom with columns proceeding to the right
- //
- // If exposed as a public API, we'd have an enum with those 4 values
- private int IREADINGLAYOUT
+ /// <summary>
+ /// Returns one of the following 4 reading layout values:
+ /// 0 - Left to right (eg en-US)
+ /// 1 - Right to left (eg arabic locales)
+ /// 2 - Vertical top to bottom with columns to the left and also left to right (ja-JP locales)
+ /// 3 - Vertical top to bottom with columns proceeding to the right
+ /// </summary>
+ private int ReadingLayout
{
get
{
@@ -1952,43 +1958,45 @@ namespace System.Globalization
}
}
- // The TextInfo name never includes that alternate sort and is always specific
- // For customs, it uses the SortLocale (since the textinfo is not exposed in Win7)
- // en -> en-US
- // en-US -> en-US
- // fj (custom neutral) -> en-US (assuming that en-US is the sort locale for fj)
- // fj_FJ (custom specific) -> en-US (assuming that en-US is the sort locale for fj-FJ)
- // es-ES_tradnl -> es-ES
- internal string STEXTINFO // Text info name to use for text information
+ /// <summary>
+ /// // Text info name to use for text information
+ /// The TextInfo name never includes that alternate sort and is always specific
+ /// For customs, it uses the SortLocale (since the textinfo is not exposed in Win7)
+ /// en -> en-US
+ /// en-US -> en-US
+ /// fj (custom neutral) -> en-US (assuming that en-US is the sort locale for fj)
+ /// fj_FJ (custom specific) -> en-US (assuming that en-US is the sort locale for fj-FJ)
+ /// es-ES_tradnl -> es-ES
+ /// </summary>
+ internal string TextInfoName
{
get
{
// Note: Custom cultures might point at another culture's textinfo, however windows knows how
// to redirect it to the desired textinfo culture, so this is OK.
- Debug.Assert(_sRealName != null, "[CultureData.STEXTINFO] Expected _sRealName to be populated by already");
- return (_sRealName);
+ Debug.Assert(_sRealName != null, "[CultureData.TextInfoName] Expected _sRealName to be populated by already");
+ return _sRealName;
}
}
- // Compare info name (including sorting key) to use if custom
- internal string SCOMPAREINFO
+ /// <summary>
+ /// Compare info name (including sorting key) to use if custom
+ /// </summary>
+ internal string SortName
{
get
{
- Debug.Assert(_sRealName != null, "[CultureData.SCOMPAREINFO] Expected _sRealName to be populated by already");
- return (_sRealName);
+ Debug.Assert(_sRealName != null, "[CultureData.SortName] Expected _sRealName to be populated by already");
+ return _sRealName;
}
}
- internal bool IsSupplementalCustomCulture
- {
- get
- {
- return IsCustomCultureId(this.ILANGUAGE);
- }
- }
+ internal bool IsSupplementalCustomCulture => IsCustomCultureId(LCID);
- internal int IDEFAULTANSICODEPAGE // default ansi code page ID (ACP)
+ /// <summary>
+ /// Default ansi code page ID (ACP)
+ /// </summary>
+ internal int ANSICodePage
{
get
{
@@ -2000,7 +2008,10 @@ namespace System.Globalization
}
}
- internal int IDEFAULTOEMCODEPAGE // default oem code page ID (OCP or OEM)
+ /// <summary>
+ /// Default oem code page ID (OCP or OEM).
+ /// </summary>
+ internal int OEMCodePage
{
get
{
@@ -2012,7 +2023,10 @@ namespace System.Globalization
}
}
- internal int IDEFAULTMACCODEPAGE // default macintosh code page
+ /// <summary>
+ /// Default macintosh code page.
+ /// </summary>
+ internal int MacCodePage
{
get
{
@@ -2024,7 +2038,10 @@ namespace System.Globalization
}
}
- internal int IDEFAULTEBCDICCODEPAGE // default EBCDIC code page
+ /// <summary>
+ /// Default EBCDIC code page.
+ /// </summary>
+ internal int EBCDICCodePage
{
get
{
@@ -2036,13 +2053,13 @@ namespace System.Globalization
}
}
- internal int ILANGUAGE
+ internal int LCID
{
get
{
if (_iLanguage == 0)
{
- Debug.Assert(_sRealName != null, "[CultureData.ILANGUAGE] Expected this.sRealName to be populated already");
+ Debug.Assert(_sRealName != null, "[CultureData.LCID] Expected this.sRealName to be populated already");
_iLanguage = LocaleNameToLCID(_sRealName);
}
return _iLanguage;
@@ -2062,11 +2079,13 @@ namespace System.Globalization
{
get
{
- return string.IsNullOrEmpty(this.SNAME);
+ return string.IsNullOrEmpty(Name);
}
}
- // Get an instance of our default calendar
+ /// <summary>
+ /// Get an instance of our default calendar
+ /// </summary>
internal Calendar DefaultCalendar
{
get
@@ -2080,40 +2099,37 @@ namespace System.Globalization
if (defaultCalId == 0)
{
- defaultCalId = this.CalendarIds[0];
+ defaultCalId = CalendarIds[0];
}
return CultureInfo.GetCalendarInstance(defaultCalId);
}
}
- // All of our era names
+ /// <summary>
+ /// All of our era names
+ /// </summary>
internal string[] EraNames(CalendarId calendarId)
{
Debug.Assert(calendarId > 0, "[CultureData.saEraNames] Expected Calendar.ID > 0");
-
- return this.GetCalendar(calendarId).saEraNames;
+ return GetCalendar(calendarId).saEraNames;
}
internal string[] AbbrevEraNames(CalendarId calendarId)
{
Debug.Assert(calendarId > 0, "[CultureData.saAbbrevEraNames] Expected Calendar.ID > 0");
-
- return this.GetCalendar(calendarId).saAbbrevEraNames;
+ return GetCalendar(calendarId).saAbbrevEraNames;
}
internal string[] AbbreviatedEnglishEraNames(CalendarId calendarId)
{
Debug.Assert(calendarId > 0, "[CultureData.saAbbrevEraNames] Expected Calendar.ID > 0");
-
- return this.GetCalendar(calendarId).saAbbrevEnglishEraNames;
+ return GetCalendar(calendarId).saAbbrevEnglishEraNames;
}
- //// string array DEFAULTS
- //// Note: GetDTFIOverrideValues does the user overrides for these, so we don't have to.
-
-
- // Time separator (derived from time format)
+ /// <summary>
+ /// Time separator (derived from time format)
+ /// </summary>
internal string TimeSeparator
{
get
@@ -2133,7 +2149,9 @@ namespace System.Globalization
}
}
- // Date separator (derived from short date format)
+ /// <summary>
+ /// Date separator (derived from short date format)
+ /// </summary>
internal string DateSeparator(CalendarId calendarId)
{
if (calendarId == CalendarId.JAPAN && !LocalAppContextSwitches.EnforceLegacyJapaneseDateParsing)
@@ -2150,29 +2168,23 @@ namespace System.Globalization
return GetDateSeparator(ShortDates(calendarId)[0]);
}
- //////////////////////////////////////
- // Helper Functions to get derived properties //
- //////////////////////////////////////
-
- ////////////////////////////////////////////////////////////////////////////
- //
- // Unescape a NLS style quote string
- //
- // This removes single quotes:
- // 'fred' -> fred
- // 'fred -> fred
- // fred' -> fred
- // fred's -> freds
- //
- // This removes the first \ of escaped characters:
- // fred\'s -> fred's
- // a\\b -> a\b
- // a\b -> ab
- //
- // We don't build the stringbuilder unless we find a ' or a \. If we find a ' or a \, we
- // always build a stringbuilder because we need to remove the ' or \.
- //
- ////////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Unescape a NLS style quote string
+ ///
+ /// This removes single quotes:
+ /// 'fred' -> fred
+ /// 'fred -> fred
+ /// fred' -> fred
+ /// fred's -> freds
+ ///
+ /// This removes the first \ of escaped characters:
+ /// fred\'s -> fred's
+ /// a\\b -> a\b
+ /// a\b -> ab
+ ///
+ /// We don't build the stringbuilder unless we find a ' or a \. If we find a ' or a \, we
+ /// always build a stringbuilder because we need to remove the ' or \.
+ /// </summary>
private static string UnescapeNlsString(string str, int start, int end)
{
Debug.Assert(str != null);
@@ -2211,34 +2223,30 @@ namespace System.Globalization
}
if (result == null)
- return (str.Substring(start, end - start + 1));
+ {
+ return str.Substring(start, end - start + 1);
+ }
- return (result.ToString());
+ return result.ToString();
}
+ /// <summary>
+ /// Time format separator (ie: : in 12:39:00)
+ /// We calculate this from the provided time format
+ /// </summary>
private static string GetTimeSeparator(string format)
{
- // Time format separator (ie: : in 12:39:00)
- //
- // We calculate this from the provided time format
- //
-
- //
- // Find the time separator so that we can pretend we know STIME.
- //
+ // Find the time separator so that we can pretend we know TimeSeparator.
return GetSeparator(format, "Hhms");
}
+ /// <summary>
+ /// Date format separator (ie: / in 9/1/03)
+ /// We calculate this from the provided short date
+ /// </summary>
private static string GetDateSeparator(string format)
{
- // Date format separator (ie: / in 9/1/03)
- //
- // We calculate this from the provided short date
- //
-
- //
- // Find the date separator so that we can pretend we know SDATE.
- //
+ // Find the date separator so that we can pretend we know DateSeparator.
return GetSeparator(format, "dyM");
}
@@ -2313,104 +2321,100 @@ namespace System.Globalization
internal static bool IsCustomCultureId(int cultureId)
{
- return (cultureId == CultureInfo.LOCALE_CUSTOM_DEFAULT || cultureId == CultureInfo.LOCALE_CUSTOM_UNSPECIFIED);
+ return cultureId == CultureInfo.LOCALE_CUSTOM_DEFAULT || cultureId == CultureInfo.LOCALE_CUSTOM_UNSPECIFIED;
}
internal void GetNFIValues(NumberFormatInfo nfi)
{
- if (GlobalizationMode.Invariant || this.IsInvariantCulture)
+ if (GlobalizationMode.Invariant || IsInvariantCulture)
{
- // FUTURE: NumberFormatInfo already has default values for many of these fields. Can we not do this?
- nfi.positiveSign = _sPositiveSign;
- nfi.negativeSign = _sNegativeSign;
+ nfi._positiveSign = _sPositiveSign;
+ nfi._negativeSign = _sNegativeSign;
- nfi.numberGroupSeparator = _sThousandSeparator;
- nfi.numberDecimalSeparator = _sDecimalSeparator;
- nfi.numberDecimalDigits = _iDigits;
- nfi.numberNegativePattern = _iNegativeNumber;
+ nfi._numberGroupSeparator = _sThousandSeparator;
+ nfi._numberDecimalSeparator = _sDecimalSeparator;
+ nfi._numberDecimalDigits = _iDigits;
+ nfi._numberNegativePattern = _iNegativeNumber;
- nfi.currencySymbol = _sCurrency;
- nfi.currencyGroupSeparator = _sMonetaryThousand;
- nfi.currencyDecimalSeparator = _sMonetaryDecimal;
- nfi.currencyDecimalDigits = _iCurrencyDigits;
- nfi.currencyNegativePattern = _iNegativeCurrency;
- nfi.currencyPositivePattern = _iCurrency;
+ nfi._currencySymbol = _sCurrency;
+ nfi._currencyGroupSeparator = _sMonetaryThousand;
+ nfi._currencyDecimalSeparator = _sMonetaryDecimal;
+ nfi._currencyDecimalDigits = _iCurrencyDigits;
+ nfi._currencyNegativePattern = _iNegativeCurrency;
+ nfi._currencyPositivePattern = _iCurrency;
}
else
{
Debug.Assert(_sWindowsName != null, "[CultureData.GetNFIValues] Expected _sWindowsName to be populated by already");
// String values
- nfi.positiveSign = GetLocaleInfo(LocaleStringData.PositiveSign);
- nfi.negativeSign = GetLocaleInfo(LocaleStringData.NegativeSign);
+ nfi._positiveSign = GetLocaleInfo(LocaleStringData.PositiveSign);
+ nfi._negativeSign = GetLocaleInfo(LocaleStringData.NegativeSign);
- nfi.numberDecimalSeparator = GetLocaleInfo(LocaleStringData.DecimalSeparator);
- nfi.numberGroupSeparator = GetLocaleInfo(LocaleStringData.ThousandSeparator);
- nfi.currencyGroupSeparator = GetLocaleInfo(LocaleStringData.MonetaryThousandSeparator);
- nfi.currencyDecimalSeparator = GetLocaleInfo(LocaleStringData.MonetaryDecimalSeparator);
- nfi.currencySymbol = GetLocaleInfo(LocaleStringData.MonetarySymbol);
+ nfi._numberDecimalSeparator = GetLocaleInfo(LocaleStringData.DecimalSeparator);
+ nfi._numberGroupSeparator = GetLocaleInfo(LocaleStringData.ThousandSeparator);
+ nfi._currencyGroupSeparator = GetLocaleInfo(LocaleStringData.MonetaryThousandSeparator);
+ nfi._currencyDecimalSeparator = GetLocaleInfo(LocaleStringData.MonetaryDecimalSeparator);
+ nfi._currencySymbol = GetLocaleInfo(LocaleStringData.MonetarySymbol);
// Numeric values
- nfi.numberDecimalDigits = GetLocaleInfo(LocaleNumberData.FractionalDigitsCount);
- nfi.currencyDecimalDigits = GetLocaleInfo(LocaleNumberData.MonetaryFractionalDigitsCount);
- nfi.currencyPositivePattern = GetLocaleInfo(LocaleNumberData.PositiveMonetaryNumberFormat);
- nfi.currencyNegativePattern = GetLocaleInfo(LocaleNumberData.NegativeMonetaryNumberFormat);
- nfi.numberNegativePattern = GetLocaleInfo(LocaleNumberData.NegativeNumberFormat);
+ nfi._numberDecimalDigits = GetLocaleInfo(LocaleNumberData.FractionalDigitsCount);
+ nfi._currencyDecimalDigits = GetLocaleInfo(LocaleNumberData.MonetaryFractionalDigitsCount);
+ nfi._currencyPositivePattern = GetLocaleInfo(LocaleNumberData.PositiveMonetaryNumberFormat);
+ nfi._currencyNegativePattern = GetLocaleInfo(LocaleNumberData.NegativeMonetaryNumberFormat);
+ nfi._numberNegativePattern = GetLocaleInfo(LocaleNumberData.NegativeNumberFormat);
// LOCALE_SNATIVEDIGITS (array of 10 single character strings).
string digits = GetLocaleInfo(LocaleStringData.Digits);
- nfi.nativeDigits = new string[10];
- for (int i = 0; i < nfi.nativeDigits.Length; i++)
+ nfi._nativeDigits = new string[10];
+ for (int i = 0; i < nfi._nativeDigits.Length; i++)
{
- nfi.nativeDigits[i] = char.ToString(digits[i]);
+ nfi._nativeDigits[i] = char.ToString(digits[i]);
}
- nfi.digitSubstitution = GetDigitSubstitution(_sRealName);
+ nfi._digitSubstitution = GetDigitSubstitution(_sRealName);
}
- //
// Gather additional data
- //
- nfi.numberGroupSizes = this.WAGROUPING;
- nfi.currencyGroupSizes = this.WAMONGROUPING;
+ nfi._numberGroupSizes = NumberGroupSizes;
+ nfi._currencyGroupSizes = CurrencyGroupSizes;
// prefer the cached value since these do not have user overrides
- nfi.percentNegativePattern = this.INEGATIVEPERCENT;
- nfi.percentPositivePattern = this.IPOSITIVEPERCENT;
- nfi.percentSymbol = this.SPERCENT;
- nfi.perMilleSymbol = this.SPERMILLE;
+ nfi._percentNegativePattern = PercentNegativePattern;
+ nfi._percentPositivePattern = PercentPositivePattern;
+ nfi._percentSymbol = PercentSymbol;
+ nfi._perMilleSymbol = PerMilleSymbol;
- nfi.negativeInfinitySymbol = this.SNEGINFINITY;
- nfi.positiveInfinitySymbol = this.SPOSINFINITY;
- nfi.nanSymbol = this.SNAN;
+ nfi._negativeInfinitySymbol = NegativeInfinitySymbol;
+ nfi._positiveInfinitySymbol = PositiveInfinitySymbol;
+ nfi._nanSymbol = NaNSymbol;
- //
// We don't have percent values, so use the number values
- //
- nfi.percentDecimalDigits = nfi.numberDecimalDigits;
- nfi.percentDecimalSeparator = nfi.numberDecimalSeparator;
- nfi.percentGroupSizes = nfi.numberGroupSizes;
- nfi.percentGroupSeparator = nfi.numberGroupSeparator;
+ nfi._percentDecimalDigits = nfi._numberDecimalDigits;
+ nfi._percentDecimalSeparator = nfi._numberDecimalSeparator;
+ nfi._percentGroupSizes = nfi._numberGroupSizes;
+ nfi._percentGroupSeparator = nfi._numberGroupSeparator;
- //
// Clean up a few odd values
- //
// Windows usually returns an empty positive sign, but we like it to be "+"
- if (nfi.positiveSign == null || nfi.positiveSign.Length == 0) nfi.positiveSign = "+";
+ if (nfi._positiveSign == null || nfi._positiveSign.Length == 0)
+ {
+ nfi._positiveSign = "+";
+ }
- //Special case for Italian. The currency decimal separator in the control panel is the empty string. When the user
- //specifies C4 as the currency format, this results in the number apparently getting multiplied by 10000 because the
- //decimal point doesn't show up. We'll just hack this here because our default currency format will never use nfi.
- if (nfi.currencyDecimalSeparator == null || nfi.currencyDecimalSeparator.Length == 0)
+ // Special case for Italian. The currency decimal separator in the control panel is the empty string. When the user
+ // specifies C4 as the currency format, this results in the number apparently getting multiplied by 10000 because the
+ // decimal point doesn't show up. We'll just hack this here because our default currency format will never use nfi.
+ if (nfi._currencyDecimalSeparator == null || nfi._currencyDecimalSeparator.Length == 0)
{
- nfi.currencyDecimalSeparator = nfi.numberDecimalSeparator;
+ nfi._currencyDecimalSeparator = nfi._numberDecimalSeparator;
}
}
- // Helper
- // This is ONLY used for caching names and shouldn't be used for anything else
- internal static string AnsiToLower(string testString) =>
- TextInfo.ToLowerAsciiInvariant(testString);
+ /// <remarks>
+ /// This is ONLY used for caching names and shouldn't be used for anything else
+ /// </remarks>
+ internal static string AnsiToLower(string testString) => TextInfo.ToLowerAsciiInvariant(testString);
/// <remarks>
/// The numeric values of the enum members match their Win32 counterparts. The CultureData Win32 PAL implementation
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.Windows.cs b/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.Windows.cs
index f66278835b..c5479deac5 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.Windows.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.Windows.cs
@@ -24,14 +24,10 @@ namespace System.Globalization
if (GlobalizationMode.Invariant)
return CultureInfo.InvariantCulture;
- const uint LOCALE_SNAME = 0x0000005c;
- const string LOCALE_NAME_USER_DEFAULT = null;
- const string LOCALE_NAME_SYSTEM_DEFAULT = "!x-sys-default-locale";
-
- string strDefault = CultureData.GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME);
+ string strDefault = CultureData.GetLocaleInfoEx(Interop.Kernel32.LOCALE_NAME_USER_DEFAULT, Interop.Kernel32.LOCALE_SNAME);
if (strDefault == null)
{
- strDefault = CultureData.GetLocaleInfoEx(LOCALE_NAME_SYSTEM_DEFAULT, LOCALE_SNAME);
+ strDefault = CultureData.GetLocaleInfoEx(Interop.Kernel32.LOCALE_NAME_SYSTEM_DEFAULT, Interop.Kernel32.LOCALE_SNAME);
if (strDefault == null)
{
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.cs
index 153512639a..01e5756e86 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/CultureInfo.cs
@@ -35,12 +35,25 @@ using Internal.Runtime.Augments;
namespace System.Globalization
{
+ /// <summary>
+ /// This class represents the software preferences of a particular culture
+ /// or community. It includes information such as the language, writing
+ /// system and a calendar used by the culture as well as methods for
+ /// common operations such as printing dates and sorting strings.
+ /// </summary>
+ /// <remarks>
+ /// !!!! NOTE WHEN CHANGING THIS CLASS !!!!
+ /// If adding or removing members to this class, please update
+ /// CultureInfoBaseObject in ndp/clr/src/vm/object.h. Note, the "actual"
+ /// layout of the class may be different than the order in which members
+ /// are declared. For instance, all reference types will come first in the
+ /// class before value types (like ints, bools, etc) regardless of the
+ /// order in which they are declared. The best way to see the actual
+ /// order of the class is to do a !dumpobj on an instance of the managed
+ /// object inside of the debugger.
+ /// </remarks>
public partial class CultureInfo : IFormatProvider, ICloneable
{
- //--------------------------------------------------------------------//
- // Internal Information //
- //--------------------------------------------------------------------//
-
// We use an RFC4646 type string to construct CultureInfo.
// This string is stored in _name and is authoritative.
// We use the _cultureData to get the data for our object
@@ -68,9 +81,9 @@ namespace System.Globalization
// en-US en-US en-US en-US
// de-de_phoneb de-DE_phoneb de-DE de-DE_phoneb
// fj-fj (custom) fj-FJ fj-FJ en-US (if specified sort is en-US)
- // en en
+ // en en
//
- // Note that in Silverlight we ask the OS for the text and sort behavior, so the
+ // Note that in Silverlight we ask the OS for the text and sort behavior, so the
// textinfo and compareinfo names are the same as the name
// This has a de-DE, de-DE_phoneb or fj-FJ style name
@@ -85,30 +98,21 @@ namespace System.Globalization
// Otherwise its the sort name, ie: de-DE or de-DE_phoneb
private string _sortName;
- //--------------------------------------------------------------------//
- //
- // Static data members
- //
- //--------------------------------------------------------------------//
-
- //Get the current user default culture. This one is almost always used, so we create it by default.
+ // Get the current user default culture. This one is almost always used, so we create it by default.
private static volatile CultureInfo s_userDefaultCulture;
//The culture used in the user interface. This is mostly used to load correct localized resources.
private static volatile CultureInfo s_userDefaultUICulture;
- //
- // All of the following will be created on demand.
- //
// WARNING: We allow diagnostic tools to directly inspect these three members (s_InvariantCultureInfo, s_DefaultThreadCurrentUICulture and s_DefaultThreadCurrentCulture)
- // See https://github.com/dotnet/corert/blob/master/Documentation/design-docs/diagnostics/diagnostics-tools-contract.md for more details.
- // Please do not change the type, the name, or the semantic usage of this member without understanding the implication for tools.
+ // See https://github.com/dotnet/corert/blob/master/Documentation/design-docs/diagnostics/diagnostics-tools-contract.md for more details.
+ // Please do not change the type, the name, or the semantic usage of this member without understanding the implication for tools.
// Get in touch with the diagnostics team if you have questions.
- //The Invariant culture;
+ // The Invariant culture;
private static readonly CultureInfo s_InvariantCultureInfo = new CultureInfo(CultureData.Invariant, isReadOnly: true);
- //These are defaults that we use if a thread has not opted into having an explicit culture
+ // These are defaults that we use if a thread has not opted into having an explicit culture
private static volatile CultureInfo s_DefaultThreadCurrentUICulture;
private static volatile CultureInfo s_DefaultThreadCurrentCulture;
@@ -132,9 +136,9 @@ namespace System.Globalization
private static readonly object _lock = new object();
private static volatile Dictionary<string, CultureInfo> s_NameCachedCultures;
- private static volatile Dictionary<int, CultureInfo> s_LcidCachedCultures;
+ private static volatile Dictionary<int, CultureInfo> s_LcidCachedCultures;
- //The parent culture.
+ // The parent culture.
private CultureInfo _parent;
// LOCALE constants of interest to us internally and privately for LCID functions
@@ -158,14 +162,7 @@ namespace System.Globalization
return s_userDefaultUICulture;
}
- ////////////////////////////////////////////////////////////////////////
- //
- // CultureInfo Constructors
- //
- ////////////////////////////////////////////////////////////////////////
-
- public CultureInfo(string name)
- : this(name, true)
+ public CultureInfo(string name) : this(name, true)
{
}
@@ -173,8 +170,7 @@ namespace System.Globalization
{
if (name == null)
{
- throw new ArgumentNullException(nameof(name),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(name));
}
// Get our data providing record
@@ -186,7 +182,7 @@ namespace System.Globalization
}
_name = _cultureData.CultureName;
- _isInherited = (this.GetType() != typeof(System.Globalization.CultureInfo));
+ _isInherited = GetType() != typeof(CultureInfo);
}
private CultureInfo(CultureData cultureData, bool isReadOnly = false)
@@ -232,22 +228,23 @@ namespace System.Globalization
// Can't support unknown custom cultures and we do not support neutral or
// non-custom user locales.
throw new CultureNotFoundException(nameof(culture), culture, SR.Argument_CultureNotSupported);
-
default:
// Now see if this LCID is supported in the system default CultureData table.
_cultureData = CultureData.GetCultureData(culture, useUserOverride);
break;
}
- _isInherited = (this.GetType() != typeof(System.Globalization.CultureInfo));
+ _isInherited = GetType() != typeof(CultureInfo);
_name = _cultureData.CultureName;
}
- // Constructor called by SQL Server's special munged culture - creates a culture with
- // a TextInfo and CompareInfo that come from a supplied alternate source. This object
- // is ALWAYS read-only.
- // Note that we really cannot use an LCID version of this override as the cached
- // name we create for it has to include both names, and the logic for this is in
- // the GetCultureInfo override *only*.
+ /// <summary>
+ /// Constructor called by SQL Server's special munged culture - creates a culture with
+ /// a TextInfo and CompareInfo that come from a supplied alternate source. This object
+ /// is ALWAYS read-only.
+ /// Note that we really cannot use an LCID version of this override as the cached
+ /// name we create for it has to include both names, and the logic for this is in
+ /// the GetCultureInfo override *only*.
+ /// </summary>
internal CultureInfo(string cultureName, string textAndCompareCultureName)
{
if (cultureName == null)
@@ -257,7 +254,9 @@ namespace System.Globalization
_cultureData = CultureData.GetCultureData(cultureName, false);
if (_cultureData == null)
+ {
throw new CultureNotFoundException(nameof(cultureName), cultureName, SR.Argument_CultureNotSupported);
+ }
_name = _cultureData.CultureName;
@@ -266,38 +265,34 @@ namespace System.Globalization
_textInfo = altCulture.TextInfo;
}
- // We do this to try to return the system UI language and the default user languages
- // This method will fallback if this fails (like Invariant)
- //
+ /// <summary>
+ /// We do this to try to return the system UI language and the default user languages
+ /// This method will fallback if this fails (like Invariant)
+ /// </summary>
private static CultureInfo GetCultureByName(string name)
{
- CultureInfo ci = null;
- // Try to get our culture
try
{
- ci = new CultureInfo(name);
- ci._isReadOnly = true;
+ return new CultureInfo(name)
+ {
+ _isReadOnly = true
+ };
}
catch (ArgumentException)
{
+ return InvariantCulture;
}
-
- if (ci == null)
- {
- ci = InvariantCulture;
- }
-
- return ci;
}
- //
- // Return a specific culture. A tad irrelevent now since we always return valid data
- // for neutral locales.
- //
- // Note that there's interesting behavior that tries to find a smaller name, ala RFC4647,
- // if we can't find a bigger name. That doesn't help with things like "zh" though, so
- // the approach is of questionable value
- //
+ /// <summary>
+ /// Return a specific culture. A tad irrelevent now since we always
+ /// return valid data for neutral locales.
+ ///
+ /// Note that there's interesting behavior that tries to find a
+ /// smaller name, ala RFC4647, if we can't find a bigger name.
+ /// That doesn't help with things like "zh" though, so the approach
+ /// is of questionable value
+ /// </summary>
public static CultureInfo CreateSpecificCulture(string name)
{
CultureInfo culture;
@@ -311,11 +306,8 @@ namespace System.Globalization
// When CultureInfo throws this exception, it may be because someone passed the form
// like "az-az" because it came out of an http accept lang. We should try a little
// parsing to perhaps fall back to "az" here and use *it* to create the neutral.
-
- int idx;
-
culture = null;
- for (idx = 0; idx < name.Length; idx++)
+ for (int idx = 0; idx < name.Length; idx++)
{
if ('-' == name[idx])
{
@@ -345,7 +337,7 @@ namespace System.Globalization
return culture;
}
- return new CultureInfo(culture._cultureData.SSPECIFICCULTURE);
+ return new CultureInfo(culture._cultureData.SpecificCultureName);
}
internal static bool VerifyCultureName(string cultureName, bool throwException)
@@ -353,7 +345,6 @@ namespace System.Globalization
// This function is used by ResourceManager.GetResourceFileName().
// ResourceManager searches for resource using CultureInfo.Name,
// so we should check against CultureInfo.Name.
-
for (int i = 0; i < cultureName.Length; i++)
{
char c = cultureName[i];
@@ -373,8 +364,8 @@ namespace System.Globalization
internal static bool VerifyCultureName(CultureInfo culture, bool throwException)
{
- //If we have an instance of one of our CultureInfos, the user can't have changed the
- //name and we know that all names are valid in files.
+ // If we have an instance of one of our CultureInfos, the user can't have changed the
+ // name and we know that all names are valid in files.
if (!culture._isInherited)
{
return true;
@@ -383,26 +374,21 @@ namespace System.Globalization
return VerifyCultureName(culture.Name, throwException);
}
- ////////////////////////////////////////////////////////////////////////
- //
- // CurrentCulture
- //
- // This instance provides methods based on the current user settings.
- // These settings are volatile and may change over the lifetime of the
- // thread.
- //
- ////////////////////////////////////////////////////////////////////////
-
- //
- // We use the following order to return CurrentCulture and CurrentUICulture
- // o Use WinRT to return the current user profile language
- // o use current thread culture if the user already set one using CurrentCulture/CurrentUICulture
- // o use thread culture if the user already set one using DefaultThreadCurrentCulture
- // or DefaultThreadCurrentUICulture
- // o Use NLS default user culture
- // o Use NLS default system culture
- // o Use Invariant culture
- //
+ /// <summary>
+ /// This instance provides methods based on the current user settings.
+ /// These settings are volatile and may change over the lifetime of the
+ /// thread.
+ /// </summary>
+ /// <remarks>
+ /// We use the following order to return CurrentCulture and CurrentUICulture
+ /// o Use WinRT to return the current user profile language
+ /// o use current thread culture if the user already set one using CurrentCulture/CurrentUICulture
+ /// o use thread culture if the user already set one using DefaultThreadCurrentCulture
+ /// or DefaultThreadCurrentUICulture
+ /// o Use NLS default user culture
+ /// o Use NLS default system culture
+ /// o Use Invariant culture
+ /// </remarks>
public static CultureInfo CurrentCulture
{
get
@@ -436,7 +422,6 @@ namespace System.Globalization
return s_userDefaultCulture ?? InitializeUserDefaultCulture();
}
-
set
{
if (value == null)
@@ -504,7 +489,6 @@ namespace System.Globalization
return UserDefaultUICulture;
}
-
set
{
if (value == null)
@@ -549,23 +533,22 @@ namespace System.Globalization
public static CultureInfo DefaultThreadCurrentCulture
{
- get { return s_DefaultThreadCurrentCulture; }
+ get => s_DefaultThreadCurrentCulture;
set
{
// If you add pre-conditions to this method, check to see if you also need to
// add them to Thread.CurrentCulture.set.
-
s_DefaultThreadCurrentCulture = value;
}
}
public static CultureInfo DefaultThreadCurrentUICulture
{
- get { return s_DefaultThreadCurrentUICulture; }
+ get => s_DefaultThreadCurrentUICulture;
set
{
- //If they're trying to use a Culture with a name that we can't use in resource lookup,
- //don't even let them set it on the thread.
+ // If they're trying to use a Culture with a name that we can't use in resource lookup,
+ // don't even let them set it on the thread.
// If you add more pre-conditions to this method, check to see if you also need to
// add them to Thread.CurrentUICulture.set.
@@ -579,20 +562,14 @@ namespace System.Globalization
}
}
- ////////////////////////////////////////////////////////////////////////
- //
- // InvariantCulture
- //
- // This instance provides methods, for example for casing and sorting,
- // that are independent of the system and current user settings. It
- // should be used only by processes such as some system services that
- // require such invariant results (eg. file systems). In general,
- // the results are not linguistically correct and do not match any
- // culture info.
- //
- ////////////////////////////////////////////////////////////////////////
-
-
+ /// <summary>
+ /// This instance provides methods, for example for casing and sorting,
+ /// that are independent of the system and current user settings. It
+ /// should be used only by processes such as some system services that
+ /// require such invariant results (eg. file systems). In general,
+ /// the results are not linguistically correct and do not match any
+ /// culture info.
+ /// </summary>
public static CultureInfo InvariantCulture
{
get
@@ -602,23 +579,17 @@ namespace System.Globalization
}
}
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Parent
- //
- // Return the parent CultureInfo for the current instance.
- //
- ////////////////////////////////////////////////////////////////////////
-
+ /// <summary>
+ /// Return the parent CultureInfo for the current instance.
+ /// </summary>
public virtual CultureInfo Parent
{
get
{
- if (null == _parent)
+ if (_parent == null)
{
CultureInfo culture = null;
- string parentName = _cultureData.SPARENT;
+ string parentName = _cultureData.ParentName;
if (string.IsNullOrEmpty(parentName))
{
@@ -642,21 +613,9 @@ namespace System.Globalization
}
}
- public virtual int LCID
- {
- get
- {
- return _cultureData.ILANGUAGE;
- }
- }
+ public virtual int LCID => _cultureData.LCID;
- public virtual int KeyboardLayoutId
- {
- get
- {
- return _cultureData.IINPUTLANGUAGEHANDLE;
- }
- }
+ public virtual int KeyboardLayoutId => _cultureData.KeyboardLayoutId;
public static CultureInfo[] GetCultures(CultureTypes types)
{
@@ -669,14 +628,10 @@ namespace System.Globalization
return CultureData.GetCultures(types);
}
- ////////////////////////////////////////////////////////////////////////
- //
- // Name
- //
- // Returns the full name of the CultureInfo. The name is in format like
- // "en-US" This version does NOT include sort information in the name.
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Returns the full name of the CultureInfo. The name is in format like
+ /// "en-US" This version does NOT include sort information in the name.
+ /// </summary>
public virtual string Name
{
get
@@ -684,24 +639,22 @@ namespace System.Globalization
// We return non sorting name here.
if (_nonSortName == null)
{
- _nonSortName = _cultureData.SNAME;
- if (_nonSortName == null)
- {
- _nonSortName = string.Empty;
- }
+ _nonSortName = _cultureData.Name ?? string.Empty;
}
return _nonSortName;
}
}
- // This one has the sort information (ie: de-DE_phoneb)
+ /// <summary>
+ /// This one has the sort information (ie: de-DE_phoneb)
+ /// </summary>
internal string SortName
{
get
{
if (_sortName == null)
{
- _sortName = _cultureData.SCOMPAREINFO;
+ _sortName = _cultureData.SortName;
}
return _sortName;
@@ -725,100 +678,54 @@ namespace System.Globalization
}
}
- ////////////////////////////////////////////////////////////////////////
- //
- // DisplayName
- //
- // Returns the full name of the CultureInfo in the localized language.
- // For example, if the localized language of the runtime is Spanish and the CultureInfo is
- // US English, "Ingles (Estados Unidos)" will be returned.
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Returns the full name of the CultureInfo in the localized language.
+ /// For example, if the localized language of the runtime is Spanish and the CultureInfo is
+ /// US English, "Ingles (Estados Unidos)" will be returned.
+ /// </summary>
public virtual string DisplayName
{
get
{
Debug.Assert(_name != null, "[CultureInfo.DisplayName] Always expect _name to be set");
-
- return _cultureData.SLOCALIZEDDISPLAYNAME;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetNativeName
- //
- // Returns the full name of the CultureInfo in the native language.
- // For example, if the CultureInfo is US English, "English
- // (United States)" will be returned.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string NativeName
- {
- get
- {
- return _cultureData.SNATIVEDISPLAYNAME;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetEnglishName
- //
- // Returns the full name of the CultureInfo in English.
- // For example, if the CultureInfo is US English, "English
- // (United States)" will be returned.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string EnglishName
- {
- get
- {
- return _cultureData.SENGDISPLAYNAME;
+ return _cultureData.DisplayName;
}
}
- // ie: en
- public virtual string TwoLetterISOLanguageName
- {
- get
- {
- return _cultureData.SISO639LANGNAME;
- }
- }
-
- // ie: eng
- public virtual string ThreeLetterISOLanguageName
- {
- get
- {
- return _cultureData.SISO639LANGNAME2;
- }
- }
+ /// <summary>
+ /// Returns the full name of the CultureInfo in the native language.
+ /// For example, if the CultureInfo is US English, "English
+ /// (United States)" will be returned.
+ /// </summary>
+ public virtual string NativeName => _cultureData.NativeName;
+
+ /// <summary>
+ /// Returns the full name of the CultureInfo in English.
+ /// For example, if the CultureInfo is US English, "English
+ /// (United States)" will be returned.
+ /// </summary>
+ public virtual string EnglishName => _cultureData.EnglishName;
+
+ /// <summary>
+ /// ie: en
+ /// </summary>
+ public virtual string TwoLetterISOLanguageName => _cultureData.TwoLetterISOLanguageName;
+
+ /// <summary>
+ /// ie: eng
+ /// </summary>
+ public virtual string ThreeLetterISOLanguageName => _cultureData.ThreeLetterISOLanguageName;
+
+ /// <summary>
+ /// Returns the 3 letter windows language name for the current instance. eg: "ENU"
+ /// The ISO names are much preferred
+ /// </summary>
+ public virtual string ThreeLetterWindowsLanguageName => _cultureData.ThreeLetterWindowsLanguageName;
- ////////////////////////////////////////////////////////////////////////
- //
- // ThreeLetterWindowsLanguageName
- //
- // Returns the 3 letter windows language name for the current instance. eg: "ENU"
- // The ISO names are much preferred
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string ThreeLetterWindowsLanguageName
- {
- get
- {
- return _cultureData.SABBREVLANGNAME;
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
// CompareInfo Read-Only Property
- //
- // Gets the CompareInfo for this culture.
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Gets the CompareInfo for this culture.
+ /// </summary>
public virtual CompareInfo CompareInfo
{
get
@@ -835,13 +742,9 @@ namespace System.Globalization
}
}
- ////////////////////////////////////////////////////////////////////////
- //
- // TextInfo
- //
- // Gets the TextInfo for this culture.
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Gets the TextInfo for this culture.
+ /// </summary>
public virtual TextInfo TextInfo
{
get
@@ -857,81 +760,50 @@ namespace System.Globalization
}
}
- ////////////////////////////////////////////////////////////////////////
- //
- // Equals
- //
- // Implements object.Equals(). Returns a boolean indicating whether
- // or not object refers to the same CultureInfo as the current instance.
- //
- ////////////////////////////////////////////////////////////////////////
-
-
public override bool Equals(object value)
{
if (object.ReferenceEquals(this, value))
+ {
return true;
+ }
if (value is CultureInfo that)
{
// using CompareInfo to verify the data passed through the constructor
// CultureInfo(String cultureName, String textAndCompareCultureName)
-
- return this.Name.Equals(that.Name) && this.CompareInfo.Equals(that.CompareInfo);
+ return Name.Equals(that.Name) && CompareInfo.Equals(that.CompareInfo);
}
return false;
}
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetHashCode
- //
- // Implements object.GetHashCode(). Returns the hash code for the
- // CultureInfo. The hash code is guaranteed to be the same for CultureInfo A
- // and B where A.Equals(B) is true.
- //
- ////////////////////////////////////////////////////////////////////////
-
public override int GetHashCode()
{
- return this.Name.GetHashCode() + this.CompareInfo.GetHashCode();
+ return Name.GetHashCode() + CompareInfo.GetHashCode();
}
- ////////////////////////////////////////////////////////////////////////
- //
- // ToString
- //
- // Implements object.ToString(). Returns the name of the CultureInfo,
- // eg. "de-DE_phoneb", "en-US", or "fj-FJ".
- //
- ////////////////////////////////////////////////////////////////////////
-
-
- public override string ToString()
- {
- return _name;
- }
-
+ /// <summary>
+ /// Implements object.ToString(). Returns the name of the CultureInfo,
+ /// eg. "de-DE_phoneb", "en-US", or "fj-FJ".
+ /// </summary>
+ public override string ToString() => _name;
public virtual object GetFormat(Type formatType)
{
if (formatType == typeof(NumberFormatInfo))
+ {
return NumberFormat;
+ }
if (formatType == typeof(DateTimeFormatInfo))
+ {
return DateTimeFormat;
+ }
+
return null;
}
- public virtual bool IsNeutralCulture
- {
- get
- {
- return _cultureData.IsNeutralCulture;
- }
- }
+ public virtual bool IsNeutralCulture => _cultureData.IsNeutralCulture;
public CultureTypes CultureTypes
{
@@ -940,9 +812,13 @@ namespace System.Globalization
CultureTypes types = 0;
if (_cultureData.IsNeutralCulture)
+ {
types |= CultureTypes.NeutralCultures;
+ }
else
+ {
types |= CultureTypes.SpecificCultures;
+ }
types |= _cultureData.IsWin32Installed ? CultureTypes.InstalledWin32Cultures : 0;
@@ -965,7 +841,7 @@ namespace System.Globalization
if (_numInfo == null)
{
NumberFormatInfo temp = new NumberFormatInfo(_cultureData);
- temp.isReadOnly = _isReadOnly;
+ temp._isReadOnly = _isReadOnly;
Interlocked.CompareExchange(ref _numInfo, temp, null);
}
return _numInfo;
@@ -976,19 +852,16 @@ namespace System.Globalization
{
throw new ArgumentNullException(nameof(value));
}
+
VerifyWritable();
_numInfo = value;
}
}
- ////////////////////////////////////////////////////////////////////////
- //
- // GetDateTimeFormatInfo
- //
- // Create a DateTimeFormatInfo, and fill in the properties according to
- // the CultureID.
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Create a DateTimeFormatInfo, and fill in the properties according to
+ /// the CultureID.
+ /// </summary>
public virtual DateTimeFormatInfo DateTimeFormat
{
get
@@ -1009,6 +882,7 @@ namespace System.Globalization
{
throw new ArgumentNullException(nameof(value));
}
+
VerifyWritable();
_dateTimeInfo = value;
}
@@ -1021,7 +895,7 @@ namespace System.Globalization
s_userDefaultUICulture = GetUserDefaultUICulture();
RegionInfo.s_currentRegionInfo = null;
-#pragma warning disable 0618 // disable the obsolete warning
+#pragma warning disable 0618 // disable the obsolete warning
TimeZone.ResetTimeZone();
#pragma warning restore 0618
TimeZoneInfo.ClearCachedData();
@@ -1031,25 +905,29 @@ namespace System.Globalization
CultureData.ClearCachedData();
}
- /*=================================GetCalendarInstance==========================
- **Action: Map a Win32 CALID to an instance of supported calendar.
- **Returns: An instance of calendar.
- **Arguments: calType The Win32 CALID
- **Exceptions:
- ** Shouldn't throw exception since the calType value is from our data table or from Win32 registry.
- ** If we are in trouble (like getting a weird value from Win32 registry), just return the GregorianCalendar.
- ============================================================================*/
+ /// <summary>
+ /// Map a Win32 CALID to an instance of supported calendar.
+ /// </summary>
+ /// <remarks>
+ /// Shouldn't throw exception since the calType value is from our data
+ /// table or from Win32 registry.
+ /// If we are in trouble (like getting a weird value from Win32
+ /// registry), just return the GregorianCalendar.
+ /// </remarks>
internal static Calendar GetCalendarInstance(CalendarId calType)
{
if (calType == CalendarId.GREGORIAN)
{
return new GregorianCalendar();
}
+
return GetCalendarInstanceRare(calType);
}
- //This function exists as a shortcut to prevent us from loading all of the non-gregorian
- //calendars unless they're required.
+ /// <summary>
+ /// This function exists as a shortcut to prevent us from loading all of the non-gregorian
+ /// calendars unless they're required.
+ /// </summary>
internal static Calendar GetCalendarInstanceRare(CalendarId calType)
{
Debug.Assert(calType != CalendarId.GREGORIAN, "calType!=CalendarId.GREGORIAN");
@@ -1082,13 +960,10 @@ namespace System.Globalization
return new GregorianCalendar();
}
- /*=================================Calendar==========================
- **Action: Return/set the default calendar used by this culture.
- ** This value can be overridden by regional option if this is a current culture.
- **Returns:
- **Arguments:
- **Exceptions:
- ============================================================================*/
+ /// <summary>
+ /// Return/set the default calendar used by this culture.
+ /// This value can be overridden by regional option if this is a current culture.
+ /// </summary>
public virtual Calendar Calendar
{
get
@@ -1100,7 +975,7 @@ namespace System.Globalization
// from registry if this is a user default culture.
Calendar newObj = _cultureData.DefaultCalendar;
- System.Threading.Interlocked.MemoryBarrier();
+ Interlocked.MemoryBarrier();
newObj.SetReadOnlyState(_isReadOnly);
_calendar = newObj;
}
@@ -1108,21 +983,14 @@ namespace System.Globalization
}
}
- /*=================================OptionCalendars==========================
- **Action: Return an array of the optional calendar for this culture.
- **Returns: an array of Calendar.
- **Arguments:
- **Exceptions:
- ============================================================================*/
-
-
+ /// <summary>
+ /// Return an array of the optional calendar for this culture.
+ /// </summary>
public virtual Calendar[] OptionalCalendars
{
get
{
- //
// This property always returns a new copy of the calendar array.
- //
CalendarId[] calID = _cultureData.CalendarIds;
Calendar[] cals = new Calendar[calID.Length];
for (int i = 0; i < cals.Length; i++)
@@ -1133,13 +1001,7 @@ namespace System.Globalization
}
}
- public bool UseUserOverride
- {
- get
- {
- return _cultureData.UseUserOverride;
- }
- }
+ public bool UseUserOverride => _cultureData.UseUserOverride;
public CultureInfo GetConsoleFallbackUICulture()
{
@@ -1158,8 +1020,8 @@ namespace System.Globalization
CultureInfo ci = (CultureInfo)MemberwiseClone();
ci._isReadOnly = false;
- //If this is exactly our type, we can make certain optimizations so that we don't allocate NumberFormatInfo or DTFI unless
- //they've already been allocated. If this is a derived type, we'll take a more generic codepath.
+ // If this is exactly our type, we can make certain optimizations so that we don't allocate NumberFormatInfo or DTFI unless
+ // they've already been allocated. If this is a derived type, we'll take a more generic codepath.
if (!_isInherited)
{
if (_dateTimeInfo != null)
@@ -1205,8 +1067,8 @@ namespace System.Globalization
if (!ci.IsNeutralCulture)
{
- //If this is exactly our type, we can make certain optimizations so that we don't allocate NumberFormatInfo or DTFI unless
- //they've already been allocated. If this is a derived type, we'll take a more generic codepath.
+ // If this is exactly our type, we can make certain optimizations so that we don't allocate NumberFormatInfo or DTFI unless
+ // they've already been allocated. If this is a derived type, we'll take a more generic codepath.
if (!ci._isInherited)
{
if (ci._dateTimeInfo != null)
@@ -1243,13 +1105,7 @@ namespace System.Globalization
}
- public bool IsReadOnly
- {
- get
- {
- return _isReadOnly;
- }
- }
+ public bool IsReadOnly => _isReadOnly;
private void VerifyWritable()
{
@@ -1259,16 +1115,20 @@ namespace System.Globalization
}
}
- // For resource lookup, we consider a culture the invariant culture by name equality.
- // We perform this check frequently during resource lookup, so adding a property for
- // improved readability.
+ /// <summary>
+ /// For resource lookup, we consider a culture the invariant culture by name equality.
+ /// We perform this check frequently during resource lookup, so adding a property for
+ /// improved readability.
+ /// </summary>
internal bool HasInvariantCultureName
{
- get { return Name == CultureInfo.InvariantCulture.Name; }
+ get => Name == CultureInfo.InvariantCulture.Name;
}
- // Helper function both both overloads of GetCachedReadOnlyCulture. If lcid is 0, we use the name.
- // If lcid is -1, use the altName and create one of those special SQL cultures.
+ /// <summary>
+ /// Helper function both both overloads of GetCachedReadOnlyCulture. If lcid is 0, we use the name.
+ /// If lcid is -1, use the altName and create one of those special SQL cultures.
+ /// </summary>
internal static CultureInfo GetCultureInfoHelper(int lcid, string name, string altName)
{
// retval is our return value.
@@ -1384,7 +1244,7 @@ namespace System.Globalization
{
tempNameHT[newName] = retval;
}
- }
+ }
else
{
lock (_lock)
@@ -1407,8 +1267,10 @@ namespace System.Globalization
return retval;
}
- // Gets a cached copy of the specified culture from an internal hashtable (or creates it
- // if not found). (LCID version)... use named version
+ /// <summary>
+ /// Gets a cached copy of the specified culture from an internal
+ /// hashtable (or creates it if not found). (LCID version)
+ /// </summary>
public static CultureInfo GetCultureInfo(int culture)
{
// Must check for -1 now since the helper function uses the value to signal
@@ -1426,8 +1288,10 @@ namespace System.Globalization
return retval;
}
- // Gets a cached copy of the specified culture from an internal hashtable (or creates it
- // if not found). (Named version)
+ /// <summary>
+ /// Gets a cached copy of the specified culture from an internal
+ /// hashtable (or creates it if not found). (Named version)
+ /// </summary>
public static CultureInfo GetCultureInfo(string name)
{
// Make sure we have a valid, non-zero length string as name
@@ -1445,16 +1309,16 @@ namespace System.Globalization
return retval;
}
- // Gets a cached copy of the specified culture from an internal hashtable (or creates it
- // if not found).
+ /// <summary>
+ /// Gets a cached copy of the specified culture from an internal
+ /// hashtable (or creates it if not found).
+ /// </summary>
public static CultureInfo GetCultureInfo(string name, string altName)
{
- // Make sure we have a valid, non-zero length string as name
if (name == null)
{
throw new ArgumentNullException(nameof(name));
}
-
if (altName == null)
{
throw new ArgumentNullException(nameof(altName));
@@ -1469,7 +1333,6 @@ namespace System.Globalization
return retval;
}
- // This function is deprecated, we don't like it
public static CultureInfo GetCultureInfoByIetfLanguageTag(string name)
{
// Disallow old zh-CHT/zh-CHS names
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs
index b105324a6b..5bf9f4ef25 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormat.cs
@@ -282,7 +282,7 @@ namespace System
if (dtfi.Calendar.IsLeapYear(dtfi.Calendar.GetYear(time)))
{
// This month is in a leap year
- return (dtfi.internalGetMonthName(month, MonthNameStyles.LeapYear, (repeatCount == 3)));
+ return dtfi.InternalGetMonthName(month, MonthNameStyles.LeapYear, (repeatCount == 3));
}
// This is in a regular year.
if (month >= 7)
@@ -346,10 +346,7 @@ namespace System
if (!foundQuote)
{
// Here we can't find the matching quote.
- throw new FormatException(
- string.Format(
- CultureInfo.CurrentCulture,
- SR.Format_BadQuote, quoteChar));
+ throw new FormatException(SR.Format(SR.Format_BadQuote, quoteChar));
}
//
@@ -633,7 +630,7 @@ namespace System
if ((dtfi.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != 0)
{
result.Append(
- dtfi.internalGetMonthName(
+ dtfi.InternalGetMonthName(
month,
IsUseGenitiveForm(format, i, tokenLen, 'd') ? MonthNameStyles.Genitive : MonthNameStyles.Regular,
tokenLen == 3));
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfo.cs
index 8123d37790..310771db02 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfo.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeFormatInfo.cs
@@ -8,13 +8,13 @@ using System.Runtime.CompilerServices;
namespace System.Globalization
{
- //
- // Flags used to indicate different styles of month names.
- // This is an internal flag used by internalGetMonthName().
- // Use flag here in case that we need to provide a combination of these styles
- // (such as month name of a leap year in genitive form. Not likely for now,
- // but would like to keep the option open).
- //
+ /// <summary>
+ /// Flags used to indicate different styles of month names.
+ /// This is an internal flag used by internalGetMonthName().
+ /// Use flag here in case that we need to provide a combination of these styles
+ /// (such as month name of a leap year in genitive form. Not likely for now,
+ /// but would like to keep the option open).
+ /// </summary>
[Flags]
internal enum MonthNameStyles
@@ -24,15 +24,15 @@ namespace System.Globalization
LeapYear = 0x00000002,
}
- //
- // Flags used to indicate special rule used in parsing/formatting
- // for a specific DateTimeFormatInfo instance.
- // This is an internal flag.
- //
- // This flag is different from MonthNameStyles because this flag
- // can be expanded to accommodate parsing behaviors like CJK month names
- // or alternative month names, etc.
-
+ /// <summary>
+ /// Flags used to indicate special rule used in parsing/formatting
+ /// for a specific DateTimeFormatInfo instance.
+ /// This is an internal flag.
+ ///
+ /// This flag is different from MonthNameStyles because this flag
+ /// can be expanded to accommodate parsing behaviors like CJK month names
+ /// or alternative month names, etc.
+ /// </summary>
[Flags]
internal enum DateTimeFormatFlags
{
@@ -47,7 +47,6 @@ namespace System.Globalization
NotInitialized = -1,
}
-
public sealed class DateTimeFormatInfo : IFormatProvider, ICloneable
{
// cache for the invariant culture.
@@ -69,10 +68,6 @@ namespace System.Globalization
// Culture matches current DTFI. mainly used for string comparisons during parsing.
private CultureInfo _cultureInfo = null;
- //
- // Caches for various properties.
- //
-
private string amDesignator = null;
private string pmDesignator = null;
@@ -84,37 +79,29 @@ namespace System.Globalization
private string timeSeparator = null; // derived from long time (whidbey expects, arrowhead doesn't)
private string monthDayPattern = null;
- // added in .NET Framework Release {2.0SP1/3.0SP1/3.5RTM}
private string dateTimeOffsetPattern = null;
- //
- // The following are constant values.
- //
private const string rfc1123Pattern = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'";
// The sortable pattern is based on ISO 8601.
private const string sortableDateTimePattern = "yyyy'-'MM'-'dd'T'HH':'mm':'ss";
private const string universalSortableDateTimePattern = "yyyy'-'MM'-'dd HH':'mm':'ss'Z'";
- //
- // The following are affected by calendar settings.
- //
private Calendar calendar = null;
private int firstDayOfWeek = -1;
private int calendarWeekRule = -1;
-
private string fullDateTimePattern = null; // long date + long time (whidbey expects, arrowhead doesn't)
private string[] abbreviatedDayNames = null;
-
private string[] m_superShortDayNames = null;
private string[] dayNames = null;
private string[] abbreviatedMonthNames = null;
private string[] monthNames = null;
+
// Cache the genitive month names that we retrieve from the data table.
private string[] genitiveMonthNames = null;
@@ -124,7 +111,6 @@ namespace System.Globalization
private string[] m_genitiveAbbreviatedMonthNames = null;
// Cache the month names of a leap year that we retrieve from the data table.
-
private string[] leapYearMonthNames = null;
// For our "patterns" arrays we have 2 variables, a string and a string[]
@@ -164,17 +150,7 @@ namespace System.Globalization
private DateTimeFormatFlags formatFlags = DateTimeFormatFlags.NotInitialized;
- private string CultureName
- {
- get
- {
- if (_name == null)
- {
- _name = _cultureData.CultureName;
- }
- return (_name);
- }
- }
+ private string CultureName => _name ?? (_name = _cultureData.CultureName);
private CultureInfo Culture
{
@@ -182,116 +158,98 @@ namespace System.Globalization
{
if (_cultureInfo == null)
{
- _cultureInfo = CultureInfo.GetCultureInfo(this.CultureName);
+ _cultureInfo = CultureInfo.GetCultureInfo(CultureName);
}
return _cultureInfo;
}
}
- // TODO: This ignores other cultures that might want to do something similar
private string LanguageName
{
get
{
if (_langName == null)
{
- _langName = _cultureData.SISO639LANGNAME;
+ _langName = _cultureData.TwoLetterISOLanguageName;
}
- return (_langName);
+ return _langName;
}
}
- ////////////////////////////////////////////////////////////////////////////
- //
- // Create an array of string which contains the abbreviated day names.
- //
- ////////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Create an array of string which contains the abbreviated day names.
+ /// </summary>
+ private string[] InternalGetAbbreviatedDayOfWeekNames() => abbreviatedDayNames ?? InternalGetAbbreviatedDayOfWeekNamesCore();
- private string[] internalGetAbbreviatedDayOfWeekNames() => this.abbreviatedDayNames ?? internalGetAbbreviatedDayOfWeekNamesCore();
[MethodImpl(MethodImplOptions.NoInlining)]
- private string[] internalGetAbbreviatedDayOfWeekNamesCore()
+ private string[] InternalGetAbbreviatedDayOfWeekNamesCore()
{
// Get the abbreviated day names for our current calendar
- this.abbreviatedDayNames = _cultureData.AbbreviatedDayNames(Calendar.ID);
- Debug.Assert(this.abbreviatedDayNames.Length == 7, "[DateTimeFormatInfo.GetAbbreviatedDayOfWeekNames] Expected 7 day names in a week");
- return this.abbreviatedDayNames;
+ abbreviatedDayNames = _cultureData.AbbreviatedDayNames(Calendar.ID);
+ Debug.Assert(abbreviatedDayNames.Length == 7, "[DateTimeFormatInfo.GetAbbreviatedDayOfWeekNames] Expected 7 day names in a week");
+ return abbreviatedDayNames;
}
- ////////////////////////////////////////////////////////////////////////
- //
- // Action: Returns the string array of the one-letter day of week names.
- // Returns:
- // an array of one-letter day of week names
- // Arguments:
- // None
- // Exceptions:
- // None
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Returns the string array of the one-letter day of week names.
+ /// </summary>
+ private string[] InternalGetSuperShortDayNames() => m_superShortDayNames ?? InternalGetSuperShortDayNamesCore();
- private string[] internalGetSuperShortDayNames() => this.m_superShortDayNames ?? internalGetSuperShortDayNamesCore();
[MethodImpl(MethodImplOptions.NoInlining)]
- private string[] internalGetSuperShortDayNamesCore()
+ private string[] InternalGetSuperShortDayNamesCore()
{
// Get the super short day names for our current calendar
- this.m_superShortDayNames = _cultureData.SuperShortDayNames(Calendar.ID);
- Debug.Assert(this.m_superShortDayNames.Length == 7, "[DateTimeFormatInfo.internalGetSuperShortDayNames] Expected 7 day names in a week");
- return this.m_superShortDayNames;
+ m_superShortDayNames = _cultureData.SuperShortDayNames(Calendar.ID);
+ Debug.Assert(m_superShortDayNames.Length == 7, "[DateTimeFormatInfo.InternalGetSuperShortDayNames] Expected 7 day names in a week");
+ return m_superShortDayNames;
}
- ////////////////////////////////////////////////////////////////////////////
- //
- // Create an array of string which contains the day names.
- //
- ////////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Create an array of string which contains the day names.
+ /// </summary>
+ private string[] InternalGetDayOfWeekNames() => dayNames ?? InternalGetDayOfWeekNamesCore();
- private string[] internalGetDayOfWeekNames() => this.dayNames ?? internalGetDayOfWeekNamesCore();
[MethodImpl(MethodImplOptions.NoInlining)]
- private string[] internalGetDayOfWeekNamesCore()
+ private string[] InternalGetDayOfWeekNamesCore()
{
// Get the day names for our current calendar
- this.dayNames = _cultureData.DayNames(Calendar.ID);
- Debug.Assert(this.dayNames.Length == 7, "[DateTimeFormatInfo.GetDayOfWeekNames] Expected 7 day names in a week");
- return this.dayNames;
+ dayNames = _cultureData.DayNames(Calendar.ID);
+ Debug.Assert(dayNames.Length == 7, "[DateTimeFormatInfo.GetDayOfWeekNames] Expected 7 day names in a week");
+ return dayNames;
}
- ////////////////////////////////////////////////////////////////////////////
- //
- // Create an array of string which contains the abbreviated month names.
- //
- ////////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Create an array of string which contains the abbreviated month names.
+ /// </summary>
+ private string[] InternalGetAbbreviatedMonthNames() => abbreviatedMonthNames ?? InternalGetAbbreviatedMonthNamesCore();
- private string[] internalGetAbbreviatedMonthNames() => this.abbreviatedMonthNames ?? internalGetAbbreviatedMonthNamesCore();
[MethodImpl(MethodImplOptions.NoInlining)]
- private string[] internalGetAbbreviatedMonthNamesCore()
+ private string[] InternalGetAbbreviatedMonthNamesCore()
{
// Get the month names for our current calendar
- this.abbreviatedMonthNames = _cultureData.AbbreviatedMonthNames(Calendar.ID);
- Debug.Assert(this.abbreviatedMonthNames.Length == 12 || this.abbreviatedMonthNames.Length == 13,
+ abbreviatedMonthNames = _cultureData.AbbreviatedMonthNames(Calendar.ID);
+ Debug.Assert(abbreviatedMonthNames.Length == 12 || abbreviatedMonthNames.Length == 13,
"[DateTimeFormatInfo.GetAbbreviatedMonthNames] Expected 12 or 13 month names in a year");
- return this.abbreviatedMonthNames;
+ return abbreviatedMonthNames;
}
- ////////////////////////////////////////////////////////////////////////////
- //
- // Create an array of string which contains the month names.
- //
- ////////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Create an array of string which contains the month names.
+ /// </summary>
+ private string[] InternalGetMonthNames() => monthNames ?? internalGetMonthNamesCore();
- private string[] internalGetMonthNames() => this.monthNames ?? internalGetMonthNamesCore();
[MethodImpl(MethodImplOptions.NoInlining)]
private string[] internalGetMonthNamesCore()
{
// Get the month names for our current calendar
- this.monthNames = _cultureData.MonthNames(Calendar.ID);
- Debug.Assert(this.monthNames.Length == 12 || this.monthNames.Length == 13,
+ monthNames = _cultureData.MonthNames(Calendar.ID);
+ Debug.Assert(monthNames.Length == 12 || monthNames.Length == 13,
"[DateTimeFormatInfo.GetMonthNames] Expected 12 or 13 month names in a year");
- return this.monthNames;
+ return monthNames;
}
- //
// Invariant DateTimeFormatInfo doesn't have user-overriden values
// Default calendar is gregorian
public DateTimeFormatInfo()
@@ -307,7 +265,7 @@ namespace System.Globalization
// Remember our culture
_cultureData = cultureData;
- this.Calendar = cal;
+ Calendar = cal;
}
private void InitializeOverridableProperties(CultureData cultureData, CalendarId calendarId)
@@ -315,35 +273,52 @@ namespace System.Globalization
Debug.Assert(cultureData != null);
Debug.Assert(calendarId != CalendarId.UNINITIALIZED_VALUE, "[DateTimeFormatInfo.Populate] Expected initalized calendarId");
- if (this.firstDayOfWeek == -1) { this.firstDayOfWeek = cultureData.IFIRSTDAYOFWEEK; }
- if (this.calendarWeekRule == -1) { this.calendarWeekRule = cultureData.IFIRSTWEEKOFYEAR; }
+ if (firstDayOfWeek == -1)
+ {
+ firstDayOfWeek = cultureData.FirstDayOfWeek;
+ }
+ if (calendarWeekRule == -1)
+ {
+ calendarWeekRule = cultureData.CalendarWeekRule;
+ }
- if (this.amDesignator == null) { this.amDesignator = cultureData.SAM1159; }
- if (this.pmDesignator == null) { this.pmDesignator = cultureData.SPM2359; }
- if (this.timeSeparator == null) { this.timeSeparator = cultureData.TimeSeparator; }
- if (this.dateSeparator == null) { this.dateSeparator = cultureData.DateSeparator(calendarId); }
+ if (amDesignator == null)
+ {
+ amDesignator = cultureData.AMDesignator;
+ }
+ if (pmDesignator == null)
+ {
+ pmDesignator = cultureData.PMDesignator;
+ }
+ if (timeSeparator == null)
+ {
+ timeSeparator = cultureData.TimeSeparator;
+ }
+ if (dateSeparator == null)
+ {
+ dateSeparator = cultureData.DateSeparator(calendarId);
+ }
- this.allLongTimePatterns = _cultureData.LongTimes;
- Debug.Assert(this.allLongTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long time patterns");
+ allLongTimePatterns = _cultureData.LongTimes;
+ Debug.Assert(allLongTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long time patterns");
- this.allShortTimePatterns = _cultureData.ShortTimes;
- Debug.Assert(this.allShortTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short time patterns");
+ allShortTimePatterns = _cultureData.ShortTimes;
+ Debug.Assert(allShortTimePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short time patterns");
- this.allLongDatePatterns = cultureData.LongDates(calendarId);
- Debug.Assert(this.allLongDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long date patterns");
+ allLongDatePatterns = cultureData.LongDates(calendarId);
+ Debug.Assert(allLongDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some long date patterns");
- this.allShortDatePatterns = cultureData.ShortDates(calendarId);
- Debug.Assert(this.allShortDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short date patterns");
+ allShortDatePatterns = cultureData.ShortDates(calendarId);
+ Debug.Assert(allShortDatePatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some short date patterns");
- this.allYearMonthPatterns = cultureData.YearMonths(calendarId);
- Debug.Assert(this.allYearMonthPatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some year month patterns");
+ allYearMonthPatterns = cultureData.YearMonths(calendarId);
+ Debug.Assert(allYearMonthPatterns.Length > 0, "[DateTimeFormatInfo.Populate] Expected some year month patterns");
}
- // Returns a default DateTimeFormatInfo that will be universally
- // supported and constant irrespective of the current culture.
- // Used by FromString methods.
- //
-
+ /// <summary>
+ /// Returns a default DateTimeFormatInfo that will be universally
+ /// supported and constant irrespective of the current culture.
+ /// </summary>
public static DateTimeFormatInfo InvariantInfo
{
get
@@ -355,12 +330,13 @@ namespace System.Globalization
info._isReadOnly = true;
s_invariantInfo = info;
}
- return (s_invariantInfo);
+ return s_invariantInfo;
}
}
- // Returns the current culture's DateTimeFormatInfo. Used by Parse methods.
- //
+ /// <summary>
+ /// Returns the current culture's DateTimeFormatInfo.
+ /// </summary>
public static DateTimeFormatInfo CurrentInfo
{
@@ -388,42 +364,42 @@ namespace System.Globalization
public object GetFormat(Type formatType)
{
- return (formatType == typeof(DateTimeFormatInfo) ? this : null);
+ return formatType == typeof(DateTimeFormatInfo) ? this : null;
}
-
public object Clone()
{
DateTimeFormatInfo n = (DateTimeFormatInfo)MemberwiseClone();
// We can use the data member calendar in the setter, instead of the property Calendar,
// since the cloned copy should have the same state as the original copy.
- n.calendar = (Calendar)this.Calendar.Clone();
+ n.calendar = (Calendar)Calendar.Clone();
n._isReadOnly = false;
return n;
}
-
public string AMDesignator
{
get
{
- if (this.amDesignator == null)
+ if (amDesignator == null)
{
- this.amDesignator = _cultureData.SAM1159;
+ amDesignator = _cultureData.AMDesignator;
}
- Debug.Assert(this.amDesignator != null, "DateTimeFormatInfo.AMDesignator, amDesignator != null");
- return (this.amDesignator);
- }
+ Debug.Assert(amDesignator != null, "DateTimeFormatInfo.AMDesignator, amDesignator != null");
+ return amDesignator;
+ }
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
+
ClearTokenHashTable();
amDesignator = value;
}
@@ -434,36 +410,35 @@ namespace System.Globalization
{
get
{
- Debug.Assert(this.calendar != null, "DateTimeFormatInfo.Calendar: calendar != null");
- return (this.calendar);
+ Debug.Assert(calendar != null, "DateTimeFormatInfo.Calendar: calendar != null");
+ return calendar;
}
-
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
throw new ArgumentNullException(nameof(value));
}
+
if (value == calendar)
{
return;
}
- for (int i = 0; i < this.OptionalCalendars.Length; i++)
+ for (int i = 0; i < OptionalCalendars.Length; i++)
{
- if (this.OptionalCalendars[i] == value.ID)
+ if (OptionalCalendars[i] == value.ID)
{
// We can use this one, so do so.
-
// Clean related properties if we already had a calendar set
if (calendar != null)
{
// clean related properties which are affected by the calendar setting,
// so that they will be refreshed when they are accessed next time.
- //
-
// These properites are in the order as appearing in calendar.xml.
m_eraNames = null;
m_abbrevEraNames = null;
@@ -521,7 +496,7 @@ namespace System.Globalization
}
// The assigned calendar is not a valid calendar for this culture, throw
- throw new ArgumentOutOfRangeException(nameof(value), SR.Argument_InvalidCalendar);
+ throw new ArgumentOutOfRangeException(nameof(value), value, SR.Argument_InvalidCalendar);
}
}
@@ -529,29 +504,22 @@ namespace System.Globalization
{
get
{
- if (this.optionalCalendars == null)
+ if (optionalCalendars == null)
{
- this.optionalCalendars = _cultureData.CalendarIds;
+ optionalCalendars = _cultureData.CalendarIds;
}
- return (this.optionalCalendars);
+ return optionalCalendars;
}
}
- /*=================================GetEra==========================
- **Action: Get the era value by parsing the name of the era.
- **Returns: The era value for the specified era name.
- ** -1 if the name of the era is not valid or not supported.
- **Arguments: eraName the name of the era.
- **Exceptions: None.
- ============================================================================*/
-
-
+ /// <summary>
+ /// Get the era value by parsing the name of the era.
+ /// </summary>
public int GetEra(string eraName)
{
if (eraName == null)
{
- throw new ArgumentNullException(nameof(eraName),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(eraName));
}
// The Era Name and Abbreviated Era Name
@@ -561,7 +529,7 @@ namespace System.Globalization
// confer 85900 DTFI.GetEra("") should fail on all cultures
if (eraName.Length == 0)
{
- return (-1);
+ return -1;
}
// The following is based on the assumption that the era value is starting from 1, and has a
@@ -575,18 +543,18 @@ namespace System.Globalization
// Compare the era name in a case-insensitive way for the appropriate culture.
if (m_eraNames[i].Length > 0)
{
- if (this.Culture.CompareInfo.Compare(eraName, m_eraNames[i], CompareOptions.IgnoreCase) == 0)
+ if (Culture.CompareInfo.Compare(eraName, m_eraNames[i], CompareOptions.IgnoreCase) == 0)
{
- return (i + 1);
+ return i + 1;
}
}
}
for (int i = 0; i < AbbreviatedEraNames.Length; i++)
{
// Compare the abbreviated era name in a case-insensitive way for the appropriate culture.
- if (this.Culture.CompareInfo.Compare(eraName, m_abbrevEraNames[i], CompareOptions.IgnoreCase) == 0)
+ if (Culture.CompareInfo.Compare(eraName, m_abbrevEraNames[i], CompareOptions.IgnoreCase) == 0)
{
- return (i + 1);
+ return i + 1;
}
}
for (int i = 0; i < AbbreviatedEnglishEraNames.Length; i++)
@@ -595,35 +563,28 @@ namespace System.Globalization
// interesting characters.
if (CompareInfo.Invariant.Compare(eraName, m_abbrevEnglishEraNames[i], CompareOptions.IgnoreCase) == 0)
{
- return (i + 1);
+ return i + 1;
}
}
- return (-1);
+ return -1;
}
-
internal string[] EraNames
{
get
{
- if (this.m_eraNames == null)
+ if (m_eraNames == null)
{
- this.m_eraNames = _cultureData.EraNames(Calendar.ID); ;
+ m_eraNames = _cultureData.EraNames(Calendar.ID);
}
- return (this.m_eraNames);
+ return m_eraNames;
}
}
- /*=================================GetEraName==========================
- **Action: Get the name of the era for the specified era value.
- **Returns: The name of the specified era.
- **Arguments:
- ** era the era value.
- **Exceptions:
- ** ArguementException if the era valie is invalid.
- ============================================================================*/
-
- // Era names are 1 indexed
+ /// <summary>
+ /// Get the name of the era for the specified era value.
+ /// Era names are 1 indexed
+ /// </summary>
public string GetEraName(int era)
{
if (era == Calendar.CurrentEra)
@@ -636,31 +597,34 @@ namespace System.Globalization
// If that ever changes, the code has to be changed.
if ((--era) < EraNames.Length && (era >= 0))
{
- return (m_eraNames[era]);
+ return m_eraNames[era];
}
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
+
+ throw new ArgumentOutOfRangeException(nameof(era), era, SR.ArgumentOutOfRange_InvalidEraValue);
}
internal string[] AbbreviatedEraNames
{
get
{
- if (this.m_abbrevEraNames == null)
+ if (m_abbrevEraNames == null)
{
- this.m_abbrevEraNames = _cultureData.AbbrevEraNames(Calendar.ID);
+ m_abbrevEraNames = _cultureData.AbbrevEraNames(Calendar.ID);
}
- return (this.m_abbrevEraNames);
+ return m_abbrevEraNames;
}
}
- // Era names are 1 indexed
+ /// <remarks>
+ /// Era names are 1 indexed
+ /// </remarks>
public string GetAbbreviatedEraName(int era)
{
if (AbbreviatedEraNames.Length == 0)
{
// If abbreviation era name is not used in this culture,
// return the full era name.
- return (GetEraName(era));
+ return GetEraName(era);
}
if (era == Calendar.CurrentEra)
{
@@ -668,26 +632,29 @@ namespace System.Globalization
}
if ((--era) < m_abbrevEraNames.Length && (era >= 0))
{
- return (m_abbrevEraNames[era]);
+ return m_abbrevEraNames[era];
}
- throw new ArgumentOutOfRangeException(nameof(era), SR.ArgumentOutOfRange_InvalidEraValue);
+
+ throw new ArgumentOutOfRangeException(nameof(era), era, SR.ArgumentOutOfRange_InvalidEraValue);
}
internal string[] AbbreviatedEnglishEraNames
{
get
{
- if (this.m_abbrevEnglishEraNames == null)
+ if (m_abbrevEnglishEraNames == null)
{
Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.AbbreviatedEnglishEraNames] Expected Calendar.ID > 0");
- this.m_abbrevEnglishEraNames = _cultureData.AbbreviatedEnglishEraNames(Calendar.ID);
+ m_abbrevEnglishEraNames = _cultureData.AbbreviatedEnglishEraNames(Calendar.ID);
}
- return (this.m_abbrevEnglishEraNames);
+ return m_abbrevEnglishEraNames;
}
}
- // Note that cultureData derives this from the short date format (unless someone's set this previously)
- // Note that this property is quite undesirable.
+ /// <remarks>
+ /// Note that cultureData derives this from the short date format (unless someone's set this previously)
+ /// Note that this property is quite undesirable.
+ /// </remarks>
public string DateSeparator
{
get
@@ -696,18 +663,20 @@ namespace System.Globalization
{
dateSeparator = _cultureData.DateSeparator(Calendar.ID);
}
- Debug.Assert(this.dateSeparator != null, "DateTimeFormatInfo.DateSeparator, dateSeparator != null");
+ Debug.Assert(dateSeparator != null, "DateTimeFormatInfo.DateSeparator, dateSeparator != null");
return dateSeparator;
}
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
-
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
+
ClearTokenHashTable();
dateSeparator = value;
}
@@ -717,29 +686,30 @@ namespace System.Globalization
{
get
{
- if (this.firstDayOfWeek == -1)
+ if (firstDayOfWeek == -1)
{
- this.firstDayOfWeek = _cultureData.IFIRSTDAYOFWEEK;
+ firstDayOfWeek = _cultureData.FirstDayOfWeek;
}
- Debug.Assert(this.firstDayOfWeek != -1, "DateTimeFormatInfo.FirstDayOfWeek, firstDayOfWeek != -1");
+ Debug.Assert(firstDayOfWeek != -1, "DateTimeFormatInfo.FirstDayOfWeek, firstDayOfWeek != -1");
- return ((DayOfWeek)this.firstDayOfWeek);
+ return (DayOfWeek)firstDayOfWeek;
}
-
set
{
if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value >= DayOfWeek.Sunday && value <= DayOfWeek.Saturday)
{
- firstDayOfWeek = (int)value;
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
- else
+
+ if (value < DayOfWeek.Sunday || value > DayOfWeek.Saturday)
{
throw new ArgumentOutOfRangeException(
- nameof(value), SR.Format(SR.ArgumentOutOfRange_Range,
- DayOfWeek.Sunday, DayOfWeek.Saturday));
+ nameof(value),
+ value,
+ SR.Format(SR.ArgumentOutOfRange_Range, DayOfWeek.Sunday, DayOfWeek.Saturday));
}
+
+ firstDayOfWeek = (int)value;
}
}
@@ -747,28 +717,29 @@ namespace System.Globalization
{
get
{
- if (this.calendarWeekRule == -1)
+ if (calendarWeekRule == -1)
{
- this.calendarWeekRule = _cultureData.IFIRSTWEEKOFYEAR;
+ calendarWeekRule = _cultureData.CalendarWeekRule;
}
- Debug.Assert(this.calendarWeekRule != -1, "DateTimeFormatInfo.CalendarWeekRule, calendarWeekRule != -1");
- return ((CalendarWeekRule)this.calendarWeekRule);
- }
+ Debug.Assert(calendarWeekRule != -1, "DateTimeFormatInfo.CalendarWeekRule, calendarWeekRule != -1");
+ return (CalendarWeekRule)calendarWeekRule;
+ }
set
{
if (IsReadOnly)
- throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
- if (value >= CalendarWeekRule.FirstDay && value <= CalendarWeekRule.FirstFourDayWeek)
{
- calendarWeekRule = (int)value;
+ throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
- else
+ if (value < CalendarWeekRule.FirstDay || value > CalendarWeekRule.FirstFourDayWeek)
{
throw new ArgumentOutOfRangeException(
- nameof(value), SR.Format(SR.ArgumentOutOfRange_Range,
- CalendarWeekRule.FirstDay, CalendarWeekRule.FirstFourDayWeek));
+ nameof(value),
+ value,
+ SR.Format(SR.ArgumentOutOfRange_Range, CalendarWeekRule.FirstDay, CalendarWeekRule.FirstFourDayWeek));
}
+
+ calendarWeekRule = (int)value;
}
}
@@ -780,200 +751,203 @@ namespace System.Globalization
{
fullDateTimePattern = LongDatePattern + " " + LongTimePattern;
}
- return (fullDateTimePattern);
+ return fullDateTimePattern;
}
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
+
fullDateTimePattern = value;
}
}
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
+ /// <summary>
+ /// For our "patterns" arrays we have 2 variables, a string and a string[]
+ /// The string[] contains the list of patterns, EXCEPT the default may not be included.
+ /// The string contains the default pattern.
+ /// When we initially construct our string[], we set the string to string[0]
+ /// </summary>
public string LongDatePattern
{
get
{
// Initialize our long date pattern from the 1st array value if not set
- if (this.longDatePattern == null)
+ if (longDatePattern == null)
{
// Initialize our data
- this.longDatePattern = this.UnclonedLongDatePatterns[0];
+ longDatePattern = UnclonedLongDatePatterns[0];
}
- return this.longDatePattern;
+ return longDatePattern;
}
-
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
// Remember the new string
- this.longDatePattern = value;
+ longDatePattern = value;
// Clear the token hash table
ClearTokenHashTable();
// Clean up cached values that will be affected by this property.
- this.fullDateTimePattern = null;
+ fullDateTimePattern = null;
}
}
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
+ /// <summary>
+ /// For our "patterns" arrays we have 2 variables, a string and a string[]
+ ///
+ /// The string[] contains the list of patterns, EXCEPT the default may not be included.
+ /// The string contains the default pattern.
+ /// When we initially construct our string[], we set the string to string[0]
+ /// </summary>
public string LongTimePattern
{
get
{
// Initialize our long time pattern from the 1st array value if not set
- if (this.longTimePattern == null)
+ if (longTimePattern == null)
{
// Initialize our data
- this.longTimePattern = this.UnclonedLongTimePatterns[0];
+ longTimePattern = UnclonedLongTimePatterns[0];
}
- return this.longTimePattern;
+ return longTimePattern;
}
-
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
// Remember the new string
- this.longTimePattern = value;
+ longTimePattern = value;
// Clear the token hash table
ClearTokenHashTable();
// Clean up cached values that will be affected by this property.
- this.fullDateTimePattern = null; // Full date = long date + long Time
- this.generalLongTimePattern = null; // General long date = short date + long Time
- this.dateTimeOffsetPattern = null;
+ fullDateTimePattern = null; // Full date = long date + long Time
+ generalLongTimePattern = null; // General long date = short date + long Time
+ dateTimeOffsetPattern = null;
}
}
-
- // Note: just to be confusing there's only 1 month day pattern, not a whole list
+ /// <remarks>
+ /// Just to be confusing there's only 1 month day pattern, not a whole list
+ /// </remarks>
public string MonthDayPattern
{
get
{
- if (this.monthDayPattern == null)
+ if (monthDayPattern == null)
{
Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.MonthDayPattern] Expected calID > 0");
- this.monthDayPattern = _cultureData.MonthDay(Calendar.ID);
+ monthDayPattern = _cultureData.MonthDay(Calendar.ID);
}
- Debug.Assert(this.monthDayPattern != null, "DateTimeFormatInfo.MonthDayPattern, monthDayPattern != null");
- return (this.monthDayPattern);
- }
+ Debug.Assert(monthDayPattern != null, "DateTimeFormatInfo.MonthDayPattern, monthDayPattern != null");
+ return monthDayPattern;
+ }
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
- this.monthDayPattern = value;
+ monthDayPattern = value;
}
}
-
public string PMDesignator
{
get
{
- if (this.pmDesignator == null)
+ if (pmDesignator == null)
{
- this.pmDesignator = _cultureData.SPM2359;
+ pmDesignator = _cultureData.PMDesignator;
}
- Debug.Assert(this.pmDesignator != null, "DateTimeFormatInfo.PMDesignator, pmDesignator != null");
- return (this.pmDesignator);
- }
+ Debug.Assert(pmDesignator != null, "DateTimeFormatInfo.PMDesignator, pmDesignator != null");
+ return pmDesignator;
+ }
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
- ClearTokenHashTable();
+ ClearTokenHashTable();
pmDesignator = value;
}
}
+ public string RFC1123Pattern => rfc1123Pattern;
- public string RFC1123Pattern
- {
- get
- {
- return (rfc1123Pattern);
- }
- }
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
+ /// <summary>
+ /// For our "patterns" arrays we have 2 variables, a string and a string[]
+ ///
+ /// The string[] contains the list of patterns, EXCEPT the default may not be included.
+ /// The string contains the default pattern.
+ /// When we initially construct our string[], we set the string to string[0]
+ /// </summary>
public string ShortDatePattern
{
get
{
// Initialize our short date pattern from the 1st array value if not set
- if (this.shortDatePattern == null)
+ if (shortDatePattern == null)
{
// Initialize our data
- this.shortDatePattern = this.UnclonedShortDatePatterns[0];
+ shortDatePattern = UnclonedShortDatePatterns[0];
}
- return this.shortDatePattern;
+ return shortDatePattern;
}
-
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
+ {
+ throw new ArgumentNullException(nameof(value));
+ }
// Remember the new string
- this.shortDatePattern = value;
+ shortDatePattern = value;
// Clear the token hash table, note that even short dates could require this
ClearTokenHashTable();
@@ -985,37 +959,38 @@ namespace System.Globalization
}
}
-
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
+ /// <summary>
+ /// For our "patterns" arrays we have 2 variables, a string and a string[]
+ ///
+ /// The string[] contains the list of patterns, EXCEPT the default may not be included.
+ /// The string contains the default pattern.
+ /// When we initially construct our string[], we set the string to string[0]
+ /// </summary>
public string ShortTimePattern
{
get
{
// Initialize our short time pattern from the 1st array value if not set
- if (this.shortTimePattern == null)
+ if (shortTimePattern == null)
{
// Initialize our data
- this.shortTimePattern = this.UnclonedShortTimePatterns[0];
+ shortTimePattern = UnclonedShortTimePatterns[0];
}
- return this.shortTimePattern;
+ return shortTimePattern;
}
-
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
// Remember the new string
- this.shortTimePattern = value;
+ shortTimePattern = value;
// Clear the token hash table, note that even short times could require this
ClearTokenHashTable();
@@ -1025,22 +1000,14 @@ namespace System.Globalization
}
}
+ public string SortableDateTimePattern => sortableDateTimePattern;
- public string SortableDateTimePattern
- {
- get
- {
- return (sortableDateTimePattern);
- }
- }
-
- /*=================================GeneralShortTimePattern=====================
- **Property: Return the pattern for 'g' general format: shortDate + short time
- **Note: This is used by DateTimeFormat.cs to get the pattern for 'g'
- ** We put this internal property here so that we can avoid doing the
- ** concatation every time somebody asks for the general format.
- ==============================================================================*/
-
+ /// <summary>
+ /// Return the pattern for 'g' general format: shortDate + short time
+ /// This is used by DateTimeFormat.cs to get the pattern for 'g'.
+ /// We put this internal property here so that we can avoid doing the
+ /// concatation every time somebody asks for the general format.
+ /// </summary>
internal string GeneralShortTimePattern
{
get
@@ -1049,17 +1016,15 @@ namespace System.Globalization
{
generalShortTimePattern = ShortDatePattern + " " + ShortTimePattern;
}
- return (generalShortTimePattern);
+ return generalShortTimePattern;
}
}
- /*=================================GeneralLongTimePattern=====================
- **Property: Return the pattern for 'g' general format: shortDate + Long time
- **Note: This is used by DateTimeFormat.cs to get the pattern for 'g'
- ** We put this internal property here so that we can avoid doing the
- ** concatation every time somebody asks for the general format.
- ==============================================================================*/
-
+ /// <summary>
+ /// Return the pattern for 'g' general format: shortDate + Long time.
+ /// We put this internal property here so that we can avoid doing the
+ /// concatation every time somebody asks for the general format.
+ /// </summary>
internal string GeneralLongTimePattern
{
get
@@ -1068,17 +1033,14 @@ namespace System.Globalization
{
generalLongTimePattern = ShortDatePattern + " " + LongTimePattern;
}
- return (generalLongTimePattern);
+ return generalLongTimePattern;
}
}
- /*=================================DateTimeOffsetPattern==========================
- **Property: Return the default pattern DateTimeOffset : shortDate + long time + time zone offset
- **Note: This is used by DateTimeFormat.cs to get the pattern for short Date + long time + time zone offset
- ** We put this internal property here so that we can avoid doing the
- ** concatation every time somebody uses this form
- ==============================================================================*/
-
+ /// Return the default pattern DateTimeOffset : shortDate + long time + time zone offset.
+ /// This is used by DateTimeFormat.cs to get the pattern for short Date + long time + time zone offset
+ /// We put this internal property here so that we can avoid doing the
+ /// concatation every time somebody uses this form.
internal string DateTimeOffsetPattern
{
get
@@ -1134,12 +1096,14 @@ namespace System.Globalization
dateTimeOffsetPattern = dateTimePattern;
}
- return (dateTimeOffsetPattern);
+ return dateTimeOffsetPattern;
}
}
- // Note that cultureData derives this from the long time format (unless someone's set this previously)
- // Note that this property is quite undesirable.
+ /// <remarks>
+ /// Note that cultureData derives this from the long time format (unless someone's set this previously)
+ /// Note that this property is quite undesirable.
+ /// </remarks>
public string TimeSeparator
{
get
@@ -1148,73 +1112,68 @@ namespace System.Globalization
{
timeSeparator = _cultureData.TimeSeparator;
}
- Debug.Assert(this.timeSeparator != null, "DateTimeFormatInfo.TimeSeparator, timeSeparator != null");
- return (timeSeparator);
+ Debug.Assert(timeSeparator != null, "DateTimeFormatInfo.TimeSeparator, timeSeparator != null");
+ return timeSeparator;
}
-
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
-
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
ClearTokenHashTable();
-
timeSeparator = value;
}
}
- public string UniversalSortableDateTimePattern
- {
- get
- {
- return (universalSortableDateTimePattern);
- }
- }
+ public string UniversalSortableDateTimePattern => universalSortableDateTimePattern;
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
+ /// <summary>
+ /// For our "patterns" arrays we have 2 variables, a string and a string[]
+ ///
+ /// The string[] contains the list of patterns, EXCEPT the default may not be included.
+ /// The string contains the default pattern.
+ /// When we initially construct our string[], we set the string to string[0]
+ /// </summary>
public string YearMonthPattern
{
get
{
// Initialize our year/month pattern from the 1st array value if not set
- if (this.yearMonthPattern == null)
+ if (yearMonthPattern == null)
{
// Initialize our data
- this.yearMonthPattern = this.UnclonedYearMonthPatterns[0];
+ yearMonthPattern = UnclonedYearMonthPatterns[0];
}
- return this.yearMonthPattern;
+ return yearMonthPattern;
}
-
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
// Remember the new string
- this.yearMonthPattern = value;
+ yearMonthPattern = value;
// Clear the token hash table, note that even short times could require this
ClearTokenHashTable();
}
}
- //
- // Check if a string array contains a null value, and throw ArgumentNullException with parameter name "value"
- //
+ /// <summary>
+ /// Check if a string array contains a null value, and throw ArgumentNullException with parameter name "value"
+ /// </summary>
private static void CheckNullValue(string[] values, int length)
{
Debug.Assert(values != null, "value != null");
@@ -1223,33 +1182,29 @@ namespace System.Globalization
{
if (values[i] == null)
{
- throw new ArgumentNullException("value",
- SR.ArgumentNull_ArrayValue);
+ throw new ArgumentNullException("value", SR.ArgumentNull_ArrayValue);
}
}
}
-
public string[] AbbreviatedDayNames
{
- get
- {
- return ((string[])internalGetAbbreviatedDayOfWeekNames().Clone());
- }
-
+ get => (string[])InternalGetAbbreviatedDayOfWeekNames().Clone();
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_Array);
+ throw new ArgumentNullException(nameof(value));
}
if (value.Length != 7)
{
throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value));
}
+
CheckNullValue(value, value.Length);
ClearTokenHashTable();
@@ -1257,53 +1212,50 @@ namespace System.Globalization
}
}
- // Returns the string array of the one-letter day of week names.
+ /// <summary>
+ /// Returns the string array of the one-letter day of week names.
+ /// </summary>
public string[] ShortestDayNames
{
- get
- {
- return ((string[])internalGetSuperShortDayNames().Clone());
- }
-
+ get => (string[])InternalGetSuperShortDayNames().Clone();
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_Array);
+ throw new ArgumentNullException(nameof(value));
}
if (value.Length != 7)
{
throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value));
}
+
CheckNullValue(value, value.Length);
- this.m_superShortDayNames = value;
+ m_superShortDayNames = value;
}
}
-
public string[] DayNames
{
- get
- {
- return ((string[])internalGetDayOfWeekNames().Clone());
- }
-
+ get => (string[])InternalGetDayOfWeekNames().Clone();
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_Array);
+ throw new ArgumentNullException(nameof(value));
}
if (value.Length != 7)
{
throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 7), nameof(value));
}
+
CheckNullValue(value, value.Length);
ClearTokenHashTable();
@@ -1311,54 +1263,48 @@ namespace System.Globalization
}
}
-
public string[] AbbreviatedMonthNames
{
- get
- {
- return ((string[])internalGetAbbreviatedMonthNames().Clone());
- }
-
+ get => (string[])InternalGetAbbreviatedMonthNames().Clone();
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_Array);
+ throw new ArgumentNullException(nameof(value));
}
if (value.Length != 13)
{
throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
}
+
CheckNullValue(value, value.Length - 1);
ClearTokenHashTable();
abbreviatedMonthNames = value;
}
}
-
public string[] MonthNames
{
- get
- {
- return ((string[])internalGetMonthNames().Clone());
- }
-
+ get => (string[])InternalGetMonthNames().Clone();
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_Array);
+ throw new ArgumentNullException(nameof(value));
}
if (value.Length != 13)
{
throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
}
+
CheckNullValue(value, value.Length - 1);
monthNames = value;
ClearTokenHashTable();
@@ -1369,147 +1315,125 @@ namespace System.Globalization
// U+00a0 is non-breaking space.
private static readonly char[] s_monthSpaces = { ' ', '\u00a0' };
- internal bool HasSpacesInMonthNames
- {
- get
- {
- return (FormatFlags & DateTimeFormatFlags.UseSpacesInMonthNames) != 0;
- }
- }
-
- internal bool HasSpacesInDayNames
- {
- get
- {
- return (FormatFlags & DateTimeFormatFlags.UseSpacesInDayNames) != 0;
- }
- }
+ internal bool HasSpacesInMonthNames =>(FormatFlags & DateTimeFormatFlags.UseSpacesInMonthNames) != 0;
+ internal bool HasSpacesInDayNames => (FormatFlags & DateTimeFormatFlags.UseSpacesInDayNames) != 0;
- //
- // internalGetMonthName
- //
- // Actions: Return the month name using the specified MonthNameStyles in either abbreviated form
- // or full form.
- // Arguments:
- // month
- // style To indicate a form like regular/genitive/month name in a leap year.
- // abbreviated When true, return abbreviated form. Otherwise, return a full form.
- // Exceptions:
- // ArgumentOutOfRangeException When month name is invalid.
- //
- internal string internalGetMonthName(int month, MonthNameStyles style, bool abbreviated)
+ /// <summary>
+ /// Return the month name using the specified MonthNameStyles in either abbreviated form
+ /// or full form.
+ /// </summary>
+ internal string InternalGetMonthName(int month, MonthNameStyles style, bool abbreviated)
{
- //
- // Right now, style is mutual exclusive, but I make the style to be flag so that
- // maybe we can combine flag if there is such a need.
- //
string[] monthNamesArray = null;
switch (style)
{
case MonthNameStyles.Genitive:
- monthNamesArray = internalGetGenitiveMonthNames(abbreviated);
+ monthNamesArray = InternalGetGenitiveMonthNames(abbreviated);
break;
case MonthNameStyles.LeapYear:
- monthNamesArray = internalGetLeapYearMonthNames(/*abbreviated*/);
+ monthNamesArray = InternalGetLeapYearMonthNames();
break;
default:
- monthNamesArray = (abbreviated ? internalGetAbbreviatedMonthNames() : internalGetMonthNames());
+ monthNamesArray = (abbreviated ? InternalGetAbbreviatedMonthNames() : InternalGetMonthNames());
break;
}
- // The month range is from 1 ~ this.m_monthNames.Length
+
+ // The month range is from 1 ~ m_monthNames.Length
// (actually is 13 right now for all cases)
if ((month < 1) || (month > monthNamesArray.Length))
{
throw new ArgumentOutOfRangeException(
- nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
- 1, monthNamesArray.Length));
+ nameof(month),
+ month,
+ SR.Format(SR.ArgumentOutOfRange_Range, 1, monthNamesArray.Length));
}
- return (monthNamesArray[month - 1]);
+
+ return monthNamesArray[month - 1];
}
- //
- // internalGetGenitiveMonthNames
- //
- // Action: Retrieve the array which contains the month names in genitive form.
- // If this culture does not use the gentive form, the normal month name is returned.
- // Arguments:
- // abbreviated When true, return abbreviated form. Otherwise, return a full form.
- //
- private string[] internalGetGenitiveMonthNames(bool abbreviated)
+ /// <summary>
+ /// Retrieve the array which contains the month names in genitive form.
+ /// If this culture does not use the gentive form, the normal month name is returned.
+ /// </summary>
+ private string[] InternalGetGenitiveMonthNames(bool abbreviated)
{
if (abbreviated)
{
- if (this.m_genitiveAbbreviatedMonthNames == null)
+ if (m_genitiveAbbreviatedMonthNames == null)
{
- this.m_genitiveAbbreviatedMonthNames = _cultureData.AbbreviatedGenitiveMonthNames(this.Calendar.ID);
- Debug.Assert(this.m_genitiveAbbreviatedMonthNames.Length == 13,
+ m_genitiveAbbreviatedMonthNames = _cultureData.AbbreviatedGenitiveMonthNames(Calendar.ID);
+ Debug.Assert(m_genitiveAbbreviatedMonthNames.Length == 13,
"[DateTimeFormatInfo.GetGenitiveMonthNames] Expected 13 abbreviated genitive month names in a year");
}
- return (this.m_genitiveAbbreviatedMonthNames);
+
+ return m_genitiveAbbreviatedMonthNames;
}
- if (this.genitiveMonthNames == null)
+ if (genitiveMonthNames == null)
{
- this.genitiveMonthNames = _cultureData.GenitiveMonthNames(this.Calendar.ID);
- Debug.Assert(this.genitiveMonthNames.Length == 13,
+ genitiveMonthNames = _cultureData.GenitiveMonthNames(Calendar.ID);
+ Debug.Assert(genitiveMonthNames.Length == 13,
"[DateTimeFormatInfo.GetGenitiveMonthNames] Expected 13 genitive month names in a year");
}
- return (this.genitiveMonthNames);
+
+ return genitiveMonthNames;
}
- //
- // internalGetLeapYearMonthNames
- //
- // Actions: Retrieve the month names used in a leap year.
- // If this culture does not have different month names in a leap year, the normal month name is returned.
- // Arguments: None. (can use abbreviated later if needed)
- //
- internal string[] internalGetLeapYearMonthNames(/*bool abbreviated*/)
+ /// <summary>
+ /// Retrieve the month names used in a leap year.
+ /// If this culture does not have different month names in a leap year,
+ /// the normal month name is returned.
+ /// </summary>
+ internal string[] InternalGetLeapYearMonthNames()
{
- if (this.leapYearMonthNames == null)
+ if (leapYearMonthNames == null)
{
- Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.internalGetLeapYearMonthNames] Expected Calendar.ID > 0");
- this.leapYearMonthNames = _cultureData.LeapYearMonthNames(Calendar.ID);
- Debug.Assert(this.leapYearMonthNames.Length == 13,
- "[DateTimeFormatInfo.internalGetLeapYearMonthNames] Expepcted 13 leap year month names");
+ Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.InternalGetLeapYearMonthNames] Expected Calendar.ID > 0");
+ leapYearMonthNames = _cultureData.LeapYearMonthNames(Calendar.ID);
+ Debug.Assert(leapYearMonthNames.Length == 13,
+ "[DateTimeFormatInfo.InternalGetLeapYearMonthNames] Expepcted 13 leap year month names");
}
+
return (leapYearMonthNames);
}
-
public string GetAbbreviatedDayName(DayOfWeek dayofweek)
{
- if ((int)dayofweek < 0 || (int)dayofweek > 6)
+ if (dayofweek < DayOfWeek.Sunday || dayofweek > DayOfWeek.Saturday)
{
throw new ArgumentOutOfRangeException(
- nameof(dayofweek), SR.Format(SR.ArgumentOutOfRange_Range,
- DayOfWeek.Sunday, DayOfWeek.Saturday));
+ nameof(dayofweek),
+ dayofweek,
+ SR.Format(SR.ArgumentOutOfRange_Range, DayOfWeek.Sunday, DayOfWeek.Saturday));
}
- //
+
// Don't call the public property AbbreviatedDayNames here since a clone is needed in that
- // property, so it will be slower. Instead, use GetAbbreviatedDayOfWeekNames() directly.
- //
- return (internalGetAbbreviatedDayOfWeekNames()[(int)dayofweek]);
+ // property, so it will be slower. Instead, use GetAbbreviatedDayOfWeekNames() directly.
+ return InternalGetAbbreviatedDayOfWeekNames()[(int)dayofweek];
}
- // Returns the super short day of week names for the specified day of week.
+ /// <summary>
+ /// Returns the super short day of week names for the specified day of week.
+ /// </summary>
public string GetShortestDayName(DayOfWeek dayOfWeek)
{
- if ((int)dayOfWeek < 0 || (int)dayOfWeek > 6)
+ if (dayOfWeek < DayOfWeek.Sunday || dayOfWeek > DayOfWeek.Saturday)
{
throw new ArgumentOutOfRangeException(
- nameof(dayOfWeek), SR.Format(SR.ArgumentOutOfRange_Range,
- DayOfWeek.Sunday, DayOfWeek.Saturday));
+ nameof(dayOfWeek),
+ dayOfWeek,
+ SR.Format(SR.ArgumentOutOfRange_Range, DayOfWeek.Sunday, DayOfWeek.Saturday));
}
- //
+
// Don't call the public property SuperShortDayNames here since a clone is needed in that
- // property, so it will be slower. Instead, use internalGetSuperShortDayNames() directly.
- //
- return (internalGetSuperShortDayNames()[(int)dayOfWeek]);
+ // property, so it will be slower. Instead, use internalGetSuperShortDayNames() directly.
+ return InternalGetSuperShortDayNames()[(int)dayOfWeek];
}
- // Get all possible combination of inputs
+ /// <summary>
+ /// Get all possible combination of inputs
+ /// </summary>
private static string[] GetCombinedPatterns(string[] patterns1, string[] patterns2, string connectString)
{
Debug.Assert(patterns1 != null);
@@ -1530,7 +1454,7 @@ namespace System.Globalization
}
// Return the combinations
- return (result);
+ return result;
}
public string[] GetAllDateTimePatterns()
@@ -1555,10 +1479,10 @@ namespace System.Globalization
switch (format)
{
case 'd':
- result = this.AllShortDatePatterns;
+ result = AllShortDatePatterns;
break;
case 'D':
- result = this.AllLongDatePatterns;
+ result = AllLongDatePatterns;
break;
case 'f':
result = GetCombinedPatterns(AllLongDatePatterns, AllShortTimePatterns, " ");
@@ -1589,36 +1513,36 @@ namespace System.Globalization
result = new string[] { sortableDateTimePattern };
break;
case 't':
- result = this.AllShortTimePatterns;
+ result = AllShortTimePatterns;
break;
case 'T':
- result = this.AllLongTimePatterns;
+ result = AllLongTimePatterns;
break;
case 'u':
result = new string[] { UniversalSortableDateTimePattern };
break;
case 'y':
case 'Y':
- result = this.AllYearMonthPatterns;
+ result = AllYearMonthPatterns;
break;
default:
throw new ArgumentException(SR.Format(SR.Format_BadFormatSpecifier, format), nameof(format));
}
- return (result);
+ return result;
}
-
public string GetDayName(DayOfWeek dayofweek)
{
if ((int)dayofweek < 0 || (int)dayofweek > 6)
{
throw new ArgumentOutOfRangeException(
- nameof(dayofweek), SR.Format(SR.ArgumentOutOfRange_Range,
- DayOfWeek.Sunday, DayOfWeek.Saturday));
+ nameof(dayofweek),
+ dayofweek,
+ SR.Format(SR.ArgumentOutOfRange_Range, DayOfWeek.Sunday, DayOfWeek.Saturday));
}
// Use the internal one so that we don't clone the array unnecessarily
- return (internalGetDayOfWeekNames()[(int)dayofweek]);
+ return InternalGetDayOfWeekNames()[(int)dayofweek];
}
public string GetAbbreviatedMonthName(int month)
@@ -1626,11 +1550,13 @@ namespace System.Globalization
if (month < 1 || month > 13)
{
throw new ArgumentOutOfRangeException(
- nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
- 1, 13));
+ nameof(month),
+ month,
+ SR.Format(SR.ArgumentOutOfRange_Range, 1, 13));
}
+
// Use the internal one so we don't clone the array unnecessarily
- return (internalGetAbbreviatedMonthNames()[month - 1]);
+ return InternalGetAbbreviatedMonthNames()[month - 1];
}
public string GetMonthName(int month)
@@ -1638,20 +1564,24 @@ namespace System.Globalization
if (month < 1 || month > 13)
{
throw new ArgumentOutOfRangeException(
- nameof(month), SR.Format(SR.ArgumentOutOfRange_Range,
- 1, 13));
+ nameof(month),
+ month,
+ SR.Format(SR.ArgumentOutOfRange_Range, 1, 13));
}
- // Use the internal one so we don't clone the array unnecessarily
- return (internalGetMonthNames()[month - 1]);
- }
- // For our "patterns" arrays we have 2 variables, a string and a string[]
- //
- // The string[] contains the list of patterns, EXCEPT the default may not be included.
- // The string contains the default pattern.
- // When we initially construct our string[], we set the string to string[0]
- //
- // The resulting [] can get returned to the calling app, so clone it.
+ // Use the internal one so we don't clone the array unnecessarily
+ return InternalGetMonthNames()[month - 1];
+ }
+
+ /// <summary>
+ /// For our "patterns" arrays we have 2 variables, a string and a string[]
+ ///
+ /// The string[] contains the list of patterns, EXCEPT the default may not be included.
+ /// The string contains the default pattern.
+ /// When we initially construct our string[], we set the string to string[0]
+ ///
+ /// The resulting [] can get returned to the calling app, so clone it.
+ /// </summary>
private static string[] GetMergedPatterns(string[] patterns, string defaultPattern)
{
Debug.Assert(patterns != null && patterns.Length > 0,
@@ -1707,50 +1637,25 @@ namespace System.Globalization
internal const string RoundtripFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK";
internal const string RoundtripDateTimeUnfixed = "yyyy'-'MM'-'ddTHH':'mm':'ss zzz";
- // Default string isn't necessarily in our string array, so get the
- // merged patterns of both
- private string[] AllYearMonthPatterns
- {
- get
- {
- return GetMergedPatterns(this.UnclonedYearMonthPatterns, this.YearMonthPattern);
- }
- }
+ /// <summary>
+ /// Default string isn't necessarily in our string array, so get the
+ /// merged patterns of both
+ /// </summary>
+ private string[] AllYearMonthPatterns => GetMergedPatterns(UnclonedYearMonthPatterns, YearMonthPattern);
- private string[] AllShortDatePatterns
- {
- get
- {
- return GetMergedPatterns(this.UnclonedShortDatePatterns, this.ShortDatePattern);
- }
- }
+ private string[] AllShortDatePatterns => GetMergedPatterns(UnclonedShortDatePatterns, ShortDatePattern);
- private string[] AllShortTimePatterns
- {
- get
- {
- return GetMergedPatterns(this.UnclonedShortTimePatterns, this.ShortTimePattern);
- }
- }
+ private string[] AllShortTimePatterns => GetMergedPatterns(UnclonedShortTimePatterns, ShortTimePattern);
- private string[] AllLongDatePatterns
- {
- get
- {
- return GetMergedPatterns(this.UnclonedLongDatePatterns, this.LongDatePattern);
- }
- }
+ private string[] AllLongDatePatterns => GetMergedPatterns(UnclonedLongDatePatterns, LongDatePattern);
- private string[] AllLongTimePatterns
- {
- get
- {
- return GetMergedPatterns(this.UnclonedLongTimePatterns, this.LongTimePattern);
- }
- }
+ private string[] AllLongTimePatterns => GetMergedPatterns(UnclonedLongTimePatterns, LongTimePattern);
- // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
- // This won't include default, call AllYearMonthPatterns
+ /// <remarks>
+ /// Clone this string array if you want to return it to user.
+ /// Otherwise, you are returning a writable cache copy.
+ /// This won't include default, call AllYearMonthPatterns
+ /// </remarks>
private string[] UnclonedYearMonthPatterns
{
get
@@ -1758,8 +1663,8 @@ namespace System.Globalization
if (allYearMonthPatterns == null)
{
Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedYearMonthPatterns] Expected Calendar.ID > 0");
- this.allYearMonthPatterns = _cultureData.YearMonths(this.Calendar.ID);
- Debug.Assert(this.allYearMonthPatterns.Length > 0,
+ allYearMonthPatterns = _cultureData.YearMonths(Calendar.ID);
+ Debug.Assert(allYearMonthPatterns.Length > 0,
"[DateTimeFormatInfo.UnclonedYearMonthPatterns] Expected some year month patterns");
}
@@ -1767,9 +1672,11 @@ namespace System.Globalization
}
}
-
- // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
- // This won't include default, call AllShortDatePatterns
+ /// <remarks>
+ /// Clone this string array if you want to return it to user.
+ /// Otherwise, you are returning a writable cache copy.
+ /// This won't include default, call AllShortDatePatterns
+ /// </remarks>
private string[] UnclonedShortDatePatterns
{
get
@@ -1777,17 +1684,20 @@ namespace System.Globalization
if (allShortDatePatterns == null)
{
Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedShortDatePatterns] Expected Calendar.ID > 0");
- this.allShortDatePatterns = _cultureData.ShortDates(this.Calendar.ID);
- Debug.Assert(this.allShortDatePatterns.Length > 0,
+ allShortDatePatterns = _cultureData.ShortDates(Calendar.ID);
+ Debug.Assert(allShortDatePatterns.Length > 0,
"[DateTimeFormatInfo.UnclonedShortDatePatterns] Expected some short date patterns");
}
- return this.allShortDatePatterns;
+ return allShortDatePatterns;
}
}
- // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
- // This won't include default, call AllLongDatePatterns
+ /// <remarks>
+ /// Clone this string array if you want to return it to user.
+ /// Otherwise, you are returning a writable cache copy.
+ /// This won't include default, call AllLongDatePatterns
+ /// </remarks>
private string[] UnclonedLongDatePatterns
{
get
@@ -1795,46 +1705,52 @@ namespace System.Globalization
if (allLongDatePatterns == null)
{
Debug.Assert(Calendar.ID > 0, "[DateTimeFormatInfo.UnclonedLongDatePatterns] Expected Calendar.ID > 0");
- this.allLongDatePatterns = _cultureData.LongDates(this.Calendar.ID);
- Debug.Assert(this.allLongDatePatterns.Length > 0,
+ allLongDatePatterns = _cultureData.LongDates(Calendar.ID);
+ Debug.Assert(allLongDatePatterns.Length > 0,
"[DateTimeFormatInfo.UnclonedLongDatePatterns] Expected some long date patterns");
}
- return this.allLongDatePatterns;
+ return allLongDatePatterns;
}
}
- // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
- // This won't include default, call AllShortTimePatterns
+ /// <remarks>
+ /// Clone this string array if you want to return it to user.
+ /// Otherwise, you are returning a writable cache copy.
+ /// This won't include default, call AllShortTimePatterns
+ /// </remarks>
private string[] UnclonedShortTimePatterns
{
get
{
- if (this.allShortTimePatterns == null)
+ if (allShortTimePatterns == null)
{
- this.allShortTimePatterns = _cultureData.ShortTimes;
- Debug.Assert(this.allShortTimePatterns.Length > 0,
+ allShortTimePatterns = _cultureData.ShortTimes;
+ Debug.Assert(allShortTimePatterns.Length > 0,
"[DateTimeFormatInfo.UnclonedShortTimePatterns] Expected some short time patterns");
}
- return this.allShortTimePatterns;
+ return allShortTimePatterns;
}
}
- // NOTE: Clone this string array if you want to return it to user. Otherwise, you are returning a writable cache copy.
- // This won't include default, call AllLongTimePatterns
+ /// <remarks>
+ /// Clone this string array if you want to return it to user.
+ /// Otherwise, you are returning a writable cache copy.
+ /// This won't include default, call AllLongTimePatterns
+ /// </remarks>
private string[] UnclonedLongTimePatterns
{
get
{
- if (this.allLongTimePatterns == null)
+ if (allLongTimePatterns == null)
{
- this.allLongTimePatterns = _cultureData.LongTimes;
- Debug.Assert(this.allLongTimePatterns.Length > 0,
+ allLongTimePatterns = _cultureData.LongTimes;
+ Debug.Assert(allLongTimePatterns.Length > 0,
"[DateTimeFormatInfo.UnclonedLongTimePatterns] Expected some long time patterns");
}
- return this.allLongTimePatterns;
+ return allLongTimePatterns;
}
}
@@ -1844,32 +1760,30 @@ namespace System.Globalization
{
throw new ArgumentNullException(nameof(dtfi));
}
+
if (dtfi.IsReadOnly)
{
- return (dtfi);
+ return dtfi;
}
+
DateTimeFormatInfo newInfo = (DateTimeFormatInfo)(dtfi.MemberwiseClone());
// We can use the data member calendar in the setter, instead of the property Calendar,
// since the cloned copy should have the same state as the original copy.
newInfo.calendar = Calendar.ReadOnly(dtfi.Calendar);
newInfo._isReadOnly = true;
- return (newInfo);
+ return newInfo;
}
- public bool IsReadOnly
- {
- get
- {
- return (_isReadOnly);
- }
- }
+ public bool IsReadOnly => _isReadOnly;
- // Return the native name for the calendar in DTFI.Calendar. The native name is referred to
- // the culture used to create the DTFI. E.g. in the following example, the native language is Japanese.
- // DateTimeFormatInfo dtfi = new CultureInfo("ja-JP", false).DateTimeFormat.Calendar = new JapaneseCalendar();
- // String nativeName = dtfi.NativeCalendarName; // Get the Japanese name for the Japanese calendar.
- // DateTimeFormatInfo dtfi = new CultureInfo("ja-JP", false).DateTimeFormat.Calendar = new GregorianCalendar(GregorianCalendarTypes.Localized);
- // String nativeName = dtfi.NativeCalendarName; // Get the Japanese name for the Gregorian calendar.
+ /// <summary>
+ /// Return the native name for the calendar in DTFI.Calendar. The native name is referred to
+ /// the culture used to create the DTFI. E.g. in the following example, the native language is Japanese.
+ /// DateTimeFormatInfo dtfi = new CultureInfo("ja-JP", false).DateTimeFormat.Calendar = new JapaneseCalendar();
+ /// String nativeName = dtfi.NativeCalendarName; // Get the Japanese name for the Japanese calendar.
+ /// DateTimeFormatInfo dtfi = new CultureInfo("ja-JP", false).DateTimeFormat.Calendar = new GregorianCalendar(GregorianCalendarTypes.Localized);
+ /// String nativeName = dtfi.NativeCalendarName; // Get the Japanese name for the Gregorian calendar.
+ /// </summary>
public string NativeCalendarName
{
get
@@ -1878,31 +1792,32 @@ namespace System.Globalization
}
}
- //
- // Used by custom cultures and others to set the list of available formats. Note that none of them are
- // explicitly used unless someone calls GetAllDateTimePatterns and subsequently uses one of the items
- // from the list.
- //
- // Most of the format characters that can be used in GetAllDateTimePatterns are
- // not really needed since they are one of the following:
- //
- // r/R/s/u locale-independent constants -- cannot be changed!
- // m/M/y/Y fields with a single string in them -- that can be set through props directly
- // f/F/g/G/U derived fields based on combinations of various of the below formats
- //
- // NOTE: No special validation is done here beyond what is done when the actual respective fields
- // are used (what would be the point of disallowing here what we allow in the appropriate property?)
- //
- // WARNING: If more validation is ever done in one place, it should be done in the other.
- //
+ /// <summary>
+ /// Used by custom cultures and others to set the list of available formats. Note that none of them are
+ /// explicitly used unless someone calls GetAllDateTimePatterns and subsequently uses one of the items
+ /// from the list.
+ ///
+ /// Most of the format characters that can be used in GetAllDateTimePatterns are
+ /// not really needed since they are one of the following:
+ ///
+ /// r/R/s/u locale-independent constants -- cannot be changed!
+ /// m/M/y/Y fields with a single string in them -- that can be set through props directly
+ /// f/F/g/G/U derived fields based on combinations of various of the below formats
+ ///
+ /// NOTE: No special validation is done here beyond what is done when the actual respective fields
+ /// are used (what would be the point of disallowing here what we allow in the appropriate property?)
+ ///
+ /// WARNING: If more validation is ever done in one place, it should be done in the other.
+ /// </summary>
public void SetAllDateTimePatterns(string[] patterns, char format)
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
-
+ }
if (patterns == null)
{
- throw new ArgumentNullException(nameof(patterns), SR.ArgumentNull_Array);
+ throw new ArgumentNullException(nameof(patterns));
}
if (patterns.Length == 0)
@@ -1910,7 +1825,6 @@ namespace System.Globalization
throw new ArgumentException(SR.Arg_ArrayZeroError, nameof(patterns));
}
-
for (int i = 0; i < patterns.Length; i++)
{
if (patterns[i] == null)
@@ -1958,59 +1872,53 @@ namespace System.Globalization
public string[] AbbreviatedMonthGenitiveNames
{
- get
- {
- return ((string[])internalGetGenitiveMonthNames(true).Clone());
- }
-
+ get => (string[])InternalGetGenitiveMonthNames(true).Clone();
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_Array);
+ throw new ArgumentNullException(nameof(value));
}
if (value.Length != 13)
{
throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
}
+
CheckNullValue(value, value.Length - 1);
ClearTokenHashTable();
- this.m_genitiveAbbreviatedMonthNames = value;
+ m_genitiveAbbreviatedMonthNames = value;
}
}
public string[] MonthGenitiveNames
{
- get
- {
- return ((string[])internalGetGenitiveMonthNames(false).Clone());
- }
-
+ get => (string[])InternalGetGenitiveMonthNames(false).Clone();
set
{
if (IsReadOnly)
+ {
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
+ }
if (value == null)
{
- throw new ArgumentNullException(nameof(value),
- SR.ArgumentNull_Array);
+ throw new ArgumentNullException(nameof(value));
}
if (value.Length != 13)
{
throw new ArgumentException(SR.Format(SR.Argument_InvalidArrayLength, 13), nameof(value));
}
+
CheckNullValue(value, value.Length - 1);
genitiveMonthNames = value;
ClearTokenHashTable();
}
}
- //
// Decimal separator used by positive TimeSpan pattern
- //
private string _decimalSeparator;
internal string DecimalSeparator
{
@@ -2027,9 +1935,7 @@ namespace System.Globalization
}
}
- //
// Positive TimeSpan Pattern
- //
private string _fullTimeSpanPositivePattern;
internal string FullTimeSpanPositivePattern
{
@@ -2043,9 +1949,7 @@ namespace System.Globalization
}
}
- //
// Negative TimeSpan Pattern
- //
private string _fullTimeSpanNegativePattern;
internal string FullTimeSpanNegativePattern
{
@@ -2057,9 +1961,7 @@ namespace System.Globalization
}
}
- //
// Get suitable CompareInfo from current DTFI object.
- //
internal CompareInfo CompareInfo
{
get
@@ -2068,14 +1970,13 @@ namespace System.Globalization
{
// We use the regular GetCompareInfo here to make sure the created CompareInfo object is stored in the
// CompareInfo cache. otherwise we would just create CompareInfo using _cultureData.
- _compareInfo = CompareInfo.GetCompareInfo(_cultureData.SCOMPAREINFO);
+ _compareInfo = CompareInfo.GetCompareInfo(_cultureData.SortName);
}
return _compareInfo;
}
}
-
internal const DateTimeStyles InvalidDateTimeStyles = ~(DateTimeStyles.AllowLeadingWhite | DateTimeStyles.AllowTrailingWhite
| DateTimeStyles.AllowInnerWhite | DateTimeStyles.NoCurrentDateDefault
| DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeLocal
@@ -2098,20 +1999,22 @@ namespace System.Globalization
}
}
- //
- // Actions: Return the internal flag used in formatting and parsing.
- // The flag can be used to indicate things like if genitive forms is used in this DTFi, or if leap year gets different month names.
- //
+ /// <summary>
+ /// Return the internal flag used in formatting and parsing.
+ /// The flag can be used to indicate things like if genitive forms is used in
+ /// this DTFi, or if leap year gets different month names.
+ /// </summary>
internal DateTimeFormatFlags FormatFlags => formatFlags != DateTimeFormatFlags.NotInitialized ? formatFlags : InitializeFormatFlags();
+
[MethodImpl(MethodImplOptions.NoInlining)]
private DateTimeFormatFlags InitializeFormatFlags()
{
// Build the format flags from the data in this DTFI
formatFlags =
(DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagGenitiveMonth(
- MonthNames, internalGetGenitiveMonthNames(false), AbbreviatedMonthNames, internalGetGenitiveMonthNames(true)) |
+ MonthNames, InternalGetGenitiveMonthNames(false), AbbreviatedMonthNames, InternalGetGenitiveMonthNames(true)) |
(DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagUseSpaceInMonthNames(
- MonthNames, internalGetGenitiveMonthNames(false), AbbreviatedMonthNames, internalGetGenitiveMonthNames(true)) |
+ MonthNames, InternalGetGenitiveMonthNames(false), AbbreviatedMonthNames, InternalGetGenitiveMonthNames(true)) |
(DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagUseSpaceInDayNames(DayNames, AbbreviatedDayNames) |
(DateTimeFormatFlags)DateTimeFormatInfoScanner.GetFormatFlagUseHebrewCalendar((int)Calendar.ID);
return formatFlags;
@@ -2139,20 +2042,21 @@ namespace System.Globalization
}
}
- // Returns whether the YearMonthAdjustment function has any fix-up work to do for this culture/calendar.
+ /// <summary>
+ /// Returns whether the YearMonthAdjustment function has any fix-up work to do for this culture/calendar.
+ /// </summary>
internal bool HasYearMonthAdjustment
{
- get
- {
- return ((FormatFlags & DateTimeFormatFlags.UseHebrewRule) != 0);
- }
+ get => (FormatFlags & DateTimeFormatFlags.UseHebrewRule) != 0;
}
- // This is a callback that the parser can make back into the DTFI to let it fiddle with special
- // cases associated with that culture or calendar. Currently this only has special cases for
- // the Hebrew calendar, but this could be extended to other cultures.
- //
- // The return value is whether the year and month are actually valid for this calendar.
+ /// <summary>
+ /// This is a callback that the parser can make back into the DTFI to let it fiddle with special
+ /// cases associated with that culture or calendar. Currently this only has special cases for
+ /// the Hebrew calendar, but this could be extended to other cultures.
+ ///
+ /// The return value is whether the year and month are actually valid for this calendar.
+ /// </summary>
internal bool YearMonthAdjustment(ref int year, ref int month, bool parsedMonthName)
{
if ((FormatFlags & DateTimeFormatFlags.UseHebrewRule) != 0)
@@ -2193,9 +2097,7 @@ namespace System.Globalization
return true;
}
- //
// DateTimeFormatInfo tokenizer. This is used by DateTime.Parse() to break input string into tokens.
- //
private TokenHashValue[] _dtfiTokenHash;
private const int TOKEN_HASH_SIZE = 199;
@@ -2204,15 +2106,11 @@ namespace System.Globalization
private const string invariantDateSeparator = "/";
private const string invariantTimeSeparator = ":";
- //
// Common Ignorable Symbols
- //
internal const string IgnorablePeriod = ".";
internal const string IgnorableComma = ",";
- //
// Year/Month/Day suffixes
- //
internal const string CJKYearSuff = "\u5e74";
internal const string CJKMonthSuff = "\u6708";
internal const string CJKDaySuff = "\u65e5";
@@ -2245,12 +2143,12 @@ namespace System.Globalization
private static volatile DateTimeFormatInfo s_jajpDTFI;
private static volatile DateTimeFormatInfo s_zhtwDTFI;
- //
- // Create a Japanese DTFI which uses JapaneseCalendar. This is used to parse
- // date string with Japanese era name correctly even when the supplied DTFI
- // does not use Japanese calendar.
- // The created instance is stored in global s_jajpDTFI.
- //
+ /// <summary>
+ /// Create a Japanese DTFI which uses JapaneseCalendar. This is used to parse
+ /// date string with Japanese era name correctly even when the supplied DTFI
+ /// does not use Japanese calendar.
+ /// The created instance is stored in global s_jajpDTFI.
+ /// </summary>
internal static DateTimeFormatInfo GetJapaneseCalendarDTFI()
{
DateTimeFormatInfo temp = s_jajpDTFI;
@@ -2260,13 +2158,15 @@ namespace System.Globalization
temp.Calendar = JapaneseCalendar.GetDefaultInstance();
s_jajpDTFI = temp;
}
- return (temp);
+ return temp;
}
- // Create a Taiwan DTFI which uses TaiwanCalendar. This is used to parse
- // date string with era name correctly even when the supplied DTFI
- // does not use Taiwan calendar.
- // The created instance is stored in global s_zhtwDTFI.
+ /// <summary>
+ /// Create a Taiwan DTFI which uses TaiwanCalendar. This is used to parse
+ /// date string with era name correctly even when the supplied DTFI
+ /// does not use Taiwan calendar.
+ /// The created instance is stored in global s_zhtwDTFI.
+ /// </summary>
internal static DateTimeFormatInfo GetTaiwanCalendarDTFI()
{
DateTimeFormatInfo temp = s_zhtwDTFI;
@@ -2276,11 +2176,12 @@ namespace System.Globalization
temp.Calendar = TaiwanCalendar.GetDefaultInstance();
s_zhtwDTFI = temp;
}
- return (temp);
+ return temp;
}
-
- // DTFI properties should call this when the setter are called.
+ /// <summary>
+ /// DTFI properties should call this when the setter are called.
+ /// </summary>
private void ClearTokenHashTable()
{
_dtfiTokenHash = null;
@@ -2296,7 +2197,7 @@ namespace System.Globalization
bool koreanLanguage = LanguageName.Equals(KoreanLangName);
- string sep = this.TimeSeparator.Trim();
+ string sep = TimeSeparator.Trim();
if (IgnorableComma != sep) InsertHash(temp, IgnorableComma, TokenType.IgnorableSymbol, 0);
if (IgnorablePeriod != sep) InsertHash(temp, IgnorablePeriod, TokenType.IgnorableSymbol, 0);
@@ -2308,18 +2209,17 @@ namespace System.Globalization
// DateTime.Parse behavior. For instance, the DateTimeFormatInfo.Tokenize() method might return SEP_DateOrOffset for KoreanHourSuff
// instead of SEP_HourSuff.
//
- InsertHash(temp, this.TimeSeparator, TokenType.SEP_Time, 0);
+ InsertHash(temp, TimeSeparator, TokenType.SEP_Time, 0);
}
- InsertHash(temp, this.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
- InsertHash(temp, this.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
+ InsertHash(temp, AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
+ InsertHash(temp, PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
- // TODO: This ignores similar custom cultures
if (LanguageName.Equals("sq"))
{
// Albanian allows time formats like "12:00.PD"
- InsertHash(temp, IgnorablePeriod + this.AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
- InsertHash(temp, IgnorablePeriod + this.PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
+ InsertHash(temp, IgnorablePeriod + AMDesignator, TokenType.SEP_Am | TokenType.Am, 0);
+ InsertHash(temp, IgnorablePeriod + PMDesignator, TokenType.SEP_Pm | TokenType.Pm, 1);
}
// CJK suffix
@@ -2395,7 +2295,7 @@ namespace System.Globalization
case DateTimeFormatInfoScanner.IgnorableSymbolChar:
string symbol = dateWords[i].Substring(1);
InsertHash(temp, symbol, TokenType.IgnorableSymbol, 0);
- if (this.DateSeparator.Trim(null).Equals(symbol))
+ if (DateSeparator.Trim(null).Equals(symbol))
{
// The date separator is the same as the ignorable symbol.
useDateSepAsIgnorableSymbol = true;
@@ -2417,7 +2317,7 @@ namespace System.Globalization
if (!useDateSepAsIgnorableSymbol)
{
// Use the normal date separator.
- InsertHash(temp, this.DateSeparator, TokenType.SEP_Date, 0);
+ InsertHash(temp, DateSeparator, TokenType.SEP_Date, 0);
}
// Add the regular month names.
AddMonthNames(temp);
@@ -2434,7 +2334,7 @@ namespace System.Globalization
for (int i = 1; i <= 13; i++)
{
string str;
- str = internalGetMonthName(i, MonthNameStyles.Genitive, false);
+ str = InternalGetMonthName(i, MonthNameStyles.Genitive, false);
InsertHash(temp, str, TokenType.MonthToken, i);
}
}
@@ -2444,7 +2344,7 @@ namespace System.Globalization
for (int i = 1; i <= 13; i++)
{
string str;
- str = internalGetMonthName(i, MonthNameStyles.LeapYear, false);
+ str = InternalGetMonthName(i, MonthNameStyles.LeapYear, false);
InsertHash(temp, str, TokenType.MonthToken, i);
}
}
@@ -2467,7 +2367,6 @@ namespace System.Globalization
InsertHash(temp, GetAbbreviatedEraName(i), TokenType.EraToken, i);
}
- // TODO: This ignores other cultures that might want to do something similar
if (LanguageName.Equals(JapaneseLangName))
{
// Japanese allows day of week forms like: "(Tue)"
@@ -2476,7 +2375,7 @@ namespace System.Globalization
string specialDayOfWeek = "(" + GetAbbreviatedDayName((DayOfWeek)i) + ")";
InsertHash(temp, specialDayOfWeek, TokenType.DayOfWeekToken, i);
}
- if (this.Calendar.GetType() != typeof(JapaneseCalendar))
+ if (Calendar.GetType() != typeof(JapaneseCalendar))
{
// Special case for Japanese. If this is a Japanese DTFI, and the calendar is not Japanese calendar,
// we will check Japanese Era name as well when the calendar is Gregorian.
@@ -2573,19 +2472,15 @@ namespace System.Globalization
}
}
- ////////////////////////////////////////////////////////////////////////
- //
- // Actions:
- // Try to parse the current word to see if it is a Hebrew number.
- // Tokens will be updated accordingly.
- // This is called by the Lexer of DateTime.Parse().
- //
- // Unlike most of the functions in this class, the return value indicates
- // whether or not it started to parse. The badFormat parameter indicates
- // if parsing began, but the format was bad.
- //
- ////////////////////////////////////////////////////////////////////////
-
+ /// <summary>
+ /// Try to parse the current word to see if it is a Hebrew number.
+ /// Tokens will be updated accordingly.
+ /// This is called by the Lexer of DateTime.Parse().
+ ///
+ /// Unlike most of the functions in this class, the return value indicates
+ /// whether or not it started to parse. The badFormat parameter indicates
+ /// if parsing began, but the format was bad.
+ /// </summary>
private static bool TryParseHebrewNumber(
ref __DTString str,
out bool badFormat,
@@ -2599,7 +2494,7 @@ namespace System.Globalization
{
// If the current character is not a Hebrew digit, just return false.
// There is no chance that we can parse a valid Hebrew number from here.
- return (false);
+ return false;
}
// The current character is a Hebrew digit. Try to parse this word as a Hebrew number.
HebrewNumberParsingContext context = new HebrewNumberParsingContext(0);
@@ -2613,7 +2508,7 @@ namespace System.Globalization
case HebrewNumberParsingState.InvalidHebrewNumber: // Not a valid Hebrew number.
case HebrewNumberParsingState.NotHebrewDigit: // The current character is not a Hebrew digit character.
// Break out so that we don't continue to try parse this as a Hebrew number.
- return (false);
+ return false;
}
} while (i < str.Value.Length && (state != HebrewNumberParsingState.FoundEndOfHebrewNumber));
@@ -2624,7 +2519,7 @@ namespace System.Globalization
if (state != HebrewNumberParsingState.FoundEndOfHebrewNumber)
{
// We reach end of the string but we can't find a terminal state in parsing Hebrew number.
- return (false);
+ return false;
}
// We have found a valid Hebrew number. Update the index.
@@ -2633,7 +2528,7 @@ namespace System.Globalization
// Get the final Hebrew number value from the HebrewNumberParsingContext.
number = context.result;
- return (true);
+ return true;
}
private static bool IsHebrewChar(char ch)
@@ -2673,7 +2568,7 @@ namespace System.Globalization
bool isLetter = char.IsLetter(ch);
if (isLetter)
{
- ch = this.Culture.TextInfo.ToLower(ch);
+ ch = Culture.TextInfo.ToLower(ch);
if (IsHebrewChar(ch) && TokenMask == TokenType.RegularTokenMask)
{
bool badFormat;
@@ -2739,7 +2634,7 @@ namespace System.Globalization
tokenType = value.tokenType & TokenMask;
tokenValue = value.tokenValue;
str.Advance(value.tokenString.Length);
- return (true);
+ return true;
}
else if ((value.tokenType == TokenType.MonthToken && HasSpacesInMonthNames) ||
(value.tokenType == TokenType.DayOfWeekToken && HasSpacesInDayNames))
@@ -2751,7 +2646,7 @@ namespace System.Globalization
tokenType = value.tokenType & TokenMask;
tokenValue = value.tokenValue;
str.Advance(matchStrLen);
- return (true);
+ return true;
}
}
}
@@ -2760,7 +2655,7 @@ namespace System.Globalization
if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
} while (i < TOKEN_HASH_SIZE);
- return (false);
+ return false;
}
private void InsertAtCurrentHashNode(TokenHashValue[] hashTable, string str, char ch, TokenType tokenType, int tokenValue, int pos, int hashcode, int hashProbe)
@@ -2768,7 +2663,6 @@ namespace System.Globalization
// Remember the current slot.
TokenHashValue previousNode = hashTable[hashcode];
- //// Console.WriteLine(" Insert Key: {0} in {1}", str, slotToInsert);
// Insert the new node into the current slot.
hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue); ;
@@ -2779,13 +2673,12 @@ namespace System.Globalization
// Remember this slot
TokenHashValue temp = hashTable[hashcode];
- if (temp != null && this.Culture.TextInfo.ToLower(temp.tokenString[0]) != ch)
+ if (temp != null && Culture.TextInfo.ToLower(temp.tokenString[0]) != ch)
{
continue;
}
// Put the previous slot into this slot.
hashTable[hashcode] = previousNode;
- //// Console.WriteLine(" Move {0} to slot {1}", previousNode.tokenString, hashcode);
if (temp == null)
{
// Done
@@ -2812,9 +2705,11 @@ namespace System.Globalization
str = str.Trim(null); // Trim white space characters.
// Could have space for separators
if (str.Length == 0)
+ {
return;
+ }
}
- char ch = this.Culture.TextInfo.ToLower(str[0]);
+ char ch = Culture.TextInfo.ToLower(str[0]);
int hashcode = ch % TOKEN_HASH_SIZE;
int hashProbe = 1 + ch % SECOND_PRIME;
do
@@ -2822,7 +2717,6 @@ namespace System.Globalization
value = hashTable[hashcode];
if (value == null)
{
- //// Console.WriteLine(" Put Key: {0} in {1}", str, hashcode);
hashTable[hashcode] = new TokenHashValue(str, tokenType, tokenValue);
return;
}
@@ -2833,7 +2727,7 @@ namespace System.Globalization
{
// If there are two tokens with the same prefix, we have to make sure that the longer token should be at the front of
// the shorter ones.
- if (this.CompareStringIgnoreCaseOptimized(str, 0, value.tokenString.Length, value.tokenString, 0, value.tokenString.Length))
+ if (CompareStringIgnoreCaseOptimized(str, 0, value.tokenString.Length, value.tokenString, 0, value.tokenString.Length))
{
if (str.Length > value.tokenString.Length)
{
@@ -2848,19 +2742,13 @@ namespace System.Globalization
// If we have the same regular token or separator token in the hash already, do NOT update the hash.
// Therefore, the order of inserting token is significant here regarding what tokenType will be kept in the hash.
-
- //
// Check the current value of RegularToken (stored in the lower 8-bit of tokenType) , and insert the tokenType into the hash ONLY when we don't have a RegularToken yet.
// Also check the current value of SeparatorToken (stored in the upper 8-bit of token), and insert the tokenType into the hash ONLY when we don't have the SeparatorToken yet.
- //
int nTokenType = (int)tokenType;
int nCurrentTokenTypeInHash = (int)value.tokenType;
- //
// The folowing is the fix for the issue of throwing FormatException when "mar" is passed in string of the short date format dd/MMM/yyyy for es-MX
- //
-
if (((nCurrentTokenTypeInHash & (int)TokenType.RegularTokenMask) == 0) && ((nTokenType & (int)TokenType.RegularTokenMask) != 0) ||
((nCurrentTokenTypeInHash & (int)TokenType.SeparatorTokenMask) == 0) && ((nTokenType & (int)TokenType.SeparatorTokenMask) != 0))
{
@@ -2876,7 +2764,6 @@ namespace System.Globalization
}
}
}
- //// Console.WriteLine(" COLLISION. Old Key: {0}, New Key: {1}", hashTable[hashcode].tokenString, str);
i++;
hashcode += hashProbe;
if (hashcode >= TOKEN_HASH_SIZE) hashcode -= TOKEN_HASH_SIZE;
@@ -2892,11 +2779,9 @@ namespace System.Globalization
return true;
}
- return (this.Culture.CompareInfo.Compare(string1, offset1, length1, string2, offset2, length2, CompareOptions.IgnoreCase) == 0);
+ return Culture.CompareInfo.Compare(string1, offset1, length1, string2, offset2, length2, CompareOptions.IgnoreCase) == 0;
}
- // class DateTimeFormatInfo
-
internal class TokenHashValue
{
internal string tokenString;
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeParse.cs b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeParse.cs
index 9c0913e8d4..bc0193d685 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/DateTimeParse.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/DateTimeParse.cs
@@ -3343,7 +3343,7 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
// Search leap year form.
if ((dtfi.FormatFlags & DateTimeFormatFlags.UseLeapYearMonth) != 0)
{
- int tempResult = str.MatchLongestWords(dtfi.internalGetLeapYearMonthNames(), ref maxMatchStrLen);
+ int tempResult = str.MatchLongestWords(dtfi.InternalGetLeapYearMonthNames(), ref maxMatchStrLen);
// We found a longer match in the leap year month name. Use this as the result.
// The result from MatchLongestWords is 0 ~ length of word array.
// So we increment the result by one to become the month value.
@@ -3414,7 +3414,7 @@ new DS[] { DS.ERROR, DS.TX_NNN, DS.TX_NNN, DS.TX_NNN, DS.ERROR, DS.ERROR,
// Search leap year form.
if ((dtfi.FormatFlags & DateTimeFormatFlags.UseLeapYearMonth) != 0)
{
- int tempResult = str.MatchLongestWords(dtfi.internalGetLeapYearMonthNames(), ref maxMatchStrLen);
+ int tempResult = str.MatchLongestWords(dtfi.InternalGetLeapYearMonthNames(), ref maxMatchStrLen);
// We found a longer match in the leap year month name. Use this as the result.
// The result from MatchLongestWords is 0 ~ length of word array.
// So we increment the result by one to become the month value.
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/EastAsianLunisolarCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/EastAsianLunisolarCalendar.cs
index 58cdedf350..00398ca021 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/EastAsianLunisolarCalendar.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/EastAsianLunisolarCalendar.cs
@@ -147,7 +147,7 @@ namespace System.Globalization
throw new ArgumentOutOfRangeException(
"time",
ticks,
- string.Format(CultureInfo.InvariantCulture, SR.ArgumentOutOfRange_CalendarRange,
+ SR.Format(CultureInfo.InvariantCulture, SR.ArgumentOutOfRange_CalendarRange,
MinSupportedDateTime, MaxSupportedDateTime));
}
}
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs b/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs
index ebe6892ee6..b7dd868258 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/GregorianCalendarHelper.cs
@@ -182,8 +182,7 @@ namespace System.Globalization
{
throw new ArgumentOutOfRangeException(
nameof(year),
- string.Format(
- CultureInfo.CurrentCulture,
+ SR.Format(
SR.ArgumentOutOfRange_Range,
m_EraInfo[i].minEraYear,
m_EraInfo[i].maxEraYear));
@@ -324,8 +323,7 @@ namespace System.Globalization
{
throw new ArgumentOutOfRangeException(
nameof(millisecond),
- string.Format(
- CultureInfo.CurrentCulture,
+ SR.Format(
SR.ArgumentOutOfRange_Range,
0,
MillisPerSecond - 1));
@@ -342,7 +340,7 @@ namespace System.Globalization
{
throw new ArgumentOutOfRangeException(
"time",
- string.Format(
+ SR.Format(
CultureInfo.InvariantCulture,
SR.ArgumentOutOfRange_CalendarRange,
m_Cal.MinSupportedDateTime,
@@ -373,8 +371,7 @@ namespace System.Globalization
{
throw new ArgumentOutOfRangeException(
nameof(months),
- string.Format(
- CultureInfo.CurrentCulture,
+ SR.Format(
SR.ArgumentOutOfRange_Range,
-120000,
120000));
@@ -571,8 +568,7 @@ namespace System.Globalization
{
throw new ArgumentOutOfRangeException(
nameof(day),
- string.Format(
- CultureInfo.CurrentCulture,
+ SR.Format(
SR.ArgumentOutOfRange_Range,
1,
GetDaysInMonth(year, month, era)));
@@ -610,8 +606,7 @@ namespace System.Globalization
{
throw new ArgumentOutOfRangeException(
nameof(month),
- string.Format(
- CultureInfo.CurrentCulture,
+ SR.Format(
SR.ArgumentOutOfRange_Range,
1,
12));
@@ -665,9 +660,7 @@ namespace System.Globalization
{
throw new ArgumentOutOfRangeException(
nameof(year),
- string.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range, m_minYear, m_maxYear));
+ SR.Format(SR.ArgumentOutOfRange_Range, m_minYear, m_maxYear));
}
// If the year value is above 100, just return the year value. Don't have to do
// the TwoDigitYearMax comparison.
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/HebrewCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/HebrewCalendar.cs
index 3b8a77a99b..dcab7e7158 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/HebrewCalendar.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/HebrewCalendar.cs
@@ -353,7 +353,7 @@ namespace System.Globalization
"time",
ticks,
// Print out the date in Gregorian using InvariantCulture since the DateTime is based on GreograinCalendar.
- string.Format(
+ SR.Format(
CultureInfo.InvariantCulture,
SR.ArgumentOutOfRange_CalendarRange,
s_calendarMinValue,
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.cs
index e773df1376..71cdb346fd 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/HijriCalendar.cs
@@ -145,7 +145,7 @@ namespace System.Globalization
throw new ArgumentOutOfRangeException(
"time",
ticks,
- string.Format(
+ SR.Format(
CultureInfo.InvariantCulture,
SR.ArgumentOutOfRange_CalendarRange,
s_calendarMinValue,
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/NumberFormatInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/NumberFormatInfo.cs
index 1945c891b3..09030b9e07 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/NumberFormatInfo.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/NumberFormatInfo.cs
@@ -2,79 +2,74 @@
// 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.Globalization
{
- //
- // Property Default Description
- // PositiveSign '+' Character used to indicate positive values.
- // NegativeSign '-' Character used to indicate negative values.
- // NumberDecimalSeparator '.' The character used as the decimal separator.
- // NumberGroupSeparator ',' The character used to separate groups of
- // digits to the left of the decimal point.
- // NumberDecimalDigits 2 The default number of decimal places.
- // NumberGroupSizes 3 The number of digits in each group to the
- // left of the decimal point.
- // NaNSymbol "NaN" The string used to represent NaN values.
- // PositiveInfinitySymbol"Infinity" The string used to represent positive
- // infinities.
- // NegativeInfinitySymbol"-Infinity" The string used to represent negative
- // infinities.
- //
- //
- //
- // Property Default Description
- // CurrencyDecimalSeparator '.' The character used as the decimal
- // separator.
- // CurrencyGroupSeparator ',' The character used to separate groups
- // of digits to the left of the decimal
- // point.
- // CurrencyDecimalDigits 2 The default number of decimal places.
- // CurrencyGroupSizes 3 The number of digits in each group to
- // the left of the decimal point.
- // CurrencyPositivePattern 0 The format of positive values.
- // CurrencyNegativePattern 0 The format of negative values.
- // CurrencySymbol "$" String used as local monetary symbol.
- //
-
+ /// <remarks>
+ /// Property Default Description
+ /// PositiveSign '+' Character used to indicate positive values.
+ /// NegativeSign '-' Character used to indicate negative values.
+ /// NumberDecimalSeparator '.' The character used as the decimal separator.
+ /// NumberGroupSeparator ',' The character used to separate groups of
+ /// digits to the left of the decimal point.
+ /// NumberDecimalDigits 2 The default number of decimal places.
+ /// NumberGroupSizes 3 The number of digits in each group to the
+ /// left of the decimal point.
+ /// NaNSymbol "NaN" The string used to represent NaN values.
+ /// PositiveInfinitySymbol"Infinity" The string used to represent positive
+ /// infinities.
+ /// NegativeInfinitySymbol"-Infinity" The string used to represent negative
+ /// infinities.
+ ///
+ /// Property Default Description
+ /// CurrencyDecimalSeparator '.' The character used as the decimal
+ /// separator.
+ /// CurrencyGroupSeparator ',' The character used to separate groups
+ /// of digits to the left of the decimal
+ /// point.
+ /// CurrencyDecimalDigits 2 The default number of decimal places.
+ /// CurrencyGroupSizes 3 The number of digits in each group to
+ /// the left of the decimal point.
+ /// CurrencyPositivePattern 0 The format of positive values.
+ /// CurrencyNegativePattern 0 The format of negative values.
+ /// CurrencySymbol "$" String used as local monetary symbol.
+ /// </remarks>
public sealed class NumberFormatInfo : IFormatProvider, ICloneable
{
- // invariantInfo is constant irrespective of your current culture.
private static volatile NumberFormatInfo s_invariantInfo;
- internal int[] numberGroupSizes = new int[] { 3 };
- internal int[] currencyGroupSizes = new int[] { 3 };
- internal int[] percentGroupSizes = new int[] { 3 };
- internal string positiveSign = "+";
- internal string negativeSign = "-";
- internal string numberDecimalSeparator = ".";
- internal string numberGroupSeparator = ",";
- internal string currencyGroupSeparator = ",";
- internal string currencyDecimalSeparator = ".";
- internal string currencySymbol = "\x00a4"; // U+00a4 is the symbol for International Monetary Fund.
- internal string nanSymbol = "NaN";
- internal string positiveInfinitySymbol = "Infinity";
- internal string negativeInfinitySymbol = "-Infinity";
- internal string percentDecimalSeparator = ".";
- internal string percentGroupSeparator = ",";
- internal string percentSymbol = "%";
- internal string perMilleSymbol = "\u2030";
-
-
- internal string[] nativeDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
-
- internal int numberDecimalDigits = 2;
- internal int currencyDecimalDigits = 2;
- internal int currencyPositivePattern = 0;
- internal int currencyNegativePattern = 0;
- internal int numberNegativePattern = 1;
- internal int percentPositivePattern = 0;
- internal int percentNegativePattern = 0;
- internal int percentDecimalDigits = 2;
-
- internal int digitSubstitution = (int)DigitShapes.None;
-
- internal bool isReadOnly = false;
+ internal int[] _numberGroupSizes = new int[] { 3 };
+ internal int[] _currencyGroupSizes = new int[] { 3 };
+ internal int[] _percentGroupSizes = new int[] { 3 };
+ internal string _positiveSign = "+";
+ internal string _negativeSign = "-";
+ internal string _numberDecimalSeparator = ".";
+ internal string _numberGroupSeparator = ",";
+ internal string _currencyGroupSeparator = ",";
+ internal string _currencyDecimalSeparator = ".";
+ internal string _currencySymbol = "\x00a4"; // U+00a4 is the symbol for International Monetary Fund.
+ internal string _nanSymbol = "NaN";
+ internal string _positiveInfinitySymbol = "Infinity";
+ internal string _negativeInfinitySymbol = "-Infinity";
+ internal string _percentDecimalSeparator = ".";
+ internal string _percentGroupSeparator = ",";
+ internal string _percentSymbol = "%";
+ internal string _perMilleSymbol = "\u2030";
+
+
+ internal string[] _nativeDigits = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
+
+ internal int _numberDecimalDigits = 2;
+ internal int _currencyDecimalDigits = 2;
+ internal int _currencyPositivePattern = 0;
+ internal int _currencyNegativePattern = 0;
+ internal int _numberNegativePattern = 1;
+ internal int _percentPositivePattern = 0;
+ internal int _percentNegativePattern = 0;
+ internal int _percentDecimalDigits = 2;
+
+ internal int _digitSubstitution = (int)DigitShapes.None;
+
+ internal bool _isReadOnly = false;
private bool _hasInvariantNumberSigns = true;
@@ -86,13 +81,12 @@ namespace System.Globalization
{
if (decSep == null)
{
- throw new ArgumentNullException(propertyName,
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(propertyName);
}
if (decSep.Length == 0)
{
- throw new ArgumentException(SR.Argument_EmptyDecString);
+ throw new ArgumentException(SR.Argument_EmptyDecString, propertyName);
}
}
@@ -100,8 +94,7 @@ namespace System.Globalization
{
if (groupSep == null)
{
- throw new ArgumentNullException(propertyName,
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(propertyName);
}
}
@@ -167,7 +160,7 @@ namespace System.Globalization
private void UpdateHasInvariantNumberSigns()
{
- _hasInvariantNumberSigns = positiveSign == "+" && negativeSign == "-";
+ _hasInvariantNumberSigns = _positiveSign == "+" && _negativeSign == "-";
}
internal NumberFormatInfo(CultureData cultureData)
@@ -184,17 +177,17 @@ namespace System.Globalization
private void VerifyWritable()
{
- if (isReadOnly)
+ if (_isReadOnly)
{
throw new InvalidOperationException(SR.InvalidOperation_ReadOnly);
}
}
- // Returns a default NumberFormatInfo that will be universally
- // supported and constant irrespective of the current culture.
- // Used by FromString methods.
- //
-
+ /// <summary>
+ /// Returns a default NumberFormatInfo that will be universally
+ /// supported and constant irrespective of the current culture.
+ /// Used by FromString methods.
+ /// </summary>
public static NumberFormatInfo InvariantInfo
{
get
@@ -205,7 +198,7 @@ namespace System.Globalization
// be thrown out of a .cctor stack that will need this.
s_invariantInfo = new NumberFormatInfo
{
- isReadOnly = true
+ _isReadOnly = true
};
}
return s_invariantInfo;
@@ -236,58 +229,47 @@ namespace System.Globalization
public object Clone()
{
NumberFormatInfo n = (NumberFormatInfo)MemberwiseClone();
- n.isReadOnly = false;
+ n._isReadOnly = false;
return n;
}
public int CurrencyDecimalDigits
{
- get { return currencyDecimalDigits; }
+ get => _currencyDecimalDigits;
set
{
if (value < 0 || value > 99)
{
throw new ArgumentOutOfRangeException(
- nameof(CurrencyDecimalDigits),
- string.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 99));
+ nameof(value),
+ value,
+ SR.Format(SR.ArgumentOutOfRange_Range, 0, 99));
}
+
VerifyWritable();
- currencyDecimalDigits = value;
+ _currencyDecimalDigits = value;
}
}
-
public string CurrencyDecimalSeparator
{
- get { return currencyDecimalSeparator; }
+ get => _currencyDecimalSeparator;
set
{
VerifyWritable();
- VerifyDecimalSeparator(value, nameof(CurrencyDecimalSeparator));
- currencyDecimalSeparator = value;
+ VerifyDecimalSeparator(value, nameof(value));
+ _currencyDecimalSeparator = value;
}
}
+ public bool IsReadOnly => _isReadOnly;
- public bool IsReadOnly
- {
- get
- {
- return isReadOnly;
- }
- }
-
- //
- // Check the values of the groupSize array.
- //
- // Every element in the groupSize array should be between 1 and 9
- // excpet the last element could be zero.
- //
+ /// <summary>
+ /// Check the values of the groupSize array.
+ /// Every element in the groupSize array should be between 1 and 9
+ /// except the last element could be zero.
+ /// </summary>
internal static void CheckGroupSize(string propName, int[] groupSize)
{
for (int i = 0; i < groupSize.Length; i++)
@@ -295,7 +277,10 @@ namespace System.Globalization
if (groupSize[i] < 1)
{
if (i == groupSize.Length - 1 && groupSize[i] == 0)
+ {
return;
+ }
+
throw new ArgumentException(SR.Argument_InvalidGroupSize, propName);
}
else if (groupSize[i] > 9)
@@ -308,96 +293,89 @@ namespace System.Globalization
public int[] CurrencyGroupSizes
{
- get
- {
- return ((int[])currencyGroupSizes.Clone());
- }
+ get => ((int[])_currencyGroupSizes.Clone());
set
{
if (value == null)
{
- throw new ArgumentNullException(nameof(CurrencyGroupSizes));
+ throw new ArgumentNullException(nameof(value));
}
+
VerifyWritable();
int[] inputSizes = (int[])value.Clone();
- CheckGroupSize(nameof(CurrencyGroupSizes), inputSizes);
- currencyGroupSizes = inputSizes;
+ CheckGroupSize(nameof(value), inputSizes);
+ _currencyGroupSizes = inputSizes;
}
}
-
-
public int[] NumberGroupSizes
{
- get
- {
- return ((int[])numberGroupSizes.Clone());
- }
+ get => ((int[])_numberGroupSizes.Clone());
set
{
if (value == null)
{
- throw new ArgumentNullException(nameof(NumberGroupSizes));
+ throw new ArgumentNullException(nameof(value));
}
+
VerifyWritable();
int[] inputSizes = (int[])value.Clone();
- CheckGroupSize(nameof(NumberGroupSizes), inputSizes);
- numberGroupSizes = inputSizes;
+ CheckGroupSize(nameof(value), inputSizes);
+ _numberGroupSizes = inputSizes;
}
}
public int[] PercentGroupSizes
{
- get
- {
- return ((int[])percentGroupSizes.Clone());
- }
+ get => ((int[])_percentGroupSizes.Clone());
set
{
if (value == null)
{
- throw new ArgumentNullException(nameof(PercentGroupSizes));
+ throw new ArgumentNullException(nameof(value));
}
+
VerifyWritable();
int[] inputSizes = (int[])value.Clone();
- CheckGroupSize(nameof(PercentGroupSizes), inputSizes);
- percentGroupSizes = inputSizes;
+ CheckGroupSize(nameof(value), inputSizes);
+ _percentGroupSizes = inputSizes;
}
}
public string CurrencyGroupSeparator
{
- get { return currencyGroupSeparator; }
+ get => _currencyGroupSeparator;
set
{
VerifyWritable();
- VerifyGroupSeparator(value, nameof(CurrencyGroupSeparator));
- currencyGroupSeparator = value;
+ VerifyGroupSeparator(value, nameof(value));
+ _currencyGroupSeparator = value;
}
}
public string CurrencySymbol
{
- get { return currencySymbol; }
+ get => _currencySymbol;
set
{
if (value == null)
{
- throw new ArgumentNullException(nameof(CurrencySymbol),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
+
VerifyWritable();
- currencySymbol = value;
+ _currencySymbol = value;
}
}
- // Returns the current culture's NumberFormatInfo. Used by Parse methods.
- //
+ /// <summary>
+ /// Returns the current culture's NumberFormatInfo. Used by Parse methods.
+ /// </summary>
public static NumberFormatInfo CurrentInfo
{
@@ -416,356 +394,309 @@ namespace System.Globalization
}
}
-
public string NaNSymbol
{
- get
- {
- return nanSymbol;
- }
+ get => _nanSymbol;
set
{
if (value == null)
{
- throw new ArgumentNullException(nameof(NaNSymbol),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
+
VerifyWritable();
- nanSymbol = value;
+ _nanSymbol = value;
}
}
-
-
public int CurrencyNegativePattern
{
- get { return currencyNegativePattern; }
+ get => _currencyNegativePattern;
set
{
if (value < 0 || value > 15)
{
throw new ArgumentOutOfRangeException(
- nameof(CurrencyNegativePattern),
- string.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 15));
+ nameof(value),
+ value,
+ SR.Format(SR.ArgumentOutOfRange_Range, 0, 15));
}
+
VerifyWritable();
- currencyNegativePattern = value;
+ _currencyNegativePattern = value;
}
}
-
public int NumberNegativePattern
{
- get { return numberNegativePattern; }
+ get => _numberNegativePattern;
set
{
- //
// NOTENOTE: the range of value should correspond to negNumberFormats[] in vm\COMNumber.cpp.
- //
if (value < 0 || value > 4)
{
throw new ArgumentOutOfRangeException(
- nameof(NumberNegativePattern),
- string.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 4));
+ nameof(value),
+ value,
+ SR.Format(SR.ArgumentOutOfRange_Range, 0, 4));
}
+
VerifyWritable();
- numberNegativePattern = value;
+ _numberNegativePattern = value;
}
}
-
public int PercentPositivePattern
{
- get { return percentPositivePattern; }
+ get => _percentPositivePattern;
set
{
- //
// NOTENOTE: the range of value should correspond to posPercentFormats[] in vm\COMNumber.cpp.
- //
if (value < 0 || value > 3)
{
throw new ArgumentOutOfRangeException(
- nameof(PercentPositivePattern),
- string.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 3));
+ nameof(value),
+ value,
+ SR.Format(SR.ArgumentOutOfRange_Range, 0, 3));
}
+
VerifyWritable();
- percentPositivePattern = value;
+ _percentPositivePattern = value;
}
}
-
public int PercentNegativePattern
{
- get { return percentNegativePattern; }
+ get => _percentNegativePattern;
set
{
- //
// NOTENOTE: the range of value should correspond to posPercentFormats[] in vm\COMNumber.cpp.
- //
if (value < 0 || value > 11)
{
throw new ArgumentOutOfRangeException(
- nameof(PercentNegativePattern),
- string.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 11));
+ nameof(value),
+ value,
+ SR.Format(SR.ArgumentOutOfRange_Range, 0, 11));
}
+
VerifyWritable();
- percentNegativePattern = value;
+ _percentNegativePattern = value;
}
}
-
public string NegativeInfinitySymbol
{
- get
- {
- return negativeInfinitySymbol;
- }
+ get => _negativeInfinitySymbol;
set
{
if (value == null)
{
- throw new ArgumentNullException(nameof(NegativeInfinitySymbol),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
+
VerifyWritable();
- negativeInfinitySymbol = value;
+ _negativeInfinitySymbol = value;
}
}
-
public string NegativeSign
{
- get { return negativeSign; }
+ get => _negativeSign;
set
{
if (value == null)
{
- throw new ArgumentNullException(nameof(NegativeSign),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
+
VerifyWritable();
- negativeSign = value;
+ _negativeSign = value;
UpdateHasInvariantNumberSigns();
}
}
-
public int NumberDecimalDigits
{
- get { return numberDecimalDigits; }
+ get => _numberDecimalDigits;
set
{
if (value < 0 || value > 99)
{
throw new ArgumentOutOfRangeException(
- nameof(NumberDecimalDigits),
- string.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 99));
+ nameof(value),
+ value,
+ SR.Format(SR.ArgumentOutOfRange_Range, 0, 99));
}
+
VerifyWritable();
- numberDecimalDigits = value;
+ _numberDecimalDigits = value;
}
}
-
public string NumberDecimalSeparator
{
- get { return numberDecimalSeparator; }
+ get => _numberDecimalSeparator;
set
{
VerifyWritable();
- VerifyDecimalSeparator(value, nameof(NumberDecimalSeparator));
- numberDecimalSeparator = value;
+ VerifyDecimalSeparator(value, nameof(value));
+ _numberDecimalSeparator = value;
}
}
-
public string NumberGroupSeparator
{
- get { return numberGroupSeparator; }
+ get => _numberGroupSeparator;
set
{
VerifyWritable();
- VerifyGroupSeparator(value, nameof(NumberGroupSeparator));
- numberGroupSeparator = value;
+ VerifyGroupSeparator(value, nameof(value));
+ _numberGroupSeparator = value;
}
}
-
public int CurrencyPositivePattern
{
- get { return currencyPositivePattern; }
+ get => _currencyPositivePattern;
set
{
if (value < 0 || value > 3)
{
throw new ArgumentOutOfRangeException(
- nameof(CurrencyPositivePattern),
- string.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 3));
+ nameof(value),
+ value,
+ SR.Format(SR.ArgumentOutOfRange_Range, 0, 3));
}
+
VerifyWritable();
- currencyPositivePattern = value;
+ _currencyPositivePattern = value;
}
}
-
public string PositiveInfinitySymbol
{
- get
- {
- return positiveInfinitySymbol;
- }
+ get => _positiveInfinitySymbol;
set
{
if (value == null)
{
- throw new ArgumentNullException(nameof(PositiveInfinitySymbol),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
+
VerifyWritable();
- positiveInfinitySymbol = value;
+ _positiveInfinitySymbol = value;
}
}
-
public string PositiveSign
{
- get { return positiveSign; }
+ get => _positiveSign;
set
{
if (value == null)
{
- throw new ArgumentNullException(nameof(PositiveSign),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
+
VerifyWritable();
- positiveSign = value;
+ _positiveSign = value;
UpdateHasInvariantNumberSigns();
}
}
-
public int PercentDecimalDigits
{
- get { return percentDecimalDigits; }
+ get => _percentDecimalDigits;
set
{
if (value < 0 || value > 99)
{
throw new ArgumentOutOfRangeException(
- nameof(PercentDecimalDigits),
- string.Format(
- CultureInfo.CurrentCulture,
- SR.ArgumentOutOfRange_Range,
- 0,
- 99));
+ nameof(value),
+ value,
+ SR.Format(SR.ArgumentOutOfRange_Range, 0, 99));
}
+
VerifyWritable();
- percentDecimalDigits = value;
+ _percentDecimalDigits = value;
}
}
public string PercentDecimalSeparator
{
- get { return percentDecimalSeparator; }
+ get => _percentDecimalSeparator;
set
{
VerifyWritable();
- VerifyDecimalSeparator(value, nameof(PercentDecimalSeparator));
- percentDecimalSeparator = value;
+ VerifyDecimalSeparator(value, nameof(value));
+ _percentDecimalSeparator = value;
}
}
public string PercentGroupSeparator
{
- get { return percentGroupSeparator; }
+ get => _percentGroupSeparator;
set
{
VerifyWritable();
- VerifyGroupSeparator(value, nameof(PercentGroupSeparator));
- percentGroupSeparator = value;
+ VerifyGroupSeparator(value, nameof(value));
+ _percentGroupSeparator = value;
}
}
public string PercentSymbol
{
- get
- {
- return percentSymbol;
- }
+ get => _percentSymbol;
set
{
if (value == null)
{
- throw new ArgumentNullException(nameof(PercentSymbol),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
+
VerifyWritable();
- percentSymbol = value;
+ _percentSymbol = value;
}
}
public string PerMilleSymbol
{
- get { return perMilleSymbol; }
+ get => _perMilleSymbol;
set
{
if (value == null)
{
- throw new ArgumentNullException(nameof(PerMilleSymbol),
- SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
+
VerifyWritable();
- perMilleSymbol = value;
+ _perMilleSymbol = value;
}
}
public string[] NativeDigits
{
- get { return (string[])nativeDigits.Clone(); }
+ get => (string[])_nativeDigits.Clone();
set
{
VerifyWritable();
- VerifyNativeDigits(value, nameof(NativeDigits));
- nativeDigits = value;
+ VerifyNativeDigits(value, nameof(value));
+ _nativeDigits = value;
}
}
public DigitShapes DigitSubstitution
{
- get { return (DigitShapes)digitSubstitution; }
+ get => (DigitShapes)_digitSubstitution;
set
{
VerifyWritable();
- VerifyDigitSubstitution(value, nameof(DigitSubstitution));
- digitSubstitution = (int)value;
+ VerifyDigitSubstitution(value, nameof(value));
+ _digitSubstitution = (int)value;
}
}
@@ -780,12 +711,14 @@ namespace System.Globalization
{
throw new ArgumentNullException(nameof(nfi));
}
+
if (nfi.IsReadOnly)
{
- return (nfi);
+ return nfi;
}
+
NumberFormatInfo info = (NumberFormatInfo)(nfi.MemberwiseClone());
- info.isReadOnly = true;
+ info._isReadOnly = true;
return info;
}
@@ -810,6 +743,7 @@ namespace System.Globalization
{
throw new ArgumentException(SR.Argument_InvalidNumberStyles, nameof(style));
}
+
throw new ArgumentException(SR.Arg_InvalidHexStyle);
}
}
@@ -828,18 +762,10 @@ namespace System.Globalization
{
throw new ArgumentException(SR.Argument_InvalidNumberStyles, nameof(style));
}
+
throw new ArgumentException(SR.Arg_HexStyleNotSupported);
}
}
}
- } // NumberFormatInfo
+ }
}
-
-
-
-
-
-
-
-
-
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/NumberStyles.cs b/src/System.Private.CoreLib/shared/System/Globalization/NumberStyles.cs
index 5909d65a2c..cf5a081016 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/NumberStyles.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/NumberStyles.cs
@@ -2,49 +2,54 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-/*============================================================
-**
-**
-**
-** Purpose: Contains valid formats for Numbers recognized by
-** the Number class' parsing code.
-**
-**
-===========================================================*/
-
namespace System.Globalization
{
+ /// <summary>
+ /// Contains valid formats for Numbers recognized by the Number
+ /// class' parsing code.
+ /// </summary>
[Flags]
public enum NumberStyles
{
- // Bit flag indicating that leading whitespace is allowed. Character values
- // 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, and 0x0020 are considered to be
- // whitespace.
-
None = 0x00000000,
+ /// <summary>
+ /// Bit flag indicating that leading whitespace is allowed. Character values
+ /// 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, and 0x0020 are considered to be
+ /// whitespace.
+ /// </summary>
AllowLeadingWhite = 0x00000001,
- AllowTrailingWhite = 0x00000002, //Bitflag indicating trailing whitespace is allowed.
-
- AllowLeadingSign = 0x00000004, //Can the number start with a sign char.
- //Specified by NumberFormatInfo.PositiveSign and NumberFormatInfo.NegativeSign
+ /// <summary>
+ /// Bitflag indicating trailing whitespace is allowed.
+ /// </summary>
+ AllowTrailingWhite = 0x00000002,
- AllowTrailingSign = 0x00000008, //Allow the number to end with a sign char
+ /// <summary>
+ /// Can the number start with a sign char specified by
+ /// NumberFormatInfo.PositiveSign and NumberFormatInfo.NegativeSign
+ /// </summary>
+ AllowLeadingSign = 0x00000004,
- AllowParentheses = 0x00000010, //Allow the number to be enclosed in parens
+ /// <summary>
+ /// Allow the number to end with a sign char
+ /// </summary>
+ AllowTrailingSign = 0x00000008,
- AllowDecimalPoint = 0x00000020, //Allow a decimal point
+ /// <summary>
+ /// Allow the number to be enclosed in parens
+ /// </summary>
+ AllowParentheses = 0x00000010,
- AllowThousands = 0x00000040, //Allow thousands separators (more properly, allow group separators)
+ AllowDecimalPoint = 0x00000020,
- AllowExponent = 0x00000080, //Allow an exponent
+ AllowThousands = 0x00000040,
- AllowCurrencySymbol = 0x00000100, //Allow a currency symbol.
+ AllowExponent = 0x00000080,
- AllowHexSpecifier = 0x00000200, //Allow specifiying hexadecimal.
- //Common uses. These represent some of the most common combinations of these flags.
+ AllowCurrencySymbol = 0x00000100,
+ AllowHexSpecifier = 0x00000200,
Integer = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign,
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/RegionInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/RegionInfo.cs
index 576672b222..03bed85c00 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/RegionInfo.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/RegionInfo.cs
@@ -2,91 +2,61 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-////////////////////////////////////////////////////////////////////////////
-//
-//
-// Purpose: This class represents settings specified by de jure or
-// de facto standards for a particular country/region. In
-// contrast to CultureInfo, the RegionInfo does not represent
-// preferences of the user and does not depend on the user's
-// language or culture.
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
using System.Diagnostics;
namespace System.Globalization
{
+ /// <summary>
+ /// This class represents settings specified by de jure or de facto
+ /// standards for a particular country/region. In contrast to
+ /// CultureInfo, the RegionInfo does not represent preferences of the
+ /// user and does not depend on the user's language or culture.
+ /// </summary>
public class RegionInfo
{
- //--------------------------------------------------------------------//
- // Internal Information //
- //--------------------------------------------------------------------//
-
- //
- // Variables.
- //
-
- //
// Name of this region (ie: es-US): serialized, the field used for deserialization
- //
- internal string _name;
+ private string _name;
- //
// The CultureData instance that we are going to read data from.
- //
- internal CultureData _cultureData;
+ private readonly CultureData _cultureData;
- //
// The RegionInfo for our current region
- //
internal static volatile RegionInfo s_currentRegionInfo;
-
- ////////////////////////////////////////////////////////////////////////
- //
- // RegionInfo Constructors
- //
- // Note: We prefer that a region be created with a full culture name (ie: en-US)
- // because otherwise the native strings won't be right.
- //
- // In Silverlight we enforce that RegionInfos must be created with a full culture name
- //
- ////////////////////////////////////////////////////////////////////////
public RegionInfo(string name)
{
if (name == null)
+ {
throw new ArgumentNullException(nameof(name));
+ }
- if (name.Length == 0) //The InvariantCulture has no matching region
+ // The InvariantCulture has no matching region
+ if (name.Length == 0)
{
throw new ArgumentException(SR.Argument_NoRegionInvariantCulture, nameof(name));
}
-
- //
// For CoreCLR we only want the region names that are full culture names
- //
_cultureData = CultureData.GetCultureDataForRegion(name, true);
if (_cultureData == null)
- throw new ArgumentException(
- string.Format(
- CultureInfo.CurrentCulture,
- SR.Argument_InvalidCultureName, name), nameof(name));
-
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidCultureName, name), nameof(name));
+ }
// Not supposed to be neutral
if (_cultureData.IsNeutralCulture)
+ {
throw new ArgumentException(SR.Format(SR.Argument_InvalidNeutralRegionName, name), nameof(name));
+ }
SetName(name);
}
public RegionInfo(int culture)
{
- if (culture == CultureInfo.LOCALE_INVARIANT) //The InvariantCulture has no matching region
- {
+ // The InvariantCulture has no matching region
+ if (culture == CultureInfo.LOCALE_INVARIANT)
+ {
throw new ArgumentException(SR.Argument_NoRegionInvariantCulture);
}
@@ -101,9 +71,9 @@ namespace System.Globalization
// Not supposed to be neutral
throw new ArgumentException(SR.Format(SR.Argument_CustomCultureCannotBePassedByNumber, culture), nameof(culture));
}
-
+
_cultureData = CultureData.GetCultureData(culture, true);
- _name = _cultureData.SREGIONNAME;
+ _name = _cultureData.RegionName;
if (_cultureData.IsNeutralCulture)
{
@@ -115,24 +85,19 @@ namespace System.Globalization
internal RegionInfo(CultureData cultureData)
{
_cultureData = cultureData;
- _name = _cultureData.SREGIONNAME;
+ _name = _cultureData.RegionName;
}
private void SetName(string name)
{
// Use the name of the region we found
- _name = _cultureData.SREGIONNAME;
+ _name = _cultureData.RegionName;
}
- ////////////////////////////////////////////////////////////////////////
- //
- // GetCurrentRegion
- //
- // This instance provides methods based on the current user settings.
- // These settings are volatile and may change over the lifetime of the
- // thread.
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// This instance provides methods based on the current user settings.
+ /// These settings are volatile and may change over the lifetime of the
+ /// </summary>
public static RegionInfo CurrentRegion
{
get
@@ -143,256 +108,100 @@ namespace System.Globalization
temp = new RegionInfo(CultureInfo.CurrentCulture._cultureData);
// Need full name for custom cultures
- temp._name = temp._cultureData.SREGIONNAME;
+ temp._name = temp._cultureData.RegionName;
s_currentRegionInfo = temp;
}
return temp;
}
}
- ////////////////////////////////////////////////////////////////////////
- //
- // GetName
- //
- // Returns the name of the region (ie: en-US)
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Returns the name of the region (ie: en-US)
+ /// </summary>
public virtual string Name
{
get
{
Debug.Assert(_name != null, "Expected RegionInfo._name to be populated already");
- return (_name);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetEnglishName
- //
- // Returns the name of the region in English. (ie: United States)
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string EnglishName
- {
- get
- {
- return (_cultureData.SENGCOUNTRY);
- }
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetDisplayName
- //
- // Returns the display name (localized) of the region. (ie: United States
- // if the current UI language is en-US)
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string DisplayName
- {
- get
- {
- return (_cultureData.SLOCALIZEDCOUNTRY);
- }
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetNativeName
- //
- // Returns the native name of the region. (ie: Deutschland)
- // WARNING: You need a full locale name for this to make sense.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string NativeName
- {
- get
- {
- return (_cultureData.SNATIVECOUNTRY);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // TwoLetterISORegionName
- //
- // Returns the two letter ISO region name (ie: US)
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string TwoLetterISORegionName
- {
- get
- {
- return (_cultureData.SISO3166CTRYNAME);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ThreeLetterISORegionName
- //
- // Returns the three letter ISO region name (ie: USA)
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string ThreeLetterISORegionName
- {
- get
- {
- return (_cultureData.SISO3166CTRYNAME2);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ThreeLetterWindowsRegionName
- //
- // Returns the three letter windows region name (ie: USA)
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string ThreeLetterWindowsRegionName
- {
- get
- {
- // ThreeLetterWindowsRegionName is really same as ThreeLetterISORegionName
- return ThreeLetterISORegionName;
- }
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // IsMetric
- //
- // Returns true if this region uses the metric measurement system
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual bool IsMetric
- {
- get
- {
- int value = _cultureData.IMEASURE;
- return (value == 0);
- }
- }
-
- public virtual int GeoId
- {
- get
- {
- return (_cultureData.IGEOID);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // CurrencyEnglishName
- //
- // English name for this region's currency, ie: Swiss Franc
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string CurrencyEnglishName
- {
- get
- {
- return (_cultureData.SENGLISHCURRENCY);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // CurrencyNativeName
- //
- // Native name for this region's currency, ie: Schweizer Franken
- // WARNING: You need a full locale name for this to make sense.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string CurrencyNativeName
- {
- get
- {
- return (_cultureData.SNATIVECURRENCY);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // CurrencySymbol
- //
- // Currency Symbol for this locale, ie: Fr. or $
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string CurrencySymbol
- {
- get
- {
- return (_cultureData.SCURRENCY);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // ISOCurrencySymbol
- //
- // ISO Currency Symbol for this locale, ie: CHF
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string ISOCurrencySymbol
- {
- get
- {
- return (_cultureData.SINTLSYMBOL);
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Equals
- //
- // Implements Object.Equals(). Returns a boolean indicating whether
- // or not object refers to the same RegionInfo as the current instance.
- //
- // RegionInfos are considered equal if and only if they have the same name
- // (ie: en-US)
- //
- ////////////////////////////////////////////////////////////////////////
+ return _name;
+ }
+ }
+
+ /// <summary>
+ /// Returns the name of the region in English. (ie: United States)
+ /// </summary>
+ public virtual string EnglishName => _cultureData.EnglishCountryName;
+
+ /// <summary>
+ /// Returns the display name (localized) of the region. (ie: United States
+ /// if the current UI language is en-US)
+ /// </summary>
+ public virtual string DisplayName => _cultureData.LocalizedCountryName;
+
+ /// <summary>
+ /// Returns the native name of the region. (ie: Deutschland)
+ /// WARNING: You need a full locale name for this to make sense.
+ /// </summary>
+ public virtual string NativeName => _cultureData.NativeCountryName;
+
+ /// <summary>
+ /// Returns the two letter ISO region name (ie: US)
+ /// </summary>
+ public virtual string TwoLetterISORegionName => _cultureData.TwoLetterISOCountryName;
+
+ /// <summary>
+ /// Returns the three letter ISO region name (ie: USA)
+ /// </summary>
+ public virtual string ThreeLetterISORegionName => _cultureData.ThreeLetterISOCountryName;
+
+ /// <summary>
+ /// Returns the three letter windows region name (ie: USA)
+ /// </summary>
+ public virtual string ThreeLetterWindowsRegionName => ThreeLetterISORegionName;
+
+
+ /// <summary>
+ /// Returns true if this region uses the metric measurement system
+ /// </summary>
+ public virtual bool IsMetric => _cultureData.MeasurementSystem == 0;
+
+ public virtual int GeoId => _cultureData.GeoId;
+
+ /// <summary>
+ /// English name for this region's currency, ie: Swiss Franc
+ /// </summary>
+ public virtual string CurrencyEnglishName => _cultureData.CurrencyEnglishName;
+
+ /// <summary>
+ /// Native name for this region's currency, ie: Schweizer Franken
+ /// WARNING: You need a full locale name for this to make sense.
+ /// </summary>
+ public virtual string CurrencyNativeName => _cultureData.CurrencyNativeName;
+
+ /// <summary>
+ /// Currency Symbol for this locale, ie: Fr. or $
+ /// </summary>
+ public virtual string CurrencySymbol => _cultureData.CurrencySymbol;
+
+ /// <summary>
+ /// ISO Currency Symbol for this locale, ie: CHF
+ /// </summary>
+ public virtual string ISOCurrencySymbol => _cultureData.ISOCurrencySymbol;
+
+ /// <summary>
+ /// Implements Object.Equals(). Returns a boolean indicating whether
+ /// or not object refers to the same RegionInfo as the current instance.
+ /// RegionInfos are considered equal if and only if they have the same name
+ /// (ie: en-US)
+ /// </summary>
public override bool Equals(object value)
{
- if (value is RegionInfo that)
- {
- return this.Name.Equals(that.Name);
- }
-
- return (false);
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetHashCode
- //
- // Implements Object.GetHashCode(). Returns the hash code for the
- // CultureInfo. The hash code is guaranteed to be the same for RegionInfo
- // A and B where A.Equals(B) is true.
- //
- ////////////////////////////////////////////////////////////////////////
- public override int GetHashCode()
- {
- return (this.Name.GetHashCode());
+ return value is RegionInfo otherRegion
+ && Name.Equals(otherRegion.Name);
}
+ public override int GetHashCode() => Name.GetHashCode();
- ////////////////////////////////////////////////////////////////////////
- //
- // ToString
- //
- // Implements Object.ToString(). Returns the name of the Region, ie: es-US
- //
- ////////////////////////////////////////////////////////////////////////
- public override string ToString()
- {
- return (Name);
- }
+ public override string ToString() => Name;
}
}
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/SortKey.cs b/src/System.Private.CoreLib/shared/System/Globalization/SortKey.cs
index f9c7f68f5e..b00f34b814 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/SortKey.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/SortKey.cs
@@ -2,37 +2,24 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-////////////////////////////////////////////////////////////////////////////
-//
-//
-// Purpose: This class implements a set of methods for retrieving
-// sort key information.
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
-using System;
-using System.Runtime.CompilerServices;
using System.Diagnostics;
namespace System.Globalization
{
+ /// <summary>
+ /// This class implements a set of methods for retrieving
+ /// </summary>
public partial class SortKey
{
- //--------------------------------------------------------------------//
- // Internal Information //
- //--------------------------------------------------------------------//
-
- internal string _localeName; // locale identifier
-
- internal CompareOptions _options; // options
- internal string _string; // original string
- internal byte[] _keyData; // sortkey data
-
- //
- // The following constructor is designed to be called from CompareInfo to get the
- // the sort key of specific string for synthetic culture
- //
+ private readonly string _localeName;
+ private readonly CompareOptions _options;
+ private readonly string _string;
+ private readonly byte[] _keyData;
+
+ /// <summary>
+ /// The following constructor is designed to be called from CompareInfo to get the
+ /// the sort key of specific string for synthetic culture
+ /// </summary>
internal SortKey(string localeName, string str, CompareOptions options, byte[] keyData)
{
_keyData = keyData;
@@ -41,52 +28,32 @@ namespace System.Globalization
_string = str;
}
- ////////////////////////////////////////////////////////////////////////
- //
- // GetOriginalString
- //
- // Returns the original string used to create the current instance
- // of SortKey.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual string OriginalString
+ /// <summary>
+ /// Returns the original string used to create the current instance
+ /// of SortKey.
+ /// </summary>
+ public virtual string OriginalString => _string;
+
+ /// <summary>
+ /// Returns a byte array representing the current instance of the
+ /// sort key.
+ /// </summary>
+ public virtual byte[] KeyData => (byte[])_keyData.Clone();
+
+ /// <summary>
+ /// Compares the two sort keys. Returns 0 if the two sort keys are
+ /// equal, a number less than 0 if sortkey1 is less than sortkey2,
+ /// and a number greater than 0 if sortkey1 is greater than sortkey2.
+ /// </summary>
+ public static int Compare(SortKey sortkey1, SortKey sortkey2)
{
- get
+ if (sortkey1 == null)
{
- return (_string);
+ throw new ArgumentNullException(nameof(sortkey1));
}
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // GetKeyData
- //
- // Returns a byte array representing the current instance of the
- // sort key.
- //
- ////////////////////////////////////////////////////////////////////////
- public virtual byte[] KeyData
- {
- get
+ if (sortkey2 == null)
{
- return (byte[])(_keyData.Clone());
- }
- }
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Compare
- //
- // Compares the two sort keys. Returns 0 if the two sort keys are
- // equal, a number less than 0 if sortkey1 is less than sortkey2,
- // and a number greater than 0 if sortkey1 is greater than sortkey2.
- //
- ////////////////////////////////////////////////////////////////////////
- public static int Compare(SortKey sortkey1, SortKey sortkey2)
- {
- if (sortkey1 == null || sortkey2 == null)
- {
- throw new ArgumentNullException((sortkey1 == null ? nameof(sortkey1) : nameof(sortkey2)));
+ throw new ArgumentNullException(nameof(sortkey2));
}
byte[] key1Data = sortkey1._keyData;
@@ -99,75 +66,45 @@ namespace System.Globalization
{
if (key2Data.Length == 0)
{
- return (0);
+ return 0;
}
- return (-1);
+
+ return -1;
}
if (key2Data.Length == 0)
{
- return (1);
+ return 1;
}
int compLen = (key1Data.Length < key2Data.Length) ? key1Data.Length : key2Data.Length;
-
for (int i = 0; i < compLen; i++)
{
if (key1Data[i] > key2Data[i])
{
- return (1);
+ return 1;
}
if (key1Data[i] < key2Data[i])
{
- return (-1);
+ return -1;
}
}
return 0;
}
- ////////////////////////////////////////////////////////////////////////
- //
- // Equals
- //
- // Implements Object.Equals(). Returns a boolean indicating whether
- // or not object refers to the same SortKey as the current instance.
- //
- ////////////////////////////////////////////////////////////////////////
public override bool Equals(object value)
{
- if (value is SortKey that)
- {
- return Compare(this, that) == 0;
- }
-
- return (false);
+ return value is SortKey otherSortKey && Compare(this, otherSortKey) == 0;
}
- ////////////////////////////////////////////////////////////////////////
- //
- // GetHashCode
- //
- // Implements Object.GetHashCode(). Returns the hash code for the
- // SortKey. The hash code is guaranteed to be the same for
- // SortKey A and B where A.Equals(B) is true.
- //
- ////////////////////////////////////////////////////////////////////////
public override int GetHashCode()
{
- return (CompareInfo.GetCompareInfo(_localeName).GetHashCodeOfString(_string, _options));
+ return CompareInfo.GetCompareInfo(_localeName).GetHashCodeOfString(_string, _options);
}
- ////////////////////////////////////////////////////////////////////////
- //
- // ToString
- //
- // Implements Object.ToString(). Returns a string describing the
- // SortKey.
- //
- ////////////////////////////////////////////////////////////////////////
public override string ToString()
{
- return ("SortKey - " + _localeName + ", " + _options + ", " + _string);
+ return "SortKey - " + _localeName + ", " + _options + ", " + _string;
}
}
}
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/SortVersion.cs b/src/System.Private.CoreLib/shared/System/Globalization/SortVersion.cs
index cb0d4c4fe1..ce86d56932 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/SortVersion.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/SortVersion.cs
@@ -13,21 +13,9 @@ namespace System.Globalization
private int m_NlsVersion; // Do not rename (binary serialization)
private Guid m_SortId; // Do not rename (binary serialization)
- public int FullVersion
- {
- get
- {
- return m_NlsVersion;
- }
- }
+ public int FullVersion => m_NlsVersion;
- public Guid SortId
- {
- get
- {
- return m_SortId;
- }
- }
+ public Guid SortId => m_SortId;
public SortVersion(int fullVersion, Guid sortId)
{
@@ -53,13 +41,7 @@ namespace System.Globalization
public override bool Equals(object obj)
{
- SortVersion n = obj as SortVersion;
- if (n != null)
- {
- return this.Equals(n);
- }
-
- return false;
+ return obj is SortVersion otherVersion && Equals(otherVersion);
}
public bool Equals(SortVersion other)
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/StringInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/StringInfo.cs
index 425e6f2379..2c9b4da5cc 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/StringInfo.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/StringInfo.cs
@@ -2,31 +2,25 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-////////////////////////////////////////////////////////////////////////////
-//
-//
-// Purpose: This class defines behaviors specific to a writing system.
-// A writing system is the collection of scripts and
-// orthographic rules required to represent a language as text.
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
-using System;
using System.Diagnostics;
namespace System.Globalization
{
+ /// <summary>
+ /// This class defines behaviors specific to a writing system.
+ /// A writing system is the collection of scripts and orthographic rules
+ /// required to represent a language as text.
+ /// </summary>
public class StringInfo
{
private string _str;
private int[] _indexes;
- // Legacy constructor
- public StringInfo() : this("") { }
+ public StringInfo() : this(string.Empty)
+ {
+ }
- // Primary, useful constructor
public StringInfo(string value)
{
this.String = value;
@@ -34,105 +28,76 @@ namespace System.Globalization
public override bool Equals(object value)
{
- if (value is StringInfo that)
- {
- return (_str.Equals(that._str));
- }
- return (false);
- }
-
- public override int GetHashCode()
- {
- return _str.GetHashCode();
+ return value is StringInfo otherStringInfo
+ && _str.Equals(otherStringInfo._str);
}
+ public override int GetHashCode() => _str.GetHashCode();
- // Our zero-based array of index values into the string. Initialize if
- // our private array is not yet, in fact, initialized.
+ /// <summary>
+ /// Our zero-based array of index values into the string. Initialize if
+ /// our private array is not yet, in fact, initialized.
+ /// </summary>
private int[] Indexes
{
get
{
- if ((null == _indexes) && (0 < this.String.Length))
+ if (_indexes == null && String.Length > 0)
{
- _indexes = StringInfo.ParseCombiningCharacters(this.String);
+ _indexes = StringInfo.ParseCombiningCharacters(String);
}
- return (_indexes);
+ return _indexes;
}
}
public string String
{
- get
- {
- return (_str);
- }
+ get => _str;
set
{
- if (null == value)
- {
- throw new ArgumentNullException(nameof(String),
- SR.ArgumentNull_String);
- }
-
- _str = value;
+ _str = value ?? throw new ArgumentNullException(nameof(value));
_indexes = null;
}
}
- public int LengthInTextElements
- {
- get
- {
- if (null == this.Indexes)
- {
- // Indexes not initialized, so assume length zero
- return (0);
- }
-
- return (this.Indexes.Length);
- }
- }
+ public int LengthInTextElements => Indexes?.Length ?? 0;
public string SubstringByTextElements(int startingTextElement)
{
// If the string is empty, no sense going further.
- if (null == this.Indexes)
+ if (Indexes == null)
{
- // Just decide which error to give depending on the param they gave us....
if (startingTextElement < 0)
{
- throw new ArgumentOutOfRangeException(nameof(startingTextElement), SR.ArgumentOutOfRange_NeedPosNum);
+ throw new ArgumentOutOfRangeException(nameof(startingTextElement), startingTextElement, SR.ArgumentOutOfRange_NeedPosNum);
}
else
{
- throw new ArgumentOutOfRangeException(nameof(startingTextElement), SR.Arg_ArgumentOutOfRangeException);
+ throw new ArgumentOutOfRangeException(nameof(startingTextElement), startingTextElement, SR.Arg_ArgumentOutOfRangeException);
}
}
- return (SubstringByTextElements(startingTextElement, Indexes.Length - startingTextElement));
+
+ return SubstringByTextElements(startingTextElement, Indexes.Length - startingTextElement);
}
public string SubstringByTextElements(int startingTextElement, int lengthInTextElements)
{
if (startingTextElement < 0)
{
- throw new ArgumentOutOfRangeException(nameof(startingTextElement), SR.ArgumentOutOfRange_NeedPosNum);
+ throw new ArgumentOutOfRangeException(nameof(startingTextElement), startingTextElement, SR.ArgumentOutOfRange_NeedPosNum);
}
-
- if (this.String.Length == 0 || startingTextElement >= Indexes.Length)
+ if (String.Length == 0 || startingTextElement >= Indexes.Length)
{
- throw new ArgumentOutOfRangeException(nameof(startingTextElement), SR.Arg_ArgumentOutOfRangeException);
+ throw new ArgumentOutOfRangeException(nameof(startingTextElement), startingTextElement, SR.Arg_ArgumentOutOfRangeException);
}
-
if (lengthInTextElements < 0)
{
- throw new ArgumentOutOfRangeException(nameof(lengthInTextElements), SR.ArgumentOutOfRange_NeedPosNum);
+ throw new ArgumentOutOfRangeException(nameof(lengthInTextElements), lengthInTextElements, SR.ArgumentOutOfRange_NeedPosNum);
}
-
if (startingTextElement > Indexes.Length - lengthInTextElements)
{
- throw new ArgumentOutOfRangeException(nameof(lengthInTextElements), SR.Arg_ArgumentOutOfRangeException);
+ throw new ArgumentOutOfRangeException(nameof(lengthInTextElements), lengthInTextElements, SR.Arg_ArgumentOutOfRangeException);
}
int start = Indexes[startingTextElement];
@@ -141,52 +106,35 @@ namespace System.Globalization
{
// We are at the last text element in the string and because of that
// must handle the call differently.
- return (this.String.Substring(start));
+ return String.Substring(start);
}
else
{
- return (this.String.Substring(start, (Indexes[lengthInTextElements + startingTextElement] - start)));
+ return String.Substring(start, Indexes[lengthInTextElements + startingTextElement] - start);
}
}
- public static string GetNextTextElement(string str)
- {
- return (GetNextTextElement(str, 0));
- }
-
-
- ////////////////////////////////////////////////////////////////////////
- //
- // Get the code point count of the current text element.
- //
- // A combining class is defined as:
- // A character/surrogate that has the following Unicode category:
- // * NonSpacingMark (e.g. U+0300 COMBINING GRAVE ACCENT)
- // * SpacingCombiningMark (e.g. U+ 0903 DEVANGARI SIGN VISARGA)
- // * EnclosingMark (e.g. U+20DD COMBINING ENCLOSING CIRCLE)
- //
- // In the context of GetNextTextElement() and ParseCombiningCharacters(), a text element is defined as:
- //
- // 1. If a character/surrogate is in the following category, it is a text element.
- // It can NOT further combine with characters in the combinging class to form a text element.
- // * one of the Unicode category in the combinging class
- // * UnicodeCategory.Format
- // * UnicodeCateogry.Control
- // * UnicodeCategory.OtherNotAssigned
- // 2. Otherwise, the character/surrogate can be combined with characters in the combinging class to form a text element.
- //
- // Return:
- // The length of the current text element
- //
- // Parameters:
- // String str
- // index The starting index
- // len The total length of str (to define the upper boundary)
- // ucCurrent The Unicode category pointed by Index. It will be updated to the uc of next character if this is not the last text element.
- // currentCharCount The char count of an abstract char pointed by Index. It will be updated to the char count of next abstract character if this is not the last text element.
- //
- ////////////////////////////////////////////////////////////////////////
-
+ public static string GetNextTextElement(string str) => GetNextTextElement(str, 0);
+
+ /// <summary>
+ /// Get the code point count of the current text element.
+ ///
+ /// A combining class is defined as:
+ /// A character/surrogate that has the following Unicode category:
+ /// * NonSpacingMark (e.g. U+0300 COMBINING GRAVE ACCENT)
+ /// * SpacingCombiningMark (e.g. U+ 0903 DEVANGARI SIGN VISARGA)
+ /// * EnclosingMark (e.g. U+20DD COMBINING ENCLOSING CIRCLE)
+ ///
+ /// In the context of GetNextTextElement() and ParseCombiningCharacters(), a text element is defined as:
+ /// 1. If a character/surrogate is in the following category, it is a text element.
+ /// It can NOT further combine with characters in the combinging class to form a text element.
+ /// * one of the Unicode category in the combinging class
+ /// * UnicodeCategory.Format
+ /// * UnicodeCateogry.Control
+ /// * UnicodeCategory.OtherNotAssigned
+ /// 2. Otherwise, the character/surrogate can be combined with characters in the combinging class to form a text element.
+ /// </summary>
+ /// <returns>The length of the current text element</returns>
internal static int GetCurrentTextElementLen(string str, int index, int len, ref UnicodeCategory ucCurrent, ref int currentCharCount)
{
Debug.Assert(index >= 0 && len >= 0, "StringInfo.GetCurrentTextElementLen() : index = " + index + ", len = " + len);
@@ -194,7 +142,7 @@ namespace System.Globalization
if (index + currentCharCount == len)
{
// This is the last character/surrogate in the string.
- return (currentCharCount);
+ return currentCharCount;
}
// Call an internal GetUnicodeCategory, which will tell us both the unicode category, and also tell us if it is a surrogate pair or not.
@@ -205,7 +153,6 @@ namespace System.Globalization
// The next element is a combining class.
// Check if the current text element to see if it is a valid base category (i.e. it should not be a combining category,
// not a format character, and not a control character).
-
if (CharUnicodeInfo.IsCombiningCategory(ucCurrent)
|| (ucCurrent == UnicodeCategory.Format)
|| (ucCurrent == UnicodeCategory.Control)
@@ -216,7 +163,8 @@ namespace System.Globalization
}
else
{
- int startIndex = index; // Remember the current index.
+ // Remember the current index.
+ int startIndex = index;
// We have a valid base characters, and we have a character (or surrogate) that is combining.
// Check if there are more combining characters to follow.
@@ -234,27 +182,28 @@ namespace System.Globalization
}
index += nextCharCount;
}
- return (index - startIndex);
+
+ return index - startIndex;
}
}
+
// The return value will be the currentCharCount.
int ret = currentCharCount;
ucCurrent = ucNext;
// Update currentCharCount.
currentCharCount = nextCharCount;
- return (ret);
+ return ret;
}
- // Returns the str containing the next text element in str starting at
- // index index. If index is not supplied, then it will start at the beginning
- // of str. It recognizes a base character plus one or more combining
- // characters or a properly formed surrogate pair as a text element. See also
- // the ParseCombiningCharacters() and the ParseSurrogates() methods.
+ /// <summary>
+ /// Returns the str containing the next text element in str starting at
+ /// index index. If index is not supplied, then it will start at the beginning
+ /// of str. It recognizes a base character plus one or more combining
+ /// characters or a properly formed surrogate pair as a text element.
+ /// See also the ParseCombiningCharacters() and the ParseSurrogates() methods.
+ /// </summary>
public static string GetNextTextElement(string str, int index)
{
- //
- // Validate parameters.
- //
if (str == null)
{
throw new ArgumentNullException(nameof(str));
@@ -265,52 +214,50 @@ namespace System.Globalization
{
if (index == len)
{
- return (string.Empty);
+ return string.Empty;
}
- throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
+
+ throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_Index);
}
int charLen;
UnicodeCategory uc = CharUnicodeInfo.InternalGetUnicodeCategory(str, index, out charLen);
- return (str.Substring(index, GetCurrentTextElementLen(str, index, len, ref uc, ref charLen)));
+ return str.Substring(index, GetCurrentTextElementLen(str, index, len, ref uc, ref charLen));
}
public static TextElementEnumerator GetTextElementEnumerator(string str)
{
- return (GetTextElementEnumerator(str, 0));
+ return GetTextElementEnumerator(str, 0);
}
public static TextElementEnumerator GetTextElementEnumerator(string str, int index)
{
- //
- // Validate parameters.
- //
if (str == null)
{
throw new ArgumentNullException(nameof(str));
}
int len = str.Length;
- if (index < 0 || (index > len))
+ if (index < 0 || index > len)
{
- throw new ArgumentOutOfRangeException(nameof(index), SR.ArgumentOutOfRange_Index);
+ throw new ArgumentOutOfRangeException(nameof(index), index, SR.ArgumentOutOfRange_Index);
}
- return (new TextElementEnumerator(str, index, len));
+ return new TextElementEnumerator(str, index, len);
}
- /*
- * Returns the indices of each base character or properly formed surrogate pair
- * within the str. It recognizes a base character plus one or more combining
- * characters or a properly formed surrogate pair as a text element and returns
- * the index of the base character or high surrogate. Each index is the
- * beginning of a text element within a str. The length of each element is
- * easily computed as the difference between successive indices. The length of
- * the array will always be less than or equal to the length of the str. For
- * example, given the str \u4f00\u302a\ud800\udc00\u4f01, this method would
- * return the indices: 0, 2, 4.
- */
-
+ /// <summary>
+ /// Returns the indices of each base character or properly formed surrogate
+ /// pair within the str. It recognizes a base character plus one or more
+ /// combining characters or a properly formed surrogate pair as a text
+ /// element and returns the index of the base character or high surrogate.
+ /// Each index is the beginning of a text element within a str. The length
+ /// of each element is easily computed as the difference between successive
+ /// indices. The length of the array will always be less than or equal to
+ /// the length of the str. For example, given the str
+ /// \u4f00\u302a\ud800\udc00\u4f01, this method would return the indices:
+ /// 0, 2, 4.
+ /// </summary>
public static int[] ParseCombiningCharacters(string str)
{
if (str == null)
@@ -343,7 +290,7 @@ namespace System.Globalization
Array.Copy(result, 0, returnArray, 0, resultCount);
return (returnArray);
}
- return (result);
+ return result;
}
}
}
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/TextElementEnumerator.cs b/src/System.Private.CoreLib/shared/System/Globalization/TextElementEnumerator.cs
index 7d8ff64a38..60d2a1055a 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/TextElementEnumerator.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/TextElementEnumerator.cs
@@ -2,36 +2,28 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-////////////////////////////////////////////////////////////////////////////
-//
-//
-// Purpose:
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
using System.Collections;
using System.Diagnostics;
namespace System.Globalization
{
- //
- // This is public because GetTextElement() is public.
- //
-
public class TextElementEnumerator : IEnumerator
{
- private string _str;
+ private readonly string _str;
private int _index;
- private int _startIndex;
+ private readonly int _startIndex;
- private int _strLen; // This is the length of the total string, counting from the beginning of string.
+ // This is the length of the total string, counting from the beginning of string.
+ private readonly int _strLen;
- private int _currTextElementLen; // The current text element lenght after MoveNext() is called.
+ // The current text element lenght after MoveNext() is called.
+ private int _currTextElementLen;
private UnicodeCategory _uc;
- private int _charLen; // The next abstract char to look at after MoveNext() is called. It could be 1 or 2, depending on if it is a surrogate or not.
+ // The next abstract char to look at after MoveNext() is called.
+ // It could be 1 or 2, depending on if it is a surrogate or not.
+ private int _charLen;
internal TextElementEnumerator(string str, int startIndex, int strLen)
{
@@ -50,28 +42,15 @@ namespace System.Globalization
{
// Make the _index to be greater than _strLen so that we can throw exception if GetTextElement() is called.
_index = _strLen + 1;
- return (false);
+ return false;
}
+
_currTextElementLen = StringInfo.GetCurrentTextElementLen(_str, _index, _strLen, ref _uc, ref _charLen);
_index += _currTextElementLen;
- return (true);
+ return true;
}
- //
- // Get the current text element.
- //
-
- public object Current
- {
- get
- {
- return (GetTextElement());
- }
- }
-
- //
- // Get the current text element.
- //
+ public object Current => GetTextElement();
public string GetTextElement()
{
@@ -84,13 +63,9 @@ namespace System.Globalization
throw new InvalidOperationException(SR.InvalidOperation_EnumEnded);
}
- return (_str.Substring(_index - _currTextElementLen, _currTextElementLen));
+ return _str.Substring(_index - _currTextElementLen, _currTextElementLen);
}
- //
- // Get the starting index of the current text element.
- //
-
public int ElementIndex
{
get
@@ -99,11 +74,11 @@ namespace System.Globalization
{
throw new InvalidOperationException(SR.InvalidOperation_EnumNotStarted);
}
- return (_index - _currTextElementLen);
+
+ return _index - _currTextElementLen;
}
}
-
public void Reset()
{
_index = _startIndex;
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.cs b/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.cs
index 77964fb642..12ce6d9696 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/TextInfo.cs
@@ -2,16 +2,6 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-////////////////////////////////////////////////////////////////////////////
-//
-//
-// Purpose: This Class defines behaviors specific to a writing system.
-// A writing system is the collection of scripts and
-// orthographic rules required to represent a language as text.
-//
-//
-////////////////////////////////////////////////////////////////////////////
-
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -29,6 +19,11 @@ using nint = System.Int32;
namespace System.Globalization
{
+ /// <summary>
+ /// This Class defines behaviors specific to a writing system.
+ /// A writing system is the collection of scripts and orthographic rules
+ /// required to represent a language as text.
+ /// </summary>
public partial class TextInfo : ICloneable, IDeserializationCallback
{
private enum Tristate : byte
@@ -41,44 +36,28 @@ namespace System.Globalization
private string _listSeparator;
private bool _isReadOnly = false;
- /* _cultureName is the name of the creating culture.
- _cultureData is the data that backs this class.
- _textInfoName is the actual name of the textInfo (from cultureData.STEXTINFO)
- In the desktop, when we call the sorting dll, it doesn't
- know how to resolve custom locle names to sort ids so we have to have already resolved this.
- */
+ private readonly string _cultureName;
+ private readonly CultureData _cultureData;
- private readonly string _cultureName; // Name of the culture that created this text info
- private readonly CultureData _cultureData; // Data record for the culture that made us, not for this textinfo
- private readonly string _textInfoName; // Name of the text info we're using (ie: _cultureData.STEXTINFO)
+ // // Name of the text info we're using (ie: _cultureData.TextInfoName)
+ private readonly string _textInfoName;
private Tristate _isAsciiCasingSameAsInvariant = Tristate.NotInitialized;
// Invariant text info
internal static TextInfo Invariant
{
- get
- {
- if (s_Invariant == null)
- s_Invariant = new TextInfo(CultureData.Invariant);
- return s_Invariant;
- }
+ get => s_invariant ?? (s_invariant = new TextInfo(CultureData.Invariant));
}
- internal volatile static TextInfo s_Invariant;
- //////////////////////////////////////////////////////////////////////////
- ////
- //// TextInfo Constructors
- ////
- //// Implements CultureInfo.TextInfo.
- ////
- //////////////////////////////////////////////////////////////////////////
+ private volatile static TextInfo s_invariant;
+
internal TextInfo(CultureData cultureData)
{
// This is our primary data source, we don't need most of the rest of this
_cultureData = cultureData;
_cultureName = _cultureData.CultureName;
- _textInfoName = _cultureData.STEXTINFO;
+ _textInfoName = _cultureData.TextInfoName;
FinishInitialization();
}
@@ -88,13 +67,13 @@ namespace System.Globalization
throw new PlatformNotSupportedException();
}
- public virtual int ANSICodePage => _cultureData.IDEFAULTANSICODEPAGE;
+ public virtual int ANSICodePage => _cultureData.ANSICodePage;
- public virtual int OEMCodePage => _cultureData.IDEFAULTOEMCODEPAGE;
+ public virtual int OEMCodePage => _cultureData.OEMCodePage;
- public virtual int MacCodePage => _cultureData.IDEFAULTMACCODEPAGE;
+ public virtual int MacCodePage => _cultureData.MacCodePage;
- public virtual int EBCDICCodePage => _cultureData.IDEFAULTEBCDICCODEPAGE;
+ public virtual int EBCDICCodePage => _cultureData.EBCDICCodePage;
// Just use the LCID from our text info name
public int LCID => CultureInfo.GetCultureInfo(_textInfoName).LCID;
@@ -103,13 +82,6 @@ namespace System.Globalization
public bool IsReadOnly => _isReadOnly;
- //////////////////////////////////////////////////////////////////////////
- ////
- //// Clone
- ////
- //// Is the implementation of ICloneable.
- ////
- //////////////////////////////////////////////////////////////////////////
public virtual object Clone()
{
object o = MemberwiseClone();
@@ -117,22 +89,24 @@ namespace System.Globalization
return o;
}
- ////////////////////////////////////////////////////////////////////////
- //
- // ReadOnly
- //
- // Create a cloned readonly instance or return the input one if it is
- // readonly.
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Create a cloned readonly instance or return the input one if it is
+ /// readonly.
+ /// </summary>
public static TextInfo ReadOnly(TextInfo textInfo)
{
- if (textInfo == null) { throw new ArgumentNullException(nameof(textInfo)); }
- if (textInfo.IsReadOnly) { return textInfo; }
+ if (textInfo == null)
+ {
+ throw new ArgumentNullException(nameof(textInfo));
+ }
+
+ if (textInfo.IsReadOnly)
+ {
+ return textInfo;
+ }
TextInfo clonedTextInfo = (TextInfo)(textInfo.MemberwiseClone());
clonedTextInfo.SetReadOnlyState(true);
-
return clonedTextInfo;
}
@@ -150,43 +124,28 @@ namespace System.Globalization
}
- ////////////////////////////////////////////////////////////////////////
- //
- // ListSeparator
- //
- // Returns the string used to separate items in a list.
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Returns the string used to separate items in a list.
+ /// </summary>
public virtual string ListSeparator
{
- get
- {
- if (_listSeparator == null)
- {
- _listSeparator = _cultureData.SLIST;
- }
- return _listSeparator;
- }
-
+ get => _listSeparator ?? (_listSeparator = _cultureData.ListSeparator);
set
{
if (value == null)
{
- throw new ArgumentNullException(nameof(value), SR.ArgumentNull_String);
+ throw new ArgumentNullException(nameof(value));
}
+
VerifyWritable();
_listSeparator = value;
}
}
- ////////////////////////////////////////////////////////////////////////
- //
- // ToLower
- //
- // Converts the character or string to lower case. Certain locales
- // have different casing semantics from the file systems in Win32.
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Converts the character or string to lower case. Certain locales
+ /// have different casing semantics from the file systems in Win32.
+ /// </summary>
public virtual char ToLower(char c)
{
if (GlobalizationMode.Invariant || (IsAscii(c) && IsAsciiCasingSameAsInvariant))
@@ -199,7 +158,10 @@ namespace System.Globalization
public virtual string ToLower(string str)
{
- if (str == null) { throw new ArgumentNullException(nameof(str)); }
+ if (str == null)
+ {
+ throw new ArgumentNullException(nameof(str));
+ }
if (GlobalizationMode.Invariant)
{
@@ -212,12 +174,12 @@ namespace System.Globalization
private unsafe char ChangeCase(char c, bool toUpper)
{
Debug.Assert(!GlobalizationMode.Invariant);
-
+
char dst = default;
ChangeCase(&c, 1, &dst, 1, toUpper);
return dst;
}
-
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void ChangeCaseToLower(ReadOnlySpan<char> source, Span<char> destination)
{
@@ -457,7 +419,7 @@ namespace System.Globalization
{
return string.Empty;
}
-
+
fixed (char* pSource = s)
{
int i = 0;
@@ -469,7 +431,7 @@ namespace System.Globalization
}
i++;
}
-
+
if (i >= s.Length)
{
return s;
@@ -482,7 +444,7 @@ namespace System.Globalization
{
pResult[j] = pSource[j];
}
-
+
pResult[i] = (char)(pSource[i] | 0x20);
i++;
@@ -513,7 +475,7 @@ namespace System.Globalization
{
return string.Empty;
}
-
+
fixed (char* pSource = s)
{
int i = 0;
@@ -525,7 +487,7 @@ namespace System.Globalization
}
i++;
}
-
+
if (i >= s.Length)
{
return s;
@@ -538,7 +500,7 @@ namespace System.Globalization
{
pResult[j] = pSource[j];
}
-
+
pResult[i] = (char)(pSource[i] & ~0x20);
i++;
@@ -572,27 +534,26 @@ namespace System.Globalization
return c;
}
- ////////////////////////////////////////////////////////////////////////
- //
- // ToUpper
- //
- // Converts the character or string to upper case. Certain locales
- // have different casing semantics from the file systems in Win32.
- //
- ////////////////////////////////////////////////////////////////////////
+ /// <summary>
+ /// Converts the character or string to upper case. Certain locales
+ /// have different casing semantics from the file systems in Win32.
+ /// </summary>
public virtual char ToUpper(char c)
{
if (GlobalizationMode.Invariant || (IsAscii(c) && IsAsciiCasingSameAsInvariant))
{
return ToUpperAsciiInvariant(c);
}
-
+
return ChangeCase(c, toUpper: true);
}
public virtual string ToUpper(string str)
{
- if (str == null) { throw new ArgumentNullException(nameof(str)); }
+ if (str == null)
+ {
+ throw new ArgumentNullException(nameof(str));
+ }
if (GlobalizationMode.Invariant)
{
@@ -611,10 +572,7 @@ namespace System.Globalization
return c;
}
- private static bool IsAscii(char c)
- {
- return c < 0x80;
- }
+ private static bool IsAscii(char c) => c < 0x80;
private bool IsAsciiCasingSameAsInvariant
{
@@ -627,7 +585,7 @@ namespace System.Globalization
}
Debug.Assert(_isAsciiCasingSameAsInvariant == Tristate.True || _isAsciiCasingSameAsInvariant == Tristate.False);
- return (_isAsciiCasingSameAsInvariant == Tristate.True);
+ return _isAsciiCasingSameAsInvariant == Tristate.True;
}
}
@@ -638,77 +596,44 @@ namespace System.Globalization
_isAsciiCasingSameAsInvariant = (compareResult) ? Tristate.True : Tristate.False;
}
- // IsRightToLeft
- //
- // Returns true if the dominant direction of text and UI such as the relative position of buttons and scroll bars
- //
+ /// <summary>
+ /// Returns true if the dominant direction of text and UI such as the
+ /// relative position of buttons and scroll bars
+ /// </summary>
public bool IsRightToLeft => _cultureData.IsRightToLeft;
- ////////////////////////////////////////////////////////////////////////
- //
- // Equals
- //
- // Implements Object.Equals(). Returns a boolean indicating whether
- // or not object refers to the same CultureInfo as the current instance.
- //
- ////////////////////////////////////////////////////////////////////////
public override bool Equals(object obj)
{
- if (obj is TextInfo that)
- {
- return CultureName.Equals(that.CultureName);
- }
-
- return false;
+ return obj is TextInfo otherTextInfo
+ && CultureName.Equals(otherTextInfo.CultureName);
}
- ////////////////////////////////////////////////////////////////////////
- //
- // GetHashCode
- //
- // Implements Object.GetHashCode(). Returns the hash code for the
- // CultureInfo. The hash code is guaranteed to be the same for CultureInfo A
- // and B where A.Equals(B) is true.
- //
- ////////////////////////////////////////////////////////////////////////
- public override int GetHashCode()
- {
- return CultureName.GetHashCode();
- }
+ public override int GetHashCode() => CultureName.GetHashCode();
- ////////////////////////////////////////////////////////////////////////
- //
- // ToString
- //
- // Implements Object.ToString(). Returns a string describing the
- // TextInfo.
- //
- ////////////////////////////////////////////////////////////////////////
public override string ToString()
{
return "TextInfo - " + _cultureData.CultureName;
}
- //
- // Titlecasing:
- // -----------
- // Titlecasing refers to a casing practice wherein the first letter of a word is an uppercase letter
- // and the rest of the letters are lowercase. The choice of which words to titlecase in headings
- // and titles is dependent on language and local conventions. For example, "The Merry Wives of Windor"
- // is the appropriate titlecasing of that play's name in English, with the word "of" not titlecased.
- // In German, however, the title is "Die lustigen Weiber von Windsor," and both "lustigen" and "von"
- // are not titlecased. In French even fewer words are titlecased: "Les joyeuses commeres de Windsor."
- //
- // Moreover, the determination of what actually constitutes a word is language dependent, and this can
- // influence which letter or letters of a "word" are uppercased when titlecasing strings. For example
- // "l'arbre" is considered two words in French, whereas "can't" is considered one word in English.
- //
+ /// <summary>
+ /// Titlecasing refers to a casing practice wherein the first letter of a word is an uppercase letter
+ /// and the rest of the letters are lowercase. The choice of which words to titlecase in headings
+ /// and titles is dependent on language and local conventions. For example, "The Merry Wives of Windor"
+ /// is the appropriate titlecasing of that play's name in English, with the word "of" not titlecased.
+ /// In German, however, the title is "Die lustigen Weiber von Windsor," and both "lustigen" and "von"
+ /// are not titlecased. In French even fewer words are titlecased: "Les joyeuses commeres de Windsor."
+ ///
+ /// Moreover, the determination of what actually constitutes a word is language dependent, and this can
+ /// influence which letter or letters of a "word" are uppercased when titlecasing strings. For example
+ /// "l'arbre" is considered two words in French, whereas "can't" is considered one word in English.
+ /// </summary>
public unsafe string ToTitleCase(string str)
{
if (str == null)
{
throw new ArgumentNullException(nameof(str));
}
+
if (str.Length == 0)
{
return str;
@@ -721,13 +646,11 @@ namespace System.Globalization
for (int i = 0; i < str.Length; i++)
{
- UnicodeCategory charType;
int charLen;
-
- charType = CharUnicodeInfo.InternalGetUnicodeCategory(str, i, out charLen);
+ UnicodeCategory charType = CharUnicodeInfo.InternalGetUnicodeCategory(str, i, out charLen);
if (char.CheckLetter(charType))
{
- // Special case to check for Dutch specific titlecasing with "IJ" characters
+ // Special case to check for Dutch specific titlecasing with "IJ" characters
// at the beginning of a word
if (isDutchCulture && i < str.Length - 1 && (str[i] == 'i' || str[i] == 'I') && (str[i+1] == 'j' || str[i+1] == 'J'))
{
@@ -740,17 +663,14 @@ namespace System.Globalization
i = AddTitlecaseLetter(ref result, ref str, i, charLen) + 1;
}
- //
// Convert the characters until the end of the this word
// to lowercase.
- //
int lowercaseStart = i;
- //
// Use hasLowerCase flag to prevent from lowercasing acronyms (like "URT", "USA", etc)
// This is in line with Word 2000 behavior of titlecasing.
- //
bool hasLowerCase = (charType == UnicodeCategory.LowercaseLetter);
+
// Use a loop to find all of the other letters following this letter.
while (i < str.Length)
{
@@ -867,7 +787,6 @@ namespace System.Globalization
{
switch (input[inputIndex])
{
- //
// For AppCompat, the Titlecase Case Mapping data from NDP 2.0 is used below.
case (char) 0x01C4: // DZ with Caron -> Dz with Caron
case (char) 0x01C5: // Dz with Caron -> Dz with Caron
@@ -897,12 +816,10 @@ namespace System.Globalization
return inputIndex;
}
- //
// Used in ToTitleCase():
// When we find a starting letter, the following array decides if a category should be
// considered as word seprator or not.
- //
- private const int c_wordSeparatorMask =
+ private const int c_wordSeparatorMask =
/* false */ (0 << 0) | // UppercaseLetter = 0,
/* false */ (0 << 1) | // LowercaseLetter = 1,
/* false */ (0 << 2) | // TitlecaseLetter = 2,
@@ -933,8 +850,8 @@ namespace System.Globalization
/* true */ (1 << 27) | // ModifierSymbol = 27,
/* true */ (1 << 28) | // OtherSymbol = 28,
/* false */ (0 << 29); // OtherNotAssigned = 29;
-
- private static bool IsWordSeparator(UnicodeCategory category)
+
+ private static bool IsWordSeparator(UnicodeCategory category)
{
return (c_wordSeparatorMask & (1 << (int) category)) != 0;
}
diff --git a/src/System.Private.CoreLib/shared/System/Globalization/UmAlQuraCalendar.cs b/src/System.Private.CoreLib/shared/System/Globalization/UmAlQuraCalendar.cs
index 25fa0e8b22..7b52e833e9 100644
--- a/src/System.Private.CoreLib/shared/System/Globalization/UmAlQuraCalendar.cs
+++ b/src/System.Private.CoreLib/shared/System/Globalization/UmAlQuraCalendar.cs
@@ -303,7 +303,7 @@ namespace System.Globalization
throw new ArgumentOutOfRangeException(
"time",
ticks,
- string.Format(
+ SR.Format(
CultureInfo.InvariantCulture,
SR.ArgumentOutOfRange_CalendarRange,
s_minDate,
diff --git a/src/System.Private.CoreLib/shared/System/IO/FileStream.Unix.cs b/src/System.Private.CoreLib/shared/System/IO/FileStream.Unix.cs
index 55f30b5569..6bbd037137 100644
--- a/src/System.Private.CoreLib/shared/System/IO/FileStream.Unix.cs
+++ b/src/System.Private.CoreLib/shared/System/IO/FileStream.Unix.cs
@@ -735,6 +735,11 @@ namespace System.IO
}, this, CancellationToken.None, TaskContinuationOptions.DenyChildAttach, TaskScheduler.Default));
}
+ public override Task CopyToAsync(Stream destination, int bufferSize, CancellationToken cancellationToken) =>
+ // Windows version overrides this method, so the Unix version does as well, but it doesn't
+ // currently have any special optimizations to be done and so just calls to the base.
+ base.CopyToAsync(destination, bufferSize, cancellationToken);
+
/// <summary>Sets the current position of this stream to the given value.</summary>
/// <param name="offset">The point relative to origin from which to begin seeking. </param>
/// <param name="origin">
diff --git a/src/System.Private.CoreLib/shared/System/Number.Formatting.cs b/src/System.Private.CoreLib/shared/System/Number.Formatting.cs
index aa6d69f21c..1ae5b65d24 100644
--- a/src/System.Private.CoreLib/shared/System/Number.Formatting.cs
+++ b/src/System.Private.CoreLib/shared/System/Number.Formatting.cs
@@ -1908,7 +1908,7 @@ namespace System
// The max is not bound since you can have formatting strings of the form "000,000..", and this
// should handle that case too.
- int[] groupDigits = info.numberGroupSizes;
+ int[] groupDigits = info._numberGroupSizes;
int groupSizeIndex = 0; // Index into the groupDigits array.
int groupTotalSizeCount = 0;
@@ -2116,7 +2116,7 @@ namespace System
switch (ch)
{
case '#':
- FormatFixed(ref sb, ref number, nMaxDigits, info, info.currencyGroupSizes, info.CurrencyDecimalSeparator, info.CurrencyGroupSeparator);
+ FormatFixed(ref sb, ref number, nMaxDigits, info, info._currencyGroupSizes, info.CurrencyDecimalSeparator, info.CurrencyGroupSeparator);
break;
case '-':
sb.Append(info.NegativeSign);
@@ -2244,7 +2244,7 @@ namespace System
switch (ch)
{
case '#':
- FormatFixed(ref sb, ref number, nMaxDigits, info, info.numberGroupSizes, info.NumberDecimalSeparator, info.NumberGroupSeparator);
+ FormatFixed(ref sb, ref number, nMaxDigits, info, info._numberGroupSizes, info.NumberDecimalSeparator, info.NumberGroupSeparator);
break;
case '-':
sb.Append(info.NegativeSign);
@@ -2351,7 +2351,7 @@ namespace System
switch (ch)
{
case '#':
- FormatFixed(ref sb, ref number, nMaxDigits, info, info.percentGroupSizes, info.PercentDecimalSeparator, info.PercentGroupSeparator);
+ FormatFixed(ref sb, ref number, nMaxDigits, info, info._percentGroupSizes, info.PercentDecimalSeparator, info.PercentGroupSeparator);
break;
case '-':
sb.Append(info.NegativeSign);
diff --git a/src/System.Private.CoreLib/shared/System/Number.NumberToFloatingPointBits.cs b/src/System.Private.CoreLib/shared/System/Number.NumberToFloatingPointBits.cs
index 5474a60c19..37609f1818 100644
--- a/src/System.Private.CoreLib/shared/System/Number.NumberToFloatingPointBits.cs
+++ b/src/System.Private.CoreLib/shared/System/Number.NumberToFloatingPointBits.cs
@@ -333,6 +333,9 @@ namespace System
{
Debug.Assert(number.GetDigitsPointer()[0] != '0');
+ Debug.Assert(number.Scale <= FloatingPointMaxExponent);
+ Debug.Assert(number.Scale >= FloatingPointMinExponent);
+
// The input is of the form 0.Mantissa x 10^Exponent, where 'Mantissa' are
// the decimal digits of the mantissa and 'Exponent' is the decimal exponent.
// We decompose the mantissa into two parts: an integer part and a fractional
diff --git a/src/System.Private.CoreLib/shared/System/Number.Parsing.cs b/src/System.Private.CoreLib/shared/System/Number.Parsing.cs
index 5a581711d4..37facda3bb 100644
--- a/src/System.Private.CoreLib/shared/System/Number.Parsing.cs
+++ b/src/System.Private.CoreLib/shared/System/Number.Parsing.cs
@@ -32,6 +32,15 @@ namespace System
private const int Int64Precision = 19;
private const int UInt64Precision = 20;
+ private const int DoubleMaxExponent = 309;
+ private const int DoubleMinExponent = -324;
+
+ private const int FloatingPointMaxExponent = DoubleMaxExponent;
+ private const int FloatingPointMinExponent = DoubleMinExponent;
+
+ private const int SingleMaxExponent = 39;
+ private const int SingleMinExponent = -45;
+
/// <summary>Map from an ASCII char to its hex value, e.g. arr['b'] == 11. 0xFF means it's not a hex digit.</summary>
internal static ReadOnlySpan<byte> CharToHexLookup => new byte[]
{
@@ -389,11 +398,11 @@ namespace System
{
char* temp = p;
ch = ++p < strEnd ? *p : '\0';
- if ((next = MatchChars(p, strEnd, info.positiveSign)) != null)
+ if ((next = MatchChars(p, strEnd, info._positiveSign)) != null)
{
ch = (p = next) < strEnd ? *p : '\0';
}
- else if ((next = MatchChars(p, strEnd, info.negativeSign)) != null)
+ else if ((next = MatchChars(p, strEnd, info._negativeSign)) != null)
{
ch = (p = next) < strEnd ? *p : '\0';
negExp = true;
@@ -1964,18 +1973,44 @@ namespace System
internal static double NumberToDouble(ref NumberBuffer number)
{
number.CheckConsistency();
+ double result;
+
+ if (number.Scale > DoubleMaxExponent)
+ {
+ result = double.PositiveInfinity;
+ }
+ else if (number.Scale < DoubleMinExponent)
+ {
+ result = 0;
+ }
+ else
+ {
+ ulong bits = NumberToFloatingPointBits(ref number, in FloatingPointInfo.Double);
+ result = BitConverter.Int64BitsToDouble((long)(bits));
+ }
- ulong bits = NumberToFloatingPointBits(ref number, in FloatingPointInfo.Double);
- double result = BitConverter.Int64BitsToDouble((long)(bits));
return number.IsNegative ? -result : result;
}
internal static float NumberToSingle(ref NumberBuffer number)
{
number.CheckConsistency();
+ float result;
+
+ if (number.Scale > SingleMaxExponent)
+ {
+ result = float.PositiveInfinity;
+ }
+ else if (number.Scale < SingleMinExponent)
+ {
+ result = 0;
+ }
+ else
+ {
+ uint bits = (uint)(NumberToFloatingPointBits(ref number, in FloatingPointInfo.Single));
+ result = BitConverter.Int32BitsToSingle((int)(bits));
+ }
- uint bits = (uint)(NumberToFloatingPointBits(ref number, in FloatingPointInfo.Single));
- float result = BitConverter.Int32BitsToSingle((int)(bits));
return number.IsNegative ? -result : result;
}
}
diff --git a/src/System.Private.CoreLib/shared/System/Resources/ManifestBasedResourceGroveler.cs b/src/System.Private.CoreLib/shared/System/Resources/ManifestBasedResourceGroveler.cs
index d7b37262fd..485417d52a 100644
--- a/src/System.Private.CoreLib/shared/System/Resources/ManifestBasedResourceGroveler.cs
+++ b/src/System.Private.CoreLib/shared/System/Resources/ManifestBasedResourceGroveler.cs
@@ -172,7 +172,7 @@ namespace System.Resources
return CultureInfo.InvariantCulture;
}
- throw new ArgumentException(SR.Format(SR.Arg_InvalidNeutralResourcesLanguage_Asm_Culture, a.ToString(), attr.CultureName), e);
+ throw new ArgumentException(SR.Format(SR.Arg_InvalidNeutralResourcesLanguage_Asm_Culture, a, attr.CultureName), e);
}
}
@@ -237,10 +237,23 @@ namespace System.Resources
}
else
{
- Type readerType = Type.GetType(readerTypeName, throwOnError: true);
- object[] args = new object[1];
- args[0] = store;
- IResourceReader reader = (IResourceReader)Activator.CreateInstance(readerType, args);
+ IResourceReader reader;
+
+ // Permit deserialization as long as the default ResourceReader is used
+ if (ResourceManager.IsDefaultType(readerTypeName, ResourceManager.ResReaderTypeName))
+ {
+ reader = new ResourceReader(
+ store,
+ new Dictionary<string, ResourceLocator>(FastResourceComparer.Default),
+ permitDeserialization: true);
+ }
+ else
+ {
+ Type readerType = Type.GetType(readerTypeName, throwOnError: true);
+ object[] args = new object[1];
+ args[0] = store;
+ reader = (IResourceReader)Activator.CreateInstance(readerType, args);
+ }
object[] resourceSetArgs = new object[1];
resourceSetArgs[0] = reader;
diff --git a/src/System.Private.CoreLib/shared/System/Resources/ResourceManager.cs b/src/System.Private.CoreLib/shared/System/Resources/ResourceManager.cs
index 7b0033c341..b770bd7c54 100644
--- a/src/System.Private.CoreLib/shared/System/Resources/ResourceManager.cs
+++ b/src/System.Private.CoreLib/shared/System/Resources/ResourceManager.cs
@@ -544,7 +544,7 @@ namespace System.Resources
if (!Version.TryParse(v, out Version version))
{
- throw new ArgumentException(SR.Format(SR.Arg_InvalidSatelliteContract_Asm_Ver, a.ToString(), v));
+ throw new ArgumentException(SR.Format(SR.Arg_InvalidSatelliteContract_Asm_Ver, a, v));
}
return version;
diff --git a/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeHelpers.cs b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeHelpers.cs
new file mode 100644
index 0000000000..fcb69eceec
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/System/Runtime/CompilerServices/RuntimeHelpers.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.
+
+using System.Runtime.Serialization;
+
+namespace System.Runtime.CompilerServices
+{
+ public static partial class RuntimeHelpers
+ {
+ public delegate void TryCode(object userData);
+
+ public delegate void CleanupCode(object userData, bool exceptionThrown);
+
+ /// <summary>
+ /// GetSubArray helper method for the compiler to slice an array using a range.
+ /// </summary>
+ public static T[] GetSubArray<T>(T[] array, Range range)
+ {
+ Type elementType = array.GetType().GetElementType();
+ Span<T> source = array.AsSpan(range);
+
+ if (elementType.IsValueType)
+ {
+ return source.ToArray();
+ }
+ else
+ {
+ T[] newArray = (T[])Array.CreateInstance(elementType, source.Length);
+ source.CopyTo(newArray);
+ return newArray;
+ }
+ }
+
+ public static object GetUninitializedObject(Type type)
+ {
+ if (type is null)
+ {
+ throw new ArgumentNullException(nameof(type), SR.ArgumentNull_Type);
+ }
+
+ if (!type.IsRuntimeImplemented())
+ {
+ throw new SerializationException(SR.Format(SR.Serialization_InvalidType, type.ToString()));
+ }
+
+ return GetUninitializedObjectInternal(type);
+ }
+
+ public static void PrepareContractedDelegate(Delegate d)
+ {
+ }
+
+ public static void ProbeForSufficientStack()
+ {
+ }
+
+ public static void PrepareConstrainedRegions()
+ {
+ }
+
+ public static void PrepareConstrainedRegionsNoOP()
+ {
+ }
+ }
+} \ No newline at end of file
diff --git a/src/System.Private.CoreLib/shared/System/Security/CryptographicException.cs b/src/System.Private.CoreLib/shared/System/Security/CryptographicException.cs
index 78ee290693..5f6cecb129 100644
--- a/src/System.Private.CoreLib/shared/System/Security/CryptographicException.cs
+++ b/src/System.Private.CoreLib/shared/System/Security/CryptographicException.cs
@@ -33,7 +33,7 @@ namespace System.Security.Cryptography
}
public CryptographicException(string format, string insert)
- : base(string.Format(CultureInfo.CurrentCulture, format, insert))
+ : base(string.Format(format, insert))
{
}
diff --git a/src/System.Private.CoreLib/shared/System/Security/SecurityElement.cs b/src/System.Private.CoreLib/shared/System/Security/SecurityElement.cs
index 9b0b37fca2..6c87684593 100644
--- a/src/System.Private.CoreLib/shared/System/Security/SecurityElement.cs
+++ b/src/System.Private.CoreLib/shared/System/Security/SecurityElement.cs
@@ -64,7 +64,7 @@ namespace System.Security
throw new ArgumentNullException(nameof(tag));
if (!IsValidTag(tag))
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, SR.Argument_InvalidElementTag, tag));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidElementTag, tag));
_tag = tag;
_text = null;
@@ -76,10 +76,10 @@ namespace System.Security
throw new ArgumentNullException(nameof(tag));
if (!IsValidTag(tag))
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, SR.Argument_InvalidElementTag, tag));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidElementTag, tag));
if (text != null && !IsValidText(text))
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, SR.Argument_InvalidElementText, text));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidElementText, text));
_tag = tag;
_text = text;
@@ -100,7 +100,7 @@ namespace System.Security
throw new ArgumentNullException(nameof(Tag));
if (!IsValidTag(value))
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, SR.Argument_InvalidElementTag, value));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidElementTag, value));
_tag = value;
}
@@ -147,10 +147,10 @@ namespace System.Security
string attrValue = (string)enumerator.Value;
if (!IsValidAttributeName(attrName))
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, SR.Argument_InvalidElementName, attrName));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidElementName, attrName));
if (!IsValidAttributeValue(attrValue))
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, SR.Argument_InvalidElementValue, attrValue));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidElementValue, attrValue));
list.Add(attrName);
list.Add(attrValue);
@@ -177,7 +177,7 @@ namespace System.Security
else
{
if (!IsValidText(value))
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, SR.Argument_InvalidElementTag, value));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidElementTag, value));
_text = value;
}
@@ -250,10 +250,10 @@ namespace System.Security
throw new ArgumentNullException(nameof(value));
if (!IsValidAttributeName(name))
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, SR.Argument_InvalidElementName, name));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidElementName, name));
if (!IsValidAttributeValue(value))
- throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, SR.Argument_InvalidElementValue, value));
+ throw new ArgumentException(SR.Format(SR.Argument_InvalidElementValue, value));
AddAttributeSafe(name, value);
}
diff --git a/src/System.Private.CoreLib/shared/System/String.cs b/src/System.Private.CoreLib/shared/System/String.cs
index 22f830a0e4..49afbc8c8c 100644
--- a/src/System.Private.CoreLib/shared/System/String.cs
+++ b/src/System.Private.CoreLib/shared/System/String.cs
@@ -480,7 +480,7 @@ namespace System
Debug.Assert(byteLength >= 0);
// Get our string length
- int stringLength = encoding.GetCharCount(bytes, byteLength, null);
+ int stringLength = encoding.GetCharCount(bytes, byteLength);
Debug.Assert(stringLength >= 0, "stringLength >= 0");
// They gave us an empty string if they needed one
@@ -491,7 +491,7 @@ namespace System
string s = FastAllocateString(stringLength);
fixed (char* pTempChars = &s._firstChar)
{
- int doubleCheck = encoding.GetChars(bytes, byteLength, pTempChars, stringLength, null);
+ int doubleCheck = encoding.GetChars(bytes, byteLength, pTempChars, stringLength);
Debug.Assert(stringLength == doubleCheck,
"Expected encoding.GetChars to return same length as encoding.GetCharCount");
}
diff --git a/src/System.Private.CoreLib/shared/System/Text/ASCIIEncoding.cs b/src/System.Private.CoreLib/shared/System/Text/ASCIIEncoding.cs
index 217d934677..8cf1f57ccb 100644
--- a/src/System.Private.CoreLib/shared/System/Text/ASCIIEncoding.cs
+++ b/src/System.Private.CoreLib/shared/System/Text/ASCIIEncoding.cs
@@ -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.
-using System;
+using System.Buffers;
using System.Diagnostics;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace System.Text
@@ -18,10 +19,30 @@ namespace System.Text
// Note: IsAlwaysNormalized remains false because 1/2 the code points are unassigned, so they'd
// use fallbacks, and we cannot guarantee that fallbacks are normalized.
- public class ASCIIEncoding : Encoding
+ public partial class ASCIIEncoding : Encoding
{
- // Allow for devirtualization (see https://github.com/dotnet/coreclr/pull/9230)
- internal sealed class ASCIIEncodingSealed : ASCIIEncoding { }
+ // This specialized sealed type has two benefits:
+ // 1) it allows for devirtualization (see https://github.com/dotnet/coreclr/pull/9230), and
+ // 2) it allows us to provide highly optimized implementations of certain routines because
+ // we can make assumptions about the fallback mechanisms in use (in particular, always
+ // replace with "?").
+ //
+ // (We don't take advantage of #2 yet, but we can do so in the future because the implementation
+ // of cloning below allows us to make assumptions about the behaviors of the sealed type.)
+ internal sealed class ASCIIEncodingSealed : ASCIIEncoding
+ {
+ public override object Clone()
+ {
+ // The base implementation of Encoding.Clone calls object.MemberwiseClone and marks the new object mutable.
+ // We don't want to do this because it violates the invariants we have set for the sealed type.
+ // Instead, we'll create a new instance of the base ASCIIEncoding type and mark it mutable.
+
+ return new ASCIIEncoding()
+ {
+ IsReadOnly = false
+ };
+ }
+ }
// Used by Encoding.ASCII for lazy initialization
// The initialization code will not be run until a static member of the class is referenced
@@ -58,22 +79,26 @@ namespace System.Text
public override unsafe int GetByteCount(char[] chars, int index, int count)
{
// Validate input parameters
- if (chars == null)
- throw new ArgumentNullException(nameof(chars), SR.ArgumentNull_Array);
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (chars is null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.chars, ExceptionResource.ArgumentNull_Array);
+ }
- if (chars.Length - index < count)
- throw new ArgumentOutOfRangeException(nameof(chars), SR.ArgumentOutOfRange_IndexCountBuffer);
+ if ((index | count) < 0)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException((index < 0) ? ExceptionArgument.index : ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ }
- // If no input, return 0, avoid fixed empty array problem
- if (count == 0)
- return 0;
+ if (chars.Length - index < count)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.chars, ExceptionResource.ArgumentOutOfRange_IndexCountBuffer);
+ }
- // Just call the pointer version
fixed (char* pChars = chars)
- return GetByteCount(pChars + index, count, null);
+ {
+ return GetByteCountCommon(pChars + index, count);
+ }
}
// All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
@@ -83,12 +108,17 @@ namespace System.Text
public override unsafe int GetByteCount(string chars)
{
- // Validate input
- if (chars==null)
- throw new ArgumentNullException(nameof(chars));
+ // Validate input parameters
+
+ if (chars is null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.chars);
+ }
fixed (char* pChars = chars)
- return GetByteCount(pChars, chars.Length, null);
+ {
+ return GetByteCountCommon(pChars, chars.Length);
+ }
}
// All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
@@ -99,22 +129,81 @@ namespace System.Text
public override unsafe int GetByteCount(char* chars, int count)
{
// Validate Parameters
+
if (chars == null)
- throw new ArgumentNullException(nameof(chars), SR.ArgumentNull_Array);
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.chars);
+ }
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ }
- // Call it with empty encoder
- return GetByteCount(chars, count, null);
+ return GetByteCountCommon(chars, count);
}
public override unsafe int GetByteCount(ReadOnlySpan<char> chars)
{
- fixed (char* charsPtr = &MemoryMarshal.GetNonNullPinnableReference(chars))
+ // It's ok for us to pass null pointers down to the workhorse below.
+
+ fixed (char* charsPtr = &MemoryMarshal.GetReference(chars))
+ {
+ return GetByteCountCommon(charsPtr, chars.Length);
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private unsafe int GetByteCountCommon(char* pChars, int charCount)
+ {
+ // Common helper method for all non-EncoderNLS entry points to GetByteCount.
+ // A modification of this method should be copied in to each of the supported encodings: ASCII, UTF8, UTF16, UTF32.
+
+ Debug.Assert(charCount >= 0, "Caller should't specify negative length buffer.");
+ Debug.Assert(pChars != null || charCount == 0, "Input pointer shouldn't be null if non-zero length specified.");
+
+ // First call into the fast path.
+
+ int totalByteCount = GetByteCountFast(pChars, charCount, EncoderFallback, out int charsConsumed);
+
+ if (charsConsumed != charCount)
+ {
+ // If there's still data remaining in the source buffer, go down the fallback path.
+ // We need to check for integer overflow since the fallback could change the required
+ // output count in unexpected ways.
+
+ totalByteCount += GetByteCountWithFallback(pChars, charCount, charsConsumed);
+ if (totalByteCount < 0)
+ {
+ ThrowConversionOverflow();
+ }
+ }
+
+ return totalByteCount;
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)] // called directly by GetByteCountCommon
+ private protected sealed override unsafe int GetByteCountFast(char* pChars, int charsLength, EncoderFallback fallback, out int charsConsumed)
+ {
+ // First: Can we short-circuit the entire calculation?
+ // If an EncoderReplacementFallback is in use, all non-ASCII chars
+ // (including surrogate halves) are replaced with the default string.
+ // If the default string consists of a single ASCII value, then we
+ // know there's a 1:1 char->byte transcoding in all cases.
+
+ int byteCount = charsLength;
+
+ if (!(fallback is EncoderReplacementFallback replacementFallback
+ && replacementFallback.MaxCharCount == 1
+ && replacementFallback.DefaultString[0] <= 0x7F))
{
- return GetByteCount(charsPtr, chars.Length, encoder: null);
+ // Unrecognized fallback mechanism - count chars manually.
+
+ byteCount = (int)ASCIIUtility.GetIndexOfFirstNonAsciiChar(pChars, (uint)charsLength);
}
+
+ charsConsumed = byteCount;
+ return byteCount;
}
// Parent method is safe.
@@ -125,22 +214,37 @@ namespace System.Text
public override unsafe int GetBytes(string chars, int charIndex, int charCount,
byte[] bytes, int byteIndex)
{
- if (chars == null || bytes == null)
- throw new ArgumentNullException((chars == null ? nameof(chars) : nameof(bytes)), SR.ArgumentNull_Array);
+ // Validate Parameters
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex < 0 ? nameof(charIndex) : nameof(charCount)), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (chars is null || bytes is null)
+ {
+ ThrowHelper.ThrowArgumentNullException(
+ argument: (chars is null) ? ExceptionArgument.chars : ExceptionArgument.bytes,
+ resource: ExceptionResource.ArgumentNull_Array);
+ }
- if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException(nameof(chars), SR.ArgumentOutOfRange_IndexCount);
+ if ((charIndex | charCount) < 0)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(
+ argument: (charIndex < 0) ? ExceptionArgument.charIndex : ExceptionArgument.charCount,
+ resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ }
- if (byteIndex < 0 || byteIndex > bytes.Length)
- throw new ArgumentOutOfRangeException(nameof(byteIndex), SR.ArgumentOutOfRange_Index);
+ if (chars.Length - charIndex < charCount)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.chars, ExceptionResource.ArgumentOutOfRange_IndexCount);
+ }
- int byteCount = bytes.Length - byteIndex;
+ if ((uint)byteIndex > bytes.Length)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.byteIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ }
- fixed (char* pChars = chars) fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
- return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
+ fixed (char* pChars = chars)
+ fixed (byte* pBytes = bytes)
+ {
+ return GetBytesCommon(pChars + charIndex, charCount, pBytes + byteIndex, bytes.Length - byteIndex);
+ }
}
// Encodes a range of characters in a character array into a range of bytes
@@ -161,28 +265,36 @@ namespace System.Text
byte[] bytes, int byteIndex)
{
// Validate parameters
- if (chars == null || bytes == null)
- throw new ArgumentNullException((chars == null ? nameof(chars) : nameof(bytes)), SR.ArgumentNull_Array);
-
- if (charIndex < 0 || charCount < 0)
- throw new ArgumentOutOfRangeException((charIndex < 0 ? nameof(charIndex) : nameof(charCount)), SR.ArgumentOutOfRange_NeedNonNegNum);
- if (chars.Length - charIndex < charCount)
- throw new ArgumentOutOfRangeException(nameof(chars), SR.ArgumentOutOfRange_IndexCountBuffer);
+ if (chars is null || bytes is null)
+ {
+ ThrowHelper.ThrowArgumentNullException(
+ argument: (chars is null) ? ExceptionArgument.chars : ExceptionArgument.bytes,
+ resource: ExceptionResource.ArgumentNull_Array);
+ }
- if (byteIndex < 0 || byteIndex > bytes.Length)
- throw new ArgumentOutOfRangeException(nameof(byteIndex), SR.ArgumentOutOfRange_Index);
+ if ((charIndex | charCount) < 0)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(
+ argument: (charIndex < 0) ? ExceptionArgument.charIndex : ExceptionArgument.charCount,
+ resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ }
- // If nothing to encode return 0
- if (charCount == 0)
- return 0;
+ if (chars.Length - charIndex < charCount)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.chars, ExceptionResource.ArgumentOutOfRange_IndexCount);
+ }
- // Just call pointer version
- int byteCount = bytes.Length - byteIndex;
+ if ((uint)byteIndex > bytes.Length)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.byteIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ }
- fixed (char* pChars = chars) fixed (byte* pBytes = &MemoryMarshal.GetReference((Span<byte>)bytes))
- // Remember that byteCount is # to decode, not size of array.
- return GetBytes(pChars + charIndex, charCount, pBytes + byteIndex, byteCount, null);
+ fixed (char* pChars = chars)
+ fixed (byte* pBytes = bytes)
+ {
+ return GetBytesCommon(pChars + charIndex, charCount, pBytes + byteIndex, bytes.Length - byteIndex);
+ }
}
// All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
@@ -193,21 +305,123 @@ namespace System.Text
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
{
// Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars), SR.ArgumentNull_Array);
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount < 0 ? nameof(charCount) : nameof(byteCount)), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (chars == null || bytes == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(
+ argument: (chars is null) ? ExceptionArgument.chars : ExceptionArgument.bytes,
+ resource: ExceptionResource.ArgumentNull_Array);
+ }
- return GetBytes(chars, charCount, bytes, byteCount, null);
+ if ((charCount | byteCount) < 0)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(
+ argument: (charCount < 0) ? ExceptionArgument.charCount : ExceptionArgument.byteCount,
+ resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ }
+
+ return GetBytesCommon(chars, charCount, bytes, byteCount);
}
public override unsafe int GetBytes(ReadOnlySpan<char> chars, Span<byte> bytes)
{
- fixed (char* charsPtr = &MemoryMarshal.GetNonNullPinnableReference(chars))
- fixed (byte* bytesPtr = &MemoryMarshal.GetNonNullPinnableReference(bytes))
+ // It's ok for us to operate on null / empty spans.
+
+ fixed (char* charsPtr = &MemoryMarshal.GetReference(chars))
+ fixed (byte* bytesPtr = &MemoryMarshal.GetReference(bytes))
{
- return GetBytes(charsPtr, chars.Length, bytesPtr, bytes.Length, encoder: null);
+ return GetBytesCommon(charsPtr, chars.Length, bytesPtr, bytes.Length);
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private unsafe int GetBytesCommon(char* pChars, int charCount, byte* pBytes, int byteCount)
+ {
+ // Common helper method for all non-EncoderNLS entry points to GetBytes.
+ // A modification of this method should be copied in to each of the supported encodings: ASCII, UTF8, UTF16, UTF32.
+
+ Debug.Assert(charCount >= 0, "Caller should't specify negative length buffer.");
+ Debug.Assert(pChars != null || charCount == 0, "Input pointer shouldn't be null if non-zero length specified.");
+ Debug.Assert(byteCount >= 0, "Caller should't specify negative length buffer.");
+ Debug.Assert(pBytes != null || byteCount == 0, "Input pointer shouldn't be null if non-zero length specified.");
+
+ // First call into the fast path.
+
+ int bytesWritten = GetBytesFast(pChars, charCount, pBytes, byteCount, out int charsConsumed);
+
+ if (charsConsumed == charCount)
+ {
+ // All elements converted - return immediately.
+
+ return bytesWritten;
+ }
+ else
+ {
+ // Simple narrowing conversion couldn't operate on entire buffer - invoke fallback.
+
+ return GetBytesWithFallback(pChars, charCount, pBytes, byteCount, charsConsumed, bytesWritten);
+ }
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)] // called directly by GetBytesCommon
+ private protected sealed override unsafe int GetBytesFast(char* pChars, int charsLength, byte* pBytes, int bytesLength, out int charsConsumed)
+ {
+ int bytesWritten = (int)ASCIIUtility.NarrowUtf16ToAscii(pChars, pBytes, (uint)Math.Min(charsLength, bytesLength));
+
+ charsConsumed = bytesWritten;
+ return bytesWritten;
+ }
+
+ private protected sealed override unsafe int GetBytesWithFallback(ReadOnlySpan<char> chars, int originalCharsLength, Span<byte> bytes, int originalBytesLength, EncoderNLS encoder)
+ {
+ // We special-case EncoderReplacementFallback if it's telling us to write a single ASCII char,
+ // since we believe this to be relatively common and we can handle it more efficiently than
+ // the base implementation.
+
+ if (((encoder is null) ? this.EncoderFallback : encoder.Fallback) is EncoderReplacementFallback replacementFallback
+ && replacementFallback.MaxCharCount == 1
+ && replacementFallback.DefaultString[0] <= 0x7F)
+ {
+ byte replacementByte = (byte)replacementFallback.DefaultString[0];
+
+ int numElementsToConvert = Math.Min(chars.Length, bytes.Length);
+ int idx = 0;
+
+ fixed (char* pChars = &MemoryMarshal.GetReference(chars))
+ fixed (byte* pBytes = &MemoryMarshal.GetReference(bytes))
+ {
+ // In a loop, replace the non-convertible data, then bulk-convert as much as we can.
+
+ while (idx < numElementsToConvert)
+ {
+ pBytes[idx++] = replacementByte;
+
+ if (idx < numElementsToConvert)
+ {
+ idx += (int)ASCIIUtility.NarrowUtf16ToAscii(&pChars[idx], &pBytes[idx], (uint)(numElementsToConvert - idx));
+ }
+
+ Debug.Assert(idx <= numElementsToConvert, "Somehow went beyond bounds of source or destination buffer?");
+ }
+ }
+
+ // Slice off how much we consumed / wrote.
+
+ chars = chars.Slice(numElementsToConvert);
+ bytes = bytes.Slice(numElementsToConvert);
+ }
+
+ // If we couldn't go through our fast fallback mechanism, or if we still have leftover
+ // data because we couldn't consume everything in the loop above, we need to go down the
+ // slow fallback path.
+
+ if (chars.IsEmpty)
+ {
+ return originalBytesLength - bytes.Length; // total number of bytes written
+ }
+ else
+ {
+ return base.GetBytesWithFallback(chars, originalCharsLength, bytes, originalBytesLength, encoder);
}
}
@@ -222,22 +436,26 @@ namespace System.Text
public override unsafe int GetCharCount(byte[] bytes, int index, int count)
{
// Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException(nameof(bytes), SR.ArgumentNull_Array);
- if (index < 0 || count < 0)
- throw new ArgumentOutOfRangeException((index < 0 ? nameof(index) : nameof(count)), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (bytes is null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.bytes, ExceptionResource.ArgumentNull_Array);
+ }
- if (bytes.Length - index < count)
- throw new ArgumentOutOfRangeException(nameof(bytes), SR.ArgumentOutOfRange_IndexCountBuffer);
+ if ((index | count) < 0)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException((index < 0) ? ExceptionArgument.index : ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ }
- // If no input just return 0, fixed doesn't like 0 length arrays
- if (count == 0)
- return 0;
+ if (bytes.Length - index < count)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.bytes, ExceptionResource.ArgumentOutOfRange_IndexCountBuffer);
+ }
- // Just call pointer version
fixed (byte* pBytes = bytes)
- return GetCharCount(pBytes + index, count, null);
+ {
+ return GetCharCountCommon(pBytes + index, count);
+ }
}
// All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
@@ -248,673 +466,367 @@ namespace System.Text
public override unsafe int GetCharCount(byte* bytes, int count)
{
// Validate Parameters
+
if (bytes == null)
- throw new ArgumentNullException(nameof(bytes), SR.ArgumentNull_Array);
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.bytes, ExceptionResource.ArgumentNull_Array);
+ }
if (count < 0)
- throw new ArgumentOutOfRangeException(nameof(count), SR.ArgumentOutOfRange_NeedNonNegNum);
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.count, ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ }
- return GetCharCount(bytes, count, null);
+ return GetCharCountCommon(bytes, count);
}
public override unsafe int GetCharCount(ReadOnlySpan<byte> bytes)
{
- fixed (byte* bytesPtr = &MemoryMarshal.GetNonNullPinnableReference(bytes))
+ // It's ok for us to pass null pointers down to the workhorse routine.
+
+ fixed (byte* bytesPtr = &MemoryMarshal.GetReference(bytes))
{
- return GetCharCount(bytesPtr, bytes.Length, decoder: null);
+ return GetCharCountCommon(bytesPtr, bytes.Length);
}
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // parent method is safe
-
- public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount,
- char[] chars, int charIndex)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private unsafe int GetCharCountCommon(byte* pBytes, int byteCount)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars), SR.ArgumentNull_Array);
+ // Common helper method for all non-DecoderNLS entry points to GetCharCount.
+ // A modification of this method should be copied in to each of the supported encodings: ASCII, UTF8, UTF16, UTF32.
- if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex < 0 ? nameof(byteIndex) : nameof(byteCount)), SR.ArgumentOutOfRange_NeedNonNegNum);
+ Debug.Assert(byteCount >= 0, "Caller should't specify negative length buffer.");
+ Debug.Assert(pBytes != null || byteCount == 0, "Input pointer shouldn't be null if non-zero length specified.");
- if ( bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException(nameof(bytes), SR.ArgumentOutOfRange_IndexCountBuffer);
+ // First call into the fast path.
- if (charIndex < 0 || charIndex > chars.Length)
- throw new ArgumentOutOfRangeException(nameof(charIndex), SR.ArgumentOutOfRange_Index);
+ int totalCharCount = GetCharCountFast(pBytes, byteCount, DecoderFallback, out int bytesConsumed);
- // If no input, return 0 & avoid fixed problem
- if (byteCount == 0)
- return 0;
+ if (bytesConsumed != byteCount)
+ {
+ // If there's still data remaining in the source buffer, go down the fallback path.
+ // We need to check for integer overflow since the fallback could change the required
+ // output count in unexpected ways.
- // Just call pointer version
- int charCount = chars.Length - charIndex;
+ totalCharCount += GetCharCountWithFallback(pBytes, byteCount, bytesConsumed);
+ if (totalCharCount < 0)
+ {
+ ThrowConversionOverflow();
+ }
+ }
- fixed (byte* pBytes = bytes) fixed (char* pChars = &MemoryMarshal.GetReference((Span<char>)chars))
- // Remember that charCount is # to decode, not size of array
- return GetChars(pBytes + byteIndex, byteCount, pChars + charIndex, charCount, null);
+ return totalCharCount;
}
- // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
- // So if you fix this, fix the others. Currently those include:
- // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
-
- [CLSCompliant(false)]
- public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)] // called directly by GetCharCountCommon
+ private protected sealed override unsafe int GetCharCountFast(byte* pBytes, int bytesLength, DecoderFallback fallback, out int bytesConsumed)
{
- // Validate Parameters
- if (bytes == null || chars == null)
- throw new ArgumentNullException(bytes == null ? nameof(bytes) : nameof(chars), SR.ArgumentNull_Array);
+ // First: Can we short-circuit the entire calculation?
+ // If a DecoderReplacementFallback is in use, all non-ASCII bytes are replaced with
+ // the default string. If the default string consists of a single BMP value, then we
+ // know there's a 1:1 byte->char transcoding in all cases.
- if (charCount < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((charCount < 0 ? nameof(charCount) : nameof(byteCount)), SR.ArgumentOutOfRange_NeedNonNegNum);
+ int charCount = bytesLength;
- return GetChars(bytes, byteCount, chars, charCount, null);
- }
-
- public override unsafe int GetChars(ReadOnlySpan<byte> bytes, Span<char> chars)
- {
- fixed (byte* bytesPtr = &MemoryMarshal.GetNonNullPinnableReference(bytes))
- fixed (char* charsPtr = &MemoryMarshal.GetNonNullPinnableReference(chars))
+ if (!(fallback is DecoderReplacementFallback replacementFallback) || replacementFallback.MaxCharCount != 1)
{
- return GetChars(bytesPtr, bytes.Length, charsPtr, chars.Length, decoder: null);
+ // Unrecognized fallback mechanism - count bytes manually.
+
+ charCount = (int)ASCIIUtility.GetIndexOfFirstNonAsciiByte(pBytes, (uint)bytesLength);
}
+
+ bytesConsumed = charCount;
+ return charCount;
}
- // Returns a string containing the decoded representation of a range of
- // bytes in a byte array.
- //
// All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
// So if you fix this, fix the others. Currently those include:
// EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
// parent method is safe
- public override unsafe string GetString(byte[] bytes, int byteIndex, int byteCount)
+ public override unsafe int GetChars(byte[] bytes, int byteIndex, int byteCount,
+ char[] chars, int charIndex)
{
// Validate Parameters
- if (bytes == null)
- throw new ArgumentNullException(nameof(bytes), SR.ArgumentNull_Array);
- if (byteIndex < 0 || byteCount < 0)
- throw new ArgumentOutOfRangeException((byteIndex < 0 ? nameof(byteIndex) : nameof(byteCount)), SR.ArgumentOutOfRange_NeedNonNegNum);
+ if (bytes is null || chars is null)
+ {
+ ThrowHelper.ThrowArgumentNullException(
+ argument: (bytes is null) ? ExceptionArgument.bytes : ExceptionArgument.chars,
+ resource: ExceptionResource.ArgumentNull_Array);
+ }
+ if ((byteIndex | byteCount) < 0)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(
+ argument: (byteIndex < 0) ? ExceptionArgument.byteIndex : ExceptionArgument.byteCount,
+ resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
+ }
if (bytes.Length - byteIndex < byteCount)
- throw new ArgumentOutOfRangeException(nameof(bytes), SR.ArgumentOutOfRange_IndexCountBuffer);
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.bytes, ExceptionResource.ArgumentOutOfRange_IndexCountBuffer);
+ }
- // Avoid problems with empty input buffer
- if (byteCount == 0) return string.Empty;
+ if ((uint)charIndex > (uint)chars.Length)
+ {
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.charIndex, ExceptionResource.ArgumentOutOfRange_Index);
+ }
fixed (byte* pBytes = bytes)
- return string.CreateStringFromEncoding(
- pBytes + byteIndex, byteCount, this);
+ fixed (char* pChars = chars)
+ {
+ return GetCharsCommon(pBytes + byteIndex, byteCount, pChars + charIndex, chars.Length - charIndex);
+ }
}
- //
- // End of standard methods copied from EncodingNLS.cs
- //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
- // GetByteCount
- // Note: We start by assuming that the output will be the same as count. Having
- // an encoder or fallback may change that assumption
- internal sealed override unsafe int GetByteCount(char* chars, int charCount, EncoderNLS encoder)
+ [CLSCompliant(false)]
+ public unsafe override int GetChars(byte* bytes, int byteCount, char* chars, int charCount)
{
- // Just need to ASSERT, this is called by something else internal that checked parameters already
- Debug.Assert(charCount >= 0, "[ASCIIEncoding.GetByteCount]count is negative");
- Debug.Assert(chars != null, "[ASCIIEncoding.GetByteCount]chars is null");
-
- // Assert because we shouldn't be able to have a null encoder.
- Debug.Assert(encoderFallback != null, "[ASCIIEncoding.GetByteCount]Attempting to use null fallback encoder");
-
- char charLeftOver = (char)0;
- EncoderReplacementFallback fallback = null;
-
- // Start by assuming default count, then +/- for fallback characters
- char* charEnd = chars + charCount;
-
- // For fallback we may need a fallback buffer, we know we aren't default fallback.
- EncoderFallbackBuffer fallbackBuffer = null;
- char* charsForFallback;
-
- if (encoder != null)
- {
- charLeftOver = encoder._charLeftOver;
- Debug.Assert(charLeftOver == 0 || char.IsHighSurrogate(charLeftOver),
- "[ASCIIEncoding.GetByteCount]leftover character should be high surrogate");
-
- fallback = encoder.Fallback as EncoderReplacementFallback;
-
- // We mustn't have left over fallback data when counting
- if (encoder.InternalHasFallbackBuffer)
- {
- // We always need the fallback buffer in get bytes so we can flush any remaining ones if necessary
- fallbackBuffer = encoder.FallbackBuffer;
- if (fallbackBuffer.Remaining > 0 && encoder._throwOnOverflow)
- throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(chars, charEnd, encoder, false);
- }
+ // Validate Parameters
- // Verify that we have no fallbackbuffer, for ASCII its always empty, so just assert
- Debug.Assert(!encoder._throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
- encoder.FallbackBuffer.Remaining == 0,
- "[ASCIICodePageEncoding.GetByteCount]Expected empty fallback buffer");
- }
- else
+ if (bytes is null || chars is null)
{
- fallback = this.EncoderFallback as EncoderReplacementFallback;
+ ThrowHelper.ThrowArgumentNullException(
+ argument: (bytes is null) ? ExceptionArgument.bytes : ExceptionArgument.chars,
+ resource: ExceptionResource.ArgumentNull_Array);
}
- // If we have an encoder AND we aren't using default fallback,
- // then we may have a complicated count.
- if (fallback != null && fallback.MaxCharCount == 1)
+ if ((byteCount | charCount) < 0)
{
- // Replacement fallback encodes surrogate pairs as two ?? (or two whatever), so return size is always
- // same as input size.
- // Note that no existing SBCS code pages map code points to supplimentary characters, so this is easy.
-
- // We could however have 1 extra byte if the last call had an encoder and a funky fallback and
- // if we don't use the funky fallback this time.
-
- // Do we have an extra char left over from last time?
- if (charLeftOver > 0)
- charCount++;
-
- return (charCount);
+ ThrowHelper.ThrowArgumentOutOfRangeException(
+ argument: (byteCount < 0) ? ExceptionArgument.byteCount : ExceptionArgument.charCount,
+ resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
- // Count is more complicated if you have a funky fallback
- // For fallback we may need a fallback buffer, we know we're not default fallback
- int byteCount = 0;
-
- // We may have a left over character from last time, try and process it.
- if (charLeftOver > 0)
- {
- Debug.Assert(char.IsHighSurrogate(charLeftOver), "[ASCIIEncoding.GetByteCount]leftover character should be high surrogate");
- Debug.Assert(encoder != null, "[ASCIIEncoding.GetByteCount]Expected encoder");
-
- // Since left over char was a surrogate, it'll have to be fallen back.
- // Get Fallback
- fallbackBuffer = encoder.FallbackBuffer;
- fallbackBuffer.InternalInitialize(chars, charEnd, encoder, false);
-
- // This will fallback a pair if *chars is a low surrogate
- charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
- fallbackBuffer.InternalFallback(charLeftOver, ref charsForFallback);
- chars = charsForFallback;
- }
+ return GetCharsCommon(bytes, byteCount, chars, charCount);
+ }
- // Now we may have fallback char[] already from the encoder
+ public override unsafe int GetChars(ReadOnlySpan<byte> bytes, Span<char> chars)
+ {
+ // It's ok for us to pass null pointers down to the workhorse below.
- // Go ahead and do it, including the fallback.
- char ch;
- while ((ch = (fallbackBuffer == null) ? '\0' : fallbackBuffer.InternalGetNextChar()) != 0 ||
- chars < charEnd)
+ fixed (byte* bytesPtr = &MemoryMarshal.GetReference(bytes))
+ fixed (char* charsPtr = &MemoryMarshal.GetReference(chars))
{
- // First unwind any fallback
- if (ch == 0)
- {
- // No fallback, just get next char
- ch = *chars;
- chars++;
- }
-
- // Check for fallback, this'll catch surrogate pairs too.
- // no chars >= 0x80 are allowed.
- if (ch > 0x7f)
- {
- if (fallbackBuffer == null)
- {
- // Initialize the buffer
- if (encoder == null)
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = encoder.FallbackBuffer;
- fallbackBuffer.InternalInitialize(charEnd - charCount, charEnd, encoder, false);
- }
-
- // Get Fallback
- charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
- fallbackBuffer.InternalFallback(ch, ref charsForFallback);
- chars = charsForFallback;
- continue;
- }
-
- // We'll use this one
- byteCount++;
+ return GetCharsCommon(bytesPtr, bytes.Length, charsPtr, chars.Length);
}
-
- Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
- "[ASCIIEncoding.GetByteCount]Expected Empty fallback buffer");
-
- return byteCount;
}
- internal sealed override unsafe int GetBytes(
- char* chars, int charCount, byte* bytes, int byteCount, EncoderNLS encoder)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private unsafe int GetCharsCommon(byte* pBytes, int byteCount, char* pChars, int charCount)
{
- // Just need to ASSERT, this is called by something else internal that checked parameters already
- Debug.Assert(bytes != null, "[ASCIIEncoding.GetBytes]bytes is null");
- Debug.Assert(byteCount >= 0, "[ASCIIEncoding.GetBytes]byteCount is negative");
- Debug.Assert(chars != null, "[ASCIIEncoding.GetBytes]chars is null");
- Debug.Assert(charCount >= 0, "[ASCIIEncoding.GetBytes]charCount is negative");
+ // Common helper method for all non-DecoderNLS entry points to GetChars.
+ // A modification of this method should be copied in to each of the supported encodings: ASCII, UTF8, UTF16, UTF32.
- // Assert because we shouldn't be able to have a null encoder.
- Debug.Assert(encoderFallback != null, "[ASCIIEncoding.GetBytes]Attempting to use null encoder fallback");
+ Debug.Assert(byteCount >= 0, "Caller should't specify negative length buffer.");
+ Debug.Assert(pBytes != null || byteCount == 0, "Input pointer shouldn't be null if non-zero length specified.");
+ Debug.Assert(charCount >= 0, "Caller should't specify negative length buffer.");
+ Debug.Assert(pChars != null || charCount == 0, "Input pointer shouldn't be null if non-zero length specified.");
- // Get any left over characters
- char charLeftOver = (char)0;
- EncoderReplacementFallback fallback = null;
+ // First call into the fast path.
- // For fallback we may need a fallback buffer, we know we aren't default fallback.
- EncoderFallbackBuffer fallbackBuffer = null;
- char* charsForFallback;
+ int charsWritten = GetCharsFast(pBytes, byteCount, pChars, charCount, out int bytesConsumed);
- // prepare our end
- char* charEnd = chars + charCount;
- byte* byteStart = bytes;
- char* charStart = chars;
-
- if (encoder != null)
+ if (bytesConsumed == byteCount)
{
- charLeftOver = encoder._charLeftOver;
- fallback = encoder.Fallback as EncoderReplacementFallback;
-
- // We mustn't have left over fallback data when counting
- if (encoder.InternalHasFallbackBuffer)
- {
- // We always need the fallback buffer in get bytes so we can flush any remaining ones if necessary
- fallbackBuffer = encoder.FallbackBuffer;
- if (fallbackBuffer.Remaining > 0 && encoder._throwOnOverflow)
- throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, this.EncodingName, encoder.Fallback.GetType()));
-
- // Set our internal fallback interesting things.
- fallbackBuffer.InternalInitialize(charStart, charEnd, encoder, true);
- }
+ // All elements converted - return immediately.
- Debug.Assert(charLeftOver == 0 || char.IsHighSurrogate(charLeftOver),
- "[ASCIIEncoding.GetBytes]leftover character should be high surrogate");
-
- // Verify that we have no fallbackbuffer, for ASCII its always empty, so just assert
- Debug.Assert(!encoder._throwOnOverflow || !encoder.InternalHasFallbackBuffer ||
- encoder.FallbackBuffer.Remaining == 0,
- "[ASCIICodePageEncoding.GetBytes]Expected empty fallback buffer");
+ return charsWritten;
}
else
{
- fallback = this.EncoderFallback as EncoderReplacementFallback;
+ // Simple narrowing conversion couldn't operate on entire buffer - invoke fallback.
+
+ return GetCharsWithFallback(pBytes, byteCount, pChars, charCount, bytesConsumed, charsWritten);
}
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)] // called directly by GetCharsCommon
+ private protected sealed override unsafe int GetCharsFast(byte* pBytes, int bytesLength, char* pChars, int charsLength, out int bytesConsumed)
+ {
+ int charsWritten = (int)ASCIIUtility.WidenAsciiToUtf16(pBytes, pChars, (uint)Math.Min(bytesLength, charsLength));
+
+ bytesConsumed = charsWritten;
+ return charsWritten;
+ }
- // See if we do the fast default or slightly slower fallback
- if (fallback != null && fallback.MaxCharCount == 1)
+ private protected sealed override unsafe int GetCharsWithFallback(ReadOnlySpan<byte> bytes, int originalBytesLength, Span<char> chars, int originalCharsLength, DecoderNLS decoder)
+ {
+ // We special-case DecoderReplacementFallback if it's telling us to write a single BMP char,
+ // since we believe this to be relatively common and we can handle it more efficiently than
+ // the base implementation.
+
+ if (((decoder is null) ? this.DecoderFallback: decoder.Fallback) is DecoderReplacementFallback replacementFallback
+ && replacementFallback.MaxCharCount == 1)
{
- // Fast version
- char cReplacement = fallback.DefaultString[0];
+ char replacementChar = replacementFallback.DefaultString[0];
+
+ int numElementsToConvert = Math.Min( bytes.Length, chars.Length);
+ int idx = 0;
- // Check for replacements in range, otherwise fall back to slow version.
- if (cReplacement <= (char)0x7f)
+ fixed (byte* pBytes = &MemoryMarshal.GetReference(bytes))
+ fixed (char* pChars = &MemoryMarshal.GetReference(chars))
{
- // We should have exactly as many output bytes as input bytes, unless there's a left
- // over character, in which case we may need one more.
- // If we had a left over character will have to add a ? (This happens if they had a funky
- // fallback last time, but not this time.) (We can't spit any out though
- // because with fallback encoder each surrogate is treated as a seperate code point)
- if (charLeftOver > 0)
- {
- // Have to have room
- // Throw even if doing no throw version because this is just 1 char,
- // so buffer will never be big enough
- if (byteCount == 0)
- ThrowBytesOverflow(encoder, true);
-
- // This'll make sure we still have more room and also make sure our return value is correct.
- *(bytes++) = (byte)cReplacement;
- byteCount--; // We used one of the ones we were counting.
- }
+ // In a loop, replace the non-convertible data, then bulk-convert as much as we can.
- // This keeps us from overrunning our output buffer
- if (byteCount < charCount)
+ while (idx < numElementsToConvert)
{
- // Throw or make buffer smaller?
- ThrowBytesOverflow(encoder, byteCount < 1);
+ pChars[idx++] = replacementChar;
- // Just use what we can
- charEnd = chars + byteCount;
- }
-
- // We just do a quick copy
- while (chars < charEnd)
- {
- char ch2 = *(chars++);
- if (ch2 >= 0x0080) *(bytes++) = (byte)cReplacement;
- else *(bytes++) = unchecked((byte)(ch2));
- }
+ if (idx < numElementsToConvert)
+ {
+ idx += (int)ASCIIUtility.WidenAsciiToUtf16(&pBytes[idx], &pChars[idx], (uint)(numElementsToConvert - idx));
+ }
- // Clear encoder
- if (encoder != null)
- {
- encoder._charLeftOver = (char)0;
- encoder._charsUsed = (int)(chars - charStart);
+ Debug.Assert(idx <= numElementsToConvert, "Somehow went beyond bounds of source or destination buffer?");
}
-
- return (int)(bytes - byteStart);
}
- }
-
- // Slower version, have to do real fallback.
- // prepare our end
- byte* byteEnd = bytes + byteCount;
+ // Slice off how much we consumed / wrote.
- // We may have a left over character from last time, try and process it.
- if (charLeftOver > 0)
- {
- // Initialize the buffer
- Debug.Assert(encoder != null,
- "[ASCIIEncoding.GetBytes]Expected non null encoder if we have surrogate left over");
- fallbackBuffer = encoder.FallbackBuffer;
- fallbackBuffer.InternalInitialize(chars, charEnd, encoder, true);
-
- // Since left over char was a surrogate, it'll have to be fallen back.
- // Get Fallback
- // This will fallback a pair if *chars is a low surrogate
- charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
- fallbackBuffer.InternalFallback(charLeftOver, ref charsForFallback);
- chars = charsForFallback;
+ bytes = bytes.Slice(numElementsToConvert);
+ chars = chars.Slice(numElementsToConvert);
}
- // Now we may have fallback char[] already from the encoder
+ // If we couldn't go through our fast fallback mechanism, or if we still have leftover
+ // data because we couldn't consume everything in the loop above, we need to go down the
+ // slow fallback path.
- // Go ahead and do it, including the fallback.
- char ch;
- while ((ch = (fallbackBuffer == null) ? '\0' : fallbackBuffer.InternalGetNextChar()) != 0 ||
- chars < charEnd)
+ if (bytes.IsEmpty)
{
- // First unwind any fallback
- if (ch == 0)
- {
- // No fallback, just get next char
- ch = *chars;
- chars++;
- }
-
- // Check for fallback, this'll catch surrogate pairs too.
- // All characters >= 0x80 must fall back.
- if (ch > 0x7f)
- {
- // Initialize the buffer
- if (fallbackBuffer == null)
- {
- if (encoder == null)
- fallbackBuffer = this.encoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = encoder.FallbackBuffer;
- fallbackBuffer.InternalInitialize(charEnd - charCount, charEnd, encoder, true);
- }
-
- // Get Fallback
- charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
- fallbackBuffer.InternalFallback(ch, ref charsForFallback);
- chars = charsForFallback;
-
- // Go ahead & continue (& do the fallback)
- continue;
- }
-
- // We'll use this one
- // Bounds check
- if (bytes >= byteEnd)
- {
- // didn't use this char, we'll throw or use buffer
- if (fallbackBuffer == null || fallbackBuffer.bFallingBack == false)
- {
- Debug.Assert(chars > charStart || bytes == byteStart,
- "[ASCIIEncoding.GetBytes]Expected chars to have advanced already.");
- chars--; // don't use last char
- }
- else
- fallbackBuffer.MovePrevious();
-
- // Are we throwing or using buffer?
- ThrowBytesOverflow(encoder, bytes == byteStart); // throw?
- break; // don't throw, stop
- }
-
- // Go ahead and add it
- *bytes = unchecked((byte)ch);
- bytes++;
+ return originalCharsLength - chars.Length; // total number of chars written
}
-
- // Need to do encoder stuff
- if (encoder != null)
+ else
{
- // Fallback stuck it in encoder if necessary, but we have to clear MustFlush cases
- if (fallbackBuffer != null && !fallbackBuffer.bUsedEncoder)
- // Clear it in case of MustFlush
- encoder._charLeftOver = (char)0;
-
- // Set our chars used count
- encoder._charsUsed = (int)(chars - charStart);
+ return base.GetCharsWithFallback(bytes, originalBytesLength, chars, originalCharsLength, decoder);
}
-
- Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0 ||
- (encoder != null && !encoder._throwOnOverflow),
- "[ASCIIEncoding.GetBytes]Expected Empty fallback buffer at end");
-
- return (int)(bytes - byteStart);
}
- // This is internal and called by something else,
- internal sealed override unsafe int GetCharCount(byte* bytes, int count, DecoderNLS decoder)
- {
- // Just assert, we're called internally so these should be safe, checked already
- Debug.Assert(bytes != null, "[ASCIIEncoding.GetCharCount]bytes is null");
- Debug.Assert(count >= 0, "[ASCIIEncoding.GetCharCount]byteCount is negative");
+ // Returns a string containing the decoded representation of a range of
+ // bytes in a byte array.
+ //
+ // All of our public Encodings that don't use EncodingNLS must have this (including EncodingNLS)
+ // So if you fix this, fix the others. Currently those include:
+ // EncodingNLS, UTF7Encoding, UTF8Encoding, UTF32Encoding, ASCIIEncoding, UnicodeEncoding
+ // parent method is safe
- // ASCII doesn't do best fit, so don't have to check for it, find out which decoder fallback we're using
- DecoderReplacementFallback fallback = null;
+ public override unsafe string GetString(byte[] bytes, int byteIndex, int byteCount)
+ {
+ // Validate Parameters
- if (decoder == null)
- fallback = this.DecoderFallback as DecoderReplacementFallback;
- else
+ if (bytes is null)
{
- fallback = decoder.Fallback as DecoderReplacementFallback;
- Debug.Assert(!decoder._throwOnOverflow || !decoder.InternalHasFallbackBuffer ||
- decoder.FallbackBuffer.Remaining == 0,
- "[ASCIICodePageEncoding.GetCharCount]Expected empty fallback buffer");
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.bytes, ExceptionResource.ArgumentNull_Array);
}
- if (fallback != null && fallback.MaxCharCount == 1)
+ if ((byteIndex | byteCount) < 0)
{
- // Just return length, SBCS stay the same length because they don't map to surrogate
- // pairs and we don't have a decoder fallback.
-
- return count;
+ ThrowHelper.ThrowArgumentOutOfRangeException(
+ argument: (byteIndex < 0) ? ExceptionArgument.byteIndex : ExceptionArgument.byteCount,
+ resource: ExceptionResource.ArgumentOutOfRange_NeedNonNegNum);
}
- // Only need decoder fallback buffer if not using default replacement fallback, no best fit for ASCII
- DecoderFallbackBuffer fallbackBuffer = null;
-
- // Have to do it the hard way.
- // Assume charCount will be == count
- int charCount = count;
- byte[] byteBuffer = new byte[1];
-
- // Do it our fast way
- byte* byteEnd = bytes + count;
-
- // Quick loop
- while (bytes < byteEnd)
+ if (bytes.Length - byteIndex < byteCount)
{
- // Faster if don't use *bytes++;
- byte b = *bytes;
- bytes++;
-
- // If unknown we have to do fallback count
- if (b >= 0x80)
- {
- if (fallbackBuffer == null)
- {
- if (decoder == null)
- fallbackBuffer = this.DecoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = decoder.FallbackBuffer;
- fallbackBuffer.InternalInitialize(byteEnd - count, null);
- }
-
- // Use fallback buffer
- byteBuffer[0] = b;
- charCount--; // Have to unreserve the one we already allocated for b
- charCount += fallbackBuffer.InternalFallback(byteBuffer, bytes);
- }
+ ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.bytes, ExceptionResource.ArgumentOutOfRange_IndexCountBuffer);
}
- // Fallback buffer must be empty
- Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
- "[ASCIIEncoding.GetCharCount]Expected Empty fallback buffer");
+ // Avoid problems with empty input buffer
+ if (byteCount == 0)
+ return string.Empty;
- // Converted sequence is same length as input
- return charCount;
+ fixed (byte* pBytes = bytes)
+ {
+ return string.CreateStringFromEncoding(pBytes + byteIndex, byteCount, this);
+ }
}
- internal sealed override unsafe int GetChars(
- byte* bytes, int byteCount, char* chars, int charCount, DecoderNLS decoder)
- {
- // Just need to ASSERT, this is called by something else internal that checked parameters already
- Debug.Assert(bytes != null, "[ASCIIEncoding.GetChars]bytes is null");
- Debug.Assert(byteCount >= 0, "[ASCIIEncoding.GetChars]byteCount is negative");
- Debug.Assert(chars != null, "[ASCIIEncoding.GetChars]chars is null");
- Debug.Assert(charCount >= 0, "[ASCIIEncoding.GetChars]charCount is negative");
-
- // Do it fast way if using ? replacement fallback
- byte* byteEnd = bytes + byteCount;
- byte* byteStart = bytes;
- char* charStart = chars;
+ //
+ // End of standard methods copied from EncodingNLS.cs
+ //
- // Note: ASCII doesn't do best fit, but we have to fallback if they use something > 0x7f
- // Only need decoder fallback buffer if not using ? fallback.
- // ASCII doesn't do best fit, so don't have to check for it, find out which decoder fallback we're using
- DecoderReplacementFallback fallback = null;
- char* charsForFallback;
+ //
+ // Beginning of methods used by shared fallback logic.
+ //
- if (decoder == null)
- fallback = this.DecoderFallback as DecoderReplacementFallback;
+ internal sealed override bool TryGetByteCount(Rune value, out int byteCount)
+ {
+ if (value.IsAscii)
+ {
+ byteCount = 1;
+ return true;
+ }
else
{
- fallback = decoder.Fallback as DecoderReplacementFallback;
- Debug.Assert(!decoder._throwOnOverflow || !decoder.InternalHasFallbackBuffer ||
- decoder.FallbackBuffer.Remaining == 0,
- "[ASCIICodePageEncoding.GetChars]Expected empty fallback buffer");
+ byteCount = default;
+ return false;
}
+ }
- if (fallback != null && fallback.MaxCharCount == 1)
+ internal sealed override OperationStatus EncodeRune(Rune value, Span<byte> bytes, out int bytesWritten)
+ {
+ if (value.IsAscii)
{
- // Try it the fast way
- char replacementChar = fallback.DefaultString[0];
-
- // Need byteCount chars, otherwise too small buffer
- if (charCount < byteCount)
+ if (!bytes.IsEmpty)
{
- // Need at least 1 output byte, throw if must throw
- ThrowCharsOverflow(decoder, charCount < 1);
-
- // Not throwing, use what we can
- byteEnd = bytes + charCount;
+ bytes[0] = (byte)value.Value;
+ bytesWritten = 1;
+ return OperationStatus.Done;
}
-
- // Quick loop, just do '?' replacement because we don't have fallbacks for decodings.
- while (bytes < byteEnd)
+ else
{
- byte b = *(bytes++);
- if (b >= 0x80)
- // This is an invalid byte in the ASCII encoding.
- *(chars++) = replacementChar;
- else
- *(chars++) = unchecked((char)b);
+ bytesWritten = 0;
+ return OperationStatus.DestinationTooSmall;
}
-
- // bytes & chars used are the same
- if (decoder != null)
- decoder._bytesUsed = (int)(bytes - byteStart);
- return (int)(chars - charStart);
}
-
- // Slower way's going to need a fallback buffer
- DecoderFallbackBuffer fallbackBuffer = null;
- byte[] byteBuffer = new byte[1];
- char* charEnd = chars + charCount;
-
- // Not quite so fast loop
- while (bytes < byteEnd)
+ else
{
- // Faster if don't use *bytes++;
- byte b = *(bytes);
- bytes++;
+ bytesWritten = 0;
+ return OperationStatus.InvalidData;
+ }
+ }
- if (b >= 0x80)
+ internal sealed override OperationStatus DecodeFirstRune(ReadOnlySpan<byte> bytes, out Rune value, out int bytesConsumed)
+ {
+ if (!bytes.IsEmpty)
+ {
+ byte b = bytes[0];
+ if (b <= 0x7F)
{
- // This is an invalid byte in the ASCII encoding.
- if (fallbackBuffer == null)
- {
- if (decoder == null)
- fallbackBuffer = this.DecoderFallback.CreateFallbackBuffer();
- else
- fallbackBuffer = decoder.FallbackBuffer;
- fallbackBuffer.InternalInitialize(byteEnd - byteCount, charEnd);
- }
-
- // Use fallback buffer
- byteBuffer[0] = b;
-
- // Note that chars won't get updated unless this succeeds
- charsForFallback = chars; // Avoid passing chars by reference to allow it to be enregistered
- bool fallbackResult = fallbackBuffer.InternalFallback(byteBuffer, bytes, ref charsForFallback);
- chars = charsForFallback;
+ // ASCII byte
- if (!fallbackResult)
- {
- // May or may not throw, but we didn't get this byte
- Debug.Assert(bytes > byteStart || chars == charStart,
- "[ASCIIEncoding.GetChars]Expected bytes to have advanced already (fallback case)");
- bytes--; // unused byte
- fallbackBuffer.InternalReset(); // Didn't fall this back
- ThrowCharsOverflow(decoder, chars == charStart); // throw?
- break; // don't throw, but stop loop
- }
+ value = new Rune(b);
+ bytesConsumed = 1;
+ return OperationStatus.Done;
}
else
{
- // Make sure we have buffer space
- if (chars >= charEnd)
- {
- Debug.Assert(bytes > byteStart || chars == charStart,
- "[ASCIIEncoding.GetChars]Expected bytes to have advanced already (normal case)");
- bytes--; // unused byte
- ThrowCharsOverflow(decoder, chars == charStart); // throw?
- break; // don't throw, but stop loop
- }
+ // Non-ASCII byte
- *(chars) = unchecked((char)b);
- chars++;
+ value = Rune.ReplacementChar;
+ bytesConsumed = 1;
+ return OperationStatus.InvalidData;
}
}
+ else
+ {
+ // No data to decode
- // Might have had decoder fallback stuff.
- if (decoder != null)
- decoder._bytesUsed = (int)(bytes - byteStart);
-
- // Expect Empty fallback buffer for GetChars
- Debug.Assert(fallbackBuffer == null || fallbackBuffer.Remaining == 0,
- "[ASCIIEncoding.GetChars]Expected Empty fallback buffer");
-
- return (int)(chars - charStart);
+ value = Rune.ReplacementChar;
+ bytesConsumed = 0;
+ return OperationStatus.NeedMoreData;
+ }
}
+ //
+ // End of methods used by shared fallback logic.
+ //
public override int GetMaxByteCount(int charCount)
{
diff --git a/src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs b/src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs
new file mode 100644
index 0000000000..5bc80c35f5
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/System/Text/ASCIIUtility.cs
@@ -0,0 +1,76 @@
+// 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;
+
+namespace System.Text
+{
+ /*
+ * Contains naive unoptimized (non-SIMD) implementations of ASCII transcoding
+ * operations. Vectorized methods can be substituted here as a drop-in replacement.
+ */
+
+ internal unsafe static class ASCIIUtility
+ {
+ [MethodImpl(MethodImplOptions.NoInlining)] // the actual implementation won't be inlined, so this shouldn't be either, lest it throw off benchmarks
+ public static uint GetIndexOfFirstNonAsciiByte(byte* pBytes, uint byteCount)
+ {
+ uint idx = 0;
+ for (; idx < byteCount; idx++)
+ {
+ if ((sbyte)pBytes[idx] < 0)
+ {
+ break;
+ }
+ }
+ return idx;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)] // the actual implementation won't be inlined, so this shouldn't be either, lest it throw off benchmarks
+ public static uint GetIndexOfFirstNonAsciiChar(char* pChars, uint charCount)
+ {
+ uint idx = 0;
+ for (; idx < charCount; idx++)
+ {
+ if (pChars[idx] > 0x7Fu)
+ {
+ break;
+ }
+ }
+ return idx;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)] // the actual implementation won't be inlined, so this shouldn't be either, lest it throw off benchmarks
+ public static uint NarrowUtf16ToAscii(char* pChars, byte* pBytes, uint elementCount)
+ {
+ uint idx = 0;
+ for (; idx < elementCount; idx++)
+ {
+ uint ch = pChars[idx];
+ if (ch > 0x7Fu)
+ {
+ break;
+ }
+ pBytes[idx] = (byte)ch;
+ }
+ return idx;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)] // the actual implementation won't be inlined, so this shouldn't be either, lest it throw off benchmarks
+ public static uint WidenAsciiToUtf16(byte* pBytes, char* pChars, uint elementCount)
+ {
+ uint idx = 0;
+ for (; idx < elementCount; idx++)
+ {
+ byte b = pBytes[idx];
+ if (b > 0x7F)
+ {
+ break;
+ }
+ pChars[idx] = (char)b;
+ }
+ return idx;
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/shared/System/Text/DecoderFallback.cs b/src/System.Private.CoreLib/shared/System/Text/DecoderFallback.cs
index fff8ad1d7b..2eb03d8089 100644
--- a/src/System.Private.CoreLib/shared/System/Text/DecoderFallback.cs
+++ b/src/System.Private.CoreLib/shared/System/Text/DecoderFallback.cs
@@ -67,6 +67,10 @@ namespace System.Text
internal unsafe byte* byteStart;
internal unsafe char* charEnd;
+ internal Encoding _encoding;
+ internal DecoderNLS _decoder;
+ private int _originalByteCount;
+
// Internal Reset
internal unsafe void InternalReset()
{
@@ -82,6 +86,22 @@ namespace System.Text
this.charEnd = charEnd;
}
+ internal static DecoderFallbackBuffer CreateAndInitialize(Encoding encoding, DecoderNLS decoder, int originalByteCount)
+ {
+ // The original byte count is only used for keeping track of what 'index' value needs
+ // to be passed to the abstract Fallback method. The index value is calculated by subtracting
+ // 'bytes.Length' (where bytes is expected to be the entire remaining input buffer)
+ // from the 'originalByteCount' value specified here.
+
+ DecoderFallbackBuffer fallbackBuffer = (decoder is null) ? encoding.DecoderFallback.CreateFallbackBuffer() : decoder.FallbackBuffer;
+
+ fallbackBuffer._encoding = encoding;
+ fallbackBuffer._decoder = decoder;
+ fallbackBuffer._originalByteCount = originalByteCount;
+
+ return fallbackBuffer;
+ }
+
// Fallback the current byte by sticking it into the remaining char buffer.
// This can only be called by our encodings (other have to use the public fallback methods), so
// we can use our DecoderNLS here too (except we don't).
@@ -191,6 +211,90 @@ namespace System.Text
return 0;
}
+ internal int InternalFallbackGetCharCount(ReadOnlySpan<byte> remainingBytes, int fallbackLength)
+ {
+ return (Fallback(remainingBytes.Slice(0, fallbackLength).ToArray(), index: _originalByteCount - remainingBytes.Length))
+ ? DrainRemainingDataForGetCharCount()
+ : 0;
+ }
+
+ internal bool TryInternalFallbackGetChars(ReadOnlySpan<byte> remainingBytes, int fallbackLength, Span<char> chars, out int charsWritten)
+ {
+ if (Fallback(remainingBytes.Slice(0, fallbackLength).ToArray(), index: _originalByteCount - remainingBytes.Length))
+ {
+ return TryDrainRemainingDataForGetChars(chars, out charsWritten);
+ }
+ else
+ {
+ // Return true because we weren't asked to write anything, so this is a "success" in the sense that
+ // the output buffer was large enough to hold the desired 0 chars of output.
+
+ charsWritten = 0;
+ return true;
+ }
+ }
+
+ private Rune GetNextRune()
+ {
+ // Call GetNextChar() and try treating it as a non-surrogate character.
+ // If that fails, call GetNextChar() again and attempt to treat the two chars
+ // as a surrogate pair. If that still fails, throw an exception since the fallback
+ // mechanism is giving us a bad replacement character.
+
+ Rune rune;
+ char ch = GetNextChar();
+ if (!Rune.TryCreate(ch, out rune) && !Rune.TryCreate(ch, GetNextChar(), out rune))
+ {
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex);
+ }
+
+ return rune;
+ }
+
+ internal int DrainRemainingDataForGetCharCount()
+ {
+ int totalCharCount = 0;
+
+ Rune thisRune;
+ while ((thisRune = GetNextRune()).Value != 0)
+ {
+ // We need to check for overflow while tallying the fallback char count.
+
+ totalCharCount += thisRune.Utf16SequenceLength;
+ if (totalCharCount < 0)
+ {
+ InternalReset();
+ Encoding.ThrowConversionOverflow();
+ }
+ }
+
+ return totalCharCount;
+ }
+
+ internal bool TryDrainRemainingDataForGetChars(Span<char> chars, out int charsWritten)
+ {
+ int originalCharCount = chars.Length;
+
+ Rune thisRune;
+ while ((thisRune = GetNextRune()).Value != 0)
+ {
+ if (thisRune.TryEncode(chars, out int charsWrittenJustNow))
+ {
+ chars = chars.Slice(charsWrittenJustNow);
+ continue;
+ }
+ else
+ {
+ InternalReset();
+ charsWritten = default;
+ return false;
+ }
+ }
+
+ charsWritten = originalCharCount - chars.Length;
+ return true;
+ }
+
// private helper methods
internal void ThrowLastBytesRecursive(byte[] bytesUnknown)
{
diff --git a/src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs b/src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs
index 8af4dc3a55..597d362bf7 100644
--- a/src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs
+++ b/src/System.Private.CoreLib/shared/System/Text/DecoderNLS.cs
@@ -2,9 +2,8 @@
// 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.Serialization;
-using System.Text;
-using System;
+using System.Buffers;
+using System.Diagnostics;
using System.Runtime.InteropServices;
namespace System.Text
@@ -27,6 +26,8 @@ namespace System.Text
private bool _mustFlush;
internal bool _throwOnOverflow;
internal int _bytesUsed;
+ private int _leftoverBytes; // leftover data from a previous invocation of GetChars (up to 4 bytes)
+ private int _leftoverByteCount; // number of bytes of actual data in _leftoverBytes
internal DecoderNLS(Encoding encoding)
{
@@ -44,6 +45,7 @@ namespace System.Text
public override void Reset()
{
+ ClearLeftoverData();
_fallbackBuffer?.Reset();
}
@@ -238,5 +240,195 @@ namespace System.Text
{
_mustFlush = false;
}
+
+ internal ReadOnlySpan<byte> GetLeftoverData()
+ {
+ return MemoryMarshal.AsBytes(new ReadOnlySpan<int>(ref _leftoverBytes, 1)).Slice(0, _leftoverByteCount);
+ }
+
+ internal void SetLeftoverData(ReadOnlySpan<byte> bytes)
+ {
+ bytes.CopyTo(MemoryMarshal.AsBytes(new Span<int>(ref _leftoverBytes, 1)));
+ _leftoverByteCount = bytes.Length;
+ }
+
+ internal bool HasLeftoverData => _leftoverByteCount != 0;
+
+ internal void ClearLeftoverData()
+ {
+ _leftoverByteCount = 0;
+ }
+
+ internal int DrainLeftoverDataForGetCharCount(ReadOnlySpan<byte> bytes, out int bytesConsumed)
+ {
+ // Quick check: we _should not_ have leftover fallback data from a previous invocation,
+ // as we'd end up consuming any such data and would corrupt whatever Convert call happens
+ // to be in progress. Unlike EncoderNLS, this is simply a Debug.Assert. No exception is thrown.
+
+ Debug.Assert(_fallbackBuffer is null || _fallbackBuffer.Remaining == 0, "Should have no data remaining in the fallback buffer.");
+
+ // Copy the existing leftover data plus as many bytes as possible of the new incoming data
+ // into a temporary concated buffer, then get its char count by decoding it.
+
+ Span<byte> combinedBuffer = stackalloc byte[4];
+ combinedBuffer = combinedBuffer.Slice(0, ConcatInto(GetLeftoverData(), bytes, combinedBuffer));
+ int charCount = 0;
+
+ switch (_encoding.DecodeFirstRune(combinedBuffer, out Rune value, out int combinedBufferBytesConsumed))
+ {
+ case OperationStatus.Done:
+ charCount = value.Utf16SequenceLength;
+ goto Finish; // successfully transcoded bytes -> chars
+
+ case OperationStatus.NeedMoreData:
+ if (MustFlush)
+ {
+ goto case OperationStatus.InvalidData; // treat as equivalent to bad data
+ }
+ else
+ {
+ goto Finish; // consumed some bytes, output 0 chars
+ }
+
+ case OperationStatus.InvalidData:
+ break;
+
+ default:
+ Debug.Fail("Unexpected OperationStatus return value.");
+ break;
+ }
+
+ // Couldn't decode the buffer. Fallback the buffer instead.
+
+ if (FallbackBuffer.Fallback(combinedBuffer.Slice(0, combinedBufferBytesConsumed).ToArray(), index: 0))
+ {
+ charCount = _fallbackBuffer.DrainRemainingDataForGetCharCount();
+ Debug.Assert(charCount >= 0, "Fallback buffer shouldn't have returned a negative char count.");
+ }
+
+ Finish:
+
+ bytesConsumed = combinedBufferBytesConsumed - _leftoverByteCount; // amount of 'bytes' buffer consumed just now
+ return charCount;
+ }
+
+ internal int DrainLeftoverDataForGetChars(ReadOnlySpan<byte> bytes, Span<char> chars, out int bytesConsumed)
+ {
+ // Quick check: we _should not_ have leftover fallback data from a previous invocation,
+ // as we'd end up consuming any such data and would corrupt whatever Convert call happens
+ // to be in progress. Unlike EncoderNLS, this is simply a Debug.Assert. No exception is thrown.
+
+ Debug.Assert(_fallbackBuffer is null || _fallbackBuffer.Remaining == 0, "Should have no data remaining in the fallback buffer.");
+
+ // Copy the existing leftover data plus as many bytes as possible of the new incoming data
+ // into a temporary concated buffer, then transcode it from bytes to chars.
+
+ Span<byte> combinedBuffer = stackalloc byte[4];
+ combinedBuffer = combinedBuffer.Slice(0, ConcatInto(GetLeftoverData(), bytes, combinedBuffer));
+ int charsWritten = 0;
+
+ bool persistNewCombinedBuffer = false;
+
+ switch (_encoding.DecodeFirstRune(combinedBuffer, out Rune value, out int combinedBufferBytesConsumed))
+ {
+ case OperationStatus.Done:
+ if (value.TryEncode(chars, out charsWritten))
+ {
+ goto Finish; // successfully transcoded bytes -> chars
+ }
+ else
+ {
+ goto DestinationTooSmall;
+ }
+
+ case OperationStatus.NeedMoreData:
+ if (MustFlush)
+ {
+ goto case OperationStatus.InvalidData; // treat as equivalent to bad data
+ }
+ else
+ {
+ persistNewCombinedBuffer = true;
+ goto Finish; // successfully consumed some bytes, output no chars
+ }
+
+ case OperationStatus.InvalidData:
+ break;
+
+ default:
+ Debug.Fail("Unexpected OperationStatus return value.");
+ break;
+ }
+
+ // Couldn't decode the buffer. Fallback the buffer instead.
+
+ if (FallbackBuffer.Fallback(combinedBuffer.Slice(0, combinedBufferBytesConsumed).ToArray(), index: 0)
+ && !_fallbackBuffer.TryDrainRemainingDataForGetChars(chars, out charsWritten))
+ {
+ goto DestinationTooSmall;
+ }
+
+ Finish:
+
+ if (persistNewCombinedBuffer)
+ {
+ Debug.Assert(combinedBufferBytesConsumed == combinedBuffer.Length, "We should be asked to persist the entire combined buffer.");
+ SetLeftoverData(combinedBuffer); // the buffer still only contains partial data; a future call to Convert will need it
+ }
+ else
+ {
+ ClearLeftoverData(); // the buffer contains no partial data; we'll go down the normal paths
+ }
+
+ bytesConsumed = combinedBufferBytesConsumed - _leftoverByteCount; // amount of 'bytes' buffer consumed just now
+ return charsWritten;
+
+ DestinationTooSmall:
+
+ // If we got to this point, we're trying to write chars to the output buffer, but we're unable to do
+ // so. Unlike EncoderNLS, this type does not allow partial writes to the output buffer. Since we know
+ // draining leftover data is the first operation performed by any DecoderNLS API, there was no
+ // opportunity for any code before us to make forward progress, so we must fail immediately.
+
+ _encoding.ThrowCharsOverflow(this, nothingDecoded: true);
+ throw null; // will never reach this point
+ }
+
+ /// <summary>
+ /// Given a byte buffer <paramref name="dest"/>, concatenates as much of <paramref name="srcLeft"/> followed
+ /// by <paramref name="srcRight"/> into it as will fit, then returns the total number of bytes copied.
+ /// </summary>
+ private static int ConcatInto(ReadOnlySpan<byte> srcLeft, ReadOnlySpan<byte> srcRight, Span<byte> dest)
+ {
+ int total = 0;
+
+ for (int i = 0; i < srcLeft.Length; i++)
+ {
+ if ((uint)total >= (uint)dest.Length)
+ {
+ goto Finish;
+ }
+ else
+ {
+ dest[total++] = srcLeft[i];
+ }
+ }
+
+ for (int i = 0; i < srcRight.Length; i++)
+ {
+ if ((uint)total >= (uint)dest.Length)
+ {
+ goto Finish;
+ }
+ else
+ {
+ dest[total++] = srcRight[i];
+ }
+ }
+
+ Finish:
+
+ return total;
+ }
}
}
diff --git a/src/System.Private.CoreLib/shared/System/Text/EncoderFallback.cs b/src/System.Private.CoreLib/shared/System/Text/EncoderFallback.cs
index f98b15e078..ff895d6788 100644
--- a/src/System.Private.CoreLib/shared/System/Text/EncoderFallback.cs
+++ b/src/System.Private.CoreLib/shared/System/Text/EncoderFallback.cs
@@ -2,6 +2,7 @@
// 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.Threading;
@@ -86,12 +87,14 @@ namespace System.Text
// These help us with our performance and messages internally
internal unsafe char* charStart;
internal unsafe char* charEnd;
- internal EncoderNLS encoder;
+ internal EncoderNLS encoder; // TODO: MAKE ME PRIVATE
internal bool setEncoder;
internal bool bUsedEncoder;
internal bool bFallingBack = false;
internal int iRecursionCount = 0;
private const int iMaxRecursion = 250;
+ private Encoding encoding;
+ private int originalCharCount;
// Internal Reset
// For example, what if someone fails a conversion and wants to reset one of our fallback buffers?
@@ -116,6 +119,22 @@ namespace System.Text
this.iRecursionCount = 0;
}
+ internal static EncoderFallbackBuffer CreateAndInitialize(Encoding encoding, EncoderNLS encoder, int originalCharCount)
+ {
+ // The original char count is only used for keeping track of what 'index' value needs
+ // to be passed to the abstract Fallback method. The index value is calculated by subtracting
+ // 'chars.Length' (where chars is expected to be the entire remaining input buffer)
+ // from the 'originalCharCount' value specified here.
+
+ EncoderFallbackBuffer fallbackBuffer = (encoder is null) ? encoding.EncoderFallback.CreateFallbackBuffer() : encoder.FallbackBuffer;
+
+ fallbackBuffer.encoding = encoding;
+ fallbackBuffer.encoder = encoder;
+ fallbackBuffer.originalCharCount = originalCharCount;
+
+ return fallbackBuffer;
+ }
+
internal char InternalGetNextChar()
{
char ch = GetNextChar();
@@ -124,6 +143,170 @@ namespace System.Text
return ch;
}
+ private bool InternalFallback(ReadOnlySpan<char> chars, out int charsConsumed)
+ {
+ Debug.Assert(!chars.IsEmpty, "Caller shouldn't invoke this if there's no data to fall back.");
+
+ // First, try falling back a single BMP character or a standalone low surrogate.
+ // If the first char is a high surrogate, we'll try to combine it with the next
+ // char in the input sequence.
+
+ char firstChar = chars[0];
+ char secondChar = default;
+
+ if (!chars.IsEmpty)
+ {
+ firstChar = chars[0];
+
+ if (1 < (uint)chars.Length)
+ {
+ secondChar = chars[1];
+ }
+ }
+
+ // Ask the subclassed type to initiate fallback logic.
+
+ int index = originalCharCount - chars.Length;
+
+ if (!char.IsSurrogatePair(firstChar, secondChar))
+ {
+ // This code path is also used when 'firstChar' is a standalone surrogate or
+ // if it's a high surrogate at the end of the input buffer.
+
+ charsConsumed = 1;
+ return Fallback(firstChar, index);
+ }
+ else
+ {
+ charsConsumed = 2;
+ return Fallback(firstChar, secondChar, index);
+ }
+ }
+
+ internal int InternalFallbackGetByteCount(ReadOnlySpan<char> chars, out int charsConsumed)
+ {
+ int bytesWritten = 0;
+
+ if (InternalFallback(chars, out charsConsumed))
+ {
+ // There's data in the fallback buffer - pull it out now.
+
+ bytesWritten = DrainRemainingDataForGetByteCount();
+ }
+
+ return bytesWritten;
+ }
+
+ internal bool TryInternalFallbackGetBytes(ReadOnlySpan<char> chars, Span<byte> bytes, out int charsConsumed, out int bytesWritten)
+ {
+ if (InternalFallback(chars, out charsConsumed))
+ {
+ // There's data in the fallback buffer - pull it out now.
+
+ return TryDrainRemainingDataForGetBytes(bytes, out bytesWritten);
+ }
+ else
+ {
+ // There's no data in the fallback buffer.
+
+ bytesWritten = 0;
+ return true; // true = didn't run out of space in destination buffer
+ }
+ }
+
+ internal bool TryDrainRemainingDataForGetBytes(Span<byte> bytes, out int bytesWritten)
+ {
+ int originalBytesLength = bytes.Length;
+
+ Rune thisRune;
+ while ((thisRune = GetNextRune()).Value != 0)
+ {
+ switch (encoding.EncodeRune(thisRune, bytes, out int bytesWrittenJustNow))
+ {
+ case OperationStatus.Done:
+
+ bytes = bytes.Slice(bytesWrittenJustNow);
+ continue;
+
+ case OperationStatus.DestinationTooSmall:
+
+ // Since we're not consuming the Rune we just read, back up as many chars as necessary
+ // to undo the read we just performed, then report to our caller that we ran out of space.
+
+ for (int i = 0; i < thisRune.Utf16SequenceLength; i++)
+ {
+ MovePrevious();
+ }
+
+ bytesWritten = originalBytesLength - bytes.Length;
+ return false; // ran out of destination buffer
+
+ case OperationStatus.InvalidData:
+
+ // We can't fallback the fallback. We can't make forward progress, so report to our caller
+ // that something went terribly wrong. The error message contains the fallback char that
+ // couldn't be converted. (Ideally we'd provide the first char that originally triggered
+ // the fallback, but it's complicated to keep this state around, and a fallback producing
+ // invalid data should be a very rare occurrence.)
+
+ ThrowLastCharRecursive(thisRune.Value);
+ break; // will never be hit; call above throws
+
+ default:
+
+ Debug.Fail("Unexpected return value.");
+ break;
+ }
+ }
+
+ bytesWritten = originalBytesLength - bytes.Length;
+ return true; // finished successfully
+ }
+
+ internal int DrainRemainingDataForGetByteCount()
+ {
+ int totalByteCount = 0;
+
+ Rune thisRune;
+ while ((thisRune = GetNextRune()).Value != 0)
+ {
+ if (!encoding.TryGetByteCount(thisRune, out int byteCountThisIteration))
+ {
+ // We can't fallback the fallback. We can't make forward progress, so report to our caller
+ // that something went terribly wrong. The error message contains the fallback char that
+ // couldn't be converted. (Ideally we'd provide the first char that originally triggered
+ // the fallback, but it's complicated to keep this state around, and a fallback producing
+ // invalid data should be a very rare occurrence.)
+
+ ThrowLastCharRecursive(thisRune.Value);
+ }
+
+ Debug.Assert(byteCountThisIteration >= 0, "Encoding shouldn't have returned a negative byte count.");
+
+ // We need to check for overflow while tallying the fallback byte count.
+
+ totalByteCount += byteCountThisIteration;
+ if (totalByteCount < 0)
+ {
+ InternalReset();
+ Encoding.ThrowConversionOverflow();
+ }
+ }
+
+ return totalByteCount;
+ }
+
+ private Rune GetNextRune()
+ {
+ char firstChar = GetNextChar();
+ if (Rune.TryCreate(firstChar, out Rune value) || Rune.TryCreate(firstChar, GetNextChar(), out value))
+ {
+ return value;
+ }
+
+ throw new ArgumentException(SR.Argument_InvalidCharSequenceNoIndex);
+ }
+
// Fallback the current character using the remaining buffer and encoder if necessary
// This can only be called by our encodings (other have to use the public fallback methods), so
// we can use our EncoderNLS here too.
diff --git a/src/System.Private.CoreLib/shared/System/Text/EncoderNLS.cs b/src/System.Private.CoreLib/shared/System/Text/EncoderNLS.cs
index e83666f7a3..2901fc37b9 100644
--- a/src/System.Private.CoreLib/shared/System/Text/EncoderNLS.cs
+++ b/src/System.Private.CoreLib/shared/System/Text/EncoderNLS.cs
@@ -2,8 +2,8 @@
// 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.Text;
-using System;
+using System.Buffers;
+using System.Diagnostics;
using System.Runtime.InteropServices;
namespace System.Text
@@ -197,9 +197,13 @@ namespace System.Text
bytesUsed = _encoding.GetBytes(chars, charCount, bytes, byteCount, this);
charsUsed = _charsUsed;
- // Its completed if they've used what they wanted AND if they didn't want flush or if we are flushed
- completed = (charsUsed == charCount) && (!flush || !this.HasState) &&
- (_fallbackBuffer == null || _fallbackBuffer.Remaining == 0);
+ // Per MSDN, "The completed output parameter indicates whether all the data in the input
+ // buffer was converted and stored in the output buffer." That means we've successfully
+ // consumed all the input _and_ there's no pending state or fallback data remaining to be output.
+
+ completed = (charsUsed == charCount)
+ && !this.HasState
+ && (_fallbackBuffer is null || _fallbackBuffer.Remaining == 0);
// Our data thingys are now full, we can return
}
@@ -220,6 +224,10 @@ namespace System.Text
}
}
+ /// <summary>
+ /// States whether a call to <see cref="Encoding.GetBytes(char*, int, byte*, int, EncoderNLS)"/> must first drain data on this <see cref="EncoderNLS"/> instance.
+ /// </summary>
+ internal bool HasLeftoverData => _charLeftOver != default || (_fallbackBuffer != null && _fallbackBuffer.Remaining > 0);
// Anything left in our encoder?
internal virtual bool HasState
@@ -235,5 +243,154 @@ namespace System.Text
{
_mustFlush = false;
}
+
+ internal int DrainLeftoverDataForGetByteCount(ReadOnlySpan<char> chars, out int charsConsumed)
+ {
+ // Quick check: we _should not_ have leftover fallback data from a previous invocation,
+ // as we'd end up consuming any such data and would corrupt whatever Convert call happens
+ // to be in progress.
+
+ if (_fallbackBuffer != null && _fallbackBuffer.Remaining > 0)
+ {
+ throw new ArgumentException(SR.Format(SR.Argument_EncoderFallbackNotEmpty, Encoding.EncodingName, _fallbackBuffer.GetType()));
+ }
+
+ // If we have a leftover high surrogate from a previous operation, consume it now.
+ // We won't clear the _charLeftOver field since GetByteCount is supposed to be
+ // a non-mutating operation, and we need the field to retain its value for the
+ // next call to Convert.
+
+ charsConsumed = 0; // could be incorrect, will fix up later in the method
+
+ if (_charLeftOver == default)
+ {
+ return 0; // no leftover high surrogate char - short-circuit and finish
+ }
+ else
+ {
+ char secondChar = default;
+
+ if (chars.IsEmpty)
+ {
+ // If the input buffer is empty and we're not being asked to flush, no-op and return
+ // success to our caller. If we're being asked to flush, the leftover high surrogate from
+ // the previous operation will go through the fallback mechanism by itself.
+
+ if (!MustFlush)
+ {
+ return 0; // no-op = success
+ }
+ }
+ else
+ {
+ secondChar = chars[0];
+ }
+
+ // If we have to fallback the chars we're reading immediately below, populate the
+ // fallback buffer with the invalid data. We'll just fall through to the "consume
+ // fallback buffer" logic at the end of the method.
+
+ bool didFallback;
+
+ if (Rune.TryCreate(_charLeftOver, secondChar, out Rune rune))
+ {
+ charsConsumed = 1; // consumed the leftover high surrogate + the first char in the input buffer
+
+ if (_encoding.TryGetByteCount(rune, out int byteCount))
+ {
+ Debug.Assert(byteCount >= 0, "Encoding shouldn't have returned a negative byte count.");
+ return byteCount;
+ }
+ else
+ {
+ didFallback = FallbackBuffer.Fallback(_charLeftOver, secondChar, index: 0);
+ }
+ }
+ else
+ {
+ didFallback = FallbackBuffer.Fallback(_charLeftOver, index: 0);
+ }
+
+ // Now tally the number of bytes that would've been emitted as part of fallback.
+
+ return _fallbackBuffer.DrainRemainingDataForGetByteCount();
+ }
+ }
+
+ internal bool TryDrainLeftoverDataForGetBytes(ReadOnlySpan<char> chars, Span<byte> bytes, out int charsConsumed, out int bytesWritten)
+ {
+ // We may have a leftover high surrogate data from a previous invocation, or we may have leftover
+ // data in the fallback buffer, or we may have neither, but we will never have both. Check for these
+ // conditions and handle them now.
+
+ charsConsumed = 0; // could be incorrect, will fix up later in the method
+ bytesWritten = 0; // could be incorrect, will fix up later in the method
+
+ if (_charLeftOver != default)
+ {
+ char secondChar = default;
+
+ if (chars.IsEmpty)
+ {
+ // If the input buffer is empty and we're not being asked to flush, no-op and return
+ // success to our caller. If we're being asked to flush, the leftover high surrogate from
+ // the previous operation will go through the fallback mechanism by itself.
+
+ if (!MustFlush)
+ {
+ charsConsumed = 0;
+ bytesWritten = 0;
+ return true; // no-op = success
+ }
+ }
+ else
+ {
+ secondChar = chars[0];
+ }
+
+ // If we have to fallback the chars we're reading immediately below, populate the
+ // fallback buffer with the invalid data. We'll just fall through to the "consume
+ // fallback buffer" logic at the end of the method.
+
+ if (Rune.TryCreate(_charLeftOver, secondChar, out Rune rune))
+ {
+ charsConsumed = 1; // at the very least, we consumed 1 char from the input
+ switch (_encoding.EncodeRune(rune, bytes, out bytesWritten))
+ {
+ case OperationStatus.Done:
+ _charLeftOver = default; // we just consumed this char
+ return true; // that's all - we've handled the leftover data
+
+ case OperationStatus.DestinationTooSmall:
+ _charLeftOver = default; // we just consumed this char
+ _encoding.ThrowBytesOverflow(this, nothingEncoded: true); // will throw
+ break;
+
+ case OperationStatus.InvalidData:
+ FallbackBuffer.Fallback(_charLeftOver, secondChar, index: 0);
+ break;
+
+ default:
+ Debug.Fail("Unknown return value.");
+ break;
+ }
+ }
+ else
+ {
+ FallbackBuffer.Fallback(_charLeftOver, index: 0);
+ }
+ }
+
+ // Now check the fallback buffer for any remaining data.
+
+ if (_fallbackBuffer != null && _fallbackBuffer.Remaining > 0)
+ {
+ return _fallbackBuffer.TryDrainRemainingDataForGetBytes(bytes, out bytesWritten);
+ }
+
+ // And we're done!
+
+ return true; // success
+ }
}
}
diff --git a/src/System.Private.CoreLib/shared/System/Text/Encoding.Internal.cs b/src/System.Private.CoreLib/shared/System/Text/Encoding.Internal.cs
new file mode 100644
index 0000000000..09044afefe
--- /dev/null
+++ b/src/System.Private.CoreLib/shared/System/Text/Encoding.Internal.cs
@@ -0,0 +1,1277 @@
+// 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 Internal.Runtime.CompilerServices;
+
+namespace System.Text
+{
+ public partial class Encoding
+ {
+ /*
+ * This file contains infrastructure code that supports a simplified way of writing
+ * internally-implemented Encoding types. In this system, the individual Encoding types
+ * are no longer responsible for handling anything related to the EncoderNLS / DecoderNLS
+ * infrastructure, nor are they responsible for implementing anything related to fallback
+ * buffers logic.
+ *
+ * Instead, subclassed types are responsible only for transcoding of individual scalar values
+ * to and from the encoding's byte representation (see the two methods immediately below).
+ * They can optionally implement fast-path logic to perform bulk transcoding up until the
+ * first segment of data that cannot be transcoded. They can special-case certain fallback
+ * mechanisms if desired.
+ *
+ * Most of the fast-path code is written using raw pointers as the exchange types, just as
+ * in the standard Encoding infrastructure. Since the fallback logic is more complex, most
+ * of it is written using type-safe constructs like Span<T>, with some amount of glue to
+ * allow it to work correctly with pointer-based fast-path code.
+ *
+ * A typical call graph for GetBytes is represented below, using ASCIIEncoding as an example.
+ *
+ * ASCIIEncoding.GetBytes(...) [non-EncoderNLS path, public virtual override]
+ * `- <parameter validation>
+ * - ASCIIEncoding.GetBytesCommon [private helper method per derived type, inlined]
+ * `- ASCIIEncoding.GetBytesFast [overridden fast-path implementation, inlined]
+ * - <if all data transcoded, return immediately>
+ * - <if all data not transcoded...>
+ * `- Encoding.GetBytesWithFallback [non-virtual stub method to call main GetBytesWithFallback worker]
+ * `- Encoding.GetBytesWithFallback [virtual method whose base implementation contains slow fallback logic]
+ * `- <may be overridden to provide optimized fallback logic>
+ * - <create EncodeFallbackBuffer instance>
+ * - <perform the following in a loop:>
+ * `- <invoke fast-path logic via virtual method dispatch on derived type>
+ * - <read next "bad" scalar value from source>
+ * - <run this bad value through the fallback buffer>
+ * - <drain the fallback buffer to the destination>
+ * - <loop until source is fully consumed or destination is full>
+ * - <signal full or partial success to EncoderNLS instance / throw if necessary>
+ *
+ * The call graph for GetBytes(..., EncoderNLS) is similar:
+ *
+ * Encoding.GetBytes(..., EncoderNLS) [base implementation]
+ * `- <if no leftover data from previous invocation, invoke fast-path>
+ * - <if fast-path invocation above completed, return immediately>
+ * - <if not all data transcoded, or if there was leftover data from previous invocation...>
+ * `- Encoding.GetBytesWithFallback [non-virtual stub method]
+ * `- <drain any leftover data from previous invocation>
+ * - <invoke fast-path again>
+ * - <if all data transcoded, return immediately>
+ * - <if all data not transcoded...>
+ * `- Encoding.GetBytesWithFallback [virtual method as described above]
+ *
+ * There are different considerations in each call graph for things like error handling,
+ * since the error conditions will be different depending on whether or not an EncoderNLS
+ * instance is available and what values its properties have.
+ */
+
+ /*
+ * THESE TWO METHODS MUST BE OVERRIDDEN BY A SUBCLASSED TYPE
+ */
+
+ internal virtual OperationStatus DecodeFirstRune(ReadOnlySpan<byte> bytes, out Rune value, out int bytesConsumed)
+ {
+ Debug.Fail("This should be overridden by a subclassed type.");
+ throw NotImplemented.ByDesign;
+ }
+
+ internal virtual OperationStatus EncodeRune(Rune value, Span<byte> bytes, out int bytesWritten)
+ {
+ Debug.Fail("This should be overridden by a subclassed type.");
+ throw NotImplemented.ByDesign;
+ }
+
+ /*
+ * ALL OTHER LOGIC CAN BE IMPLEMENTED IN TERMS OF THE TWO METHODS ABOVE.
+ * FOR IMPROVED PERFORMANCE, SUBCLASSED TYPES MAY WANT TO OVERRIDE ONE OR MORE VIRTUAL METHODS BELOW.
+ */
+
+ /*
+ * GETBYTECOUNT FAMILY OF FUNCTIONS
+ */
+
+ /// <summary>
+ /// Given a <see cref="Rune"/>, determines its byte count under the current <see cref="Encoding"/>.
+ /// Returns <see langword="false"/> if the <see cref="Rune"/> cannot be represented in the
+ /// current <see cref="Encoding"/>.
+ /// </summary>
+ internal virtual bool TryGetByteCount(Rune value, out int byteCount)
+ {
+ // Any production-quality type would override this method and provide a real
+ // implementation, so we won't provide a base implementation. However, a
+ // non-shipping slow reference implementation is provided below for convenience.
+
+#if false
+ Span<byte> bytes = stackalloc byte[4]; // max 4 bytes per input scalar
+
+ OperationStatus opStatus = EncodeRune(value, bytes, out byteCount);
+ Debug.Assert(opStatus == OperationStatus.Done || opStatus == OperationStatus.InvalidData, "Unexpected return value.");
+
+ return (opStatus == OperationStatus.Done);
+#else
+ Debug.Fail("This should be overridden by a subclassed type.");
+ throw NotImplemented.ByDesign;
+#endif
+ }
+
+ /// <summary>
+ /// Entry point from <see cref="EncoderNLS.GetByteCount"/>.
+ /// </summary>
+ internal virtual unsafe int GetByteCount(char* pChars, int charCount, EncoderNLS encoder)
+ {
+ Debug.Assert(encoder != null, "This code path should only be called from EncoderNLS.");
+ Debug.Assert(charCount >= 0, "Caller should've checked this condition.");
+ Debug.Assert(pChars != null || charCount == 0, "Cannot provide a null pointer and a non-zero count.");
+
+ // We're going to try to stay on the fast-path as much as we can. That means that we have
+ // no leftover data to drain and the entire source buffer can be consumed in a single
+ // fast-path invocation. If either of these doesn't hold, we'll go down the slow path of
+ // creating spans, draining the EncoderNLS instance, and falling back.
+
+ int totalByteCount = 0;
+ int charsConsumed = 0;
+
+ if (!encoder.HasLeftoverData)
+ {
+ totalByteCount = GetByteCountFast(pChars, charCount, encoder.Fallback, out charsConsumed);
+ if (charsConsumed == charCount)
+ {
+ return totalByteCount;
+ }
+ }
+
+ // We had leftover data, or we couldn't consume the entire input buffer.
+ // Let's go down the draining + fallback mechanisms.
+
+ totalByteCount += GetByteCountWithFallback(pChars, charCount, charsConsumed, encoder);
+ if (totalByteCount < 0)
+ {
+ ThrowConversionOverflow();
+ }
+
+ return totalByteCount;
+ }
+
+ /// <summary>
+ /// Counts the number of <see langword="byte"/>s that would result from transcoding the source
+ /// data, exiting when the source buffer is consumed or when the first unreadable data is encountered.
+ /// The implementation may inspect <paramref name="fallback"/> to short-circuit any counting
+ /// operation, but it should not attempt to call <see cref="EncoderFallback.CreateFallbackBuffer"/>.
+ /// </summary>
+ /// <returns>
+ /// Via <paramref name="charsConsumed"/>, the number of elements from <paramref name="pChars"/> which
+ /// were consumed; and returns the transcoded byte count up to this point.
+ /// </returns>
+ /// <exception cref="ArgumentException">
+ /// If the byte count would be greater than <see cref="int.MaxValue"/>.
+ /// (Implementation should call <see cref="ThrowConversionOverflow"/>.)
+ /// </exception>
+ /// <remarks>
+ /// The implementation should not attempt to perform any sort of fallback behavior.
+ /// If custom fallback behavior is necessary, override <see cref="GetByteCountWithFallback"/>.
+ /// </remarks>
+ private protected virtual unsafe int GetByteCountFast(char* pChars, int charsLength, EncoderFallback fallback, out int charsConsumed)
+ {
+ // Any production-quality type would override this method and provide a real
+ // implementation, so we won't provide a base implementation. However, a
+ // non-shipping slow reference implementation is provided below for convenience.
+
+#if false
+ ReadOnlySpan<char> chars = new ReadOnlySpan<char>(pChars, charsLength);
+ int totalByteCount = 0;
+
+ while (!chars.IsEmpty)
+ {
+ if (Rune.DecodeUtf16(chars, out Rune scalarValue, out int charsConsumedThisIteration) != OperationStatus.Done
+ || !TryGetByteCount(scalarValue, out int byteCountThisIteration))
+ {
+ // Invalid UTF-16 data, or not convertible to target encoding
+
+ break;
+ }
+
+ chars = chars.Slice(charsConsumedThisIteration);
+
+ totalByteCount += byteCountThisIteration;
+ if (totalByteCount < 0)
+ {
+ ThrowConversionOverflow();
+ }
+ }
+
+ charsConsumed = charsLength - chars.Length; // number of chars consumed across all loop iterations above
+ return totalByteCount;
+#else
+ Debug.Fail("This should be overridden by a subclassed type.");
+ throw NotImplemented.ByDesign;
+#endif
+ }
+
+ /// <summary>
+ /// Counts the number of bytes that would result from transcoding the provided chars,
+ /// with no associated <see cref="EncoderNLS"/>. The first two arguments are based on the
+ /// original input before invoking this method; and <paramref name="charsConsumedSoFar"/>
+ /// signals where in the provided buffer the fallback loop should begin operating.
+ /// </summary>
+ /// <returns>
+ /// The byte count resulting from transcoding the input data.
+ /// </returns>
+ /// <exception cref="ArgumentException">
+ /// If the resulting byte count is greater than <see cref="int.MaxValue"/>.
+ /// (Implementation should call <see cref="ThrowConversionOverflow"/>.)
+ /// </exception>
+ [MethodImpl(MethodImplOptions.NoInlining)] // don't stack spill spans into our caller
+ private protected unsafe int GetByteCountWithFallback(char* pCharsOriginal, int originalCharCount, int charsConsumedSoFar)
+ {
+ // This is a stub method that's marked "no-inlining" so that it we don't stack-spill spans
+ // into our immediate caller. Doing so increases the method prolog in what's supposed to
+ // be a very fast path.
+
+ Debug.Assert(0 <= charsConsumedSoFar && charsConsumedSoFar < originalCharCount, "Invalid arguments provided to method.");
+
+ return GetByteCountWithFallback(
+ chars: new ReadOnlySpan<char>(pCharsOriginal, originalCharCount).Slice(charsConsumedSoFar),
+ originalCharsLength: originalCharCount,
+ encoder: null);
+ }
+
+ /// <summary>
+ /// Gets the number of <see langword="byte"/>s that would result from transcoding the provided
+ /// input data, with an associated <see cref="EncoderNLS"/>. The first two arguments are
+ /// based on the original input before invoking this method; and <paramref name="charsConsumedSoFar"/>
+ /// signals where in the provided source buffer the fallback loop should begin operating.
+ /// The behavior of this method is to consume (non-destructively) any leftover data in the
+ /// <see cref="EncoderNLS"/> instance, then to invoke the <see cref="GetByteCountFast"/> virtual method
+ /// after data has been drained, then to call <see cref="GetByteCountWithFallback(ReadOnlySpan{char}, int, EncoderNLS)"/>.
+ /// </summary>
+ /// <returns>
+ /// The total number of bytes that would result from transcoding the remaining portion of the source buffer.
+ /// </returns>
+ /// <exception cref="ArgumentException">
+ /// If the return value would exceed <see cref="int.MaxValue"/>.
+ /// (The implementation should call <see cref="ThrowConversionOverflow"/>.)
+ /// </exception>
+ private unsafe int GetByteCountWithFallback(char* pOriginalChars, int originalCharCount, int charsConsumedSoFar, EncoderNLS encoder)
+ {
+ Debug.Assert(encoder != null, "This code path should only be called from EncoderNLS.");
+ Debug.Assert(0 <= charsConsumedSoFar && charsConsumedSoFar < originalCharCount, "Caller should've checked this condition.");
+
+ // First, try draining any data that already exists on the encoder instance. If we can't complete
+ // that operation, there's no point to continuing down to the main workhorse methods.
+
+ ReadOnlySpan<char> chars = new ReadOnlySpan<char>(pOriginalChars, originalCharCount).Slice(charsConsumedSoFar);
+
+ int totalByteCount = encoder.DrainLeftoverDataForGetByteCount(chars, out int charsConsumedJustNow);
+ chars = chars.Slice(charsConsumedJustNow);
+
+ // Now try invoking the "fast path" (no fallback) implementation.
+ // We can use Unsafe.AsPointer here since these spans are created from pinned data (raw pointers).
+
+ totalByteCount += GetByteCountFast(
+ pChars: (char*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(chars)),
+ charsLength: chars.Length,
+ fallback: encoder.Fallback,
+ charsConsumed: out charsConsumedJustNow);
+
+ if (totalByteCount < 0)
+ {
+ ThrowConversionOverflow();
+ }
+
+ chars = chars.Slice(charsConsumedJustNow);
+
+ // If there's still data remaining in the source buffer, go down the fallback path.
+ // Otherwise we're finished.
+
+ if (!chars.IsEmpty)
+ {
+ totalByteCount += GetByteCountWithFallback(chars, originalCharCount, encoder);
+ if (totalByteCount < 0)
+ {
+ ThrowConversionOverflow();
+ }
+ }
+
+ return totalByteCount;
+ }
+
+ /// <summary>
+ /// Counts the number of bytes that would result from transcoding the provided chars,
+ /// using the provided <see cref="EncoderFallbackBuffer"/> if necessary.
+ /// </summary>
+ /// <returns>
+ /// The byte count resulting from transcoding the input data.
+ /// </returns>
+ /// <exception cref="ArgumentException">
+ /// If the resulting byte count is greater than <see cref="int.MaxValue"/>.
+ /// (Implementation should call <see cref="ThrowConversionOverflow"/>.)
+ /// </exception>
+ private protected virtual unsafe int GetByteCountWithFallback(ReadOnlySpan<char> chars, int originalCharsLength, EncoderNLS encoder)
+ {
+ Debug.Assert(!chars.IsEmpty, "Caller shouldn't invoke this method with an empty input buffer.");
+ Debug.Assert(originalCharsLength >= 0, "Caller provided invalid parameter.");
+
+ // Since we're using Unsafe.AsPointer in our central loop, we want to ensure everything is pinned.
+
+ fixed (char* _pChars_Unused = &MemoryMarshal.GetReference(chars))
+ {
+ EncoderFallbackBuffer fallbackBuffer = EncoderFallbackBuffer.CreateAndInitialize(this, encoder, originalCharsLength);
+ int totalByteCount = 0;
+
+ do
+ {
+ // There's still data in the source buffer; why wasn't the previous fast-path able to consume it fully?
+ // There are two scenarios: (a) the source buffer contained invalid / incomplete UTF-16 data;
+ // or (b) the encoding can't translate this scalar value.
+
+ if (Rune.DecodeUtf16(chars, out Rune firstScalarValue, out int charsConsumedThisIteration) == OperationStatus.NeedMoreData
+ && encoder != null
+ && !encoder.MustFlush)
+ {
+ // We saw a standalone high surrogate at the end of the buffer, and the
+ // active EncoderNLS instance isn't asking us to flush. Since a call to
+ // GetBytes would've consumed this char by storing it in EncoderNLS._charLeftOver,
+ // we'll "consume" it by ignoring it. The next call to GetBytes will
+ // pick it up correctly.
+
+ goto Finish;
+ }
+
+ // We saw invalid UTF-16 data, or we saw a high surrogate that we need to flush (and
+ // thus treat as invalid), or we saw valid UTF-16 data that this encoder doesn't support.
+ // In any case we'll run it through the fallback mechanism.
+
+ int byteCountThisIteration = fallbackBuffer.InternalFallbackGetByteCount(chars, out charsConsumedThisIteration);
+
+ Debug.Assert(byteCountThisIteration >= 0, "Fallback shouldn't have returned a negative value.");
+ Debug.Assert(charsConsumedThisIteration >= 0, "Fallback shouldn't have returned a negative value.");
+
+ totalByteCount += byteCountThisIteration;
+ if (totalByteCount < 0)
+ {
+ ThrowConversionOverflow();
+ }
+
+ chars = chars.Slice(charsConsumedThisIteration);
+
+ if (!chars.IsEmpty)
+ {
+ // Still data remaining - run it through the fast-path to find the next data to fallback.
+ // While building up the tally we need to continually check for integer overflow
+ // since fallbacks can change the total byte count in unexpected ways.
+
+ byteCountThisIteration = GetByteCountFast(
+ pChars: (char*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(chars)),
+ charsLength: chars.Length,
+ fallback: null, // already tried this earlier and we still fell down the common path, so skip from now on
+ charsConsumed: out charsConsumedThisIteration);
+
+ Debug.Assert(byteCountThisIteration >= 0, "Workhorse shouldn't have returned a negative value.");
+ Debug.Assert(charsConsumedThisIteration >= 0, "Workhorse shouldn't have returned a negative value.");
+
+ totalByteCount += byteCountThisIteration;
+ if (totalByteCount < 0)
+ {
+ ThrowConversionOverflow();
+ }
+
+ chars = chars.Slice(charsConsumedThisIteration);
+ }
+ } while (!chars.IsEmpty);
+
+ Finish:
+
+ Debug.Assert(fallbackBuffer.Remaining == 0, "There should be no data in the fallback buffer after GetByteCount.");
+
+ return totalByteCount;
+ }
+ }
+
+ /*
+ * GETBYTES FAMILY OF FUNCTIONS
+ */
+
+ /// <summary>
+ /// Entry point from <see cref="EncoderNLS.GetBytes"/> and <see cref="EncoderNLS.Convert"/>.
+ /// </summary>
+ internal virtual unsafe int GetBytes(char* pChars, int charCount, byte* pBytes, int byteCount, EncoderNLS encoder)
+ {
+ Debug.Assert(encoder != null, "This code path should only be called from EncoderNLS.");
+ Debug.Assert(charCount >= 0, "Caller should've checked this condition.");
+ Debug.Assert(pChars != null || charCount == 0, "Cannot provide a null pointer and a non-zero count.");
+ Debug.Assert(byteCount >= 0, "Caller should've checked this condition.");
+ Debug.Assert(pBytes != null || byteCount == 0, "Cannot provide a null pointer and a non-zero count.");
+
+ // We're going to try to stay on the fast-path as much as we can. That means that we have
+ // no leftover data to drain and the entire source buffer can be transcoded in a single
+ // fast-path invocation. If either of these doesn't hold, we'll go down the slow path of
+ // creating spans, draining the EncoderNLS instance, and falling back.
+
+ int bytesWritten = 0;
+ int charsConsumed = 0;
+
+ if (!encoder.HasLeftoverData)
+ {
+ bytesWritten = GetBytesFast(pChars, charCount, pBytes, byteCount, out charsConsumed);
+ if (charsConsumed == charCount)
+ {
+ encoder._charsUsed = charCount;
+ return bytesWritten;
+ }
+ }
+
+ // We had leftover data, or we couldn't consume the entire input buffer.
+ // Let's go down the draining + fallback mechanisms.
+
+ return GetBytesWithFallback(pChars, charCount, pBytes, byteCount, charsConsumed, bytesWritten, encoder);
+ }
+
+ /// <summary>
+ /// Transcodes <see langword="char"/>s to <see langword="byte"/>s, exiting when the source or destination
+ /// buffer is consumed or when the first unreadable data is encountered.
+ /// </summary>
+ /// <returns>
+ /// Via <paramref name="charsConsumed"/>, the number of elements from <paramref name="pChars"/> which
+ /// were consumed; and returns the number of elements written to <paramref name="pBytes"/>.
+ /// </returns>
+ /// <remarks>
+ /// The implementation should not attempt to perform any sort of fallback behavior.
+ /// If custom fallback behavior is necessary, override <see cref="GetBytesWithFallback"/>.
+ /// </remarks>
+ private protected virtual unsafe int GetBytesFast(char* pChars, int charsLength, byte* pBytes, int bytesLength, out int charsConsumed)
+ {
+ // Any production-quality type would override this method and provide a real
+ // implementation, so we won't provide a base implementation. However, a
+ // non-shipping slow reference implementation is provided below for convenience.
+
+#if false
+ ReadOnlySpan<char> chars = new ReadOnlySpan<char>(pChars, charsLength);
+ Span<byte> bytes = new Span<byte>(pBytes, bytesLength);
+
+ while (!chars.IsEmpty)
+ {
+ if (Rune.DecodeUtf16(chars, out Rune scalarValue, out int charsConsumedJustNow) != OperationStatus.Done
+ || EncodeRune(scalarValue, bytes, out int bytesWrittenJustNow) != OperationStatus.Done)
+ {
+ // Invalid UTF-16 data, or not convertible to target encoding, or destination buffer too small to contain encoded value
+
+ break;
+ }
+
+ chars = chars.Slice(charsConsumedJustNow);
+ bytes = bytes.Slice(bytesWrittenJustNow);
+ }
+
+ charsConsumed = charsLength - chars.Length; // number of chars consumed across all loop iterations above
+ return bytesLength - bytes.Length; // number of bytes written across all loop iterations above
+#else
+ Debug.Fail("This should be overridden by a subclassed type.");
+ throw NotImplemented.ByDesign;
+#endif
+ }
+
+ /// <summary>
+ /// Transcodes chars to bytes, with no associated <see cref="EncoderNLS"/>. The first four arguments are
+ /// based on the original input before invoking this method; and <paramref name="charsConsumedSoFar"/>
+ /// and <paramref name="bytesWrittenSoFar"/> signal where in the provided buffers the fallback loop
+ /// should begin operating. The behavior of this method is to call the <see cref="GetBytesWithFallback"/>
+ /// virtual method as overridden by the specific type, and failing that go down the shared fallback path.
+ /// </summary>
+ /// <returns>
+ /// The total number of bytes written to <paramref name="pOriginalBytes"/>, including <paramref name="bytesWrittenSoFar"/>.
+ /// </returns>
+ /// <exception cref="ArgumentException">
+ /// If the destination buffer is not large enough to hold the entirety of the transcoded data.
+ /// </exception>
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private protected unsafe int GetBytesWithFallback(char* pOriginalChars, int originalCharCount, byte* pOriginalBytes, int originalByteCount, int charsConsumedSoFar, int bytesWrittenSoFar)
+ {
+ // This is a stub method that's marked "no-inlining" so that it we don't stack-spill spans
+ // into our immediate caller. Doing so increases the method prolog in what's supposed to
+ // be a very fast path.
+
+ Debug.Assert(0 <= charsConsumedSoFar && charsConsumedSoFar < originalCharCount, "Invalid arguments provided to method.");
+ Debug.Assert(0 <= bytesWrittenSoFar && bytesWrittenSoFar <= originalByteCount, "Invalid arguments provided to method.");
+
+ return GetBytesWithFallback(
+ chars: new ReadOnlySpan<char>(pOriginalChars, originalCharCount).Slice(charsConsumedSoFar),
+ originalCharsLength: originalCharCount,
+ bytes: new Span<byte>(pOriginalBytes, originalByteCount).Slice(bytesWrittenSoFar),
+ originalBytesLength: originalByteCount,
+ encoder: null);
+ }
+
+ /// <summary>
+ /// Transcodes chars to bytes, with an associated <see cref="EncoderNLS"/>. The first four arguments are
+ /// based on the original input before invoking this method; and <paramref name="charsConsumedSoFar"/>
+ /// and <paramref name="bytesWrittenSoFar"/> signal where in the provided buffers the fallback loop
+ /// should begin operating. The behavior of this method is to drain any leftover data in the
+ /// <see cref="EncoderNLS"/> instance, then to invoke the <see cref="GetBytesFast"/> virtual method
+ /// after data has been drained, then to call <see cref="GetBytesWithFallback(ReadOnlySpan{char}, int, Span{byte}, int, EncoderNLS)"/>.
+ /// </summary>
+ /// <returns>
+ /// The total number of bytes written to <paramref name="pOriginalBytes"/>, including <paramref name="bytesWrittenSoFar"/>.
+ /// </returns>
+ /// <exception cref="ArgumentException">
+ /// If the destination buffer is too small to make any forward progress at all, or if the destination buffer is
+ /// too small to contain the entirety of the transcoded data and the <see cref="EncoderNLS"/> instance disallows
+ /// partial transcoding.
+ /// </exception>
+ private unsafe int GetBytesWithFallback(char* pOriginalChars, int originalCharCount, byte* pOriginalBytes, int originalByteCount, int charsConsumedSoFar, int bytesWrittenSoFar, EncoderNLS encoder)
+ {
+ Debug.Assert(encoder != null, "This code path should only be called from EncoderNLS.");
+ Debug.Assert(0 <= charsConsumedSoFar && charsConsumedSoFar < originalCharCount, "Caller should've checked this condition.");
+ Debug.Assert(0 <= bytesWrittenSoFar && bytesWrittenSoFar <= originalByteCount, "Caller should've checked this condition.");
+
+ // First, try draining any data that already exists on the encoder instance. If we can't complete
+ // that operation, there's no point to continuing down to the main workhorse methods.
+
+ ReadOnlySpan<char> chars = new ReadOnlySpan<char>(pOriginalChars, originalCharCount).Slice(charsConsumedSoFar);
+ Span<byte> bytes = new Span<byte>(pOriginalBytes, originalByteCount).Slice(bytesWrittenSoFar);
+
+ bool drainFinishedSuccessfully = encoder.TryDrainLeftoverDataForGetBytes(chars, bytes, out int charsConsumedJustNow, out int bytesWrittenJustNow);
+
+ chars = chars.Slice(charsConsumedJustNow); // whether or not the drain finished, we may have made some progress
+ bytes = bytes.Slice(bytesWrittenJustNow);
+
+ if (!drainFinishedSuccessfully)
+ {
+ ThrowBytesOverflow(encoder, nothingEncoded: bytes.Length == originalByteCount); // might not throw if we wrote at least one byte
+ }
+ else
+ {
+ // Now try invoking the "fast path" (no fallback) implementation.
+ // We can use Unsafe.AsPointer here since these spans are created from pinned data (raw pointers).
+
+ bytesWrittenJustNow = GetBytesFast(
+ pChars: (char*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(chars)),
+ charsLength: chars.Length,
+ pBytes: (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(bytes)),
+ bytesLength: bytes.Length,
+ charsConsumed: out charsConsumedJustNow);
+
+ chars = chars.Slice(charsConsumedJustNow);
+ bytes = bytes.Slice(bytesWrittenJustNow);
+
+ // If there's still data remaining in the source buffer, go down the fallback path.
+ // Otherwise we're finished.
+
+ if (!chars.IsEmpty)
+ {
+ // We'll optimistically tell the encoder that we're using everything; the
+ // GetBytesWithFallback method will overwrite this field if necessary.
+
+ encoder._charsUsed = originalCharCount;
+ return GetBytesWithFallback(chars, originalCharCount, bytes, originalByteCount, encoder);
+ }
+ }
+
+ encoder._charsUsed = originalCharCount - chars.Length; // total number of characters consumed up until now
+ return originalByteCount - bytes.Length; // total number of bytes written up until now
+ }
+
+ /// <summary>
+ /// Transcodes chars to bytes, using <see cref="Encoding.EncoderFallback"/> or <see cref="Encoder.Fallback"/> if needed.
+ /// </summary>
+ /// <returns>
+ /// The total number of bytes written to <paramref name="bytes"/> (based on <paramref name="originalBytesLength"/>).
+ /// </returns>
+ /// <remarks>
+ /// The derived class should override this method if it might be able to provide a more optimized fallback
+ /// implementation, deferring to the base implementation if needed. This method calls <see cref="ThrowBytesOverflow"/>
+ /// if necessary.
+ /// </remarks>
+ private protected virtual unsafe int GetBytesWithFallback(ReadOnlySpan<char> chars, int originalCharsLength, Span<byte> bytes, int originalBytesLength, EncoderNLS encoder)
+ {
+ Debug.Assert(!chars.IsEmpty, "Caller shouldn't invoke this method with an empty input buffer.");
+ Debug.Assert(originalCharsLength >= 0, "Caller provided invalid parameter.");
+ Debug.Assert(originalBytesLength >= 0, "Caller provided invalid parameter.");
+
+ // Since we're using Unsafe.AsPointer in our central loop, we want to ensure everything is pinned.
+
+ fixed (char* _pChars_Unused = &MemoryMarshal.GetReference(chars))
+ fixed (byte* _pBytes_Unused = &MemoryMarshal.GetReference(bytes))
+ {
+ EncoderFallbackBuffer fallbackBuffer = EncoderFallbackBuffer.CreateAndInitialize(this, encoder, originalCharsLength);
+
+ do
+ {
+ // There's still data in the source buffer; why wasn't the previous fast-path able to consume it fully?
+ // There are two scenarios: (a) the source buffer contained invalid / incomplete UTF-16 data;
+ // or (b) the encoding can't translate this scalar value.
+
+ switch (Rune.DecodeUtf16(chars, out Rune firstScalarValue, out int charsConsumedThisIteration))
+ {
+ case OperationStatus.NeedMoreData:
+ Debug.Assert(charsConsumedThisIteration == chars.Length, "If returning NeedMoreData, should out the entire buffer length as chars consumed.");
+ if (encoder is null || encoder.MustFlush)
+ {
+ goto case OperationStatus.InvalidData; // see comment in GetByteCountWithFallback
+ }
+ else
+ {
+ encoder._charLeftOver = chars[0]; // squirrel away remaining high surrogate char and finish
+ chars = ReadOnlySpan<char>.Empty;
+ goto Finish;
+ }
+
+ case OperationStatus.InvalidData:
+ break;
+
+ default:
+ if (EncodeRune(firstScalarValue, bytes, out _) == OperationStatus.DestinationTooSmall)
+ {
+ goto Finish; // source buffer contained valid UTF-16 but encoder ran out of space in destination buffer
+ }
+ break; // source buffer contained valid UTF-16 but encoder doesn't support this scalar value
+ }
+
+ // Now we know the reason for failure was that the original input was invalid
+ // for the encoding in use. Run it through the fallback mechanism.
+
+ bool fallbackFinished = fallbackBuffer.TryInternalFallbackGetBytes(chars, bytes, out charsConsumedThisIteration, out int bytesWrittenThisIteration);
+
+ // Regardless of whether the fallback finished, it did consume some number of
+ // chars, and it may have written some number of bytes.
+
+ chars = chars.Slice(charsConsumedThisIteration);
+ bytes = bytes.Slice(bytesWrittenThisIteration);
+
+ if (!fallbackFinished)
+ {
+ goto Finish; // fallback has pending state - it'll get written out on the next GetBytes call
+ }
+
+ if (!chars.IsEmpty)
+ {
+ // Still data remaining - run it through the fast-path to find the next data to fallback.
+
+ bytesWrittenThisIteration = GetBytesFast(
+ pChars: (char*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(chars)),
+ charsLength: chars.Length,
+ pBytes: (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(bytes)),
+ bytesLength: bytes.Length,
+ charsConsumed: out charsConsumedThisIteration);
+
+ Debug.Assert(bytesWrittenThisIteration >= 0, "Workhorse shouldn't have returned a negative value.");
+ Debug.Assert(charsConsumedThisIteration >= 0, "Workhorse shouldn't have returned a negative value.");
+
+ chars = chars.Slice(charsConsumedThisIteration);
+ bytes = bytes.Slice(bytesWrittenThisIteration);
+ }
+ } while (!chars.IsEmpty);
+
+ Finish:
+
+ // We reach this point when we deplete the source or destination buffer. There are a few
+ // cases to consider now. If the source buffer has been fully consumed and there's no
+ // leftover data in the EncoderNLS or the fallback buffer, we've completed transcoding.
+ // If the source buffer isn't empty or there's leftover data in the fallback buffer,
+ // it means we ran out of space in the destintion buffer. This is an unrecoverable error
+ // if no EncoderNLS is in use (because only EncoderNLS can handle partial success), and
+ // even if an EncoderNLS is in use this is only recoverable if the EncoderNLS instance
+ // allows partial completion. Let's check all of these conditions now.
+
+ if (!chars.IsEmpty || fallbackBuffer.Remaining > 0)
+ {
+ // The line below will also throw if the encoder couldn't make any progress at all
+ // because the output buffer wasn't large enough to contain the result of even
+ // a single scalar conversion or fallback.
+
+ ThrowBytesOverflow(encoder, nothingEncoded: bytes.Length == originalBytesLength);
+ }
+
+ // If an EncoderNLS instance is active, update its "total consumed character count" value.
+
+ if (encoder != null)
+ {
+ Debug.Assert(originalCharsLength >= chars.Length, "About to report a negative number of chars used?");
+ encoder._charsUsed = originalCharsLength - chars.Length; // number of chars consumed
+ }
+
+ Debug.Assert(fallbackBuffer.Remaining == 0 || encoder != null, "Shouldn't have any leftover data in fallback buffer unless an EncoderNLS is in use.");
+
+ return originalBytesLength - bytes.Length;
+ }
+ }
+
+ /*
+ * GETCHARCOUNT FAMILY OF FUNCTIONS
+ */
+
+ /// <summary>
+ /// Entry point from <see cref="DecoderNLS.GetCharCount"/>.
+ /// </summary>
+ internal virtual unsafe int GetCharCount(byte* pBytes, int byteCount, DecoderNLS decoder)
+ {
+ Debug.Assert(decoder != null, "This code path should only be called from DecoderNLS.");
+ Debug.Assert(byteCount >= 0, "Caller should've checked this condition.");
+ Debug.Assert(pBytes != null || byteCount == 0, "Cannot provide a null pointer and a non-zero count.");
+
+ // We're going to try to stay on the fast-path as much as we can. That means that we have
+ // no leftover data to drain and the entire source buffer can be consumed in a single
+ // fast-path invocation. If either of these doesn't hold, we'll go down the slow path of
+ // creating spans, draining the DecoderNLS instance, and falling back.
+
+ Debug.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0, "Fallback buffer can't hold data between GetChars invocations.");
+
+ int totalCharCount = 0;
+ int bytesConsumed = 0;
+
+ if (!decoder.HasLeftoverData)
+ {
+ totalCharCount = GetCharCountFast(pBytes, byteCount, decoder.Fallback, out bytesConsumed);
+ if (bytesConsumed == byteCount)
+ {
+ return totalCharCount;
+ }
+ }
+
+ // We had leftover data, or we couldn't consume the entire input buffer.
+ // Let's go down the draining + fallback mechanisms.
+
+ totalCharCount += GetCharCountWithFallback(pBytes, byteCount, bytesConsumed, decoder);
+ if (totalCharCount < 0)
+ {
+ ThrowConversionOverflow();
+ }
+
+ return totalCharCount;
+ }
+
+ /// <summary>
+ /// Counts the number of <see langword="char"/>s that would result from transcoding the source
+ /// data, exiting when the source buffer is consumed or when the first unreadable data is encountered.
+ /// The implementation may inspect <paramref name="fallback"/> to short-circuit any counting
+ /// operation, but it should not attempt to call <see cref="DecoderFallback.CreateFallbackBuffer"/>.
+ /// </summary>
+ /// <returns>
+ /// Via <paramref name="bytesConsumed"/>, the number of elements from <paramref name="pBytes"/> which
+ /// were consumed; and returns the transcoded char count up to this point.
+ /// </returns>
+ /// <exception cref="ArgumentException">
+ /// If the char count would be greater than <see cref="int.MaxValue"/>.
+ /// (Implementation should call <see cref="ThrowConversionOverflow"/>.)
+ /// </exception>
+ /// <remarks>
+ /// The implementation should not attempt to perform any sort of fallback behavior.
+ /// If custom fallback behavior is necessary, override <see cref="GetCharCountWithFallback"/>.
+ /// </remarks>
+ private protected virtual unsafe int GetCharCountFast(byte* pBytes, int bytesLength, DecoderFallback fallback, out int bytesConsumed)
+ {
+ // Any production-quality type would override this method and provide a real
+ // implementation, so we won't provide a base implementation. However, a
+ // non-shipping slow reference implementation is provided below for convenience.
+
+#if false
+ ReadOnlySpan<byte> bytes = new ReadOnlySpan<byte>(pBytes, bytesLength);
+ int totalCharCount = 0;
+
+ while (!bytes.IsEmpty)
+ {
+ // We don't care about statuses other than Done. The fallback mechanism will handle those.
+
+ if (DecodeFirstRune(bytes, out Rune value, out int bytesConsumedJustNow) != OperationStatus.Done)
+ {
+ break;
+ }
+
+ totalCharCount += value.Utf16SequenceLength;
+ if (totalCharCount < 0)
+ {
+ ThrowConversionOverflow();
+ }
+
+ bytes = bytes.Slice(bytesConsumedJustNow);
+ }
+
+ bytesConsumed = bytesLength - bytes.Length; // number of bytes consumed across all loop iterations above
+ return totalCharCount;
+#else
+ Debug.Fail("This should be overridden by a subclassed type.");
+ throw NotImplemented.ByDesign;
+#endif
+ }
+
+ /// <summary>
+ /// Counts the number of chars that would result from transcoding the provided bytes,
+ /// with no associated <see cref="DecoderNLS"/>. The first two arguments are based on the
+ /// original input before invoking this method; and <paramref name="bytesConsumedSoFar"/>
+ /// signals where in the provided buffer the fallback loop should begin operating.
+ /// </summary>
+ /// <returns>
+ /// The char count resulting from transcoding the input data.
+ /// </returns>
+ /// <exception cref="ArgumentException">
+ /// If the resulting char count is greater than <see cref="int.MaxValue"/>.
+ /// (Implementation should call <see cref="ThrowConversionOverflow"/>.)
+ /// </exception>
+ [MethodImpl(MethodImplOptions.NoInlining)] // don't stack spill spans into our caller
+ private protected unsafe int GetCharCountWithFallback(byte* pBytesOriginal, int originalByteCount, int bytesConsumedSoFar)
+ {
+ // This is a stub method that's marked "no-inlining" so that it we don't stack-spill spans
+ // into our immediate caller. Doing so increases the method prolog in what's supposed to
+ // be a very fast path.
+
+ Debug.Assert(0 <= bytesConsumedSoFar && bytesConsumedSoFar < originalByteCount, "Invalid arguments provided to method.");
+
+ return GetCharCountWithFallback(
+ bytes: new ReadOnlySpan<byte>(pBytesOriginal, originalByteCount).Slice(bytesConsumedSoFar),
+ originalBytesLength: originalByteCount,
+ decoder: null);
+ }
+
+ /// <summary>
+ /// Gets the number of <see langword="char"/>s that would result from transcoding the provided
+ /// input data, with an associated <see cref="DecoderNLS"/>. The first two arguments are
+ /// based on the original input before invoking this method; and <paramref name="bytesConsumedSoFar"/>
+ /// signals where in the provided source buffer the fallback loop should begin operating.
+ /// The behavior of this method is to consume (non-destructively) any leftover data in the
+ /// <see cref="DecoderNLS"/> instance, then to invoke the <see cref="GetCharCountFast"/> virtual method
+ /// after data has been drained, then to call <see cref="GetCharCountWithFallback(ReadOnlySpan{byte}, int, DecoderNLS)"/>.
+ /// </summary>
+ /// <returns>
+ /// The total number of chars that would result from transcoding the remaining portion of the source buffer.
+ /// </returns>
+ /// <exception cref="ArgumentException">
+ /// If the return value would exceed <see cref="int.MaxValue"/>.
+ /// (The implementation should call <see cref="ThrowConversionOverflow"/>.)
+ /// </exception>
+ private unsafe int GetCharCountWithFallback(byte* pOriginalBytes, int originalByteCount, int bytesConsumedSoFar, DecoderNLS decoder)
+ {
+ Debug.Assert(decoder != null, "This code path should only be called from DecoderNLS.");
+ Debug.Assert(0 <= bytesConsumedSoFar && bytesConsumedSoFar < originalByteCount, "Caller should've checked this condition.");
+
+ // First, try draining any data that already exists on the decoder instance. If we can't complete
+ // that operation, there's no point to continuing down to the main workhorse methods.
+
+ ReadOnlySpan<byte> bytes = new ReadOnlySpan<byte>(pOriginalBytes, originalByteCount).Slice(bytesConsumedSoFar);
+
+ int totalCharCount = decoder.DrainLeftoverDataForGetCharCount(bytes, out int bytesConsumedJustNow);
+ bytes = bytes.Slice(bytesConsumedJustNow);
+
+ // Now try invoking the "fast path" (no fallback) implementation.
+ // We can use Unsafe.AsPointer here since these spans are created from pinned data (raw pointers).
+
+ totalCharCount += GetCharCountFast(
+ pBytes: (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(bytes)),
+ bytesLength: bytes.Length,
+ fallback: decoder.Fallback,
+ bytesConsumed: out bytesConsumedJustNow);
+
+ if (totalCharCount < 0)
+ {
+ ThrowConversionOverflow();
+ }
+
+ bytes = bytes.Slice(bytesConsumedJustNow);
+
+ // If there's still data remaining in the source buffer, go down the fallback path.
+ // Otherwise we're finished.
+
+ if (!bytes.IsEmpty)
+ {
+ totalCharCount += GetCharCountWithFallback(bytes, originalByteCount, decoder);
+ if (totalCharCount < 0)
+ {
+ ThrowConversionOverflow();
+ }
+ }
+
+ return totalCharCount;
+ }
+
+ /// <summary>
+ /// Counts the number of chars that would result from transcoding the provided bytes,
+ /// using the provided <see cref="DecoderFallbackBuffer"/> if necessary.
+ /// </summary>
+ /// <returns>
+ /// The char count resulting from transcoding the input data.
+ /// </returns>
+ /// <exception cref="ArgumentException">
+ /// If the resulting char count is greater than <see cref="int.MaxValue"/>.
+ /// (Implementation should call <see cref="ThrowConversionOverflow"/>.)
+ /// </exception>
+ private unsafe int GetCharCountWithFallback(ReadOnlySpan<byte> bytes, int originalBytesLength, DecoderNLS decoder)
+ {
+ Debug.Assert(!bytes.IsEmpty, "Caller shouldn't invoke this method with an empty input buffer.");
+ Debug.Assert(originalBytesLength >= 0, "Caller provided invalid parameter.");
+
+ // Since we're using Unsafe.AsPointer in our central loop, we want to ensure everything is pinned.
+
+ fixed (byte* _pBytes_Unused = &MemoryMarshal.GetReference(bytes))
+ {
+ DecoderFallbackBuffer fallbackBuffer = DecoderFallbackBuffer.CreateAndInitialize(this, decoder, originalBytesLength);
+ int totalCharCount = 0;
+
+ do
+ {
+ // There's still data in the source buffer; why wasn't the previous fast-path able to consume it fully?
+ // There are two scenarios: (a) the source buffer contained invalid data, or it contained incomplete data.
+
+ if (DecodeFirstRune(bytes, out Rune firstScalarValue, out int bytesConsumedThisIteration) == OperationStatus.NeedMoreData
+ && decoder != null
+ && !decoder.MustFlush)
+ {
+ // We saw incomplete data at the end of the buffer, and the active DecoderNLS isntance
+ // isn't asking us to flush. Since a call to GetChars would've consumed this data by
+ // storing it in the DecoderNLS instance, we'll "consume" it by ignoring it.
+ // The next call to GetChars will pick it up correctly.
+
+ goto Finish;
+ }
+
+ // We saw invalid binary data, or we saw incomplete data that we need to flush (and thus
+ // treat as invalid). In any case we'll run through the fallback mechanism.
+
+ int charCountThisIteration = fallbackBuffer.InternalFallbackGetCharCount(bytes, bytesConsumedThisIteration);
+
+ Debug.Assert(charCountThisIteration >= 0, "Fallback shouldn't have returned a negative value.");
+
+ totalCharCount += charCountThisIteration;
+ if (totalCharCount < 0)
+ {
+ ThrowConversionOverflow();
+ }
+
+ bytes = bytes.Slice(bytesConsumedThisIteration);
+
+ if (!bytes.IsEmpty)
+ {
+ // Still data remaining - run it through the fast-path to find the next data to fallback.
+ // While building up the tally we need to continually check for integer overflow
+ // since fallbacks can change the total byte count in unexpected ways.
+
+ charCountThisIteration = GetCharCountFast(
+ pBytes: (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(bytes)),
+ bytesLength: bytes.Length,
+ fallback: null, // wasn't able to be short-circuited by our caller; don't bother trying again
+ bytesConsumed: out bytesConsumedThisIteration);
+
+ Debug.Assert(charCountThisIteration >= 0, "Workhorse shouldn't have returned a negative value.");
+ Debug.Assert(bytesConsumedThisIteration >= 0, "Workhorse shouldn't have returned a negative value.");
+
+ totalCharCount += charCountThisIteration;
+ if (totalCharCount < 0)
+ {
+ ThrowConversionOverflow();
+ }
+
+ bytes = bytes.Slice(bytesConsumedThisIteration);
+ }
+ } while (!bytes.IsEmpty);
+
+ Finish:
+
+ Debug.Assert(fallbackBuffer.Remaining == 0, "There should be no data in the fallback buffer after GetCharCount.");
+
+ return totalCharCount;
+ }
+ }
+
+ /*
+ * GETCHARS FAMILY OF FUNCTIONS
+ */
+
+ /// <summary>
+ /// Entry point from <see cref="DecoderNLS.GetChars"/> and <see cref="DecoderNLS.Convert"/>.
+ /// </summary>
+ internal virtual unsafe int GetChars(byte* pBytes, int byteCount, char* pChars, int charCount, DecoderNLS decoder)
+ {
+ Debug.Assert(decoder != null, "This code path should only be called from DecoderNLS.");
+ Debug.Assert(byteCount >= 0, "Caller should've checked this condition.");
+ Debug.Assert(pBytes != null || byteCount == 0, "Cannot provide a null pointer and a non-zero count.");
+ Debug.Assert(charCount >= 0, "Caller should've checked this condition.");
+ Debug.Assert(pChars != null || charCount == 0, "Cannot provide a null pointer and a non-zero count.");
+
+ // We're going to try to stay on the fast-path as much as we can. That means that we have
+ // no leftover data to drain and the entire source buffer can be transcoded in a single
+ // fast-path invocation. If either of these doesn't hold, we'll go down the slow path of
+ // creating spans, draining the DecoderNLS instance, and falling back.
+
+ int charsWritten = 0;
+ int bytesConsumed = 0;
+
+ if (!decoder.HasLeftoverData)
+ {
+ charsWritten = GetCharsFast(pBytes, byteCount, pChars, charCount, out bytesConsumed);
+ if (bytesConsumed == byteCount)
+ {
+ decoder._bytesUsed = byteCount;
+ return charsWritten;
+ }
+ }
+
+ // We had leftover data, or we couldn't consume the entire input buffer.
+ // Let's go down the draining + fallback mechanisms.
+
+ return GetCharsWithFallback(pBytes, byteCount, pChars, charCount, bytesConsumed, charsWritten, decoder);
+ }
+
+ /// <summary>
+ /// Transcodes <see langword="byte"/>s to <see langword="char"/>s, exiting when the source or destination
+ /// buffer is consumed or when the first unreadable data is encountered.
+ /// </summary>
+ /// <returns>
+ /// Via <paramref name="bytesConsumed"/>, the number of elements from <paramref name="pBytes"/> which
+ /// were consumed; and returns the number of elements written to <paramref name="pChars"/>.
+ /// </returns>
+ /// <remarks>
+ /// The implementation should not attempt to perform any sort of fallback behavior.
+ /// If custom fallback behavior is necessary, override <see cref="GetCharsWithFallback"/>.
+ /// </remarks>
+ private protected virtual unsafe int GetCharsFast(byte* pBytes, int bytesLength, char* pChars, int charsLength, out int bytesConsumed)
+ {
+ // Any production-quality type would override this method and provide a real
+ // implementation, so we won't provide a base implementation. However, a
+ // non-shipping slow reference implementation is provided below for convenience.
+
+#if false
+ ReadOnlySpan<byte> bytes = new ReadOnlySpan<byte>(pBytes, bytesLength);
+ Span<char> chars = new Span<char>(pChars, charsLength);
+
+ while (!bytes.IsEmpty)
+ {
+ if ((DecodeFirstRune(bytes, out Rune firstScalarValue, out int bytesConsumedJustNow) != OperationStatus.Done)
+ || !firstScalarValue.TryEncode(chars, out int charsWrittenJustNow))
+ {
+ // Invalid or incomplete binary data, or destination buffer too small to contain decoded value
+
+ break;
+ }
+
+ bytes = bytes.Slice(bytesConsumedJustNow);
+ chars = chars.Slice(charsWrittenJustNow);
+ }
+
+ bytesConsumed = bytesLength - bytes.Length; // number of bytes consumed across all loop iterations above
+ return charsLength - chars.Length; // number of chars written across all loop iterations above
+#else
+ Debug.Fail("This should be overridden by a subclassed type.");
+ throw NotImplemented.ByDesign;
+#endif
+ }
+
+ /// <summary>
+ /// Transcodes bytes to chars, with no associated <see cref="DecoderNLS"/>. The first four arguments are
+ /// based on the original input before invoking this method; and <paramref name="bytesConsumedSoFar"/>
+ /// and <paramref name="charsWrittenSoFar"/> signal where in the provided buffers the fallback loop
+ /// should begin operating. The behavior of this method is to call the <see cref="GetCharsWithFallback"/>
+ /// virtual method as overridden by the specific type, and failing that go down the shared fallback path.
+ /// </summary>
+ /// <returns>
+ /// The total number of chars written to <paramref name="pOriginalChars"/>, including <paramref name="charsWrittenSoFar"/>.
+ /// </returns>
+ /// <exception cref="ArgumentException">
+ /// If the destination buffer is not large enough to hold the entirety of the transcoded data.
+ /// </exception>
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private protected unsafe int GetCharsWithFallback(byte* pOriginalBytes, int originalByteCount, char* pOriginalChars, int originalCharCount, int bytesConsumedSoFar, int charsWrittenSoFar)
+ {
+ // This is a stub method that's marked "no-inlining" so that it we don't stack-spill spans
+ // into our immediate caller. Doing so increases the method prolog in what's supposed to
+ // be a very fast path.
+
+ Debug.Assert(0 <= bytesConsumedSoFar && bytesConsumedSoFar < originalByteCount, "Invalid arguments provided to method.");
+ Debug.Assert(0 <= charsWrittenSoFar && charsWrittenSoFar <= originalCharCount, "Invalid arguments provided to method.");
+
+ return GetCharsWithFallback(
+ bytes: new ReadOnlySpan<byte>(pOriginalBytes, originalByteCount).Slice(bytesConsumedSoFar),
+ originalBytesLength: originalByteCount,
+ chars: new Span<char>(pOriginalChars, originalCharCount).Slice(charsWrittenSoFar),
+ originalCharsLength: originalCharCount,
+ decoder: null);
+ }
+
+ /// <summary>
+ /// Transcodes bytes to chars, with an associated <see cref="DecoderNLS"/>. The first four arguments are
+ /// based on the original input before invoking this method; and <paramref name="bytesConsumedSoFar"/>
+ /// and <paramref name="charsWrittenSoFar"/> signal where in the provided buffers the fallback loop
+ /// should begin operating. The behavior of this method is to drain any leftover data in the
+ /// <see cref="DecoderNLS"/> instance, then to invoke the <see cref="GetCharsFast"/> virtual method
+ /// after data has been drained, then to call <see cref="GetCharsWithFallback(ReadOnlySpan{byte}, int, Span{char}, int, DecoderNLS)"/>.
+ /// </summary>
+ /// <returns>
+ /// The total number of chars written to <paramref name="pOriginalChars"/>, including <paramref name="charsWrittenSoFar"/>.
+ /// </returns>
+ /// <exception cref="ArgumentException">
+ /// If the destination buffer is too small to make any forward progress at all, or if the destination buffer is
+ /// too small to contain the entirety of the transcoded data and the <see cref="DecoderNLS"/> instance disallows
+ /// partial transcoding.
+ /// </exception>
+ private protected unsafe int GetCharsWithFallback(byte* pOriginalBytes, int originalByteCount, char* pOriginalChars, int originalCharCount, int bytesConsumedSoFar, int charsWrittenSoFar, DecoderNLS decoder)
+ {
+ Debug.Assert(decoder != null, "This code path should only be called from DecoderNLS.");
+ Debug.Assert(0 <= bytesConsumedSoFar && bytesConsumedSoFar < originalByteCount, "Caller should've checked this condition.");
+ Debug.Assert(0 <= charsWrittenSoFar && charsWrittenSoFar <= originalCharCount, "Caller should've checked this condition.");
+
+ // First, try draining any data that already exists on the encoder instance. If we can't complete
+ // that operation, there's no point to continuing down to the main workhorse methods.
+ //
+ // Like GetBytes, there may be leftover data in the DecoderNLS instance. But unlike GetBytes,
+ // the bytes -> chars conversion doesn't allow leftover data in the fallback buffer. This means
+ // that the drain operation below will either succeed fully or fail; there's no partial success
+ // condition as with the chars -> bytes conversion. The drain method will throw if there's not
+ // enough space in the destination buffer.
+
+ ReadOnlySpan<byte> bytes = new ReadOnlySpan<byte>(pOriginalBytes, originalByteCount).Slice(bytesConsumedSoFar);
+ Span<char> chars = new Span<char>(pOriginalChars, originalCharCount).Slice(charsWrittenSoFar);
+
+ int charsWrittenJustNow = decoder.DrainLeftoverDataForGetChars(bytes, chars, out int bytesConsumedJustNow);
+
+ bytes = bytes.Slice(bytesConsumedJustNow);
+ chars = chars.Slice(charsWrittenJustNow);
+
+ Debug.Assert(!decoder.InternalHasFallbackBuffer || decoder.FallbackBuffer.Remaining == 0, "Should be no remaining fallback data at this point.");
+
+ // Now try invoking the "fast path" (no fallback buffer) implementation.
+ // We can use Unsafe.AsPointer here since these spans are created from pinned data (raw pointers).
+
+ charsWrittenJustNow = GetCharsFast(
+ pBytes: (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(bytes)),
+ bytesLength: bytes.Length,
+ pChars: (char*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(chars)),
+ charsLength: chars.Length,
+ bytesConsumed: out bytesConsumedJustNow);
+
+ bytes = bytes.Slice(bytesConsumedJustNow);
+ chars = chars.Slice(charsWrittenJustNow);
+
+ // We'll optimistically tell the decoder that we're using everything; the
+ // GetCharsWithFallback method will overwrite this field if necessary.
+
+ decoder._bytesUsed = originalByteCount;
+
+ if (bytes.IsEmpty)
+ {
+ return originalCharCount - chars.Length; // total number of chars written
+ }
+ else
+ {
+ return GetCharsWithFallback(bytes, originalByteCount, chars, originalCharCount, decoder);
+ }
+ }
+
+ /// <summary>
+ /// Transcodes bytes to chars, using <see cref="Encoding.DecoderFallback"/> or <see cref="Decoder.Fallback"/> if needed.
+ /// </summary>
+ /// <returns>
+ /// The total number of chars written to <paramref name="chars"/> (based on <paramref name="originalCharsLength"/>).
+ /// </returns>
+ /// <remarks>
+ /// The derived class should override this method if it might be able to provide a more optimized fallback
+ /// implementation, deferring to the base implementation if needed. This method calls <see cref="ThrowCharsOverflow"/>
+ /// if necessary.
+ /// </remarks>
+ private protected virtual unsafe int GetCharsWithFallback(ReadOnlySpan<byte> bytes, int originalBytesLength, Span<char> chars, int originalCharsLength, DecoderNLS decoder)
+ {
+ Debug.Assert(!bytes.IsEmpty, "Caller shouldn't invoke this method with an empty input buffer.");
+ Debug.Assert(originalBytesLength >= 0, "Caller provided invalid parameter.");
+ Debug.Assert(originalCharsLength >= 0, "Caller provided invalid parameter.");
+
+ // Since we're using Unsafe.AsPointer in our central loop, we want to ensure everything is pinned.
+
+ fixed (byte* _pBytes_Unused = &MemoryMarshal.GetReference(bytes))
+ fixed (char* _pChars_Unused = &MemoryMarshal.GetReference(chars))
+ {
+ DecoderFallbackBuffer fallbackBuffer = DecoderFallbackBuffer.CreateAndInitialize(this, decoder, originalBytesLength);
+
+ do
+ {
+ // There's still data in the source buffer; why wasn't the previous fast-path able to consume it fully?
+ // There are two scenarios: (a) the source buffer contained invalid data, or it contained incomplete data.
+
+ int charsWrittenThisIteration;
+
+ switch (DecodeFirstRune(bytes, out _, out int bytesConsumedThisIteration))
+ {
+ case OperationStatus.NeedMoreData:
+ Debug.Assert(bytesConsumedThisIteration == bytes.Length, "If returning NeedMoreData, should out the entire buffer length as bytes consumed.");
+ if (decoder is null || decoder.MustFlush)
+ {
+ goto case OperationStatus.InvalidData; // see comment in GetCharCountWithFallback
+ }
+ else
+ {
+ decoder.SetLeftoverData(bytes); // squirrel away remaining data and finish
+ bytes = ReadOnlySpan<byte>.Empty;
+ goto Finish;
+ }
+
+ case OperationStatus.InvalidData:
+ if (fallbackBuffer.TryInternalFallbackGetChars(bytes, bytesConsumedThisIteration, chars, out charsWrittenThisIteration))
+ {
+ // We successfully consumed some bytes, sent it through the fallback, and wrote some chars.
+
+ Debug.Assert(charsWrittenThisIteration >= 0, "Fallback shouldn't have returned a negative value.");
+ break;
+ }
+ else
+ {
+ // We generated fallback data, but the destination buffer wasn't large enough to hold it.
+ // Don't mark any of the bytes we ran through the fallback as consumed, and terminate
+ // the loop now and let our caller handle this condition.
+
+ goto Finish;
+ }
+
+ default:
+ goto Finish; // no error on input, so destination must have been too small
+ }
+
+ bytes = bytes.Slice(bytesConsumedThisIteration);
+ chars = chars.Slice(charsWrittenThisIteration);
+
+ if (!bytes.IsEmpty)
+ {
+ // Still data remaining - run it through the fast-path to find the next data to fallback.
+ // We need to figure out why we weren't able to make progress.
+
+ charsWrittenThisIteration = GetCharsFast(
+ pBytes: (byte*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(bytes)),
+ bytesLength: bytes.Length,
+ pChars: (char*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(chars)),
+ charsLength: chars.Length,
+ bytesConsumed: out bytesConsumedThisIteration);
+
+ Debug.Assert(charsWrittenThisIteration >= 0, "Workhorse shouldn't have returned a negative value.");
+ Debug.Assert(bytesConsumedThisIteration >= 0, "Workhorse shouldn't have returned a negative value.");
+
+ bytes = bytes.Slice(bytesConsumedThisIteration);
+ chars = chars.Slice(charsWrittenThisIteration);
+ }
+ } while (!bytes.IsEmpty);
+
+ Finish:
+
+ // We reach this point when we deplete the source or destination buffer. See main comment
+ // at the end of GetBytesWithFallback for how the below logic works; the primary difference
+ // here is that GetChars disallows leftover data in the fallback buffer between calls.
+
+ Debug.Assert(fallbackBuffer.Remaining == 0);
+
+ if (!bytes.IsEmpty)
+ {
+ // The line below will also throw if the decoder couldn't make any progress at all
+ // because the output buffer wasn't large enough to contain the result of even
+ // a single scalar conversion or fallback.
+
+ ThrowCharsOverflow(decoder, nothingDecoded: chars.Length == originalCharsLength);
+ }
+
+ // If a DecoderNLS instance is active, update its "total consumed byte count" value.
+
+ if (decoder != null)
+ {
+ Debug.Assert(originalBytesLength >= bytes.Length, "About to report a negative number of bytes used?");
+ decoder._bytesUsed = originalBytesLength - bytes.Length; // number of bytes consumed
+ }
+
+ return originalCharsLength - chars.Length; // total number of chars written
+ }
+ }
+ }
+}
diff --git a/src/System.Private.CoreLib/shared/System/Text/Encoding.cs b/src/System.Private.CoreLib/shared/System/Text/Encoding.cs
index 175e5442fd..8947b7fca0 100644
--- a/src/System.Private.CoreLib/shared/System/Text/Encoding.cs
+++ b/src/System.Private.CoreLib/shared/System/Text/Encoding.cs
@@ -3,11 +3,8 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
-using System.Globalization;
-using System.Threading;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
-using System.Diagnostics.CodeAnalysis;
namespace System.Text
{
@@ -74,7 +71,7 @@ namespace System.Text
// generally executes faster.
//
- public abstract class Encoding : ICloneable
+ public abstract partial class Encoding : ICloneable
{
// For netcore we use UTF8 as default encoding since ANSI isn't available
private static readonly UTF8Encoding.UTF8EncodingSealed s_defaultEncoding = new UTF8Encoding.UTF8EncodingSealed(encoderShouldEmitUTF8Identifier: false);
@@ -559,13 +556,16 @@ namespace System.Text
return newEncoding;
}
-
public bool IsReadOnly
{
get
{
return (_isReadOnly);
}
+ private protected set
+ {
+ _isReadOnly = value;
+ }
}
// Returns an encoding for the ASCII character set. The returned encoding
@@ -666,16 +666,6 @@ namespace System.Text
}
}
- // For NLS Encodings, workhorse takes an encoder (may be null)
- // Always validate parameters before calling internal version, which will only assert.
- internal virtual unsafe int GetByteCount(char* chars, int count, EncoderNLS encoder)
- {
- Debug.Assert(chars != null);
- Debug.Assert(count >= 0);
-
- return GetByteCount(chars, count);
- }
-
// Returns a byte array containing the encoded representation of the given
// character array.
//
@@ -772,14 +762,6 @@ namespace System.Text
return GetBytes(s.ToCharArray(), charIndex, charCount, bytes, byteIndex);
}
- // This is our internal workhorse
- // Always validate parameters before calling internal version, which will only assert.
- internal virtual unsafe int GetBytes(char* chars, int charCount,
- byte* bytes, int byteCount, EncoderNLS encoder)
- {
- return GetBytes(chars, charCount, bytes, byteCount);
- }
-
// We expect this to be the workhorse for NLS Encodings, but for existing
// ones we need a working (if slow) default implementation)
//
@@ -898,13 +880,6 @@ namespace System.Text
}
}
- // This is our internal workhorse
- // Always validate parameters before calling internal version, which will only assert.
- internal virtual unsafe int GetCharCount(byte* bytes, int count, DecoderNLS decoder)
- {
- return GetCharCount(bytes, count);
- }
-
// Returns a character array containing the decoded representation of a
// given byte array.
//
@@ -1011,15 +986,6 @@ namespace System.Text
}
}
- // This is our internal workhorse
- // Always validate parameters before calling internal version, which will only assert.
- internal virtual unsafe int GetChars(byte* bytes, int byteCount,
- char* chars, int charCount, DecoderNLS decoder)
- {
- return GetChars(bytes, byteCount, chars, charCount);
- }
-
-
[CLSCompliant(false)]
public unsafe string GetString(byte* bytes, int byteCount)
{
@@ -1238,6 +1204,12 @@ namespace System.Text
encoder.ClearMustFlush();
}
+ [StackTraceHidden]
+ internal static void ThrowConversionOverflow()
+ {
+ throw new ArgumentException(SR.Argument_ConversionOverflow);
+ }
+
internal void ThrowCharsOverflow()
{
// Special message to include fallback type in case fallback's GetMaxCharCount is broken
diff --git a/src/System.Private.CoreLib/shared/System/Text/EncodingNLS.cs b/src/System.Private.CoreLib/shared/System/Text/EncodingNLS.cs
index e6fa0627d3..51d0e66044 100644
--- a/src/System.Private.CoreLib/shared/System/Text/EncodingNLS.cs
+++ b/src/System.Private.CoreLib/shared/System/Text/EncodingNLS.cs
@@ -4,6 +4,7 @@
using System;
using System.Collections;
+using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Threading;
@@ -27,6 +28,7 @@ namespace System.Text
{
protected EncodingNLS(int codePage) : base(codePage)
{
+ Debug.Assert(GetType() == typeof(Latin1Encoding), "Should be no instantiations of this type except via Latin1Encoding.");
}
// Returns the number of bytes required to encode a range of characters in
diff --git a/src/System.Private.CoreLib/shared/System/Text/ValueStringBuilder.cs b/src/System.Private.CoreLib/shared/System/Text/ValueStringBuilder.cs
index 963e45825c..31f51ce53e 100644
--- a/src/System.Private.CoreLib/shared/System/Text/ValueStringBuilder.cs
+++ b/src/System.Private.CoreLib/shared/System/Text/ValueStringBuilder.cs
@@ -45,7 +45,7 @@ namespace System.Text
public void EnsureCapacity(int capacity)
{
if (capacity > _chars.Length)
- Grow(capacity - _chars.Length);
+ Grow(capacity - _pos);
}
/// <summary>
@@ -259,12 +259,21 @@ namespace System.Text
Append(c);
}
+ /// <summary>
+ /// Resize the internal buffer either by doubling current buffer size or
+ /// by adding <paramref name="additionalCapacityBeyondPos"/> to
+ /// <see cref="_pos"/> whichever is greater.
+ /// </summary>
+ /// <param name="additionalCapacityBeyondPos">
+ /// Number of chars requested beyond current position.
+ /// </param>
[MethodImpl(MethodImplOptions.NoInlining)]
- private void Grow(int requiredAdditionalCapacity)
+ private void Grow(int additionalCapacityBeyondPos)
{
- Debug.Assert(requiredAdditionalCapacity > 0);
+ Debug.Assert(additionalCapacityBeyondPos > 0);
+ Debug.Assert(_pos > _chars.Length - additionalCapacityBeyondPos, "Grow called incorrectly, no resize is needed.");
- char[] poolArray = ArrayPool<char>.Shared.Rent(Math.Max(_pos + requiredAdditionalCapacity, _chars.Length * 2));
+ char[] poolArray = ArrayPool<char>.Shared.Rent(Math.Max(_pos + additionalCapacityBeyondPos, _chars.Length * 2));
_chars.CopyTo(poolArray);
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs
index 4d790f483d..5d893c5cee 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/Task.cs
@@ -131,8 +131,6 @@ namespace System.Threading.Tasks
{
[ThreadStatic]
internal static Task t_currentTask; // The currently executing task.
- [ThreadStatic]
- private static StackGuard t_stackGuard; // The stack guard object for this thread
internal static int s_taskIdCounter; //static counter used to generate unique task IDs
@@ -1258,23 +1256,6 @@ namespace System.Threading.Tasks
}
/// <summary>
- /// Gets the StackGuard object assigned to the current thread.
- /// </summary>
- internal static StackGuard CurrentStackGuard
- {
- get
- {
- StackGuard sg = t_stackGuard;
- if (sg == null)
- {
- t_stackGuard = sg = new StackGuard();
- }
- return sg;
- }
- }
-
-
- /// <summary>
/// Gets the <see cref="T:System.AggregateException">Exception</see> that caused the <see
/// cref="Task">Task</see> to end prematurely. If the <see
/// cref="Task">Task</see> completed successfully or has not yet thrown any
@@ -3336,7 +3317,9 @@ namespace System.Threading.Tasks
if (AsyncCausalityTracer.LoggingOn)
AsyncCausalityTracer.TraceSynchronousWorkStart(this, CausalitySynchronousWork.CompletionNotification);
- bool canInlineContinuations = (m_stateFlags & (int)TaskCreationOptions.RunContinuationsAsynchronously) == 0;
+ bool canInlineContinuations =
+ (m_stateFlags & (int)TaskCreationOptions.RunContinuationsAsynchronously) == 0 &&
+ RuntimeHelpers.TryEnsureSufficientExecutionStack();
switch (continuationObject)
{
@@ -6485,51 +6468,6 @@ namespace System.Threading.Tasks
ExecuteSynchronously = 0x80000
}
- /// <summary>
- /// Internal helper class to keep track of stack depth and decide whether we should inline or not.
- /// </summary>
- internal class StackGuard
- {
- // current thread's depth of nested inline task executions
- private int m_inliningDepth = 0;
-
- // For relatively small inlining depths we don't want to get into the business of stack probing etc.
- // This clearly leaves a window of opportunity for the user code to SO. However a piece of code
- // that can SO in 20 inlines on a typical 1MB stack size probably needs to be revisited anyway.
- private const int MAX_UNCHECKED_INLINING_DEPTH = 20;
-
- /// <summary>
- /// This method needs to be called before attempting inline execution on the current thread.
- /// If false is returned, it means we are too close to the end of the stack and should give up inlining.
- /// Each call to TryBeginInliningScope() that returns true must be matched with a
- /// call to EndInliningScope() regardless of whether inlining actually took place.
- /// </summary>
- internal bool TryBeginInliningScope()
- {
- // If we're still under the 'safe' limit we'll just skip the stack probe to save p/invoke calls
- if (m_inliningDepth < MAX_UNCHECKED_INLINING_DEPTH || RuntimeHelpers.TryEnsureSufficientExecutionStack())
- {
- m_inliningDepth++;
- return true;
- }
- else
- return false;
- }
-
- /// <summary>
- /// This needs to be called once for each previous successful TryBeginInliningScope() call after
- /// inlining related logic runs.
- /// </summary>
- internal void EndInliningScope()
- {
- m_inliningDepth--;
- Debug.Assert(m_inliningDepth >= 0, "Inlining depth count should never go negative.");
-
- // do the right thing just in case...
- if (m_inliningDepth < 0) m_inliningDepth = 0;
- }
- }
-
// Special internal struct that we use to signify that we are not interested in
// a Task<VoidTaskResult>'s result.
internal struct VoidTaskResult { }
@@ -6609,18 +6547,17 @@ namespace System.Threading.Tasks
// For ITaskCompletionAction
public void Invoke(Task completingTask)
{
- // Check the current stack guard. If we're ok to inline,
- // process the task, and reset the guard when we're done.
- var sg = Task.CurrentStackGuard;
- if (sg.TryBeginInliningScope())
+ // If we're ok to inline, process the task. Otherwise, we're too deep on the stack, and
+ // we shouldn't run the continuation chain here, so queue a work item to call back here
+ // to Invoke asynchronously.
+ if (RuntimeHelpers.TryEnsureSufficientExecutionStack())
+ {
+ InvokeCore(completingTask);
+ }
+ else
{
- try { InvokeCore(completingTask); }
- finally { sg.EndInliningScope(); }
+ InvokeCoreAsync(completingTask);
}
- // Otherwise, we're too deep on the stack, and
- // we shouldn't run the continuation chain here, so queue a work
- // item to call back here to Invoke asynchronously.
- else InvokeCoreAsync(completingTask);
}
/// <summary>
diff --git a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskScheduler.cs b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskScheduler.cs
index f274f20558..1d1a581b0b 100644
--- a/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskScheduler.cs
+++ b/src/System.Private.CoreLib/shared/System/Threading/Tasks/TaskScheduler.cs
@@ -179,12 +179,11 @@ namespace System.Threading.Tasks
// Delegate cross-scheduler inlining requests to target scheduler
if (ets != this && ets != null) return ets.TryRunInline(task, taskWasPreviouslyQueued);
- StackGuard currentStackGuard;
if ((ets == null) ||
(task.m_action == null) ||
task.IsDelegateInvoked ||
task.IsCanceled ||
- (currentStackGuard = Task.CurrentStackGuard).TryBeginInliningScope() == false)
+ !RuntimeHelpers.TryEnsureSufficientExecutionStack())
{
return false;
}
@@ -192,27 +191,19 @@ namespace System.Threading.Tasks
// Task class will still call into TaskScheduler.TryRunInline rather than TryExecuteTaskInline() so that
// 1) we can adjust the return code from TryExecuteTaskInline in case a buggy custom scheduler lies to us
// 2) we maintain a mechanism for the TLS lookup optimization that we used to have for the ConcRT scheduler (will potentially introduce the same for TP)
- bool bInlined = false;
- try
- {
- if (TplEventSource.Log.IsEnabled())
- task.FireTaskScheduledIfNeeded(this);
+ if (TplEventSource.Log.IsEnabled())
+ task.FireTaskScheduledIfNeeded(this);
- bInlined = TryExecuteTaskInline(task, taskWasPreviouslyQueued);
- }
- finally
- {
- currentStackGuard.EndInliningScope();
- }
+ bool inlined = TryExecuteTaskInline(task, taskWasPreviouslyQueued);
// If the custom scheduler returned true, we should either have the TASK_STATE_DELEGATE_INVOKED or TASK_STATE_CANCELED bit set
// Otherwise the scheduler is buggy
- if (bInlined && !(task.IsDelegateInvoked || task.IsCanceled))
+ if (inlined && !(task.IsDelegateInvoked || task.IsCanceled))
{
throw new InvalidOperationException(SR.TaskScheduler_InconsistentStateAfterTryExecuteTaskInline);
}
- return bInlined;
+ return inlined;
}
/// <summary>
diff --git a/src/System.Private.CoreLib/shared/System/ThrowHelper.cs b/src/System.Private.CoreLib/shared/System/ThrowHelper.cs
index cc3906999b..06b3ce41a6 100644
--- a/src/System.Private.CoreLib/shared/System/ThrowHelper.cs
+++ b/src/System.Private.CoreLib/shared/System/ThrowHelper.cs
@@ -366,7 +366,7 @@ namespace System
private static KeyNotFoundException GetKeyNotFoundException(object key)
{
- return new KeyNotFoundException(SR.Format(SR.Arg_KeyNotFoundWithKey, key.ToString()));
+ return new KeyNotFoundException(SR.Format(SR.Arg_KeyNotFoundWithKey, key));
}
private static ArgumentOutOfRangeException GetArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
@@ -452,8 +452,20 @@ namespace System
return "startIndex";
case ExceptionArgument.task:
return "task";
+ case ExceptionArgument.bytes:
+ return "bytes";
+ case ExceptionArgument.byteIndex:
+ return "byteIndex";
+ case ExceptionArgument.byteCount:
+ return "byteCount";
case ExceptionArgument.ch:
return "ch";
+ case ExceptionArgument.chars:
+ return "chars";
+ case ExceptionArgument.charIndex:
+ return "charIndex";
+ case ExceptionArgument.charCount:
+ return "charCount";
case ExceptionArgument.s:
return "s";
case ExceptionArgument.input:
@@ -612,6 +624,10 @@ namespace System
{
case ExceptionResource.ArgumentOutOfRange_Index:
return SR.ArgumentOutOfRange_Index;
+ case ExceptionResource.ArgumentOutOfRange_IndexCount:
+ return SR.ArgumentOutOfRange_IndexCount;
+ case ExceptionResource.ArgumentOutOfRange_IndexCountBuffer:
+ return SR.ArgumentOutOfRange_IndexCountBuffer;
case ExceptionResource.ArgumentOutOfRange_Count:
return SR.ArgumentOutOfRange_Count;
case ExceptionResource.Arg_ArrayPlusOffTooSmall:
@@ -694,6 +710,8 @@ namespace System
return SR.Task_WaitMulti_NullTask;
case ExceptionResource.ArgumentException_OtherNotArrayOfCorrectLength:
return SR.ArgumentException_OtherNotArrayOfCorrectLength;
+ case ExceptionResource.ArgumentNull_Array:
+ return SR.ArgumentNull_Array;
case ExceptionResource.ArgumentNull_SafeHandle:
return SR.ArgumentNull_SafeHandle;
case ExceptionResource.ArgumentOutOfRange_EndIndexStartIndex:
@@ -731,8 +749,7 @@ namespace System
case ExceptionResource.Arg_TypeNotSupported:
return SR.Arg_TypeNotSupported;
default:
- Debug.Assert(false,
- "The enum value is not defined, please check the ExceptionResource Enum.");
+ Debug.Fail("The enum value is not defined, please check the ExceptionResource Enum.");
return "";
}
}
@@ -753,7 +770,13 @@ namespace System
value,
startIndex,
task,
+ bytes,
+ byteIndex,
+ byteCount,
ch,
+ chars,
+ charIndex,
+ charCount,
s,
input,
ownedMemory,
@@ -829,6 +852,8 @@ namespace System
internal enum ExceptionResource
{
ArgumentOutOfRange_Index,
+ ArgumentOutOfRange_IndexCount,
+ ArgumentOutOfRange_IndexCountBuffer,
ArgumentOutOfRange_Count,
Arg_ArrayPlusOffTooSmall,
NotSupported_ReadOnlyCollection,
@@ -870,6 +895,7 @@ namespace System
Task_ThrowIfDisposed,
Task_WaitMulti_NullTask,
ArgumentException_OtherNotArrayOfCorrectLength,
+ ArgumentNull_Array,
ArgumentNull_SafeHandle,
ArgumentOutOfRange_EndIndexStartIndex,
ArgumentOutOfRange_Enum,
diff --git a/src/System.Private.CoreLib/shared/System/Tuple.cs b/src/System.Private.CoreLib/shared/System/Tuple.cs
index bb72e4f0ec..f9111b9b40 100644
--- a/src/System.Private.CoreLib/shared/System/Tuple.cs
+++ b/src/System.Private.CoreLib/shared/System/Tuple.cs
@@ -143,7 +143,7 @@ namespace System
if (!(other is Tuple<T1> objTuple))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, GetType()), nameof(other));
}
return comparer.Compare(m_Item1, objTuple.m_Item1);
@@ -242,7 +242,7 @@ namespace System
if (!(other is Tuple<T1, T2> objTuple))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, GetType()), nameof(other));
}
int c = 0;
@@ -356,7 +356,7 @@ namespace System
if (!(other is Tuple<T1, T2, T3> objTuple))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, GetType()), nameof(other));
}
int c = 0;
@@ -481,7 +481,7 @@ namespace System
if (!(other is Tuple<T1, T2, T3, T4> objTuple))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, GetType()), nameof(other));
}
int c = 0;
@@ -617,7 +617,7 @@ namespace System
if (!(other is Tuple<T1, T2, T3, T4, T5> objTuple))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, GetType()), nameof(other));
}
int c = 0;
@@ -764,7 +764,7 @@ namespace System
if (!(other is Tuple<T1, T2, T3, T4, T5, T6> objTuple))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, GetType()), nameof(other));
}
int c = 0;
@@ -922,7 +922,7 @@ namespace System
if (!(other is Tuple<T1, T2, T3, T4, T5, T6, T7> objTuple))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, GetType()), nameof(other));
}
int c = 0;
@@ -1096,7 +1096,7 @@ namespace System
if (!(other is Tuple<T1, T2, T3, T4, T5, T6, T7, TRest> objTuple))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_TupleIncorrectType, GetType()), nameof(other));
}
int c = 0;
diff --git a/src/System.Private.CoreLib/shared/System/Type.Enum.cs b/src/System.Private.CoreLib/shared/System/Type.Enum.cs
index 4d82410383..84a6482709 100644
--- a/src/System.Private.CoreLib/shared/System/Type.Enum.cs
+++ b/src/System.Private.CoreLib/shared/System/Type.Enum.cs
@@ -32,7 +32,7 @@ namespace System
if (valueType.IsEnum)
{
if (!valueType.IsEquivalentTo(this))
- throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, valueType.ToString(), this.ToString()));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, valueType, this));
valueType = valueType.GetEnumUnderlyingType();
}
@@ -53,7 +53,7 @@ namespace System
Type underlyingType = GetEnumUnderlyingType();
// We cannot compare the types directly because valueType is always a runtime type but underlyingType might not be.
if (underlyingType.GetTypeCodeImpl() != valueType.GetTypeCodeImpl())
- throw new ArgumentException(SR.Format(SR.Arg_EnumUnderlyingTypeAndObjectMustBeSameType, valueType.ToString(), underlyingType.ToString()));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumUnderlyingTypeAndObjectMustBeSameType, valueType, underlyingType));
Array values = GetEnumRawConstantValues();
return (BinarySearch(values, value) >= 0);
diff --git a/src/System.Private.CoreLib/shared/System/ValueTuple.cs b/src/System.Private.CoreLib/shared/System/ValueTuple.cs
index bf00871e5a..fdcead2def 100644
--- a/src/System.Private.CoreLib/shared/System/ValueTuple.cs
+++ b/src/System.Private.CoreLib/shared/System/ValueTuple.cs
@@ -62,7 +62,7 @@ namespace System
if (!(other is ValueTuple))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
return 0;
@@ -87,7 +87,7 @@ namespace System
if (!(other is ValueTuple))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
return 0;
@@ -365,7 +365,7 @@ namespace System
if (!(other is ValueTuple<T1>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
var objTuple = (ValueTuple<T1>)other;
@@ -392,7 +392,7 @@ namespace System
if (!(other is ValueTuple<T1>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
var objTuple = (ValueTuple<T1>)other;
@@ -559,7 +559,7 @@ namespace System
if (!(other is ValueTuple<T1, T2>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
return CompareTo((ValueTuple<T1, T2>)other);
@@ -587,7 +587,7 @@ namespace System
if (!(other is ValueTuple<T1, T2>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
var objTuple = (ValueTuple<T1, T2>)other;
@@ -759,7 +759,7 @@ namespace System
if (!(other is ValueTuple<T1, T2, T3>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
return CompareTo((ValueTuple<T1, T2, T3>)other);
@@ -790,7 +790,7 @@ namespace System
if (!(other is ValueTuple<T1, T2, T3>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
var objTuple = (ValueTuple<T1, T2, T3>)other;
@@ -976,7 +976,7 @@ namespace System
if (!(other is ValueTuple<T1, T2, T3, T4>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
return CompareTo((ValueTuple<T1, T2, T3, T4>)other);
@@ -1010,7 +1010,7 @@ namespace System
if (!(other is ValueTuple<T1, T2, T3, T4>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
var objTuple = (ValueTuple<T1, T2, T3, T4>)other;
@@ -1212,7 +1212,7 @@ namespace System
if (!(other is ValueTuple<T1, T2, T3, T4, T5>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
return CompareTo((ValueTuple<T1, T2, T3, T4, T5>)other);
@@ -1249,7 +1249,7 @@ namespace System
if (!(other is ValueTuple<T1, T2, T3, T4, T5>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
var objTuple = (ValueTuple<T1, T2, T3, T4, T5>)other;
@@ -1467,7 +1467,7 @@ namespace System
if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
return CompareTo((ValueTuple<T1, T2, T3, T4, T5, T6>)other);
@@ -1507,7 +1507,7 @@ namespace System
if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
var objTuple = (ValueTuple<T1, T2, T3, T4, T5, T6>)other;
@@ -1741,7 +1741,7 @@ namespace System
if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
return CompareTo((ValueTuple<T1, T2, T3, T4, T5, T6, T7>)other);
@@ -1784,7 +1784,7 @@ namespace System
if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
var objTuple = (ValueTuple<T1, T2, T3, T4, T5, T6, T7>)other;
@@ -2040,7 +2040,7 @@ namespace System
if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
return CompareTo((ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)other);
@@ -2086,7 +2086,7 @@ namespace System
if (!(other is ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>))
{
- throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, this.GetType().ToString()), nameof(other));
+ throw new ArgumentException(SR.Format(SR.ArgumentException_ValueTupleIncorrectType, GetType()), nameof(other));
}
var objTuple = (ValueTuple<T1, T2, T3, T4, T5, T6, T7, TRest>)other;
diff --git a/src/System.Private.CoreLib/src/System/Buffer.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Buffer.CoreCLR.cs
new file mode 100644
index 0000000000..56f36de771
--- /dev/null
+++ b/src/System.Private.CoreLib/src/System/Buffer.CoreCLR.cs
@@ -0,0 +1,62 @@
+// 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;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+#if BIT64
+using nuint = System.UInt64;
+#else
+using nuint = System.UInt32;
+#endif
+
+namespace System
+{
+ partial class Buffer
+ {
+ // Copies from one primitive array to another primitive array without
+ // respecting types. This calls memmove internally. The count and
+ // offset parameters here are in bytes. If you want to use traditional
+ // array element indices and counts, use Array.Copy.
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern void BlockCopy(Array src, int srcOffset,
+ Array dst, int dstOffset, int count);
+
+ // Returns a bool to indicate if the array is of primitive data types
+ // or not.
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern bool IsPrimitiveTypeArray(Array array);
+
+ // Gets the length of the array in bytes. The array must be an
+ // array of primitives.
+ //
+ // This essentially does the following:
+ // return array.length * sizeof(array.UnderlyingElementType).
+ //
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern int _ByteLength(Array array);
+
+ // This method has a slightly different behavior on arm and other platforms.
+ // On arm this method behaves like memcpy and does not handle overlapping buffers.
+ // While on other platforms it behaves like memmove and handles overlapping buffers.
+ // This behavioral difference is unfortunate but intentional because
+ // 1. This method is given access to other internal dlls and this close to release we do not want to change it.
+ // 2. It is difficult to get this right for arm and again due to release dates we would like to visit it later.
+#if ARM
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern unsafe void Memcpy(byte* dest, byte* src, int len);
+#else // ARM
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ internal static unsafe void Memcpy(byte* dest, byte* src, int len)
+ {
+ Debug.Assert(len >= 0, "Negative length in memcpy!");
+ Memmove(dest, src, (nuint)len);
+ }
+#endif // ARM
+
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
+ private static extern unsafe void __Memmove(byte* dest, byte* src, nuint len);
+ }
+}
diff --git a/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs b/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs
index c03ba4f745..cac4ac1f5d 100644
--- a/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs
+++ b/src/System.Private.CoreLib/src/System/Diagnostics/Eventing/EventPipeController.cs
@@ -212,7 +212,7 @@ namespace System.Diagnostics.Tracing
{
// If set, bail out early if the specified process does not match the current process.
int processID = Convert.ToInt32(strProcessID);
- if (processID != Interop.Kernel32.GetCurrentProcessId())
+ if (processID != (int)Interop.GetCurrentProcessId())
{
return null;
}
@@ -294,7 +294,7 @@ namespace System.Diagnostics.Tracing
private static string BuildTraceFileName()
{
- return GetAppName() + "." + Interop.Kernel32.GetCurrentProcessId().ToString() + NetPerfFileExtension;
+ return GetAppName() + "." + Interop.GetCurrentProcessId().ToString() + NetPerfFileExtension;
}
private static string GetAppName()
diff --git a/src/System.Private.CoreLib/src/System/Enum.cs b/src/System.Private.CoreLib/src/System/Enum.cs
index e085517f58..93c91f2468 100644
--- a/src/System.Private.CoreLib/src/System/Enum.cs
+++ b/src/System.Private.CoreLib/src/System/Enum.cs
@@ -924,7 +924,7 @@ namespace System
if (valueType.IsEnum)
{
if (!valueType.IsEquivalentTo(enumType))
- throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, valueType.ToString(), enumType.ToString()));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, valueType, enumType));
if (format.Length != 1)
{
@@ -938,7 +938,7 @@ namespace System
Type underlyingType = GetUnderlyingType(enumType);
if (valueType != underlyingType)
{
- throw new ArgumentException(SR.Format(SR.Arg_EnumFormatUnderlyingTypeAndObjectMustBeSameType, valueType.ToString(), underlyingType.ToString()));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumFormatUnderlyingTypeAndObjectMustBeSameType, valueType, underlyingType));
}
if (format.Length == 1)
@@ -1156,7 +1156,7 @@ namespace System
Type thisType = this.GetType();
Type targetType = target.GetType();
- throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, targetType.ToString(), thisType.ToString()));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, targetType, thisType));
}
else
{
diff --git a/src/System.Private.CoreLib/src/System/GC.cs b/src/System.Private.CoreLib/src/System/GC.cs
index 98266b3349..4485afe469 100644
--- a/src/System.Private.CoreLib/src/System/GC.cs
+++ b/src/System.Private.CoreLib/src/System/GC.cs
@@ -350,8 +350,7 @@ namespace System
if ((maxGenerationThreshold <= 0) || (maxGenerationThreshold >= 100))
{
throw new ArgumentOutOfRangeException(nameof(maxGenerationThreshold),
- string.Format(
- CultureInfo.CurrentCulture,
+ SR.Format(
SR.ArgumentOutOfRange_Bounds_Lower_Upper,
1,
99));
@@ -360,8 +359,7 @@ namespace System
if ((largeObjectHeapThreshold <= 0) || (largeObjectHeapThreshold >= 100))
{
throw new ArgumentOutOfRangeException(nameof(largeObjectHeapThreshold),
- string.Format(
- CultureInfo.CurrentCulture,
+ SR.Format(
SR.ArgumentOutOfRange_Bounds_Lower_Upper,
1,
99));
diff --git a/src/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs b/src/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs
index b839ddb52d..ef593b974d 100644
--- a/src/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs
+++ b/src/System.Private.CoreLib/src/System/IO/FileLoadException.CoreCLR.cs
@@ -32,7 +32,7 @@ namespace System.IO
else
GetMessageForHR(hResult, JitHelpers.GetStringHandleOnStack(ref message));
- return string.Format(CultureInfo.CurrentCulture, format, fileName, message);
+ return string.Format(format, fileName, message);
}
[DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode)]
diff --git a/src/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs b/src/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs
index 00f9db1ce2..e4d86f45dd 100644
--- a/src/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs
+++ b/src/System.Private.CoreLib/src/System/Reflection/CustomAttribute.cs
@@ -427,13 +427,13 @@ namespace System.Reflection
{
string ctorArgs = "";
for (int i = 0; i < ConstructorArguments.Count; i++)
- ctorArgs += string.Format(CultureInfo.CurrentCulture, i == 0 ? "{0}" : ", {0}", ConstructorArguments[i]);
+ ctorArgs += string.Format(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]);
+ namedArgs += string.Format(i == 0 && ctorArgs.Length == 0 ? "{0}" : ", {0}", NamedArguments[i]);
- return string.Format(CultureInfo.CurrentCulture, "[{0}({1}{2})]", Constructor.DeclaringType.FullName, ctorArgs, namedArgs);
+ return string.Format("[{0}({1}{2})]", Constructor.DeclaringType.FullName, ctorArgs, namedArgs);
}
public override int GetHashCode() => base.GetHashCode();
public override bool Equals(object obj) => obj == (object)this;
@@ -548,7 +548,7 @@ namespace System.Reflection
if (m_memberInfo == null)
return base.ToString();
- return string.Format(CultureInfo.CurrentCulture, "{0} = {1}", MemberInfo.Name, TypedValue.ToString(ArgumentType != typeof(object)));
+ return string.Format("{0} = {1}", MemberInfo.Name, TypedValue.ToString(ArgumentType != typeof(object)));
}
public override int GetHashCode()
{
@@ -694,7 +694,7 @@ namespace System.Reflection
if (type == null)
throw new InvalidOperationException(
- string.Format(CultureInfo.CurrentUICulture, SR.Arg_CATypeResolutionFailed, typeName));
+ SR.Format(SR.Arg_CATypeResolutionFailed, typeName));
return type;
}
@@ -806,30 +806,30 @@ namespace System.Reflection
return base.ToString();
if (ArgumentType.IsEnum)
- return string.Format(CultureInfo.CurrentCulture, typed ? "{0}" : "({1}){0}", Value, ArgumentType.FullName);
+ return string.Format(typed ? "{0}" : "({1}){0}", Value, ArgumentType.FullName);
else if (Value == null)
- return string.Format(CultureInfo.CurrentCulture, typed ? "null" : "({0})null", ArgumentType.Name);
+ return string.Format(typed ? "null" : "({0})null", ArgumentType.Name);
else if (ArgumentType == typeof(string))
- return string.Format(CultureInfo.CurrentCulture, "\"{0}\"", Value);
+ return string.Format("\"{0}\"", Value);
else if (ArgumentType == typeof(char))
- return string.Format(CultureInfo.CurrentCulture, "'{0}'", Value);
+ return string.Format("'{0}'", Value);
else if (ArgumentType == typeof(Type))
- return string.Format(CultureInfo.CurrentCulture, "typeof({0})", ((Type)Value).FullName);
+ return string.Format("typeof({0})", ((Type)Value).FullName);
else if (ArgumentType.IsArray)
{
IList<CustomAttributeTypedArgument> array = (IList<CustomAttributeTypedArgument>)Value;
Type elementType = ArgumentType.GetElementType();
- string result = string.Format(CultureInfo.CurrentCulture, @"new {0}[{1}] {{ ", elementType.IsEnum ? elementType.FullName : elementType.Name, array.Count);
+ string result = string.Format(@"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)));
+ result += string.Format(i == 0 ? "{0}" : ", {0}", array[i].ToString(elementType != typeof(object)));
}
result += " }";
@@ -837,7 +837,7 @@ namespace System.Reflection
return result;
}
- return string.Format(CultureInfo.CurrentCulture, typed ? "{0}" : "({1}){0}", Value, ArgumentType.Name);
+ return string.Format(typed ? "{0}" : "({1}){0}", Value, ArgumentType.Name);
}
public override int GetHashCode() => base.GetHashCode();
@@ -1450,8 +1450,7 @@ namespace System.Reflection
if (property == null)
{
throw new CustomAttributeFormatException(
- string.Format(CultureInfo.CurrentUICulture,
- SR.RFLCT_InvalidPropFail, name));
+ SR.Format(SR.RFLCT_InvalidPropFail, name));
}
MethodInfo setMethod = property.GetSetMethod(true);
@@ -1473,8 +1472,7 @@ namespace System.Reflection
catch (Exception e)
{
throw new CustomAttributeFormatException(
- string.Format(CultureInfo.CurrentUICulture,
- isProperty ? SR.RFLCT_InvalidPropFail : SR.RFLCT_InvalidFieldFail, name), e);
+ SR.Format(isProperty ? SR.RFLCT_InvalidPropFail : SR.RFLCT_InvalidFieldFail, name), e);
}
}
@@ -1640,8 +1638,7 @@ namespace System.Reflection
continue;
if (attributeUsageAttribute != null)
- throw new FormatException(string.Format(
- CultureInfo.CurrentUICulture, SR.Format_AttributeUsage, attributeType));
+ throw new FormatException(SR.Format(SR.Format_AttributeUsage, attributeType));
ParseAttributeUsageAttribute(caRecord.blob, out AttributeTargets targets, out bool inherited, out bool allowMultiple);
attributeUsageAttribute = new AttributeUsageAttribute(targets, allowMultiple, inherited);
diff --git a/src/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs b/src/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs
index e02002e4bd..c3da6cc3d9 100644
--- a/src/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs
+++ b/src/System.Private.CoreLib/src/System/Reflection/Emit/CustomAttributeBuilder.cs
@@ -301,7 +301,7 @@ namespace System.Reflection.Emit
}
if (passedType == typeof(IntPtr) || passedType == typeof(UIntPtr))
{
- throw new ArgumentException(SR.Format(SR.Argument_BadParameterTypeForCAB, passedType.ToString()), paramName);
+ throw new ArgumentException(SR.Format(SR.Argument_BadParameterTypeForCAB, passedType), paramName);
}
}
@@ -524,7 +524,7 @@ namespace System.Reflection.Emit
// 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(SR.Format(SR.Argument_BadParameterTypeForCAB, ot.ToString()));
+ throw new ArgumentException(SR.Format(SR.Argument_BadParameterTypeForCAB, ot));
EmitType(writer, ot);
EmitValue(writer, ot, value);
diff --git a/src/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs b/src/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs
index c0712822e4..b47b305057 100644
--- a/src/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs
+++ b/src/System.Private.CoreLib/src/System/Reflection/Emit/DynamicILGenerator.cs
@@ -1064,8 +1064,7 @@ namespace System.Reflection.Emit
MethodBase m = RuntimeType.GetMethodBase(methodReal);
Type t = m.DeclaringType.GetGenericTypeDefinition();
- throw new ArgumentException(string.Format(
- CultureInfo.CurrentCulture, SR.Argument_MethodDeclaringTypeGenericLcg, m, t));
+ throw new ArgumentException(SR.Format(SR.Argument_MethodDeclaringTypeGenericLcg, m, t));
}
}
diff --git a/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs b/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs
index 8eba214c08..e611c604d7 100644
--- a/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs
+++ b/src/System.Private.CoreLib/src/System/Reflection/Emit/TypeBuilder.cs
@@ -384,7 +384,7 @@ namespace System.Reflection.Emit
}
else
{
- throw new ArgumentException(SR.Format(SR.Argument_ConstantNotSupported, type.ToString()));
+ throw new ArgumentException(SR.Format(SR.Argument_ConstantNotSupported, type));
}
break;
}
diff --git a/src/System.Private.CoreLib/src/System/Reflection/FieldInfo.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Reflection/FieldInfo.CoreCLR.cs
index 56f457848b..24f0c480b8 100644
--- a/src/System.Private.CoreLib/src/System/Reflection/FieldInfo.CoreCLR.cs
+++ b/src/System.Private.CoreLib/src/System/Reflection/FieldInfo.CoreCLR.cs
@@ -17,8 +17,8 @@ namespace System.Reflection
Type declaringType = f.DeclaringType;
if (declaringType != null && declaringType.IsGenericType)
- throw new ArgumentException(string.Format(
- CultureInfo.CurrentCulture, SR.Argument_FieldDeclaringTypeGeneric,
+ throw new ArgumentException(SR.Format(
+ SR.Argument_FieldDeclaringTypeGeneric,
f.Name, declaringType.GetGenericTypeDefinition()));
return f;
diff --git a/src/System.Private.CoreLib/src/System/Reflection/MdImport.cs b/src/System.Private.CoreLib/src/System/Reflection/MdImport.cs
index 792662efb2..3277bb0210 100644
--- a/src/System.Private.CoreLib/src/System/Reflection/MdImport.cs
+++ b/src/System.Private.CoreLib/src/System/Reflection/MdImport.cs
@@ -629,7 +629,7 @@ namespace System.Reflection
public override string ToString()
{
- return string.Format(CultureInfo.CurrentCulture, "MetadataException HResult = {0:x}.", m_hr);
+ return string.Format("MetadataException HResult = {0:x}.", m_hr);
}
}
}
diff --git a/src/System.Private.CoreLib/src/System/Reflection/MethodBase.CoreCLR.cs b/src/System.Private.CoreLib/src/System/Reflection/MethodBase.CoreCLR.cs
index 4f6547499b..477fe32ccd 100644
--- a/src/System.Private.CoreLib/src/System/Reflection/MethodBase.CoreCLR.cs
+++ b/src/System.Private.CoreLib/src/System/Reflection/MethodBase.CoreCLR.cs
@@ -20,8 +20,8 @@ namespace System.Reflection
Type declaringType = m.DeclaringType;
if (declaringType != null && declaringType.IsGenericType)
- throw new ArgumentException(string.Format(
- CultureInfo.CurrentCulture, SR.Argument_MethodDeclaringTypeGeneric,
+ throw new ArgumentException(SR.Format(
+ SR.Argument_MethodDeclaringTypeGeneric,
m, declaringType.GetGenericTypeDefinition()));
return m;
diff --git a/src/System.Private.CoreLib/src/System/Reflection/RtFieldInfo.cs b/src/System.Private.CoreLib/src/System/Reflection/RtFieldInfo.cs
index 47b519493e..8514fb7e0f 100644
--- a/src/System.Private.CoreLib/src/System/Reflection/RtFieldInfo.cs
+++ b/src/System.Private.CoreLib/src/System/Reflection/RtFieldInfo.cs
@@ -102,7 +102,7 @@ namespace System.Reflection
else
{
throw new ArgumentException(
- string.Format(CultureInfo.CurrentUICulture, SR.Arg_FieldDeclTarget,
+ SR.Format(SR.Arg_FieldDeclTarget,
Name, m_declaringType, target.GetType()));
}
}
@@ -137,7 +137,7 @@ namespace System.Reflection
{
get
{
- return string.Format("{0}.{1}", DeclaringType.FullName, Name);
+ return DeclaringType.FullName + "." + Name;
}
}
diff --git a/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs b/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs
index 0659b60319..394a8f3c22 100644
--- a/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs
+++ b/src/System.Private.CoreLib/src/System/Reflection/RuntimeAssembly.cs
@@ -658,7 +658,7 @@ namespace System.Reflection
if (retAssembly == null && throwOnFileNotFound)
{
- throw new FileNotFoundException(string.Format(culture, SR.IO_FileNotFound_FileName, an.Name));
+ throw new FileNotFoundException(SR.Format(culture, SR.IO_FileNotFound_FileName, an.Name));
}
return retAssembly;
diff --git a/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs b/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs
index 25cc51997d..9951fd122f 100644
--- a/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs
+++ b/src/System.Private.CoreLib/src/System/Reflection/RuntimeConstructorInfo.cs
@@ -301,12 +301,12 @@ namespace System.Reflection
// ctor is declared on interface class
if (declaringType.IsInterface)
throw new MemberAccessException(
- string.Format(CultureInfo.CurrentUICulture, SR.Acc_CreateInterfaceEx, declaringType));
+ SR.Format(SR.Acc_CreateInterfaceEx, declaringType));
// ctor is on an abstract class
else if (declaringType.IsAbstract)
throw new MemberAccessException(
- string.Format(CultureInfo.CurrentUICulture, SR.Acc_CreateAbstEx, declaringType));
+ SR.Format(SR.Acc_CreateAbstEx, declaringType));
// ctor is on a class that contains stack pointers
else if (declaringType.GetRootElementType() == typeof(ArgIterator))
@@ -320,7 +320,7 @@ namespace System.Reflection
else if (declaringType.ContainsGenericParameters)
{
throw new MemberAccessException(
- string.Format(CultureInfo.CurrentUICulture, SR.Acc_CreateGenericEx, declaringType));
+ SR.Format(SR.Acc_CreateGenericEx, declaringType));
}
// ctor is declared on System.Void
diff --git a/src/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs b/src/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs
index b33f004198..342fedbf5d 100644
--- a/src/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs
+++ b/src/System.Private.CoreLib/src/System/Reflection/RuntimeModule.cs
@@ -145,7 +145,7 @@ namespace System.Reflection
if (!MetadataImport.IsValidToken(tk) || !tk.IsFieldDef)
throw new ArgumentOutOfRangeException(nameof(metadataToken),
- string.Format(CultureInfo.CurrentUICulture, SR.Format(SR.Argument_InvalidToken, tk, this)));
+ SR.Format(SR.Argument_InvalidToken, tk, this));
int tkDeclaringType;
string fieldName;
@@ -305,17 +305,17 @@ namespace System.Reflection
MetadataToken tk = new MetadataToken(metadataToken);
if (!tk.IsString)
throw new ArgumentException(
- string.Format(CultureInfo.CurrentUICulture, SR.Argument_ResolveString, metadataToken, ToString()));
+ SR.Format(SR.Argument_ResolveString, metadataToken, this));
if (!MetadataImport.IsValidToken(tk))
throw new ArgumentOutOfRangeException(nameof(metadataToken),
- string.Format(CultureInfo.CurrentUICulture, SR.Format(SR.Argument_InvalidToken, tk, this)));
+ SR.Format(SR.Argument_InvalidToken, tk, this));
string str = MetadataImport.GetUserString(metadataToken);
if (str == null)
throw new ArgumentException(
- string.Format(CultureInfo.CurrentUICulture, SR.Argument_ResolveString, metadataToken, ToString()));
+ SR.Format(SR.Argument_ResolveString, metadataToken, this));
return str;
}
diff --git a/src/System.Private.CoreLib/src/System/RtType.cs b/src/System.Private.CoreLib/src/System/RtType.cs
index 85ede7c4dc..3d03771258 100644
--- a/src/System.Private.CoreLib/src/System/RtType.cs
+++ b/src/System.Private.CoreLib/src/System/RtType.cs
@@ -1776,9 +1776,9 @@ namespace System
}
if (!loaderAssuredCompatible)
- throw new ArgumentException(string.Format(
- CultureInfo.CurrentCulture, SR.Argument_ResolveMethodHandle,
- reflectedType.ToString(), declaredType.ToString()));
+ throw new ArgumentException(SR.Format(
+ SR.Argument_ResolveMethodHandle,
+ reflectedType, declaredType));
}
// Action<in string> is assignable from, but not a subclass of Action<in object>.
else if (declaredType.IsGenericType)
@@ -1804,9 +1804,9 @@ namespace System
if (baseType == null)
{
// ignoring instantiation is the ReflectedType is not a subtype of the DeclaringType
- throw new ArgumentException(string.Format(
- CultureInfo.CurrentCulture, SR.Argument_ResolveMethodHandle,
- reflectedType.ToString(), declaredType.ToString()));
+ throw new ArgumentException(SR.Format(
+ SR.Argument_ResolveMethodHandle,
+ reflectedType, declaredType));
}
// remap the method to same method on the subclass ReflectedType
@@ -1894,10 +1894,10 @@ namespace System
if (!RuntimeFieldHandle.AcquiresContextFromThis(fieldHandle) ||
!RuntimeTypeHandle.CompareCanonicalHandles(declaredType, reflectedType))
{
- throw new ArgumentException(string.Format(
- CultureInfo.CurrentCulture, SR.Argument_ResolveFieldHandle,
- reflectedType.ToString(),
- declaredType.ToString()));
+ throw new ArgumentException(SR.Format(
+ SR.Argument_ResolveFieldHandle,
+ reflectedType,
+ declaredType));
}
}
}
@@ -1929,7 +1929,7 @@ namespace System
{
if (type.IsPointer || type.IsByRef || type == typeof(void))
throw new ArgumentException(
- SR.Format(SR.Argument_NeverValidGenericArgument, type.ToString()));
+ SR.Format(SR.Argument_NeverValidGenericArgument, type));
}
@@ -1985,7 +1985,7 @@ namespace System
typeContext, methodContext, genericArgument.GetTypeHandleInternal().GetTypeChecked()))
{
throw new ArgumentException(
- SR.Format(SR.Argument_GenConstraintViolation, i.ToString(CultureInfo.CurrentCulture), genericArgument.ToString(), definition.ToString(), genericParameter.ToString()), e);
+ SR.Format(SR.Argument_GenConstraintViolation, i.ToString(), genericArgument, definition, genericParameter), e);
}
}
}
@@ -3225,6 +3225,25 @@ namespace System
return false;
}
+#if FEATURE_TYPEEQUIVALENCE
+ // Reflexive, symmetric, transitive.
+ public override bool IsEquivalentTo(Type other)
+ {
+ var otherRtType = other as RuntimeType;
+ if (otherRtType is null)
+ {
+ return false;
+ }
+
+ if (otherRtType == this)
+ {
+ return true;
+ }
+
+ return RuntimeTypeHandle.IsEquivalentTo(this, otherRtType);
+ }
+#endif // FEATURE_TYPEEQUIVALENCE
+
public override Type BaseType => GetBaseType();
private RuntimeType GetBaseType()
@@ -3466,7 +3485,7 @@ namespace System
if (valueType.IsEnum)
{
if (!valueType.IsEquivalentTo(this))
- throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, valueType.ToString(), ToString()));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumAndObjectMustBeSameType, valueType, this));
valueType = (RuntimeType)valueType.GetEnumUnderlyingType();
}
@@ -3487,7 +3506,7 @@ namespace System
{
RuntimeType underlyingType = Enum.InternalGetUnderlyingType(this);
if (underlyingType != valueType)
- throw new ArgumentException(SR.Format(SR.Arg_EnumUnderlyingTypeAndObjectMustBeSameType, valueType.ToString(), underlyingType.ToString()));
+ throw new ArgumentException(SR.Format(SR.Arg_EnumUnderlyingTypeAndObjectMustBeSameType, valueType, underlyingType));
ulong[] ulValues = Enum.InternalGetValues(this);
ulong ulValue = Enum.ToUInt64(value);
@@ -3750,7 +3769,7 @@ namespace System
}
if ((invokeAttr & BindingFlags.ExactBinding) == BindingFlags.ExactBinding)
- throw new ArgumentException(string.Format(CultureInfo.CurrentUICulture, SR.Arg_ObjObjEx, value.GetType(), this));
+ throw new ArgumentException(SR.Format(SR.Arg_ObjObjEx, value.GetType(), this));
return TryChangeType(value, binder, culture, needsSpecialCast);
}
@@ -3791,7 +3810,7 @@ namespace System
}
}
- throw new ArgumentException(string.Format(CultureInfo.CurrentUICulture, SR.Arg_ObjObjEx, value.GetType(), this));
+ throw new ArgumentException(SR.Format(SR.Arg_ObjObjEx, value.GetType(), this));
}
// GetDefaultMembers
@@ -4398,8 +4417,7 @@ namespace System
{
Debug.Assert((invokeMethod.CallingConvention & CallingConventions.VarArgs) ==
CallingConventions.VarArgs);
- throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture,
- SR.NotSupported_CallToVarArg));
+ throw new NotSupportedException(SR.NotSupported_CallToVarArg);
}
// fast path??
diff --git a/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs b/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs
index 94a6379f5f..1851d9fb2b 100644
--- a/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs
+++ b/src/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs
@@ -2,37 +2,14 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////
-//
-// RuntimeHelpers
-// This class defines a set of static methods that provide support for compilers.
-//
-//
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using Internal.Runtime.CompilerServices;
namespace System.Runtime.CompilerServices
{
- using System;
- using System.Diagnostics;
- using System.Security;
- using System.Runtime;
- using System.Runtime.CompilerServices;
- using System.Runtime.InteropServices;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.Serialization;
- using System.Threading;
- using System.Runtime.Versioning;
- using Internal.Runtime.CompilerServices;
-
- public static class RuntimeHelpers
+ public static partial class RuntimeHelpers
{
- // Exposed here as a more appropriate place than on FormatterServices itself,
- // which is a high level reflection heavy type.
- public static object GetUninitializedObject(Type type)
- {
- return FormatterServices.GetUninitializedObject(type);
- }
-
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void InitializeArray(Array array, RuntimeFieldHandle fldHandle);
@@ -113,8 +90,6 @@ namespace System.Runtime.CompilerServices
}
}
- public static void PrepareContractedDelegate(Delegate d) { }
-
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void PrepareDelegate(Delegate d);
@@ -160,27 +135,6 @@ namespace System.Runtime.CompilerServices
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern bool TryEnsureSufficientExecutionStack();
- public static void ProbeForSufficientStack()
- {
- }
-
- // This method is a marker placed immediately before a try clause to mark the corresponding catch and finally blocks as
- // constrained. There's no code here other than the probe because most of the work is done at JIT time when we spot a call to this routine.
- public static void PrepareConstrainedRegions()
- {
- ProbeForSufficientStack();
- }
-
- // When we detect a CER with no calls, we can point the JIT to this non-probing version instead
- // as we don't need to probe.
- public static void PrepareConstrainedRegionsNoOP()
- {
- }
-
- public delegate void TryCode(object userData);
-
- public delegate void CleanupCode(object userData, bool exceptionThrown);
-
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, object userData);
@@ -197,26 +151,6 @@ namespace System.Runtime.CompilerServices
throw new InvalidOperationException();
}
- /// <summary>
- /// GetSubArray helper method for the compiler to slice an array using a range.
- /// </summary>
- public static T[] GetSubArray<T>(T[] array, Range range)
- {
- Type elementType = array.GetType().GetElementType();
- Span<T> source = array.AsSpan(range);
-
- if (elementType.IsValueType)
- {
- return source.ToArray();
- }
- else
- {
- T[] newArray = (T[])Array.CreateInstance(elementType, source.Length);
- source.CopyTo(newArray);
- return newArray;
- }
- }
-
// Returns true iff the object has a component size;
// i.e., is variable length like System.String or Array.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -256,5 +190,9 @@ namespace System.Runtime.CompilerServices
// Ideally this would just be a single dereference:
// mov tmp, qword ptr [rax] ; rax = obj ref, tmp = MethodTable* pointer
}
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern object GetUninitializedObjectInternal(Type type);
+
}
}
diff --git a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs
index 634963e7b3..6874148191 100644
--- a/src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs
+++ b/src/System.Private.CoreLib/src/System/Runtime/InteropServices/WindowsRuntime/CustomPropertyImpl.cs
@@ -109,10 +109,9 @@ namespace System.Runtime.InteropServices.WindowsRuntime
if (!accessor.IsPublic)
throw new MethodAccessException(
- string.Format(
- CultureInfo.CurrentCulture,
+ SR.Format(
SR.Arg_MethodAccessException_WithMethodName,
- accessor.ToString(),
+ accessor,
accessor.DeclaringType.FullName));
RuntimeMethodInfo rtMethod = accessor as RuntimeMethodInfo;
diff --git a/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyDependencyResolver.cs b/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyDependencyResolver.cs
index f1a2a1f9fb..584c60a146 100644
--- a/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyDependencyResolver.cs
+++ b/src/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyDependencyResolver.cs
@@ -83,7 +83,7 @@ namespace System.Runtime.Loader
SR.AssemblyDependencyResolver_FailedToResolveDependencies,
componentAssemblyPath,
returnCode,
- errorMessage.ToString()));
+ errorMessage));
}
string[] assemblyPaths = SplitPathsList(assemblyPathsList);
diff --git a/src/System.Private.CoreLib/src/System/Runtime/Serialization/FormatterServices.cs b/src/System.Private.CoreLib/src/System/Runtime/Serialization/FormatterServices.cs
deleted file mode 100644
index 7642f1eb9e..0000000000
--- a/src/System.Private.CoreLib/src/System/Runtime/Serialization/FormatterServices.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-// 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: Provides some static methods to aid with the implementation
-** of a Formatter for Serialization.
-**
-**
-============================================================*/
-
-using System;
-using System.Reflection;
-using System.Collections;
-using System.Collections.Generic;
-using System.Security;
-using System.Runtime.CompilerServices;
-using System.Runtime.Versioning;
-using System.Threading;
-using System.IO;
-using System.Text;
-using System.Globalization;
-using System.Diagnostics;
-
-namespace System.Runtime.Serialization
-{
- // This class duplicates a class on CoreFX. We are keeping it here -- just this one method --
- // as it was widely invoked by reflection to workaround it being missing in .NET Core 1.0
- internal static class FormatterServices
- {
- // Gets a new instance of the object. The entire object is initalized to 0 and no
- // constructors have been run. **THIS MEANS THAT THE OBJECT MAY NOT BE IN A STATE
- // CONSISTENT WITH ITS INTERNAL REQUIREMENTS** This method should only be used for
- // deserialization when the user intends to immediately populate all fields. This method
- // will not create an unitialized string because it is non-sensical to create an empty
- // instance of an immutable type.
- //
- public static object GetUninitializedObject(Type type)
- {
- if ((object)type == null)
- {
- throw new ArgumentNullException(nameof(type));
- }
-
- if (!(type is RuntimeType))
- {
- throw new SerializationException(SR.Format(SR.Serialization_InvalidType, type.ToString()));
- }
-
- return nativeGetUninitializedObject((RuntimeType)type);
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern object nativeGetUninitializedObject(RuntimeType type);
- }
-}
-
-
-
-
-
diff --git a/src/System.Private.CoreLib/src/System/RuntimeHandles.cs b/src/System.Private.CoreLib/src/System/RuntimeHandles.cs
index 1325aa831f..56694c63b8 100644
--- a/src/System.Private.CoreLib/src/System/RuntimeHandles.cs
+++ b/src/System.Private.CoreLib/src/System/RuntimeHandles.cs
@@ -615,6 +615,11 @@ namespace System
{
throw new PlatformNotSupportedException();
}
+
+#if FEATURE_TYPEEQUIVALENCE
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern bool IsEquivalentTo(RuntimeType rtType1, RuntimeType rtType2);
+#endif // FEATURE_TYPEEQUIVALENCE
}
// This type is used to remove the expense of having a managed reference object that is dynamically
diff --git a/src/System.Private.CoreLib/src/System/StubHelpers.cs b/src/System.Private.CoreLib/src/System/StubHelpers.cs
index 90767fa6a7..7fc7db154e 100644
--- a/src/System.Private.CoreLib/src/System/StubHelpers.cs
+++ b/src/System.Private.CoreLib/src/System/StubHelpers.cs
@@ -1302,7 +1302,7 @@ namespace System.StubHelpers
{
if (managedType.GetType() != typeof(System.RuntimeType))
{ // The type should be exactly System.RuntimeType (and not its child System.ReflectionOnlyType, or other System.Type children)
- throw new ArgumentException(SR.Format(SR.Argument_WinRTSystemRuntimeType, managedType.GetType().ToString()));
+ throw new ArgumentException(SR.Format(SR.Argument_WinRTSystemRuntimeType, managedType.GetType()));
}
bool isPrimitive;
diff --git a/src/System.Private.CoreLib/src/System/TypeLoadException.cs b/src/System.Private.CoreLib/src/System/TypeLoadException.cs
index 6438670283..ff0b972414 100644
--- a/src/System.Private.CoreLib/src/System/TypeLoadException.cs
+++ b/src/System.Private.CoreLib/src/System/TypeLoadException.cs
@@ -70,7 +70,7 @@ namespace System
string format = null;
GetTypeLoadExceptionMessage(ResourceId, JitHelpers.GetStringHandleOnStack(ref format));
- _message = string.Format(CultureInfo.CurrentCulture, format, ClassName, AssemblyName, MessageArg);
+ _message = string.Format(format, ClassName, AssemblyName, MessageArg);
}
}
}
diff --git a/src/debug/createdump/createdump.h b/src/debug/createdump/createdump.h
index 4892e5464b..92365f22e3 100644
--- a/src/debug/createdump/createdump.h
+++ b/src/debug/createdump/createdump.h
@@ -54,6 +54,8 @@ typedef int T_CONTEXT;
#include <map>
#include <set>
#include <vector>
+#include <array>
+#include <string>
#include "datatarget.h"
#include "threadinfo.h"
#include "memoryregion.h"
diff --git a/src/debug/di/process.cpp b/src/debug/di/process.cpp
index 150d0e30da..1536f8c918 100644
--- a/src/debug/di/process.cpp
+++ b/src/debug/di/process.cpp
@@ -106,7 +106,7 @@ STDAPI DLLEXPORT OpenVirtualProcessImpl(
pDataTarget, // takes a reference
hDacModule,
NULL, // Cordb
- &pd, // 0 for V3 cases (pShim == NULL).
+ &pd, // 0 for V3 cases (pShim == NULL).
NULL, // no Shim in V3 cases
&pProcess));
@@ -4921,7 +4921,7 @@ void CordbProcess::RawDispatchEvent(
case DB_IPCE_DATA_BREAKPOINT:
{
_ASSERTE(pThread != NULL);
-
+
{
PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
pCallback4->DataBreakpoint(static_cast<ICorDebugProcess*>(this), pThread, reinterpret_cast<BYTE*>(&(pEvent->DataBreakpointData.context)), sizeof(CONTEXT));
@@ -5642,24 +5642,6 @@ void CordbProcess::RawDispatchEvent(
PUBLIC_CALLBACK_IN_THIS_SCOPE(this, pLockHolder, pEvent);
hr = pCallback1->ControlCTrap((ICorDebugProcess*) this);
}
-
- {
- RSLockHolder ch(this->GetStopGoLock());
-
- DebuggerIPCEvent eventControlCResult;
-
- InitIPCEvent(&eventControlCResult,
- DB_IPCE_CONTROL_C_EVENT_RESULT,
- false,
- VMPTR_AppDomain::NullPtr());
-
- // Indicate whether the debugger has handled the event.
- eventControlCResult.hr = hr;
-
- // Send the reply to the LS.
- SendIPCEvent(&eventControlCResult, sizeof(eventControlCResult));
- } // release SG lock
-
}
break;
@@ -6497,7 +6479,7 @@ HRESULT CordbProcess::GetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE
hr = E_INVALIDARG;
}
else
- {
+ {
DT_CONTEXT* managedContext;
hr = thread->GetManagedContext(&managedContext);
*pContext = *managedContext;
@@ -6576,7 +6558,7 @@ HRESULT CordbProcess::SetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE
{
RSLockHolder ch(GetProcess()->GetStopGoLock());
RSLockHolder lockHolder(GetProcessLock());
-
+
EX_TRY
{
CordbThread* thread = this->TryLookupThreadByVolatileOSId(threadID);
@@ -6595,7 +6577,7 @@ HRESULT CordbProcess::SetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE
}
EX_END_CATCH(SwallowAllExceptions)
-
+
}
return hr;
}
@@ -15245,3 +15227,21 @@ bool CordbProcess::IsThreadSuspendedOrHijacked(ICorDebugThread * pICorDebugThrea
CordbThread * pCordbThread = static_cast<CordbThread *> (pICorDebugThread);
return GetDAC()->IsThreadSuspendedOrHijacked(pCordbThread->m_vmThreadToken);
}
+
+void CordbProcess::HandleControlCTrapResult(HRESULT result)
+{
+ RSLockHolder ch(GetStopGoLock());
+
+ DebuggerIPCEvent eventControlCResult;
+
+ InitIPCEvent(&eventControlCResult,
+ DB_IPCE_CONTROL_C_EVENT_RESULT,
+ false,
+ VMPTR_AppDomain::NullPtr());
+
+ // Indicate whether the debugger has handled the event.
+ eventControlCResult.hr = result;
+
+ // Send the reply to the LS.
+ SendIPCEvent(&eventControlCResult, sizeof(eventControlCResult));
+}
diff --git a/src/debug/di/rspriv.h b/src/debug/di/rspriv.h
index fef79d80ca..64d1fae3db 100644
--- a/src/debug/di/rspriv.h
+++ b/src/debug/di/rspriv.h
@@ -3273,6 +3273,9 @@ public:
bool IsThreadSuspendedOrHijacked(ICorDebugThread * pICorDebugThread);
+ // Handle the result of the ctrlC trap.
+ void HandleControlCTrapResult(HRESULT result);
+
// Helper to get ProcessDescriptor internally.
const ProcessDescriptor* GetProcessDescriptor();
diff --git a/src/debug/di/shimcallback.cpp b/src/debug/di/shimcallback.cpp
index e987f9b944..fab5fbfd60 100644
--- a/src/debug/di/shimcallback.cpp
+++ b/src/debug/di/shimcallback.cpp
@@ -868,7 +868,7 @@ HRESULT ShimProxyCallback::ControlCTrap(ICorDebugProcess * pProcess)
class ControlCTrapEvent : public ManagedEvent
{
// callbacks parameters. These are strong references
- RSExtSmartPtr<ICorDebugProcess > m_pProcess;
+ RSExtSmartPtr<ICorDebugProcess> m_pProcess;
public:
// Ctor
@@ -880,7 +880,12 @@ HRESULT ShimProxyCallback::ControlCTrap(ICorDebugProcess * pProcess)
HRESULT Dispatch(DispatchArgs args)
{
- return args.GetCallback1()->ControlCTrap(m_pProcess);
+ HRESULT hr = args.GetCallback1()->ControlCTrap(m_pProcess);
+
+ // Pass the callback result to the CordbProcess
+ CordbProcess *proc = static_cast<CordbProcess*>((ICorDebugProcess*) m_pProcess);
+ proc->HandleControlCTrapResult(hr);
+ return hr;
}
}; // end class ControlCTrapEvent
@@ -1417,6 +1422,3 @@ HRESULT ShimProxyCallback::DataBreakpoint(ICorDebugProcess* pProcess, ICorDebugT
m_pShim->GetManagedEventQueue()->QueueEvent(new DataBreakpointEvent(pProcess, pThread, pContext, contextSize));
return S_OK;
}
-
-
-
diff --git a/src/debug/ee/debugger.cpp b/src/debug/ee/debugger.cpp
index 86cd547501..63aa8c256c 100644
--- a/src/debug/ee/debugger.cpp
+++ b/src/debug/ee/debugger.cpp
@@ -943,7 +943,6 @@ Debugger::Debugger()
m_pModules(NULL),
m_RSRequestedSync(FALSE),
m_sendExceptionsOutsideOfJMC(TRUE),
- m_pIDbgThreadControl(NULL),
m_forceNonInterceptable(FALSE),
m_pLazyData(NULL),
m_defines(_defines),
@@ -16083,24 +16082,6 @@ HRESULT Debugger::UpdateSpecialThreadList(DWORD cThreadArrayLength,
return (S_OK);
}
-// Updates the pointer for the debugger services
-void Debugger::SetIDbgThreadControl(IDebuggerThreadControl *pIDbgThreadControl)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
- if (m_pIDbgThreadControl)
- m_pIDbgThreadControl->Release();
-
- m_pIDbgThreadControl = pIDbgThreadControl;
-
- if (m_pIDbgThreadControl)
- m_pIDbgThreadControl->AddRef();
-}
-
//
// If a thread is Win32 suspended right after hitting a breakpoint instruction, but before the OS has transitioned the
// thread over to the user-level exception dispatching logic, then we may see the IP pointing after the breakpoint
diff --git a/src/debug/ee/debugger.h b/src/debug/ee/debugger.h
index 15299c0a38..3d3118e85e 100644
--- a/src/debug/ee/debugger.h
+++ b/src/debug/ee/debugger.h
@@ -2579,9 +2579,6 @@ public:
// Allows the debugger to keep an up to date list of special threads
HRESULT UpdateSpecialThreadList(DWORD cThreadArrayLength, DWORD *rgdwThreadIDArray);
- // Updates the pointer for the debugger services
- void SetIDbgThreadControl(IDebuggerThreadControl *pIDbgThreadControl);
-
#ifndef DACCESS_COMPILE
static void AcquireDebuggerDataLock(Debugger *pDebugger);
@@ -2897,10 +2894,6 @@ private:
public:
-
- IDebuggerThreadControl *m_pIDbgThreadControl;
-
-
// Sometimes we force all exceptions to be non-interceptable.
// There are currently three cases where we set this field to true:
//
diff --git a/src/dlls/mscorrc/mscorrc.rc b/src/dlls/mscorrc/mscorrc.rc
index 20612bbd7c..517c548bd7 100644
--- a/src/dlls/mscorrc/mscorrc.rc
+++ b/src/dlls/mscorrc/mscorrc.rc
@@ -907,7 +907,7 @@ BEGIN
IDS_CLASSLOAD_CONSTRAINT_MISMATCH_ON_INTERFACE_METHOD_IMPL "Method '%3' on type '%1' from assembly '%2' tried to explicitly implement an interface method with weaker type parameter constraints."
IDS_CLASSLOAD_EXPLICIT_GENERIC "Could not load type '%1' from assembly '%2' because generic types cannot have explicit layout."
- IDS_EE_COM_INVISIBLE_PARENT "This type has a ComVisible(false) parent in its hierarchy, therefore QueryInterface calls for IDispatch or class interfaces are disallowed."
+ IDS_EE_COM_INVISIBLE_PARENT "Type '%1' has a ComVisible(false) parent '%2' in its hierarchy, therefore QueryInterface calls for IDispatch or class interfaces are disallowed."
IDS_EE_COMIMPORT_METHOD_NO_INTERFACE "Method '%1' in ComImport class '%2' must implement an interface method."
IDS_EE_ATTEMPT_TO_CREATE_GENERIC_CCW "Generic types cannot be marshaled to COM interface pointers."
diff --git a/src/gc/env/gcenv.ee.h b/src/gc/env/gcenv.ee.h
index ec72517bec..c91eadb6de 100644
--- a/src/gc/env/gcenv.ee.h
+++ b/src/gc/env/gcenv.ee.h
@@ -96,6 +96,7 @@ public:
static void AnalyzeSurvivorsFinished(int condemnedGeneration);
static void VerifySyncTableEntry();
+ static void UpdateGCEventStatus(int publicLevel, int publicKeywords, int privateLevel, int privateKeywords);
};
#endif // __GCENV_EE_H__
diff --git a/src/gc/gc.cpp b/src/gc/gc.cpp
index 95fe21ccb6..a26ad8d24f 100644
--- a/src/gc/gc.cpp
+++ b/src/gc/gc.cpp
@@ -10192,6 +10192,13 @@ HRESULT gc_heap::initialize_gc (size_t segment_size,
yp_spin_count_unit = 32 * g_num_processors;
#endif //MULTIPLE_HEAPS
+#if defined(__linux__)
+ GCToEEInterface::UpdateGCEventStatus(static_cast<int>(GCEventStatus::GetEnabledLevel(GCEventProvider_Default)),
+ static_cast<int>(GCEventStatus::GetEnabledKeywords(GCEventProvider_Default)),
+ static_cast<int>(GCEventStatus::GetEnabledLevel(GCEventProvider_Private)),
+ static_cast<int>(GCEventStatus::GetEnabledKeywords(GCEventProvider_Private)));
+#endif // __linux__
+
if (!init_semi_shared())
{
hres = E_FAIL;
@@ -35553,6 +35560,12 @@ void gc_heap::do_pre_gc()
last_gc_index = VolatileLoad(&settings.gc_index);
GCHeap::UpdatePreGCCounters();
+#if defined(__linux__)
+ GCToEEInterface::UpdateGCEventStatus(static_cast<int>(GCEventStatus::GetEnabledLevel(GCEventProvider_Default)),
+ static_cast<int>(GCEventStatus::GetEnabledKeywords(GCEventProvider_Default)),
+ static_cast<int>(GCEventStatus::GetEnabledLevel(GCEventProvider_Private)),
+ static_cast<int>(GCEventStatus::GetEnabledKeywords(GCEventProvider_Private)));
+#endif // __linux__
if (settings.concurrent)
{
diff --git a/src/gc/gcenv.ee.standalone.inl b/src/gc/gcenv.ee.standalone.inl
index b000dadcbc..b5c2c764b6 100644
--- a/src/gc/gcenv.ee.standalone.inl
+++ b/src/gc/gcenv.ee.standalone.inl
@@ -323,4 +323,12 @@ inline void GCToEEInterface::VerifySyncTableEntry()
g_theGCToCLR->VerifySyncTableEntry();
}
+inline void GCToEEInterface::UpdateGCEventStatus(int publicLevel, int publicKeywords, int privateLevel, int privateKeywords)
+{
+ assert(g_theGCToCLR != nullptr);
+#if defined(__linux__)
+ g_theGCToCLR->UpdateGCEventStatus(publicLevel, publicKeywords, privateLevel, privateKeywords);
+#endif // __linux__
+}
+
#endif // __GCTOENV_EE_STANDALONE_INL__
diff --git a/src/gc/gceventstatus.h b/src/gc/gceventstatus.h
index c49e767171..1f31d424be 100644
--- a/src/gc/gceventstatus.h
+++ b/src/gc/gceventstatus.h
@@ -32,15 +32,6 @@
// Uncomment this define to print out event state changes to standard error.
// #define TRACE_GC_EVENT_STATE 1
-/*
- * GCEventProvider represents one of the two providers that the GC can
- * fire events from: the default and private providers.
- */
-enum GCEventProvider
-{
- GCEventProvider_Default = 0,
- GCEventProvider_Private = 1
-};
/*
* GCEventStatus maintains all eventing state for the GC. It consists
@@ -98,6 +89,22 @@ public:
#endif // TRACE_GC_EVENT_STATE
}
+ /*
+ * Returns currently enabled levels
+ */
+ static inline GCEventLevel GetEnabledLevel(GCEventProvider provider)
+ {
+ return enabledLevels[static_cast<size_t>(provider)].LoadWithoutBarrier();
+ }
+
+ /*
+ * Returns currently enabled keywords in GCPublic
+ */
+ static inline GCEventKeyword GetEnabledKeywords(GCEventProvider provider)
+ {
+ return enabledKeywords[static_cast<size_t>(provider)].LoadWithoutBarrier();
+ }
+
#if TRACE_GC_EVENT_STATE
private:
static void DebugDumpState(GCEventProvider provider)
@@ -236,6 +243,7 @@ void FireDynamicEvent(const char* name, EventArgument... arguments)
* payload. Known events will delegate to IGCToCLREventSink::Fire##name.
*/
#if FEATURE_EVENT_TRACE
+
#define KNOWN_EVENT(name, provider, level, keyword) \
inline bool GCEventEnabled##name() { return GCEventStatus::IsEnabled(provider, keyword, level); } \
template<typename... EventActualArgument> \
@@ -258,7 +266,8 @@ void FireDynamicEvent(const char* name, EventArgument... arguments)
#define EVENT_ENABLED(name) GCEventEnabled##name()
#define FIRE_EVENT(name, ...) GCEventFire##name(__VA_ARGS__)
-#else
+
+#else // FEATURE_EVENT_TRACE
#define EVENT_ENABLED(name) false
#define FIRE_EVENT(name, ...) 0
#endif // FEATURE_EVENT_TRACE
diff --git a/src/gc/gcinterface.ee.h b/src/gc/gcinterface.ee.h
index 228bb37075..4ce9203ab0 100644
--- a/src/gc/gcinterface.ee.h
+++ b/src/gc/gcinterface.ee.h
@@ -435,6 +435,9 @@ public:
virtual
void VerifySyncTableEntry() = 0;
+
+ virtual
+ void UpdateGCEventStatus(int publicLevel, int publicKeywords, int privateLEvel, int privateKeywords) = 0;
};
#endif // _GCINTERFACE_EE_H_
diff --git a/src/gc/gcinterface.h b/src/gc/gcinterface.h
index 249466aee4..9744eb0f38 100644
--- a/src/gc/gcinterface.h
+++ b/src/gc/gcinterface.h
@@ -199,6 +199,16 @@ extern uint8_t* g_GCShadowEnd;
extern uint8_t* g_shadow_lowest_address;
#endif
+/*
+ * GCEventProvider represents one of the two providers that the GC can
+ * fire events from: the default and private providers.
+ */
+enum GCEventProvider
+{
+ GCEventProvider_Default = 0,
+ GCEventProvider_Private = 1
+};
+
// Event levels corresponding to events that can be fired by the GC.
enum GCEventLevel
{
diff --git a/src/inc/CMakeLists.txt b/src/inc/CMakeLists.txt
index c54b4f0ec9..517ea8e0f4 100644
--- a/src/inc/CMakeLists.txt
+++ b/src/inc/CMakeLists.txt
@@ -6,7 +6,6 @@ set( CORGUIDS_IDL_SOURCES
xclrdata.idl
corprof.idl
corpub.idl
- gchost.idl
mscorsvc.idl
clrprivappxhosting.idl
clrprivbinding.idl
diff --git a/src/inc/MSCOREE.IDL b/src/inc/MSCOREE.IDL
index cfc0f6b145..93e4042816 100644
--- a/src/inc/MSCOREE.IDL
+++ b/src/inc/MSCOREE.IDL
@@ -19,49 +19,18 @@ cpp_quote("")
// Interface descriptions
//
import "unknwn.idl";
-#if defined(FEATURE_WINDOWSPHONE)
-import "gchost.idl";
-#endif
-
-#include "product_version.h"
cpp_quote("struct IActivationFactory;")
interface IActivationFactory;
-// CLSID TypeNameFactory : uuid{B81FF171-20F3-11d2-8DCC-00A0C9B00525}
-cpp_quote("EXTERN_GUID(CLSID_TypeNameFactory, 0xB81FF171, 0x20F3, 0x11d2, 0x8d, 0xcc, 0x00, 0xa0, 0xc9, 0xb0, 0x05, 0x25);")
-
+cpp_quote("struct IHostControl;")
+interface IHostControl;
-#ifdef FEATURE_COMINTEROP
-// CLSID ComCallUnmarshal
-cpp_quote("EXTERN_GUID(CLSID_ComCallUnmarshal, 0x3F281000,0xE95A,0x11d2,0x88,0x6B,0x00,0xC0,0x4F,0x86,0x9F,0x04);")
+cpp_quote("struct ICLRControl;")
+interface ICLRControl;
// CLSID ComCallUnmarshal2
cpp_quote("EXTERN_GUID(CLSID_ComCallUnmarshalV4, 0x45fb4600,0xe6e8,0x4928,0xb2,0x5e,0x50,0x47,0x6f,0xf7,0x94,0x25);")
-#endif // FEATURE_COMINTEROP
-
-#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
-// IID ICLRAppDomainResourceMonitor: uuid(C62DE18C-2E23-4AEA-8423-B40C1FC59EAE)
-cpp_quote("EXTERN_GUID(IID_ICLRAppDomainResourceMonitor, 0XC62DE18C, 0X2E23, 0X4AEA, 0X84, 0X23, 0XB4, 0X0C, 0X1F, 0XC5, 0X9E, 0XAE);")
-#endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING
-
-// {7D290010-D781-45da-A6F8-AA5D711A730E}
-cpp_quote("EXTERN_GUID(IID_ICLRPolicyManager, 0x7D290010, 0xD781, 0x45da, 0xA6, 0xF8, 0xAA, 0x5D, 0x71, 0x1A, 0x73, 0x0E);")
-
-#if defined (FEATURE_WINDOWSPHONE)
-// IID_ICLRGCManager : uuid(54D9007E-A8E2-4885-B7BF-F998DEEE4F2A)
-cpp_quote("EXTERN_GUID(IID_ICLRGCManager, 0x54D9007E, 0xA8E2, 0x4885, 0xB7, 0xBF, 0xF9, 0x98, 0xDE, 0xEE, 0x4F, 0x2A);")
-// IID_ICLRGCManager2 : uuid(0603B793-A97A-4712-9CB4-0CD1C74C0F7C)
-cpp_quote("EXTERN_GUID(IID_ICLRGCManager2, 0x0603B793, 0xA97A, 0x4712, 0x9C, 0xB4, 0x0C, 0xD1, 0xC7, 0x4C, 0x0F, 0x7C);")
-// IID_ICLRErrorReportingManager : uuid(980D2F1A-BF79-4c08-812A-BB9778928F78)
-cpp_quote("EXTERN_GUID(IID_ICLRErrorReportingManager, 0x980d2f1a, 0xbf79, 0x4c08, 0x81, 0x2a, 0xbb, 0x97, 0x78, 0x92, 0x8f, 0x78);")
-#endif // FEATURE_WINDOWSPHONE
-
-#ifdef FEATURE_WINDOWSPHONE
-// IID_ICLRErrorReportingManager2 : uuid(C68F63B1-4D8B-4E0B-9564-9D2EFE2FA18C)
-cpp_quote("EXTERN_GUID(IID_ICLRErrorReportingManager2, 0xc68f63b1, 0x4d8b, 0x4e0b, 0x95, 0x64, 0x9d, 0x2e, 0xfe, 0x2f, 0xa1, 0x8c);")
-#endif // FEATURE_WINDOWSPHONE
-
// IID ICLRRuntimeHost: uuid(90F1A06C-7712-4762-86B5-7A5EBA6BDB02)
cpp_quote("EXTERN_GUID(IID_ICLRRuntimeHost, 0x90F1A06C, 0x7712, 0x4762, 0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02);")
@@ -72,48 +41,8 @@ cpp_quote("EXTERN_GUID(IID_ICLRRuntimeHost2, 0x712AB73F, 0x2C22, 0x4807, 0xAD, 0
// IID ICLRRuntimeHost4: uuid(64F6D366-D7C2-4F1F-B4B2-E8160CAC43AF)
cpp_quote("EXTERN_GUID(IID_ICLRRuntimeHost4, 0x64F6D366, 0xD7C2, 0x4F1F, 0xB4, 0xB2, 0xE8, 0x16, 0x0C, 0xAC, 0x43, 0xAF);")
-
-// IID ITypeName : uuid{B81FF171-20F3-11d2-8DCC-00A0C9B00522}
-cpp_quote("EXTERN_GUID(IID_ITypeName, 0xB81FF171, 0x20F3, 0x11d2, 0x8d, 0xcc, 0x00, 0xa0, 0xc9, 0xb0, 0x05, 0x22);")
-
-
-// IID ITypeNameBuilder : uuid{B81FF171-20F3-11d2-8DCC-00A0C9B00523}
-cpp_quote("EXTERN_GUID(IID_ITypeNameBuilder, 0xB81FF171, 0x20F3, 0x11d2, 0x8d, 0xcc, 0x00, 0xa0, 0xc9, 0xb0, 0x05, 0x23);")
-
-// IID ITypeNameFactory : uuid{B81FF171-20F3-11d2-8DCC-00A0C9B00521}
-cpp_quote("EXTERN_GUID(IID_ITypeNameFactory, 0xB81FF171, 0x20F3, 0x11d2, 0x8d, 0xcc, 0x00, 0xa0, 0xc9, 0xb0, 0x05, 0x21);")
-
-#pragma midl_echo("DEPRECATED_CLR_STDAPI GetCORSystemDirectory(_Out_writes_to_(cchBuffer, *dwLength) LPWSTR pbuffer, DWORD cchBuffer, DWORD* dwLength);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI GetCORVersion(_Out_writes_to_(cchBuffer, *dwLength) LPWSTR pbBuffer, DWORD cchBuffer, DWORD* dwLength);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI GetFileVersion(LPCWSTR szFilename, _Out_writes_to_opt_(cchBuffer, *dwLength) LPWSTR szBuffer, DWORD cchBuffer, DWORD* dwLength);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI GetCORRequiredVersion(_Out_writes_to_(cchBuffer, *dwLength) LPWSTR pbuffer, DWORD cchBuffer, DWORD* dwLength);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI GetRequestedRuntimeInfo(LPCWSTR pExe, LPCWSTR pwszVersion, LPCWSTR pConfigurationFile, DWORD startupFlags, DWORD runtimeInfoFlags, _Out_writes_opt_(dwDirectory) LPWSTR pDirectory, DWORD dwDirectory, _Out_opt_ DWORD *dwDirectoryLength, _Out_writes_opt_(cchBuffer) LPWSTR pVersion, DWORD cchBuffer, _Out_opt_ DWORD* dwlength);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI GetRequestedRuntimeVersion(_In_ LPWSTR pExe, _Out_writes_to_(cchBuffer, *dwLength) LPWSTR pVersion, DWORD cchBuffer, _Out_ DWORD* dwLength);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI CorBindToRuntimeHost(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, LPCWSTR pwszHostConfigFile, VOID* pReserved, DWORD startupFlags, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI CorBindToRuntimeEx(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, DWORD startupFlags, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI CorBindToRuntimeByCfg(IStream* pCfgStream, DWORD reserved, DWORD startupFlags, REFCLSID rclsid,REFIID riid, LPVOID FAR* ppv);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI CorBindToRuntime(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI CorBindToCurrentRuntime(LPCWSTR pwszFileName, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI RunDll32ShimW(HWND hwnd, HINSTANCE hinst, LPCWSTR lpszCmdLine, int nCmdShow);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI LoadLibraryShim(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE *phModDll);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI CallFunctionShim(LPCWSTR szDllName, LPCSTR szFunctionName, LPVOID lpvArgument1, LPVOID lpvArgument2, LPCWSTR szVersion, LPVOID pvReserved);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI GetRealProcAddress(LPCSTR pwszProcName, VOID** ppv);")
-#pragma midl_echo("DECLARE_DEPRECATED void STDMETHODCALLTYPE CorExitProcess(int exitCode);")
-#pragma midl_echo("DEPRECATED_CLR_STDAPI LoadStringRC(UINT iResouceID, _Out_writes_z_(iMax) LPWSTR szBuffer, int iMax, int bQuiet);")
-#ifdef FEATURE_USE_LCID
-#pragma midl_echo("DEPRECATED_CLR_STDAPI LoadStringRCEx(LCID lcid, UINT iResouceID, _Out_writes_z_(iMax) LPWSTR szBuffer, int iMax, int bQuiet, int *pcwchUsed);")
-#endif
-
#pragma midl_echo("typedef HRESULT (STDAPICALLTYPE *FnGetCLRRuntimeHost)(REFIID riid, IUnknown **pUnk);")
-typedef enum {
- HOST_TYPE_DEFAULT = 0x0,
- HOST_TYPE_APPLAUNCH = 0x1,
- HOST_TYPE_CORFLAG = 0x2
-} HOST_TYPE;
-
-#pragma midl_echo("STDAPI CorLaunchApplication(HOST_TYPE dwClickOnceHost, LPCWSTR pwzAppFullName, DWORD dwManifestPaths, LPCWSTR* ppwzManifestPaths, DWORD dwActivationData, LPCWSTR* ppwzActivationData, LPPROCESS_INFORMATION lpProcessInformation);")
-
typedef HRESULT (__stdcall *FExecuteInAppDomainCallback) (void* cookie);
// By default GC is concurrent and only the base system library is loaded into the domain-neutral area.
@@ -145,26 +74,6 @@ typedef enum {
STARTUP_DISABLE_RANDOMIZED_STRING_HASHING = 0x2000000 // Disable the randomized string hashing (not supported)
} STARTUP_FLAGS;
-typedef enum {
- CLSID_RESOLUTION_DEFAULT = 0x0, // Standard behavior that interop uses
- CLSID_RESOLUTION_REGISTERED = 0x1, // Searches the registry and applies shim policy
-} CLSID_RESOLUTION_FLAGS;
-
-typedef enum
-{
- RUNTIME_INFO_UPGRADE_VERSION = 0x001, // apply upgrades - i.e RTM->Everett
- RUNTIME_INFO_REQUEST_IA64 = 0x002, // requesting a CLR for ia64
- RUNTIME_INFO_REQUEST_AMD64 = 0x004, // requesting a CLR for amd64
- RUNTIME_INFO_REQUEST_X86 = 0x008, // requesting a CLR for x86
- RUNTIME_INFO_DONT_RETURN_DIRECTORY = 0x010, // don't return directory information
- RUNTIME_INFO_DONT_RETURN_VERSION = 0x020, // don't return version information
- RUNTIME_INFO_DONT_SHOW_ERROR_DIALOG = 0x040, // don't pop up an error dialog on failure
- RUNTIME_INFO_IGNORE_ERROR_MODE = 0x1000,// ignore SEM_FAILCRITICALERRORS
- // (by default the error dialog is not shown if SEM_FAILCRITICALERRORS is set)
- // Reserved values here - see mscoreepriv.h
-} RUNTIME_INFO_FLAGS;
-
-
typedef enum
{
APPDOMAIN_SECURITY_DEFAULT =0x0,
@@ -182,85 +91,12 @@ typedef enum
APPDOMAIN_DISABLE_TRANSPARENCY_ENFORCEMENT = 0x100,
} APPDOMAIN_SECURITY_FLAGS;
-#pragma midl_echo("STDAPI GetRequestedRuntimeVersionForCLSID(REFCLSID rclsid, _Out_writes_opt_(cchBuffer) LPWSTR pVersion, DWORD cchBuffer, _Out_opt_ DWORD* dwLength, CLSID_RESOLUTION_FLAGS dwResolutionFlags);")
-
-
-cpp_quote("EXTERN_GUID(IID_IDebuggerThreadControl, 0x23d86786, 0x0bb5, 0x4774, 0x8f, 0xb5, 0xe3, 0x52, 0x2a, 0xdd, 0x62, 0x46);")
-[
- uuid(23D86786-0BB5-4774-8FB5-E3522ADD6246),
- version(1.0),
- helpstring("Control over threads blocked in debugging services"),
- pointer_default(unique),
- local
-]
-interface IDebuggerThreadControl : IUnknown
-{
- // Notification that the thread making the call is about to
- // block within the debugging services. This gives the host
- // an opportunity to perform another action while the thread
- // blocks. This will always be called on a Runtime thread.
- HRESULT ThreadIsBlockingForDebugger();
-
- // Notification that the debugging services is about to
- // release all threads it has blocked. This will never be
- // called on a Runtime thread. If the host has a Runtime
- // thread blocked in ThreadIsBlockingForDebugger() then it
- // should release it now.
- HRESULT ReleaseAllRuntimeThreads();
-
- // Notification that the debugging services are about to
- // start blocking all threads. This could be called on a
- // Runtime thread. This is the signal to the host to
- // start blocking threads in ThreadIsBlockingForDebugger().
- HRESULT StartBlockingForDebugger(DWORD dwUnused);
-}
-
-cpp_quote("EXTERN_GUID(IID_IDebuggerInfo, 0xbf24142d, 0xa47d, 0x4d24, 0xa6, 0x6d, 0x8c, 0x21, 0x41, 0x94, 0x4e, 0x44);")
-[
- uuid(BF24142D-A47D-4d24-A66D-8C2141944E44),
- version(1.0),
- helpstring("Information on the state of the debugging services"),
- pointer_default(unique),
- local
-]
-interface IDebuggerInfo : IUnknown
-{
- // Indicates whether or not a managed debugger is attached to this process.
- HRESULT IsDebuggerAttached([out] BOOL *pbAttached);
-}
-
-
-//*****************************************************************************
-// Interface for hosting mscoree
-//*****************************************************************************
-typedef void* HDOMAINENUM;
-
-
-typedef enum
-{
- eMemoryAvailableLow = 1,
- eMemoryAvailableNeutral = 2,
- eMemoryAvailableHigh = 3
-} EMemoryAvailable;
-
-typedef enum
-{
- eTaskCritical = 0,
- eAppDomainCritical = 1,
- eProcessCritical = 2
-} EMemoryCriticalLevel;
-
typedef enum {
WAIT_MSGPUMP = 0x1,
WAIT_ALERTABLE = 0x2,
WAIT_NOTINDEADLOCK = 0x4
}WAIT_OPTION;
-
-typedef UINT64 TASKID;
-typedef DWORD CONNID;
-
-
typedef enum ETaskType
{
TT_DEBUGGERHELPER = 0x1,
@@ -277,14 +113,6 @@ typedef enum ETaskType
TT_UNKNOWN = 0x80000000,
} ETaskType;
-
-typedef enum {
- eSymbolReadingNever = 0, // Never read PDBs
- eSymbolReadingAlways = 1, // Always read PDBs
- eSymbolReadingFullTrustOnly = 2 // Only read PDBs that correspond to full-trust assemblies
-} ESymbolReadingPolicy;
-
-
typedef enum {
// Default to minidump
DUMP_FLAVOR_Mini = 0,
@@ -300,26 +128,6 @@ typedef enum {
} ECustomDumpFlavor;
-// reserved for future extension
-typedef enum
-{
- DUMP_ITEM_None = 0
-} ECustomDumpItemKind;
-
-//
-// The CustomDumpItem structure describes an item to be added to a dump.
-// It is defined for future expansion and is not presently used.
-//
-typedef struct
-{
- ECustomDumpItemKind itemKind; //this affects how next fields are interpreted.
- union
- {
- // Union to be expanded later if need be
- UINT_PTR pReserved;
- };
-} CustomDumpItem;
-
const DWORD BucketParamsCount = 10;
const DWORD BucketParamLength = 255;
@@ -345,112 +153,6 @@ typedef struct _BucketParameters
WCHAR pszParams[BucketParamsCount][BucketParamLength]; // Parameter strings.
} BucketParameters;
-#if defined(FEATURE_WINDOWSPHONE)
-[
- uuid(980D2F1A-BF79-4c08-812A-BB9778928F78),
- version(1.0),
- helpstring("CLR error reporting manager"),
- pointer_default(unique),
- local
-]
-interface ICLRErrorReportingManager : IUnknown
-{
- // Get Watson bucket parameters for "current" exception (on calling thread).
- HRESULT GetBucketParametersForCurrentException([out] BucketParameters *pParams);
-
- // The BeginCustomDump function configures the custom dump support
- HRESULT BeginCustomDump( [in] ECustomDumpFlavor dwFlavor,
- [in] DWORD dwNumItems,
- [in, size_is(dwNumItems), length_is(dwNumItems)] CustomDumpItem *items,
- DWORD dwReserved);
-
- // EndCustomDump clears the custom dump configuration
- HRESULT EndCustomDump();
-}
-
-#ifdef FEATURE_WINDOWSPHONE
-typedef enum
-{
- // indicates that the specified value is the Application ID
- ApplicationID = 0x1,
-
- // indicates that the specified value is the application's Instance ID
- InstanceID = 0x2,
-
- // additional values are reserved for future use
-} ApplicationDataKey;
-
-[
- uuid(C68F63B1-4D8B-4E0B-9564-9D2EFE2FA18C),
- version(1.0),
- helpstring("CLR error reporting manager 2"),
- pointer_default(unique),
- local
-]
-interface ICLRErrorReportingManager2 : ICLRErrorReportingManager
-{
- // This API will allow the host to specify key/value pairs of data to be consumed by the CLR.
- //
- // Parameters:
- // [in] key - One of the values specified in the ApplicationDataKey enumerated type.
- //
- // [in] pValue - A NULL-terminated WCHAR string with a maximum length of MAX_PATH containing the corresponding
- // value. Note that the CLR maintains its own copy of the data so this structure does not need
- // to persist after the API call returns.
- //
- // Return values:
- // S_OK upon success.
- //
- // Any other return value indicates that the API did not complete successfully and no value was set.
- //
- // Well-defined errors:
- // E_INVALIDOPERATION if the CLR has already started.
- // E_INVALIDARG for any of the following:
- // key is not within the range of valid values for ApplicationDataKey
- // pValue == NULL
- // length of pValue is greater than MAX_PATH
- HRESULT SetApplicationData([in] ApplicationDataKey key, [in] WCHAR const* pValue);
-
- // This API will allow the host to specify pre-defined Watson bucket data in the event of an unhandled
- // exception, allowing the host to override Watson bucket parameter data that is usually collected and
- // populated by the CLR. It should be called before the CLR has started.
- // The BucketParameters data structure must be properly initialized before calling this API by zeroing
- // out all fields, setting pszParams entries as required, then setting fInited to TRUE.
- // A NULL pszParams entry indicates that the bucket parameter should not be overridden, and if all pszParams
- // entries are NULL then the API call will fail.
- // To override a bucket parameter with an empty string specify a pszParams entry with a blank string (one or
- // more whitespace characters).
- //
- // NOTE: The current implementation allows overriding of the first bucket parameter only (pszParams[0]).
- // Any other non-NULL pszParams entries will be ignored. This is subject to change in future releases.
- //
- // Parameters:
- // [in] pBucketParams - A pointer to an initialized BucketParameters structure which contains the data to be
- // reported in the event of an unhandled exception. Note that the CLR maintains its own
- // copy of the data so this structure does not need to persist after the API call returns.
- //
- // [out] pCountParams - A pointer to a DWORD indicating the number of bucket parameter values that have
- // been overridden by the host. A count of 0 indicates that no parameters were
- // overridden.
- //
- // Return values:
- // S_OK upon success. In this case the value pointed to by pCountParams will be greater than 0.
- //
- // Any other return value indicates that the API did not complete successfully. In this case the value
- // pointed to by pCountParams will be 0.
- //
- // Well-defined errors:
- // E_INVALIDOPERATION if the CLR has already started.
- // E_INVALIDARG for any of the following:
- // pBucketParams or pCountParams is NULL
- // pBucketParams->fInited != TRUE
- // if all BucketParameters.pszParams are NULL
- HRESULT SetBucketParametersForUnhandledException([in] BucketParameters const* pBucketParams, [out] DWORD* pCountParams);
-}
-#endif // FEATURE_WINDOWSPHONE
-
-#endif // defined(FEATURE_WINDOWSPHONE)
-
typedef enum
{
@@ -506,225 +208,6 @@ typedef enum
MaxPolicyAction
} EPolicyAction;
-[
- uuid(7D290010-D781-45da-A6F8-AA5D711A730E),
- version(1.0),
- helpstring("Allow host to specify policy for CLR to follow in abnormal condition"),
- pointer_default(unique),
- local
-]
-interface ICLRPolicyManager: IUnknown
-{
- HRESULT SetDefaultAction(
- [in] EClrOperation operation,
- [in] EPolicyAction action);
-
- HRESULT SetTimeout(
- [in] EClrOperation operation,
- [in] DWORD dwMilliseconds);
-
- HRESULT SetActionOnTimeout(
- [in] EClrOperation operation,
- [in] EPolicyAction action);
-
- HRESULT SetTimeoutAndAction(
- [in] EClrOperation operation,
- [in] DWORD dwMilliseconds,
- [in] EPolicyAction action);
-
- HRESULT SetActionOnFailure(
- [in] EClrFailure failure,
- [in] EPolicyAction action);
-
- HRESULT SetUnhandledExceptionPolicy(
- [in] EClrUnhandledException policy);
-}
-
-
-typedef enum
-{
- Event_DomainUnload,
- Event_ClrDisabled,
- Event_MDAFired,
- Event_StackOverflow,
- MaxClrEvent
- // Do not add anything after this
-} EClrEvent;
-
-// An MDAInfo is passed via OnEvent for Event_MDAFired events.
-typedef struct _MDAInfo
-{
- LPCWSTR lpMDACaption;
- LPCWSTR lpMDAMessage;
- LPCWSTR lpStackTrace;
-} MDAInfo;
-
-// An StackOverflowInfo is passed via OnEvent for Event_StackOverflow events.
-typedef enum
-{
- SO_Managed,
- SO_ClrEngine,
- SO_Other,
-} StackOverflowType;
-
-cpp_quote("typedef struct _StackOverflowInfo")
-cpp_quote("{")
-cpp_quote(" StackOverflowType soType;")
-cpp_quote(" EXCEPTION_POINTERS *pExceptionInfo;")
-cpp_quote("} StackOverflowInfo;")
-
-
-#if defined(FEATURE_WINDOWSPHONE)
-
-/*
- * This interface is used to get information about the GC system and
- * control some aspects of the GC. This interface is for expert usage
- * only, and can severely impact the performance of an application if
- * used improperly!!
- */
-[
- uuid(54D9007E-A8E2-4885-B7BF-F998DEEE4F2A),
- version(1.0),
- pointer_default(unique),
- local
-]
-interface ICLRGCManager : IUnknown
-{
- /*
- * Forces a collection to occur for the given generation, regardless of
- * current GC statistics. A value of -1 means collect all generations.
- */
- HRESULT Collect([in] LONG Generation);
-
- /*
- * Returns a set of current statistics about the state of the GC system.
- * These values can then be used by a smart allocation system to help the
- * GC run, by say adding more memory or forcing a collection.
- */
- HRESULT GetStats([in][out] COR_GC_STATS *pStats);
-
- /*
- * Sets the segment size and gen 0 maximum size. This value may only be
- * specified once and will not change if called later.
- */
- HRESULT SetGCStartupLimits([in] DWORD SegmentSize, [in] DWORD MaxGen0Size);
-}
-
-/*
- * This interface is added to allow users to specify 64-bit numbers on 64-bit OSs
- * for the parameters to SetGCStartupLimits.
- */
-[
- uuid(0603B793-A97A-4712-9CB4-0CD1C74C0F7C),
- version(2.0),
- pointer_default(unique),
- local
-]
-interface ICLRGCManager2 : ICLRGCManager
-{
- /*
- * Sets the segment size and gen 0 maximum size. This value may only be
- * specified once and will not change if called later.
- */
- HRESULT SetGCStartupLimitsEx([in] SIZE_T SegmentSize, [in] SIZE_T MaxGen0Size);
-};
-
-
-#endif // FEATURE_WINDOWSPHONE
-
-///////////////////////////////////////////////////////////////////////////////
-//
-// enum EBindPolicyLevels
-//
-///////////////////////////////////////////////////////////////////////////////
-typedef enum
-{
- ePolicyLevelNone = 0x0,
- ePolicyLevelRetargetable = 0x1,
- ePolicyUnifiedToCLR = 0x2,
- ePolicyLevelApp = 0x4,
- ePolicyLevelPublisher = 0x8,
- ePolicyLevelHost = 0x10,
- ePolicyLevelAdmin = 0x20,
- ePolicyPortability = 0x40,
-} EBindPolicyLevels;
-///////////////////////////////////////////////////////////////////////////////
-//
-// struct AssemblyBindInfo
-//
-///////////////////////////////////////////////////////////////////////////////
-typedef struct _AssemblyBindInfo
-{
- DWORD dwAppDomainId;
- LPCWSTR lpReferencedIdentity;
- LPCWSTR lpPostPolicyIdentity;
- DWORD ePolicyLevel;
-}AssemblyBindInfo;
-///////////////////////////////////////////////////////////////////////////////
-//
-// struct ModuleBindInfo
-//
-///////////////////////////////////////////////////////////////////////////////
-typedef struct _ModuleBindInfo
-{
- DWORD dwAppDomainId;
- LPCWSTR lpAssemblyIdentity;
- LPCWSTR lpModuleName;
-} ModuleBindInfo;
-
-
-typedef enum _HostApplicationPolicy
-{
- HOST_APPLICATION_BINDING_POLICY = 1
-}EHostApplicationPolicy;
-
-
-
-// Implemented in mscorwks.dll, use mscoree!GetRealProcAddress to get
-// a function pointer of this API.
-#pragma midl_echo("STDAPI GetCLRIdentityManager(REFIID riid, IUnknown **ppManager);")
-
-// {02CA073D-7079-4860-880A-C2F7A449C991}
-cpp_quote("EXTERN_GUID(IID_IHostControl, 0x02CA073C, 0x7079, 0x4860, 0x88, 0x0A, 0xC2, 0xF7, 0xA4, 0x49, 0xC9, 0x91);")
-[
- uuid(02CA073C-7079-4860-880A-C2F7A449C991),
- version(1.0),
- helpstring("Common Language Runtime Host Control Interface"),
- pointer_default(unique),
- local
-]
-interface IHostControl : IUnknown
-{
- HRESULT GetHostManager(
- [in] REFIID riid,
- [out] void **ppObject);
-
- /* Notify Host with IUnknown with the pointer to AppDomainManager */
- HRESULT SetAppDomainManager(
- [in] DWORD dwAppDomainID,
- [in] IUnknown* pUnkAppDomainManager);
-}
-
-cpp_quote("EXTERN_GUID(IID_ICLRControl, 0x9065597E, 0xD1A1, 0x4fb2, 0xB6, 0xBA, 0x7E, 0x1F, 0xCE, 0x23, 0x0F, 0x61);")
-[
- uuid(9065597E-D1A1-4fb2-B6BA-7E1FCE230F61),
- version(1.0),
- helpstring("Common Language Runtime Control Interface"),
- pointer_default(unique),
- local
-]
-interface ICLRControl : IUnknown
-{
- HRESULT GetCLRManager(
- [in] REFIID riid,
- [out] void **ppObject);
-
- HRESULT SetAppDomainManagerType(
- [in] LPCWSTR pwzAppDomainManagerAssembly,
- [in] LPCWSTR pwzAppDomainManagerType);
-}
-
-
//*****************************************************************************
// New interface for hosting mscoree
@@ -774,10 +257,6 @@ interface ICLRRuntimeHost : IUnknown
[out] DWORD *pReturnValue);
};
-// Keys for ICLRRuntmeHost2::Authenticate. No longer required.
-cpp_quote("#define CORECLR_HOST_AUTHENTICATION_KEY 0x1C6CA6F94025800LL")
-cpp_quote("#define CORECLR_HOST_AUTHENTICATION_KEY_NONGEN 0x1C6CA6F94025801LL")
-
//*****************************************************************************
// New interface for hosting mscoree
//*****************************************************************************
@@ -843,209 +322,6 @@ interface ICLRRuntimeHost4 : ICLRRuntimeHost2
[out] int *pLatchedExitCode);
};
-//*****************************************************************************
-// Interface to utilize HostProtection
-//*****************************************************************************
-typedef enum
-{
- eNoChecks = 0,
- //---------------------------------
- eSynchronization = 0x1,
- eSharedState = 0x2,
- eExternalProcessMgmt = 0x4,
- eSelfAffectingProcessMgmt = 0x8,
- eExternalThreading = 0x10,
- eSelfAffectingThreading = 0x20,
- eSecurityInfrastructure = 0x40,
- eUI = 0x80,
- eMayLeakOnAbort = 0x100,
- //----------------------------------
- eAll = 0x1ff
-} EApiCategories;
-
-
-//
-// Interface for configuring the default AppDomain
-//
-
-typedef enum
-{
- eInitializeNewDomainFlags_None = 0x0000,
-
- // InitializeNewDomain will not make changes to the security state of the AppDomain
- eInitializeNewDomainFlags_NoSecurityChanges = 0x0002
-}
-EInitializeNewDomainFlags;
-
-
-//*****************************************************************************
-// mscoree typelib definition
-//*****************************************************************************
-
-[
- uuid(5477469e-83b1-11d2-8b49-00a0c9b7c9c4),
- version(2.4),
- helpstring("Common Language Runtime Execution Engine 2.4 Library")
-]
-library mscoree
-{
- importlib("stdole32.tlb");
-
- //*****************************************************************************
- //
- //*****************************************************************************
- [
- object,
- oleautomation,
- uuid(B81FF171-20F3-11d2-8DCC-00A0C9B00522),
- helpstring("Type name parser"),
- pointer_default(unique)
- ]
- interface ITypeName : IUnknown
- {
- HRESULT GetNameCount([out, retval] DWORD* pCount);
- HRESULT GetNames([in] DWORD count, [out] BSTR* rgbszNames, [out, retval] DWORD* pCount);
- HRESULT GetTypeArgumentCount([out, retval] DWORD* pCount);
- HRESULT GetTypeArguments([in] DWORD count, [out] ITypeName** rgpArguments, [out, retval] DWORD* pCount);
- HRESULT GetModifierLength([out, retval] DWORD* pCount);
- HRESULT GetModifiers([in] DWORD count, [out] DWORD* rgModifiers, [out, retval] DWORD* pCount);
- HRESULT GetAssemblyName([out, retval] BSTR* rgbszAssemblyNames);
- };
-
- //*****************************************************************************
- //
- //*****************************************************************************
- [
- object,
- oleautomation,
- uuid(B81FF171-20F3-11d2-8DCC-00A0C9B00523),
- helpstring("Type name builder"),
- pointer_default(unique)
- ]
- interface ITypeNameBuilder : IUnknown
- {
- HRESULT OpenGenericArguments();
- HRESULT CloseGenericArguments();
- HRESULT OpenGenericArgument();
- HRESULT CloseGenericArgument();
- HRESULT AddName([in] LPCWSTR szName);
- HRESULT AddPointer();
- HRESULT AddByRef();
- HRESULT AddSzArray();
- HRESULT AddArray([in] DWORD rank);
- HRESULT AddAssemblySpec([in] LPCWSTR szAssemblySpec);
- HRESULT ToString([out, retval] BSTR* pszStringRepresentation);
- HRESULT Clear();
- };
-
- //*****************************************************************************
- //
- //*****************************************************************************
- [
- object,
- oleautomation,
- uuid(B81FF171-20F3-11d2-8DCC-00A0C9B00521),
- helpstring("Type name builder and parser factory"),
- pointer_default(unique)
- ]
- interface ITypeNameFactory : IUnknown
- {
- HRESULT ParseTypeName([in] LPCWSTR szName, [out] DWORD* pError, [out, retval] ITypeName** ppTypeName);
- HRESULT GetTypeNameBuilder([out, retval] ITypeNameBuilder** ppTypeBuilder);
- };
-
-
-#ifdef _WIN64
- #define CCW_PTR __int64 *
- cpp_quote("#define CCW_PTR __int64 *")
-#else // WIN64
- #define CCW_PTR int *
- cpp_quote("#define CCW_PTR int *")
-#endif // WIN64
-
-#ifdef FEATURE_COMINTEROP
- //*****************************************************************************
- // IMarshal implementation for 1.0, 1.1, and 2.0 COM callable wrappers
- //*****************************************************************************
- [
- uuid(3F281000-E95A-11d2-886B-00C04F869F04),
- helpstring("Com Call Wrapper Unmarshalling Class")
- ]
- coclass ComCallUnmarshal
- {
- [default] interface IMarshal;
- };
-
- //*****************************************************************************
- // IMarshal implementation for 4.0 COM callable wrappers
- //*****************************************************************************
- [
- uuid(45FB4600-E6E8-4928-B25E-50476FF79425),
- helpstring("Com Call Wrapper Unmarshalling Class 4.0")
- ]
- coclass ComCallUnmarshalV4
- {
- [default] interface IMarshal;
- };
-#endif // FEATURE_COMINTEROP
-
-
- [
- uuid(90F1A06E-7712-4762-86B5-7A5EBA6BDB02),
- helpstring("CLR Runtime Hosting Class V2")
- ]
- coclass CLRRuntimeHost
- {
- [default] interface ICLRRuntimeHost;
- interface ICLRValidator;
- };
-
- [
- uuid(B81FF171-20F3-11d2-8DCC-00A0C9B00525),
- helpstring("TypeName parser and builder")
- ]
- coclass TypeNameFactory
- {
- [default] interface ITypeNameFactory;
- };
-};
-
-typedef enum
-{
- eCurrentContext=0x00,
- eRestrictedContext=0x01
-} EContextType;
-
-
-#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
-///////////////////////////////////////////////////////////////////////////////
-//
-// ICLRAppDomainResourceMonitor
-//
-///////////////////////////////////////////////////////////////////////////////
-[
- version(1.0),
- uuid(c62de18c-2e23-4aea-8423-b40c1fc59eae),
- helpstring("ARM interface"),
- pointer_default(unique),
- local
-]
-interface ICLRAppDomainResourceMonitor: IUnknown
-{
- HRESULT GetCurrentAllocated([in] DWORD dwAppDomainId,
- [out] ULONGLONG* pBytesAllocated);
-
- HRESULT GetCurrentSurvived([in] DWORD dwAppDomainId,
- [out] ULONGLONG* pAppDomainBytesSurvived,
- [out] ULONGLONG* pTotalBytesSurvived);
-
- HRESULT GetCurrentCpuTime([in] DWORD dwAppDomainId,
- [out] ULONGLONG* pMilliseconds);
-
-
-};
-#endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING
-
cpp_quote("#undef DEPRECATED_CLR_STDAPI")
cpp_quote("#undef DECLARE_DEPRECATED")
cpp_quote("#undef DEPRECATED_CLR_API_MESG")
diff --git a/src/inc/clrconfigvalues.h b/src/inc/clrconfigvalues.h
index ecf43f0d81..201a123211 100644
--- a/src/inc/clrconfigvalues.h
+++ b/src/inc/clrconfigvalues.h
@@ -102,7 +102,6 @@
///
/// AppDomain
///
-CONFIG_DWORD_INFO(INTERNAL_ADBreakOnCannotUnload, W("ADBreakOnCannotUnload"), 0, "Used to troubleshoot failures to unload appdomain (e.g. someone sitting in unmanged code). In some cases by the time we throw the appropriate exception the thread has moved from the offending call. This setting allows in an instrumented build to stop exactly at the right moment.")
RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(UNSUPPORTED_AddRejitNops, W("AddRejitNops"), "Control for the profiler rejit feature infrastructure")
CONFIG_DWORD_INFO(INTERNAL_ADDumpSB, W("ADDumpSB"), 0, "Not used")
CONFIG_DWORD_INFO(INTERNAL_ADForceSB, W("ADForceSB"), 0, "Forces sync block creation for all objects")
@@ -110,8 +109,6 @@ CONFIG_DWORD_INFO(INTERNAL_ADLogMemory, W("ADLogMemory"), 0, "Superseded by test
CONFIG_DWORD_INFO(INTERNAL_ADTakeDHSnapShot, W("ADTakeDHSnapShot"), 0, "Superseded by test hooks")
CONFIG_DWORD_INFO(INTERNAL_ADTakeSnapShot, W("ADTakeSnapShot"), 0, "Superseded by test hooks")
CONFIG_DWORD_INFO_DIRECT_ACCESS(INTERNAL_EnableFullDebug, W("EnableFullDebug"), "Heavy-weight checking for AD boundary violations (AD leaks)")
-RETAIL_CONFIG_DWORD_INFO(EXTERNAL_ADULazyMemoryRelease, W("ADULazyMemoryRelease"), 1, "On by default. Turned off in cases when people try to catch memory leaks, in which case AD unload should be immediately followed by GC)")
-RETAIL_CONFIG_DWORD_INFO_DIRECT_ACCESS(EXTERNAL_ADURetryCount, W("ADURetryCount"), "Controls timeout of AD unload. Used for workarounds when machine is too slow, there are network issues etc.")
// For the proposal and discussion on why finalizers are not run on shutdown by default anymore in CoreCLR, see the API review:
// https://github.com/dotnet/corefx/issues/5205
diff --git a/src/inc/corhost.h b/src/inc/corhost.h
index 3045decd7c..09ea994b59 100644
--- a/src/inc/corhost.h
+++ b/src/inc/corhost.h
@@ -55,47 +55,6 @@ protected:
// Starts the runtime. This is equivalent to CoInitializeCor()
STDMETHODIMP Start();
-#ifdef FEATURE_COMINTEROP
- // Creates a domain in the runtime. The identity array is
- // a pointer to an array TYPE containing IIdentity objects defining
- // the security identity.
- STDMETHODIMP CreateDomain(LPCWSTR pwzFriendlyName, // Optional
- IUnknown* pIdentityArray, // Optional
- IUnknown ** pAppDomain);
-
- // Returns the default domain.
- STDMETHODIMP GetDefaultDomain(IUnknown ** pAppDomain);
-
- // Enumerate currently existing domains.
- STDMETHODIMP EnumDomains(HDOMAINENUM *hEnum);
-
- // Returns S_FALSE when there are no more domains. A domain
- // is passed out only when S_OK is returned.
- STDMETHODIMP NextDomain(HDOMAINENUM hEnum,
- IUnknown** pAppDomain);
-
- // Close the enumeration releasing resources
- STDMETHODIMP CloseEnum(HDOMAINENUM hEnum);
-
- STDMETHODIMP CreateDomainEx(LPCWSTR pwzFriendlyName,
- IUnknown* pSetup, // Optional
- IUnknown* pEvidence, // Optional
- IUnknown ** pAppDomain);
-
- // Create appdomain setup object that can be passed into CreateDomainEx
- STDMETHODIMP CreateDomainSetup(IUnknown** pAppDomainSetup);
-
- // Create Evidence object that can be passed into CreateDomainEx
- STDMETHODIMP CreateEvidence(IUnknown** pEvidence);
-
- // Unload a domain, releasing the reference will only release the
- // the wrapper to the domain not unload the domain.
- STDMETHODIMP UnloadDomain(IUnknown* pAppDomain);
-
- // Returns the threads domain if there is one.
- STDMETHODIMP CurrentDomain(IUnknown ** pAppDomain);
-#endif // FEATURE_COMINTEROP
-
STDMETHODIMP MapFile( // Return code.
HANDLE hFile, // [in] Handle for file
HMODULE *hMapAddress // [out] HINSTANCE for mapped file
@@ -142,79 +101,6 @@ enum ESymbolReadingSetBy
eSymbolReadingSetBy_COUNT
};
-
-#if defined(FEATURE_WINDOWSPHONE)
-class CCLRErrorReportingManager :
-#ifdef FEATURE_WINDOWSPHONE
- public ICLRErrorReportingManager2
-#else
- public ICLRErrorReportingManager
-#endif // FEATURE_WINDOWSPHONE
-{
- friend class ClrDataAccess;
- friend struct _DacGlobals;
-
- SVAL_DECL(ECustomDumpFlavor, g_ECustomDumpFlavor);
-
-#ifdef FEATURE_WINDOWSPHONE
- WCHAR* m_pApplicationId;
- WCHAR* m_pInstanceId;
-
- class BucketParamsCache
- {
- private:
- WCHAR** m_pParams;
- DWORD const m_cMaxParams;
- public:
- BucketParamsCache(DWORD maxNumParams);
- ~BucketParamsCache();
-
- WCHAR const* GetAt(BucketParameterIndex index);
- HRESULT SetAt(BucketParameterIndex index, WCHAR const* val);
- };
-
- BucketParamsCache* m_pBucketParamsCache;
-
- HRESULT CopyToDataCache(_In_ WCHAR** pTarget, WCHAR const* pSource);
-#endif // FEATURE_WINDOWSPHONE
-
-public:
- CCLRErrorReportingManager();
- ~CCLRErrorReportingManager();
-
- STDMETHODIMP QueryInterface(REFIID riid, void** ppv);
- STDMETHODIMP_(ULONG) AddRef(void);
- STDMETHODIMP_(ULONG) Release(void);
-
- // ICLRErrorReportingManager APIs //
-
- // Get Watson bucket parameters for "current" exception (on calling thread).
- STDMETHODIMP GetBucketParametersForCurrentException(BucketParameters *pParams);
- STDMETHODIMP BeginCustomDump( ECustomDumpFlavor dwFlavor,
- DWORD dwNumItems,
- CustomDumpItem items[],
- DWORD dwReserved);
- STDMETHODIMP EndCustomDump();
-
-#ifdef FEATURE_WINDOWSPHONE
- // ICLRErrorReportingManager2 APIs //
-
- STDMETHODIMP SetApplicationData(ApplicationDataKey key, WCHAR const* pValue);
- STDMETHODIMP SetBucketParametersForUnhandledException(BucketParameters const* pBucketParams, DWORD* pCountParams);
-
- // internal APIs
-
- // returns the application data for the specified key if available, else returns NULL.
- WCHAR const* GetApplicationData(ApplicationDataKey key);
-
- // returns bucket parameter override data if available, else returns NULL.
- WCHAR const* GetBucketParamOverride(BucketParameterIndex bucketParamId);
-#endif // FEATURE_WINDOWSPHONE
-};
-
-extern CCLRErrorReportingManager g_CLRErrorReportingManager;
-#endif // defined(FEATURE_WINDOWSPHONE)
-
class CorHost2 :
public CorRuntimeHostBase
#ifndef FEATURE_PAL
@@ -334,8 +220,6 @@ public:
static STARTUP_FLAGS GetStartupFlags();
- static EInitializeNewDomainFlags GetAppDomainManagerInitializeNewDomainFlags();
-
static BOOL HasStarted()
{
return m_RefCount != 0;
@@ -372,39 +256,9 @@ private:
static LONG m_RefCount;
- static IHostControl *m_HostControl;
-
SVAL_DECL(STARTUP_FLAGS, m_dwStartupFlags);
};
-class CorHostProtectionManager
-{
-private:
- EApiCategories m_eProtectedCategories;
- bool m_fEagerSerializeGrantSet;
- bool m_fFrozen;
-
-public:
- CorHostProtectionManager();
-
- // IUnknown methods
- HRESULT STDMETHODCALLTYPE QueryInterface(
- REFIID id,
- void **pInterface);
- ULONG STDMETHODCALLTYPE AddRef();
- ULONG STDMETHODCALLTYPE Release();
-
- // Interface methods
- virtual HRESULT STDMETHODCALLTYPE SetProtectedCategories(/* [in] */ EApiCategories eFullTrustOnlyResources);
- virtual HRESULT STDMETHODCALLTYPE SetEagerSerializeGrantSets();
-
- // Getters
- EApiCategories GetProtectedCategories();
- bool GetEagerSerializeGrantSets() const;
-
- void Freeze();
-};
-
#ifdef FEATURE_COMINTEROP
extern "C"
HRESULT STDMETHODCALLTYPE DllGetActivationFactoryImpl(
diff --git a/src/inc/dacvars.h b/src/inc/dacvars.h
index f4a04b2f19..fc5be15590 100644
--- a/src/inc/dacvars.h
+++ b/src/inc/dacvars.h
@@ -131,10 +131,6 @@ DEFINE_DACVAR(ULONG, DWORD, dac__g_debuggerWordTLSIndex, g_debuggerWordTLSIndex)
#endif
DEFINE_DACVAR(ULONG, DWORD, dac__g_TlsIndex, g_TlsIndex)
-#if defined(FEATURE_WINDOWSPHONE)
-DEFINE_DACVAR(ULONG, int, CCLRErrorReportingManager__g_ECustomDumpFlavor, CCLRErrorReportingManager::g_ECustomDumpFlavor)
-#endif
-
DEFINE_DACVAR(ULONG, PTR_SString, SString__s_Empty, SString::s_Empty)
#ifdef FEATURE_APPX
diff --git a/src/inc/gchost.idl b/src/inc/gchost.idl
deleted file mode 100644
index 6d85f91513..0000000000
--- a/src/inc/gchost.idl
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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.
-/* -------------------------------------------------------------------------- *
- * Common Language Runtime Profiling interfaces
- *
- * The IGCHost allows a host environment to get statistics about the
- * garbage collector as well as to gain some limited control over collections.
- * This interface can be QueryInterface'd for on from the CorHost object.
- * -------------------------------------------------------------------------- */
-import "unknwn.idl";
-
-
-#if defined(FEATURE_WINDOWSPHONE)
-/*
- * This structure is used to return statics for the GC system. Set the Flags
- * value to a bitmask of values that should be returned. Only those values which
- * are requested are calculated and returned to the caller.
- */
-typedef struct _COR_GC_STATS
-{
- ULONG Flags; // What values to get.
-
- // Value when COR_GC_COUNTS is specified.
- SIZE_T ExplicitGCCount; // How many times was GC forced to run by external request.
- SIZE_T GenCollectionsTaken[3]; // Number of collections done for each generation
-
- // Memory sizes, valid for COR_GC_MEMORYUSAGE.
- SIZE_T CommittedKBytes; // Total committed bytes from all heaps.
- SIZE_T ReservedKBytes; // Total reserved bytes from all heaps.
- SIZE_T Gen0HeapSizeKBytes; // Size of gen 0 heap.
- SIZE_T Gen1HeapSizeKBytes; // Size of gen 1 heap.
- SIZE_T Gen2HeapSizeKBytes; // Size of gen 2 heap.
- SIZE_T LargeObjectHeapSizeKBytes; // Size of large object heap.
- SIZE_T KBytesPromotedFromGen0; // How many bytes promoted to next generation.
- SIZE_T KBytesPromotedFromGen1;
-
-} COR_GC_STATS;
-#endif // FEATURE_WINDOWSPHONE
-
-cpp_quote("/*")
-cpp_quote(" * WARNING - This is a dummy interface that should never be used.")
-cpp_quote(" * The code is written this way because Midl requires a CoClass, Interface, etc... that generates")
-cpp_quote(" * a guid. Removing the IGCHost interface removes the only guid")
-cpp_quote(" * This option was selected because ifdefs are not simple to implement for excluding files in SOURCES")
-cpp_quote("*/")
-[
- object,
- uuid(F9423916-2A35-4f03-9EE9-DDAFA3C8AEE0),
- pointer_default(unique),
- local
-]
-interface IDummyDoNotUse : IUnknown
-{
-}
diff --git a/src/inc/metahost.idl b/src/inc/metahost.idl
index 83f711ae54..b7c2e0ba67 100644
--- a/src/inc/metahost.idl
+++ b/src/inc/metahost.idl
@@ -37,32 +37,15 @@ import "ocidl.idl";
import "mscoree.idl";
cpp_quote("#include <winapifamily.h>")
-cpp_quote("#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)")
-/**************************************************************************************
- ** This should be the only flat public API exposed from mscoree going forward. **
- ** The returned interface is likely to be implemented in a separate versioned DLL **
- ** (mscorhst.dll living in the versioned directory for instance). Acceptable values **
- ** for riid in v4.0 are IID_ICLRMetaHost, IID_ICLRMetaHostPolicy and **
- ** IID_ICLRDebugging. **
- **************************************************************************************/
cpp_quote("STDAPI CLRCreateInstance(REFCLSID clsid, REFIID riid, /*iid_is(riid)*/ LPVOID *ppInterface);")
-// CLSID CLRStrongName : uuid(B79B0ACD-F5CD-409b-B5A5-A16244610B92)
-cpp_quote("EXTERN_GUID(CLSID_CLRStrongName, 0xB79B0ACD, 0xF5CD, 0x409b, 0xB5, 0xA5, 0xA1, 0x62, 0x44, 0x61, 0x0B, 0x92);")
-
// IID ICLRMetaHost : uuid(D332DB9E-B9B3-4125-8207-A14884F53216)
cpp_quote("EXTERN_GUID(IID_ICLRMetaHost, 0xD332DB9E, 0xB9B3, 0x4125, 0x82, 0x07, 0xA1, 0x48, 0x84, 0xF5, 0x32, 0x16);")
// CLSID_CLRMetaHost : uuid(9280188D-0E8E-4867-B30C-7FA83884E8DE)
cpp_quote("EXTERN_GUID(CLSID_CLRMetaHost, 0x9280188d, 0xe8e, 0x4867, 0xb3, 0xc, 0x7f, 0xa8, 0x38, 0x84, 0xe8, 0xde);")
-// IID ICLRMetaHostPolicy : uuid(E2190695-77B2-492e-8E14-C4B3A7FDD593)
-cpp_quote("EXTERN_GUID(IID_ICLRMetaHostPolicy, 0xE2190695, 0x77B2, 0x492e, 0x8E, 0x14, 0xC4, 0xB3, 0xA7, 0xFD, 0xD5, 0x93);")
-
-// CLSID_CLRMetaHostPolicy : uuid(2EBCD49A-1B47-4a61-B13A-4A03701E594B)
-cpp_quote("EXTERN_GUID(CLSID_CLRMetaHostPolicy, 0x2ebcd49a, 0x1b47, 0x4a61, 0xb1, 0x3a, 0x4a, 0x3, 0x70, 0x1e, 0x59, 0x4b);")
-
// IID ICLRDebugging : uuid(D28F3C5A-9634-4206-A509-477552EEFB10)
cpp_quote("EXTERN_GUID(IID_ICLRDebugging, 0xd28f3c5a, 0x9634, 0x4206, 0xa5, 0x9, 0x47, 0x75, 0x52, 0xee, 0xfb, 0x10);")
@@ -72,37 +55,12 @@ cpp_quote("EXTERN_GUID(CLSID_CLRDebugging, 0xbacc578d, 0xfbdd, 0x48a4, 0x96, 0x9
// IID ICLRRuntimeInfo : uuid(BD39D1D2-BA2F-486a-89B0-B4B0CB466891)
cpp_quote("EXTERN_GUID(IID_ICLRRuntimeInfo, 0xBD39D1D2, 0xBA2F, 0x486a, 0x89, 0xB0, 0xB4, 0xB0, 0xCB, 0x46, 0x68, 0x91);")
-// IID ICLRStrongName : uuid(9FD93CCF-3280-4391-B3A9-96E1CDE77C8D)
-cpp_quote("EXTERN_GUID(IID_ICLRStrongName, 0x9FD93CCF, 0x3280, 0x4391, 0xB3, 0xA9, 0x96, 0xE1, 0xCD, 0xE7, 0x7C, 0x8D);")
-
-// IID ICLRStrongName2 : uuid(C22ED5C5-4B59-4975-90EB-85EA55C0069B)
-cpp_quote("EXTERN_GUID(IID_ICLRStrongName2, 0xC22ED5C5, 0x4B59, 0x4975, 0x90, 0xEB, 0x85, 0xEA, 0x55, 0xC0, 0x06, 0x9B);")
-
-// IID ICLRStrongName3 : uuid(22c7089b-bbd3-414a-b698-210f263f1fed)
-cpp_quote("EXTERN_GUID(IID_ICLRStrongName3, 0x22c7089b, 0xbbd3, 0x414a, 0xb6, 0x98, 0x21, 0x0f, 0x26, 0x3f, 0x1f, 0xed);")
-
-// CLSID for legacy debugging interface : uuid(DF8395B5-A4BA-450b-A77C-A9A47762C520}
-cpp_quote("EXTERN_GUID(CLSID_CLRDebuggingLegacy, 0xDF8395B5, 0xA4BA, 0x450b, 0xA7, 0x7C, 0xA9, 0xA4, 0x77, 0x62, 0xC5, 0x20);")
-
-// CLSID CLRProfiling interface : uuid{BD097ED8-733E-43fe-8ED7-A95FF9A8448C}
-cpp_quote("EXTERN_GUID(CLSID_CLRProfiling, 0xbd097ed8, 0x733e, 0x43fe, 0x8e, 0xd7, 0xa9, 0x5f, 0xf9, 0xa8, 0x44, 0x8c);")
-
// IID ICLRDebuggingLibraryProvider interface : uuid{3151C08D-4D09-4f9b-8838-2880BF18FE51}
cpp_quote("EXTERN_GUID(IID_ICLRDebuggingLibraryProvider, 0x3151c08d, 0x4d09, 0x4f9b, 0x88, 0x38, 0x28, 0x80, 0xbf, 0x18, 0xfe, 0x51);")
// IID ICLRDebuggingLibraryProvider2 interface : uuid{E04E2FF1-DCFD-45D5-BCD1-16FFF2FAF7BA}
cpp_quote("EXTERN_GUID(IID_ICLRDebuggingLibraryProvider2, 0xE04E2FF1, 0xDCFD, 0x45D5, 0xBC, 0xD1, 0x16, 0xFF, 0xF2, 0xFA, 0xF7, 0xBA);")
-typedef HRESULT(__stdcall * CLRCreateInstanceFnPtr)(
- REFCLSID clsid,
- REFIID riid,
- LPVOID *ppInterface);
-
-typedef HRESULT(__stdcall * CreateInterfaceFnPtr)(
- REFCLSID clsid,
- REFIID riid,
- LPVOID *ppInterface);
-
// For use in ICLRMetaHost::RequestRuntimeLoadedNotification
interface ICLRRuntimeInfo;
@@ -211,125 +169,6 @@ interface ICLRMetaHost : IUnknown
[in] INT32 iExitCode);
} // interface ICLRMetaHost
-typedef enum
-{
- /**********************************************************************************
- ** Functions will not take into account runtimes already loaded into the **
- ** process (thus guaranteed to give the same answer regardless of load order). **
- **********************************************************************************/
- METAHOST_POLICY_HIGHCOMPAT = 0x00000000,
-
- /**********************************************************************************
- ** 0x00000000 - 0x00000004 reserved for future policies. **
- **********************************************************************************/
-
- /**********************************************************************************
- ** Applies upgrade policy when an exact match is not found. **
- **********************************************************************************/
- METAHOST_POLICY_APPLY_UPGRADE_POLICY = 0x00000008,
-
- /**********************************************************************************
- ** Binds as if the provided information were being use in a new process. This **
- ** allows a host to determine what runtime an EXE will bind to when launched. **
- **********************************************************************************/
- METAHOST_POLICY_EMULATE_EXE_LAUNCH = 0x00000010,
-
- /**********************************************************************************
- ** Produces an error dialog if GetRequestedRuntime is unable to find a runtime **
- ** compatible with the input parameters. This error dialog can take the form **
- ** of a dialog box that takes a user to an fwlink, or as a Windows feature **
- ** dialog asking if the user would like to enable the appropriate feature (when **
- ** available, this dialog is preferred over the fwlink dialog). **
- **********************************************************************************/
- METAHOST_POLICY_SHOW_ERROR_DIALOG = 0x00000020,
-
- /**********************************************************************************
- ** By default, GetRequestedRuntime will not fall back to the process image path **
- ** (typically the EXE that was used to launch the process) when determining the **
- ** runtime to bind to. Specify this flag to have GetRequestedRuntime implicitly **
- ** use the process image (and any corresponding configuration file) as **
- ** additional input to the binding process. **
- **********************************************************************************/
- METAHOST_POLICY_USE_PROCESS_IMAGE_PATH = 0x00000040,
-
- /**********************************************************************************
- ** By default, we will not check whether the appropriate SKU is installed **
- ** unless SKU is specified in the config file entry. **
- ** Setting this flag forces the check when no information is available in the **
- ** config file, allowing applications without config files to fail gracefully **
- ** on smaller SKUs than the default install of .NET **
- **********************************************************************************/
- METAHOST_POLICY_ENSURE_SKU_SUPPORTED = 0x00000080,
-
- /**********************************************************************************
- ** By default, we ignore METAHOST_POLICY_SHOW_ERROR_DIALOG if **
- ** SEM_FAILCRITICALERRORS is set **
- ** This flag tell us that a silent failure would be so undesirable that **
- ** the METAHOST_POLICY_SHOW_ERROR_DIALOG should be honored, even if for some **
- ** reason (e.g. inheritance from another process) SEM_FAILCRITICALERRORS is set **
- **********************************************************************************/
- METAHOST_POLICY_IGNORE_ERROR_MODE = 0x00001000,
-
-}
-METAHOST_POLICY_FLAGS;
-
-/**************************************************************************************
- ** This enum describes the possible flags returned in GetRequestedRuntinme's **
- ** pdwConfigFlags out parameter.
- **************************************************************************************/
-typedef enum
-{
- /**********************************************************************************
- ** If a config file is used during GetRequestedRuntime's binding process, these **
- ** values indicate whether or not the startup tag has the **
- ** useLegacyV2RuntimeActivationPolicy attribute set, and if so to what value. **
- **********************************************************************************/
-
- // Indicates presence and value of useLegacyV2RuntimeActivationPolicy <startup> attr
- METAHOST_CONFIG_FLAGS_LEGACY_V2_ACTIVATION_POLICY_UNSET = 0x00000000,
- METAHOST_CONFIG_FLAGS_LEGACY_V2_ACTIVATION_POLICY_TRUE = 0x00000001,
- METAHOST_CONFIG_FLAGS_LEGACY_V2_ACTIVATION_POLICY_FALSE = 0x00000002,
- METAHOST_CONFIG_FLAGS_LEGACY_V2_ACTIVATION_POLICY_MASK = 0x00000003,
-}
-METAHOST_CONFIG_FLAGS;
-
-/**************************************************************************************
- ** ICLRMetaHostPolicy **
- ** Activated using mscoree!CLRCreateInstance. Implements a policy for determining **
- ** a runtime based on various inputs (metadata, config stream, ...). **
- **************************************************************************************/
-[
- uuid(E2190695-77B2-492e-8E14-C4B3A7FDD593),
- version(1.0),
- helpstring("CLR meta hosting policy"),
- local
-]
-interface ICLRMetaHostPolicy : IUnknown
-{
- /**********************************************************************************
- ** Returns requested runtime version and runtime (not necessarily of that **
- ** version) based on a managed binary, version, and config file. **
- ** The return value is S_OK if a compatible runtime was found and S_FALSE if **
- ** not. *ppRuntime will be NULL in the latter case. **
- ** Supersedes: GetRequestedRuntimeInfo, GetRequestedRuntimeVersion, **
- ** CorBindToRuntimeHost, CorBindToRuntimeByCfg, **
- ** GetCORRequiredVersion **
- **********************************************************************************/
- HRESULT GetRequestedRuntime(
- [in] METAHOST_POLICY_FLAGS dwPolicyFlags,
- [in] LPCWSTR pwzBinary, // optional
- [in] IStream *pCfgStream, // optional
- [in, out, size_is(*pcchVersion), annotation("_Inout_updates_all_opt_(*pcchVersion)")]
- LPWSTR pwzVersion, // optional
- [in, out] DWORD *pcchVersion,
- [out, size_is(*pcchImageVersion), annotation("_Out_writes_all_opt_(*pcchImageVersion)")]
- LPWSTR pwzImageVersion, // image version to be used by compilers
- [in, out] DWORD *pcchImageVersion,
- [out] DWORD *pdwConfigFlags,
- [in] REFIID riid, // IID_ICLRRuntimeInfo
- [out, iid_is(riid), retval] LPVOID *ppRuntime);
-} // interface ICLRMetaHostPolicy
-
/*************************************************************************************
** This structure defines the version of a CLR for debugging purposes. **
** The wStructVersion field allows for future revisions to this structure to be **
@@ -708,403 +547,3 @@ interface ICLRRuntimeInfo : IUnknown
[out] BOOL *pbStarted,
[out] DWORD *pdwStartupFlags);
};
-
-/**************************************************************************************
- ** ICLRStrongName **
- ** These are the strong name APIs exposed by mscoree refactored into an interface. **
- ** The only change is the omission of StrongNameErrorInfo and having all methods **
- ** return the COM standard HRESULT. TODO (low-pri): **
- ** ideas what could be done here - we have an opportunity to make breaking changes, **
- ** cleanup etc.
- **************************************************************************************/
-[
- uuid(9FD93CCF-3280-4391-B3A9-96E1CDE77C8D),
- version(1.0),
- helpstring("CLR strong name interface"),
- local
-]
-interface ICLRStrongName : IUnknown
-{
- /**********************************************************************************
- ** Gets a hash of the specified assembly file, using the specified hash **
- ** algorithm. **
- ** Supersedes: GetHashFromAssemblyFile **
- **********************************************************************************/
- HRESULT GetHashFromAssemblyFile(
- [in] LPCSTR pszFilePath,
- [in, out] unsigned int *piHashAlg,
- [out, size_is(cchHash), length_is(*pchHash)] BYTE *pbHash,
- [in] DWORD cchHash,
- [out] DWORD *pchHash);
-
- /**********************************************************************************
- ** Gets a hash of the specified assembly file, using the specified hash **
- ** algorithm (Unicode version). **
- ** Supersedes: GetHashFromAssemblyFileW **
- **********************************************************************************/
- HRESULT GetHashFromAssemblyFileW(
- [in] LPCWSTR pwzFilePath,
- [in, out] unsigned int *piHashAlg,
- [out, size_is(cchHash), length_is(*pchHash)] BYTE *pbHash,
- [in] DWORD cchHash,
- [out] DWORD *pchHash);
-
- /**********************************************************************************
- ** Gets a hash of the assembly at the specified memory address, using the **
- ** specified hash algorithm. **
- ** Supersedes: GetHashFromBlob **
- **********************************************************************************/
- HRESULT GetHashFromBlob(
- [in] BYTE *pbBlob,
- [in] DWORD cchBlob,
- [in, out] unsigned int *piHashAlg,
- [out, size_is(cchHash), length_is(*pchHash)] BYTE *pbHash,
- [in] DWORD cchHash,
- [out] DWORD *pchHash);
-
- /**********************************************************************************
- ** Generates a hash over the contents of the specified file. **
- ** Supersedes: GetHashFromFile **
- **********************************************************************************/
- HRESULT GetHashFromFile(
- [in] LPCSTR pszFilePath,
- [in, out] unsigned int *piHashAlg,
- [out, size_is(cchHash), length_is(*pchHash)] BYTE *pbHash,
- [in] DWORD cchHash,
- [out] DWORD *pchHash);
-
- /**********************************************************************************
- ** Generates a hash over the contents of the specified file (Unicode version). **
- ** Supersedes: GetHashFromFileW **
- **********************************************************************************/
- HRESULT GetHashFromFileW(
- [in] LPCWSTR pwzFilePath,
- [in, out] unsigned int *piHashAlg,
- [out, size_is(cchHash), length_is(*pchHash)] BYTE *pbHash,
- [in] DWORD cchHash,
- [out] DWORD *pchHash);
-
- /**********************************************************************************
- ** Generates a hash over the contents of the file with the specified file **
- ** handle, using the specified hash algorithm. **
- ** Supersedes: GetHashFromHandle **
- **********************************************************************************/
- HRESULT GetHashFromHandle(
- [in] HANDLE hFile,
- [in, out] unsigned int *piHashAlg,
- [out, size_is(cchHash), length_is(*pchHash)] BYTE *pbHash,
- [in] DWORD cchHash,
- [out] DWORD *pchHash);
-
- /**********************************************************************************
- ** Determines whether two assemblies differ only by their strong name **
- ** signatures. **
- ** Supersedes: StrongNameCompareAssemblies **
- **********************************************************************************/
- HRESULT StrongNameCompareAssemblies(
- [in] LPCWSTR pwzAssembly1,
- [in] LPCWSTR pwzAssembly2,
- [out, retval] DWORD *pdwResult);
-
- /**********************************************************************************
- ** Frees memory that was allocated with a previous call to a strong name **
- ** function such as StrongNameGetPublicKey, StrongNameTokenFromPublicKey, or **
- ** StrongNameSignatureGeneration. **
- ** Supersedes: StrongNameFreeBuffer **
- **********************************************************************************/
- HRESULT StrongNameFreeBuffer(
- [in] BYTE *pbMemory);
-
- /**********************************************************************************
- ** Fills the specified buffer with the binary representation of the executable. **
- ** Supersedes: StrongNameGetBlob **
- **********************************************************************************/
- HRESULT StrongNameGetBlob(
- [in] LPCWSTR pwzFilePath,
- [in, out, size_is(*pcbBlob), length_is(*pcbBlob)] BYTE *pbBlob,
- [in, out] DWORD *pcbBlob);
-
- /**********************************************************************************
- ** Gets a binary representation of the assembly image at the specified memory **
- ** address. **
- ** Supersedes: StrongNameGetBlobFromImage **
- **********************************************************************************/
- HRESULT StrongNameGetBlobFromImage(
- [in, size_is(dwLength)] BYTE *pbBase,
- [in] DWORD dwLength,
- [out, size_is(*pcbBlob), length_is(*pcbBlob)] BYTE *pbBlob,
- [in, out] DWORD *pcbBlob);
-
- /**********************************************************************************
- ** Gets the public key from a private/public key pair. **
- ** Supersedes: StrongNameGetPublicKey **
- **********************************************************************************/
- HRESULT StrongNameGetPublicKey(
- [in] LPCWSTR pwzKeyContainer,
- [in] BYTE *pbKeyBlob,
- [in] ULONG cbKeyBlob,
- [out] BYTE **ppbPublicKeyBlob,
- [out] ULONG *pcbPublicKeyBlob);
-
- /**********************************************************************************
- ** Gets the buffer size required for a hash, using the specified hash **
- ** algorithm. **
- ** Supersedes: StrongNameHashSize **
- **********************************************************************************/
- HRESULT StrongNameHashSize(
- [in] ULONG ulHashAlg,
- [out, retval] DWORD *pcbSize);
-
- /**********************************************************************************
- ** Deletes the specified key container. **
- ** Supersedes: StrongNameKeyDelete **
- **********************************************************************************/
- HRESULT StrongNameKeyDelete(
- [in] LPCWSTR pwzKeyContainer);
-
- /**********************************************************************************
- ** Creates a new public/private key pair for strong name use. **
- ** Supersedes: StrongNameKeyGen **
- **********************************************************************************/
- HRESULT StrongNameKeyGen(
- [in] LPCWSTR pwzKeyContainer,
- [in] DWORD dwFlags,
- [out] BYTE **ppbKeyBlob,
- [out] ULONG *pcbKeyBlob);
-
- /**********************************************************************************
- ** Generates a new public/private key pair with the specified key size, for **
- ** strong name use. **
- ** Supersedes: StrongNameKeyGenEx **
- **********************************************************************************/
- HRESULT StrongNameKeyGenEx(
- [in] LPCWSTR pwzKeyContainer,
- [in] DWORD dwFlags,
- [in] DWORD dwKeySize,
- [out] BYTE **ppbKeyBlob,
- [out] ULONG *pcbKeyBlob);
-
- /**********************************************************************************
- ** Imports a public/private key pair into a container. **
- ** Supersedes: StrongNameKeyInstall **
- **********************************************************************************/
- HRESULT StrongNameKeyInstall(
- [in] LPCWSTR pwzKeyContainer,
- [in] BYTE *pbKeyBlob,
- [in] ULONG cbKeyBlob);
-
- /**********************************************************************************
- ** Generates a strong name signature for the specified assembly. **
- ** Supersedes: StrongNameSignatureGeneration **
- **********************************************************************************/
- HRESULT StrongNameSignatureGeneration(
- [in] LPCWSTR pwzFilePath,
- [in] LPCWSTR pwzKeyContainer,
- [in] BYTE *pbKeyBlob,
- [in] ULONG cbKeyBlob,
- [out] BYTE **ppbSignatureBlob,
- [out] ULONG *pcbSignatureBlob);
-
- /**********************************************************************************
- ** Generates a strong name signature for the specified assembly, according to **
- ** the specified flags. **
- ** Supersedes: StrongNameSignatureGenerationEx **
- **********************************************************************************/
- HRESULT StrongNameSignatureGenerationEx(
- [in] LPCWSTR wszFilePath,
- [in] LPCWSTR wszKeyContainer,
- [in] BYTE *pbKeyBlob,
- [in] ULONG cbKeyBlob,
- [out] BYTE **ppbSignatureBlob,
- [out] ULONG *pcbSignatureBlob,
- [in] DWORD dwFlags);
-
- /**********************************************************************************
- ** Returns the size of the strong name signature. **
- ** Supersedes: StrongNameSignatureSize **
- **********************************************************************************/
- HRESULT StrongNameSignatureSize(
- [in] BYTE *pbPublicKeyBlob,
- [in] ULONG cbPublicKeyBlob,
- [in] DWORD *pcbSize);
-
- /**********************************************************************************
- ** Gets a value indicating whether the assembly manifest at the supplied path **
- ** contains a strong name signature, which is verified according to the **
- ** specified flags. **
- ** Supersedes: StrongNameSignatureVerification **
- **********************************************************************************/
- HRESULT StrongNameSignatureVerification(
- [in] LPCWSTR pwzFilePath,
- [in] DWORD dwInFlags,
- [out, retval] DWORD *pdwOutFlags);
-
- /**********************************************************************************
- ** Gets a value indicating whether the assembly manifest at the supplied path **
- ** contains a strong name signature. **
- ** Supersedes: StrongNameSignatureVerificationEx **
- **********************************************************************************/
- HRESULT StrongNameSignatureVerificationEx(
- [in] LPCWSTR pwzFilePath,
- [in] BOOLEAN fForceVerification,
- [out, retval] BOOLEAN *pfWasVerified);
-
- /**********************************************************************************
- ** Verifies that an assembly that has already been mapped to memory is valid **
- ** for the associated public key. **
- ** Supersedes: StrongNameSignatureVerificationFromImage **
- **********************************************************************************/
- HRESULT StrongNameSignatureVerificationFromImage(
- [in] BYTE *pbBase,
- [in] DWORD dwLength,
- [in] DWORD dwInFlags,
- [out, retval] DWORD *pdwOutFlags);
-
- /**********************************************************************************
- ** Creates a strong name token from the specified assembly file. **
- ** Supersedes: StrongNameTokenFromAssembly **
- **********************************************************************************/
- HRESULT StrongNameTokenFromAssembly(
- [in] LPCWSTR pwzFilePath,
- [out] BYTE **ppbStrongNameToken,
- [out] ULONG *pcbStrongNameToken);
-
- /**********************************************************************************
- ** Creates a strong name token from the specified assembly file, and returns **
- ** the public key that the token represents. **
- ** Supersedes: StrongNameTokenFromAssemblyEx **
- **********************************************************************************/
- HRESULT StrongNameTokenFromAssemblyEx(
- [in] LPCWSTR pwzFilePath,
- [out] BYTE **ppbStrongNameToken,
- [out] ULONG *pcbStrongNameToken,
- [out] BYTE **ppbPublicKeyBlob,
- [out] ULONG *pcbPublicKeyBlob);
- /**********************************************************************************
- ** Gets a token representing a public key. A strong name token is the shortened **
- ** form of a public key. **
- ** Supersedes: StrongNameTokenFromPublicKey **
- **********************************************************************************/
- HRESULT StrongNameTokenFromPublicKey(
- [in] BYTE *pbPublicKeyBlob,
- [in] ULONG cbPublicKeyBlob,
- [out] BYTE **ppbStrongNameToken,
- [out] ULONG *pcbStrongNameToken);
-}; // interface ICLRStrongName
-
-/**************************************************************************************
- ** ICLRStrongName2 **
- ** Strongname Api's **
- **************************************************************************************/
-[
- uuid(C22ED5C5-4B59-4975-90EB-85EA55C0069B),
- version(1.0),
- helpstring("CLR strong name interface 2"),
- local
-]
-interface ICLRStrongName2 : IUnknown
-{
- /**********************************************************************************
- ** Gets the public key from a private/public key pair, specifying a hash **
- ** algorithm and a signature algorithm. **
- **********************************************************************************/
- HRESULT StrongNameGetPublicKeyEx(
- [in] LPCWSTR pwzKeyContainer,
- [in] BYTE *pbKeyBlob,
- [in] ULONG cbKeyBlob,
- [out] BYTE **ppbPublicKeyBlob,
- [out] ULONG *pcbPublicKeyBlob,
- [in] ULONG uHashAlgId, // specify algorithm, or set to 0 for default
- [in] ULONG uReserved); // reserved for future use, always set to 0
-
- /**********************************************************************************
- ** Verify the signature of a strongly named assembly, providing a mapping from **
- ** the ECMA key to a real key **
- **********************************************************************************/
- HRESULT StrongNameSignatureVerificationEx2(
- [in] LPCWSTR wszFilePath,
- [in] BOOLEAN fForceVerification,
- [in] BYTE *pbEcmaPublicKey,
- [in] DWORD cbEcmaPublicKey,
- [out] BOOLEAN *pfWasVerified);
-}; // interface ICLRStrongName2
-
-/*************************************************************************************
-** ICLRStrongName3 **
-** StrongName digest signing APIs **
-**************************************************************************************/
-[
- uuid(22c7089b-bbd3-414a-b698-210f263f1fed),
- version(1.0),
- helpstring("CLR strong name digest signing interface"),
- local
-]
-interface ICLRStrongName3 : IUnknown
-{
- // Generate the digest of an input assembly, which can be signed with StrongNameDigestSign
- HRESULT StrongNameDigestGenerate(
- [in] LPCWSTR wszFilePath,
- [out] BYTE** ppbDigestBlob,
- [out] ULONG* pcbDigestBlob,
- [in] DWORD dwFlags);
-
- // Sign an the digest of an assembly calculated by StrongNameDigestGenerate
- HRESULT StrongNameDigestSign(
- [in] LPCWSTR wszKeyContainer,
- [in, size_is(cbKeyBlob)] BYTE* pbKeyBlob,
- [in] ULONG cbKeyBlob,
- [in, size_is(cbDigestBlob)] BYTE* pbDigestBlob,
- [in] ULONG cbDigestBlob,
- [in] DWORD hashAlgId,
- [out] BYTE** ppbSignatureBlob,
- [out] ULONG* pcbSignatureBlob,
- [in] DWORD dwFlags);
-
- // Embed a digest signature generated with StrongNameDigestSign into an assembly
- HRESULT StrongNameDigestEmbed(
- [in] LPCWSTR wszFilePath,
- [in, size_is(cbSignatureBlob)] BYTE* pbSignatureBlob,
- [in] ULONG cbSignatureBlob);
-};
-
-[
- uuid(5288DA6A-A8D3-43a1-8365-37DB0E7D5943),
- version(1.0),
-]
-library CLRMetaHost
-{
- interface ICLRMetaHost;
- interface ICLRMetaHostPolicy;
- interface ICLRDebuggingLibraryProvider;
- interface ICLRDebugging;
- interface ICLRRuntimeInfo;
- interface ICLRStrongName;
-
- // Scenario: EXE activation
- // 1. ICLRMetaHostPolicy::GetRequestedRuntime
- // 2. ICLRRuntimeInfo::GetProcAddress("ExeMain")
- // 3. ExeMain() - TODO: Add a hosting API to execute an EXE?
-
- // Scenario: Hosting with custom policy
- // 1. ICLRMetaHost::GetFileVersion
- // 2. ICLRMetaHost::EnumerateInstalledRuntimes
- // 3. ICLRRuntimeInfo::IsLoaded/IsStarted
- // ...
-
- // Scenario: Debugger attach for v1.0 to v4 using v2 lookalike interface
- // ICLRMetaHost::EnumerateLoadedRuntimes
- // ICLRRuntimeInfo::GetInterface(CLSID_CLRDebuggingLegacy, IID_ICorDebug)
-
- // Scenario: Profiler attach for v4
- // ICLRMetaHost::EnumerateLoadedRuntimes
-
- // Scenario: An installer needs to modify configuration of supported runtimes
- // 1. ICLRMetaHost::EnumerateInstalledRuntimes
- // 2. ICLRRuntimeInfo::GetVersionString
- // 3. <policy>
- // 4. ICLRRuntimeInfo::GetRuntimeDirectory
- // 5. <modify the config file under the runtime dir>
-
-}; // library CLRMetaHost
-
-cpp_quote("#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)")
diff --git a/src/inc/mscoreepriv.h b/src/inc/mscoreepriv.h
deleted file mode 100644
index df07612010..0000000000
--- a/src/inc/mscoreepriv.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// 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.
-//
-
-#ifndef __MSCOREEPRIV_H__
-#define __MSCOREEPRIV_H__
-
-
-typedef enum
-{
- RUNTIME_INFO_CONSIDER_POST_2_0 = 0x80, // consider v4.0+ versions
- RUNTIME_INFO_EMULATE_EXE_LAUNCH = 0x100, // Binds as if the provided information were being use in a new process
- RUNTIME_INFO_APPEND_FORCE_PERFORMANCE_COUNTER_UNIQUE_SHARED_MEMORY_READS_SETTING_TO_VERSION // appends either !0 (false), !1 (true) or !2 (unset) depending on the value of forcePerformanceCounterUniqueSharedMemoryReads in the runtime section of the config
- = 0x200,
-} RUNTIME_INFO_FLAGS_FOR_SHARED_COMPONENTS;
-
-
-
-#endif //__MSCOREEPRIV_H__
-
diff --git a/src/inc/switches.h b/src/inc/switches.h
index e47c78ce2d..60034602c3 100644
--- a/src/inc/switches.h
+++ b/src/inc/switches.h
@@ -47,13 +47,6 @@
#if 0
#define APPDOMAIN_STATE
- #define BREAK_ON_UNLOAD
- #define AD_LOG_MEMORY
- #define AD_NO_UNLOAD
- #define AD_SNAPSHOT
- #define BREAK_META_ACCESS
- #define AD_BREAK_ON_CANNOT_UNLOAD
- #define BREAK_ON_CLSLOAD
// Enable to track details of EESuspension
#define TIME_SUSPEND
diff --git a/src/inc/utilcode.h b/src/inc/utilcode.h
index cd847366d5..a3123efa84 100644
--- a/src/inc/utilcode.h
+++ b/src/inc/utilcode.h
@@ -4200,7 +4200,7 @@ void TrimWhiteSpace(__inout_ecount(*pcch) LPCWSTR *pwsz, __inout LPDWORD pcch);
HRESULT Utf2Quick(
LPCUTF8 pStr, // The string to convert.
CQuickArray<WCHAR> &rStr, // The QuickArray<WCHAR> to convert it into.
- int iCurLen); // Inital characters in the array to leave (default 0).
+ int iCurLen = 0); // Initial characters in the array to leave (default 0).
//*****************************************************************************
// Extract the movl 64-bit unsigned immediate from an IA64 bundle
@@ -5186,9 +5186,6 @@ HMODULE LoadLocalizedResourceDLLForSDK(_In_z_ LPCWSTR wzResourceDllName, _In_opt
typedef void* (__cdecl *LocalizedFileHandler)(LPCWSTR);
void* FindLocalizedFile(_In_z_ LPCWSTR wzResourceDllName, LocalizedFileHandler lfh, _In_opt_z_ LPCWSTR modulePath=NULL);
-BOOL IsClrHostedLegacyComObject(REFCLSID rclsid);
-
-
// Helper to support termination due to heap corruption
diff --git a/src/jit/assertionprop.cpp b/src/jit/assertionprop.cpp
index 0ec9f4b55b..1ee56b22d6 100644
--- a/src/jit/assertionprop.cpp
+++ b/src/jit/assertionprop.cpp
@@ -1989,11 +1989,23 @@ AssertionInfo Compiler::optAssertionGenJtrue(GenTree* tree)
op2 = op1->gtCall.gtCallLateArgs->gtOp.gtOp2;
op1 = op1->gtCall.gtCallLateArgs;
+ // For the assertion, ensure op1 is the object being tested.
+ // Morph may have swizzled the operand order.
+ GenTree* op1op = op1->gtOp.gtOp1;
+
+ if (op1op->TypeGet() == TYP_I_IMPL)
+ {
+ jitstd::swap(op1, op2);
+ op1op = op1->gtOp.gtOp1;
+ }
+
+ assert(op1op->TypeGet() == TYP_REF);
+
// Reverse the assertion
assert(assertionKind == OAK_EQUAL || assertionKind == OAK_NOT_EQUAL);
assertionKind = (assertionKind == OAK_EQUAL) ? OAK_NOT_EQUAL : OAK_EQUAL;
- if (op1->gtOp.gtOp1->gtOper == GT_LCL_VAR)
+ if (op1op->OperIs(GT_LCL_VAR))
{
return optCreateJtrueAssertions(op1, op2, assertionKind);
}
diff --git a/src/jit/codegen.h b/src/jit/codegen.h
index b0534c0f3a..c4af197d2b 100644
--- a/src/jit/codegen.h
+++ b/src/jit/codegen.h
@@ -261,7 +261,7 @@ protected:
regNumber tmpReg,
bool inUnwindRegion = false);
- void genStackPointerAdjustment(ssize_t spAdjustment, regNumber tmpReg, bool* pTmpRegIsZero);
+ void genStackPointerAdjustment(ssize_t spAdjustment, regNumber tmpReg, bool* pTmpRegIsZero, bool reportUnwindData);
void genPrologSaveRegPair(regNumber reg1,
regNumber reg2,
@@ -592,7 +592,7 @@ public:
void siBeginBlock(BasicBlock* block);
void siEndBlock(BasicBlock* block);
-
+ // Closes the "ScopeInfo" of the tracked variables that has become dead.
virtual void siUpdate();
void siCheckVarScope(unsigned varNum, IL_OFFSET offs);
diff --git a/src/jit/codegenarm64.cpp b/src/jit/codegenarm64.cpp
index a9caf107a1..9d1959e850 100644
--- a/src/jit/codegenarm64.cpp
+++ b/src/jit/codegenarm64.cpp
@@ -145,11 +145,12 @@ bool CodeGen::genInstrWithConstant(instruction ins,
// tmpReg - an available temporary register
// pTmpRegIsZero - If we use tmpReg, and pTmpRegIsZero is non-null, we set *pTmpRegIsZero to 'false'.
// Otherwise, we don't touch it.
+// reportUnwindData - If true, report the change in unwind data. Otherwise, do not report it.
//
// Return Value:
// None.
-void CodeGen::genStackPointerAdjustment(ssize_t spDelta, regNumber tmpReg, bool* pTmpRegIsZero)
+void CodeGen::genStackPointerAdjustment(ssize_t spDelta, regNumber tmpReg, bool* pTmpRegIsZero, bool reportUnwindData)
{
// Even though INS_add is specified here, the encoder will choose either
// an INS_add or an INS_sub and encode the immediate as a positive value
@@ -162,13 +163,16 @@ void CodeGen::genStackPointerAdjustment(ssize_t spDelta, regNumber tmpReg, bool*
}
}
- // spDelta is negative in the prolog, positive in the epilog, but we always tell the unwind codes the positive
- // value.
- ssize_t spDeltaAbs = abs(spDelta);
- unsigned unwindSpDelta = (unsigned)spDeltaAbs;
- assert((ssize_t)unwindSpDelta == spDeltaAbs); // make sure that it fits in a unsigned
+ if (reportUnwindData)
+ {
+ // spDelta is negative in the prolog, positive in the epilog, but we always tell the unwind codes the positive
+ // value.
+ ssize_t spDeltaAbs = abs(spDelta);
+ unsigned unwindSpDelta = (unsigned)spDeltaAbs;
+ assert((ssize_t)unwindSpDelta == spDeltaAbs); // make sure that it fits in a unsigned
- compiler->unwindAllocStack(unwindSpDelta);
+ compiler->unwindAllocStack(unwindSpDelta);
+ }
}
//------------------------------------------------------------------------
@@ -220,13 +224,13 @@ void CodeGen::genPrologSaveRegPair(regNumber reg1,
needToSaveRegs = false;
}
- else // (spDelta < -512))
+ else // (spOffset != 0) || (spDelta < -512)
{
// We need to do SP adjustment separately from the store; we can't fold in a pre-indexed addressing and the
// non-zero offset.
// generate sub SP,SP,imm
- genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero);
+ genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero, /* reportUnwindData */ true);
}
}
@@ -276,16 +280,32 @@ void CodeGen::genPrologSaveReg(regNumber reg1, int spOffset, int spDelta, regNum
assert(spDelta <= 0);
assert((spDelta % 16) == 0); // SP changes must be 16-byte aligned
+ bool needToSaveRegs = true;
if (spDelta != 0)
{
- // generate sub SP,SP,imm
- genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero);
+ if ((spOffset == 0) && (spDelta >= -256))
+ {
+ // We can use pre-index addressing.
+ // str REG, [SP, #spDelta]!
+ getEmitter()->emitIns_R_R_I(INS_str, EA_PTRSIZE, reg1, REG_SPBASE, spDelta, INS_OPTS_PRE_INDEX);
+ compiler->unwindSaveRegPreindexed(reg1, spDelta);
+
+ needToSaveRegs = false;
+ }
+ else // (spOffset != 0) || (spDelta < -256)
+ {
+ // generate sub SP,SP,imm
+ genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero, /* reportUnwindData */ true);
+ }
}
- // str REG, [SP, #offset]
- // 64-bit STR offset range: 0 to 32760, multiple of 8.
- getEmitter()->emitIns_R_R_I(INS_str, EA_PTRSIZE, reg1, REG_SPBASE, spOffset);
- compiler->unwindSaveReg(reg1, spOffset);
+ if (needToSaveRegs)
+ {
+ // str REG, [SP, #offset]
+ // 64-bit STR offset range: 0 to 32760, multiple of 8.
+ getEmitter()->emitIns_R_R_I(INS_str, EA_PTRSIZE, reg1, REG_SPBASE, spOffset);
+ compiler->unwindSaveReg(reg1, spOffset);
+ }
}
//------------------------------------------------------------------------
@@ -333,7 +353,7 @@ void CodeGen::genEpilogRestoreRegPair(regNumber reg1,
getEmitter()->emitIns_R_R_R_I(INS_ldp, EA_PTRSIZE, reg1, reg2, REG_SPBASE, spDelta, INS_OPTS_POST_INDEX);
compiler->unwindSaveRegPairPreindexed(reg1, reg2, -spDelta);
}
- else // (spDelta > 504))
+ else // (spOffset != 0) || (spDelta > 504)
{
// Can't fold in the SP change; need to use a separate ADD instruction.
@@ -342,7 +362,7 @@ void CodeGen::genEpilogRestoreRegPair(regNumber reg1,
compiler->unwindSaveRegPair(reg1, reg2, spOffset);
// generate add SP,SP,imm
- genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero);
+ genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero, /* reportUnwindData */ true);
}
}
else
@@ -381,14 +401,30 @@ void CodeGen::genEpilogRestoreReg(regNumber reg1, int spOffset, int spDelta, reg
assert(spDelta >= 0);
assert((spDelta % 16) == 0); // SP changes must be 16-byte aligned
- // ldr reg1, [SP, #offset]
- getEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, reg1, REG_SPBASE, spOffset);
- compiler->unwindSaveReg(reg1, spOffset);
-
if (spDelta != 0)
{
- // generate add SP,SP,imm
- genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero);
+ if ((spOffset == 0) && (spDelta <= 255))
+ {
+ // We can use post-index addressing.
+ // ldr REG, [SP], #spDelta
+ getEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, reg1, REG_SPBASE, spDelta, INS_OPTS_POST_INDEX);
+ compiler->unwindSaveRegPreindexed(reg1, -spDelta);
+ }
+ else // (spOffset != 0) || (spDelta > 255)
+ {
+ // ldr reg1, [SP, #offset]
+ getEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, reg1, REG_SPBASE, spOffset);
+ compiler->unwindSaveReg(reg1, spOffset);
+
+ // generate add SP,SP,imm
+ genStackPointerAdjustment(spDelta, tmpReg, pTmpRegIsZero, /* reportUnwindData */ true);
+ }
+ }
+ else
+ {
+ // ldr reg1, [SP, #offset]
+ getEmitter()->emitIns_R_R_I(INS_ldr, EA_PTRSIZE, reg1, REG_SPBASE, spOffset);
+ compiler->unwindSaveReg(reg1, spOffset);
}
}
@@ -603,7 +639,7 @@ void CodeGen::genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowe
{
// Currently this is the case for varargs only
// whose size is MAX_REG_ARG * REGSIZE_BYTES = 64 bytes.
- genStackPointerAdjustment(spDelta, REG_NA, nullptr);
+ genStackPointerAdjustment(spDelta, REG_NA, nullptr, /* reportUnwindData */ true);
}
return;
}
@@ -613,28 +649,22 @@ void CodeGen::genSaveCalleeSavedRegistersHelp(regMaskTP regsToSaveMask, int lowe
// We also can save FP and LR, even though they are not in RBM_CALLEE_SAVED.
assert(regsToSaveCount <= genCountBits(RBM_CALLEE_SAVED | RBM_FP | RBM_LR));
- if (genSaveFpLrWithAllCalleeSavedRegisters)
- {
- // TODO: always save int regs higher than float, to be consistent?
- regMaskTP maskSaveRegsFloat = regsToSaveMask & RBM_ALLFLOAT;
- regMaskTP maskSaveRegsInt = regsToSaveMask & ~maskSaveRegsFloat;
+ // Save integer registers at higher addresses than floating-point registers.
- if (maskSaveRegsFloat != RBM_NONE)
- {
- genSaveCalleeSavedRegisterGroup(maskSaveRegsFloat, spDelta, lowestCalleeSavedOffset);
- spDelta = 0;
- lowestCalleeSavedOffset += genCountBits(maskSaveRegsFloat) * FPSAVE_REGSIZE_BYTES;
- }
+ regMaskTP maskSaveRegsFloat = regsToSaveMask & RBM_ALLFLOAT;
+ regMaskTP maskSaveRegsInt = regsToSaveMask & ~maskSaveRegsFloat;
- if (maskSaveRegsInt != RBM_NONE)
- {
- genSaveCalleeSavedRegisterGroup(maskSaveRegsInt, spDelta, lowestCalleeSavedOffset);
- // No need to update spDelta, lowestCalleeSavedOffset since they're not used after this.
- }
+ if (maskSaveRegsFloat != RBM_NONE)
+ {
+ genSaveCalleeSavedRegisterGroup(maskSaveRegsFloat, spDelta, lowestCalleeSavedOffset);
+ spDelta = 0;
+ lowestCalleeSavedOffset += genCountBits(maskSaveRegsFloat) * FPSAVE_REGSIZE_BYTES;
}
- else
+
+ if (maskSaveRegsInt != RBM_NONE)
{
- genSaveCalleeSavedRegisterGroup(regsToSaveMask, spDelta, lowestCalleeSavedOffset);
+ genSaveCalleeSavedRegisterGroup(maskSaveRegsInt, spDelta, lowestCalleeSavedOffset);
+ // No need to update spDelta, lowestCalleeSavedOffset since they're not used after this.
}
}
@@ -722,7 +752,7 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
{
// Currently this is the case for varargs only
// whose size is MAX_REG_ARG * REGSIZE_BYTES = 64 bytes.
- genStackPointerAdjustment(spDelta, REG_NA, nullptr);
+ genStackPointerAdjustment(spDelta, REG_NA, nullptr, /* reportUnwindData */ true);
}
return;
}
@@ -736,31 +766,25 @@ void CodeGen::genRestoreCalleeSavedRegistersHelp(regMaskTP regsToRestoreMask, in
static_assert_no_msg(REGSIZE_BYTES == FPSAVE_REGSIZE_BYTES);
int spOffset = lowestCalleeSavedOffset + regsToRestoreCount * REGSIZE_BYTES;
- if (genSaveFpLrWithAllCalleeSavedRegisters)
- {
- // TODO: always save int regs higher than float, to be consistent?
- regMaskTP maskRestoreRegsFloat = regsToRestoreMask & RBM_ALLFLOAT;
- regMaskTP maskRestoreRegsInt = regsToRestoreMask & ~maskRestoreRegsFloat;
+ // Save integer registers at higher addresses than floating-point registers.
- // Restore in the opposite order of saving.
+ regMaskTP maskRestoreRegsFloat = regsToRestoreMask & RBM_ALLFLOAT;
+ regMaskTP maskRestoreRegsInt = regsToRestoreMask & ~maskRestoreRegsFloat;
- if (maskRestoreRegsInt != RBM_NONE)
- {
- int spIntDelta = (maskRestoreRegsFloat != RBM_NONE) ? 0 : spDelta; // should we delay the SP adjustment?
- genRestoreCalleeSavedRegisterGroup(maskRestoreRegsInt, spIntDelta, spOffset);
- spOffset -= genCountBits(maskRestoreRegsInt) * REGSIZE_BYTES;
- }
+ // Restore in the opposite order of saving.
- if (maskRestoreRegsFloat != RBM_NONE)
- {
- // If there is any spDelta, it must be used here.
- genRestoreCalleeSavedRegisterGroup(maskRestoreRegsFloat, spDelta, spOffset);
- // No need to update spOffset since it's not used after this.
- }
+ if (maskRestoreRegsInt != RBM_NONE)
+ {
+ int spIntDelta = (maskRestoreRegsFloat != RBM_NONE) ? 0 : spDelta; // should we delay the SP adjustment?
+ genRestoreCalleeSavedRegisterGroup(maskRestoreRegsInt, spIntDelta, spOffset);
+ spOffset -= genCountBits(maskRestoreRegsInt) * REGSIZE_BYTES;
}
- else
+
+ if (maskRestoreRegsFloat != RBM_NONE)
{
- genRestoreCalleeSavedRegisterGroup(regsToRestoreMask, spDelta, spOffset);
+ // If there is any spDelta, it must be used here.
+ genRestoreCalleeSavedRegisterGroup(maskRestoreRegsFloat, spDelta, spOffset);
+ // No need to update spOffset since it's not used after this.
}
}
@@ -1088,7 +1112,7 @@ void CodeGen::genFuncletProlog(BasicBlock* block)
assert(genFuncletInfo.fiSpDelta1 >= -512);
// generate sub SP,SP,imm
- genStackPointerAdjustment(genFuncletInfo.fiSpDelta1, REG_NA, nullptr);
+ genStackPointerAdjustment(genFuncletInfo.fiSpDelta1, REG_NA, nullptr, /* reportUnwindData */ true);
assert(genFuncletInfo.fiSpDelta2 == 0);
@@ -1113,7 +1137,7 @@ void CodeGen::genFuncletProlog(BasicBlock* block)
assert(genFuncletInfo.fiSpDelta1 >= -512);
// generate sub SP,SP,imm
- genStackPointerAdjustment(genFuncletInfo.fiSpDelta1, REG_NA, nullptr);
+ genStackPointerAdjustment(genFuncletInfo.fiSpDelta1, REG_NA, nullptr, /* reportUnwindData */ true);
assert(genFuncletInfo.fiSpDelta2 == 0);
}
@@ -1134,7 +1158,7 @@ void CodeGen::genFuncletProlog(BasicBlock* block)
assert(genFuncletInfo.fiSpDelta2 < 0);
// generate sub SP,SP,imm
- genStackPointerAdjustment(genFuncletInfo.fiSpDelta2, REG_R2, nullptr);
+ genStackPointerAdjustment(genFuncletInfo.fiSpDelta2, REG_R2, nullptr, /* reportUnwindData */ true);
}
// This is the end of the OS-reported prolog for purposes of unwinding
@@ -1215,7 +1239,7 @@ void CodeGen::genFuncletEpilog()
assert(genFuncletInfo.fiSpDelta2 < 0);
// generate add SP,SP,imm
- genStackPointerAdjustment(-genFuncletInfo.fiSpDelta2, REG_R2, nullptr);
+ genStackPointerAdjustment(-genFuncletInfo.fiSpDelta2, REG_R2, nullptr, /* reportUnwindData */ true);
}
regMaskTP regsToRestoreMask = maskRestoreRegsInt | maskRestoreRegsFloat;
@@ -1246,7 +1270,7 @@ void CodeGen::genFuncletEpilog()
assert(genFuncletInfo.fiSpDelta1 >= -512);
// generate add SP,SP,imm
- genStackPointerAdjustment(-genFuncletInfo.fiSpDelta1, REG_NA, nullptr);
+ genStackPointerAdjustment(-genFuncletInfo.fiSpDelta1, REG_NA, nullptr, /* reportUnwindData */ true);
assert(genFuncletInfo.fiSpDelta2 == 0);
}
@@ -1263,7 +1287,7 @@ void CodeGen::genFuncletEpilog()
assert(genFuncletInfo.fiSpDelta1 >= -512);
// generate add SP,SP,imm
- genStackPointerAdjustment(-genFuncletInfo.fiSpDelta1, REG_NA, nullptr);
+ genStackPointerAdjustment(-genFuncletInfo.fiSpDelta1, REG_NA, nullptr, /* reportUnwindData */ true);
assert(genFuncletInfo.fiSpDelta2 == 0);
}
@@ -1276,7 +1300,7 @@ void CodeGen::genFuncletEpilog()
assert(genFuncletInfo.fiSpDelta1 >= -240);
// generate add SP,SP,imm
- genStackPointerAdjustment(-genFuncletInfo.fiSpDelta1, REG_NA, nullptr);
+ genStackPointerAdjustment(-genFuncletInfo.fiSpDelta1, REG_NA, nullptr, /* reportUnwindData */ true);
}
inst_RV(INS_ret, REG_LR, TYP_I_IMPL);
@@ -5236,66 +5260,21 @@ void CodeGen::genHWIntrinsicSimdBinaryOp(GenTreeHWIntrinsic* node)
}
//------------------------------------------------------------------------
-// genHWIntrinsicSwitchTable:
-//
-// Generate code for an immediate switch table
-//
-// In cases where an instruction only supports const immediate operands, we
-// need to generate functionally correct code when the operand is not constant
-//
-// This is required by the HW Intrinsic design to handle indirect calls, such as:
-// debugger calls
-// reflection
-// call backs
-//
-// Generated code implements a switch of this form
-//
-// switch (swReg)
-// {
-// case 0:
-// ins0; // emitSwCase(0)
-// break;
-// case 1:
-// ins1; // emitSwCase(1)
-// break;
-// ...
-// ...
-// ...
-// case swMax - 1:
-// insLast; // emitSwCase(swMax - 1)
-// break;
-// default:
-// throw ArgumentOutOfRangeException
-// }
-//
-// Generated code looks like:
-//
-// cmp swReg, #swMax
-// b.hs ThrowArgumentOutOfRangeExceptionHelper
-// adr tmpReg, labelFirst
-// add tmpReg, tmpReg, swReg, LSL #3
-// b [tmpReg]
-// labelFirst:
-// ins0
-// b labelBreakTarget
-// ins1
-// b labelBreakTarget
-// ...
-// ...
-// ...
-// insLast
-// b labelBreakTarget
-// labelBreakTarget:
-//
+// genHWIntrinsicSwitchTable: generate the jump-table for imm-intrinsics
+// with non-constant argument
//
// Arguments:
// swReg - register containing the switch case to execute
// tmpReg - temporary integer register for calculating the switch indirect branch target
-// swMax - the number of switch cases. If swReg >= swMax throw SCK_ARG_RNG_EXCPN
-// emitSwCase - function like argument taking an immediate value and emitting one instruction
+// swMax - the number of switch cases.
+// emitSwCase - lambda to generate an individual switch case
//
-// Return Value:
-// None.
+// Notes:
+// Used for cases where an instruction only supports immediate operands,
+// but at jit time the operand is not a constant.
+//
+// The importer is responsible for inserting an upstream range check
+// (GT_HW_INTRINSIC_CHK) for swReg, so no range check is needed here.
//
template <typename HWIntrinsicSwitchCaseBody>
void CodeGen::genHWIntrinsicSwitchTable(regNumber swReg,
@@ -5309,27 +5288,24 @@ void CodeGen::genHWIntrinsicSwitchTable(regNumber swReg,
assert(genIsValidIntReg(tmpReg));
assert(genIsValidIntReg(swReg));
- BasicBlock* labelFirst = genCreateTempLabel();
- BasicBlock* labelBreakTarget = genCreateTempLabel();
-
- // Detect and throw out of range exception
- getEmitter()->emitIns_R_I(INS_cmp, EA_4BYTE, swReg, swMax);
-
- genJumpToThrowHlpBlk(EJ_hs, SCK_ARG_RNG_EXCPN);
+ BasicBlock* switchTableBeg = genCreateTempLabel();
+ BasicBlock* switchTableEnd = genCreateTempLabel();
// Calculate switch target
- labelFirst->bbFlags |= BBF_JMP_TARGET;
+ //
+ // Each switch table case needs exactly 8 bytes of code.
+ switchTableBeg->bbFlags |= BBF_JMP_TARGET;
- // tmpReg = labelFirst
- getEmitter()->emitIns_R_L(INS_adr, EA_PTRSIZE, labelFirst, tmpReg);
+ // tmpReg = switchTableBeg
+ getEmitter()->emitIns_R_L(INS_adr, EA_PTRSIZE, switchTableBeg, tmpReg);
- // tmpReg = labelFirst + swReg * 8
+ // tmpReg = switchTableBeg + swReg * 8
getEmitter()->emitIns_R_R_R_I(INS_add, EA_PTRSIZE, tmpReg, tmpReg, swReg, 3, INS_OPTS_LSL);
// br tmpReg
getEmitter()->emitIns_R(INS_br, EA_PTRSIZE, tmpReg);
- genDefineTempLabel(labelFirst);
+ genDefineTempLabel(switchTableBeg);
for (int i = 0; i < swMax; ++i)
{
unsigned prevInsCount = getEmitter()->emitInsCount;
@@ -5338,11 +5314,11 @@ void CodeGen::genHWIntrinsicSwitchTable(regNumber swReg,
assert(getEmitter()->emitInsCount == prevInsCount + 1);
- inst_JMP(EJ_jmp, labelBreakTarget);
+ inst_JMP(EJ_jmp, switchTableEnd);
assert(getEmitter()->emitInsCount == prevInsCount + 2);
}
- genDefineTempLabel(labelBreakTarget);
+ genDefineTempLabel(switchTableEnd);
}
//------------------------------------------------------------------------
@@ -6419,14 +6395,14 @@ void CodeGen::genArm64EmitterUnitTests()
//
genDefineTempLabel(genCreateTempLabel());
- theEmitter->emitIns_R_R_R(INS_casb, EA_1BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_casab, EA_1BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_casalb, EA_1BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_caslb, EA_1BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_cash, EA_2BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_casah, EA_2BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_casalh, EA_2BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_caslh, EA_2BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_casb, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_casab, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_casalb, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_caslb, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_cash, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_casah, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_casalh, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_caslh, EA_4BYTE, REG_R8, REG_R9, REG_R10);
theEmitter->emitIns_R_R_R(INS_cas, EA_4BYTE, REG_R8, REG_R9, REG_R10);
theEmitter->emitIns_R_R_R(INS_casa, EA_4BYTE, REG_R8, REG_R9, REG_R10);
theEmitter->emitIns_R_R_R(INS_casal, EA_4BYTE, REG_R8, REG_R9, REG_R10);
@@ -6435,14 +6411,14 @@ void CodeGen::genArm64EmitterUnitTests()
theEmitter->emitIns_R_R_R(INS_casa, EA_8BYTE, REG_R8, REG_R9, REG_R10);
theEmitter->emitIns_R_R_R(INS_casal, EA_8BYTE, REG_R8, REG_R9, REG_R10);
theEmitter->emitIns_R_R_R(INS_casl, EA_8BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_ldaddb, EA_1BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_ldaddab, EA_1BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_ldaddalb, EA_1BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_ldaddlb, EA_1BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_ldaddh, EA_2BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_ldaddah, EA_2BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_ldaddalh, EA_2BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_ldaddlh, EA_2BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_ldaddb, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_ldaddab, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_ldaddalb, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_ldaddlb, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_ldaddh, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_ldaddah, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_ldaddalh, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_ldaddlh, EA_4BYTE, REG_R8, REG_R9, REG_R10);
theEmitter->emitIns_R_R_R(INS_ldadd, EA_4BYTE, REG_R8, REG_R9, REG_R10);
theEmitter->emitIns_R_R_R(INS_ldadda, EA_4BYTE, REG_R8, REG_R9, REG_R10);
theEmitter->emitIns_R_R_R(INS_ldaddal, EA_4BYTE, REG_R8, REG_R9, REG_R10);
@@ -6451,14 +6427,14 @@ void CodeGen::genArm64EmitterUnitTests()
theEmitter->emitIns_R_R_R(INS_ldadda, EA_8BYTE, REG_R8, REG_R9, REG_R10);
theEmitter->emitIns_R_R_R(INS_ldaddal, EA_8BYTE, REG_R8, REG_R9, REG_R10);
theEmitter->emitIns_R_R_R(INS_ldaddl, EA_8BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_swpb, EA_1BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_swpab, EA_1BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_swpalb, EA_1BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_swplb, EA_1BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_swph, EA_2BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_swpah, EA_2BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_swpalh, EA_2BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R_R(INS_swplh, EA_2BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_swpb, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_swpab, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_swpalb, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_swplb, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_swph, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_swpah, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_swpalh, EA_4BYTE, REG_R8, REG_R9, REG_R10);
+ theEmitter->emitIns_R_R_R(INS_swplh, EA_4BYTE, REG_R8, REG_R9, REG_R10);
theEmitter->emitIns_R_R_R(INS_swp, EA_4BYTE, REG_R8, REG_R9, REG_R10);
theEmitter->emitIns_R_R_R(INS_swpa, EA_4BYTE, REG_R8, REG_R9, REG_R10);
theEmitter->emitIns_R_R_R(INS_swpal, EA_4BYTE, REG_R8, REG_R9, REG_R10);
@@ -6468,10 +6444,10 @@ void CodeGen::genArm64EmitterUnitTests()
theEmitter->emitIns_R_R_R(INS_swpal, EA_8BYTE, REG_R8, REG_R9, REG_R10);
theEmitter->emitIns_R_R_R(INS_swpl, EA_8BYTE, REG_R8, REG_R9, REG_R10);
- theEmitter->emitIns_R_R(INS_staddb, EA_1BYTE, REG_R8, REG_R10);
- theEmitter->emitIns_R_R(INS_staddlb, EA_1BYTE, REG_R8, REG_R10);
- theEmitter->emitIns_R_R(INS_staddh, EA_2BYTE, REG_R8, REG_R10);
- theEmitter->emitIns_R_R(INS_staddlh, EA_2BYTE, REG_R8, REG_R10);
+ theEmitter->emitIns_R_R(INS_staddb, EA_4BYTE, REG_R8, REG_R10);
+ theEmitter->emitIns_R_R(INS_staddlb, EA_4BYTE, REG_R8, REG_R10);
+ theEmitter->emitIns_R_R(INS_staddh, EA_4BYTE, REG_R8, REG_R10);
+ theEmitter->emitIns_R_R(INS_staddlh, EA_4BYTE, REG_R8, REG_R10);
theEmitter->emitIns_R_R(INS_stadd, EA_4BYTE, REG_R8, REG_R10);
theEmitter->emitIns_R_R(INS_staddl, EA_4BYTE, REG_R8, REG_R10);
theEmitter->emitIns_R_R(INS_stadd, EA_8BYTE, REG_R8, REG_R10);
diff --git a/src/jit/codegenarmarch.cpp b/src/jit/codegenarmarch.cpp
index 843e6bde48..5e50e927e4 100644
--- a/src/jit/codegenarmarch.cpp
+++ b/src/jit/codegenarmarch.cpp
@@ -374,6 +374,9 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
#ifdef FEATURE_SIMD
case GT_SIMD_CHK:
#endif // FEATURE_SIMD
+#ifdef FEATURE_HW_INTRINSICS
+ case GT_HW_INTRINSIC_CHK:
+#endif // FEATURE_HW_INTRINSICS
genRangeCheck(treeNode);
break;
@@ -1312,12 +1315,7 @@ void CodeGen::genMultiRegCallStoreToLocal(GenTree* treeNode)
//
void CodeGen::genRangeCheck(GenTree* oper)
{
-#ifdef FEATURE_SIMD
- noway_assert(oper->OperGet() == GT_ARR_BOUNDS_CHECK || oper->OperGet() == GT_SIMD_CHK);
-#else // !FEATURE_SIMD
- noway_assert(oper->OperGet() == GT_ARR_BOUNDS_CHECK);
-#endif // !FEATURE_SIMD
-
+ noway_assert(oper->OperIsBoundsCheck());
GenTreeBoundsChk* bndsChk = oper->AsBoundsChk();
GenTree* arrLen = bndsChk->gtArrLen;
diff --git a/src/jit/codegencommon.cpp b/src/jit/codegencommon.cpp
index 7d1c8c5034..55028e9e82 100644
--- a/src/jit/codegencommon.cpp
+++ b/src/jit/codegencommon.cpp
@@ -4873,6 +4873,8 @@ void CodeGen::genPushCalleeSavedRegisters()
// |-----------------------|
// | locals, temps, etc. |
// |-----------------------|
+ // | possible GS cookie |
+ // |-----------------------|
// | Saved LR | // 8 bytes
// |-----------------------|
// | Saved FP | // 8 bytes
@@ -4902,6 +4904,8 @@ void CodeGen::genPushCalleeSavedRegisters()
// |-----------------------|
// | locals, temps, etc. |
// |-----------------------|
+ // | possible GS cookie |
+ // |-----------------------|
// | Outgoing arg space | // multiple of 8 bytes; if required (i.e., #outsz != 0)
// |-----------------------| <---- Ambient SP
// | | |
@@ -4962,8 +4966,7 @@ void CodeGen::genPushCalleeSavedRegisters()
// not do this. That means that negative offsets from FP might need to use the reserved register to form
// the local variable offset for an addressing mode.
- // TODO-ARM64-Bug?: should this be "totalFrameSize <= 512"?
- if (((compiler->lvaOutgoingArgSpaceSize == 0) && (totalFrameSize < 512)) &&
+ if (((compiler->lvaOutgoingArgSpaceSize == 0) && (totalFrameSize <= 504)) &&
!genSaveFpLrWithAllCalleeSavedRegisters)
{
// Case #1.
@@ -4971,8 +4974,10 @@ void CodeGen::genPushCalleeSavedRegisters()
// Generate:
// stp fp,lr,[sp,#-framesz]!
//
- // The (totalFrameSize < 512) condition ensures that both the predecrement
- // and the postincrement of SP can occur with STP.
+ // The (totalFrameSize <= 504) condition ensures that both the pre-index STP instruction
+ // used in the prolog, and the post-index LDP instruction used in the epilog, can be generated.
+ // Note that STP and the unwind codes can handle -512, but LDP with a positive post-index value
+ // can only handle up to 504, and we want our prolog and epilog to match.
//
// After saving callee-saved registers, we establish the frame pointer with:
// mov fp,sp
@@ -4995,7 +5000,9 @@ void CodeGen::genPushCalleeSavedRegisters()
// Case #2.
//
// The (totalFrameSize <= 512) condition ensures the callee-saved registers can all be saved using STP
- // with signed offset encoding.
+ // with signed offset encoding. The maximum positive STP offset is 504, but when storing a pair of
+ // 8 byte registers, the largest actual offset we use would be 512 - 8 * 2 = 496. And STR with positive
+ // offset has a range 0 to 32760.
//
// After saving callee-saved registers, we establish the frame pointer with:
// add fp,sp,#outsz
@@ -5209,7 +5216,7 @@ void CodeGen::genPushCalleeSavedRegisters()
assert((remainingFrameSz % 16) == 0); // this is guaranteed to be 16-byte aligned because each component --
// totalFrameSize and calleeSaveSPDelta -- is 16-byte aligned.
- if (compiler->lvaOutgoingArgSpaceSize >= 504)
+ if (compiler->lvaOutgoingArgSpaceSize > 504)
{
// We can't do "stp fp,lr,[sp,#outsz]" because #outsz is too big.
// If compiler->lvaOutgoingArgSpaceSize is not aligned, we need to align the SP adjustment.
@@ -5239,9 +5246,9 @@ void CodeGen::genPushCalleeSavedRegisters()
JITDUMP(" spAdjustment3=%d\n", spAdjustment3);
- // TODO-ARM64-CQ: we're reporting this SUB SP in the unwind info. Do we need to, since we've already
- // established the frame pointer?
- genStackPointerAdjustment(-spAdjustment3, initReg, pInitRegZeroed);
+ // We've already established the frame pointer, so no need to report the stack pointer change to unwind
+ // info.
+ genStackPointerAdjustment(-spAdjustment3, initReg, pInitRegZeroed, /* reportUnwindData */ false);
offset += spAdjustment3;
}
else
@@ -5278,9 +5285,8 @@ void CodeGen::genPushCalleeSavedRegisters()
JITDUMP(" remainingFrameSz=%d\n", remainingFrameSz);
- // TODO-ARM64-CQ: we're reporting this SUB SP in the unwind info. Do we need to, since we've already
- // established the frame pointer?
- genStackPointerAdjustment(-remainingFrameSz, initReg, pInitRegZeroed);
+ // We've already established the frame pointer, so no need to report the stack pointer change to unwind info.
+ genStackPointerAdjustment(-remainingFrameSz, initReg, pInitRegZeroed, /* reportUnwindData */ false);
offset += remainingFrameSz;
}
else
@@ -5716,8 +5722,7 @@ void CodeGen::genPopCalleeSavedRegistersAndFreeLclFrame(bool jmpEpilog)
if (isFramePointerUsed())
{
- // TODO-ARM64-Bug?: should this be "totalFrameSize <= 512"?
- if ((compiler->lvaOutgoingArgSpaceSize == 0) && (totalFrameSize < 512) &&
+ if ((compiler->lvaOutgoingArgSpaceSize == 0) && (totalFrameSize <= 504) &&
!genSaveFpLrWithAllCalleeSavedRegisters)
{
JITDUMP("Frame type 1. #outsz=0; #framesz=%d; localloc? %s\n", totalFrameSize,
@@ -5797,7 +5802,7 @@ void CodeGen::genPopCalleeSavedRegistersAndFreeLclFrame(bool jmpEpilog)
int remainingFrameSz = totalFrameSize - calleeSaveSPDelta;
assert(remainingFrameSz > 0);
- if (compiler->lvaOutgoingArgSpaceSize >= 504)
+ if (compiler->lvaOutgoingArgSpaceSize > 504)
{
// We can't do "ldp fp,lr,[sp,#outsz]" because #outsz is too big.
// If compiler->lvaOutgoingArgSpaceSize is not aligned, we need to align the SP adjustment.
@@ -5807,27 +5812,11 @@ void CodeGen::genPopCalleeSavedRegistersAndFreeLclFrame(bool jmpEpilog)
int alignmentAdjustment2 = spAdjustment2 - spAdjustment2Unaligned;
assert((alignmentAdjustment2 == 0) || (alignmentAdjustment2 == REGSIZE_BYTES));
- if (compiler->compLocallocUsed)
- {
- // Restore sp from fp. No need to update sp after this since we've set up fp before adjusting sp
- // in prolog.
- // sub sp, fp, #alignmentAdjustment2
- getEmitter()->emitIns_R_R_I(INS_sub, EA_PTRSIZE, REG_SPBASE, REG_FPBASE, alignmentAdjustment2);
- compiler->unwindSetFrameReg(REG_FPBASE, alignmentAdjustment2);
- }
- else
- {
- // Generate:
- // add sp,sp,#outsz ; if #outsz is not 16-byte aligned, we need to be more
- // ; careful
- int spAdjustment3 = compiler->lvaOutgoingArgSpaceSize - alignmentAdjustment2;
- assert(spAdjustment3 > 0);
- assert((spAdjustment3 % 16) == 0);
-
- JITDUMP(" spAdjustment3=%d\n", spAdjustment3);
-
- genStackPointerAdjustment(spAdjustment3, REG_IP0, nullptr);
- }
+ // Restore sp from fp. No need to update sp after this since we've set up fp before adjusting sp
+ // in prolog.
+ // sub sp, fp, #alignmentAdjustment2
+ getEmitter()->emitIns_R_R_I(INS_sub, EA_PTRSIZE, REG_SPBASE, REG_FPBASE, alignmentAdjustment2);
+ compiler->unwindSetFrameReg(REG_FPBASE, alignmentAdjustment2);
// Generate:
// ldp fp,lr,[sp]
@@ -5883,7 +5872,7 @@ void CodeGen::genPopCalleeSavedRegistersAndFreeLclFrame(bool jmpEpilog)
// Restore sp from fp:
// sub sp, fp, #sp-to-fp-delta
// This is the same whether there is localloc or not. Note that we don't need to do anything to remove the
- // "remainingFrameSz" to reverse the SUB of that amount in the prolog. The unwind codes won't match.
+ // "remainingFrameSz" to reverse the SUB of that amount in the prolog.
int offsetSpToSavedFp = calleeSaveSPDelta -
(compiler->info.compIsVarArgs ? MAX_REG_ARG * REGSIZE_BYTES : 0) -
diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp
index cef3083c47..489218800e 100644
--- a/src/jit/compiler.cpp
+++ b/src/jit/compiler.cpp
@@ -2135,14 +2135,15 @@ void Compiler::compDoComponentUnitTestsOnce()
// Note that we can't use small values like zero, because we have some
// asserts that can fire for such values.
//
-unsigned char Compiler::compGetJitDefaultFill()
+// static
+unsigned char Compiler::compGetJitDefaultFill(Compiler* comp)
{
unsigned char defaultFill = (unsigned char)JitConfig.JitDefaultFill();
- if ((this != nullptr) && (compStressCompile(STRESS_GENERIC_VARN, 50)))
+ if (comp != nullptr && comp->compStressCompile(STRESS_GENERIC_VARN, 50))
{
unsigned temp;
- temp = info.compMethodHash();
+ temp = comp->info.compMethodHash();
temp = (temp >> 16) ^ temp;
temp = (temp >> 8) ^ temp;
temp = temp & 0xff;
@@ -2153,6 +2154,11 @@ unsigned char Compiler::compGetJitDefaultFill()
{
temp |= 0x80;
}
+
+ // Make a misaligned pointer value to reduce probability of getting a valid value and firing
+ // assert(!IsUninitialized(pointer)).
+ temp |= 0x1;
+
defaultFill = (unsigned char)temp;
}
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index fbf7fdc5e1..8c2b945863 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -3515,7 +3515,7 @@ protected:
#ifdef _TARGET_ARM64_
InstructionSet lookupHWIntrinsicISA(const char* className);
NamedIntrinsic lookupHWIntrinsic(const char* className, const char* methodName);
- bool impCheckImmediate(GenTree* immediateOp, unsigned int max);
+ GenTree* addRangeCheckIfNeeded(GenTree* lastOp, unsigned int max, bool mustExpand);
#endif // _TARGET_ARM64_
#endif // FEATURE_HW_INTRINSICS
GenTree* impArrayAccessIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
@@ -7188,11 +7188,6 @@ public:
template <bool ForCodeGen>
void compChangeLife(VARSET_VALARG_TP newLife);
- void genChangeLife(VARSET_VALARG_TP newLife)
- {
- compChangeLife</*ForCodeGen*/ true>(newLife);
- }
-
template <bool ForCodeGen>
inline void compUpdateLife(VARSET_VALARG_TP newLife);
@@ -8856,8 +8851,8 @@ public:
bool compDonotInline();
#ifdef DEBUG
- unsigned char compGetJitDefaultFill(); // Get the default fill char value
- // we randomize this value when JitStress is enabled
+ // Get the default fill char value we randomize this value when JitStress is enabled.
+ static unsigned char compGetJitDefaultFill(Compiler* comp);
const char* compLocalVarName(unsigned varNum, unsigned offs);
VarName compVarName(regNumber reg, bool isFloatReg = false);
diff --git a/src/jit/ee_il_dll.cpp b/src/jit/ee_il_dll.cpp
index 8b2f29e7d8..410ef6ca01 100644
--- a/src/jit/ee_il_dll.cpp
+++ b/src/jit/ee_il_dll.cpp
@@ -270,7 +270,7 @@ void JitTls::SetCompiler(Compiler* compiler)
reinterpret_cast<JitTls*>(GetJitTls())->m_compiler = compiler;
}
-#else // defined(DEBUG)
+#else // !defined(DEBUG)
JitTls::JitTls(ICorJitInfo* jitInfo)
{
diff --git a/src/jit/emitarm64.cpp b/src/jit/emitarm64.cpp
index bcd2542dc3..9f4208a4a5 100644
--- a/src/jit/emitarm64.cpp
+++ b/src/jit/emitarm64.cpp
@@ -11009,8 +11009,9 @@ void emitter::emitDispIns(
case IF_LS_3E: // LS_3E .X.........mmmmm ......nnnnnttttt Rm Rt Rn ARMv8.1 LSE Atomics
assert(insOptsNone(id->idInsOpt()));
- emitDispReg(id->idReg1(), emitInsTargetRegSize(id), true);
- emitDispReg(id->idReg2(), emitInsTargetRegSize(id), true);
+ assert((EA_SIZE(size) == 4) || (EA_SIZE(size) == 8));
+ emitDispReg(id->idReg1(), size, true);
+ emitDispReg(id->idReg2(), size, true);
emitDispAddrRI(id->idReg3(), id->idInsOpt(), 0);
break;
diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp
index a9dd5395ff..623a98c22c 100644
--- a/src/jit/gentree.cpp
+++ b/src/jit/gentree.cpp
@@ -17894,11 +17894,11 @@ bool GenTreeHWIntrinsic::OperIsMemoryLoad()
// Avx2.BroadcastScalarToVector128/256 have vector and pointer overloads both, e.g.,
// Vector128<byte> BroadcastScalarToVector128(Vector128<byte> value)
// Vector128<byte> BroadcastScalarToVector128(byte* source)
- // So, we need to check the argument's type is memory-reference (TYP_I_IMPL) or not
+ // So, we need to check the argument's type is memory-reference or Vector128
assert(HWIntrinsicInfo::lookupNumArgs(this) == 1);
return (gtHWIntrinsicId == NI_AVX2_BroadcastScalarToVector128 ||
gtHWIntrinsicId == NI_AVX2_BroadcastScalarToVector256) &&
- gtOp.gtOp1->TypeGet() == TYP_I_IMPL;
+ gtOp.gtOp1->TypeGet() != TYP_SIMD16;
}
else if (category == HW_Category_IMM)
{
diff --git a/src/jit/gentree.h b/src/jit/gentree.h
index 28888396e9..ef3bca2667 100644
--- a/src/jit/gentree.h
+++ b/src/jit/gentree.h
@@ -4995,10 +4995,10 @@ struct GenTreePhiArg : public GenTreeLclVarCommon
{
BasicBlock* gtPredBB;
- GenTreePhiArg(var_types type, unsigned lclNum, unsigned snum, BasicBlock* block)
+ GenTreePhiArg(var_types type, unsigned lclNum, unsigned ssaNum, BasicBlock* block)
: GenTreeLclVarCommon(GT_PHI_ARG, type, lclNum), gtPredBB(block)
{
- SetSsaNum(snum);
+ SetSsaNum(ssaNum);
}
#if DEBUGGABLE_GENTREE
diff --git a/src/jit/hwintrinsicArm64.cpp b/src/jit/hwintrinsicArm64.cpp
index 7fff58c66c..31df5b0456 100644
--- a/src/jit/hwintrinsicArm64.cpp
+++ b/src/jit/hwintrinsicArm64.cpp
@@ -129,14 +129,6 @@ NamedIntrinsic Compiler::lookupHWIntrinsic(const char* className, const char* me
}
//------------------------------------------------------------------------
-// impCheckImmediate: check if immediate is const and in range for inlining
-//
-bool Compiler::impCheckImmediate(GenTree* immediateOp, unsigned int max)
-{
- return immediateOp->IsCnsIntOrI() && (immediateOp->AsIntConCommon()->IconValue() < max);
-}
-
-//------------------------------------------------------------------------
// isFullyImplementedIsa: Gets a value that indicates whether the InstructionSet is fully implemented
//
// Arguments:
@@ -196,6 +188,46 @@ bool HWIntrinsicInfo::isScalarIsa(InstructionSet isa)
}
//------------------------------------------------------------------------
+// addRangeCheckIfNeeded: add a GT_HW_INTRINSIC_CHK node for non-full-range imm-intrinsic
+//
+// Arguments:
+// immOp -- the operand of the intrinsic that points to the imm-arg
+// max -- maximum allowable value for the immOp
+// mustExpand -- true if the compiler is compiling the fallback(GT_CALL) of this intrinsics
+//
+// Return Value:
+// if necessary, add a GT_HW_INTRINSIC_CHK node which throws an ArgumentOutOfRangeException
+// when the immOp is not in the valid range; otherwise, just return the provided immOp.
+//
+GenTree* Compiler::addRangeCheckIfNeeded(GenTree* immOp, unsigned int max, bool mustExpand)
+{
+ assert(immOp != nullptr);
+
+ // Need to range check only if we're must expand and don't have an appropriate constant
+ if (mustExpand && (!immOp->IsCnsIntOrI() || (immOp->AsIntConCommon()->IconValue() < max)))
+ {
+ GenTree* upperBoundNode = new (this, GT_CNS_INT) GenTreeIntCon(TYP_INT, max);
+ GenTree* index = nullptr;
+ if ((immOp->gtFlags & GTF_SIDE_EFFECT) != 0)
+ {
+ index = fgInsertCommaFormTemp(&immOp);
+ }
+ else
+ {
+ index = gtCloneExpr(immOp);
+ }
+ GenTreeBoundsChk* hwIntrinsicChk = new (this, GT_HW_INTRINSIC_CHK)
+ GenTreeBoundsChk(GT_HW_INTRINSIC_CHK, TYP_VOID, index, upperBoundNode, SCK_RNGCHK_FAIL);
+ hwIntrinsicChk->gtThrowKind = SCK_ARG_RNG_EXCPN;
+ return gtNewOperNode(GT_COMMA, immOp->TypeGet(), hwIntrinsicChk, immOp);
+ }
+ else
+ {
+ return immOp;
+ }
+}
+
+//------------------------------------------------------------------------
// compSupportsHWIntrinsic: compiler support of hardware intrinsics
//
// Arguments:
@@ -426,24 +458,16 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic,
return gtNewSimdHWIntrinsicNode(simdType, op1, intrinsic, simdBaseType, simdSizeBytes);
case HWIntrinsicInfo::SimdExtractOp:
- if (!mustExpand && !impCheckImmediate(impStackTop(0).val, getSIMDVectorLength(simdSizeBytes, simdBaseType)))
- {
- // Immediate lane not constant or out of range
- return nullptr;
- }
- op2 = impPopStack().val;
+ op2 =
+ addRangeCheckIfNeeded(impPopStack().val, getSIMDVectorLength(simdSizeBytes, simdBaseType), mustExpand);
op1 = impSIMDPopStack(simdType);
return gtNewScalarHWIntrinsicNode(JITtype2varType(sig->retType), op1, op2, intrinsic);
case HWIntrinsicInfo::SimdInsertOp:
- if (!mustExpand && !impCheckImmediate(impStackTop(1).val, getSIMDVectorLength(simdSizeBytes, simdBaseType)))
- {
- // Immediate lane not constant or out of range
- return nullptr;
- }
op3 = impPopStack().val;
- op2 = impPopStack().val;
+ op2 =
+ addRangeCheckIfNeeded(impPopStack().val, getSIMDVectorLength(simdSizeBytes, simdBaseType), mustExpand);
op1 = impSIMDPopStack(simdType);
return gtNewSimdHWIntrinsicNode(simdType, op1, op2, op3, intrinsic, simdBaseType, simdSizeBytes);
diff --git a/src/jit/hwintrinsiccodegenxarch.cpp b/src/jit/hwintrinsiccodegenxarch.cpp
index ae1a80eaca..9660ae346e 100644
--- a/src/jit/hwintrinsiccodegenxarch.cpp
+++ b/src/jit/hwintrinsiccodegenxarch.cpp
@@ -1197,7 +1197,7 @@ void CodeGen::genHWIntrinsic_R_R_R_RM(
// nonConstImmReg - the register contains non-constant imm8 argument
// baseReg - a register for the start of the switch table
// offsReg - a register for the offset into the switch table
-// emitSwCase - the lambda to generate siwtch-case
+// emitSwCase - the lambda to generate a switch case
//
// Return Value:
// generate the jump-table fallback for imm-intrinsics with non-constant argument.
@@ -1520,16 +1520,6 @@ void CodeGen::genSSEIntrinsic(GenTreeHWIntrinsic* node)
break;
}
- case NI_SSE_MoveMask:
- {
- assert(baseType == TYP_FLOAT);
- assert(op2 == nullptr);
-
- instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, node->gtSIMDBaseType);
- emit->emitIns_R_R(ins, emitTypeSize(TYP_INT), targetReg, op1Reg);
- break;
- }
-
case NI_SSE_Prefetch0:
case NI_SSE_Prefetch1:
case NI_SSE_Prefetch2:
@@ -1749,16 +1739,6 @@ void CodeGen::genSSE2Intrinsic(GenTreeHWIntrinsic* node)
break;
}
- case NI_SSE2_MoveMask:
- {
- assert(op2 == nullptr);
- assert(baseType == TYP_BYTE || baseType == TYP_UBYTE || baseType == TYP_DOUBLE);
-
- instruction ins = HWIntrinsicInfo::lookupIns(intrinsicId, baseType);
- emit->emitIns_R_R(ins, emitTypeSize(TYP_INT), targetReg, op1Reg);
- break;
- }
-
case NI_SSE2_StoreNonTemporal:
case NI_SSE2_X64_StoreNonTemporal:
{
diff --git a/src/jit/hwintrinsiclistxarch.h b/src/jit/hwintrinsiclistxarch.h
index 5903a69348..60e0f801e2 100644
--- a/src/jit/hwintrinsiclistxarch.h
+++ b/src/jit/hwintrinsiclistxarch.h
@@ -125,7 +125,7 @@ HARDWARE_INTRINSIC(SSE_Min, "Min",
HARDWARE_INTRINSIC(SSE_MinScalar, "MinScalar", SSE, -1, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_minss, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_CopyUpperBits)
HARDWARE_INTRINSIC(SSE_MoveHighToLow, "MoveHighToLow", SSE, -1, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movhlps, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoContainment)
HARDWARE_INTRINSIC(SSE_MoveLowToHigh, "MoveLowToHigh", SSE, -1, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movlhps, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoContainment)
-HARDWARE_INTRINSIC(SSE_MoveMask, "MoveMask", SSE, -1, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movmskps, INS_invalid}, HW_Category_Special, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(SSE_MoveMask, "MoveMask", SSE, -1, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movmskps, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics|HW_Flag_BaseTypeFromFirstArg)
HARDWARE_INTRINSIC(SSE_MoveScalar, "MoveScalar", SSE, -1, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movss, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_NoContainment)
HARDWARE_INTRINSIC(SSE_Multiply, "Multiply", SSE, -1, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_mulps, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative)
HARDWARE_INTRINSIC(SSE_MultiplyScalar, "MultiplyScalar", SSE, -1, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_mulss, INS_invalid}, HW_Category_SIMDScalar, HW_Flag_CopyUpperBits)
@@ -239,7 +239,7 @@ HARDWARE_INTRINSIC(SSE2_MemoryFence, "MemoryFence
HARDWARE_INTRINSIC(SSE2_MaxScalar, "MaxScalar", SSE2, -1, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_maxsd}, HW_Category_SIMDScalar, HW_Flag_CopyUpperBits)
HARDWARE_INTRINSIC(SSE2_Min, "Min", SSE2, -1, 16, 2, {INS_invalid, INS_pminub, INS_pminsw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_minpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative)
HARDWARE_INTRINSIC(SSE2_MinScalar, "MinScalar", SSE2, -1, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_minsd}, HW_Category_SIMDScalar, HW_Flag_CopyUpperBits)
-HARDWARE_INTRINSIC(SSE2_MoveMask, "MoveMask", SSE2, -1, 16, 1, {INS_pmovmskb, INS_pmovmskb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movmskpd}, HW_Category_Special, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(SSE2_MoveMask, "MoveMask", SSE2, -1, 16, 1, {INS_pmovmskb, INS_pmovmskb, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movmskpd}, HW_Category_SimpleSIMD, HW_Flag_NoContainment|HW_Flag_NoRMWSemantics|HW_Flag_BaseTypeFromFirstArg)
HARDWARE_INTRINSIC(SSE2_MoveScalar, "MoveScalar", SSE2, -1, 16, -1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movq, INS_movq, INS_invalid, INS_movsdsse2}, HW_Category_SIMDScalar, HW_Flag_NoContainment)
HARDWARE_INTRINSIC(SSE2_Multiply, "Multiply", SSE2, -1, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_pmuludq, INS_invalid, INS_mulpd}, HW_Category_SimpleSIMD, HW_Flag_Commutative)
HARDWARE_INTRINSIC(SSE2_MultiplyHigh, "MultiplyHigh", SSE2, -1, 16, 2, {INS_invalid, INS_invalid, INS_pmulhw, INS_pmulhuw, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_Commutative)
diff --git a/src/jit/hwintrinsicxarch.cpp b/src/jit/hwintrinsicxarch.cpp
index a0008e5fcc..fcc20e04c6 100644
--- a/src/jit/hwintrinsicxarch.cpp
+++ b/src/jit/hwintrinsicxarch.cpp
@@ -1608,14 +1608,6 @@ GenTree* Compiler::impSSEIntrinsic(NamedIntrinsic intrinsic,
switch (intrinsic)
{
- case NI_SSE_MoveMask:
- assert(sig->numArgs == 1);
- assert(JITtype2varType(sig->retType) == TYP_INT);
- assert(getBaseTypeOfSIMDType(info.compCompHnd->getArgClass(sig, sig->args)) == TYP_FLOAT);
- op1 = impSIMDPopStack(TYP_SIMD16);
- retNode = gtNewSimdHWIntrinsicNode(TYP_INT, op1, intrinsic, TYP_FLOAT, simdSize);
- break;
-
case NI_SSE_Prefetch0:
case NI_SSE_Prefetch1:
case NI_SSE_Prefetch2:
@@ -1691,17 +1683,6 @@ GenTree* Compiler::impSSE2Intrinsic(NamedIntrinsic intrinsic,
break;
}
- case NI_SSE2_MoveMask:
- {
- assert(sig->numArgs == 1);
- retType = JITtype2varType(sig->retType);
- assert(retType == TYP_INT);
- op1 = impSIMDPopStack(TYP_SIMD16);
- baseType = getBaseTypeOfSIMDType(info.compCompHnd->getArgClass(sig, sig->args));
- retNode = gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, baseType, simdSize);
- break;
- }
-
case NI_SSE2_StoreNonTemporal:
{
assert(sig->numArgs == 2);
diff --git a/src/jit/jit.h b/src/jit/jit.h
index 5cdb1fdcb9..5157d66e98 100644
--- a/src/jit/jit.h
+++ b/src/jit/jit.h
@@ -867,7 +867,7 @@ inline T UninitializedWord(Compiler* comp)
{
comp = JitTls::GetCompiler();
}
- defaultFill = comp->compGetJitDefaultFill();
+ defaultFill = Compiler::compGetJitDefaultFill(comp);
assert(defaultFill <= 0xff);
__int64 word = 0x0101010101010101LL * defaultFill;
return (T)word;
diff --git a/src/jit/liveness.cpp b/src/jit/liveness.cpp
index ded6c05ce1..c9d5452427 100644
--- a/src/jit/liveness.cpp
+++ b/src/jit/liveness.cpp
@@ -1056,6 +1056,42 @@ void Compiler::fgExtendDbgLifetimes()
#endif // DEBUG
}
+//------------------------------------------------------------------------
+// fgGetHandlerLiveVars: determine set of locals live because of implicit
+// exception flow from a block.
+//
+// Arguments:
+// block - the block in question
+//
+// Returns:
+// Additional set of locals to be considered live throughout the block.
+//
+// Notes:
+// Assumes caller has screened candidate blocks to only those with
+// exception flow, via `ehBlockHasExnFlowDsc`.
+//
+// Exception flow can arise because of a newly raised exception (for
+// blocks within try regions) or because of an actively propagating exception
+// (for filter blocks). This flow effectively creates additional successor
+// edges in the flow graph that the jit does not model. This method computes
+// the net contribution from all the missing successor edges.
+//
+// For example, with the following C# source, during EH processing of the throw,
+// the outer filter will execute in pass1, before the inner handler executes
+// in pass2, and so the filter blocks should show the inner handler's local is live.
+//
+// try
+// {
+// using (AllocateObject()) // ==> try-finally; handler calls Dispose
+// {
+// throw new Exception();
+// }
+// }
+// catch (Exception e1) when (IsExpectedException(e1))
+// {
+// Console.WriteLine("In catch 1");
+// }
+
VARSET_VALRET_TP Compiler::fgGetHandlerLiveVars(BasicBlock* block)
{
noway_assert(block);
@@ -1067,7 +1103,6 @@ VARSET_VALRET_TP Compiler::fgGetHandlerLiveVars(BasicBlock* block)
do
{
/* Either we enter the filter first or the catch/finally */
-
if (HBtab->HasFilter())
{
VarSetOps::UnionD(this, liveVars, HBtab->ebdFilter->bbLiveIn);
@@ -1099,6 +1134,72 @@ VARSET_VALRET_TP Compiler::fgGetHandlerLiveVars(BasicBlock* block)
} while (true);
+ // If this block is within a filter, we also need to report as live
+ // any vars live into enclosed finally or fault handlers, since the
+ // filter will run during the first EH pass, and enclosed or enclosing
+ // handlers will run during the second EH pass. So all these handlers
+ // are "exception flow" successors of the filter.
+ //
+ // Note we are relying on ehBlockHasExnFlowDsc to return true
+ // for any filter block that we should examine here.
+ if (block->hasHndIndex())
+ {
+ const unsigned thisHndIndex = block->getHndIndex();
+ EHblkDsc* enclosingHBtab = ehGetDsc(thisHndIndex);
+
+ if (enclosingHBtab->InFilterRegionBBRange(block))
+ {
+ assert(enclosingHBtab->HasFilter());
+
+ // Search the EH table for enclosed regions.
+ //
+ // All the enclosed regions will be lower numbered and
+ // immediately prior to and contiguous with the enclosing
+ // region in the EH tab.
+ unsigned index = thisHndIndex;
+
+ while (index > 0)
+ {
+ index--;
+ unsigned enclosingIndex = ehGetEnclosingTryIndex(index);
+ bool isEnclosed = false;
+
+ // To verify this is an enclosed region, search up
+ // through the enclosing regions until we find the
+ // region associated with the filter.
+ while (enclosingIndex != EHblkDsc::NO_ENCLOSING_INDEX)
+ {
+ if (enclosingIndex == thisHndIndex)
+ {
+ isEnclosed = true;
+ break;
+ }
+
+ enclosingIndex = ehGetEnclosingTryIndex(enclosingIndex);
+ }
+
+ // If we found an enclosed region, check if the region
+ // is a try fault or try finally, and if so, add any
+ // locals live into the enclosed region's handler into this
+ // block's live-in set.
+ if (isEnclosed)
+ {
+ EHblkDsc* enclosedHBtab = ehGetDsc(index);
+
+ if (enclosedHBtab->HasFinallyOrFaultHandler())
+ {
+ VarSetOps::UnionD(this, liveVars, enclosedHBtab->ebdHndBeg->bbLiveIn);
+ }
+ }
+ // Once we run across a non-enclosed region, we can stop searching.
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+
return liveVars;
}
@@ -1171,14 +1272,17 @@ class LiveVarAnalysis
// since (without proof otherwise) the use and def may touch different memory at run-time.
m_memoryLiveIn = m_memoryLiveOut | block->bbMemoryUse;
- /* Can exceptions from this block be handled (in this function)? */
-
+ // Does this block have implicit exception flow to a filter or handler?
+ // If so, include the effects of that flow.
if (m_compiler->ehBlockHasExnFlowDsc(block))
{
const VARSET_TP& liveVars(m_compiler->fgGetHandlerLiveVars(block));
-
VarSetOps::UnionD(m_compiler, m_liveIn, liveVars);
VarSetOps::UnionD(m_compiler, m_liveOut, liveVars);
+
+ // Implicit eh edges can induce loop-like behavior,
+ // so make sure we iterate to closure.
+ m_hasPossibleBackEdge = true;
}
/* Has there been any change in either live set? */
@@ -2399,7 +2503,6 @@ void Compiler::fgInterBlockLocalVarLiveness()
if (block->bbCatchTyp != BBCT_NONE)
{
/* Note the set of variables live on entry to exception handler */
-
VarSetOps::UnionD(this, exceptVars, block->bbLiveIn);
}
diff --git a/src/jit/lsraarm64.cpp b/src/jit/lsraarm64.cpp
index 13907a7b24..6af777ccd2 100644
--- a/src/jit/lsraarm64.cpp
+++ b/src/jit/lsraarm64.cpp
@@ -596,6 +596,9 @@ int LinearScan::BuildNode(GenTree* tree)
#ifdef FEATURE_SIMD
case GT_SIMD_CHK:
#endif // FEATURE_SIMD
+#ifdef FEATURE_HW_INTRINSICS
+ case GT_HW_INTRINSIC_CHK:
+#endif // FEATURE_HW_INTRINSICS
{
GenTreeBoundsChk* node = tree->AsBoundsChk();
// Consumes arrLen & index - has no result
diff --git a/src/jit/register_arg_convention.cpp b/src/jit/register_arg_convention.cpp
index 4678cdec41..93c3b0bef8 100644
--- a/src/jit/register_arg_convention.cpp
+++ b/src/jit/register_arg_convention.cpp
@@ -72,10 +72,9 @@ bool InitVarDscInfo::enoughAvailRegs(var_types type, unsigned numRegs /* = 1 */)
return regArgNum(type) + numRegs - backFillCount <= maxRegArgNum(type);
}
+#ifdef _TARGET_ARM_
unsigned InitVarDscInfo::alignReg(var_types type, unsigned requiredRegAlignment)
{
- NYI_ARM64("alignReg");
-
assert(requiredRegAlignment > 0);
if (requiredRegAlignment == 1)
{
@@ -93,12 +92,10 @@ unsigned InitVarDscInfo::alignReg(var_types type, unsigned requiredRegAlignment)
unsigned cAlignSkipped = requiredRegAlignment - alignMask;
assert(cAlignSkipped == 1); // Alignment is currently only 1 or 2, so misalignment can only be 1.
-#ifdef _TARGET_ARM_
if (varTypeIsFloating(type))
{
fltArgSkippedRegMask |= genMapFloatRegArgNumToRegMask(floatRegArgNum);
}
-#endif // _TARGET_ARM_
assert(regArgNum(type) + cAlignSkipped <= maxRegArgNum(type)); // if equal, then we aligned the last slot, and the
// arg can't be enregistered
@@ -106,6 +103,7 @@ unsigned InitVarDscInfo::alignReg(var_types type, unsigned requiredRegAlignment)
return cAlignSkipped;
}
+#endif // _TARGET_ARM_
bool InitVarDscInfo::canEnreg(var_types type, unsigned numRegs /* = 1 */)
{
diff --git a/src/jit/register_arg_convention.h b/src/jit/register_arg_convention.h
index f948e45eba..28f29b7c13 100644
--- a/src/jit/register_arg_convention.h
+++ b/src/jit/register_arg_convention.h
@@ -71,12 +71,14 @@ public:
// Returns the first argument register of the allocated set.
unsigned allocRegArg(var_types type, unsigned numRegs = 1);
+#ifdef _TARGET_ARM_
// We are aligning the register to an ABI-required boundary, such as putting
// double-precision floats in even-numbered registers, by skipping one register.
// "requiredRegAlignment" is the amount to align to: 1 for no alignment (everything
// is 1-aligned), 2 for "double" alignment.
// Returns the number of registers skipped.
unsigned alignReg(var_types type, unsigned requiredRegAlignment);
+#endif // _TARGET_ARM_
// Return true if it is an enregisterable type and there is room.
// Note that for "type", we only care if it is float or not. In particular,
diff --git a/src/jit/scopeinfo.cpp b/src/jit/scopeinfo.cpp
index 51f231e9dd..19aa5428fa 100644
--- a/src/jit/scopeinfo.cpp
+++ b/src/jit/scopeinfo.cpp
@@ -44,7 +44,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
* Also,
* o At every assignment to a variable, siCheckVarScope() adds an open scope
* for the variable being assigned to.
- * o genChangeLife() calls siUpdate() which closes scopes for variables which
+ * o UpdateLifeVar() calls siUpdate() which closes scopes for variables which
* are not live anymore.
*
******************************************************************************
@@ -918,15 +918,15 @@ void CodeGen::siEndBlock(BasicBlock* block)
#endif
}
-/*****************************************************************************
- * siUpdate
- *
- * Called at the start of basic blocks, and during code-gen of a block,
- * for non-debuggable code, whenever the life of any tracked variable changes
- * and the appropriate code has been generated. For debuggable code, variables are
- * live over their entire scope, and so they go live or dead only on
- * block boundaries.
- */
+//------------------------------------------------------------------------
+// siUpdate: Closes the "ScopeInfo" of the tracked variables that has become dead.
+//
+// Notes:
+// Called at the start of basic blocks, and during code-gen of a block,
+// for non-debuggable code, whenever the life of any tracked variable changes
+// and the appropriate code has been generated. For debuggable code, variables are
+// live over their entire scope, and so they go live or dead only on
+// block boundaries.
void CodeGen::siUpdate()
{
if (!compiler->opts.compScopeInfo)
diff --git a/src/jit/simd.cpp b/src/jit/simd.cpp
index 3d265ee12d..4f3f8eb04c 100644
--- a/src/jit/simd.cpp
+++ b/src/jit/simd.cpp
@@ -1022,17 +1022,17 @@ const SIMDIntrinsicInfo* Compiler::getSIMDIntrinsicInfo(CORINFO_CLASS_HANDLE* in
// Normalizes TYP_STRUCT value in case of GT_CALL, GT_RET_EXPR and arg nodes.
//
// Arguments:
-// type - the type of value that the caller expects to be popped off the stack.
-// expectAddr - if true indicates we are expecting type stack entry to be a TYP_BYREF.
-// structType - the class handle to use when normalizing if it is not the same as the stack entry class handle;
-// this can happen for certain scenarios, such as folding away a static cast, where we want the
-// value popped to have the type that would have been returned.
+// type - the type of value that the caller expects to be popped off the stack.
+// expectAddr - if true indicates we are expecting type stack entry to be a TYP_BYREF.
+// structHandle - the class handle to use when normalizing if it is not the same as the stack entry class handle;
+// this can happen for certain scenarios, such as folding away a static cast, where we want the
+// value popped to have the type that would have been returned.
//
// Notes:
// If the popped value is a struct, and the expected type is a simd type, it will be set
// to that type, otherwise it will assert if the type being popped is not the expected type.
-GenTree* Compiler::impSIMDPopStack(var_types type, bool expectAddr, CORINFO_CLASS_HANDLE structType)
+GenTree* Compiler::impSIMDPopStack(var_types type, bool expectAddr, CORINFO_CLASS_HANDLE structHandle)
{
StackEntry se = impPopStack();
typeInfo ti = se.seTypeInfo;
@@ -1058,10 +1058,18 @@ GenTree* Compiler::impSIMDPopStack(var_types type, bool expectAddr, CORINFO_CLAS
// If we have a ldobj of a SIMD local we need to transform it.
if (tree->OperGet() == GT_OBJ)
{
- GenTree* addr = tree->gtOp.gtOp1;
- if ((addr->OperGet() == GT_ADDR) && isSIMDTypeLocal(addr->gtOp.gtOp1))
+ if (tree->AsObj()->gtClass != structHandle)
{
- tree = addr->gtOp.gtOp1;
+ // In this case we need to retain the GT_OBJ to retype the value.
+ tree->AsObj()->gtClass = structHandle;
+ }
+ else
+ {
+ GenTree* addr = tree->gtOp.gtOp1;
+ if ((addr->OperGet() == GT_ADDR) && isSIMDTypeLocal(addr->gtOp.gtOp1))
+ {
+ tree = addr->gtOp.gtOp1;
+ }
}
}
@@ -1077,12 +1085,12 @@ GenTree* Compiler::impSIMDPopStack(var_types type, bool expectAddr, CORINFO_CLAS
{
assert(ti.IsType(TI_STRUCT));
- if (structType == nullptr)
+ if (structHandle == nullptr)
{
- structType = ti.GetClassHandleForValueClass();
+ structHandle = ti.GetClassHandleForValueClass();
}
- tree = impNormStructVal(tree, structType, (unsigned)CHECK_SPILL_ALL);
+ tree = impNormStructVal(tree, structHandle, (unsigned)CHECK_SPILL_ALL);
}
// Now set the type of the tree to the specialized SIMD struct type, if applicable.
diff --git a/src/jit/ssabuilder.cpp b/src/jit/ssabuilder.cpp
index d7b8b7610c..7fdc37ba93 100644
--- a/src/jit/ssabuilder.cpp
+++ b/src/jit/ssabuilder.cpp
@@ -881,7 +881,6 @@ void SsaBuilder::TreeRenameVariables(GenTree* tree, BasicBlock* block, SsaRename
{
// GcHeap and ByrefExposed share the same stacks, SsaMap, and phis
assert(!hasByrefHavoc);
- assert(pRenameState->CountForMemoryUse(GcHeap) == ssaNum);
assert(*m_pCompiler->GetMemorySsaMap(GcHeap)->LookupPointer(tree) == ssaNum);
assert(block->bbMemorySsaPhiFunc[GcHeap] == block->bbMemorySsaPhiFunc[ByrefExposed]);
}
@@ -926,7 +925,7 @@ void SsaBuilder::TreeRenameVariables(GenTree* tree, BasicBlock* block, SsaRename
// This is a partial definition of a variable. The node records only the SSA number
// of the use that is implied by this partial definition. The SSA number of the new
// definition will be recorded in the m_opAsgnVarDefSsaNums map.
- tree->AsLclVarCommon()->SetSsaNum(pRenameState->CountForUse(lclNum));
+ tree->AsLclVarCommon()->SetSsaNum(pRenameState->Top(lclNum));
m_pCompiler->GetOpAsgnVarDefSsaNums()->Set(tree, ssaNum);
}
@@ -937,7 +936,7 @@ void SsaBuilder::TreeRenameVariables(GenTree* tree, BasicBlock* block, SsaRename
pRenameState->Push(block, lclNum, ssaNum);
- // If necessary, add "lclNum/count" to the arg list of a phi def in any
+ // If necessary, add "lclNum/ssaNum" to the arg list of a phi def in any
// handlers for try blocks that "block" is within. (But only do this for "real" definitions,
// not phi definitions.)
if (!isPhiDefn)
@@ -965,13 +964,12 @@ void SsaBuilder::TreeRenameVariables(GenTree* tree, BasicBlock* block, SsaRename
return;
}
}
- // Give the count as top of stack.
- unsigned count = pRenameState->CountForUse(lclNum);
- tree->gtLclVarCommon.SetSsaNum(count);
+
+ tree->AsLclVarCommon()->SetSsaNum(pRenameState->Top(lclNum));
}
}
-void SsaBuilder::AddDefToHandlerPhis(BasicBlock* block, unsigned lclNum, unsigned count)
+void SsaBuilder::AddDefToHandlerPhis(BasicBlock* block, unsigned lclNum, unsigned ssaNum)
{
assert(m_pCompiler->lvaTable[lclNum].lvTracked); // Precondition.
unsigned lclIndex = m_pCompiler->lvaTable[lclNum].lvVarIndex;
@@ -981,7 +979,7 @@ void SsaBuilder::AddDefToHandlerPhis(BasicBlock* block, unsigned lclNum, unsigne
{
DBG_SSA_JITDUMP("Definition of local V%02u/d:%d in block " FMT_BB
" has exn handler; adding as phi arg to handlers.\n",
- lclNum, count, block->bbNum);
+ lclNum, ssaNum, block->bbNum);
while (true)
{
BasicBlock* handler = tryBlk->ExFlowBlock();
@@ -1007,7 +1005,7 @@ void SsaBuilder::AddDefToHandlerPhis(BasicBlock* block, unsigned lclNum, unsigne
if (tree->gtOp.gtOp1->gtLclVar.gtLclNum == lclNum)
{
- // It's the definition for the right local. Add "count" to the RHS.
+ // It's the definition for the right local. Add "ssaNum" to the RHS.
GenTree* phi = tree->gtOp.gtOp2;
GenTreeArgList* args = nullptr;
if (phi->gtOp.gtOp1 != nullptr)
@@ -1019,12 +1017,12 @@ void SsaBuilder::AddDefToHandlerPhis(BasicBlock* block, unsigned lclNum, unsigne
for (GenTreeArgList* curArgs = args; curArgs != nullptr; curArgs = curArgs->Rest())
{
GenTreePhiArg* phiArg = curArgs->Current()->AsPhiArg();
- assert(phiArg->gtSsaNum != count);
+ assert(phiArg->gtSsaNum != ssaNum);
}
#endif
var_types typ = m_pCompiler->lvaTable[lclNum].TypeGet();
GenTreePhiArg* newPhiArg =
- new (m_pCompiler, GT_PHI_ARG) GenTreePhiArg(typ, lclNum, count, block);
+ new (m_pCompiler, GT_PHI_ARG) GenTreePhiArg(typ, lclNum, ssaNum, block);
phi->gtOp.gtOp1 = new (m_pCompiler, GT_LIST) GenTreeArgList(newPhiArg, args);
m_pCompiler->gtSetStmtInfo(stmt);
@@ -1033,7 +1031,7 @@ void SsaBuilder::AddDefToHandlerPhis(BasicBlock* block, unsigned lclNum, unsigne
phiFound = true;
#endif
DBG_SSA_JITDUMP(" Added phi arg u:%d for V%02u to phi defn in handler block " FMT_BB ".\n",
- count, lclNum, handler->bbNum);
+ ssaNum, lclNum, handler->bbNum);
break;
}
}
@@ -1051,7 +1049,7 @@ void SsaBuilder::AddDefToHandlerPhis(BasicBlock* block, unsigned lclNum, unsigne
}
}
-void SsaBuilder::AddMemoryDefToHandlerPhis(MemoryKind memoryKind, BasicBlock* block, unsigned count)
+void SsaBuilder::AddMemoryDefToHandlerPhis(MemoryKind memoryKind, BasicBlock* block, unsigned ssaNum)
{
if (m_pCompiler->ehBlockHasExnFlowDsc(block))
{
@@ -1063,7 +1061,7 @@ void SsaBuilder::AddMemoryDefToHandlerPhis(MemoryKind memoryKind, BasicBlock* bl
// Otherwise...
DBG_SSA_JITDUMP("Definition of %s/d:%d in block " FMT_BB " has exn handler; adding as phi arg to handlers.\n",
- memoryKindNames[memoryKind], count, block->bbNum);
+ memoryKindNames[memoryKind], ssaNum, block->bbNum);
EHblkDsc* tryBlk = m_pCompiler->ehGetBlockExnFlowDsc(block);
while (true)
{
@@ -1074,7 +1072,7 @@ void SsaBuilder::AddMemoryDefToHandlerPhis(MemoryKind memoryKind, BasicBlock* bl
{
assert(handler->bbMemorySsaPhiFunc != nullptr);
- // Add "count" to the phi args of memoryKind.
+ // Add "ssaNum" to the phi args of memoryKind.
BasicBlock::MemoryPhiArg*& handlerMemoryPhi = handler->bbMemorySsaPhiFunc[memoryKind];
#if DEBUG
@@ -1093,7 +1091,7 @@ void SsaBuilder::AddMemoryDefToHandlerPhis(MemoryKind memoryKind, BasicBlock* bl
if (handlerMemoryPhi == BasicBlock::EmptyMemoryPhiDef)
{
- handlerMemoryPhi = new (m_pCompiler) BasicBlock::MemoryPhiArg(count);
+ handlerMemoryPhi = new (m_pCompiler) BasicBlock::MemoryPhiArg(ssaNum);
}
else
{
@@ -1101,14 +1099,14 @@ void SsaBuilder::AddMemoryDefToHandlerPhis(MemoryKind memoryKind, BasicBlock* bl
BasicBlock::MemoryPhiArg* curArg = handler->bbMemorySsaPhiFunc[memoryKind];
while (curArg != nullptr)
{
- assert(curArg->GetSsaNum() != count);
+ assert(curArg->GetSsaNum() != ssaNum);
curArg = curArg->m_nextArg;
}
#endif // DEBUG
- handlerMemoryPhi = new (m_pCompiler) BasicBlock::MemoryPhiArg(count, handlerMemoryPhi);
+ handlerMemoryPhi = new (m_pCompiler) BasicBlock::MemoryPhiArg(ssaNum, handlerMemoryPhi);
}
- DBG_SSA_JITDUMP(" Added phi arg u:%d for %s to phi defn in handler block " FMT_BB ".\n", count,
+ DBG_SSA_JITDUMP(" Added phi arg u:%d for %s to phi defn in handler block " FMT_BB ".\n", ssaNum,
memoryKindNames[memoryKind], memoryKind, handler->bbNum);
if ((memoryKind == ByrefExposed) && m_pCompiler->byrefStatesMatchGcHeapStates)
@@ -1148,7 +1146,8 @@ void SsaBuilder::BlockRenameVariables(BasicBlock* block, SsaRenameState* pRename
assert(block->bbMemorySsaPhiFunc[memoryKind] == block->bbMemorySsaPhiFunc[ByrefExposed]);
// so we will have already allocated a defnum for it if needed.
assert(memoryKind > ByrefExposed);
- assert(pRenameState->CountForMemoryUse(memoryKind) == pRenameState->CountForMemoryUse(ByrefExposed));
+
+ block->bbMemorySsaNumIn[memoryKind] = pRenameState->TopMemory(ByrefExposed);
}
else
{
@@ -1160,11 +1159,14 @@ void SsaBuilder::BlockRenameVariables(BasicBlock* block, SsaRenameState* pRename
DBG_SSA_JITDUMP("Ssa # for %s phi on entry to " FMT_BB " is %d.\n", memoryKindNames[memoryKind],
block->bbNum, ssaNum);
+
+ block->bbMemorySsaNumIn[memoryKind] = ssaNum;
+ }
+ else
+ {
+ block->bbMemorySsaNumIn[memoryKind] = pRenameState->TopMemory(memoryKind);
}
}
-
- // Record the "in" Ssa # for memoryKind.
- block->bbMemorySsaNumIn[memoryKind] = pRenameState->CountForMemoryUse(memoryKind);
}
// We need to iterate over phi definitions, to give them SSA names, but we need
@@ -1199,7 +1201,8 @@ void SsaBuilder::BlockRenameVariables(BasicBlock* block, SsaRenameState* pRename
assert(memoryKind > ByrefExposed);
assert(((block->bbMemoryDef & memorySet) != 0) ==
((block->bbMemoryDef & memoryKindSet(ByrefExposed)) != 0));
- assert(pRenameState->CountForMemoryUse(memoryKind) == pRenameState->CountForMemoryUse(ByrefExposed));
+
+ block->bbMemorySsaNumOut[memoryKind] = pRenameState->TopMemory(ByrefExposed);
}
else
{
@@ -1208,12 +1211,15 @@ void SsaBuilder::BlockRenameVariables(BasicBlock* block, SsaRenameState* pRename
unsigned ssaNum = m_pCompiler->lvMemoryPerSsaData.AllocSsaNum(m_allocator);
pRenameState->PushMemory(memoryKind, block, ssaNum);
AddMemoryDefToHandlerPhis(memoryKind, block, ssaNum);
+
+ block->bbMemorySsaNumOut[memoryKind] = ssaNum;
+ }
+ else
+ {
+ block->bbMemorySsaNumOut[memoryKind] = pRenameState->TopMemory(memoryKind);
}
}
- // Record the "out" Ssa" # for memoryKind.
- block->bbMemorySsaNumOut[memoryKind] = pRenameState->CountForMemoryUse(memoryKind);
-
DBG_SSA_JITDUMP("Ssa # for %s on entry to " FMT_BB " is %d; on exit is %d.\n", memoryKindNames[memoryKind],
block->bbNum, block->bbMemorySsaNumIn[memoryKind], block->bbMemorySsaNumOut[memoryKind]);
}
@@ -1243,7 +1249,7 @@ void SsaBuilder::AssignPhiNodeRhsVariables(BasicBlock* block, SsaRenameState* pR
assert(phiNode->gtOp.gtOp1 == nullptr || phiNode->gtOp.gtOp1->OperGet() == GT_LIST);
unsigned lclNum = tree->gtOp.gtOp1->gtLclVar.gtLclNum;
- unsigned ssaNum = pRenameState->CountForUse(lclNum);
+ unsigned ssaNum = pRenameState->Top(lclNum);
// Search the arglist for an existing definition for ssaNum.
// (Can we assert that its the head of the list? This should only happen when we add
// during renaming for a definition that occurs within a try, and then that's the last
@@ -1399,8 +1405,7 @@ void SsaBuilder::AssignPhiNodeRhsVariables(BasicBlock* block, SsaRenameState* pR
assert(phiNode->gtOp.gtOp1 == nullptr || phiNode->gtOp.gtOp1->OperGet() == GT_LIST);
GenTreeArgList* argList = reinterpret_cast<GenTreeArgList*>(phiNode->gtOp.gtOp1);
- // What is the current SSAName from the predecessor for this local?
- unsigned ssaNum = pRenameState->CountForUse(lclNum);
+ unsigned ssaNum = pRenameState->Top(lclNum);
// See if this ssaNum is already an arg to the phi.
bool alreadyArg = false;
@@ -1474,35 +1479,10 @@ void SsaBuilder::AssignPhiNodeRhsVariables(BasicBlock* block, SsaRenameState* pR
}
/**
- * Walk the block's tree in the evaluation order and reclaim rename stack for var definitions.
- *
- * @param block Block for which SSA variables have to be renamed.
- * @param pRenameState The incremental rename information stored during renaming process.
- *
- */
-void SsaBuilder::BlockPopStacks(BasicBlock* block, SsaRenameState* pRenameState)
-{
- // Pop the names given to the non-phi nodes.
- pRenameState->PopBlockStacks(block);
-
- // And for memory.
- for (MemoryKind memoryKind : allMemoryKinds())
- {
- if ((memoryKind == GcHeap) && m_pCompiler->byrefStatesMatchGcHeapStates)
- {
- // GcHeap and ByrefExposed share a rename stack, so don't try
- // to pop it a second time.
- continue;
- }
- pRenameState->PopBlockMemoryStack(memoryKind, block);
- }
-}
-
-/**
* Perform variable renaming.
*
* Walks the blocks and renames all var defs with ssa numbers and all uses with the
- * current count that is in the top of the stack. Assigns phi node rhs variables
+ * SSA number that is in the top of the stack. Assigns phi node rhs variables
* (i.e., the arguments to the phi.) Then, calls the function recursively on child
* nodes in the DOM tree to continue the renaming process.
*
@@ -1540,7 +1520,7 @@ void SsaBuilder::RenameVariables(BlkToBlkVectorMap* domTree, SsaRenameState* pRe
// In ValueNum we'd assume un-inited variables get FIRST_SSA_NUM.
assert(ssaNum == SsaConfig::FIRST_SSA_NUM);
- pRenameState->Push(nullptr, lclNum, ssaNum);
+ pRenameState->Push(m_pCompiler->fgFirstBB, lclNum, ssaNum);
}
}
@@ -1602,7 +1582,6 @@ void SsaBuilder::RenameVariables(BlkToBlkVectorMap* domTree, SsaRenameState* pRe
// been (recursively) processed, we still need to call BlockPopStacks on it.
blocksToDo->push_back(BlockWork(block, true));
- // Walk the block give counts to DEFs and give top of stack count for USEs.
BlockRenameVariables(block, pRenameState);
// Assign arguments to the phi node of successors, corresponding to the block's index.
@@ -1621,8 +1600,8 @@ void SsaBuilder::RenameVariables(BlkToBlkVectorMap* domTree, SsaRenameState* pRe
}
else
{
- // Done, pop all the stack count, if there is one for this block.
- BlockPopStacks(block, pRenameState);
+ // Done, pop all SSA numbers pushed in this block.
+ pRenameState->PopBlockStacks(block);
DBG_SSA_JITDUMP("[SsaBuilder::RenameVariables] done with " FMT_BB "\n", block->bbNum);
}
}
@@ -1744,9 +1723,8 @@ void SsaBuilder::Build()
InsertPhiFunctions(postOrder, count);
// Rename local variables and collect UD information for each ssa var.
- SsaRenameState* pRenameState =
- new (m_allocator) SsaRenameState(m_allocator, m_pCompiler->lvaCount, m_pCompiler->byrefStatesMatchGcHeapStates);
- RenameVariables(domTree, pRenameState);
+ SsaRenameState renameState(m_allocator, m_pCompiler->lvaCount);
+ RenameVariables(domTree, &renameState);
EndPhase(PHASE_BUILD_SSA_RENAME);
#ifdef DEBUG
diff --git a/src/jit/ssabuilder.h b/src/jit/ssabuilder.h
index eab25549df..86c1d12543 100644
--- a/src/jit/ssabuilder.h
+++ b/src/jit/ssabuilder.h
@@ -9,7 +9,7 @@
#include "compiler.h"
-struct SsaRenameState;
+class SsaRenameState;
typedef int LclVarNum;
@@ -105,12 +105,6 @@ private:
// Assigns gtSsaNames to all variables.
void RenameVariables(BlkToBlkVectorMap* domTree, SsaRenameState* pRenameState);
- // Requires "block" to be any basic block participating in variable renaming, and has at least a
- // definition that pushed a ssa number into the rename stack for a variable. Requires "pRenameState"
- // to have variable stacks that have counts pushed into them for the block while assigning def
- // numbers. Pops the stack for any local variable that has an entry for block on top.
- void BlockPopStacks(BasicBlock* block, SsaRenameState* pRenameState);
-
// Requires "block" to be non-NULL; and is searched for defs and uses to assign ssa numbers.
// Requires "pRenameState" to be non-NULL and be currently used for variables renaming.
void BlockRenameVariables(BasicBlock* block, SsaRenameState* pRenameState);
@@ -120,15 +114,15 @@ private:
// implies that any definition occurring within "tree" is a phi definition.
void TreeRenameVariables(GenTree* tree, BasicBlock* block, SsaRenameState* pRenameState, bool isPhiDefn);
- // Assumes that "block" contains a definition for local var "lclNum", with SSA number "count".
+ // Assumes that "block" contains a definition for local var "lclNum", with SSA number "ssaNum".
// IF "block" is within one or more try blocks,
// and the local variable is live at the start of the corresponding handlers,
- // add this SSA number "count" to the argument list of the phi for the variable in the start
+ // add this SSA number "ssaNum" to the argument list of the phi for the variable in the start
// block of those handlers.
- void AddDefToHandlerPhis(BasicBlock* block, unsigned lclNum, unsigned count);
+ void AddDefToHandlerPhis(BasicBlock* block, unsigned lclNum, unsigned ssaNum);
// Same as above, for memory.
- void AddMemoryDefToHandlerPhis(MemoryKind memoryKind, BasicBlock* block, unsigned count);
+ void AddMemoryDefToHandlerPhis(MemoryKind memoryKind, BasicBlock* block, unsigned ssaNum);
// Requires "block" to be non-NULL. Requires "pRenameState" to be non-NULL and be currently used
// for variables renaming. Assigns the rhs arguments to the phi, i.e., block's phi node arguments.
diff --git a/src/jit/ssarenamestate.cpp b/src/jit/ssarenamestate.cpp
index 63f120a521..c715aeb643 100644
--- a/src/jit/ssarenamestate.cpp
+++ b/src/jit/ssarenamestate.cpp
@@ -6,185 +6,156 @@
#include "ssaconfig.h"
#include "ssarenamestate.h"
-/**
- * Constructor - initialize the stacks and counters maps (lclVar -> stack/counter) map.
- *
- * @params alloc The allocator class used to allocate jitstd data.
- */
-SsaRenameState::SsaRenameState(CompAllocator alloc, unsigned lvaCount, bool byrefStatesMatchGcHeapStates)
- : stacks(nullptr)
- , definedLocs(alloc)
- , memoryStack(alloc)
- , lvaCount(lvaCount)
- , m_alloc(alloc)
- , byrefStatesMatchGcHeapStates(byrefStatesMatchGcHeapStates)
+//------------------------------------------------------------------------
+// SsaRenameState: Initialize SsaRenameState
+//
+// Arguments:
+// alloc - A memory allocator
+// lvaCount - The number of local variables
+//
+SsaRenameState::SsaRenameState(CompAllocator alloc, unsigned lvaCount)
+ : m_alloc(alloc), m_lvaCount(lvaCount), m_stacks(nullptr), m_stackListTail(nullptr)
{
}
-/**
- * Allocates memory for holding pointers to lcl's stacks,
- * if not allocated already.
- *
- */
+//------------------------------------------------------------------------
+// EnsureStacks: Allocate memory for the stacks array.
+//
void SsaRenameState::EnsureStacks()
{
- if (stacks == nullptr)
+ if (m_stacks == nullptr)
{
- stacks = m_alloc.allocate<Stack*>(lvaCount);
- for (unsigned i = 0; i < lvaCount; ++i)
- {
- stacks[i] = nullptr;
- }
+ m_stacks = new (m_alloc) Stack[m_lvaCount]();
}
}
-/**
- * Returns a SSA count number for a local variable from top of the stack.
- *
- * @params lclNum The local variable def for which a count has to be returned.
- * @return the current variable name for the "use".
- *
- * @remarks If the stack is empty, then we have an use before a def. To handle this
- * special case, we need to initialize the count with 'default+1', so the
- * next definition will always use 'default+1' but return 'default' for
- * all uses until a definition.
- *
- */
-unsigned SsaRenameState::CountForUse(unsigned lclNum)
+//------------------------------------------------------------------------
+// Top: Get the SSA number at the top of the stack for the specified variable.
+//
+// Arguments:
+// lclNum - The local variable number
+//
+// Return Value:
+// The SSA number.
+//
+// Notes:
+// The stack must not be empty. Method parameters and local variables that are live in at
+// the start of the first block must have associated SSA definitions and their SSA numbers
+// must have been pushed first.
+//
+unsigned SsaRenameState::Top(unsigned lclNum)
{
- EnsureStacks();
- DBG_SSA_JITDUMP("[SsaRenameState::CountForUse] V%02u\n", lclNum);
+ DBG_SSA_JITDUMP("[SsaRenameState::Top] V%02u\n", lclNum);
- Stack* stack = stacks[lclNum];
- noway_assert((stack != nullptr) && !stack->empty());
- return stack->back().m_count;
+ noway_assert(m_stacks != nullptr);
+ StackNode* top = m_stacks[lclNum].Top();
+ noway_assert(top != nullptr);
+ return top->m_ssaNum;
}
-/**
- * Pushes a count value on the variable stack.
- *
- * @params lclNum The local variable def whose stack the count needs to be pushed onto.
- * @params count The current count value that needs to be pushed on to the stack.
- *
- * @remarks Usually called when renaming a "def."
- * Create stack lazily when needed for the first time.
- */
-void SsaRenameState::Push(BasicBlock* bb, unsigned lclNum, unsigned count)
+//------------------------------------------------------------------------
+// Push: Push a SSA number onto the stack for the specified variable.
+//
+// Arguments:
+// block - The block where the SSA definition occurs
+// lclNum - The local variable number
+// ssaNum - The SSA number
+//
+void SsaRenameState::Push(BasicBlock* block, unsigned lclNum, unsigned ssaNum)
{
- EnsureStacks();
-
- // We'll use BB00 here to indicate the "block before any real blocks..."
- DBG_SSA_JITDUMP("[SsaRenameState::Push] " FMT_BB ", V%02u, count = %d\n", bb != nullptr ? bb->bbNum : 0, lclNum,
- count);
+ DBG_SSA_JITDUMP("[SsaRenameState::Push] " FMT_BB ", V%02u, count = %d\n", block->bbNum, lclNum, ssaNum);
- Stack* stack = stacks[lclNum];
+ EnsureStacks();
+ Push(&m_stacks[lclNum], block, ssaNum);
+}
- if (stack == nullptr)
- {
- DBG_SSA_JITDUMP("\tCreating a new stack\n");
- stack = stacks[lclNum] = new (m_alloc) Stack(m_alloc);
- }
+//------------------------------------------------------------------------
+// Push: Push a SSA number onto a stack
+//
+// Arguments:
+// stack - The stack to push to
+// block - The block where the SSA definition occurs
+// ssaNum - The SSA number
+//
+void SsaRenameState::Push(Stack* stack, BasicBlock* block, unsigned ssaNum)
+{
+ StackNode* top = stack->Top();
- if (stack->empty() || stack->back().m_bb != bb)
+ if ((top == nullptr) || (top->m_block != block))
{
- stack->push_back(SsaRenameStateForBlock(bb, count));
- // Remember that we've pushed a def for this loc (so we don't have
- // to traverse *all* the locs to do the necessary pops later).
- definedLocs.push_back(SsaRenameStateLocDef(bb, lclNum));
+ stack->Push(AllocStackNode(m_stackListTail, block, ssaNum));
+ // Append the stack to the stack list. The stack list allows PopBlockStacks
+ // to easily find stacks that need popping.
+ m_stackListTail = stack;
}
else
{
- stack->back().m_count = count;
+ // If we already have a stack node for this block then simply update
+ // update the SSA number, the previous one is no longer needed.
+ top->m_ssaNum = ssaNum;
}
-#ifdef DEBUG
- if (JitTls::GetCompiler()->verboseSsa)
- {
- printf("\tContents of the stack: [");
- for (Stack::iterator iter2 = stack->begin(); iter2 != stack->end(); iter2++)
- {
- printf("<" FMT_BB ", %d>", ((*iter2).m_bb != nullptr ? (*iter2).m_bb->bbNum : 0), (*iter2).m_count);
- }
- printf("]\n");
-
- DumpStacks();
- }
-#endif
+ INDEBUG(DumpStack(stack));
}
void SsaRenameState::PopBlockStacks(BasicBlock* block)
{
DBG_SSA_JITDUMP("[SsaRenameState::PopBlockStacks] " FMT_BB "\n", block->bbNum);
- // Iterate over the stacks for all the variables, popping those that have an entry
- // for "block" on top.
- while (!definedLocs.empty() && definedLocs.back().m_bb == block)
+
+ while ((m_stackListTail != nullptr) && (m_stackListTail->Top()->m_block == block))
{
- unsigned lclNum = definedLocs.back().m_lclNum;
- assert(stacks != nullptr); // Cannot be empty because definedLocs is not empty.
- Stack* stack = stacks[lclNum];
- assert(stack != nullptr);
- assert(stack->back().m_bb == block);
- stack->pop_back();
- definedLocs.pop_back();
+ StackNode* top = m_stackListTail->Pop();
+ INDEBUG(DumpStack(m_stackListTail));
+ m_stackListTail = top->m_listPrev;
+ m_freeStack.Push(top);
}
+
#ifdef DEBUG
- // It should now be the case that no stack in stacks has an entry for "block" on top --
- // the loop above popped them all.
- for (unsigned i = 0; i < lvaCount; ++i)
+ if (m_stacks != nullptr)
{
- if (stacks != nullptr && stacks[i] != nullptr && !stacks[i]->empty())
+ // It should now be the case that no stack in stacks has an entry for "block" on top --
+ // the loop above popped them all.
+ for (unsigned i = 0; i < m_lvaCount; ++i)
{
- assert(stacks[i]->back().m_bb != block);
+ if (m_stacks[i].Top() != nullptr)
+ {
+ assert(m_stacks[i].Top()->m_block != block);
+ }
}
}
- if (JitTls::GetCompiler()->verboseSsa)
- {
- DumpStacks();
- }
#endif // DEBUG
}
-void SsaRenameState::PopBlockMemoryStack(MemoryKind memoryKind, BasicBlock* block)
-{
- auto& stack = memoryStack[memoryKind];
- while (stack.size() > 0 && stack.back().m_bb == block)
- {
- stack.pop_back();
- }
-}
-
#ifdef DEBUG
-/**
- * Print the stack data for each variable in a loop.
- */
-void SsaRenameState::DumpStacks()
+//------------------------------------------------------------------------
+// DumpStack: Print the specified stack.
+//
+// Arguments:
+// stack - The stack to print
+//
+void SsaRenameState::DumpStack(Stack* stack)
{
- printf("Dumping stacks:\n-------------------------------\n");
- if (lvaCount == 0)
- {
- printf("None\n");
- }
- else
+ if (JitTls::GetCompiler()->verboseSsa)
{
- EnsureStacks();
- for (unsigned i = 0; i < lvaCount; ++i)
+ if (stack == &m_memoryStack[ByrefExposed])
{
- Stack* stack = stacks[i];
- printf("V%02u:\t", i);
- if (stack != nullptr)
- {
- for (Stack::iterator iter2 = stack->begin(); iter2 != stack->end(); ++iter2)
- {
- if (iter2 != stack->begin())
- {
- printf(", ");
- }
- printf("<" FMT_BB ", %2d>", ((*iter2).m_bb != nullptr ? (*iter2).m_bb->bbNum : 0),
- (*iter2).m_count);
- }
- }
- printf("\n");
+ printf("ByrefExposed: ");
+ }
+ else if (stack == &m_memoryStack[GcHeap])
+ {
+ printf("GcHeap: ");
+ }
+ else
+ {
+ printf("V%02u: ", stack - m_stacks);
}
+
+ for (StackNode* i = stack->Top(); i != nullptr; i = i->m_stackPrev)
+ {
+ printf("%s<" FMT_BB ", %u>", (i == stack->Top()) ? "" : ", ", i->m_block->bbNum, i->m_ssaNum);
+ }
+
+ printf("\n");
}
}
#endif // DEBUG
diff --git a/src/jit/ssarenamestate.h b/src/jit/ssarenamestate.h
index 96abf5aa20..bf7dac15d8 100644
--- a/src/jit/ssarenamestate.h
+++ b/src/jit/ssarenamestate.h
@@ -4,144 +4,114 @@
#pragma once
-#include "jitstd.h"
-
-// Fixed-size array that can hold elements with no default constructor;
-// it will construct them all by forwarding whatever arguments are
-// supplied to its constructor.
-template <typename T, int N>
-class ConstructedArray
+class SsaRenameState
{
- union {
- // Storage that gets used to hold the T objects.
- unsigned char bytes[N * sizeof(T)];
-
-#if defined(_MSC_VER) && (_MSC_VER < 1900)
- // With MSVC pre-VS2015, the code in the #else branch would hit error C2621,
- // so in that case just count on pointer alignment being sufficient
- // (currently T is only ever instantiated as jitstd::list<SsaRenameStateForBlock>)
-
- // Unused (except to impart alignment requirement)
- void* pointer;
-#else
- // Unused (except to impart alignment requirement)
- T alignedArray[N];
-#endif // defined(_MSC_VER) && (_MSC_VER < 1900)
- };
+ struct StackNode;
-public:
- T& operator[](size_t i)
+ class Stack
{
- return *(reinterpret_cast<T*>(bytes + i * sizeof(T)));
- }
+ StackNode* m_top;
- template <typename... Args>
- ConstructedArray(Args&&... args)
- {
- for (int i = 0; i < N; ++i)
+ public:
+ Stack() : m_top(nullptr)
{
- new (bytes + i * sizeof(T), jitstd::placement_t()) T(jitstd::forward<Args>(args)...);
}
- }
- ~ConstructedArray()
- {
- for (int i = 0; i < N; ++i)
+ StackNode* Top()
{
- operator[](i).~T();
+ return m_top;
}
- }
-};
-struct SsaRenameStateForBlock
-{
- BasicBlock* m_bb;
- unsigned m_count;
-
- SsaRenameStateForBlock(BasicBlock* bb, unsigned count) : m_bb(bb), m_count(count)
- {
- }
- SsaRenameStateForBlock() : m_bb(nullptr), m_count(0)
- {
- }
-};
+ void Push(StackNode* node)
+ {
+ node->m_stackPrev = m_top;
+ m_top = node;
+ }
-// A record indicating that local "m_loc" was defined in block "m_bb".
-struct SsaRenameStateLocDef
-{
- BasicBlock* m_bb;
- unsigned m_lclNum;
+ StackNode* Pop()
+ {
+ StackNode* top = m_top;
+ m_top = top->m_stackPrev;
+ return top;
+ }
+ };
- SsaRenameStateLocDef(BasicBlock* bb, unsigned lclNum) : m_bb(bb), m_lclNum(lclNum)
+ struct StackNode
{
- }
-};
-
-struct SsaRenameState
-{
- typedef jitstd::list<SsaRenameStateForBlock> Stack;
- typedef Stack** Stacks;
- typedef jitstd::list<SsaRenameStateLocDef> DefStack;
+ // Link to the previous stack top node
+ StackNode* m_stackPrev;
+ // Link to the previously pushed stack (used only when popping blocks)
+ Stack* m_listPrev;
+ // The basic block (used only when popping blocks)
+ BasicBlock* m_block;
+ // The actual information StackNode stores - the SSA number
+ unsigned m_ssaNum;
+
+ StackNode(Stack* listPrev, BasicBlock* block, unsigned ssaNum)
+ : m_listPrev(listPrev), m_block(block), m_ssaNum(ssaNum)
+ {
+ }
+ };
- SsaRenameState(CompAllocator allocator, unsigned lvaCount, bool byrefStatesMatchGcHeapStates);
+ // Memory allocator
+ CompAllocator m_alloc;
+ // Number of local variables to allocate stacks for
+ unsigned m_lvaCount;
+ // An array of stack objects, one for each local variable
+ Stack* m_stacks;
+ // The tail of the list of stacks that have been pushed to
+ Stack* m_stackListTail;
+ // Same state for the special implicit memory variables
+ Stack m_memoryStack[MemoryKindCount];
+ // A stack of free stack nodes
+ Stack m_freeStack;
- void EnsureStacks();
+public:
+ SsaRenameState(CompAllocator alloc, unsigned lvaCount);
- // Requires "lclNum" to be a variable number for which an ssa number at the top of the
- // stack is required i.e., for variable "uses."
- unsigned CountForUse(unsigned lclNum);
+ // Get the SSA number at the top of the stack for the specified variable.
+ unsigned Top(unsigned lclNum);
- // Requires "lclNum" to be a variable number, and requires "count" to represent
- // an ssa number, that needs to be pushed on to the stack corresponding to the lclNum.
- void Push(BasicBlock* bb, unsigned lclNum, unsigned count);
+ // Push a SSA number onto the stack for the specified variable.
+ void Push(BasicBlock* block, unsigned lclNum, unsigned ssaNum);
- // Pop all stacks that have an entry for "bb" on top.
- void PopBlockStacks(BasicBlock* bb);
+ // Pop all stacks that have an entry for "block" on top.
+ void PopBlockStacks(BasicBlock* block);
// Similar functions for the special implicit memory variable.
- unsigned CountForMemoryUse(MemoryKind memoryKind)
+ unsigned TopMemory(MemoryKind memoryKind)
{
- if ((memoryKind == GcHeap) && byrefStatesMatchGcHeapStates)
- {
- // Share rename stacks in this configuration.
- memoryKind = ByrefExposed;
- }
- return memoryStack[memoryKind].back().m_count;
+ return m_memoryStack[memoryKind].Top()->m_ssaNum;
}
- void PushMemory(MemoryKind memoryKind, BasicBlock* bb, unsigned count)
+ void PushMemory(MemoryKind memoryKind, BasicBlock* block, unsigned ssaNum)
{
- if ((memoryKind == GcHeap) && byrefStatesMatchGcHeapStates)
- {
- // Share rename stacks in this configuration.
- memoryKind = ByrefExposed;
- }
- memoryStack[memoryKind].push_back(SsaRenameStateForBlock(bb, count));
+ Push(&m_memoryStack[memoryKind], block, ssaNum);
}
- void PopBlockMemoryStack(MemoryKind memoryKind, BasicBlock* bb);
-
-#ifdef DEBUG
- // Debug interface
- void DumpStacks();
-#endif
-
private:
- // Map of lclNum -> SsaRenameStateForBlock.
- Stacks stacks;
+ void EnsureStacks();
- // This list represents the set of locals defined in the current block.
- DefStack definedLocs;
+ // Allocate a new stack entry (possibly by popping it from the free stack)
+ template <class... Args>
+ StackNode* AllocStackNode(Args&&... args)
+ {
+ StackNode* stack = m_freeStack.Top();
- // Same state for the special implicit memory variables.
- ConstructedArray<Stack, MemoryKindCount> memoryStack;
+ if (stack != nullptr)
+ {
+ m_freeStack.Pop();
+ }
+ else
+ {
+ stack = m_alloc.allocate<StackNode>(1);
+ }
- // Number of stacks/counts to allocate.
- unsigned lvaCount;
+ return new (stack, jitstd::placement_t()) StackNode(jitstd::forward<Args>(args)...);
+ }
- // Allocator to allocate stacks.
- CompAllocator m_alloc;
+ // Push a SSA number onto a stack
+ void Push(Stack* stack, BasicBlock* block, unsigned ssaNum);
- // Indicates whether GcHeap and ByrefExposed use the same state.
- bool byrefStatesMatchGcHeapStates;
+ INDEBUG(void DumpStack(Stack* stack);)
};
diff --git a/src/md/compiler/classfactory.cpp b/src/md/compiler/classfactory.cpp
index 338095add3..af34970d59 100644
--- a/src/md/compiler/classfactory.cpp
+++ b/src/md/compiler/classfactory.cpp
@@ -26,8 +26,6 @@
#include "clrprivhosting.h"
-extern HRESULT TypeNameFactoryCreateObject(REFIID riid, void **ppUnk);
-
#include <ndpversion.h>
diff --git a/src/pal/prebuilt/idl/gchost_i.cpp b/src/pal/prebuilt/idl/gchost_i.cpp
deleted file mode 100644
index 32ecfbe9d5..0000000000
--- a/src/pal/prebuilt/idl/gchost_i.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-// 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 ALWAYS GENERATED file contains the IIDs and CLSIDs */
-
-/* link this file in with the server and any clients */
-
-
- /* File created by MIDL compiler version 8.00.0603 */
-/* @@MIDL_FILE_HEADING( ) */
-
-#pragma warning( disable: 4049 ) /* more than 64k source lines */
-
-
-#ifdef __cplusplus
-extern "C"{
-#endif
-
-
-#include <rpc.h>
-#include <rpcndr.h>
-
-#ifdef _MIDL_USE_GUIDDEF_
-
-#ifndef INITGUID
-#define INITGUID
-#include <guiddef.h>
-#undef INITGUID
-#else
-#include <guiddef.h>
-#endif
-
-#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
- DEFINE_GUID(name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8)
-
-#else // !_MIDL_USE_GUIDDEF_
-
-#ifndef __IID_DEFINED__
-#define __IID_DEFINED__
-
-typedef struct _IID
-{
- unsigned long x;
- unsigned short s1;
- unsigned short s2;
- unsigned char c[8];
-} IID;
-
-#endif // __IID_DEFINED__
-
-#ifndef CLSID_DEFINED
-#define CLSID_DEFINED
-typedef IID CLSID;
-#endif // CLSID_DEFINED
-
-#define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) \
- const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}}
-
-#endif !_MIDL_USE_GUIDDEF_
-
-MIDL_DEFINE_GUID(IID, IID_IDummyDoNotUse,0xF9423916,0x2A35,0x4f03,0x9E,0xE9,0xDD,0xAF,0xA3,0xC8,0xAE,0xE0);
-
-#undef MIDL_DEFINE_GUID
-
-#ifdef __cplusplus
-}
-#endif
-
-
-
diff --git a/src/pal/prebuilt/inc/gchost.h b/src/pal/prebuilt/inc/gchost.h
deleted file mode 100644
index c9e4fffa18..0000000000
--- a/src/pal/prebuilt/inc/gchost.h
+++ /dev/null
@@ -1,166 +0,0 @@
-// 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 ALWAYS GENERATED file contains the definitions for the interfaces */
-
-
- /* File created by MIDL compiler version 8.00.0603 */
-/* @@MIDL_FILE_HEADING( ) */
-
-#pragma warning( disable: 4049 ) /* more than 64k source lines */
-
-
-/* verify that the <rpcndr.h> version is high enough to compile this file*/
-#ifndef __REQUIRED_RPCNDR_H_VERSION__
-#define __REQUIRED_RPCNDR_H_VERSION__ 475
-#endif
-
-#include "rpc.h"
-#include "rpcndr.h"
-
-#ifndef __RPCNDR_H_VERSION__
-#error this stub requires an updated version of <rpcndr.h>
-#endif // __RPCNDR_H_VERSION__
-
-#ifndef COM_NO_WINDOWS_H
-#include "windows.h"
-#include "ole2.h"
-#endif /*COM_NO_WINDOWS_H*/
-
-#ifndef __gchost_h__
-#define __gchost_h__
-
-#if defined(_MSC_VER) && (_MSC_VER >= 1020)
-#pragma once
-#endif
-
-/* Forward Declarations */
-
-#ifndef __IDummyDoNotUse_FWD_DEFINED__
-#define __IDummyDoNotUse_FWD_DEFINED__
-typedef interface IDummyDoNotUse IDummyDoNotUse;
-
-#endif /* __IDummyDoNotUse_FWD_DEFINED__ */
-
-
-/* header files for imported files */
-#include "unknwn.h"
-
-#ifdef __cplusplus
-extern "C"{
-#endif
-
-
-/* interface __MIDL_itf_gchost_0000_0000 */
-/* [local] */
-
-typedef struct _COR_GC_STATS
- {
- ULONG Flags;
- SIZE_T ExplicitGCCount;
- SIZE_T GenCollectionsTaken[ 3 ];
- SIZE_T CommittedKBytes;
- SIZE_T ReservedKBytes;
- SIZE_T Gen0HeapSizeKBytes;
- SIZE_T Gen1HeapSizeKBytes;
- SIZE_T Gen2HeapSizeKBytes;
- SIZE_T LargeObjectHeapSizeKBytes;
- SIZE_T KBytesPromotedFromGen0;
- SIZE_T KBytesPromotedFromGen1;
- } COR_GC_STATS;
-
-/*
- * WARNING - This is a dummy interface that should never be used.
- * The code is written this way because Midl requires a CoClass, Interface, etc... that generates
- * a guid. Removing the IGCHost interface removes the only guid
- * This option was selected because ifdefs are not simple to implement for excluding files in SOURCES
-*/
-
-
-extern RPC_IF_HANDLE __MIDL_itf_gchost_0000_0000_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_gchost_0000_0000_v0_0_s_ifspec;
-
-#ifndef __IDummyDoNotUse_INTERFACE_DEFINED__
-#define __IDummyDoNotUse_INTERFACE_DEFINED__
-
-/* interface IDummyDoNotUse */
-/* [local][unique][uuid][object] */
-
-
-EXTERN_C const IID IID_IDummyDoNotUse;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("F9423916-2A35-4f03-9EE9-DDAFA3C8AEE0")
- IDummyDoNotUse : public IUnknown
- {
- public:
- };
-
-
-#else /* C style interface */
-
- typedef struct IDummyDoNotUseVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDummyDoNotUse * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDummyDoNotUse * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDummyDoNotUse * This);
-
- END_INTERFACE
- } IDummyDoNotUseVtbl;
-
- interface IDummyDoNotUse
- {
- CONST_VTBL struct IDummyDoNotUseVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDummyDoNotUse_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDummyDoNotUse_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDummyDoNotUse_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDummyDoNotUse_INTERFACE_DEFINED__ */
-
-
-/* Additional Prototypes for ALL interfaces */
-
-/* end of Additional Prototypes */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-
diff --git a/src/pal/prebuilt/inc/metahost.h b/src/pal/prebuilt/inc/metahost.h
index aa6c78c944..aae25d70db 100644
--- a/src/pal/prebuilt/inc/metahost.h
+++ b/src/pal/prebuilt/inc/metahost.h
@@ -6,7 +6,7 @@
/* File created by MIDL compiler version 8.01.0622 */
/* at Mon Jan 18 19:14:07 2038
*/
-/* Compiler settings for C:/ssd/coreclr/src/inc/metahost.idl:
+/* Compiler settings for metahost.idl:
Oicf, W1, Zp8, env=Win32 (32b run), target_arch=X86 8.01.0622
protocol : dce , ms_ext, c_ext, robust
error checks: allocation ref bounds_check enum stub_data
@@ -52,13 +52,6 @@ typedef interface ICLRMetaHost ICLRMetaHost;
#endif /* __ICLRMetaHost_FWD_DEFINED__ */
-#ifndef __ICLRMetaHostPolicy_FWD_DEFINED__
-#define __ICLRMetaHostPolicy_FWD_DEFINED__
-typedef interface ICLRMetaHostPolicy ICLRMetaHostPolicy;
-
-#endif /* __ICLRMetaHostPolicy_FWD_DEFINED__ */
-
-
#ifndef __ICLRDebuggingLibraryProvider_FWD_DEFINED__
#define __ICLRDebuggingLibraryProvider_FWD_DEFINED__
typedef interface ICLRDebuggingLibraryProvider ICLRDebuggingLibraryProvider;
@@ -87,69 +80,6 @@ typedef interface ICLRRuntimeInfo ICLRRuntimeInfo;
#endif /* __ICLRRuntimeInfo_FWD_DEFINED__ */
-#ifndef __ICLRStrongName_FWD_DEFINED__
-#define __ICLRStrongName_FWD_DEFINED__
-typedef interface ICLRStrongName ICLRStrongName;
-
-#endif /* __ICLRStrongName_FWD_DEFINED__ */
-
-
-#ifndef __ICLRStrongName2_FWD_DEFINED__
-#define __ICLRStrongName2_FWD_DEFINED__
-typedef interface ICLRStrongName2 ICLRStrongName2;
-
-#endif /* __ICLRStrongName2_FWD_DEFINED__ */
-
-
-#ifndef __ICLRStrongName3_FWD_DEFINED__
-#define __ICLRStrongName3_FWD_DEFINED__
-typedef interface ICLRStrongName3 ICLRStrongName3;
-
-#endif /* __ICLRStrongName3_FWD_DEFINED__ */
-
-
-#ifndef __ICLRMetaHost_FWD_DEFINED__
-#define __ICLRMetaHost_FWD_DEFINED__
-typedef interface ICLRMetaHost ICLRMetaHost;
-
-#endif /* __ICLRMetaHost_FWD_DEFINED__ */
-
-
-#ifndef __ICLRMetaHostPolicy_FWD_DEFINED__
-#define __ICLRMetaHostPolicy_FWD_DEFINED__
-typedef interface ICLRMetaHostPolicy ICLRMetaHostPolicy;
-
-#endif /* __ICLRMetaHostPolicy_FWD_DEFINED__ */
-
-
-#ifndef __ICLRDebuggingLibraryProvider_FWD_DEFINED__
-#define __ICLRDebuggingLibraryProvider_FWD_DEFINED__
-typedef interface ICLRDebuggingLibraryProvider ICLRDebuggingLibraryProvider;
-
-#endif /* __ICLRDebuggingLibraryProvider_FWD_DEFINED__ */
-
-
-#ifndef __ICLRDebugging_FWD_DEFINED__
-#define __ICLRDebugging_FWD_DEFINED__
-typedef interface ICLRDebugging ICLRDebugging;
-
-#endif /* __ICLRDebugging_FWD_DEFINED__ */
-
-
-#ifndef __ICLRRuntimeInfo_FWD_DEFINED__
-#define __ICLRRuntimeInfo_FWD_DEFINED__
-typedef interface ICLRRuntimeInfo ICLRRuntimeInfo;
-
-#endif /* __ICLRRuntimeInfo_FWD_DEFINED__ */
-
-
-#ifndef __ICLRStrongName_FWD_DEFINED__
-#define __ICLRStrongName_FWD_DEFINED__
-typedef interface ICLRStrongName ICLRStrongName;
-
-#endif /* __ICLRStrongName_FWD_DEFINED__ */
-
-
/* header files for imported files */
#include "unknwn.h"
#include "oaidl.h"
@@ -165,33 +95,14 @@ extern "C"{
/* [local] */
#include <winapifamily.h>
-#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
STDAPI CLRCreateInstance(REFCLSID clsid, REFIID riid, /*iid_is(riid)*/ LPVOID *ppInterface);
-EXTERN_GUID(CLSID_CLRStrongName, 0xB79B0ACD, 0xF5CD, 0x409b, 0xB5, 0xA5, 0xA1, 0x62, 0x44, 0x61, 0x0B, 0x92);
EXTERN_GUID(IID_ICLRMetaHost, 0xD332DB9E, 0xB9B3, 0x4125, 0x82, 0x07, 0xA1, 0x48, 0x84, 0xF5, 0x32, 0x16);
EXTERN_GUID(CLSID_CLRMetaHost, 0x9280188d, 0xe8e, 0x4867, 0xb3, 0xc, 0x7f, 0xa8, 0x38, 0x84, 0xe8, 0xde);
-EXTERN_GUID(IID_ICLRMetaHostPolicy, 0xE2190695, 0x77B2, 0x492e, 0x8E, 0x14, 0xC4, 0xB3, 0xA7, 0xFD, 0xD5, 0x93);
-EXTERN_GUID(CLSID_CLRMetaHostPolicy, 0x2ebcd49a, 0x1b47, 0x4a61, 0xb1, 0x3a, 0x4a, 0x3, 0x70, 0x1e, 0x59, 0x4b);
EXTERN_GUID(IID_ICLRDebugging, 0xd28f3c5a, 0x9634, 0x4206, 0xa5, 0x9, 0x47, 0x75, 0x52, 0xee, 0xfb, 0x10);
EXTERN_GUID(CLSID_CLRDebugging, 0xbacc578d, 0xfbdd, 0x48a4, 0x96, 0x9f, 0x2, 0xd9, 0x32, 0xb7, 0x46, 0x34);
EXTERN_GUID(IID_ICLRRuntimeInfo, 0xBD39D1D2, 0xBA2F, 0x486a, 0x89, 0xB0, 0xB4, 0xB0, 0xCB, 0x46, 0x68, 0x91);
-EXTERN_GUID(IID_ICLRStrongName, 0x9FD93CCF, 0x3280, 0x4391, 0xB3, 0xA9, 0x96, 0xE1, 0xCD, 0xE7, 0x7C, 0x8D);
-EXTERN_GUID(IID_ICLRStrongName2, 0xC22ED5C5, 0x4B59, 0x4975, 0x90, 0xEB, 0x85, 0xEA, 0x55, 0xC0, 0x06, 0x9B);
-EXTERN_GUID(IID_ICLRStrongName3, 0x22c7089b, 0xbbd3, 0x414a, 0xb6, 0x98, 0x21, 0x0f, 0x26, 0x3f, 0x1f, 0xed);
-EXTERN_GUID(CLSID_CLRDebuggingLegacy, 0xDF8395B5, 0xA4BA, 0x450b, 0xA7, 0x7C, 0xA9, 0xA4, 0x77, 0x62, 0xC5, 0x20);
-EXTERN_GUID(CLSID_CLRProfiling, 0xbd097ed8, 0x733e, 0x43fe, 0x8e, 0xd7, 0xa9, 0x5f, 0xf9, 0xa8, 0x44, 0x8c);
EXTERN_GUID(IID_ICLRDebuggingLibraryProvider, 0x3151c08d, 0x4d09, 0x4f9b, 0x88, 0x38, 0x28, 0x80, 0xbf, 0x18, 0xfe, 0x51);
EXTERN_GUID(IID_ICLRDebuggingLibraryProvider2, 0xE04E2FF1, 0xDCFD, 0x45D5, 0xBC, 0xD1, 0x16, 0xFF, 0xF2, 0xFA, 0xF7, 0xBA);
-typedef HRESULT ( __stdcall *CLRCreateInstanceFnPtr )(
- REFCLSID clsid,
- REFIID riid,
- LPVOID *ppInterface);
-
-typedef HRESULT ( __stdcall *CreateInterfaceFnPtr )(
- REFCLSID clsid,
- REFIID riid,
- LPVOID *ppInterface);
-
typedef HRESULT ( __stdcall *CallbackThreadSetFnPtr )( void);
@@ -364,137 +275,6 @@ EXTERN_C const IID IID_ICLRMetaHost;
/* interface __MIDL_itf_metahost_0000_0001 */
/* [local] */
-typedef /* [public][public] */
-enum __MIDL___MIDL_itf_metahost_0000_0001_0001
- {
- METAHOST_POLICY_HIGHCOMPAT = 0,
- METAHOST_POLICY_APPLY_UPGRADE_POLICY = 0x8,
- METAHOST_POLICY_EMULATE_EXE_LAUNCH = 0x10,
- METAHOST_POLICY_SHOW_ERROR_DIALOG = 0x20,
- METAHOST_POLICY_USE_PROCESS_IMAGE_PATH = 0x40,
- METAHOST_POLICY_ENSURE_SKU_SUPPORTED = 0x80,
- METAHOST_POLICY_IGNORE_ERROR_MODE = 0x1000
- } METAHOST_POLICY_FLAGS;
-
-typedef /* [public] */
-enum __MIDL___MIDL_itf_metahost_0000_0001_0002
- {
- METAHOST_CONFIG_FLAGS_LEGACY_V2_ACTIVATION_POLICY_UNSET = 0,
- METAHOST_CONFIG_FLAGS_LEGACY_V2_ACTIVATION_POLICY_TRUE = 0x1,
- METAHOST_CONFIG_FLAGS_LEGACY_V2_ACTIVATION_POLICY_FALSE = 0x2,
- METAHOST_CONFIG_FLAGS_LEGACY_V2_ACTIVATION_POLICY_MASK = 0x3
- } METAHOST_CONFIG_FLAGS;
-
-
-
-extern RPC_IF_HANDLE __MIDL_itf_metahost_0000_0001_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_metahost_0000_0001_v0_0_s_ifspec;
-
-#ifndef __ICLRMetaHostPolicy_INTERFACE_DEFINED__
-#define __ICLRMetaHostPolicy_INTERFACE_DEFINED__
-
-/* interface ICLRMetaHostPolicy */
-/* [object][local][helpstring][version][uuid] */
-
-
-EXTERN_C const IID IID_ICLRMetaHostPolicy;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("E2190695-77B2-492e-8E14-C4B3A7FDD593")
- ICLRMetaHostPolicy : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetRequestedRuntime(
- /* [in] */ METAHOST_POLICY_FLAGS dwPolicyFlags,
- /* [in] */ LPCWSTR pwzBinary,
- /* [in] */ IStream *pCfgStream,
- /* [annotation][size_is][out][in] */
- _Inout_updates_all_opt_(*pcchVersion) LPWSTR pwzVersion,
- /* [out][in] */ DWORD *pcchVersion,
- /* [annotation][size_is][out] */
- _Out_writes_all_opt_(*pcchImageVersion) LPWSTR pwzImageVersion,
- /* [out][in] */ DWORD *pcchImageVersion,
- /* [out] */ DWORD *pdwConfigFlags,
- /* [in] */ REFIID riid,
- /* [retval][iid_is][out] */ LPVOID *ppRuntime) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct ICLRMetaHostPolicyVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- ICLRMetaHostPolicy * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- ICLRMetaHostPolicy * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- ICLRMetaHostPolicy * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetRequestedRuntime )(
- ICLRMetaHostPolicy * This,
- /* [in] */ METAHOST_POLICY_FLAGS dwPolicyFlags,
- /* [in] */ LPCWSTR pwzBinary,
- /* [in] */ IStream *pCfgStream,
- /* [annotation][size_is][out][in] */
- _Inout_updates_all_opt_(*pcchVersion) LPWSTR pwzVersion,
- /* [out][in] */ DWORD *pcchVersion,
- /* [annotation][size_is][out] */
- _Out_writes_all_opt_(*pcchImageVersion) LPWSTR pwzImageVersion,
- /* [out][in] */ DWORD *pcchImageVersion,
- /* [out] */ DWORD *pdwConfigFlags,
- /* [in] */ REFIID riid,
- /* [retval][iid_is][out] */ LPVOID *ppRuntime);
-
- END_INTERFACE
- } ICLRMetaHostPolicyVtbl;
-
- interface ICLRMetaHostPolicy
- {
- CONST_VTBL struct ICLRMetaHostPolicyVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define ICLRMetaHostPolicy_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define ICLRMetaHostPolicy_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define ICLRMetaHostPolicy_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define ICLRMetaHostPolicy_GetRequestedRuntime(This,dwPolicyFlags,pwzBinary,pCfgStream,pwzVersion,pcchVersion,pwzImageVersion,pcchImageVersion,pdwConfigFlags,riid,ppRuntime) \
- ( (This)->lpVtbl -> GetRequestedRuntime(This,dwPolicyFlags,pwzBinary,pCfgStream,pwzVersion,pcchVersion,pwzImageVersion,pcchImageVersion,pdwConfigFlags,riid,ppRuntime) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __ICLRMetaHostPolicy_INTERFACE_DEFINED__ */
-
-
-/* interface __MIDL_itf_metahost_0000_0003 */
-/* [local] */
-
typedef struct _CLR_DEBUGGING_VERSION
{
WORD wStructVersion;
@@ -505,7 +285,7 @@ typedef struct _CLR_DEBUGGING_VERSION
} CLR_DEBUGGING_VERSION;
typedef /* [public][public] */
-enum __MIDL___MIDL_itf_metahost_0000_0003_0001
+enum __MIDL___MIDL_itf_metahost_0000_0001_0001
{
CLR_DEBUGGING_MANAGED_EVENT_PENDING = 1,
CLR_DEBUGGING_MANAGED_EVENT_DEBUGGER_LAUNCH = 2
@@ -513,8 +293,8 @@ enum __MIDL___MIDL_itf_metahost_0000_0003_0001
-extern RPC_IF_HANDLE __MIDL_itf_metahost_0000_0003_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_metahost_0000_0003_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_metahost_0000_0001_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_metahost_0000_0001_v0_0_s_ifspec;
#ifndef __ICLRDebuggingLibraryProvider_INTERFACE_DEFINED__
#define __ICLRDebuggingLibraryProvider_INTERFACE_DEFINED__
@@ -1016,739 +796,6 @@ EXTERN_C const IID IID_ICLRRuntimeInfo;
#endif /* __ICLRRuntimeInfo_INTERFACE_DEFINED__ */
-#ifndef __ICLRStrongName_INTERFACE_DEFINED__
-#define __ICLRStrongName_INTERFACE_DEFINED__
-
-/* interface ICLRStrongName */
-/* [object][local][helpstring][version][uuid] */
-
-
-EXTERN_C const IID IID_ICLRStrongName;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("9FD93CCF-3280-4391-B3A9-96E1CDE77C8D")
- ICLRStrongName : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetHashFromAssemblyFile(
- /* [in] */ LPCSTR pszFilePath,
- /* [out][in] */ unsigned int *piHashAlg,
- /* [length_is][size_is][out] */ BYTE *pbHash,
- /* [in] */ DWORD cchHash,
- /* [out] */ DWORD *pchHash) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetHashFromAssemblyFileW(
- /* [in] */ LPCWSTR pwzFilePath,
- /* [out][in] */ unsigned int *piHashAlg,
- /* [length_is][size_is][out] */ BYTE *pbHash,
- /* [in] */ DWORD cchHash,
- /* [out] */ DWORD *pchHash) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetHashFromBlob(
- /* [in] */ BYTE *pbBlob,
- /* [in] */ DWORD cchBlob,
- /* [out][in] */ unsigned int *piHashAlg,
- /* [length_is][size_is][out] */ BYTE *pbHash,
- /* [in] */ DWORD cchHash,
- /* [out] */ DWORD *pchHash) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetHashFromFile(
- /* [in] */ LPCSTR pszFilePath,
- /* [out][in] */ unsigned int *piHashAlg,
- /* [length_is][size_is][out] */ BYTE *pbHash,
- /* [in] */ DWORD cchHash,
- /* [out] */ DWORD *pchHash) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetHashFromFileW(
- /* [in] */ LPCWSTR pwzFilePath,
- /* [out][in] */ unsigned int *piHashAlg,
- /* [length_is][size_is][out] */ BYTE *pbHash,
- /* [in] */ DWORD cchHash,
- /* [out] */ DWORD *pchHash) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetHashFromHandle(
- /* [in] */ HANDLE hFile,
- /* [out][in] */ unsigned int *piHashAlg,
- /* [length_is][size_is][out] */ BYTE *pbHash,
- /* [in] */ DWORD cchHash,
- /* [out] */ DWORD *pchHash) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameCompareAssemblies(
- /* [in] */ LPCWSTR pwzAssembly1,
- /* [in] */ LPCWSTR pwzAssembly2,
- /* [retval][out] */ DWORD *pdwResult) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameFreeBuffer(
- /* [in] */ BYTE *pbMemory) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameGetBlob(
- /* [in] */ LPCWSTR pwzFilePath,
- /* [length_is][size_is][out][in] */ BYTE *pbBlob,
- /* [out][in] */ DWORD *pcbBlob) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameGetBlobFromImage(
- /* [size_is][in] */ BYTE *pbBase,
- /* [in] */ DWORD dwLength,
- /* [length_is][size_is][out] */ BYTE *pbBlob,
- /* [out][in] */ DWORD *pcbBlob) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameGetPublicKey(
- /* [in] */ LPCWSTR pwzKeyContainer,
- /* [in] */ BYTE *pbKeyBlob,
- /* [in] */ ULONG cbKeyBlob,
- /* [out] */ BYTE **ppbPublicKeyBlob,
- /* [out] */ ULONG *pcbPublicKeyBlob) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameHashSize(
- /* [in] */ ULONG ulHashAlg,
- /* [retval][out] */ DWORD *pcbSize) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameKeyDelete(
- /* [in] */ LPCWSTR pwzKeyContainer) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameKeyGen(
- /* [in] */ LPCWSTR pwzKeyContainer,
- /* [in] */ DWORD dwFlags,
- /* [out] */ BYTE **ppbKeyBlob,
- /* [out] */ ULONG *pcbKeyBlob) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameKeyGenEx(
- /* [in] */ LPCWSTR pwzKeyContainer,
- /* [in] */ DWORD dwFlags,
- /* [in] */ DWORD dwKeySize,
- /* [out] */ BYTE **ppbKeyBlob,
- /* [out] */ ULONG *pcbKeyBlob) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameKeyInstall(
- /* [in] */ LPCWSTR pwzKeyContainer,
- /* [in] */ BYTE *pbKeyBlob,
- /* [in] */ ULONG cbKeyBlob) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameSignatureGeneration(
- /* [in] */ LPCWSTR pwzFilePath,
- /* [in] */ LPCWSTR pwzKeyContainer,
- /* [in] */ BYTE *pbKeyBlob,
- /* [in] */ ULONG cbKeyBlob,
- /* [out] */ BYTE **ppbSignatureBlob,
- /* [out] */ ULONG *pcbSignatureBlob) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameSignatureGenerationEx(
- /* [in] */ LPCWSTR wszFilePath,
- /* [in] */ LPCWSTR wszKeyContainer,
- /* [in] */ BYTE *pbKeyBlob,
- /* [in] */ ULONG cbKeyBlob,
- /* [out] */ BYTE **ppbSignatureBlob,
- /* [out] */ ULONG *pcbSignatureBlob,
- /* [in] */ DWORD dwFlags) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameSignatureSize(
- /* [in] */ BYTE *pbPublicKeyBlob,
- /* [in] */ ULONG cbPublicKeyBlob,
- /* [in] */ DWORD *pcbSize) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameSignatureVerification(
- /* [in] */ LPCWSTR pwzFilePath,
- /* [in] */ DWORD dwInFlags,
- /* [retval][out] */ DWORD *pdwOutFlags) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameSignatureVerificationEx(
- /* [in] */ LPCWSTR pwzFilePath,
- /* [in] */ BOOLEAN fForceVerification,
- /* [retval][out] */ BOOLEAN *pfWasVerified) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameSignatureVerificationFromImage(
- /* [in] */ BYTE *pbBase,
- /* [in] */ DWORD dwLength,
- /* [in] */ DWORD dwInFlags,
- /* [retval][out] */ DWORD *pdwOutFlags) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameTokenFromAssembly(
- /* [in] */ LPCWSTR pwzFilePath,
- /* [out] */ BYTE **ppbStrongNameToken,
- /* [out] */ ULONG *pcbStrongNameToken) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameTokenFromAssemblyEx(
- /* [in] */ LPCWSTR pwzFilePath,
- /* [out] */ BYTE **ppbStrongNameToken,
- /* [out] */ ULONG *pcbStrongNameToken,
- /* [out] */ BYTE **ppbPublicKeyBlob,
- /* [out] */ ULONG *pcbPublicKeyBlob) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameTokenFromPublicKey(
- /* [in] */ BYTE *pbPublicKeyBlob,
- /* [in] */ ULONG cbPublicKeyBlob,
- /* [out] */ BYTE **ppbStrongNameToken,
- /* [out] */ ULONG *pcbStrongNameToken) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct ICLRStrongNameVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- ICLRStrongName * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- ICLRStrongName * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- ICLRStrongName * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetHashFromAssemblyFile )(
- ICLRStrongName * This,
- /* [in] */ LPCSTR pszFilePath,
- /* [out][in] */ unsigned int *piHashAlg,
- /* [length_is][size_is][out] */ BYTE *pbHash,
- /* [in] */ DWORD cchHash,
- /* [out] */ DWORD *pchHash);
-
- HRESULT ( STDMETHODCALLTYPE *GetHashFromAssemblyFileW )(
- ICLRStrongName * This,
- /* [in] */ LPCWSTR pwzFilePath,
- /* [out][in] */ unsigned int *piHashAlg,
- /* [length_is][size_is][out] */ BYTE *pbHash,
- /* [in] */ DWORD cchHash,
- /* [out] */ DWORD *pchHash);
-
- HRESULT ( STDMETHODCALLTYPE *GetHashFromBlob )(
- ICLRStrongName * This,
- /* [in] */ BYTE *pbBlob,
- /* [in] */ DWORD cchBlob,
- /* [out][in] */ unsigned int *piHashAlg,
- /* [length_is][size_is][out] */ BYTE *pbHash,
- /* [in] */ DWORD cchHash,
- /* [out] */ DWORD *pchHash);
-
- HRESULT ( STDMETHODCALLTYPE *GetHashFromFile )(
- ICLRStrongName * This,
- /* [in] */ LPCSTR pszFilePath,
- /* [out][in] */ unsigned int *piHashAlg,
- /* [length_is][size_is][out] */ BYTE *pbHash,
- /* [in] */ DWORD cchHash,
- /* [out] */ DWORD *pchHash);
-
- HRESULT ( STDMETHODCALLTYPE *GetHashFromFileW )(
- ICLRStrongName * This,
- /* [in] */ LPCWSTR pwzFilePath,
- /* [out][in] */ unsigned int *piHashAlg,
- /* [length_is][size_is][out] */ BYTE *pbHash,
- /* [in] */ DWORD cchHash,
- /* [out] */ DWORD *pchHash);
-
- HRESULT ( STDMETHODCALLTYPE *GetHashFromHandle )(
- ICLRStrongName * This,
- /* [in] */ HANDLE hFile,
- /* [out][in] */ unsigned int *piHashAlg,
- /* [length_is][size_is][out] */ BYTE *pbHash,
- /* [in] */ DWORD cchHash,
- /* [out] */ DWORD *pchHash);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameCompareAssemblies )(
- ICLRStrongName * This,
- /* [in] */ LPCWSTR pwzAssembly1,
- /* [in] */ LPCWSTR pwzAssembly2,
- /* [retval][out] */ DWORD *pdwResult);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameFreeBuffer )(
- ICLRStrongName * This,
- /* [in] */ BYTE *pbMemory);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameGetBlob )(
- ICLRStrongName * This,
- /* [in] */ LPCWSTR pwzFilePath,
- /* [length_is][size_is][out][in] */ BYTE *pbBlob,
- /* [out][in] */ DWORD *pcbBlob);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameGetBlobFromImage )(
- ICLRStrongName * This,
- /* [size_is][in] */ BYTE *pbBase,
- /* [in] */ DWORD dwLength,
- /* [length_is][size_is][out] */ BYTE *pbBlob,
- /* [out][in] */ DWORD *pcbBlob);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameGetPublicKey )(
- ICLRStrongName * This,
- /* [in] */ LPCWSTR pwzKeyContainer,
- /* [in] */ BYTE *pbKeyBlob,
- /* [in] */ ULONG cbKeyBlob,
- /* [out] */ BYTE **ppbPublicKeyBlob,
- /* [out] */ ULONG *pcbPublicKeyBlob);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameHashSize )(
- ICLRStrongName * This,
- /* [in] */ ULONG ulHashAlg,
- /* [retval][out] */ DWORD *pcbSize);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameKeyDelete )(
- ICLRStrongName * This,
- /* [in] */ LPCWSTR pwzKeyContainer);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameKeyGen )(
- ICLRStrongName * This,
- /* [in] */ LPCWSTR pwzKeyContainer,
- /* [in] */ DWORD dwFlags,
- /* [out] */ BYTE **ppbKeyBlob,
- /* [out] */ ULONG *pcbKeyBlob);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameKeyGenEx )(
- ICLRStrongName * This,
- /* [in] */ LPCWSTR pwzKeyContainer,
- /* [in] */ DWORD dwFlags,
- /* [in] */ DWORD dwKeySize,
- /* [out] */ BYTE **ppbKeyBlob,
- /* [out] */ ULONG *pcbKeyBlob);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameKeyInstall )(
- ICLRStrongName * This,
- /* [in] */ LPCWSTR pwzKeyContainer,
- /* [in] */ BYTE *pbKeyBlob,
- /* [in] */ ULONG cbKeyBlob);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameSignatureGeneration )(
- ICLRStrongName * This,
- /* [in] */ LPCWSTR pwzFilePath,
- /* [in] */ LPCWSTR pwzKeyContainer,
- /* [in] */ BYTE *pbKeyBlob,
- /* [in] */ ULONG cbKeyBlob,
- /* [out] */ BYTE **ppbSignatureBlob,
- /* [out] */ ULONG *pcbSignatureBlob);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameSignatureGenerationEx )(
- ICLRStrongName * This,
- /* [in] */ LPCWSTR wszFilePath,
- /* [in] */ LPCWSTR wszKeyContainer,
- /* [in] */ BYTE *pbKeyBlob,
- /* [in] */ ULONG cbKeyBlob,
- /* [out] */ BYTE **ppbSignatureBlob,
- /* [out] */ ULONG *pcbSignatureBlob,
- /* [in] */ DWORD dwFlags);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameSignatureSize )(
- ICLRStrongName * This,
- /* [in] */ BYTE *pbPublicKeyBlob,
- /* [in] */ ULONG cbPublicKeyBlob,
- /* [in] */ DWORD *pcbSize);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameSignatureVerification )(
- ICLRStrongName * This,
- /* [in] */ LPCWSTR pwzFilePath,
- /* [in] */ DWORD dwInFlags,
- /* [retval][out] */ DWORD *pdwOutFlags);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameSignatureVerificationEx )(
- ICLRStrongName * This,
- /* [in] */ LPCWSTR pwzFilePath,
- /* [in] */ BOOLEAN fForceVerification,
- /* [retval][out] */ BOOLEAN *pfWasVerified);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameSignatureVerificationFromImage )(
- ICLRStrongName * This,
- /* [in] */ BYTE *pbBase,
- /* [in] */ DWORD dwLength,
- /* [in] */ DWORD dwInFlags,
- /* [retval][out] */ DWORD *pdwOutFlags);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameTokenFromAssembly )(
- ICLRStrongName * This,
- /* [in] */ LPCWSTR pwzFilePath,
- /* [out] */ BYTE **ppbStrongNameToken,
- /* [out] */ ULONG *pcbStrongNameToken);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameTokenFromAssemblyEx )(
- ICLRStrongName * This,
- /* [in] */ LPCWSTR pwzFilePath,
- /* [out] */ BYTE **ppbStrongNameToken,
- /* [out] */ ULONG *pcbStrongNameToken,
- /* [out] */ BYTE **ppbPublicKeyBlob,
- /* [out] */ ULONG *pcbPublicKeyBlob);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameTokenFromPublicKey )(
- ICLRStrongName * This,
- /* [in] */ BYTE *pbPublicKeyBlob,
- /* [in] */ ULONG cbPublicKeyBlob,
- /* [out] */ BYTE **ppbStrongNameToken,
- /* [out] */ ULONG *pcbStrongNameToken);
-
- END_INTERFACE
- } ICLRStrongNameVtbl;
-
- interface ICLRStrongName
- {
- CONST_VTBL struct ICLRStrongNameVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define ICLRStrongName_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define ICLRStrongName_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define ICLRStrongName_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define ICLRStrongName_GetHashFromAssemblyFile(This,pszFilePath,piHashAlg,pbHash,cchHash,pchHash) \
- ( (This)->lpVtbl -> GetHashFromAssemblyFile(This,pszFilePath,piHashAlg,pbHash,cchHash,pchHash) )
-
-#define ICLRStrongName_GetHashFromAssemblyFileW(This,pwzFilePath,piHashAlg,pbHash,cchHash,pchHash) \
- ( (This)->lpVtbl -> GetHashFromAssemblyFileW(This,pwzFilePath,piHashAlg,pbHash,cchHash,pchHash) )
-
-#define ICLRStrongName_GetHashFromBlob(This,pbBlob,cchBlob,piHashAlg,pbHash,cchHash,pchHash) \
- ( (This)->lpVtbl -> GetHashFromBlob(This,pbBlob,cchBlob,piHashAlg,pbHash,cchHash,pchHash) )
-
-#define ICLRStrongName_GetHashFromFile(This,pszFilePath,piHashAlg,pbHash,cchHash,pchHash) \
- ( (This)->lpVtbl -> GetHashFromFile(This,pszFilePath,piHashAlg,pbHash,cchHash,pchHash) )
-
-#define ICLRStrongName_GetHashFromFileW(This,pwzFilePath,piHashAlg,pbHash,cchHash,pchHash) \
- ( (This)->lpVtbl -> GetHashFromFileW(This,pwzFilePath,piHashAlg,pbHash,cchHash,pchHash) )
-
-#define ICLRStrongName_GetHashFromHandle(This,hFile,piHashAlg,pbHash,cchHash,pchHash) \
- ( (This)->lpVtbl -> GetHashFromHandle(This,hFile,piHashAlg,pbHash,cchHash,pchHash) )
-
-#define ICLRStrongName_StrongNameCompareAssemblies(This,pwzAssembly1,pwzAssembly2,pdwResult) \
- ( (This)->lpVtbl -> StrongNameCompareAssemblies(This,pwzAssembly1,pwzAssembly2,pdwResult) )
-
-#define ICLRStrongName_StrongNameFreeBuffer(This,pbMemory) \
- ( (This)->lpVtbl -> StrongNameFreeBuffer(This,pbMemory) )
-
-#define ICLRStrongName_StrongNameGetBlob(This,pwzFilePath,pbBlob,pcbBlob) \
- ( (This)->lpVtbl -> StrongNameGetBlob(This,pwzFilePath,pbBlob,pcbBlob) )
-
-#define ICLRStrongName_StrongNameGetBlobFromImage(This,pbBase,dwLength,pbBlob,pcbBlob) \
- ( (This)->lpVtbl -> StrongNameGetBlobFromImage(This,pbBase,dwLength,pbBlob,pcbBlob) )
-
-#define ICLRStrongName_StrongNameGetPublicKey(This,pwzKeyContainer,pbKeyBlob,cbKeyBlob,ppbPublicKeyBlob,pcbPublicKeyBlob) \
- ( (This)->lpVtbl -> StrongNameGetPublicKey(This,pwzKeyContainer,pbKeyBlob,cbKeyBlob,ppbPublicKeyBlob,pcbPublicKeyBlob) )
-
-#define ICLRStrongName_StrongNameHashSize(This,ulHashAlg,pcbSize) \
- ( (This)->lpVtbl -> StrongNameHashSize(This,ulHashAlg,pcbSize) )
-
-#define ICLRStrongName_StrongNameKeyDelete(This,pwzKeyContainer) \
- ( (This)->lpVtbl -> StrongNameKeyDelete(This,pwzKeyContainer) )
-
-#define ICLRStrongName_StrongNameKeyGen(This,pwzKeyContainer,dwFlags,ppbKeyBlob,pcbKeyBlob) \
- ( (This)->lpVtbl -> StrongNameKeyGen(This,pwzKeyContainer,dwFlags,ppbKeyBlob,pcbKeyBlob) )
-
-#define ICLRStrongName_StrongNameKeyGenEx(This,pwzKeyContainer,dwFlags,dwKeySize,ppbKeyBlob,pcbKeyBlob) \
- ( (This)->lpVtbl -> StrongNameKeyGenEx(This,pwzKeyContainer,dwFlags,dwKeySize,ppbKeyBlob,pcbKeyBlob) )
-
-#define ICLRStrongName_StrongNameKeyInstall(This,pwzKeyContainer,pbKeyBlob,cbKeyBlob) \
- ( (This)->lpVtbl -> StrongNameKeyInstall(This,pwzKeyContainer,pbKeyBlob,cbKeyBlob) )
-
-#define ICLRStrongName_StrongNameSignatureGeneration(This,pwzFilePath,pwzKeyContainer,pbKeyBlob,cbKeyBlob,ppbSignatureBlob,pcbSignatureBlob) \
- ( (This)->lpVtbl -> StrongNameSignatureGeneration(This,pwzFilePath,pwzKeyContainer,pbKeyBlob,cbKeyBlob,ppbSignatureBlob,pcbSignatureBlob) )
-
-#define ICLRStrongName_StrongNameSignatureGenerationEx(This,wszFilePath,wszKeyContainer,pbKeyBlob,cbKeyBlob,ppbSignatureBlob,pcbSignatureBlob,dwFlags) \
- ( (This)->lpVtbl -> StrongNameSignatureGenerationEx(This,wszFilePath,wszKeyContainer,pbKeyBlob,cbKeyBlob,ppbSignatureBlob,pcbSignatureBlob,dwFlags) )
-
-#define ICLRStrongName_StrongNameSignatureSize(This,pbPublicKeyBlob,cbPublicKeyBlob,pcbSize) \
- ( (This)->lpVtbl -> StrongNameSignatureSize(This,pbPublicKeyBlob,cbPublicKeyBlob,pcbSize) )
-
-#define ICLRStrongName_StrongNameSignatureVerification(This,pwzFilePath,dwInFlags,pdwOutFlags) \
- ( (This)->lpVtbl -> StrongNameSignatureVerification(This,pwzFilePath,dwInFlags,pdwOutFlags) )
-
-#define ICLRStrongName_StrongNameSignatureVerificationEx(This,pwzFilePath,fForceVerification,pfWasVerified) \
- ( (This)->lpVtbl -> StrongNameSignatureVerificationEx(This,pwzFilePath,fForceVerification,pfWasVerified) )
-
-#define ICLRStrongName_StrongNameSignatureVerificationFromImage(This,pbBase,dwLength,dwInFlags,pdwOutFlags) \
- ( (This)->lpVtbl -> StrongNameSignatureVerificationFromImage(This,pbBase,dwLength,dwInFlags,pdwOutFlags) )
-
-#define ICLRStrongName_StrongNameTokenFromAssembly(This,pwzFilePath,ppbStrongNameToken,pcbStrongNameToken) \
- ( (This)->lpVtbl -> StrongNameTokenFromAssembly(This,pwzFilePath,ppbStrongNameToken,pcbStrongNameToken) )
-
-#define ICLRStrongName_StrongNameTokenFromAssemblyEx(This,pwzFilePath,ppbStrongNameToken,pcbStrongNameToken,ppbPublicKeyBlob,pcbPublicKeyBlob) \
- ( (This)->lpVtbl -> StrongNameTokenFromAssemblyEx(This,pwzFilePath,ppbStrongNameToken,pcbStrongNameToken,ppbPublicKeyBlob,pcbPublicKeyBlob) )
-
-#define ICLRStrongName_StrongNameTokenFromPublicKey(This,pbPublicKeyBlob,cbPublicKeyBlob,ppbStrongNameToken,pcbStrongNameToken) \
- ( (This)->lpVtbl -> StrongNameTokenFromPublicKey(This,pbPublicKeyBlob,cbPublicKeyBlob,ppbStrongNameToken,pcbStrongNameToken) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __ICLRStrongName_INTERFACE_DEFINED__ */
-
-
-#ifndef __ICLRStrongName2_INTERFACE_DEFINED__
-#define __ICLRStrongName2_INTERFACE_DEFINED__
-
-/* interface ICLRStrongName2 */
-/* [object][local][helpstring][version][uuid] */
-
-
-EXTERN_C const IID IID_ICLRStrongName2;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("C22ED5C5-4B59-4975-90EB-85EA55C0069B")
- ICLRStrongName2 : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE StrongNameGetPublicKeyEx(
- /* [in] */ LPCWSTR pwzKeyContainer,
- /* [in] */ BYTE *pbKeyBlob,
- /* [in] */ ULONG cbKeyBlob,
- /* [out] */ BYTE **ppbPublicKeyBlob,
- /* [out] */ ULONG *pcbPublicKeyBlob,
- /* [in] */ ULONG uHashAlgId,
- /* [in] */ ULONG uReserved) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameSignatureVerificationEx2(
- /* [in] */ LPCWSTR wszFilePath,
- /* [in] */ BOOLEAN fForceVerification,
- /* [in] */ BYTE *pbEcmaPublicKey,
- /* [in] */ DWORD cbEcmaPublicKey,
- /* [out] */ BOOLEAN *pfWasVerified) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct ICLRStrongName2Vtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- ICLRStrongName2 * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- ICLRStrongName2 * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- ICLRStrongName2 * This);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameGetPublicKeyEx )(
- ICLRStrongName2 * This,
- /* [in] */ LPCWSTR pwzKeyContainer,
- /* [in] */ BYTE *pbKeyBlob,
- /* [in] */ ULONG cbKeyBlob,
- /* [out] */ BYTE **ppbPublicKeyBlob,
- /* [out] */ ULONG *pcbPublicKeyBlob,
- /* [in] */ ULONG uHashAlgId,
- /* [in] */ ULONG uReserved);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameSignatureVerificationEx2 )(
- ICLRStrongName2 * This,
- /* [in] */ LPCWSTR wszFilePath,
- /* [in] */ BOOLEAN fForceVerification,
- /* [in] */ BYTE *pbEcmaPublicKey,
- /* [in] */ DWORD cbEcmaPublicKey,
- /* [out] */ BOOLEAN *pfWasVerified);
-
- END_INTERFACE
- } ICLRStrongName2Vtbl;
-
- interface ICLRStrongName2
- {
- CONST_VTBL struct ICLRStrongName2Vtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define ICLRStrongName2_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define ICLRStrongName2_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define ICLRStrongName2_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define ICLRStrongName2_StrongNameGetPublicKeyEx(This,pwzKeyContainer,pbKeyBlob,cbKeyBlob,ppbPublicKeyBlob,pcbPublicKeyBlob,uHashAlgId,uReserved) \
- ( (This)->lpVtbl -> StrongNameGetPublicKeyEx(This,pwzKeyContainer,pbKeyBlob,cbKeyBlob,ppbPublicKeyBlob,pcbPublicKeyBlob,uHashAlgId,uReserved) )
-
-#define ICLRStrongName2_StrongNameSignatureVerificationEx2(This,wszFilePath,fForceVerification,pbEcmaPublicKey,cbEcmaPublicKey,pfWasVerified) \
- ( (This)->lpVtbl -> StrongNameSignatureVerificationEx2(This,wszFilePath,fForceVerification,pbEcmaPublicKey,cbEcmaPublicKey,pfWasVerified) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __ICLRStrongName2_INTERFACE_DEFINED__ */
-
-
-#ifndef __ICLRStrongName3_INTERFACE_DEFINED__
-#define __ICLRStrongName3_INTERFACE_DEFINED__
-
-/* interface ICLRStrongName3 */
-/* [object][local][helpstring][version][uuid] */
-
-
-EXTERN_C const IID IID_ICLRStrongName3;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("22c7089b-bbd3-414a-b698-210f263f1fed")
- ICLRStrongName3 : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE StrongNameDigestGenerate(
- /* [in] */ LPCWSTR wszFilePath,
- /* [out] */ BYTE **ppbDigestBlob,
- /* [out] */ ULONG *pcbDigestBlob,
- /* [in] */ DWORD dwFlags) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameDigestSign(
- /* [in] */ LPCWSTR wszKeyContainer,
- /* [size_is][in] */ BYTE *pbKeyBlob,
- /* [in] */ ULONG cbKeyBlob,
- /* [size_is][in] */ BYTE *pbDigestBlob,
- /* [in] */ ULONG cbDigestBlob,
- /* [in] */ DWORD hashAlgId,
- /* [out] */ BYTE **ppbSignatureBlob,
- /* [out] */ ULONG *pcbSignatureBlob,
- /* [in] */ DWORD dwFlags) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StrongNameDigestEmbed(
- /* [in] */ LPCWSTR wszFilePath,
- /* [size_is][in] */ BYTE *pbSignatureBlob,
- /* [in] */ ULONG cbSignatureBlob) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct ICLRStrongName3Vtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- ICLRStrongName3 * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- ICLRStrongName3 * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- ICLRStrongName3 * This);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameDigestGenerate )(
- ICLRStrongName3 * This,
- /* [in] */ LPCWSTR wszFilePath,
- /* [out] */ BYTE **ppbDigestBlob,
- /* [out] */ ULONG *pcbDigestBlob,
- /* [in] */ DWORD dwFlags);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameDigestSign )(
- ICLRStrongName3 * This,
- /* [in] */ LPCWSTR wszKeyContainer,
- /* [size_is][in] */ BYTE *pbKeyBlob,
- /* [in] */ ULONG cbKeyBlob,
- /* [size_is][in] */ BYTE *pbDigestBlob,
- /* [in] */ ULONG cbDigestBlob,
- /* [in] */ DWORD hashAlgId,
- /* [out] */ BYTE **ppbSignatureBlob,
- /* [out] */ ULONG *pcbSignatureBlob,
- /* [in] */ DWORD dwFlags);
-
- HRESULT ( STDMETHODCALLTYPE *StrongNameDigestEmbed )(
- ICLRStrongName3 * This,
- /* [in] */ LPCWSTR wszFilePath,
- /* [size_is][in] */ BYTE *pbSignatureBlob,
- /* [in] */ ULONG cbSignatureBlob);
-
- END_INTERFACE
- } ICLRStrongName3Vtbl;
-
- interface ICLRStrongName3
- {
- CONST_VTBL struct ICLRStrongName3Vtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define ICLRStrongName3_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define ICLRStrongName3_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define ICLRStrongName3_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define ICLRStrongName3_StrongNameDigestGenerate(This,wszFilePath,ppbDigestBlob,pcbDigestBlob,dwFlags) \
- ( (This)->lpVtbl -> StrongNameDigestGenerate(This,wszFilePath,ppbDigestBlob,pcbDigestBlob,dwFlags) )
-
-#define ICLRStrongName3_StrongNameDigestSign(This,wszKeyContainer,pbKeyBlob,cbKeyBlob,pbDigestBlob,cbDigestBlob,hashAlgId,ppbSignatureBlob,pcbSignatureBlob,dwFlags) \
- ( (This)->lpVtbl -> StrongNameDigestSign(This,wszKeyContainer,pbKeyBlob,cbKeyBlob,pbDigestBlob,cbDigestBlob,hashAlgId,ppbSignatureBlob,pcbSignatureBlob,dwFlags) )
-
-#define ICLRStrongName3_StrongNameDigestEmbed(This,wszFilePath,pbSignatureBlob,cbSignatureBlob) \
- ( (This)->lpVtbl -> StrongNameDigestEmbed(This,wszFilePath,pbSignatureBlob,cbSignatureBlob) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __ICLRStrongName3_INTERFACE_DEFINED__ */
-
-
-
-#ifndef __CLRMetaHost_LIBRARY_DEFINED__
-#define __CLRMetaHost_LIBRARY_DEFINED__
-
-/* library CLRMetaHost */
-/* [version][uuid] */
-
-
-
-
-
-
-
-
-
-EXTERN_C const IID LIBID_CLRMetaHost;
-#endif /* __CLRMetaHost_LIBRARY_DEFINED__ */
-
-/* interface __MIDL_itf_metahost_0000_0011 */
-/* [local] */
-
-#endif // WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-
-
-extern RPC_IF_HANDLE __MIDL_itf_metahost_0000_0011_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_metahost_0000_0011_v0_0_s_ifspec;
-
/* Additional Prototypes for ALL interfaces */
/* end of Additional Prototypes */
diff --git a/src/pal/prebuilt/inc/mscoree.h b/src/pal/prebuilt/inc/mscoree.h
index 3bd961dac4..42a97c0096 100644
--- a/src/pal/prebuilt/inc/mscoree.h
+++ b/src/pal/prebuilt/inc/mscoree.h
@@ -22,7 +22,7 @@
#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
-#endif // __RPCNDR_H_VERSION__
+#endif /* __RPCNDR_H_VERSION__ */
#ifndef COM_NO_WINDOWS_H
#include "windows.h"
@@ -38,69 +38,6 @@
/* Forward Declarations */
-#ifndef __IDebuggerThreadControl_FWD_DEFINED__
-#define __IDebuggerThreadControl_FWD_DEFINED__
-typedef interface IDebuggerThreadControl IDebuggerThreadControl;
-
-#endif /* __IDebuggerThreadControl_FWD_DEFINED__ */
-
-
-#ifndef __IDebuggerInfo_FWD_DEFINED__
-#define __IDebuggerInfo_FWD_DEFINED__
-typedef interface IDebuggerInfo IDebuggerInfo;
-
-#endif /* __IDebuggerInfo_FWD_DEFINED__ */
-
-
-#ifndef __ICLRErrorReportingManager_FWD_DEFINED__
-#define __ICLRErrorReportingManager_FWD_DEFINED__
-typedef interface ICLRErrorReportingManager ICLRErrorReportingManager;
-
-#endif /* __ICLRErrorReportingManager_FWD_DEFINED__ */
-
-
-#ifndef __ICLRErrorReportingManager2_FWD_DEFINED__
-#define __ICLRErrorReportingManager2_FWD_DEFINED__
-typedef interface ICLRErrorReportingManager2 ICLRErrorReportingManager2;
-
-#endif /* __ICLRErrorReportingManager2_FWD_DEFINED__ */
-
-
-#ifndef __ICLRPolicyManager_FWD_DEFINED__
-#define __ICLRPolicyManager_FWD_DEFINED__
-typedef interface ICLRPolicyManager ICLRPolicyManager;
-
-#endif /* __ICLRPolicyManager_FWD_DEFINED__ */
-
-
-#ifndef __ICLRGCManager_FWD_DEFINED__
-#define __ICLRGCManager_FWD_DEFINED__
-typedef interface ICLRGCManager ICLRGCManager;
-
-#endif /* __ICLRGCManager_FWD_DEFINED__ */
-
-
-#ifndef __ICLRGCManager2_FWD_DEFINED__
-#define __ICLRGCManager2_FWD_DEFINED__
-typedef interface ICLRGCManager2 ICLRGCManager2;
-
-#endif /* __ICLRGCManager2_FWD_DEFINED__ */
-
-
-#ifndef __IHostControl_FWD_DEFINED__
-#define __IHostControl_FWD_DEFINED__
-typedef interface IHostControl IHostControl;
-
-#endif /* __IHostControl_FWD_DEFINED__ */
-
-
-#ifndef __ICLRControl_FWD_DEFINED__
-#define __ICLRControl_FWD_DEFINED__
-typedef interface ICLRControl ICLRControl;
-
-#endif /* __ICLRControl_FWD_DEFINED__ */
-
-
#ifndef __ICLRRuntimeHost_FWD_DEFINED__
#define __ICLRRuntimeHost_FWD_DEFINED__
typedef interface ICLRRuntimeHost ICLRRuntimeHost;
@@ -112,108 +49,18 @@ typedef interface ICLRRuntimeHost ICLRRuntimeHost;
#define __ICLRRuntimeHost2_FWD_DEFINED__
typedef interface ICLRRuntimeHost2 ICLRRuntimeHost2;
-#endif /* __ICLRRuntimeHost4_FWD_DEFINED__ */
+#endif /* __ICLRRuntimeHost2_FWD_DEFINED__ */
+
#ifndef __ICLRRuntimeHost4_FWD_DEFINED__
#define __ICLRRuntimeHost4_FWD_DEFINED__
typedef interface ICLRRuntimeHost4 ICLRRuntimeHost4;
-#endif /* __ICLRRuntimeHost4_FWD_DEFINED__ */
-
-
-#ifndef __IHostNetCFDebugControlManager_FWD_DEFINED__
-#define __IHostNetCFDebugControlManager_FWD_DEFINED__
-typedef interface IHostNetCFDebugControlManager IHostNetCFDebugControlManager;
-
-#endif /* __IHostNetCFDebugControlManager_FWD_DEFINED__ */
-
-
-#ifndef __ITypeName_FWD_DEFINED__
-#define __ITypeName_FWD_DEFINED__
-typedef interface ITypeName ITypeName;
-
-#endif /* __ITypeName_FWD_DEFINED__ */
-
-
-#ifndef __ITypeNameBuilder_FWD_DEFINED__
-#define __ITypeNameBuilder_FWD_DEFINED__
-typedef interface ITypeNameBuilder ITypeNameBuilder;
-
-#endif /* __ITypeNameBuilder_FWD_DEFINED__ */
-
-
-#ifndef __ITypeNameFactory_FWD_DEFINED__
-#define __ITypeNameFactory_FWD_DEFINED__
-typedef interface ITypeNameFactory ITypeNameFactory;
-
-#endif /* __ITypeNameFactory_FWD_DEFINED__ */
-
-
-#ifndef __IManagedObject_FWD_DEFINED__
-#define __IManagedObject_FWD_DEFINED__
-typedef interface IManagedObject IManagedObject;
-
-#endif /* __IManagedObject_FWD_DEFINED__ */
-
-
-#ifndef __ComCallUnmarshal_FWD_DEFINED__
-#define __ComCallUnmarshal_FWD_DEFINED__
-
-#ifdef __cplusplus
-typedef class ComCallUnmarshal ComCallUnmarshal;
-#else
-typedef struct ComCallUnmarshal ComCallUnmarshal;
-#endif /* __cplusplus */
-
-#endif /* __ComCallUnmarshal_FWD_DEFINED__ */
-
-
-#ifndef __ComCallUnmarshalV4_FWD_DEFINED__
-#define __ComCallUnmarshalV4_FWD_DEFINED__
-
-#ifdef __cplusplus
-typedef class ComCallUnmarshalV4 ComCallUnmarshalV4;
-#else
-typedef struct ComCallUnmarshalV4 ComCallUnmarshalV4;
-#endif /* __cplusplus */
-
-#endif /* __ComCallUnmarshalV4_FWD_DEFINED__ */
-
-
-#ifndef __CLRRuntimeHost_FWD_DEFINED__
-#define __CLRRuntimeHost_FWD_DEFINED__
-
-#ifdef __cplusplus
-typedef class CLRRuntimeHost CLRRuntimeHost;
-#else
-typedef struct CLRRuntimeHost CLRRuntimeHost;
-#endif /* __cplusplus */
-
-#endif /* __CLRRuntimeHost_FWD_DEFINED__ */
-
-
-#ifndef __TypeNameFactory_FWD_DEFINED__
-#define __TypeNameFactory_FWD_DEFINED__
-
-#ifdef __cplusplus
-typedef class TypeNameFactory TypeNameFactory;
-#else
-typedef struct TypeNameFactory TypeNameFactory;
-#endif /* __cplusplus */
-
-#endif /* __TypeNameFactory_FWD_DEFINED__ */
-
-
-#ifndef __ICLRAppDomainResourceMonitor_FWD_DEFINED__
-#define __ICLRAppDomainResourceMonitor_FWD_DEFINED__
-typedef interface ICLRAppDomainResourceMonitor ICLRAppDomainResourceMonitor;
-
-#endif /* __ICLRAppDomainResourceMonitor_FWD_DEFINED__ */
+#endif /* __ICLRRuntimeHost4_FWD_DEFINED__ */
/* header files for imported files */
#include "unknwn.h"
-#include "gchost.h"
#ifdef __cplusplus
extern "C"{
@@ -228,54 +75,20 @@ extern "C"{
struct IActivationFactory;
-EXTERN_GUID(CLSID_TypeNameFactory, 0xB81FF171, 0x20F3, 0x11d2, 0x8d, 0xcc, 0x00, 0xa0, 0xc9, 0xb0, 0x05, 0x25);
-EXTERN_GUID(CLSID_ComCallUnmarshal, 0x3F281000,0xE95A,0x11d2,0x88,0x6B,0x00,0xC0,0x4F,0x86,0x9F,0x04);
+struct IHostControl;
+
+struct ICLRControl;
+
EXTERN_GUID(CLSID_ComCallUnmarshalV4, 0x45fb4600,0xe6e8,0x4928,0xb2,0x5e,0x50,0x47,0x6f,0xf7,0x94,0x25);
-EXTERN_GUID(IID_IManagedObject, 0xc3fcc19e, 0xa970, 0x11d2, 0x8b, 0x5a, 0x00, 0xa0, 0xc9, 0xb7, 0xc9, 0xc4);
-EXTERN_GUID(IID_ICLRAppDomainResourceMonitor, 0XC62DE18C, 0X2E23, 0X4AEA, 0X84, 0X23, 0XB4, 0X0C, 0X1F, 0XC5, 0X9E, 0XAE);
-EXTERN_GUID(IID_ICLRPolicyManager, 0x7D290010, 0xD781, 0x45da, 0xA6, 0xF8, 0xAA, 0x5D, 0x71, 0x1A, 0x73, 0x0E);
-EXTERN_GUID(IID_ICLRGCManager, 0x54D9007E, 0xA8E2, 0x4885, 0xB7, 0xBF, 0xF9, 0x98, 0xDE, 0xEE, 0x4F, 0x2A);
-EXTERN_GUID(IID_ICLRGCManager2, 0x0603B793, 0xA97A, 0x4712, 0x9C, 0xB4, 0x0C, 0xD1, 0xC7, 0x4C, 0x0F, 0x7C);
-EXTERN_GUID(IID_ICLRErrorReportingManager, 0x980d2f1a, 0xbf79, 0x4c08, 0x81, 0x2a, 0xbb, 0x97, 0x78, 0x92, 0x8f, 0x78);
-EXTERN_GUID(IID_ICLRErrorReportingManager2, 0xc68f63b1, 0x4d8b, 0x4e0b, 0x95, 0x64, 0x9d, 0x2e, 0xfe, 0x2f, 0xa1, 0x8c);
EXTERN_GUID(IID_ICLRRuntimeHost, 0x90F1A06C, 0x7712, 0x4762, 0x86, 0xB5, 0x7A, 0x5E, 0xBA, 0x6B, 0xDB, 0x02);
EXTERN_GUID(IID_ICLRRuntimeHost2, 0x712AB73F, 0x2C22, 0x4807, 0xAD, 0x7E, 0xF5, 0x01, 0xD7, 0xb7, 0x2C, 0x2D);
EXTERN_GUID(IID_ICLRRuntimeHost4, 0x64F6D366, 0xD7C2, 0x4F1F, 0xB4, 0xB2, 0xE8, 0x16, 0x0C, 0xAC, 0x43, 0xAF);
-EXTERN_GUID(IID_ITypeName, 0xB81FF171, 0x20F3, 0x11d2, 0x8d, 0xcc, 0x00, 0xa0, 0xc9, 0xb0, 0x05, 0x22);
-EXTERN_GUID(IID_ITypeNameBuilder, 0xB81FF171, 0x20F3, 0x11d2, 0x8d, 0xcc, 0x00, 0xa0, 0xc9, 0xb0, 0x05, 0x23);
-EXTERN_GUID(IID_ITypeNameFactory, 0xB81FF171, 0x20F3, 0x11d2, 0x8d, 0xcc, 0x00, 0xa0, 0xc9, 0xb0, 0x05, 0x21);
-DEPRECATED_CLR_STDAPI GetCORSystemDirectory(_Out_writes_to_(cchBuffer, *dwLength) LPWSTR pbuffer, DWORD cchBuffer, DWORD* dwLength);
-DEPRECATED_CLR_STDAPI GetCORVersion(_Out_writes_to_(cchBuffer, *dwLength) LPWSTR pbBuffer, DWORD cchBuffer, DWORD* dwLength);
-DEPRECATED_CLR_STDAPI GetFileVersion(LPCWSTR szFilename, _Out_writes_to_opt_(cchBuffer, *dwLength) LPWSTR szBuffer, DWORD cchBuffer, DWORD* dwLength);
-DEPRECATED_CLR_STDAPI GetCORRequiredVersion(_Out_writes_to_(cchBuffer, *dwLength) LPWSTR pbuffer, DWORD cchBuffer, DWORD* dwLength);
-DEPRECATED_CLR_STDAPI GetRequestedRuntimeInfo(LPCWSTR pExe, LPCWSTR pwszVersion, LPCWSTR pConfigurationFile, DWORD startupFlags, DWORD runtimeInfoFlags, _Out_writes_opt_(dwDirectory) LPWSTR pDirectory, DWORD dwDirectory, _Out_opt_ DWORD *dwDirectoryLength, _Out_writes_opt_(cchBuffer) LPWSTR pVersion, DWORD cchBuffer, _Out_opt_ DWORD* dwlength);
-DEPRECATED_CLR_STDAPI GetRequestedRuntimeVersion(_In_ LPWSTR pExe, _Out_writes_to_(cchBuffer, *dwLength) LPWSTR pVersion, DWORD cchBuffer, _Out_ DWORD* dwLength);
-DEPRECATED_CLR_STDAPI CorBindToRuntimeHost(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, LPCWSTR pwszHostConfigFile, VOID* pReserved, DWORD startupFlags, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);
-DEPRECATED_CLR_STDAPI CorBindToRuntimeEx(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, DWORD startupFlags, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);
-DEPRECATED_CLR_STDAPI CorBindToRuntimeByCfg(IStream* pCfgStream, DWORD reserved, DWORD startupFlags, REFCLSID rclsid,REFIID riid, LPVOID FAR* ppv);
-DEPRECATED_CLR_STDAPI CorBindToRuntime(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);
-DEPRECATED_CLR_STDAPI CorBindToCurrentRuntime(LPCWSTR pwszFileName, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);
-DEPRECATED_CLR_STDAPI RunDll32ShimW(HWND hwnd, HINSTANCE hinst, LPCWSTR lpszCmdLine, int nCmdShow);
-DEPRECATED_CLR_STDAPI LoadLibraryShim(LPCWSTR szDllName, LPCWSTR szVersion, LPVOID pvReserved, HMODULE *phModDll);
-DEPRECATED_CLR_STDAPI CallFunctionShim(LPCWSTR szDllName, LPCSTR szFunctionName, LPVOID lpvArgument1, LPVOID lpvArgument2, LPCWSTR szVersion, LPVOID pvReserved);
-DEPRECATED_CLR_STDAPI GetRealProcAddress(LPCSTR pwszProcName, VOID** ppv);
-DECLARE_DEPRECATED void STDMETHODCALLTYPE CorExitProcess(int exitCode);
-DEPRECATED_CLR_STDAPI LoadStringRC(UINT iResouceID, _Out_writes_z_(iMax) LPWSTR szBuffer, int iMax, int bQuiet);
typedef HRESULT (STDAPICALLTYPE *FnGetCLRRuntimeHost)(REFIID riid, IUnknown **pUnk);
-typedef /* [public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0000_0001
- {
- HOST_TYPE_DEFAULT = 0,
- HOST_TYPE_APPLAUNCH = 0x1,
- HOST_TYPE_CORFLAG = 0x2
- } HOST_TYPE;
-
-STDAPI CorLaunchApplication(HOST_TYPE dwClickOnceHost, LPCWSTR pwzAppFullName, DWORD dwManifestPaths, LPCWSTR* ppwzManifestPaths, DWORD dwActivationData, LPCWSTR* ppwzActivationData, LPPROCESS_INFORMATION lpProcessInformation);
typedef HRESULT ( __stdcall *FExecuteInAppDomainCallback )(
void *cookie);
typedef /* [public][public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0000_0002
+enum __MIDL___MIDL_itf_mscoree_0000_0000_0001
{
STARTUP_CONCURRENT_GC = 0x1,
STARTUP_LOADER_OPTIMIZATION_MASK = ( 0x3 << 1 ) ,
@@ -295,31 +108,11 @@ enum __MIDL___MIDL_itf_mscoree_0000_0000_0002
STARTUP_ARM = 0x400000,
STARTUP_SINGLE_APPDOMAIN = 0x800000,
STARTUP_APPX_APP_MODEL = 0x1000000,
- STARTUP_DISABLE_RANDOMIZED_STRING_HASHING = 0x2000000 // not supported
+ STARTUP_DISABLE_RANDOMIZED_STRING_HASHING = 0x2000000
} STARTUP_FLAGS;
typedef /* [public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0000_0003
- {
- CLSID_RESOLUTION_DEFAULT = 0,
- CLSID_RESOLUTION_REGISTERED = 0x1
- } CLSID_RESOLUTION_FLAGS;
-
-typedef /* [public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0000_0004
- {
- RUNTIME_INFO_UPGRADE_VERSION = 0x1,
- RUNTIME_INFO_REQUEST_IA64 = 0x2,
- RUNTIME_INFO_REQUEST_AMD64 = 0x4,
- RUNTIME_INFO_REQUEST_X86 = 0x8,
- RUNTIME_INFO_DONT_RETURN_DIRECTORY = 0x10,
- RUNTIME_INFO_DONT_RETURN_VERSION = 0x20,
- RUNTIME_INFO_DONT_SHOW_ERROR_DIALOG = 0x40,
- RUNTIME_INFO_IGNORE_ERROR_MODE = 0x1000
- } RUNTIME_INFO_FLAGS;
-
-typedef /* [public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0000_0005
+enum __MIDL___MIDL_itf_mscoree_0000_0000_0002
{
APPDOMAIN_SECURITY_DEFAULT = 0,
APPDOMAIN_SECURITY_SANDBOXED = 0x1,
@@ -327,237 +120,19 @@ enum __MIDL___MIDL_itf_mscoree_0000_0000_0005
APPDOMAIN_IGNORE_UNHANDLED_EXCEPTIONS = 0x4,
APPDOMAIN_FORCE_TRIVIAL_WAIT_OPERATIONS = 0x8,
APPDOMAIN_ENABLE_PINVOKE_AND_CLASSIC_COMINTEROP = 0x10,
- APPDOMAIN_SET_TEST_KEY = 0x20,
APPDOMAIN_ENABLE_PLATFORM_SPECIFIC_APPS = 0x40,
APPDOMAIN_ENABLE_ASSEMBLY_LOADFILE = 0x80,
APPDOMAIN_DISABLE_TRANSPARENCY_ENFORCEMENT = 0x100
} APPDOMAIN_SECURITY_FLAGS;
-STDAPI GetRequestedRuntimeVersionForCLSID(REFCLSID rclsid, _Out_writes_opt_(cchBuffer) LPWSTR pVersion, DWORD cchBuffer, _Out_opt_ DWORD* dwLength, CLSID_RESOLUTION_FLAGS dwResolutionFlags);
-EXTERN_GUID(IID_IDebuggerThreadControl, 0x23d86786, 0x0bb5, 0x4774, 0x8f, 0xb5, 0xe3, 0x52, 0x2a, 0xdd, 0x62, 0x46);
-
-
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0000_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0000_v0_0_s_ifspec;
-
-#ifndef __IDebuggerThreadControl_INTERFACE_DEFINED__
-#define __IDebuggerThreadControl_INTERFACE_DEFINED__
-
-/* interface IDebuggerThreadControl */
-/* [object][local][unique][helpstring][version][uuid] */
-
-
-EXTERN_C const IID IID_IDebuggerThreadControl;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("23D86786-0BB5-4774-8FB5-E3522ADD6246")
- IDebuggerThreadControl : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE ThreadIsBlockingForDebugger( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE ReleaseAllRuntimeThreads( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE StartBlockingForDebugger(
- DWORD dwUnused) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IDebuggerThreadControlVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDebuggerThreadControl * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDebuggerThreadControl * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDebuggerThreadControl * This);
-
- HRESULT ( STDMETHODCALLTYPE *ThreadIsBlockingForDebugger )(
- IDebuggerThreadControl * This);
-
- HRESULT ( STDMETHODCALLTYPE *ReleaseAllRuntimeThreads )(
- IDebuggerThreadControl * This);
-
- HRESULT ( STDMETHODCALLTYPE *StartBlockingForDebugger )(
- IDebuggerThreadControl * This,
- DWORD dwUnused);
-
- END_INTERFACE
- } IDebuggerThreadControlVtbl;
-
- interface IDebuggerThreadControl
- {
- CONST_VTBL struct IDebuggerThreadControlVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDebuggerThreadControl_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDebuggerThreadControl_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDebuggerThreadControl_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDebuggerThreadControl_ThreadIsBlockingForDebugger(This) \
- ( (This)->lpVtbl -> ThreadIsBlockingForDebugger(This) )
-
-#define IDebuggerThreadControl_ReleaseAllRuntimeThreads(This) \
- ( (This)->lpVtbl -> ReleaseAllRuntimeThreads(This) )
-
-#define IDebuggerThreadControl_StartBlockingForDebugger(This,dwUnused) \
- ( (This)->lpVtbl -> StartBlockingForDebugger(This,dwUnused) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDebuggerThreadControl_INTERFACE_DEFINED__ */
-
-
-/* interface __MIDL_itf_mscoree_0000_0001 */
-/* [local] */
-
-EXTERN_GUID(IID_IDebuggerInfo, 0xbf24142d, 0xa47d, 0x4d24, 0xa6, 0x6d, 0x8c, 0x21, 0x41, 0x94, 0x4e, 0x44);
-
-
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0001_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0001_v0_0_s_ifspec;
-
-#ifndef __IDebuggerInfo_INTERFACE_DEFINED__
-#define __IDebuggerInfo_INTERFACE_DEFINED__
-
-/* interface IDebuggerInfo */
-/* [object][local][unique][helpstring][version][uuid] */
-
-
-EXTERN_C const IID IID_IDebuggerInfo;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("BF24142D-A47D-4d24-A66D-8C2141944E44")
- IDebuggerInfo : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE IsDebuggerAttached(
- /* [out] */ BOOL *pbAttached) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IDebuggerInfoVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IDebuggerInfo * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IDebuggerInfo * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IDebuggerInfo * This);
-
- HRESULT ( STDMETHODCALLTYPE *IsDebuggerAttached )(
- IDebuggerInfo * This,
- /* [out] */ BOOL *pbAttached);
-
- END_INTERFACE
- } IDebuggerInfoVtbl;
-
- interface IDebuggerInfo
- {
- CONST_VTBL struct IDebuggerInfoVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IDebuggerInfo_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IDebuggerInfo_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IDebuggerInfo_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IDebuggerInfo_IsDebuggerAttached(This,pbAttached) \
- ( (This)->lpVtbl -> IsDebuggerAttached(This,pbAttached) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IDebuggerInfo_INTERFACE_DEFINED__ */
-
-
-/* interface __MIDL_itf_mscoree_0000_0002 */
-/* [local] */
-
-typedef void *HDOMAINENUM;
-
typedef /* [public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0002_0001
- {
- eMemoryAvailableLow = 1,
- eMemoryAvailableNeutral = 2,
- eMemoryAvailableHigh = 3
- } EMemoryAvailable;
-
-typedef /* [public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0002_0002
- {
- eTaskCritical = 0,
- eAppDomainCritical = 1,
- eProcessCritical = 2
- } EMemoryCriticalLevel;
-
-typedef /* [public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0002_0003
+enum __MIDL___MIDL_itf_mscoree_0000_0000_0003
{
WAIT_MSGPUMP = 0x1,
WAIT_ALERTABLE = 0x2,
WAIT_NOTINDEADLOCK = 0x4
} WAIT_OPTION;
-typedef UINT64 TASKID;
-
-typedef DWORD CONNID;
-
typedef
enum ETaskType
{
@@ -575,15 +150,7 @@ enum ETaskType
} ETaskType;
typedef /* [public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0002_0004
- {
- eSymbolReadingNever = 0,
- eSymbolReadingAlways = 1,
- eSymbolReadingFullTrustOnly = 2
- } ESymbolReadingPolicy;
-
-typedef /* [public][public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0002_0005
+enum __MIDL___MIDL_itf_mscoree_0000_0000_0004
{
DUMP_FLAVOR_Mini = 0,
DUMP_FLAVOR_CriticalCLRState = 1,
@@ -591,27 +158,12 @@ enum __MIDL___MIDL_itf_mscoree_0000_0002_0005
DUMP_FLAVOR_Default = DUMP_FLAVOR_Mini
} ECustomDumpFlavor;
-typedef /* [public][public][public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0002_0006
- {
- DUMP_ITEM_None = 0
- } ECustomDumpItemKind;
-
-typedef /* [public][public] */ struct __MIDL___MIDL_itf_mscoree_0000_0002_0007
- {
- ECustomDumpItemKind itemKind;
- union
- {
- UINT_PTR pReserved;
- } ;
- } CustomDumpItem;
-
#define BucketParamsCount ( 10 )
#define BucketParamLength ( 255 )
typedef /* [public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0002_0009
+enum __MIDL___MIDL_itf_mscoree_0000_0000_0005
{
Parameter1 = 0,
Parameter2 = ( Parameter1 + 1 ) ,
@@ -632,253 +184,8 @@ typedef struct _BucketParameters
WCHAR pszParams[ 10 ][ 255 ];
} BucketParameters;
-
-
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0002_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0002_v0_0_s_ifspec;
-
-#ifndef __ICLRErrorReportingManager_INTERFACE_DEFINED__
-#define __ICLRErrorReportingManager_INTERFACE_DEFINED__
-
-/* interface ICLRErrorReportingManager */
-/* [object][local][unique][helpstring][version][uuid] */
-
-
-EXTERN_C const IID IID_ICLRErrorReportingManager;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("980D2F1A-BF79-4c08-812A-BB9778928F78")
- ICLRErrorReportingManager : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetBucketParametersForCurrentException(
- /* [out] */ BucketParameters *pParams) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE BeginCustomDump(
- /* [in] */ ECustomDumpFlavor dwFlavor,
- /* [in] */ DWORD dwNumItems,
- /* [length_is][size_is][in] */ CustomDumpItem *items,
- DWORD dwReserved) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE EndCustomDump( void) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct ICLRErrorReportingManagerVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- ICLRErrorReportingManager * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- ICLRErrorReportingManager * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- ICLRErrorReportingManager * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetBucketParametersForCurrentException )(
- ICLRErrorReportingManager * This,
- /* [out] */ BucketParameters *pParams);
-
- HRESULT ( STDMETHODCALLTYPE *BeginCustomDump )(
- ICLRErrorReportingManager * This,
- /* [in] */ ECustomDumpFlavor dwFlavor,
- /* [in] */ DWORD dwNumItems,
- /* [length_is][size_is][in] */ CustomDumpItem *items,
- DWORD dwReserved);
-
- HRESULT ( STDMETHODCALLTYPE *EndCustomDump )(
- ICLRErrorReportingManager * This);
-
- END_INTERFACE
- } ICLRErrorReportingManagerVtbl;
-
- interface ICLRErrorReportingManager
- {
- CONST_VTBL struct ICLRErrorReportingManagerVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define ICLRErrorReportingManager_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define ICLRErrorReportingManager_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define ICLRErrorReportingManager_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define ICLRErrorReportingManager_GetBucketParametersForCurrentException(This,pParams) \
- ( (This)->lpVtbl -> GetBucketParametersForCurrentException(This,pParams) )
-
-#define ICLRErrorReportingManager_BeginCustomDump(This,dwFlavor,dwNumItems,items,dwReserved) \
- ( (This)->lpVtbl -> BeginCustomDump(This,dwFlavor,dwNumItems,items,dwReserved) )
-
-#define ICLRErrorReportingManager_EndCustomDump(This) \
- ( (This)->lpVtbl -> EndCustomDump(This) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __ICLRErrorReportingManager_INTERFACE_DEFINED__ */
-
-
-/* interface __MIDL_itf_mscoree_0000_0003 */
-/* [local] */
-
-typedef /* [public][public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0003_0001
- {
- ApplicationID = 0x1,
- InstanceID = 0x2
- } ApplicationDataKey;
-
-
-
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0003_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0003_v0_0_s_ifspec;
-
-#ifndef __ICLRErrorReportingManager2_INTERFACE_DEFINED__
-#define __ICLRErrorReportingManager2_INTERFACE_DEFINED__
-
-/* interface ICLRErrorReportingManager2 */
-/* [object][local][unique][helpstring][version][uuid] */
-
-
-EXTERN_C const IID IID_ICLRErrorReportingManager2;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("C68F63B1-4D8B-4E0B-9564-9D2EFE2FA18C")
- ICLRErrorReportingManager2 : public ICLRErrorReportingManager
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE SetApplicationData(
- /* [in] */ ApplicationDataKey key,
- /* [in] */ const WCHAR *pValue) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE SetBucketParametersForUnhandledException(
- /* [in] */ const BucketParameters *pBucketParams,
- /* [out] */ DWORD *pCountParams) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct ICLRErrorReportingManager2Vtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- ICLRErrorReportingManager2 * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- ICLRErrorReportingManager2 * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- ICLRErrorReportingManager2 * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetBucketParametersForCurrentException )(
- ICLRErrorReportingManager2 * This,
- /* [out] */ BucketParameters *pParams);
-
- HRESULT ( STDMETHODCALLTYPE *BeginCustomDump )(
- ICLRErrorReportingManager2 * This,
- /* [in] */ ECustomDumpFlavor dwFlavor,
- /* [in] */ DWORD dwNumItems,
- /* [length_is][size_is][in] */ CustomDumpItem *items,
- DWORD dwReserved);
-
- HRESULT ( STDMETHODCALLTYPE *EndCustomDump )(
- ICLRErrorReportingManager2 * This);
-
- HRESULT ( STDMETHODCALLTYPE *SetApplicationData )(
- ICLRErrorReportingManager2 * This,
- /* [in] */ ApplicationDataKey key,
- /* [in] */ const WCHAR *pValue);
-
- HRESULT ( STDMETHODCALLTYPE *SetBucketParametersForUnhandledException )(
- ICLRErrorReportingManager2 * This,
- /* [in] */ const BucketParameters *pBucketParams,
- /* [out] */ DWORD *pCountParams);
-
- END_INTERFACE
- } ICLRErrorReportingManager2Vtbl;
-
- interface ICLRErrorReportingManager2
- {
- CONST_VTBL struct ICLRErrorReportingManager2Vtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define ICLRErrorReportingManager2_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define ICLRErrorReportingManager2_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define ICLRErrorReportingManager2_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define ICLRErrorReportingManager2_GetBucketParametersForCurrentException(This,pParams) \
- ( (This)->lpVtbl -> GetBucketParametersForCurrentException(This,pParams) )
-
-#define ICLRErrorReportingManager2_BeginCustomDump(This,dwFlavor,dwNumItems,items,dwReserved) \
- ( (This)->lpVtbl -> BeginCustomDump(This,dwFlavor,dwNumItems,items,dwReserved) )
-
-#define ICLRErrorReportingManager2_EndCustomDump(This) \
- ( (This)->lpVtbl -> EndCustomDump(This) )
-
-
-#define ICLRErrorReportingManager2_SetApplicationData(This,key,pValue) \
- ( (This)->lpVtbl -> SetApplicationData(This,key,pValue) )
-
-#define ICLRErrorReportingManager2_SetBucketParametersForUnhandledException(This,pBucketParams,pCountParams) \
- ( (This)->lpVtbl -> SetBucketParametersForUnhandledException(This,pBucketParams,pCountParams) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __ICLRErrorReportingManager2_INTERFACE_DEFINED__ */
-
-
-/* interface __MIDL_itf_mscoree_0000_0004 */
-/* [local] */
-
-typedef /* [public][public][public][public][public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0004_0001
+typedef /* [public] */
+enum __MIDL___MIDL_itf_mscoree_0000_0000_0006
{
OPR_ThreadAbort = 0,
OPR_ThreadRudeAbortInNonCriticalRegion = ( OPR_ThreadAbort + 1 ) ,
@@ -890,8 +197,8 @@ enum __MIDL___MIDL_itf_mscoree_0000_0004_0001
MaxClrOperation = ( OPR_FinalizerRun + 1 )
} EClrOperation;
-typedef /* [public][public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0004_0002
+typedef /* [public] */
+enum __MIDL___MIDL_itf_mscoree_0000_0000_0007
{
FAIL_NonCriticalResource = 0,
FAIL_CriticalResource = ( FAIL_NonCriticalResource + 1 ) ,
@@ -903,15 +210,15 @@ enum __MIDL___MIDL_itf_mscoree_0000_0004_0002
MaxClrFailure = ( FAIL_CodeContract + 1 )
} EClrFailure;
-typedef /* [public][public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0004_0003
+typedef /* [public] */
+enum __MIDL___MIDL_itf_mscoree_0000_0000_0008
{
eRuntimeDeterminedPolicy = 0,
eHostDeterminedPolicy = ( eRuntimeDeterminedPolicy + 1 )
} EClrUnhandledException;
-typedef /* [public][public][public][public][public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0004_0004
+typedef /* [public] */
+enum __MIDL___MIDL_itf_mscoree_0000_0000_0009
{
eNoAction = 0,
eThrowException = ( eNoAction + 1 ) ,
@@ -928,636 +235,8 @@ enum __MIDL___MIDL_itf_mscoree_0000_0004_0004
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0004_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0004_v0_0_s_ifspec;
-
-#ifndef __ICLRPolicyManager_INTERFACE_DEFINED__
-#define __ICLRPolicyManager_INTERFACE_DEFINED__
-
-/* interface ICLRPolicyManager */
-/* [object][local][unique][helpstring][version][uuid] */
-
-
-EXTERN_C const IID IID_ICLRPolicyManager;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("7D290010-D781-45da-A6F8-AA5D711A730E")
- ICLRPolicyManager : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE SetDefaultAction(
- /* [in] */ EClrOperation operation,
- /* [in] */ EPolicyAction action) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE SetTimeout(
- /* [in] */ EClrOperation operation,
- /* [in] */ DWORD dwMilliseconds) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE SetActionOnTimeout(
- /* [in] */ EClrOperation operation,
- /* [in] */ EPolicyAction action) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE SetTimeoutAndAction(
- /* [in] */ EClrOperation operation,
- /* [in] */ DWORD dwMilliseconds,
- /* [in] */ EPolicyAction action) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE SetActionOnFailure(
- /* [in] */ EClrFailure failure,
- /* [in] */ EPolicyAction action) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE SetUnhandledExceptionPolicy(
- /* [in] */ EClrUnhandledException policy) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct ICLRPolicyManagerVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- ICLRPolicyManager * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- ICLRPolicyManager * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- ICLRPolicyManager * This);
-
- HRESULT ( STDMETHODCALLTYPE *SetDefaultAction )(
- ICLRPolicyManager * This,
- /* [in] */ EClrOperation operation,
- /* [in] */ EPolicyAction action);
-
- HRESULT ( STDMETHODCALLTYPE *SetTimeout )(
- ICLRPolicyManager * This,
- /* [in] */ EClrOperation operation,
- /* [in] */ DWORD dwMilliseconds);
-
- HRESULT ( STDMETHODCALLTYPE *SetActionOnTimeout )(
- ICLRPolicyManager * This,
- /* [in] */ EClrOperation operation,
- /* [in] */ EPolicyAction action);
-
- HRESULT ( STDMETHODCALLTYPE *SetTimeoutAndAction )(
- ICLRPolicyManager * This,
- /* [in] */ EClrOperation operation,
- /* [in] */ DWORD dwMilliseconds,
- /* [in] */ EPolicyAction action);
-
- HRESULT ( STDMETHODCALLTYPE *SetActionOnFailure )(
- ICLRPolicyManager * This,
- /* [in] */ EClrFailure failure,
- /* [in] */ EPolicyAction action);
-
- HRESULT ( STDMETHODCALLTYPE *SetUnhandledExceptionPolicy )(
- ICLRPolicyManager * This,
- /* [in] */ EClrUnhandledException policy);
-
- END_INTERFACE
- } ICLRPolicyManagerVtbl;
-
- interface ICLRPolicyManager
- {
- CONST_VTBL struct ICLRPolicyManagerVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define ICLRPolicyManager_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define ICLRPolicyManager_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define ICLRPolicyManager_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define ICLRPolicyManager_SetDefaultAction(This,operation,action) \
- ( (This)->lpVtbl -> SetDefaultAction(This,operation,action) )
-
-#define ICLRPolicyManager_SetTimeout(This,operation,dwMilliseconds) \
- ( (This)->lpVtbl -> SetTimeout(This,operation,dwMilliseconds) )
-
-#define ICLRPolicyManager_SetActionOnTimeout(This,operation,action) \
- ( (This)->lpVtbl -> SetActionOnTimeout(This,operation,action) )
-
-#define ICLRPolicyManager_SetTimeoutAndAction(This,operation,dwMilliseconds,action) \
- ( (This)->lpVtbl -> SetTimeoutAndAction(This,operation,dwMilliseconds,action) )
-
-#define ICLRPolicyManager_SetActionOnFailure(This,failure,action) \
- ( (This)->lpVtbl -> SetActionOnFailure(This,failure,action) )
-
-#define ICLRPolicyManager_SetUnhandledExceptionPolicy(This,policy) \
- ( (This)->lpVtbl -> SetUnhandledExceptionPolicy(This,policy) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __ICLRPolicyManager_INTERFACE_DEFINED__ */
-
-
-/* interface __MIDL_itf_mscoree_0000_0005 */
-/* [local] */
-
-typedef /* [public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0005_0001
- {
- Event_DomainUnload = 0,
- Event_ClrDisabled = ( Event_DomainUnload + 1 ) ,
- Event_MDAFired = ( Event_ClrDisabled + 1 ) ,
- Event_StackOverflow = ( Event_MDAFired + 1 ) ,
- MaxClrEvent = ( Event_StackOverflow + 1 )
- } EClrEvent;
-
-typedef struct _MDAInfo
- {
- LPCWSTR lpMDACaption;
- LPCWSTR lpMDAMessage;
- LPCWSTR lpStackTrace;
- } MDAInfo;
-
-typedef /* [public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0005_0002
- {
- SO_Managed = 0,
- SO_ClrEngine = ( SO_Managed + 1 ) ,
- SO_Other = ( SO_ClrEngine + 1 )
- } StackOverflowType;
-
-typedef struct _StackOverflowInfo
-{
- StackOverflowType soType;
- EXCEPTION_POINTERS *pExceptionInfo;
-} StackOverflowInfo;
-
-
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0005_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0005_v0_0_s_ifspec;
-
-#ifndef __ICLRGCManager_INTERFACE_DEFINED__
-#define __ICLRGCManager_INTERFACE_DEFINED__
-
-/* interface ICLRGCManager */
-/* [object][local][unique][version][uuid] */
-
-
-EXTERN_C const IID IID_ICLRGCManager;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("54D9007E-A8E2-4885-B7BF-F998DEEE4F2A")
- ICLRGCManager : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE Collect(
- /* [in] */ LONG Generation) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetStats(
- /* [out][in] */ COR_GC_STATS *pStats) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE SetGCStartupLimits(
- /* [in] */ DWORD SegmentSize,
- /* [in] */ DWORD MaxGen0Size) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct ICLRGCManagerVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- ICLRGCManager * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- ICLRGCManager * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- ICLRGCManager * This);
-
- HRESULT ( STDMETHODCALLTYPE *Collect )(
- ICLRGCManager * This,
- /* [in] */ LONG Generation);
-
- HRESULT ( STDMETHODCALLTYPE *GetStats )(
- ICLRGCManager * This,
- /* [out][in] */ COR_GC_STATS *pStats);
-
- HRESULT ( STDMETHODCALLTYPE *SetGCStartupLimits )(
- ICLRGCManager * This,
- /* [in] */ DWORD SegmentSize,
- /* [in] */ DWORD MaxGen0Size);
-
- END_INTERFACE
- } ICLRGCManagerVtbl;
-
- interface ICLRGCManager
- {
- CONST_VTBL struct ICLRGCManagerVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define ICLRGCManager_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define ICLRGCManager_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define ICLRGCManager_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define ICLRGCManager_Collect(This,Generation) \
- ( (This)->lpVtbl -> Collect(This,Generation) )
-
-#define ICLRGCManager_GetStats(This,pStats) \
- ( (This)->lpVtbl -> GetStats(This,pStats) )
-
-#define ICLRGCManager_SetGCStartupLimits(This,SegmentSize,MaxGen0Size) \
- ( (This)->lpVtbl -> SetGCStartupLimits(This,SegmentSize,MaxGen0Size) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __ICLRGCManager_INTERFACE_DEFINED__ */
-
-
-#ifndef __ICLRGCManager2_INTERFACE_DEFINED__
-#define __ICLRGCManager2_INTERFACE_DEFINED__
-
-/* interface ICLRGCManager2 */
-/* [object][local][unique][version][uuid] */
-
-
-EXTERN_C const IID IID_ICLRGCManager2;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("0603B793-A97A-4712-9CB4-0CD1C74C0F7C")
- ICLRGCManager2 : public ICLRGCManager
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE SetGCStartupLimitsEx(
- /* [in] */ SIZE_T SegmentSize,
- /* [in] */ SIZE_T MaxGen0Size) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct ICLRGCManager2Vtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- ICLRGCManager2 * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- ICLRGCManager2 * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- ICLRGCManager2 * This);
-
- HRESULT ( STDMETHODCALLTYPE *Collect )(
- ICLRGCManager2 * This,
- /* [in] */ LONG Generation);
-
- HRESULT ( STDMETHODCALLTYPE *GetStats )(
- ICLRGCManager2 * This,
- /* [out][in] */ COR_GC_STATS *pStats);
-
- HRESULT ( STDMETHODCALLTYPE *SetGCStartupLimits )(
- ICLRGCManager2 * This,
- /* [in] */ DWORD SegmentSize,
- /* [in] */ DWORD MaxGen0Size);
-
- HRESULT ( STDMETHODCALLTYPE *SetGCStartupLimitsEx )(
- ICLRGCManager2 * This,
- /* [in] */ SIZE_T SegmentSize,
- /* [in] */ SIZE_T MaxGen0Size);
-
- END_INTERFACE
- } ICLRGCManager2Vtbl;
-
- interface ICLRGCManager2
- {
- CONST_VTBL struct ICLRGCManager2Vtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define ICLRGCManager2_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define ICLRGCManager2_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define ICLRGCManager2_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define ICLRGCManager2_Collect(This,Generation) \
- ( (This)->lpVtbl -> Collect(This,Generation) )
-
-#define ICLRGCManager2_GetStats(This,pStats) \
- ( (This)->lpVtbl -> GetStats(This,pStats) )
-
-#define ICLRGCManager2_SetGCStartupLimits(This,SegmentSize,MaxGen0Size) \
- ( (This)->lpVtbl -> SetGCStartupLimits(This,SegmentSize,MaxGen0Size) )
-
-
-#define ICLRGCManager2_SetGCStartupLimitsEx(This,SegmentSize,MaxGen0Size) \
- ( (This)->lpVtbl -> SetGCStartupLimitsEx(This,SegmentSize,MaxGen0Size) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __ICLRGCManager2_INTERFACE_DEFINED__ */
-
-
-/* interface __MIDL_itf_mscoree_0000_0007 */
-/* [local] */
-
-typedef /* [public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0007_0001
- {
- ePolicyLevelNone = 0,
- ePolicyLevelRetargetable = 0x1,
- ePolicyUnifiedToCLR = 0x2,
- ePolicyLevelApp = 0x4,
- ePolicyLevelPublisher = 0x8,
- ePolicyLevelHost = 0x10,
- ePolicyLevelAdmin = 0x20,
- ePolicyPortability = 0x40
- } EBindPolicyLevels;
-
-typedef struct _AssemblyBindInfo
- {
- DWORD dwAppDomainId;
- LPCWSTR lpReferencedIdentity;
- LPCWSTR lpPostPolicyIdentity;
- DWORD ePolicyLevel;
- } AssemblyBindInfo;
-
-typedef struct _ModuleBindInfo
- {
- DWORD dwAppDomainId;
- LPCWSTR lpAssemblyIdentity;
- LPCWSTR lpModuleName;
- } ModuleBindInfo;
-
-typedef
-enum _HostApplicationPolicy
- {
- HOST_APPLICATION_BINDING_POLICY = 1
- } EHostApplicationPolicy;
-
-STDAPI GetCLRIdentityManager(REFIID riid, IUnknown **ppManager);
-EXTERN_GUID(IID_IHostControl, 0x02CA073C, 0x7079, 0x4860, 0x88, 0x0A, 0xC2, 0xF7, 0xA4, 0x49, 0xC9, 0x91);
-
-
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0007_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0007_v0_0_s_ifspec;
-
-#ifndef __IHostControl_INTERFACE_DEFINED__
-#define __IHostControl_INTERFACE_DEFINED__
-
-/* interface IHostControl */
-/* [object][local][unique][helpstring][version][uuid] */
-
-
-EXTERN_C const IID IID_IHostControl;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("02CA073C-7079-4860-880A-C2F7A449C991")
- IHostControl : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetHostManager(
- /* [in] */ REFIID riid,
- /* [out] */ void **ppObject) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE SetAppDomainManager(
- /* [in] */ DWORD dwAppDomainID,
- /* [in] */ IUnknown *pUnkAppDomainManager) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IHostControlVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IHostControl * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IHostControl * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IHostControl * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetHostManager )(
- IHostControl * This,
- /* [in] */ REFIID riid,
- /* [out] */ void **ppObject);
-
- HRESULT ( STDMETHODCALLTYPE *SetAppDomainManager )(
- IHostControl * This,
- /* [in] */ DWORD dwAppDomainID,
- /* [in] */ IUnknown *pUnkAppDomainManager);
-
- END_INTERFACE
- } IHostControlVtbl;
-
- interface IHostControl
- {
- CONST_VTBL struct IHostControlVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IHostControl_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IHostControl_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IHostControl_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IHostControl_GetHostManager(This,riid,ppObject) \
- ( (This)->lpVtbl -> GetHostManager(This,riid,ppObject) )
-
-#define IHostControl_SetAppDomainManager(This,dwAppDomainID,pUnkAppDomainManager) \
- ( (This)->lpVtbl -> SetAppDomainManager(This,dwAppDomainID,pUnkAppDomainManager) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IHostControl_INTERFACE_DEFINED__ */
-
-
-/* interface __MIDL_itf_mscoree_0000_0008 */
-/* [local] */
-
-EXTERN_GUID(IID_ICLRControl, 0x9065597E, 0xD1A1, 0x4fb2, 0xB6, 0xBA, 0x7E, 0x1F, 0xCE, 0x23, 0x0F, 0x61);
-
-
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0008_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0008_v0_0_s_ifspec;
-
-#ifndef __ICLRControl_INTERFACE_DEFINED__
-#define __ICLRControl_INTERFACE_DEFINED__
-
-/* interface ICLRControl */
-/* [object][local][unique][helpstring][version][uuid] */
-
-
-EXTERN_C const IID IID_ICLRControl;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("9065597E-D1A1-4fb2-B6BA-7E1FCE230F61")
- ICLRControl : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetCLRManager(
- /* [in] */ REFIID riid,
- /* [out] */ void **ppObject) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE SetAppDomainManagerType(
- /* [in] */ LPCWSTR pwzAppDomainManagerAssembly,
- /* [in] */ LPCWSTR pwzAppDomainManagerType) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct ICLRControlVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- ICLRControl * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- ICLRControl * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- ICLRControl * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetCLRManager )(
- ICLRControl * This,
- /* [in] */ REFIID riid,
- /* [out] */ void **ppObject);
-
- HRESULT ( STDMETHODCALLTYPE *SetAppDomainManagerType )(
- ICLRControl * This,
- /* [in] */ LPCWSTR pwzAppDomainManagerAssembly,
- /* [in] */ LPCWSTR pwzAppDomainManagerType);
-
- END_INTERFACE
- } ICLRControlVtbl;
-
- interface ICLRControl
- {
- CONST_VTBL struct ICLRControlVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define ICLRControl_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define ICLRControl_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define ICLRControl_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define ICLRControl_GetCLRManager(This,riid,ppObject) \
- ( (This)->lpVtbl -> GetCLRManager(This,riid,ppObject) )
-
-#define ICLRControl_SetAppDomainManagerType(This,pwzAppDomainManagerAssembly,pwzAppDomainManagerType) \
- ( (This)->lpVtbl -> SetAppDomainManagerType(This,pwzAppDomainManagerAssembly,pwzAppDomainManagerType) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __ICLRControl_INTERFACE_DEFINED__ */
-
+extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0000_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0000_v0_0_s_ifspec;
#ifndef __ICLRRuntimeHost_INTERFACE_DEFINED__
#define __ICLRRuntimeHost_INTERFACE_DEFINED__
@@ -1739,16 +418,6 @@ EXTERN_C const IID IID_ICLRRuntimeHost;
#endif /* __ICLRRuntimeHost_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_mscoree_0000_0010 */
-/* [local] */
-
-#define CORECLR_HOST_AUTHENTICATION_KEY 0x1C6CA6F94025800LL
-#define CORECLR_HOST_AUTHENTICATION_KEY_NONGEN 0x1C6CA6F94025801LL
-
-
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0010_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0010_v0_0_s_ifspec;
-
#ifndef __ICLRRuntimeHost2_INTERFACE_DEFINED__
#define __ICLRRuntimeHost2_INTERFACE_DEFINED__
@@ -1803,14 +472,6 @@ EXTERN_C const IID IID_ICLRRuntimeHost2;
};
- MIDL_INTERFACE("64F6D366-D7C2-4F1F-B4B2-E8160CAC43AF")
- ICLRRuntimeHost4 : public ICLRRuntimeHost2
- {
- virtual HRESULT STDMETHODCALLTYPE UnloadAppDomain2(
- /* [in] */ DWORD dwAppDomainId,
- /* [in] */ BOOL fWaitUntilDone,
- /* [out] */ int *pLatchedExitCode) = 0;
- };
#else /* C style interface */
@@ -2003,618 +664,149 @@ EXTERN_C const IID IID_ICLRRuntimeHost2;
#endif /* __ICLRRuntimeHost2_INTERFACE_DEFINED__ */
-#ifndef __IHostNetCFDebugControlManager_INTERFACE_DEFINED__
-#define __IHostNetCFDebugControlManager_INTERFACE_DEFINED__
-
-/* interface IHostNetCFDebugControlManager */
-/* [object][local][unique][helpstring][version][uuid] */
-
-
-EXTERN_C const IID IID_IHostNetCFDebugControlManager;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("F2833A0C-F944-48d8-940E-F59425EDBFCF")
- IHostNetCFDebugControlManager : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE NotifyPause(
- DWORD dwReserved) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE NotifyResume(
- DWORD dwReserved) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct IHostNetCFDebugControlManagerVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IHostNetCFDebugControlManager * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IHostNetCFDebugControlManager * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- IHostNetCFDebugControlManager * This);
-
- HRESULT ( STDMETHODCALLTYPE *NotifyPause )(
- IHostNetCFDebugControlManager * This,
- DWORD dwReserved);
-
- HRESULT ( STDMETHODCALLTYPE *NotifyResume )(
- IHostNetCFDebugControlManager * This,
- DWORD dwReserved);
-
- END_INTERFACE
- } IHostNetCFDebugControlManagerVtbl;
-
- interface IHostNetCFDebugControlManager
- {
- CONST_VTBL struct IHostNetCFDebugControlManagerVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define IHostNetCFDebugControlManager_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define IHostNetCFDebugControlManager_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define IHostNetCFDebugControlManager_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define IHostNetCFDebugControlManager_NotifyPause(This,dwReserved) \
- ( (This)->lpVtbl -> NotifyPause(This,dwReserved) )
-
-#define IHostNetCFDebugControlManager_NotifyResume(This,dwReserved) \
- ( (This)->lpVtbl -> NotifyResume(This,dwReserved) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IHostNetCFDebugControlManager_INTERFACE_DEFINED__ */
-
-
-/* interface __MIDL_itf_mscoree_0000_0013 */
-/* [local] */
-
-typedef /* [public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0013_0001
- {
- eNoChecks = 0,
- eSynchronization = 0x1,
- eSharedState = 0x2,
- eExternalProcessMgmt = 0x4,
- eSelfAffectingProcessMgmt = 0x8,
- eExternalThreading = 0x10,
- eSelfAffectingThreading = 0x20,
- eSecurityInfrastructure = 0x40,
- eUI = 0x80,
- eMayLeakOnAbort = 0x100,
- eAll = 0x1ff
- } EApiCategories;
-
-typedef /* [public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0013_0002
- {
- eInitializeNewDomainFlags_None = 0,
- eInitializeNewDomainFlags_NoSecurityChanges = 0x2
- } EInitializeNewDomainFlags;
-
-
-
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0013_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0013_v0_0_s_ifspec;
+#ifndef __ICLRRuntimeHost4_INTERFACE_DEFINED__
+#define __ICLRRuntimeHost4_INTERFACE_DEFINED__
-
-#ifndef __mscoree_LIBRARY_DEFINED__
-#define __mscoree_LIBRARY_DEFINED__
-
-/* library mscoree */
-/* [helpstring][version][uuid] */
-
-#define CCW_PTR int *
-
-EXTERN_C const IID LIBID_mscoree;
-
-#ifndef __ITypeName_INTERFACE_DEFINED__
-#define __ITypeName_INTERFACE_DEFINED__
-
-/* interface ITypeName */
-/* [unique][helpstring][uuid][oleautomation][object] */
-
-
-EXTERN_C const IID IID_ITypeName;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("B81FF171-20F3-11d2-8DCC-00A0C9B00522")
- ITypeName : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetNameCount(
- /* [retval][out] */ DWORD *pCount) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetNames(
- /* [in] */ DWORD count,
- /* [out] */ BSTR *rgbszNames,
- /* [retval][out] */ DWORD *pCount) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetTypeArgumentCount(
- /* [retval][out] */ DWORD *pCount) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetTypeArguments(
- /* [in] */ DWORD count,
- /* [out] */ ITypeName **rgpArguments,
- /* [retval][out] */ DWORD *pCount) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetModifierLength(
- /* [retval][out] */ DWORD *pCount) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetModifiers(
- /* [in] */ DWORD count,
- /* [out] */ DWORD *rgModifiers,
- /* [retval][out] */ DWORD *pCount) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetAssemblyName(
- /* [retval][out] */ BSTR *rgbszAssemblyNames) = 0;
-
- };
-
-
-#else /* C style interface */
-
- typedef struct ITypeNameVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- ITypeName * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- ITypeName * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- ITypeName * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetNameCount )(
- ITypeName * This,
- /* [retval][out] */ DWORD *pCount);
-
- HRESULT ( STDMETHODCALLTYPE *GetNames )(
- ITypeName * This,
- /* [in] */ DWORD count,
- /* [out] */ BSTR *rgbszNames,
- /* [retval][out] */ DWORD *pCount);
-
- HRESULT ( STDMETHODCALLTYPE *GetTypeArgumentCount )(
- ITypeName * This,
- /* [retval][out] */ DWORD *pCount);
-
- HRESULT ( STDMETHODCALLTYPE *GetTypeArguments )(
- ITypeName * This,
- /* [in] */ DWORD count,
- /* [out] */ ITypeName **rgpArguments,
- /* [retval][out] */ DWORD *pCount);
-
- HRESULT ( STDMETHODCALLTYPE *GetModifierLength )(
- ITypeName * This,
- /* [retval][out] */ DWORD *pCount);
-
- HRESULT ( STDMETHODCALLTYPE *GetModifiers )(
- ITypeName * This,
- /* [in] */ DWORD count,
- /* [out] */ DWORD *rgModifiers,
- /* [retval][out] */ DWORD *pCount);
-
- HRESULT ( STDMETHODCALLTYPE *GetAssemblyName )(
- ITypeName * This,
- /* [retval][out] */ BSTR *rgbszAssemblyNames);
-
- END_INTERFACE
- } ITypeNameVtbl;
-
- interface ITypeName
- {
- CONST_VTBL struct ITypeNameVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define ITypeName_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define ITypeName_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define ITypeName_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define ITypeName_GetNameCount(This,pCount) \
- ( (This)->lpVtbl -> GetNameCount(This,pCount) )
-
-#define ITypeName_GetNames(This,count,rgbszNames,pCount) \
- ( (This)->lpVtbl -> GetNames(This,count,rgbszNames,pCount) )
-
-#define ITypeName_GetTypeArgumentCount(This,pCount) \
- ( (This)->lpVtbl -> GetTypeArgumentCount(This,pCount) )
-
-#define ITypeName_GetTypeArguments(This,count,rgpArguments,pCount) \
- ( (This)->lpVtbl -> GetTypeArguments(This,count,rgpArguments,pCount) )
-
-#define ITypeName_GetModifierLength(This,pCount) \
- ( (This)->lpVtbl -> GetModifierLength(This,pCount) )
-
-#define ITypeName_GetModifiers(This,count,rgModifiers,pCount) \
- ( (This)->lpVtbl -> GetModifiers(This,count,rgModifiers,pCount) )
-
-#define ITypeName_GetAssemblyName(This,rgbszAssemblyNames) \
- ( (This)->lpVtbl -> GetAssemblyName(This,rgbszAssemblyNames) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __ITypeName_INTERFACE_DEFINED__ */
-
-
-#ifndef __ITypeNameBuilder_INTERFACE_DEFINED__
-#define __ITypeNameBuilder_INTERFACE_DEFINED__
-
-/* interface ITypeNameBuilder */
-/* [unique][helpstring][uuid][oleautomation][object] */
+/* interface ICLRRuntimeHost4 */
+/* [local][unique][helpstring][version][uuid][object] */
-EXTERN_C const IID IID_ITypeNameBuilder;
+EXTERN_C const IID IID_ICLRRuntimeHost4;
#if defined(__cplusplus) && !defined(CINTERFACE)
- MIDL_INTERFACE("B81FF171-20F3-11d2-8DCC-00A0C9B00523")
- ITypeNameBuilder : public IUnknown
+ MIDL_INTERFACE("64F6D366-D7C2-4F1F-B4B2-E8160CAC43AF")
+ ICLRRuntimeHost4 : public ICLRRuntimeHost2
{
public:
- virtual HRESULT STDMETHODCALLTYPE OpenGenericArguments( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE CloseGenericArguments( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE OpenGenericArgument( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE CloseGenericArgument( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE AddName(
- /* [in] */ LPCWSTR szName) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE AddPointer( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE AddByRef( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE AddSzArray( void) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE AddArray(
- /* [in] */ DWORD rank) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE AddAssemblySpec(
- /* [in] */ LPCWSTR szAssemblySpec) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE ToString(
- /* [retval][out] */ BSTR *pszStringRepresentation) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE Clear( void) = 0;
+ virtual HRESULT STDMETHODCALLTYPE UnloadAppDomain2(
+ /* [in] */ DWORD dwAppDomainId,
+ /* [in] */ BOOL fWaitUntilDone,
+ /* [out] */ int *pLatchedExitCode) = 0;
};
#else /* C style interface */
- typedef struct ITypeNameBuilderVtbl
+ typedef struct ICLRRuntimeHost4Vtbl
{
BEGIN_INTERFACE
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- ITypeNameBuilder * This,
+ ICLRRuntimeHost4 * This,
/* [in] */ REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject);
ULONG ( STDMETHODCALLTYPE *AddRef )(
- ITypeNameBuilder * This);
+ ICLRRuntimeHost4 * This);
ULONG ( STDMETHODCALLTYPE *Release )(
- ITypeNameBuilder * This);
-
- HRESULT ( STDMETHODCALLTYPE *OpenGenericArguments )(
- ITypeNameBuilder * This);
-
- HRESULT ( STDMETHODCALLTYPE *CloseGenericArguments )(
- ITypeNameBuilder * This);
-
- HRESULT ( STDMETHODCALLTYPE *OpenGenericArgument )(
- ITypeNameBuilder * This);
+ ICLRRuntimeHost4 * This);
- HRESULT ( STDMETHODCALLTYPE *CloseGenericArgument )(
- ITypeNameBuilder * This);
-
- HRESULT ( STDMETHODCALLTYPE *AddName )(
- ITypeNameBuilder * This,
- /* [in] */ LPCWSTR szName);
-
- HRESULT ( STDMETHODCALLTYPE *AddPointer )(
- ITypeNameBuilder * This);
-
- HRESULT ( STDMETHODCALLTYPE *AddByRef )(
- ITypeNameBuilder * This);
-
- HRESULT ( STDMETHODCALLTYPE *AddSzArray )(
- ITypeNameBuilder * This);
-
- HRESULT ( STDMETHODCALLTYPE *AddArray )(
- ITypeNameBuilder * This,
- /* [in] */ DWORD rank);
-
- HRESULT ( STDMETHODCALLTYPE *AddAssemblySpec )(
- ITypeNameBuilder * This,
- /* [in] */ LPCWSTR szAssemblySpec);
-
- HRESULT ( STDMETHODCALLTYPE *ToString )(
- ITypeNameBuilder * This,
- /* [retval][out] */ BSTR *pszStringRepresentation);
-
- HRESULT ( STDMETHODCALLTYPE *Clear )(
- ITypeNameBuilder * This);
+ HRESULT ( STDMETHODCALLTYPE *Start )(
+ ICLRRuntimeHost4 * This);
- END_INTERFACE
- } ITypeNameBuilderVtbl;
-
- interface ITypeNameBuilder
- {
- CONST_VTBL struct ITypeNameBuilderVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define ITypeNameBuilder_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define ITypeNameBuilder_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define ITypeNameBuilder_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define ITypeNameBuilder_OpenGenericArguments(This) \
- ( (This)->lpVtbl -> OpenGenericArguments(This) )
-
-#define ITypeNameBuilder_CloseGenericArguments(This) \
- ( (This)->lpVtbl -> CloseGenericArguments(This) )
-
-#define ITypeNameBuilder_OpenGenericArgument(This) \
- ( (This)->lpVtbl -> OpenGenericArgument(This) )
-
-#define ITypeNameBuilder_CloseGenericArgument(This) \
- ( (This)->lpVtbl -> CloseGenericArgument(This) )
-
-#define ITypeNameBuilder_AddName(This,szName) \
- ( (This)->lpVtbl -> AddName(This,szName) )
-
-#define ITypeNameBuilder_AddPointer(This) \
- ( (This)->lpVtbl -> AddPointer(This) )
-
-#define ITypeNameBuilder_AddByRef(This) \
- ( (This)->lpVtbl -> AddByRef(This) )
-
-#define ITypeNameBuilder_AddSzArray(This) \
- ( (This)->lpVtbl -> AddSzArray(This) )
-
-#define ITypeNameBuilder_AddArray(This,rank) \
- ( (This)->lpVtbl -> AddArray(This,rank) )
-
-#define ITypeNameBuilder_AddAssemblySpec(This,szAssemblySpec) \
- ( (This)->lpVtbl -> AddAssemblySpec(This,szAssemblySpec) )
-
-#define ITypeNameBuilder_ToString(This,pszStringRepresentation) \
- ( (This)->lpVtbl -> ToString(This,pszStringRepresentation) )
-
-#define ITypeNameBuilder_Clear(This) \
- ( (This)->lpVtbl -> Clear(This) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __ITypeNameBuilder_INTERFACE_DEFINED__ */
-
-
-#ifndef __ITypeNameFactory_INTERFACE_DEFINED__
-#define __ITypeNameFactory_INTERFACE_DEFINED__
-
-/* interface ITypeNameFactory */
-/* [unique][helpstring][uuid][oleautomation][object] */
-
-
-EXTERN_C const IID IID_ITypeNameFactory;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("B81FF171-20F3-11d2-8DCC-00A0C9B00521")
- ITypeNameFactory : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE ParseTypeName(
- /* [in] */ LPCWSTR szName,
- /* [out] */ DWORD *pError,
- /* [retval][out] */ ITypeName **ppTypeName) = 0;
+ HRESULT ( STDMETHODCALLTYPE *Stop )(
+ ICLRRuntimeHost4 * This);
- virtual HRESULT STDMETHODCALLTYPE GetTypeNameBuilder(
- /* [retval][out] */ ITypeNameBuilder **ppTypeBuilder) = 0;
+ HRESULT ( STDMETHODCALLTYPE *SetHostControl )(
+ ICLRRuntimeHost4 * This,
+ /* [in] */ IHostControl *pHostControl);
- };
-
-
-#else /* C style interface */
-
- typedef struct ITypeNameFactoryVtbl
- {
- BEGIN_INTERFACE
+ HRESULT ( STDMETHODCALLTYPE *GetCLRControl )(
+ ICLRRuntimeHost4 * This,
+ /* [out] */ ICLRControl **pCLRControl);
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- ITypeNameFactory * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
+ HRESULT ( STDMETHODCALLTYPE *UnloadAppDomain )(
+ ICLRRuntimeHost4 * This,
+ /* [in] */ DWORD dwAppDomainId,
+ /* [in] */ BOOL fWaitUntilDone);
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- ITypeNameFactory * This);
+ HRESULT ( STDMETHODCALLTYPE *ExecuteInAppDomain )(
+ ICLRRuntimeHost4 * This,
+ /* [in] */ DWORD dwAppDomainId,
+ /* [in] */ FExecuteInAppDomainCallback pCallback,
+ /* [in] */ void *cookie);
- ULONG ( STDMETHODCALLTYPE *Release )(
- ITypeNameFactory * This);
+ HRESULT ( STDMETHODCALLTYPE *GetCurrentAppDomainId )(
+ ICLRRuntimeHost4 * This,
+ /* [out] */ DWORD *pdwAppDomainId);
- HRESULT ( STDMETHODCALLTYPE *ParseTypeName )(
- ITypeNameFactory * This,
- /* [in] */ LPCWSTR szName,
- /* [out] */ DWORD *pError,
- /* [retval][out] */ ITypeName **ppTypeName);
+ HRESULT ( STDMETHODCALLTYPE *ExecuteApplication )(
+ ICLRRuntimeHost4 * This,
+ /* [in] */ LPCWSTR pwzAppFullName,
+ /* [in] */ DWORD dwManifestPaths,
+ /* [in] */ LPCWSTR *ppwzManifestPaths,
+ /* [in] */ DWORD dwActivationData,
+ /* [in] */ LPCWSTR *ppwzActivationData,
+ /* [out] */ int *pReturnValue);
- HRESULT ( STDMETHODCALLTYPE *GetTypeNameBuilder )(
- ITypeNameFactory * This,
- /* [retval][out] */ ITypeNameBuilder **ppTypeBuilder);
+ HRESULT ( STDMETHODCALLTYPE *ExecuteInDefaultAppDomain )(
+ ICLRRuntimeHost4 * This,
+ /* [in] */ LPCWSTR pwzAssemblyPath,
+ /* [in] */ LPCWSTR pwzTypeName,
+ /* [in] */ LPCWSTR pwzMethodName,
+ /* [in] */ LPCWSTR pwzArgument,
+ /* [out] */ DWORD *pReturnValue);
- END_INTERFACE
- } ITypeNameFactoryVtbl;
-
- interface ITypeNameFactory
- {
- CONST_VTBL struct ITypeNameFactoryVtbl *lpVtbl;
- };
-
-
-
-#ifdef COBJMACROS
-
-
-#define ITypeNameFactory_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-
-#define ITypeNameFactory_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
-
-#define ITypeNameFactory_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
-
-
-#define ITypeNameFactory_ParseTypeName(This,szName,pError,ppTypeName) \
- ( (This)->lpVtbl -> ParseTypeName(This,szName,pError,ppTypeName) )
-
-#define ITypeNameFactory_GetTypeNameBuilder(This,ppTypeBuilder) \
- ( (This)->lpVtbl -> GetTypeNameBuilder(This,ppTypeBuilder) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __ITypeNameFactory_INTERFACE_DEFINED__ */
-
-
-#ifndef __IManagedObject_INTERFACE_DEFINED__
-#define __IManagedObject_INTERFACE_DEFINED__
-
-/* interface IManagedObject */
-/* [proxy][unique][helpstring][uuid][oleautomation][object] */
-
-
-EXTERN_C const IID IID_IManagedObject;
-
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("C3FCC19E-A970-11d2-8B5A-00A0C9B7C9C4")
- IManagedObject : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetSerializedBuffer(
- /* [out] */ BSTR *pBSTR) = 0;
+ HRESULT ( STDMETHODCALLTYPE *CreateAppDomainWithManager )(
+ ICLRRuntimeHost4 * This,
+ /* [in] */ LPCWSTR wszFriendlyName,
+ /* [in] */ DWORD dwFlags,
+ /* [in] */ LPCWSTR wszAppDomainManagerAssemblyName,
+ /* [in] */ LPCWSTR wszAppDomainManagerTypeName,
+ /* [in] */ int nProperties,
+ /* [in] */ LPCWSTR *pPropertyNames,
+ /* [in] */ LPCWSTR *pPropertyValues,
+ /* [out] */ DWORD *pAppDomainID);
- virtual HRESULT STDMETHODCALLTYPE GetObjectIdentity(
- /* [out] */ BSTR *pBSTRGUID,
- /* [out] */ int *AppDomainID,
- /* [out] */ int *pCCW) = 0;
+ HRESULT ( STDMETHODCALLTYPE *CreateDelegate )(
+ ICLRRuntimeHost4 * This,
+ /* [in] */ DWORD appDomainID,
+ /* [in] */ LPCWSTR wszAssemblyName,
+ /* [in] */ LPCWSTR wszClassName,
+ /* [in] */ LPCWSTR wszMethodName,
+ /* [out] */ INT_PTR *fnPtr);
- };
-
-
-#else /* C style interface */
-
- typedef struct IManagedObjectVtbl
- {
- BEGIN_INTERFACE
+ HRESULT ( STDMETHODCALLTYPE *Authenticate )(
+ ICLRRuntimeHost4 * This,
+ /* [in] */ ULONGLONG authKey);
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- IManagedObject * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
+ HRESULT ( STDMETHODCALLTYPE *RegisterMacEHPort )(
+ ICLRRuntimeHost4 * This);
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- IManagedObject * This);
+ HRESULT ( STDMETHODCALLTYPE *SetStartupFlags )(
+ ICLRRuntimeHost4 * This,
+ /* [in] */ STARTUP_FLAGS dwFlags);
- ULONG ( STDMETHODCALLTYPE *Release )(
- IManagedObject * This);
+ HRESULT ( STDMETHODCALLTYPE *DllGetActivationFactory )(
+ ICLRRuntimeHost4 * This,
+ /* [in] */ DWORD appDomainID,
+ /* [in] */ LPCWSTR wszTypeName,
+ /* [out] */ IActivationFactory **factory);
- HRESULT ( STDMETHODCALLTYPE *GetSerializedBuffer )(
- IManagedObject * This,
- /* [out] */ BSTR *pBSTR);
+ HRESULT ( STDMETHODCALLTYPE *ExecuteAssembly )(
+ ICLRRuntimeHost4 * This,
+ /* [in] */ DWORD dwAppDomainId,
+ /* [in] */ LPCWSTR pwzAssemblyPath,
+ /* [in] */ int argc,
+ /* [in] */ LPCWSTR *argv,
+ /* [out] */ DWORD *pReturnValue);
- HRESULT ( STDMETHODCALLTYPE *GetObjectIdentity )(
- IManagedObject * This,
- /* [out] */ BSTR *pBSTRGUID,
- /* [out] */ int *AppDomainID,
- /* [out] */ int *pCCW);
+ HRESULT ( STDMETHODCALLTYPE *UnloadAppDomain2 )(
+ ICLRRuntimeHost4 * This,
+ /* [in] */ DWORD dwAppDomainId,
+ /* [in] */ BOOL fWaitUntilDone,
+ /* [out] */ int *pLatchedExitCode);
END_INTERFACE
- } IManagedObjectVtbl;
+ } ICLRRuntimeHost4Vtbl;
- interface IManagedObject
+ interface ICLRRuntimeHost4
{
- CONST_VTBL struct IManagedObjectVtbl *lpVtbl;
+ CONST_VTBL struct ICLRRuntimeHost4Vtbl *lpVtbl;
};
@@ -2622,177 +814,68 @@ EXTERN_C const IID IID_IManagedObject;
#ifdef COBJMACROS
-#define IManagedObject_QueryInterface(This,riid,ppvObject) \
+#define ICLRRuntimeHost4_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
-#define IManagedObject_AddRef(This) \
+#define ICLRRuntimeHost4_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )
-#define IManagedObject_Release(This) \
+#define ICLRRuntimeHost4_Release(This) \
( (This)->lpVtbl -> Release(This) )
-#define IManagedObject_GetSerializedBuffer(This,pBSTR) \
- ( (This)->lpVtbl -> GetSerializedBuffer(This,pBSTR) )
-
-#define IManagedObject_GetObjectIdentity(This,pBSTRGUID,AppDomainID,pCCW) \
- ( (This)->lpVtbl -> GetObjectIdentity(This,pBSTRGUID,AppDomainID,pCCW) )
-
-#endif /* COBJMACROS */
-
-
-#endif /* C style interface */
-
-
-
-
-#endif /* __IManagedObject_INTERFACE_DEFINED__ */
-
-
-EXTERN_C const CLSID CLSID_ComCallUnmarshal;
-
-#ifdef __cplusplus
-
-class DECLSPEC_UUID("3F281000-E95A-11d2-886B-00C04F869F04")
-ComCallUnmarshal;
-#endif
-
-EXTERN_C const CLSID CLSID_ComCallUnmarshalV4;
-
-#ifdef __cplusplus
-
-class DECLSPEC_UUID("45FB4600-E6E8-4928-B25E-50476FF79425")
-ComCallUnmarshalV4;
-#endif
-
-EXTERN_C const CLSID CLSID_CLRRuntimeHost;
-
-#ifdef __cplusplus
-
-class DECLSPEC_UUID("90F1A06E-7712-4762-86B5-7A5EBA6BDB02")
-CLRRuntimeHost;
-#endif
-
-EXTERN_C const CLSID CLSID_TypeNameFactory;
-
-#ifdef __cplusplus
-
-class DECLSPEC_UUID("B81FF171-20F3-11d2-8DCC-00A0C9B00525")
-TypeNameFactory;
-#endif
-#endif /* __mscoree_LIBRARY_DEFINED__ */
-
-/* interface __MIDL_itf_mscoree_0000_0014 */
-/* [local] */
-
-typedef /* [public] */
-enum __MIDL___MIDL_itf_mscoree_0000_0014_0001
- {
- eCurrentContext = 0,
- eRestrictedContext = 0x1
- } EContextType;
-
-
+#define ICLRRuntimeHost4_Start(This) \
+ ( (This)->lpVtbl -> Start(This) )
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0014_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0014_v0_0_s_ifspec;
+#define ICLRRuntimeHost4_Stop(This) \
+ ( (This)->lpVtbl -> Stop(This) )
-#ifndef __ICLRAppDomainResourceMonitor_INTERFACE_DEFINED__
-#define __ICLRAppDomainResourceMonitor_INTERFACE_DEFINED__
+#define ICLRRuntimeHost4_SetHostControl(This,pHostControl) \
+ ( (This)->lpVtbl -> SetHostControl(This,pHostControl) )
-/* interface ICLRAppDomainResourceMonitor */
-/* [object][local][unique][helpstring][uuid][version] */
+#define ICLRRuntimeHost4_GetCLRControl(This,pCLRControl) \
+ ( (This)->lpVtbl -> GetCLRControl(This,pCLRControl) )
+#define ICLRRuntimeHost4_UnloadAppDomain(This,dwAppDomainId,fWaitUntilDone) \
+ ( (This)->lpVtbl -> UnloadAppDomain(This,dwAppDomainId,fWaitUntilDone) )
-EXTERN_C const IID IID_ICLRAppDomainResourceMonitor;
+#define ICLRRuntimeHost4_ExecuteInAppDomain(This,dwAppDomainId,pCallback,cookie) \
+ ( (This)->lpVtbl -> ExecuteInAppDomain(This,dwAppDomainId,pCallback,cookie) )
-#if defined(__cplusplus) && !defined(CINTERFACE)
-
- MIDL_INTERFACE("c62de18c-2e23-4aea-8423-b40c1fc59eae")
- ICLRAppDomainResourceMonitor : public IUnknown
- {
- public:
- virtual HRESULT STDMETHODCALLTYPE GetCurrentAllocated(
- /* [in] */ DWORD dwAppDomainId,
- /* [out] */ ULONGLONG *pBytesAllocated) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetCurrentSurvived(
- /* [in] */ DWORD dwAppDomainId,
- /* [out] */ ULONGLONG *pAppDomainBytesSurvived,
- /* [out] */ ULONGLONG *pTotalBytesSurvived) = 0;
-
- virtual HRESULT STDMETHODCALLTYPE GetCurrentCpuTime(
- /* [in] */ DWORD dwAppDomainId,
- /* [out] */ ULONGLONG *pMilliseconds) = 0;
-
- };
-
-
-#else /* C style interface */
+#define ICLRRuntimeHost4_GetCurrentAppDomainId(This,pdwAppDomainId) \
+ ( (This)->lpVtbl -> GetCurrentAppDomainId(This,pdwAppDomainId) )
- typedef struct ICLRAppDomainResourceMonitorVtbl
- {
- BEGIN_INTERFACE
-
- HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
- ICLRAppDomainResourceMonitor * This,
- /* [in] */ REFIID riid,
- /* [annotation][iid_is][out] */
- _COM_Outptr_ void **ppvObject);
-
- ULONG ( STDMETHODCALLTYPE *AddRef )(
- ICLRAppDomainResourceMonitor * This);
-
- ULONG ( STDMETHODCALLTYPE *Release )(
- ICLRAppDomainResourceMonitor * This);
-
- HRESULT ( STDMETHODCALLTYPE *GetCurrentAllocated )(
- ICLRAppDomainResourceMonitor * This,
- /* [in] */ DWORD dwAppDomainId,
- /* [out] */ ULONGLONG *pBytesAllocated);
-
- HRESULT ( STDMETHODCALLTYPE *GetCurrentSurvived )(
- ICLRAppDomainResourceMonitor * This,
- /* [in] */ DWORD dwAppDomainId,
- /* [out] */ ULONGLONG *pAppDomainBytesSurvived,
- /* [out] */ ULONGLONG *pTotalBytesSurvived);
-
- HRESULT ( STDMETHODCALLTYPE *GetCurrentCpuTime )(
- ICLRAppDomainResourceMonitor * This,
- /* [in] */ DWORD dwAppDomainId,
- /* [out] */ ULONGLONG *pMilliseconds);
-
- END_INTERFACE
- } ICLRAppDomainResourceMonitorVtbl;
+#define ICLRRuntimeHost4_ExecuteApplication(This,pwzAppFullName,dwManifestPaths,ppwzManifestPaths,dwActivationData,ppwzActivationData,pReturnValue) \
+ ( (This)->lpVtbl -> ExecuteApplication(This,pwzAppFullName,dwManifestPaths,ppwzManifestPaths,dwActivationData,ppwzActivationData,pReturnValue) )
- interface ICLRAppDomainResourceMonitor
- {
- CONST_VTBL struct ICLRAppDomainResourceMonitorVtbl *lpVtbl;
- };
+#define ICLRRuntimeHost4_ExecuteInDefaultAppDomain(This,pwzAssemblyPath,pwzTypeName,pwzMethodName,pwzArgument,pReturnValue) \
+ ( (This)->lpVtbl -> ExecuteInDefaultAppDomain(This,pwzAssemblyPath,pwzTypeName,pwzMethodName,pwzArgument,pReturnValue) )
-
-#ifdef COBJMACROS
+#define ICLRRuntimeHost4_CreateAppDomainWithManager(This,wszFriendlyName,dwFlags,wszAppDomainManagerAssemblyName,wszAppDomainManagerTypeName,nProperties,pPropertyNames,pPropertyValues,pAppDomainID) \
+ ( (This)->lpVtbl -> CreateAppDomainWithManager(This,wszFriendlyName,dwFlags,wszAppDomainManagerAssemblyName,wszAppDomainManagerTypeName,nProperties,pPropertyNames,pPropertyValues,pAppDomainID) )
+#define ICLRRuntimeHost4_CreateDelegate(This,appDomainID,wszAssemblyName,wszClassName,wszMethodName,fnPtr) \
+ ( (This)->lpVtbl -> CreateDelegate(This,appDomainID,wszAssemblyName,wszClassName,wszMethodName,fnPtr) )
-#define ICLRAppDomainResourceMonitor_QueryInterface(This,riid,ppvObject) \
- ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )
+#define ICLRRuntimeHost4_Authenticate(This,authKey) \
+ ( (This)->lpVtbl -> Authenticate(This,authKey) )
-#define ICLRAppDomainResourceMonitor_AddRef(This) \
- ( (This)->lpVtbl -> AddRef(This) )
+#define ICLRRuntimeHost4_RegisterMacEHPort(This) \
+ ( (This)->lpVtbl -> RegisterMacEHPort(This) )
-#define ICLRAppDomainResourceMonitor_Release(This) \
- ( (This)->lpVtbl -> Release(This) )
+#define ICLRRuntimeHost4_SetStartupFlags(This,dwFlags) \
+ ( (This)->lpVtbl -> SetStartupFlags(This,dwFlags) )
+#define ICLRRuntimeHost4_DllGetActivationFactory(This,appDomainID,wszTypeName,factory) \
+ ( (This)->lpVtbl -> DllGetActivationFactory(This,appDomainID,wszTypeName,factory) )
-#define ICLRAppDomainResourceMonitor_GetCurrentAllocated(This,dwAppDomainId,pBytesAllocated) \
- ( (This)->lpVtbl -> GetCurrentAllocated(This,dwAppDomainId,pBytesAllocated) )
+#define ICLRRuntimeHost4_ExecuteAssembly(This,dwAppDomainId,pwzAssemblyPath,argc,argv,pReturnValue) \
+ ( (This)->lpVtbl -> ExecuteAssembly(This,dwAppDomainId,pwzAssemblyPath,argc,argv,pReturnValue) )
-#define ICLRAppDomainResourceMonitor_GetCurrentSurvived(This,dwAppDomainId,pAppDomainBytesSurvived,pTotalBytesSurvived) \
- ( (This)->lpVtbl -> GetCurrentSurvived(This,dwAppDomainId,pAppDomainBytesSurvived,pTotalBytesSurvived) )
-#define ICLRAppDomainResourceMonitor_GetCurrentCpuTime(This,dwAppDomainId,pMilliseconds) \
- ( (This)->lpVtbl -> GetCurrentCpuTime(This,dwAppDomainId,pMilliseconds) )
+#define ICLRRuntimeHost4_UnloadAppDomain2(This,dwAppDomainId,fWaitUntilDone,pLatchedExitCode) \
+ ( (This)->lpVtbl -> UnloadAppDomain2(This,dwAppDomainId,fWaitUntilDone,pLatchedExitCode) )
#endif /* COBJMACROS */
@@ -2802,10 +885,10 @@ EXTERN_C const IID IID_ICLRAppDomainResourceMonitor;
-#endif /* __ICLRAppDomainResourceMonitor_INTERFACE_DEFINED__ */
+#endif /* __ICLRRuntimeHost4_INTERFACE_DEFINED__ */
-/* interface __MIDL_itf_mscoree_0000_0015 */
+/* interface __MIDL_itf_mscoree_0000_0003 */
/* [local] */
#undef DEPRECATED_CLR_STDAPI
@@ -2813,8 +896,8 @@ EXTERN_C const IID IID_ICLRAppDomainResourceMonitor;
#undef DEPRECATED_CLR_API_MESG
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0015_v0_0_c_ifspec;
-extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0015_v0_0_s_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0003_v0_0_c_ifspec;
+extern RPC_IF_HANDLE __MIDL_itf_mscoree_0000_0003_v0_0_s_ifspec;
/* Additional Prototypes for ALL interfaces */
diff --git a/src/pal/tools/gen-buildsys-clang.sh b/src/pal/tools/gen-buildsys-clang.sh
index 2047b1eccf..95b227d89f 100755
--- a/src/pal/tools/gen-buildsys-clang.sh
+++ b/src/pal/tools/gen-buildsys-clang.sh
@@ -6,12 +6,13 @@
if [ $# -lt 4 ]
then
echo "Usage..."
- echo "gen-buildsys-clang.sh <path to top level CMakeLists.txt> <ClangMajorVersion> <ClangMinorVersion> <Architecture> [build flavor] [coverage] [ninja] [cmakeargs]"
+ echo "gen-buildsys-clang.sh <path to top level CMakeLists.txt> <ClangMajorVersion> <ClangMinorVersion> <Architecture> [build flavor] [coverage] [ninja] [scan-build] [cmakeargs]"
echo "Specify the path to the top level CMake file - <ProjectK>/src/NDP"
echo "Specify the clang version to use, split into major and minor version"
echo "Specify the target architecture."
echo "Optionally specify the build configuration (flavor.) Defaults to DEBUG."
echo "Optionally specify 'coverage' to enable code coverage build."
+ echo "Optionally specify 'scan-build' to enable build with clang static analyzer."
echo "Target ninja instead of make. ninja must be on the PATH."
echo "Pass additional arguments to CMake call."
exit 1
@@ -42,6 +43,7 @@ build_arch="$4"
buildtype=DEBUG
code_coverage=OFF
build_tests=OFF
+scan_build=OFF
generator="Unix Makefiles"
__UnprocessedCMakeArgs=""
@@ -59,6 +61,10 @@ for i in "${@:5}"; do
NINJA)
generator=Ninja
;;
+ SCAN-BUILD)
+ echo "Static analysis is turned on for this build."
+ scan_build=ON
+ ;;
*)
__UnprocessedCMakeArgs="${__UnprocessedCMakeArgs}${__UnprocessedCMakeArgs:+ }$i"
esac
@@ -152,7 +158,16 @@ fi
# Determine the current script directory
__currentScriptDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-cmake \
+cmake_command=cmake
+
+if [[ "$scan_build" == "ON" ]]; then
+ export CCC_CC=$CC
+ export CCC_CXX=$CXX
+ export SCAN_BUILD_COMMAND=$(command -v scan-build$desired_llvm_version)
+ cmake_command="$SCAN_BUILD_COMMAND $cmake_command"
+fi
+
+$cmake_command \
-G "$generator" \
"-DCMAKE_USER_MAKE_RULES_OVERRIDE=${__currentScriptDir}/$overridefile" \
"-DCMAKE_AR=$llvm_ar" \
diff --git a/src/utilcode/util.cpp b/src/utilcode/util.cpp
index 9ebc401db4..d0a6035318 100644
--- a/src/utilcode/util.cpp
+++ b/src/utilcode/util.cpp
@@ -3035,21 +3035,6 @@ void EnableTerminationOnHeapCorruption()
HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
}
-#ifdef FEATURE_COMINTEROP
-BOOL IsClrHostedLegacyComObject(REFCLSID rclsid)
-{
- // let's simply check for all CLSIDs that are known to be runtime implemented and capped to 2.0
- return (
- rclsid == CLSID_ComCallUnmarshal ||
- rclsid == CLSID_CorMetaDataDispenser ||
- rclsid == CLSID_CorMetaDataDispenserRuntime ||
- rclsid == CLSID_TypeNameFactory);
-}
-#endif // FEATURE_COMINTEROP
-
-
-
-
namespace Clr
{
namespace Util
diff --git a/src/vm/ceeload.cpp b/src/vm/ceeload.cpp
index 6d1643b46e..cd46cffaaa 100644
--- a/src/vm/ceeload.cpp
+++ b/src/vm/ceeload.cpp
@@ -7442,6 +7442,11 @@ MethodDesc* Module::LoadIBCMethodHelper(DataImage *image, CORBBTPROF_BLOB_PARAM_
DWORD slot;
IfFailThrow(p.GetData(&slot));
+ if (slot >= pOwnerMT->GetNumVtableSlots())
+ {
+ COMPlusThrow(kTypeLoadException, IDS_IBC_MISSING_EXTERNAL_METHOD);
+ }
+
pMethod = pOwnerMT->GetMethodDescForSlot(slot);
}
else // otherwise we use the normal metadata MethodDef token encoding and we handle ibc tokens.
diff --git a/src/vm/ceemain.cpp b/src/vm/ceemain.cpp
index 41b6fe0b6f..e5267cf131 100644
--- a/src/vm/ceemain.cpp
+++ b/src/vm/ceemain.cpp
@@ -632,10 +632,6 @@ void EEStartupHelper(COINITIEE fFlags)
#ifndef CROSSGEN_COMPILE
-#ifdef _DEBUG
- DisableGlobalAllocStore();
-#endif //_DEBUG
-
#ifndef FEATURE_PAL
::SetConsoleCtrlHandler(DbgCtrlCHandler, TRUE/*add*/);
#endif
@@ -1519,11 +1515,7 @@ void STDMETHODCALLTYPE EEShutDownHelper(BOOL fIsDllUnloading)
{
ClrFlsSetThreadType(ThreadType_Shutdown);
- if (!fIsDllUnloading)
- {
- ProcessEventForHost(Event_ClrDisabled, NULL);
- }
- else if (g_fEEShutDown)
+ if (fIsDllUnloading && g_fEEShutDown)
{
// I'm in the final shutdown and the first part has already been run.
goto part2;
diff --git a/src/vm/ceemain.h b/src/vm/ceemain.h
index 451bbc58b1..25152564c0 100644
--- a/src/vm/ceemain.h
+++ b/src/vm/ceemain.h
@@ -181,10 +181,6 @@ private:
};
-#ifdef _DEBUG
-extern void DisableGlobalAllocStore ();
-#endif //_DEBUG
-
void SetLatchedExitCode (INT32 code);
INT32 GetLatchedExitCode (void);
diff --git a/src/vm/comcallablewrapper.cpp b/src/vm/comcallablewrapper.cpp
index 415cfa8232..ec05f00cd3 100644
--- a/src/vm/comcallablewrapper.cpp
+++ b/src/vm/comcallablewrapper.cpp
@@ -5305,7 +5305,16 @@ void ComCallWrapperTemplate::CheckParentComVisibility(BOOL fForIDispatch)
// Throw an exception to report the error.
if (!CheckParentComVisibilityNoThrow(fForIDispatch))
- COMPlusThrow(kInvalidOperationException, IDS_EE_COM_INVISIBLE_PARENT);
+ {
+ ComCallWrapperTemplate *invisParent = FindInvisibleParent();
+ _ASSERTE(invisParent != NULL);
+
+ SString thisType;
+ SString invisParentType;
+ TypeString::AppendType(thisType, m_thClass);
+ TypeString::AppendType(invisParentType, invisParent->m_thClass);
+ COMPlusThrow(kInvalidOperationException, IDS_EE_COM_INVISIBLE_PARENT, thisType.GetUnicode(), invisParentType.GetUnicode());
+ }
}
BOOL ComCallWrapperTemplate::CheckParentComVisibilityNoThrow(BOOL fForIDispatch)
@@ -6173,20 +6182,36 @@ void ComCallWrapperTemplate::DetermineComVisibility()
m_flags &= (~enum_InvisibleParent);
- // If there are no parents...leave it as false.
if (m_pParent == NULL)
return;
- // If our parent has an invisible parent
- if (m_pParent->HasInvisibleParent())
+ // Check if the parent has an invisible parent
+ // or if the parent itself is invisible.
+ if (m_pParent->HasInvisibleParent()
+ || !IsTypeVisibleFromCom(m_pParent->m_thClass))
{
+ _ASSERTE(NULL != FindInvisibleParent());
m_flags |= enum_InvisibleParent;
}
- // If our parent is invisible
- else if (!IsTypeVisibleFromCom(m_pParent->m_thClass))
+}
+
+ComCallWrapperTemplate* ComCallWrapperTemplate::FindInvisibleParent()
+{
+ ComCallWrapperTemplate* invisParentMaybe = m_pParent;
+
+ // Walk up the CCW parent classes and try to find
+ // if one is invisible to COM.
+ while (invisParentMaybe != NULL)
{
- m_flags |= enum_InvisibleParent;
+ // If our parent is invisible, return it.
+ if (!IsTypeVisibleFromCom(invisParentMaybe->m_thClass))
+ return invisParentMaybe;
+
+ invisParentMaybe = invisParentMaybe->m_pParent;
}
+
+ // All classes in hierarchy are COM visible
+ return NULL;
}
//--------------------------------------------------------------------------
diff --git a/src/vm/comcallablewrapper.h b/src/vm/comcallablewrapper.h
index a8cce3dccb..11c057444a 100644
--- a/src/vm/comcallablewrapper.h
+++ b/src/vm/comcallablewrapper.h
@@ -449,7 +449,8 @@ private:
ComMethodTable* CreateComMethodTableForBasic(MethodTable* pClassMT);
ComMethodTable* CreateComMethodTableForDelegate(MethodTable *pDelegateMT);
- void DetermineComVisibility();
+ void DetermineComVisibility();
+ ComCallWrapperTemplate* FindInvisibleParent();
private:
LONG m_cbRefCount;
diff --git a/src/vm/commtmemberinfomap.cpp b/src/vm/commtmemberinfomap.cpp
index 01904ef212..e53cd2f525 100644
--- a/src/vm/commtmemberinfomap.cpp
+++ b/src/vm/commtmemberinfomap.cpp
@@ -13,7 +13,6 @@
#include "commtmemberinfomap.h"
#include "comcallablewrapper.h"
-#include "tlbexport.h"
#include "field.h"
#include "caparser.h"
@@ -1381,6 +1380,67 @@ void ComMTMemberInfoMap::AssignNewEnumMember(
}
} // void ComMTMemberInfoMap::AssignNewEnumMember()
+//*****************************************************************************
+// Signature utilities.
+//*****************************************************************************
+class MetaSigExport : public MetaSig
+{
+public:
+ MetaSigExport(MethodDesc *pMD) :
+ MetaSig(pMD)
+ {
+ WRAPPER_NO_CONTRACT;
+ }
+
+ BOOL IsVbRefType()
+ {
+ CONTRACT(BOOL)
+ {
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_ANY;
+ }
+ CONTRACT_END;
+
+ // Get the arg, and skip decorations.
+ SigPointer pt = GetArgProps();
+ CorElementType mt;
+ if (FAILED(pt.PeekElemType(&mt)))
+ return FALSE;
+
+ while (mt == ELEMENT_TYPE_BYREF || mt == ELEMENT_TYPE_PTR)
+ {
+ // Eat the one just examined, and peek at the next one.
+ if (FAILED(pt.GetElemType(NULL)) || FAILED(pt.PeekElemType(&mt)))
+ return FALSE;
+ }
+
+ // Is it just Object?
+ if (mt == ELEMENT_TYPE_OBJECT)
+ RETURN TRUE;
+
+ // A particular class?
+ if (mt == ELEMENT_TYPE_CLASS)
+ {
+ // Exclude "string".
+ if (pt.IsStringType(m_pModule, GetSigTypeContext()))
+ RETURN FALSE;
+ RETURN TRUE;
+ }
+
+ // A particular valuetype?
+ if (mt == ELEMENT_TYPE_VALUETYPE)
+ {
+ // Include "variant".
+ if (pt.IsClass(m_pModule, g_VariantClassName, GetSigTypeContext()))
+ RETURN TRUE;
+ RETURN FALSE;
+ }
+
+ // An array, a string, or POD.
+ RETURN FALSE;
+ }
+}; // class MetaSigExport : public MetaSig
// ============================================================================
// For each property set and let functions, determine PROPERTYPUT and
diff --git a/src/vm/corhost.cpp b/src/vm/corhost.cpp
index 703e3a3384..1a376f0918 100644
--- a/src/vm/corhost.cpp
+++ b/src/vm/corhost.cpp
@@ -62,10 +62,6 @@ EXTERN_C UINT32 _tls_index;
UINT32 _tls_index = 0;
#endif // FEATURE_PAL
-#if defined(FEATURE_WINDOWSPHONE)
-SVAL_IMPL_INIT(ECustomDumpFlavor, CCLRErrorReportingManager, g_ECustomDumpFlavor, DUMP_FLAVOR_Default);
-#endif
-
#ifndef DACCESS_COMPILE
extern void STDMETHODCALLTYPE EEShutDown(BOOL fIsDllUnloading);
@@ -78,11 +74,6 @@ extern BOOL g_fEEHostedStartup;
ULONG CorRuntimeHostBase::m_Version = 0;
-
-#if defined(FEATURE_WINDOWSPHONE)
-CCLRErrorReportingManager g_CLRErrorReportingManager;
-#endif // defined(FEATURE_WINDOWSPHONE)
-
#endif // !DAC
typedef DPTR(CONNID) PTR_CONNID;
@@ -979,48 +970,6 @@ STARTUP_FLAGS CorHost2::GetStartupFlags()
#ifndef DACCESS_COMPILE
-#ifdef FEATURE_COMINTEROP
-
-// Enumerate currently existing domains.
-HRESULT CorRuntimeHostBase::EnumDomains(HDOMAINENUM *hEnum)
-{
- CONTRACTL
- {
- NOTHROW;
- MODE_PREEMPTIVE;
- WRAPPER(GC_TRIGGERS);
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- if(hEnum == NULL) return E_POINTER;
-
- // Thread setup happens in BEGIN_EXTERNAL_ENTRYPOINT below.
- // If the runtime has not started, we have nothing to do.
- if (!g_fEEStarted)
- {
- return HOST_E_CLRNOTAVAILABLE;
- }
-
- HRESULT hr = E_OUTOFMEMORY;
- *hEnum = NULL;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- BEGIN_EXTERNAL_ENTRYPOINT(&hr)
-
- AppDomainIterator *pEnum = new (nothrow) AppDomainIterator(FALSE);
- if(pEnum) {
- *hEnum = (HDOMAINENUM) pEnum;
- hr = S_OK;
- }
- END_EXTERNAL_ENTRYPOINT;
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-#endif // FEATURE_COMINTEROP
-
extern "C"
DLLEXPORT
HRESULT GetCLRRuntimeHost(REFIID riid, IUnknown **ppUnk)
@@ -1341,17 +1290,8 @@ HRESULT CorRuntimeHostBase::MapFile(HANDLE hFile, HMODULE* phHandle)
return hr;
}
-///////////////////////////////////////////////////////////////////////////////
-// IDebuggerInfo::IsDebuggerAttached
-
LONG CorHost2::m_RefCount = 0;
-IHostControl *CorHost2::m_HostControl = NULL;
-
-#ifdef _DEBUG
-extern void ValidateHostInterface();
-#endif
-
static Volatile<BOOL> fOneOnly = 0;
///////////////////////////////////////////////////////////////////////////////
@@ -1359,1068 +1299,16 @@ static Volatile<BOOL> fOneOnly = 0;
///////////////////////////////////////////////////////////////////////////////
HRESULT CorHost2::SetHostControl(IHostControl* pHostControl)
{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
- if (m_Version < 2)
- // CLR is hosted with v1 hosting interface. Some part of v2 hosting API are disabled.
- return HOST_E_INVALIDOPERATION;
-
- if (pHostControl == 0)
- return E_INVALIDARG;
-
- // If Runtime has been started, do not allow setting HostMemoryManager
- if (g_fEEStarted)
- return E_ACCESSDENIED;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- DWORD dwSwitchCount = 0;
-
- while (FastInterlockExchange((LONG*)&fOneOnly, 1) == 1)
- {
- __SwitchToThread(0, ++dwSwitchCount);
- }
-
-
- if (m_HostControl == NULL)
- {
- m_HostControl = pHostControl;
- m_HostControl->AddRef();
- }
-
- goto ErrExit;
-
-ErrExit:
- fOneOnly = 0;
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-class CCLRPolicyManager: public ICLRPolicyManager
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE SetDefaultAction(EClrOperation operation,
- EPolicyAction action)
- {
- LIMITED_METHOD_CONTRACT;
- return E_NOTIMPL;
- }
-
- virtual HRESULT STDMETHODCALLTYPE SetTimeout(EClrOperation operation,
- DWORD dwMilliseconds)
- {
- LIMITED_METHOD_CONTRACT;
- return E_NOTIMPL;
- }
-
- virtual HRESULT STDMETHODCALLTYPE SetActionOnTimeout(EClrOperation operation,
- EPolicyAction action)
- {
- LIMITED_METHOD_CONTRACT;
- return E_NOTIMPL;
- }
-
- virtual HRESULT STDMETHODCALLTYPE SetTimeoutAndAction(EClrOperation operation, DWORD dwMilliseconds,
- EPolicyAction action)
- {
- LIMITED_METHOD_CONTRACT;
- return E_NOTIMPL;
- }
-
- virtual HRESULT STDMETHODCALLTYPE SetActionOnFailure(EClrFailure failure,
- EPolicyAction action)
- {
- // This is enabled for CoreCLR since a host can use this to
- // specify action for handling AV.
- STATIC_CONTRACT_ENTRY_POINT;
- LIMITED_METHOD_CONTRACT;
- HRESULT hr;
- // For CoreCLR, this method just supports FAIL_AccessViolation as a valid
- // failure input arg. The validation of the specified action for the failure
- // will be done in EEPolicy::IsValidActionForFailure.
- if (failure != FAIL_AccessViolation)
- {
- return E_INVALIDARG;
- }
- BEGIN_ENTRYPOINT_NOTHROW;
- hr = GetEEPolicy()->SetActionOnFailure(failure,action);
- END_ENTRYPOINT_NOTHROW;
- return hr;
- }
-
- virtual HRESULT STDMETHODCALLTYPE SetUnhandledExceptionPolicy(EClrUnhandledException policy)
- {
- LIMITED_METHOD_CONTRACT;
- return E_NOTIMPL;
- }
-
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- BEGIN_INTERFACE HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,
- void **ppvObject)
- {
- LIMITED_METHOD_CONTRACT;
- if (riid != IID_ICLRPolicyManager && riid != IID_IUnknown)
- return (E_NOINTERFACE);
-
- // Ensure that the out going pointer is not null
- if (ppvObject == NULL)
- return E_POINTER;
-
- *ppvObject = this;
- return S_OK;
- }
-};
-
-static CCLRPolicyManager s_PolicyManager;
-
-
-
-void ProcessEventForHost(EClrEvent event, void *data)
-{
-}
-
-// We do not call ProcessEventForHost for stack overflow, since we have limit stack
-// and we should avoid calling GCX_PREEMPT
-void ProcessSOEventForHost(EXCEPTION_POINTERS *pExceptionInfo, BOOL fInSoTolerant)
-{
-}
-
-BOOL IsHostRegisteredForEvent(EClrEvent event)
-{
- WRAPPER_NO_CONTRACT;
- return FALSE;
-}
-
-inline size_t SizeInKBytes(size_t cbSize)
-{
- LIMITED_METHOD_CONTRACT;
- size_t cb = (cbSize % 1024) ? 1 : 0;
- return ((cbSize / 1024) + cb);
-}
-
-SIZE_T Host_SegmentSize = 0;
-SIZE_T Host_MaxGen0Size = 0;
-BOOL Host_fSegmentSizeSet = FALSE;
-BOOL Host_fMaxGen0SizeSet = FALSE;
-
-void UpdateGCSettingFromHost ()
-{
- WRAPPER_NO_CONTRACT;
- _ASSERTE (g_pConfig);
- if (Host_fSegmentSizeSet)
- {
- g_pConfig->SetSegmentSize(Host_SegmentSize);
- }
- if (Host_fMaxGen0SizeSet)
- {
- g_pConfig->SetGCgen0size(Host_MaxGen0Size);
- }
-}
-
-#if defined(FEATURE_WINDOWSPHONE)
-class CCLRGCManager: public ICLRGCManager2
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE Collect(LONG Generation)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- if (Generation > (int) GCHeapUtilities::GetGCHeap()->GetMaxGeneration())
- hr = E_INVALIDARG;
-
- if (SUCCEEDED(hr))
- {
- // Set up a Thread object if this is called on a native thread.
- Thread *pThread;
- pThread = GetThread();
- if (pThread == NULL)
- pThread = SetupThreadNoThrow(&hr);
- if (pThread != NULL)
- {
- BEGIN_ENTRYPOINT_NOTHROW_WITH_THREAD(pThread);
- GCX_COOP();
-
- EX_TRY
- {
- STRESS_LOG0(LF_GC, LL_INFO100, "Host triggers GC\n");
- hr = GCHeapUtilities::GetGCHeap()->GarbageCollect(Generation);
- }
- EX_CATCH
- {
- hr = GET_EXCEPTION()->GetHR();
- }
- EX_END_CATCH(SwallowAllExceptions);
-
- END_ENTRYPOINT_NOTHROW_WITH_THREAD;
- }
- }
-
- return (hr);
- }
-
- virtual HRESULT STDMETHODCALLTYPE GetStats(COR_GC_STATS *pStats)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- return E_NOTIMPL;
- }
- virtual HRESULT STDMETHODCALLTYPE SetGCStartupLimits(
- DWORD SegmentSize,
- DWORD MaxGen0Size)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
-
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- // Set default overrides if specified by caller.
- if (SegmentSize != (DWORD) ~0 && SegmentSize > 0)
- {
- hr = _SetGCSegmentSize(SegmentSize);
- }
-
- if (SUCCEEDED(hr) && MaxGen0Size != (DWORD) ~0 && MaxGen0Size > 0)
- {
- hr = _SetGCMaxGen0Size(MaxGen0Size);
- }
-
- END_ENTRYPOINT_NOTHROW;
-
- return (hr);
- }
-
- virtual HRESULT STDMETHODCALLTYPE SetGCStartupLimitsEx(
- SIZE_T SegmentSize,
- SIZE_T MaxGen0Size)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
-
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- // Set default overrides if specified by caller.
- if (SegmentSize != (SIZE_T) ~0 && SegmentSize > 0)
- {
- hr = _SetGCSegmentSize(SegmentSize);
- }
-
- if (SUCCEEDED(hr) && MaxGen0Size != (SIZE_T) ~0 && MaxGen0Size > 0)
- {
- hr = _SetGCMaxGen0Size(MaxGen0Size);
- }
-
- END_ENTRYPOINT_NOTHROW;
-
- return (hr);
- }
-
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, OUT PVOID *ppUnk)
- {
- LIMITED_METHOD_CONTRACT;
- if (riid != IID_ICLRGCManager && riid != IID_ICLRGCManager2 && riid != IID_IUnknown)
- return (E_NOINTERFACE);
- *ppUnk = this;
- return S_OK;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-private:
- HRESULT _SetGCSegmentSize(SIZE_T SegmentSize);
- HRESULT _SetGCMaxGen0Size(SIZE_T MaxGen0Size);
-};
-
-
-HRESULT CCLRGCManager::_SetGCSegmentSize(SIZE_T SegmentSize)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // Sanity check the value, it must be a power of two and big enough.
- if (!GCHeapUtilities::GetGCHeap()->IsValidSegmentSize(SegmentSize))
- {
- hr = E_INVALIDARG;
- }
- else
- {
- Host_SegmentSize = SegmentSize;
- Host_fSegmentSizeSet = TRUE;
- }
-
- return (hr);
-}
-
-HRESULT CCLRGCManager::_SetGCMaxGen0Size(SIZE_T MaxGen0Size)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- // Sanity check the value is at least large enough.
- if (!GCHeapUtilities::GetGCHeap()->IsValidGen0MaxSize(MaxGen0Size))
- {
- hr = E_INVALIDARG;
- }
- else
- {
- Host_MaxGen0Size = MaxGen0Size;
- Host_fMaxGen0SizeSet = TRUE;
- }
-
- return (hr);
+ return E_NOTIMPL;
}
-static CCLRGCManager s_GCManager;
-#endif //FEATURE_WINDOWSPHONE
-
-#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
-class CCLRAppDomainResourceMonitor : public ICLRAppDomainResourceMonitor
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE GetCurrentAllocated(DWORD dwAppDomainId,
- ULONGLONG* pBytesAllocated)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- SystemDomain::LockHolder lh;
-
- AppDomain* pAppDomain = SystemDomain::GetAppDomainFromId((ADID)dwAppDomainId, ADV_CURRENTAD);
- if (pBytesAllocated)
- {
- *pBytesAllocated = pAppDomain->GetAllocBytes();
- }
-
- END_ENTRYPOINT_NOTHROW;
-
- return (hr);
- }
-
- virtual HRESULT STDMETHODCALLTYPE GetCurrentSurvived(DWORD dwAppDomainId,
- ULONGLONG* pAppDomainBytesSurvived,
- ULONGLONG* pTotalBytesSurvived)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- SystemDomain::LockHolder lh;
-
- AppDomain* pAppDomain = SystemDomain::GetAppDomainFromId((ADID)dwAppDomainId, ADV_CURRENTAD);
- if (pAppDomainBytesSurvived)
- {
- *pAppDomainBytesSurvived = pAppDomain->GetSurvivedBytes();
- }
- if (pTotalBytesSurvived)
- {
- *pTotalBytesSurvived = SystemDomain::GetTotalSurvivedBytes();
- }
-
- END_ENTRYPOINT_NOTHROW;
-
- return (hr);
- }
-
- virtual HRESULT STDMETHODCALLTYPE GetCurrentCpuTime(DWORD dwAppDomainId,
- ULONGLONG* pMilliseconds)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_TRIGGERS;
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- {
- SystemDomain::LockHolder lh;
-
- AppDomain* pAppDomain = SystemDomain::GetAppDomainFromId((ADID)dwAppDomainId, ADV_CURRENTAD);
- if (pMilliseconds)
- {
- *pMilliseconds = pAppDomain->QueryProcessorUsage() / 10000;
- }
- }
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
- }
-
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, OUT PVOID *ppUnk)
- {
- LIMITED_METHOD_CONTRACT;
- *ppUnk = NULL;
- if (riid == IID_IUnknown)
- *ppUnk = (IUnknown*)this;
- else if (riid == IID_ICLRAppDomainResourceMonitor)
- *ppUnk = (ICLRAppDomainResourceMonitor*)this;
- else
- return E_NOINTERFACE;
- return S_OK;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-};
-static CCLRAppDomainResourceMonitor s_Arm;
-#endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING
-
-
-BOOL g_CLRPolicyRequested = FALSE;
-
-class CCorCLRControl: public ICLRControl
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE GetCLRManager(REFIID riid, void **ppObject)
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- // Sanity check.
- if (ppObject == NULL)
- return E_INVALIDARG;
-
-#if defined(FEATURE_WINDOWSPHONE)
- if (riid == IID_ICLRErrorReportingManager2)
- {
- *ppObject = &g_CLRErrorReportingManager;
- return S_OK;
- }
- else
-#endif //defined(FEATURE_WINDOWSPHONE)
- if (g_fEEStarted && !m_fFullAccess)
- {
- // If runtime has been started, do not allow user to obtain CLR managers.
- return HOST_E_INVALIDOPERATION;
- }
-
- // CoreCLR supports ICLRPolicyManager since it allows the host
- // to specify the policy for AccessViolation.
- else if (riid == IID_ICLRPolicyManager) {
- *ppObject = &s_PolicyManager;
- FastInterlockExchange((LONG*)&g_CLRPolicyRequested, TRUE);
- return S_OK;
- }
-
-#if defined(FEATURE_WINDOWSPHONE)
- else if ((riid == IID_ICLRGCManager) || (riid == IID_ICLRGCManager2))
- {
- *ppObject = &s_GCManager;
- return S_OK;
- }
-#endif //FEATURE_WINDOWSPHONE
-
-#ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING
- else if (riid == IID_ICLRAppDomainResourceMonitor)
- {
- EnableARM();
- *ppObject = &s_Arm;
- return S_OK;
- }
-#endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING
- else
- return (E_NOINTERFACE);
- }
-
- virtual HRESULT STDMETHODCALLTYPE SetAppDomainManagerType(
- LPCWSTR pwzAppDomainManagerAssembly,
- LPCWSTR pwzAppDomainManagerType)
- {
-
- // CoreCLR does not support this method
- return E_NOTIMPL;
- }
-
- virtual ULONG STDMETHODCALLTYPE AddRef(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- virtual ULONG STDMETHODCALLTYPE Release(void)
- {
- LIMITED_METHOD_CONTRACT;
- return 1;
- }
-
- BEGIN_INTERFACE HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid,
- void **ppvObject)
- {
- LIMITED_METHOD_CONTRACT;
- if (riid != IID_ICLRControl && riid != IID_IUnknown)
- return (E_NOINTERFACE);
-
- // Ensure that the out going pointer is not null
- if (ppvObject == NULL)
- return E_POINTER;
-
- *ppvObject = this;
- return S_OK;
- }
-
- // This is to avoid having ctor. We have static objects, and it is
- // difficult to support ctor on certain platform.
- void SetAccess(BOOL fFullAccess)
- {
- LIMITED_METHOD_CONTRACT;
- m_fFullAccess = fFullAccess;
- }
-private:
- BOOL m_fFullAccess;
-};
-
-// Before CLR starts, we give out s_CorCLRControl which has full access to all managers.
-// After CLR starts, we give out s_CorCLRControlLimited which allows limited access to managers.
-static CCorCLRControl s_CorCLRControl;
-
-
///////////////////////////////////////////////////////////////////////////////
// ICLRRuntimeHost::GetCLRControl
HRESULT CorHost2::GetCLRControl(ICLRControl** pCLRControl)
{
- LIMITED_METHOD_CONTRACT;
-
- // Ensure that we have a valid pointer
- if (pCLRControl == NULL)
- {
- return E_POINTER;
- }
-
- HRESULT hr = S_OK;
-
- STATIC_CONTRACT_ENTRY_POINT;
- BEGIN_ENTRYPOINT_NOTHROW;
- if (!g_fEEStarted && m_Version >= 2)
- {
- s_CorCLRControl.SetAccess(TRUE);
- *pCLRControl = &s_CorCLRControl;
- }
- else
- {
- // If :
- // 1) request comes for interface other than ICLRControl*, OR
- // 2) runtime has already started, OR
- // 3) version is not 2
- //
- // we will return failure and set the out pointer to NULL
- *pCLRControl = NULL;
- if (g_fEEStarted)
- {
- // Return HOST_E_INVALIDOPERATION as per MSDN if runtime has already started
- hr = HOST_E_INVALIDOPERATION;
- }
- else
- {
- hr = E_NOTIMPL;
- }
- }
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-// static
-EInitializeNewDomainFlags CorHost2::GetAppDomainManagerInitializeNewDomainFlags()
-{
- LIMITED_METHOD_CONTRACT;
- return eInitializeNewDomainFlags_None;
-}
-
-
-#endif // !DAC
-
-
-#ifdef DACCESS_COMPILE
-
-
-#endif //DACCESS_COMPILE
-
-#ifndef DACCESS_COMPILE
-
-
-#if defined(FEATURE_WINDOWSPHONE)
-
-HRESULT CCLRErrorReportingManager::QueryInterface(REFIID riid, void** ppUnk)
-{
- if (!ppUnk)
- return E_POINTER;
-
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- if (ppUnk == NULL)
- {
- return E_POINTER;
- }
-
- *ppUnk = 0;
-
- // Deliberately do NOT hand out ICorConfiguration. They must explicitly call
- // GetConfiguration to obtain that interface.
- if (riid == IID_IUnknown)
- {
- *ppUnk = (IUnknown *) this;
- }
- else if (riid == IID_ICLRErrorReportingManager)
- {
- *ppUnk = (ICLRErrorReportingManager *) this;
- }
-#ifdef FEATURE_WINDOWSPHONE
- else if (riid == IID_ICLRErrorReportingManager2)
- {
- *ppUnk = (ICLRErrorReportingManager2 *) this;
- }
-#endif // FEATURE_WINDOWSPHONE
- else
- {
- hr = E_NOINTERFACE;
- }
-
- return hr;
-
-} // HRESULT CCLRErrorReportingManager::QueryInterface()
-
-ULONG CCLRErrorReportingManager::AddRef()
-{
- LIMITED_METHOD_CONTRACT;
- return 1;
-} // HRESULT CCLRErrorReportingManager::AddRef()
-
-ULONG CCLRErrorReportingManager::Release()
-{
- LIMITED_METHOD_CONTRACT;
- return 1;
-} // HRESULT CCLRErrorReportingManager::Release()
-
-// Get Watson bucket parameters for "current" exception (on calling thread).
-HRESULT CCLRErrorReportingManager::GetBucketParametersForCurrentException(
- BucketParameters *pParams)
-{
- CONTRACTL
- {
- WRAPPER(THROWS);
- WRAPPER(GC_TRIGGERS);
- ENTRY_POINT;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
- BEGIN_ENTRYPOINT_NOTHROW;
-
- // To avoid confusion, clear the buckets.
- memset(pParams, 0, sizeof(BucketParameters));
-
-#ifndef FEATURE_PAL
- // Defer to Watson helper.
- hr = ::GetBucketParametersForCurrentException(pParams);
- #else
- // Watson doesn't exist on non-windows platforms
- hr = E_NOTIMPL;
-#endif // !FEATURE_PAL
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-
-} // HRESULT CCLRErrorReportingManager::GetBucketParametersForCurrentException()
-
-//
-// The BeginCustomDump function configures the custom dump support
-//
-// Parameters -
-// dwFlavor - The flavor of the dump
-// dwNumItems - The number of items in the CustomDumpItem array.
-// Should always be zero today, since no custom items are defined
-// items - Array of CustomDumpItem structs specifying items to be added to the dump.
-// Should always be NULL today, since no custom items are defined.
-// dwReserved - reserved for future use. Must be zero today
-//
-HRESULT CCLRErrorReportingManager::BeginCustomDump( ECustomDumpFlavor dwFlavor,
- DWORD dwNumItems,
- CustomDumpItem items[],
- DWORD dwReserved)
-{
- STATIC_CONTRACT_ENTRY_POINT;
- HRESULT hr = S_OK;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- if (dwNumItems != 0 || items != NULL || dwReserved != 0)
- {
- IfFailGo(E_INVALIDARG);
- }
- if (g_ECustomDumpFlavor != DUMP_FLAVOR_Default)
- {
- // BeginCustomDump is called without matching EndCustomDump
- IfFailGo(E_INVALIDARG);
- }
- g_ECustomDumpFlavor = dwFlavor;
-
-ErrExit:
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-//
-// EndCustomDump clears the custom dump configuration
-//
-HRESULT CCLRErrorReportingManager::EndCustomDump()
-{
- STATIC_CONTRACT_ENTRY_POINT;
- // NOT IMPLEMENTED YET
- BEGIN_ENTRYPOINT_NOTHROW;
- g_ECustomDumpFlavor = DUMP_FLAVOR_Default;
- END_ENTRYPOINT_NOTHROW;
-
- return S_OK;
-}
-
-#ifdef FEATURE_WINDOWSPHONE
-HRESULT CopyStringWorker(_Out_ WCHAR** pTarget, WCHAR const* pSource)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (pTarget == NULL || pSource == NULL)
- return E_INVALIDARG;
-
- if (*pTarget)
- delete[] (*pTarget);
-
- // allocate space for the data plus one wchar for NULL
- size_t sourceLen = wcslen(pSource);
- *pTarget = new (nothrow) WCHAR[sourceLen + 1];
-
- if (!(*pTarget))
- return E_OUTOFMEMORY;
-
- errno_t result = wcsncpy_s(*pTarget, sourceLen + 1, pSource, sourceLen);
- _ASSERTE(result == 0);
-
- if (result != 0)
- {
- delete[] (*pTarget);
- *pTarget = NULL;
-
- return E_FAIL;
- }
-
- return S_OK;
-}
-
-CCLRErrorReportingManager::BucketParamsCache::BucketParamsCache(DWORD maxNumParams) : m_pParams(NULL), m_cMaxParams(maxNumParams)
-{
- LIMITED_METHOD_CONTRACT;
-}
-
-CCLRErrorReportingManager::BucketParamsCache::~BucketParamsCache()
-{
- LIMITED_METHOD_CONTRACT;
-
- if (m_pParams)
- {
- for (DWORD i = 0; i < m_cMaxParams; ++i)
- if (m_pParams[i]) delete[] m_pParams[i];
- }
-}
-
-WCHAR const* CCLRErrorReportingManager::BucketParamsCache::GetAt(BucketParameterIndex index)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (index >= InvalidBucketParamIndex)
- {
- _ASSERTE(!"bad bucket parameter index");
- return NULL;
- }
-
- if (!m_pParams)
- return NULL;
-
- return m_pParams[index];
-}
-
-HRESULT CCLRErrorReportingManager::BucketParamsCache::SetAt(BucketParameterIndex index, WCHAR const* val)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (index < 0 || index >= InvalidBucketParamIndex)
- {
- _ASSERTE(!"bad bucket parameter index");
- return E_INVALIDARG;
- }
-
- if (!val)
- return E_INVALIDARG;
-
- if (!m_pParams)
- {
- m_pParams = new (nothrow) WCHAR*[m_cMaxParams];
- if (!m_pParams)
- return E_OUTOFMEMORY;
-
- for (DWORD i = 0; i < m_cMaxParams; ++i)
- m_pParams[i] = NULL;
- }
-
- return CopyStringWorker(&m_pParams[index], val);
-}
-
-HRESULT CCLRErrorReportingManager::CopyToDataCache(_Out_ WCHAR** pTarget, WCHAR const* pSource)
-{
- LIMITED_METHOD_CONTRACT;
-
- return CopyStringWorker(pTarget, pSource);
-}
-
-HRESULT CCLRErrorReportingManager::SetApplicationData(ApplicationDataKey key, WCHAR const* pValue)
-{
- STATIC_CONTRACT_ENTRY_POINT;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- if(g_fEEStarted)
- return HOST_E_INVALIDOPERATION;
-
- if (pValue == NULL || wcslen(pValue) > MAX_LONGPATH)
- return E_INVALIDARG;
-
- HRESULT hr = S_OK;
-
- switch (key)
- {
- case ApplicationID:
- hr = CopyToDataCache(&m_pApplicationId, pValue);
- break;
-
- case InstanceID:
- hr = CopyToDataCache(&m_pInstanceId, pValue);
- break;
-
- default:
- hr = E_INVALIDARG;
- }
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-HRESULT CCLRErrorReportingManager::SetBucketParametersForUnhandledException(BucketParameters const* pBucketParams, DWORD* pCountParams)
-{
- STATIC_CONTRACT_ENTRY_POINT;
-
- BEGIN_ENTRYPOINT_NOTHROW;
-
- if(g_fEEStarted)
- return HOST_E_INVALIDOPERATION;
-
- if (pBucketParams == NULL || pCountParams == NULL || pBucketParams->fInited != TRUE)
- return E_INVALIDARG;
-
- *pCountParams = 0;
-
- if (!m_pBucketParamsCache)
- {
- m_pBucketParamsCache = new (nothrow) BucketParamsCache(InvalidBucketParamIndex);
- if (!m_pBucketParamsCache)
- return E_OUTOFMEMORY;
- }
-
- HRESULT hr = S_OK;
- bool hasOverride = false;
-
- for (DWORD i = 0; i < InvalidBucketParamIndex; ++i)
- {
- if (pBucketParams->pszParams[i][0] != W('\0'))
- {
- hasOverride = true;
- hr = m_pBucketParamsCache->SetAt(static_cast<BucketParameterIndex>(i), pBucketParams->pszParams[i]);
- if (SUCCEEDED(hr))
- *pCountParams += 1;
- else
- break;
- }
- }
-
- if (!hasOverride)
- return E_INVALIDARG;
-
- END_ENTRYPOINT_NOTHROW;
-
- return hr;
-}
-
-WCHAR const* CCLRErrorReportingManager::GetApplicationData(ApplicationDataKey key)
-{
- LIMITED_METHOD_CONTRACT;
-
- WCHAR* pValue = NULL;
-
- switch (key)
- {
- case ApplicationID:
- pValue = m_pApplicationId;
- break;
-
- case InstanceID:
- pValue = m_pInstanceId;
- break;
-
- default:
- _ASSERTE(!"invalid key specified");
- }
-
- return pValue;
-}
-
-WCHAR const* CCLRErrorReportingManager::GetBucketParamOverride(BucketParameterIndex bucketParamId)
-{
- LIMITED_METHOD_CONTRACT;
-
- if (!m_pBucketParamsCache)
- return NULL;
-
- return m_pBucketParamsCache->GetAt(bucketParamId);
-}
-
-#endif // FEATURE_WINDOWSPHONE
-
-CCLRErrorReportingManager::CCLRErrorReportingManager()
-{
- LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_WINDOWSPHONE
- m_pApplicationId = NULL;
- m_pInstanceId = NULL;
- m_pBucketParamsCache = NULL;
-#endif
-}
-
-CCLRErrorReportingManager::~CCLRErrorReportingManager()
-{
- LIMITED_METHOD_CONTRACT;
-#ifdef FEATURE_WINDOWSPHONE
- if (m_pApplicationId)
- delete[] m_pApplicationId;
-
- if (m_pInstanceId)
- delete[] m_pInstanceId;
-
- if (m_pBucketParamsCache)
- delete m_pBucketParamsCache;
-#endif
+ return E_NOTIMPL;
}
-#endif // defined(FEATURE_WINDOWSPHONE)
-
void GetProcessMemoryLoad(LPMEMORYSTATUSEX pMSEX)
{
CONTRACTL
diff --git a/src/vm/crossgencompile.cpp b/src/vm/crossgencompile.cpp
index 1380c1fe77..d357bd7622 100644
--- a/src/vm/crossgencompile.cpp
+++ b/src/vm/crossgencompile.cpp
@@ -113,10 +113,6 @@ GVAL_IMPL_INIT(DWORD, g_fHostConfig, 0);
GVAL_IMPL_INIT(GCHeapType, g_heap_type, GC_HEAP_WKS);
-void UpdateGCSettingFromHost()
-{
-}
-
HRESULT GetExceptionHResult(OBJECTREF throwable)
{
return E_FAIL;
diff --git a/src/vm/dbginterface.h b/src/vm/dbginterface.h
index a75974a600..13231c0f5f 100644
--- a/src/vm/dbginterface.h
+++ b/src/vm/dbginterface.h
@@ -343,9 +343,6 @@ public:
virtual HRESULT UpdateSpecialThreadList(DWORD cThreadArrayLength,
DWORD *rgdwThreadIDArray) = 0;
- // Updates the pointer for the debugger services
- virtual void SetIDbgThreadControl(IDebuggerThreadControl *pIDbgThreadControl) = 0;
-
virtual DWORD GetRCThreadId(void) = 0;
virtual HRESULT GetVariablesFromOffset(MethodDesc *pMD,
diff --git a/src/vm/dwbucketmanager.hpp b/src/vm/dwbucketmanager.hpp
index 2e37e1be5e..0095eb6a1c 100644
--- a/src/vm/dwbucketmanager.hpp
+++ b/src/vm/dwbucketmanager.hpp
@@ -458,17 +458,7 @@ void BaseBucketParamsManager::PopulateBucketParameter(BucketParameterIndex param
// verify that we haven't already written data to this param
_ASSERTE(targetParam && targetParam[0] == W('\0'));
-#ifdef FEATURE_WINDOWSPHONE
- WCHAR const* overrideParam = g_CLRErrorReportingManager.GetBucketParamOverride(paramIndex);
- if (overrideParam != NULL)
- {
- CopyStringToBucket(targetParam, maxLength, overrideParam, false);
- }
- else
-#endif // FEATURE_WINDOWSPHONE
- {
- (this->*pFnDataPopulator)(targetParam, maxLength);
- }
+ (this->*pFnDataPopulator)(targetParam, maxLength);
LogParam(targetParam, paramIndex);
}
diff --git a/src/vm/ecalllist.h b/src/vm/ecalllist.h
index 35fbae2160..b4f9895301 100644
--- a/src/vm/ecalllist.h
+++ b/src/vm/ecalllist.h
@@ -163,10 +163,6 @@ FCFuncStart(gEnvironmentFuncs)
FCFuncElementSig("FailFast", &gsig_SM_Str_Exception_Str_RetVoid, SystemNative::FailFastWithExceptionAndSource)
FCFuncEnd()
-FCFuncStart(gSerializationFuncs)
- FCFuncElement("nativeGetUninitializedObject", ReflectionSerialization::GetUninitializedObject)
-FCFuncEnd()
-
FCFuncStart(gExceptionFuncs)
FCFuncElement("IsImmutableAgileException", ExceptionNative::IsImmutableAgileException)
FCFuncElement("nIsTransient", ExceptionNative::IsTransient)
@@ -268,6 +264,7 @@ FCFuncStart(gCOMTypeHandleFuncs)
FCFuncElement("Allocate", RuntimeTypeHandle::Allocate) //for A.CI
FCFuncElement("CompareCanonicalHandles", RuntimeTypeHandle::CompareCanonicalHandles)
FCIntrinsic("GetValueInternal", RuntimeTypeHandle::GetValueInternal, CORINFO_INTRINSIC_RTH_GetValueInternal)
+ FCFuncElement("IsEquivalentTo", RuntimeTypeHandle::IsEquivalentTo)
FCFuncEnd()
FCFuncStart(gMetaDataImport)
@@ -918,6 +915,7 @@ FCFuncStart(gRuntimeHelpers)
FCFuncElement("Equals", ObjectNative::Equals)
FCFuncElement("EnsureSufficientExecutionStack", ReflectionInvocation::EnsureSufficientExecutionStack)
FCFuncElement("TryEnsureSufficientExecutionStack", ReflectionInvocation::TryEnsureSufficientExecutionStack)
+ FCFuncElement("GetUninitializedObjectInternal", ReflectionSerialization::GetUninitializedObject)
FCFuncEnd()
FCFuncStart(gContextSynchronizationFuncs)
@@ -1195,7 +1193,6 @@ FCClassElement("EventPipeInternal", "System.Diagnostics.Tracing", gEventPipeInte
#endif // FEATURE_PERFTRACING
FCClassElement("Exception", "System", gExceptionFuncs)
FCClassElement("FileLoadException", "System.IO", gFileLoadExceptionFuncs)
-FCClassElement("FormatterServices", "System.Runtime.Serialization", gSerializationFuncs)
FCClassElement("GC", "System", gGCInterfaceFuncs)
FCClassElement("GCHandle", "System.Runtime.InteropServices", gGCHandleFuncs)
FCClassElement("GCSettings", "System.Runtime", gGCSettingsFuncs)
diff --git a/src/vm/eeconfig.cpp b/src/vm/eeconfig.cpp
index a3a636ddf4..b5da7def9b 100644
--- a/src/vm/eeconfig.cpp
+++ b/src/vm/eeconfig.cpp
@@ -122,8 +122,6 @@ LPUTF8 NarrowWideChar(__inout_z LPWSTR str)
RETURN NULL;
}
-extern void UpdateGCSettingFromHost ();
-
HRESULT EEConfig::Setup()
{
STANDARD_VM_CONTRACT;
@@ -144,8 +142,6 @@ HRESULT EEConfig::Setup()
_ASSERTE(pConfigOld == NULL && "EEConfig::Setup called multiple times!");
- UpdateGCSettingFromHost();
-
return S_OK;
}
@@ -310,9 +306,6 @@ HRESULT EEConfig::Init()
szZapBBInstr = NULL;
szZapBBInstrDir = NULL;
- fAppDomainUnload = true;
- dwADURetryCount=1000;
-
#ifdef _DEBUG
// interop logging
m_pTraceIUnknown = NULL;
@@ -1097,17 +1090,6 @@ HRESULT EEConfig::sync()
fExpandAllOnLoad = (GetConfigDWORD_DontUse_(CLRConfig::INTERNAL_ExpandAllOnLoad, fExpandAllOnLoad) != 0);
#endif //_DEBUG
-
-#ifdef AD_NO_UNLOAD
- fAppDomainUnload = (CLRConfig::GetConfigValue(CLRConfig::INTERNAL_AppDomainNoUnload) == 0);
-#endif
- dwADURetryCount=GetConfigDWORD_DontUse_(CLRConfig::EXTERNAL_ADURetryCount, dwADURetryCount);
- if (dwADURetryCount==(DWORD)-1)
- {
- _ASSERTE(!"Reserved value");
- dwADURetryCount=(DWORD)-2;
- }
-
#ifdef ENABLE_STARTUP_DELAY
{
//I want this string in decimal
diff --git a/src/vm/eeconfig.h b/src/vm/eeconfig.h
index 20dde06604..dc6725fb44 100644
--- a/src/vm/eeconfig.h
+++ b/src/vm/eeconfig.h
@@ -505,13 +505,6 @@ public:
return fProbeForStackOverflow;
}
- inline bool AppDomainUnload() const
- {LIMITED_METHOD_CONTRACT; return fAppDomainUnload; }
-
- inline DWORD AppDomainUnloadRetryCount() const
- {LIMITED_METHOD_CONTRACT; return dwADURetryCount; }
-
-
#ifdef _DEBUG
inline bool AppDomainLeaks() const
{
@@ -866,10 +859,6 @@ private: //----------------------------------------------------------------
unsigned int DoubleArrayToLargeObjectHeapThreshold; // double arrays of more than this number of elems go in large object heap
#endif
- bool fAppDomainUnload; // Enable appdomain unloading
-
- DWORD dwADURetryCount;
-
#ifdef _DEBUG
bool fExpandAllOnLoad; // True if we want to load all types/jit all methods in an assembly
// at load time.
@@ -1152,8 +1141,6 @@ public:
#endif
-extern BOOL g_CLRPolicyRequested;
-
// NGENImagesAllowed is the safe way to determine if NGEN Images are allowed to be loaded. (Defined as
// a macro instead of an inlined function to avoid compilation errors due to dependent
// definitions not being available to this header.)
diff --git a/src/vm/eepolicy.cpp b/src/vm/eepolicy.cpp
index 22d196bca6..bba511a275 100644
--- a/src/vm/eepolicy.cpp
+++ b/src/vm/eepolicy.cpp
@@ -455,9 +455,7 @@ void SafeExitProcess(UINT exitCode, BOOL fAbort = FALSE, ShutdownCompleteAction
GCX_PREEMP_NO_DTOR();
FastInterlockExchange((LONG*)&g_fForbidEnterEE, TRUE);
-
- ProcessEventForHost(Event_ClrDisabled, NULL);
-
+
// Note that for free and retail builds StressLog must also be enabled
if (g_pConfig && g_pConfig->StressLog())
{
@@ -504,7 +502,7 @@ void SafeExitProcess(UINT exitCode, BOOL fAbort = FALSE, ShutdownCompleteAction
if (sca == SCA_ExitProcessWhenShutdownComplete)
{
// disabled because if we fault in this code path we will trigger our
- // Watson code via EntryPointFilter which is THROWS (see Dev11 317016)
+ // Watson code
CONTRACT_VIOLATION(ThrowsViolation);
#ifdef FEATURE_PAL
@@ -580,7 +578,6 @@ void DisableRuntime(ShutdownCompleteAction sca)
GCX_PREEMP_NO_DTOR();
- ProcessEventForHost(Event_ClrDisabled, NULL);
ClrFlsClearThreadType(ThreadType_Shutdown);
if (g_pDebugInterface != NULL)
@@ -757,12 +754,7 @@ void EEPolicy::HandleStackOverflow(StackOverflowDetector detector, void * pLimit
if (pThread == NULL)
{
- //_ASSERTE (detector != SOD_ManagedFrameHandler);
- // ProcessSOEventForHost(NULL, FALSE);
-
// For security reason, it is not safe to continue execution if stack overflow happens
- // unless a host tells us to do something different.
- // EEPolicy::HandleFatalStackOverflow(NULL);
return;
}
@@ -771,8 +763,6 @@ void EEPolicy::HandleStackOverflow(StackOverflowDetector detector, void * pLimit
_ASSERTE(exceptionInfo.ExceptionRecord);
- ProcessSOEventForHost(&exceptionInfo, false /* fInSoTolerant */);
-
EEPolicy::HandleFatalStackOverflow(&exceptionInfo);
}
diff --git a/src/vm/eventpipe.cpp b/src/vm/eventpipe.cpp
index c2db06de8c..4de0b3c943 100644
--- a/src/vm/eventpipe.cpp
+++ b/src/vm/eventpipe.cpp
@@ -798,6 +798,7 @@ void EventPipe::WriteEventInternal(EventPipeEvent &event, EventPipeEventPayload
payload.GetSize(),
pActivityId,
pRelatedActivityId);
+ instance.EnsureStack(*s_pSession);
if(s_pFile != NULL)
{
diff --git a/src/vm/eventpipe.h b/src/vm/eventpipe.h
index 3f5919f13f..c77b94dbdc 100644
--- a/src/vm/eventpipe.h
+++ b/src/vm/eventpipe.h
@@ -20,7 +20,6 @@ class EventPipeBufferManager;
class EventPipeEventSource;
class EventPipeProvider;
class MethodDesc;
-class SampleProfilerEventInstance;
struct EventPipeProviderConfiguration;
class EventPipeSession;
diff --git a/src/vm/eventpipebuffer.cpp b/src/vm/eventpipebuffer.cpp
index 1149427798..6cc901cb7b 100644
--- a/src/vm/eventpipebuffer.cpp
+++ b/src/vm/eventpipebuffer.cpp
@@ -67,12 +67,12 @@ bool EventPipeBuffer::WriteEvent(Thread *pThread, EventPipeSession &session, Eve
return false;
}
- // Calculate the location of the data payload.
- BYTE *pDataDest = m_pCurrent + sizeof(EventPipeEventInstance);
-
bool success = true;
EX_TRY
{
+ // Calculate the location of the data payload.
+ BYTE *pDataDest = payload.GetSize() == 0 ? NULL : m_pCurrent + sizeof(EventPipeEventInstance);
+
// Placement-new the EventPipeEventInstance.
// if pthread is NULL, it's likely we are running in something like a GC thread which is not a Thread object, so it can't have an activity ID set anyway
EventPipeEventInstance *pInstance = new (m_pCurrent) EventPipeEventInstance(
@@ -83,7 +83,7 @@ bool EventPipeBuffer::WriteEvent(Thread *pThread, EventPipeSession &session, Eve
payload.GetSize(),
(pThread == NULL) ? NULL : pActivityId,
pRelatedActivityId);
-
+ pInstance->EnsureStack(session); // TODO: Perform the stackwalk before the constructor
// Copy the stack if a separate stack trace was provided.
if(pStack != NULL)
@@ -175,9 +175,17 @@ EventPipeEventInstance* EventPipeBuffer::GetNext(EventPipeEventInstance *pEvent,
return NULL;
}
- // We have a pointer within the bounds of the buffer.
- // Find the next event by skipping the current event with it's data payload immediately after the instance.
- pNextInstance = (EventPipeEventInstance *)GetNextAlignedAddress(const_cast<BYTE *>(pEvent->GetData() + pEvent->GetDataLength()));
+ if (pEvent->GetData())
+ {
+ // We have a pointer within the bounds of the buffer.
+ // Find the next event by skipping the current event with it's data payload immediately after the instance.
+ pNextInstance = (EventPipeEventInstance *)GetNextAlignedAddress(const_cast<BYTE *>(pEvent->GetData() + pEvent->GetDataLength()));
+ }
+ else
+ {
+ // In case we do not have a payload, the next instance is right after the current instance
+ pNextInstance = (EventPipeEventInstance*)GetNextAlignedAddress((BYTE*)(pEvent + 1));
+ }
// Check to see if we've reached the end of the written portion of the buffer.
if((BYTE*)pNextInstance >= m_pCurrent)
diff --git a/src/vm/eventpipeconfiguration.cpp b/src/vm/eventpipeconfiguration.cpp
index d40f2b789e..9cf8280722 100644
--- a/src/vm/eventpipeconfiguration.cpp
+++ b/src/vm/eventpipeconfiguration.cpp
@@ -505,6 +505,7 @@ EventPipeEventInstance* EventPipeConfiguration::BuildEventMetadataEvent(EventPip
instancePayloadSize,
NULL /* pActivityId */,
NULL /* pRelatedActivityId */);
+ _ASSERTE(!m_pMetadataEvent->NeedStack());
// Set the timestamp to match the source event, because the metadata event
// will be emitted right before the source event.
diff --git a/src/vm/eventpipeeventinstance.cpp b/src/vm/eventpipeeventinstance.cpp
index 1424dbc94c..f1e5919bd2 100644
--- a/src/vm/eventpipeeventinstance.cpp
+++ b/src/vm/eventpipeeventinstance.cpp
@@ -34,7 +34,7 @@ EventPipeEventInstance::EventPipeEventInstance(
#endif // _DEBUG
m_pEvent = &event;
m_threadID = threadID;
- if(pActivityId != NULL)
+ if (pActivityId != NULL)
{
m_activityId = *pActivityId;
}
@@ -42,7 +42,7 @@ EventPipeEventInstance::EventPipeEventInstance(
{
m_activityId = {0};
}
- if(pRelatedActivityId != NULL)
+ if (pRelatedActivityId != NULL)
{
m_relatedActivityId = *pRelatedActivityId;
}
@@ -55,15 +55,17 @@ EventPipeEventInstance::EventPipeEventInstance(
m_dataLength = length;
QueryPerformanceCounter(&m_timeStamp);
_ASSERTE(m_timeStamp.QuadPart > 0);
+#ifdef _DEBUG
+ EnsureConsistency();
+#endif // _DEBUG
+}
- if(event.NeedStack() && !session.RundownEnabled())
+void EventPipeEventInstance::EnsureStack(const EventPipeSession &session)
+{
+ if (m_pEvent->NeedStack() && !session.RundownEnabled())
{
EventPipe::WalkManagedStackForCurrentThread(m_stackContents);
}
-
-#ifdef _DEBUG
- EnsureConsistency();
-#endif // _DEBUG
}
unsigned int EventPipeEventInstance::GetAlignedTotalSize() const
@@ -155,10 +157,4 @@ bool EventPipeEventInstance::EnsureConsistency()
}
#endif // _DEBUG
-SampleProfilerEventInstance::SampleProfilerEventInstance(EventPipeSession &session, EventPipeEvent &event, Thread *pThread, BYTE *pData, unsigned int length)
- :EventPipeEventInstance(session, event, pThread->GetOSThreadId(), pData, length, NULL /* pActivityId */, NULL /* pRelatedActivityId */)
-{
- LIMITED_METHOD_CONTRACT;
-}
-
#endif // FEATURE_PERFTRACING
diff --git a/src/vm/eventpipeeventinstance.h b/src/vm/eventpipeeventinstance.h
index 47f1b5c35b..80fd49d946 100644
--- a/src/vm/eventpipeeventinstance.h
+++ b/src/vm/eventpipeeventinstance.h
@@ -23,6 +23,8 @@ public:
EventPipeEventInstance(EventPipeSession &session, EventPipeEvent &event, DWORD threadID, BYTE *pData, unsigned int length, LPCGUID pActivityId, LPCGUID pRelatedActivityId);
+ void EnsureStack(const EventPipeSession &session);
+
StackContents* GetStack()
{
LIMITED_METHOD_CONTRACT;
@@ -138,17 +140,6 @@ private:
void SetTimeStamp(LARGE_INTEGER timeStamp);
};
-// A specific type of event instance for use by the SampleProfiler.
-// This is needed because the SampleProfiler knows how to walk stacks belonging
-// to threads other than the current thread.
-class SampleProfilerEventInstance : public EventPipeEventInstance
-{
-
-public:
-
- SampleProfilerEventInstance(EventPipeSession &session, EventPipeEvent &event, Thread *pThread, BYTE *pData, unsigned int length);
-};
-
#endif // FEATURE_PERFTRACING
#endif // __EVENTPIPE_EVENTINSTANCE_H__
diff --git a/src/vm/excep.cpp b/src/vm/excep.cpp
index 2d5a1601b5..8f5cc089c3 100644
--- a/src/vm/excep.cpp
+++ b/src/vm/excep.cpp
@@ -2755,13 +2755,6 @@ VOID DECLSPEC_NORETURN RaiseTheException(OBJECTREF throwable, BOOL rethrow
EEPOLICY_HANDLE_FATAL_ERROR(COR_E_EXECUTIONENGINE);
}
- if (g_CLRPolicyRequested &&
- throwable->GetMethodTable() == g_pOutOfMemoryExceptionClass)
- {
- // We depends on UNINSTALL_UNWIND_AND_CONTINUE_HANDLER to handle out of memory escalation.
- // We should throw c++ exception instead.
- ThrowOutOfMemory();
- }
_ASSERTE(throwable != CLRException::GetPreallocatedStackOverflowException());
#ifdef FEATURE_CORRUPTING_EXCEPTIONS
@@ -3007,13 +3000,6 @@ static VOID DECLSPEC_NORETURN RealCOMPlusThrowWorker(OBJECTREF throwable, BOOL r
// Unfortunately, COMPlusFrameHandler installed here, will try to create managed exception object.
// We may hit a recursion.
- if (g_CLRPolicyRequested &&
- throwable->GetMethodTable() == g_pOutOfMemoryExceptionClass)
- {
- // We depends on UNINSTALL_UNWIND_AND_CONTINUE_HANDLER to handle out of memory escalation.
- // We should throw c++ exception instead.
- ThrowOutOfMemory();
- }
_ASSERTE(throwable != CLRException::GetPreallocatedStackOverflowException());
// TODO: Do we need to install COMPlusFrameHandler here?
@@ -5771,7 +5757,7 @@ static LONG ThreadBaseExceptionFilter_Worker(PEXCEPTION_POINTERS pExceptionInfo,
{
// No, don't swallow unhandled exceptions...
- // ...except if the exception is of a type that is always swallowed (ThreadAbort, AppDomainUnload)...
+ // ...except if the exception is of a type that is always swallowed (ThreadAbort, ...)
if (ExceptionIsAlwaysSwallowed(pExceptionInfo))
{ // ...return EXCEPTION_EXECUTE_HANDLER to swallow the exception anyway.
return EXCEPTION_EXECUTE_HANDLER;
@@ -6562,7 +6548,7 @@ LONG FilterAccessViolation(PEXCEPTION_POINTERS pExceptionPointers, LPVOID lpvPar
}
/*
- * IsContinuableException
+ * IsInterceptableException
*
* Returns whether this is an exception the EE knows how to intercept and continue from.
*
@@ -8287,19 +8273,6 @@ VOID DECLSPEC_NORETURN UnwindAndContinueRethrowHelperAfterCatch(Frame* pEntryFra
Exception::Delete(pException);
- if (orThrowable != NULL && g_CLRPolicyRequested)
- {
- if (orThrowable->GetMethodTable() == g_pOutOfMemoryExceptionClass)
- {
- EEPolicy::HandleOutOfMemory();
- }
- else if (orThrowable->GetMethodTable() == g_pStackOverflowExceptionClass)
- {
- /* The parameters of the function do not matter here */
- EEPolicy::HandleStackOverflow(SOD_UnmanagedFrameHandler, NULL);
- }
- }
-
RaiseTheExceptionInternalOnly(orThrowable, FALSE);
}
diff --git a/src/vm/excep.h b/src/vm/excep.h
index 3568d2415f..cc4e97f07f 100644
--- a/src/vm/excep.h
+++ b/src/vm/excep.h
@@ -732,8 +732,6 @@ BOOL IsInFirstFrameOfHandler(Thread *pThread,
//==========================================================================
LONG FilterAccessViolation(PEXCEPTION_POINTERS pExceptionPointers, LPVOID lpvParam);
-bool IsContinuableException(Thread *pThread);
-
bool IsInterceptableException(Thread *pThread);
#ifdef DEBUGGING_SUPPORTED
diff --git a/src/vm/fieldmarshaler.cpp b/src/vm/fieldmarshaler.cpp
index 5e231f700d..6d4ff96c12 100644
--- a/src/vm/fieldmarshaler.cpp
+++ b/src/vm/fieldmarshaler.cpp
@@ -56,133 +56,6 @@ static const NFTDataBaseEntry NFTDataBase[] =
#include "nsenums.h"
};
-
-//=======================================================================
-// This is invoked from the class loader while building the internal structures for a type
-// This function should check if explicit layout metadata exists.
-//
-// Returns:
-// TRUE - yes, there's layout metadata
-// FALSE - no, there's no layout.
-// fail - throws a typeload exception
-//
-// If TRUE,
-// *pNLType gets set to nltAnsi or nltUnicode
-// *pPackingSize declared packing size
-// *pfExplicitoffsets offsets explicit in metadata or computed?
-//=======================================================================
-BOOL HasLayoutMetadata(Assembly* pAssembly, IMDInternalImport *pInternalImport, mdTypeDef cl, MethodTable*pParentMT, BYTE *pPackingSize, BYTE *pNLTType, BOOL *pfExplicitOffsets)
-{
- CONTRACTL
- {
- THROWS;
- GC_TRIGGERS;
- MODE_ANY;
- PRECONDITION(CheckPointer(pInternalImport));
- PRECONDITION(CheckPointer(pPackingSize));
- PRECONDITION(CheckPointer(pNLTType));
- PRECONDITION(CheckPointer(pfExplicitOffsets));
- }
- CONTRACTL_END;
-
- HRESULT hr;
- ULONG clFlags;
-#ifdef _DEBUG
- clFlags = 0xcccccccc;
-#endif
-
- if (FAILED(pInternalImport->GetTypeDefProps(cl, &clFlags, NULL)))
- {
- pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT);
- }
-
- if (IsTdAutoLayout(clFlags))
- {
- // <BUGNUM>workaround for B#104780 - VC fails to set SequentialLayout on some classes
- // with ClassSize. Too late to fix compiler for V1.
- //
- // To compensate, we treat AutoLayout classes as Sequential if they
- // meet all of the following criteria:
- //
- // - ClassSize present and nonzero.
- // - No instance fields declared
- // - Base class is System.ValueType.
- //</BUGNUM>
- ULONG cbTotalSize = 0;
- if (SUCCEEDED(pInternalImport->GetClassTotalSize(cl, &cbTotalSize)) && cbTotalSize != 0)
- {
- if (pParentMT && pParentMT->IsValueTypeClass())
- {
- MDEnumHolder hEnumField(pInternalImport);
- if (SUCCEEDED(pInternalImport->EnumInit(mdtFieldDef, cl, &hEnumField)))
- {
- ULONG numFields = pInternalImport->EnumGetCount(&hEnumField);
- if (numFields == 0)
- {
- *pfExplicitOffsets = FALSE;
- *pNLTType = nltAnsi;
- *pPackingSize = 1;
- return TRUE;
- }
- }
- }
- }
-
- return FALSE;
- }
- else if (IsTdSequentialLayout(clFlags))
- {
- *pfExplicitOffsets = FALSE;
- }
- else if (IsTdExplicitLayout(clFlags))
- {
- *pfExplicitOffsets = TRUE;
- }
- else
- {
- pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT);
- }
-
- // We now know this class has seq. or explicit layout. Ensure the parent does too.
- if (pParentMT && !(pParentMT->IsObjectClass() || pParentMT->IsValueTypeClass()) && !(pParentMT->HasLayout()))
- pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT);
-
- if (IsTdAnsiClass(clFlags))
- {
- *pNLTType = nltAnsi;
- }
- else if (IsTdUnicodeClass(clFlags))
- {
- *pNLTType = nltUnicode;
- }
- else if (IsTdAutoClass(clFlags))
- {
- // We no longer support Win9x so TdAuto always maps to Unicode.
- *pNLTType = nltUnicode;
- }
- else
- {
- pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT);
- }
-
- DWORD dwPackSize;
- hr = pInternalImport->GetClassPackSize(cl, &dwPackSize);
- if (FAILED(hr) || dwPackSize == 0)
- dwPackSize = DEFAULT_PACKING_SIZE;
-
- // This has to be reduced to a BYTE value, so we had better make sure it fits. If
- // not, we'll throw an exception instead of trying to munge the value to what we
- // think the user might want.
- if (!FitsInU1((UINT64)(dwPackSize)))
- {
- pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT);
- }
-
- *pPackingSize = (BYTE)dwPackSize;
-
- return TRUE;
-}
-
#ifdef _PREFAST_
#pragma warning(push)
#pragma warning(disable:21000) // Suppress PREFast warning about overly large function
diff --git a/src/vm/fieldmarshaler.h b/src/vm/fieldmarshaler.h
index e83835844a..e3eba6cd6d 100644
--- a/src/vm/fieldmarshaler.h
+++ b/src/vm/fieldmarshaler.h
@@ -119,25 +119,6 @@ VOID ParseNativeType(Module* pModule,
BOOL IsFieldBlittable(FieldMarshaler* pFM);
//=======================================================================
-// This is invoked from the class loader while building the data structures for a type.
-// This function checks if explicit layout metadata exists.
-//
-// Returns:
-// TRUE - yes, there's layout metadata
-// FALSE - no, there's no layout.
-// fail - throws a typeload exception
-//
-// If S_OK,
-// *pNLType gets set to nltAnsi or nltUnicode
-// *pPackingSize declared packing size
-// *pfExplicitoffsets offsets explicit in metadata or computed?
-//=======================================================================
-BOOL HasLayoutMetadata(Assembly* pAssembly, IMDInternalImport *pInternalImport, mdTypeDef cl,
- MethodTable *pParentMT, BYTE *pPackingSize, BYTE *pNLTType,
- BOOL *pfExplicitOffsets);
-
-
-//=======================================================================
// This function returns TRUE if the type passed in is either a value class or a class and if it has layout information
// and is marshalable. In all other cases it will return FALSE.
//=======================================================================
diff --git a/src/vm/gcenv.ee.cpp b/src/vm/gcenv.ee.cpp
index f27d3f32c8..7788022374 100644
--- a/src/vm/gcenv.ee.cpp
+++ b/src/vm/gcenv.ee.cpp
@@ -1558,3 +1558,50 @@ void GCToEEInterface::VerifySyncTableEntry()
SyncBlockCache::GetSyncBlockCache()->VerifySyncTableEntry();
#endif // VERIFY_HEAP
}
+
+void GCToEEInterface::UpdateGCEventStatus(int currentPublicLevel, int currentPublicKeywords, int currentPrivateLevel, int currentPrivateKeywords)
+{
+#if defined(__linux__)
+ LIMITED_METHOD_CONTRACT;
+ // LTTng does not have a notion of enabling events via "keyword"/"level" but we have to
+ // somehow implement a similar behavior to it.
+
+ // To do this, we manaully check for events that are enabled via different provider/keywords/level.
+ // Ex 1. GCJoin_V2 is what we use to check whether the GC keyword is enabled in verbose level in the public provider
+ // Ex 2. SetGCHandle is what we use to check whether the GCHandle keyword is enabled in informational level in the public provider
+ // Refer to the comments in src/vm/gcenv.ee.h next to the EXTERN C definitions to see which events are enabled.
+
+ // WARNING: To change an event's GC level, perfcollect script needs to be updated simultaneously to reflect it.
+ BOOL keyword_gc_verbose = EventXplatEnabledGCJoin_V2();
+ BOOL keyword_gc_informational = EventXplatEnabledGCStart();
+
+ BOOL keyword_gc_heapsurvival_and_movement_informational = EventXplatEnabledGCGenerationRange();
+ BOOL keyword_gchandle_informational = EventXplatEnabledSetGCHandle();
+ BOOL keyword_gchandle_prv_informational = EventXplatEnabledPrvSetGCHandle();
+
+ BOOL prv_gcprv_informational = EventXplatEnabledBGCBegin();
+ BOOL prv_gcprv_verbose = EventXplatEnabledPinPlugAtGCTime();
+
+ int publicProviderLevel = keyword_gc_verbose ? GCEventLevel_Verbose : (keyword_gc_informational ? GCEventLevel_Information : GCEventLevel_None);
+ int publicProviderKeywords = (keyword_gc_informational ? GCEventKeyword_GC : GCEventKeyword_None) |
+ (keyword_gchandle_informational ? GCEventKeyword_GCHandle : GCEventKeyword_None) |
+ (keyword_gc_heapsurvival_and_movement_informational ? GCEventKeyword_GCHeapSurvivalAndMovement : GCEventKeyword_None);
+
+ int privateProviderLevel = prv_gcprv_verbose ? GCEventLevel_Verbose : (prv_gcprv_informational ? GCEventLevel_Information : GCEventLevel_None);
+ int privateProviderKeywords = (prv_gcprv_informational ? GCEventKeyword_GCPrivate : GCEventKeyword_None) |
+ (keyword_gchandle_prv_informational ? GCEventKeyword_GCHandlePrivate : GCEventKeyword_None);
+
+ if (publicProviderLevel != currentPublicLevel || publicProviderKeywords != currentPublicKeywords)
+ {
+ GCEventLevel publicLevel = static_cast<GCEventLevel>(publicProviderLevel);
+ GCEventKeyword publicKeywords = static_cast<GCEventKeyword>(publicProviderKeywords);
+ GCHeapUtilities::RecordEventStateChange(true, publicKeywords, publicLevel);
+ }
+ if (privateProviderLevel != currentPrivateLevel || privateProviderKeywords != currentPrivateKeywords)
+ {
+ GCEventLevel privateLevel = static_cast<GCEventLevel>(privateProviderLevel);
+ GCEventKeyword privateKeywords = static_cast<GCEventKeyword>(privateProviderKeywords);
+ GCHeapUtilities::RecordEventStateChange(false, privateKeywords, privateLevel);
+ }
+#endif // __linux__
+}
diff --git a/src/vm/gcenv.ee.h b/src/vm/gcenv.ee.h
index 08f9021640..0b542ef291 100644
--- a/src/vm/gcenv.ee.h
+++ b/src/vm/gcenv.ee.h
@@ -9,6 +9,19 @@
#ifdef FEATURE_STANDALONE_GC
+#if defined(__linux__)
+extern "C" BOOL EventXplatEnabledGCStart(); // GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GC
+extern "C" BOOL EventXPlatEnabledGCJoin_V2(); // GCEventProvider_Default, GCEventLevel_Verbose, GCEventKeyword_GC
+
+extern "C" BOOL EventXplatEnabledGCGenerationRange(); // GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GCHeapSurvivalAndMovement
+
+extern "C" BOOL EventXplatEnabledSetGCHandle(); // GCEventProvider_Default, GCEventLevel_Information, GCEventKeyword_GCHandle
+extern "C" BOOL EventXplatEnabledPrvSetGCHandle();; // GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCHandlePrivate
+
+extern "C" BOOL EventXplatEnabledBGCBegin(); // GCEventProvider_Private, GCEventLevel_Information, GCEventKeyword_GCPrivate
+extern "C" BOOL EventXplatEnabledPinPlugAtGCTime(); // GCEventProvider_Private, GCEventLevel_Verbose, GCEventKeyword_GC
+#endif // __linux__
+
namespace standalone
{
@@ -74,6 +87,8 @@ public:
void AnalyzeSurvivorsFinished(int condemnedGeneration);
void VerifySyncTableEntry();
+
+ void UpdateGCEventStatus(int publicLevel, int publicKeywords, int privateLevel, int privateKeywords);
};
} // namespace standalone
diff --git a/src/vm/hosting.cpp b/src/vm/hosting.cpp
index 720a691478..5b447221bd 100644
--- a/src/vm/hosting.cpp
+++ b/src/vm/hosting.cpp
@@ -10,189 +10,12 @@
#include "hosting.h"
#include "mscoree.h"
-#include "mscoreepriv.h"
#include "corhost.h"
#include "threads.h"
#define countof(x) (sizeof(x) / sizeof(x[0]))
-//Copied from winbase.h
-#ifndef STARTF_TITLEISAPPID
-#define STARTF_TITLEISAPPID 0x00001000
-#endif
-#ifndef STARTF_PREVENTPINNING
-#define STARTF_PREVENTPINNING 0x00002000
-#endif
-
-//Flags encoded in the first parameter of CorLaunchApplication.
-#define MASK_NOTPINNABLE 0x80000000
-#define MASK_HOSTTYPE 0x00000003
-#define MASK_DONT_SHOW_INSTALL_DIALOG 0x00000100
-
-#ifdef _DEBUG
-// This function adds a static annotation read by SCAN to indicate HOST_CALLS. Its
-// purpose is to be called from the BEGIN_SO_TOLERANT_CODE_CALLING_HOST macro, to
-// effectively mark all functions that use BEGIN_SO_TOLERANT_CODE_CALLING_HOST as being
-// HOST_CALLS. If you hit a SCAN violation that references AddHostCallsStaticMarker, then
-// you have a function marked as HOST_NOCALLS that eventually calls into a function that
-// uses BEGIN_SO_TOLERANT_CODE_CALLING_HOST.
-DEBUG_NOINLINE void AddHostCallsStaticMarker()
-{
- STATIC_CONTRACT_NOTHROW;
- STATIC_CONTRACT_CANNOT_TAKE_LOCK;
- STATIC_CONTRACT_GC_NOTRIGGER;
- STATIC_CONTRACT_HOST_CALLS;
-
- METHOD_CANNOT_BE_FOLDED_DEBUG;
-}
-#endif //_DEBUG
-
-//
-// memory management functions
-//
-
-// global debug only tracking utilities
-#ifdef _DEBUG
-
-static const LONG MaxGlobalAllocCount = 8;
-
-class GlobalAllocStore {
-public:
- static void AddAlloc (LPVOID p)
- {
- LIMITED_METHOD_CONTRACT;
-
- if (!p) {
- return;
- }
- if (m_Disabled) {
- return;
- }
-
- //InterlockedIncrement (&numMemWriter);
- //if (CheckMemFree) {
- // goto Return;
- //}
-
- //m_Count is number of allocation we've ever tried, it's OK to be bigger than
- //size of m_Alloc[]
- InterlockedIncrement (&m_Count);
-
- //this is by no means an accurate record of heap allocation.
- //the algorithm used here can't guarantee an allocation is saved in
- //m_Alloc[] even there's enough free space. However this is only used
- //for debugging purpose and most importantly, m_Count is accurate.
- for (size_t n = 0; n < countof(m_Alloc); n ++) {
- if (m_Alloc[n] == 0) {
- if (InterlockedCompareExchangeT(&m_Alloc[n],p,0) == 0) {
- return;
- }
- }
- }
-
- //InterlockedDecrement (&numMemWriter);
- }
-
- //this is called in non-host case where we don't care the free after
- //alloc store is disabled
- static BOOL RemoveAlloc (LPVOID p)
- {
- LIMITED_METHOD_CONTRACT;
-
- if (m_Disabled)
- {
- return TRUE;
- }
- //decrement the counter even we might not find the allocation
- //in m_Alloc. Because it's possible for an allocation not to be saved
- //in the array
- InterlockedDecrement (&m_Count);
- // Binary search
- for (size_t n = 0; n < countof(m_Alloc); n ++) {
- if (m_Alloc[n] == p) {
- m_Alloc[n] = 0;
- return TRUE;
- }
- }
- return FALSE;
- }
-
- //this is called in host case where if the store is disabled, we want to
- //guarantee we don't try to free anything the host doesn't know about
- static void ValidateFree(LPVOID p)
- {
- LIMITED_METHOD_CONTRACT;
-
- if (p == 0) {
- return;
- }
- if (m_Disabled) {
- for (size_t n = 0; n < countof(m_Alloc); n ++) {
- //there could be miss, because an allocation might not be saved
- //in the array
- if (m_Alloc[n] == p) {
- _ASSERTE (!"Free a memory that host interface does not know");
- return;
- }
- }
- }
- }
-
- static void Validate()
- {
- LIMITED_METHOD_CONTRACT;
-
- if (m_Count > MaxGlobalAllocCount) {
- _ASSERTE (!"Using too many memory allocator before Host Interface is set up");
- }
-
- //while (numMemWriter != 0) {
- // Sleep(5);
- //}
- //qsort (GlobalMemAddr, (MemAllocCount>MaxAllocCount)?MaxAllocCount:MemAllocCount, sizeof(LPVOID), MemAddrCompare);
- }
-
- static void Disable ()
- {
- LIMITED_METHOD_CONTRACT;
- if (!m_Disabled)
- {
- // Let all threads know
- InterlockedIncrement((LONG*)&m_Disabled);
- }
- }
-
-private:
- static BOOL m_Disabled;
- static LPVOID m_Alloc[MaxGlobalAllocCount];
- //m_Count is number of allocation we tried, it's legal to be bigger than
- //size of m_Alloc[]
- static LONG m_Count;
- // static LONG numMemWriter = 0;
-};
-
-// used from corhost.cpp
-void ValidateHostInterface()
-{
- WRAPPER_NO_CONTRACT;
-
- GlobalAllocStore::Validate();
- GlobalAllocStore::Disable();
-}
-
-void DisableGlobalAllocStore ()
-{
- WRAPPER_NO_CONTRACT;
- GlobalAllocStore::Disable();
-}
-LPVOID GlobalAllocStore::m_Alloc[MaxGlobalAllocCount];
-LONG GlobalAllocStore::m_Count = 0;
-BOOL GlobalAllocStore::m_Disabled = FALSE;
-
-#endif
-
-
HANDLE g_ExecutableHeapHandle = NULL;
@@ -255,10 +78,6 @@ LPVOID EEVirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocationType, D
p = ::VirtualAlloc (lpAddress, dwSize, flAllocationType, flProtect);
}
-#ifdef _DEBUG
- GlobalAllocStore::AddAlloc (p);
-#endif
-
if(p == NULL){
STRESS_LOG_OOM_STACK(dwSize);
}
@@ -278,17 +97,7 @@ BOOL EEVirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType) {
}
CONTRACTL_END;
- BOOL retVal = FALSE;
-
- {
-#ifdef _DEBUG
- GlobalAllocStore::RemoveAlloc (lpAddress);
-#endif
-
- retVal = (BOOL)(BYTE)::VirtualFree (lpAddress, dwSize, dwFreeType);
- }
-
- return retVal;
+ return (BOOL)(BYTE)::VirtualFree (lpAddress, dwSize, dwFreeType);
}
#define VirtualFree(lpAddress, dwSize, dwFreeType) Dont_Use_VirtualFree(lpAddress, dwSize, dwFreeType)
@@ -408,7 +217,6 @@ LPVOID EEHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes)
*((HANDLE*)p) = hHeap;
p = (BYTE*)p + OS_HEAP_ALIGN;
}
- GlobalAllocStore::AddAlloc (p);
#else
p = ::HeapAlloc (hHeap, dwFlags, dwBytes);
#endif
@@ -455,8 +263,6 @@ BOOL EEHeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)
{
#ifdef _DEBUG
- GlobalAllocStore::RemoveAlloc (lpMem);
-
if (lpMem != NULL)
{
// Check the heap handle to detect heap contamination
diff --git a/src/vm/jithelpers.cpp b/src/vm/jithelpers.cpp
index 0144d960d9..04de717cce 100644
--- a/src/vm/jithelpers.cpp
+++ b/src/vm/jithelpers.cpp
@@ -4828,11 +4828,6 @@ HCIMPL1(void, IL_Throw, Object* obj)
}
else
{ // We know that the object derives from System.Exception
- if (g_CLRPolicyRequested &&
- oref->GetMethodTable() == g_pOutOfMemoryExceptionClass)
- {
- EEPolicy::HandleOutOfMemory();
- }
// If the flag indicating ForeignExceptionRaise has been set,
// then do not clear the "_stackTrace" field of the exception object.
@@ -4882,12 +4877,6 @@ HCIMPL0(void, IL_Rethrow)
OBJECTREF throwable = GetThread()->GetThrowable();
if (throwable != NULL)
{
- if (g_CLRPolicyRequested &&
- throwable->GetMethodTable() == g_pOutOfMemoryExceptionClass)
- {
- EEPolicy::HandleOutOfMemory();
- }
-
RaiseTheExceptionInternalOnly(throwable, TRUE);
}
else
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index 31f6d1a78a..42975b6537 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -5295,6 +5295,7 @@ void CEEInfo::getCallInfo(
//
MethodDesc * pTargetMD = pMDAfterConstraintResolution;
+ DWORD dwTargetMethodAttrs = pTargetMD->GetAttrs();
if (pTargetMD->HasMethodInstantiation())
{
@@ -5352,12 +5353,6 @@ void CEEInfo::getCallInfo(
directCall = true;
}
else
- // Backwards compat: calls to abstract interface methods are treated as callvirt
- if (pTargetMD->GetMethodTable()->IsInterface() && pTargetMD->IsAbstract())
- {
- directCall = false;
- }
- else
if (!(flags & CORINFO_CALLINFO_CALLVIRT) || fResolvedConstraint)
{
directCall = true;
@@ -5398,12 +5393,11 @@ void CEEInfo::getCallInfo(
if (pTargetMD->GetMethodTable()->IsInterface())
{
// Handle interface methods specially because the Sealed bit has no meaning on interfaces.
- devirt = !IsMdVirtual(pTargetMD->GetAttrs());
+ devirt = !IsMdVirtual(dwTargetMethodAttrs);
}
else
{
- DWORD dwMethodAttrs = pTargetMD->GetAttrs();
- devirt = !IsMdVirtual(dwMethodAttrs) || IsMdFinal(dwMethodAttrs) || pTargetMD->GetMethodTable()->IsSealed();
+ devirt = !IsMdVirtual(dwTargetMethodAttrs) || IsMdFinal(dwTargetMethodAttrs) || pTargetMD->GetMethodTable()->IsSealed();
}
if (devirt)
@@ -5415,6 +5409,14 @@ void CEEInfo::getCallInfo(
if (directCall)
{
+ // Direct calls to abstract methods are not allowed
+ if (IsMdAbstract(dwTargetMethodAttrs) &&
+ // Compensate for always treating delegates as direct calls above
+ !(((flags & CORINFO_CALLINFO_LDFTN) && (flags & CORINFO_CALLINFO_CALLVIRT) && !resolvedCallVirt)))
+ {
+ COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL);
+ }
+
bool allowInstParam = (flags & CORINFO_CALLINFO_ALLOWINSTPARAM);
// Create instantiating stub if necesary
diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp
index 72aa6f5cf6..d0045411db 100644
--- a/src/vm/methodtablebuilder.cpp
+++ b/src/vm/methodtablebuilder.cpp
@@ -11839,6 +11839,94 @@ MethodTableBuilder::GatherGenericsInfo(
bmtGenericsInfo->typeContext = typeContext;
} // MethodTableBuilder::GatherGenericsInfo
+//=======================================================================
+// This is invoked from the class loader while building the internal structures for a type
+// This function should check if explicit layout metadata exists.
+//
+// Returns:
+// TRUE - yes, there's layout metadata
+// FALSE - no, there's no layout.
+// fail - throws a typeload exception
+//
+// If TRUE,
+// *pNLType gets set to nltAnsi or nltUnicode
+// *pPackingSize declared packing size
+// *pfExplicitoffsets offsets explicit in metadata or computed?
+//=======================================================================
+BOOL HasLayoutMetadata(Assembly* pAssembly, IMDInternalImport* pInternalImport, mdTypeDef cl, MethodTable* pParentMT, BYTE* pPackingSize, BYTE* pNLTType, BOOL* pfExplicitOffsets)
+{
+ CONTRACTL
+ {
+ THROWS;
+ GC_TRIGGERS;
+ MODE_ANY;
+ PRECONDITION(CheckPointer(pInternalImport));
+ PRECONDITION(CheckPointer(pPackingSize));
+ PRECONDITION(CheckPointer(pNLTType));
+ PRECONDITION(CheckPointer(pfExplicitOffsets));
+ }
+ CONTRACTL_END;
+
+ HRESULT hr;
+ ULONG clFlags;
+
+ if (FAILED(pInternalImport->GetTypeDefProps(cl, &clFlags, NULL)))
+ {
+ pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT);
+ }
+
+ if (IsTdAutoLayout(clFlags))
+ {
+ return FALSE;
+ }
+ else if (IsTdSequentialLayout(clFlags))
+ {
+ *pfExplicitOffsets = FALSE;
+ }
+ else if (IsTdExplicitLayout(clFlags))
+ {
+ *pfExplicitOffsets = TRUE;
+ }
+ else
+ {
+ pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT);
+ }
+
+ // We now know this class has seq. or explicit layout. Ensure the parent does too.
+ if (pParentMT && !(pParentMT->IsObjectClass() || pParentMT->IsValueTypeClass()) && !(pParentMT->HasLayout()))
+ pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT);
+
+ if (IsTdAnsiClass(clFlags))
+ {
+ *pNLTType = nltAnsi;
+ }
+ else if (IsTdUnicodeClass(clFlags) || IsTdAutoClass(clFlags))
+ {
+ *pNLTType = nltUnicode;
+ }
+ else
+ {
+ pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT);
+ }
+
+ DWORD dwPackSize;
+ hr = pInternalImport->GetClassPackSize(cl, &dwPackSize);
+ if (FAILED(hr) || dwPackSize == 0)
+ dwPackSize = DEFAULT_PACKING_SIZE;
+
+ // This has to be reduced to a BYTE value, so we had better make sure it fits. If
+ // not, we'll throw an exception instead of trying to munge the value to what we
+ // think the user might want.
+ if (!FitsInU1((UINT64)(dwPackSize)))
+ {
+ pAssembly->ThrowTypeLoadException(pInternalImport, cl, IDS_CLASSLOAD_BADFORMAT);
+ }
+
+ *pPackingSize = (BYTE)dwPackSize;
+
+ return TRUE;
+}
+
//---------------------------------------------------------------------------------------
//
// This service is called for normal classes -- and for the pseudo class we invent to
diff --git a/src/vm/reflectioninvocation.cpp b/src/vm/reflectioninvocation.cpp
index a69f5439c2..1f8aa04593 100644
--- a/src/vm/reflectioninvocation.cpp
+++ b/src/vm/reflectioninvocation.cpp
@@ -2581,10 +2581,6 @@ FCIMPL1(Object*, ReflectionSerialization::GetUninitializedObject, ReflectClassBa
HELPER_METHOD_FRAME_BEGIN_RET_NOPOLL();
- if (objType == NULL) {
- COMPlusThrowArgumentNull(W("type"), W("ArgumentNull_Type"));
- }
-
TypeHandle type = objType->GetType();
// Don't allow arrays, pointers, byrefs or function pointers.
diff --git a/src/vm/runtimehandles.cpp b/src/vm/runtimehandles.cpp
index dda5d1d139..c8782db7ef 100644
--- a/src/vm/runtimehandles.cpp
+++ b/src/vm/runtimehandles.cpp
@@ -250,6 +250,25 @@ FCIMPL1_V(EnregisteredTypeHandle, RuntimeTypeHandle::GetValueInternal, FCALLRunt
}
FCIMPLEND
+FCIMPL2(FC_BOOL_RET, RuntimeTypeHandle::IsEquivalentTo, ReflectClassBaseObject *rtType1UNSAFE, ReflectClassBaseObject *rtType2UNSAFE)
+{
+ FCALL_CONTRACT;
+
+ REFLECTCLASSBASEREF rtType1 = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(rtType1UNSAFE);
+ REFLECTCLASSBASEREF rtType2 = (REFLECTCLASSBASEREF)ObjectToOBJECTREF(rtType2UNSAFE);
+
+ BOOL areEquivalent = FALSE;
+ HELPER_METHOD_FRAME_BEGIN_RET_2(rtType1, rtType2);
+
+ if (rtType1 != NULL && rtType2 != NULL)
+ areEquivalent = rtType1->GetType().IsEquivalentTo(rtType2->GetType());
+
+ HELPER_METHOD_FRAME_END();
+
+ FC_RETURN_BOOL(areEquivalent);
+}
+FCIMPLEND
+
// TypeEqualsHelper and TypeNotEqualsHelper are almost identical.
// Unfortunately we cannot combime them because they need to hardcode the caller's name
NOINLINE static BOOL TypeEqualSlow(OBJECTREF refL, OBJECTREF refR, LPVOID __me)
diff --git a/src/vm/runtimehandles.h b/src/vm/runtimehandles.h
index 6edf61ec99..66a27f4626 100644
--- a/src/vm/runtimehandles.h
+++ b/src/vm/runtimehandles.h
@@ -152,6 +152,8 @@ public:
static FCDECL1_V(ReflectClassBaseObject*, GetTypeFromHandle, FCALLRuntimeTypeHandle th);
static FCDECL1_V(EnregisteredTypeHandle, GetValueInternal, FCALLRuntimeTypeHandle RTH);
+ static FCDECL2(FC_BOOL_RET, IsEquivalentTo, ReflectClassBaseObject *rtType1UNSAFE, ReflectClassBaseObject *rtType2UNSAFE);
+
static FCDECL2(FC_BOOL_RET, TypeEQ, Object* left, Object* right);
static FCDECL2(FC_BOOL_RET, TypeNEQ, Object* left, Object* right);
diff --git a/src/vm/sampleprofiler.h b/src/vm/sampleprofiler.h
index 871b175604..00c20f3b5a 100644
--- a/src/vm/sampleprofiler.h
+++ b/src/vm/sampleprofiler.h
@@ -22,7 +22,6 @@ class SampleProfiler
// Declare friends.
friend class EventPipe;
- friend class SampleProfilerEventInstance;
public:
diff --git a/src/vm/stdinterfaces.cpp b/src/vm/stdinterfaces.cpp
index 285f65f8e9..1a9d0e2db1 100644
--- a/src/vm/stdinterfaces.cpp
+++ b/src/vm/stdinterfaces.cpp
@@ -26,7 +26,6 @@
#include "field.h"
#include "threads.h"
#include "interoputil.h"
-#include "tlbexport.h"
#include "comdelegate.h"
#include "olevariant.h"
#include "eeconfig.h"
diff --git a/src/vm/stdinterfaces.h b/src/vm/stdinterfaces.h
index aa79d72eca..3ac0d5e3f2 100644
--- a/src/vm/stdinterfaces.h
+++ b/src/vm/stdinterfaces.h
@@ -48,7 +48,6 @@ public:
class Assembly;
class Module;
class MethodTable;
-struct ITypeLibExporterNotifySink;
typedef HRESULT (__stdcall* PCOMFN)(void);
@@ -62,16 +61,6 @@ typedef HRESULT (__stdcall* PCOMFN)(void);
extern BYTE g_UnmarshalSecret[sizeof(GUID)];
extern bool g_fInitedUnmarshalSecret;
-struct ExportTypeLibFromLoadedAssembly_Args
-{
- Assembly* pAssembly;
- LPCWSTR szTlb;
- ITypeLib** ppTlb;
- ITypeLibExporterNotifySink* pINotify;
- int flags;
- HRESULT hr;
-};
-
// make sure to keep the following enum and the g_stdVtables array in sync
enum Enum_StdInterfaces
{
diff --git a/src/vm/stdinterfaces_wrapper.cpp b/src/vm/stdinterfaces_wrapper.cpp
index cf0b1e6b74..429fef99ee 100644
--- a/src/vm/stdinterfaces_wrapper.cpp
+++ b/src/vm/stdinterfaces_wrapper.cpp
@@ -25,7 +25,6 @@
#include "field.h"
#include "threads.h"
#include "interoputil.h"
-#include "tlbexport.h"
#include "comdelegate.h"
#include "olevariant.h"
#include "eeconfig.h"
diff --git a/src/vm/threads.cpp b/src/vm/threads.cpp
index 53707759a4..bffd81edfc 100644
--- a/src/vm/threads.cpp
+++ b/src/vm/threads.cpp
@@ -7802,8 +7802,6 @@ static LONG ThreadBaseRedirectingFilter(PEXCEPTION_POINTERS pExceptionInfo, LPVO
STATIC_CONTRACT_GC_TRIGGERS;
STATIC_CONTRACT_MODE_ANY;
- LONG (*ptrFilter) (PEXCEPTION_POINTERS, PVOID);
-
TryParam * pRealParam = reinterpret_cast<TryParam *>(pParam);
ManagedThreadCallState * _pCallState = pRealParam->m_pCallState;
@@ -7811,12 +7809,10 @@ static LONG ThreadBaseRedirectingFilter(PEXCEPTION_POINTERS pExceptionInfo, LPVO
// This will invoke the swallowing filter. If that returns EXCEPTION_CONTINUE_SEARCH,
// it will trigger unhandled exception processing.
- ptrFilter = ThreadBaseExceptionAppDomainFilter;
-
- // WARNING - ptrFilter may not return
+ // WARNING - ThreadBaseExceptionAppDomainFilter may not return
// This occurs when the debugger decides to intercept an exception and catch it in a frame closer
// to the leaf than the one executing this filter
- ret = (*ptrFilter) (pExceptionInfo, _pCallState);
+ ret = ThreadBaseExceptionAppDomainFilter(pExceptionInfo, _pCallState);
// Although EXCEPTION_EXECUTE_HANDLER can also be returned in cases corresponding to
// unhandled exceptions, all of those cases have already notified the debugger of an unhandled
@@ -7834,43 +7830,32 @@ static LONG ThreadBaseRedirectingFilter(PEXCEPTION_POINTERS pExceptionInfo, LPVO
Thread *pCurThread = GetThread();
_ASSERTE(pCurThread);
+ //
+ // In the default domain, when an exception goes unhandled on a managed thread whose threadbase is in the VM (e.g. explicitly spawned threads,
+ // ThreadPool threads, finalizer thread, etc), CLR can end up in the unhandled exception processing path twice.
+ //
+ // The first attempt to perform UE processing happens at the managed thread base (via this function). When it completes,
+ // we will set TSNC_ProcessedUnhandledException state against the thread to indicate that we have perform the unhandled exception processing.
+ //
+ // On CoreSys CoreCLR, the host can ask CoreCLR to run all code in the default domain. As a result, when we return from the first attempt to perform UE
+ // processing, the call could return back with EXCEPTION_EXECUTE_HANDLER since, like desktop CoreCLR is instructed by SL host to swallow all unhandled exceptions,
+ // CoreSys CoreCLR can also be instructed by its Phone host to swallow all unhandled exceptions. As a result, the exception dispatch will never continue to go upstack
+ // to the native threadbase in the OS kernel and thus, there will never be a second attempt to perform UE processing. Hence, we dont, and shouldnt, need to set
+ // TSNC_ProcessedUnhandledException state against the thread if we are in SingleAppDomain mode and have been asked to swallow the exception.
+ //
+ // If we continue to set TSNC_ProcessedUnhandledException and a ThreadPool Thread A has an exception go unhandled, we will swallow it correctly for the first time.
+ // The next time Thread A has an exception go unhandled, our UEF will see TSNC_ProcessedUnhandledException set and assume (incorrectly) UE processing has happened and
+ // will fail to honor the host policy (e.g. swallow unhandled exception). Thus, the 2nd unhandled exception may end up crashing the app when it should not.
+ //
+ if (ret != EXCEPTION_EXECUTE_HANDLER)
{
LOG((LF_EH, LL_INFO100, "ThreadBaseRedirectingFilter: setting TSNC_ProcessedUnhandledException\n"));
+ // Since we have already done unhandled exception processing for it, we dont want it
+ // to happen again if our UEF gets invoked upon returning back to the OS.
//
- // In the default domain, when an exception goes unhandled on a managed thread whose threadbase is in the VM (e.g. explicitly spawned threads,
- // ThreadPool threads, finalizer thread, etc), CLR can end up in the unhandled exception processing path twice.
- //
- // The first attempt to perform UE processing happens at the managed thread base (via this function). When it completes,
- // we will set TSNC_ProcessedUnhandledException state against the thread to indicate that we have perform the unhandled exception processing.
- //
- // On the desktop CLR, after the first attempt, we will return back to the OS with EXCEPTION_CONTINUE_SEARCH as unhandled exceptions cannot be swallowed. When the exception reaches
- // the native threadbase in the OS kernel, the OS will invoke the UEF registered for the process. This can result in CLR's UEF (COMUnhandledExceptionFilter)
- // getting invoked that will attempt to perform UE processing yet again for the same thread. To avoid this duplicate processing, we check the presence of
- // TSNC_ProcessedUnhandledException state on the thread and if present, we simply return back to the OS.
- //
- // On desktop CoreCLR, we will only do UE processing once (at the managed threadbase) since no thread is created in default domain - all are created and executed in non-default domain.
- // As a result, we go via completely different codepath that prevents duplication of UE processing from happening, especially since desktop CoreCLR is targetted for SL and SL
- // always passes us a flag to swallow unhandled exceptions.
- //
- // On CoreSys CoreCLR, the host can ask CoreCLR to run all code in the default domain. As a result, when we return from the first attempt to perform UE
- // processing, the call could return back with EXCEPTION_EXECUTE_HANDLER since, like desktop CoreCLR is instructed by SL host to swallow all unhandled exceptions,
- // CoreSys CoreCLR can also be instructed by its Phone host to swallow all unhandled exceptions. As a result, the exception dispatch will never continue to go upstack
- // to the native threadbase in the OS kernel and thus, there will never be a second attempt to perform UE processing. Hence, we dont, and shouldnt, need to set
- // TSNC_ProcessedUnhandledException state against the thread if we are in SingleAppDomain mode and have been asked to swallow the exception.
- //
- // If we continue to set TSNC_ProcessedUnhandledException and a ThreadPool Thread A has an exception go unhandled, we will swallow it correctly for the first time.
- // The next time Thread A has an exception go unhandled, our UEF will see TSNC_ProcessedUnhandledException set and assume (incorrectly) UE processing has happened and
- // will fail to honor the host policy (e.g. swallow unhandled exception). Thus, the 2nd unhandled exception may end up crashing the app when it should not.
- //
- if (ret != EXCEPTION_EXECUTE_HANDLER)
- {
- // Since we have already done unhandled exception processing for it, we dont want it
- // to happen again if our UEF gets invoked upon returning back to the OS.
- //
- // Set the flag to indicate so.
- pCurThread->SetThreadStateNC(Thread::TSNC_ProcessedUnhandledException);
- }
+ // Set the flag to indicate so.
+ pCurThread->SetThreadStateNC(Thread::TSNC_ProcessedUnhandledException);
}
return ret;
diff --git a/src/vm/tlbexport.h b/src/vm/tlbexport.h
deleted file mode 100644
index 32db10b7aa..0000000000
--- a/src/vm/tlbexport.h
+++ /dev/null
@@ -1,484 +0,0 @@
-// 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.
-//===========================================================================
-// File: TlbExport.h
-//
-
-//
-// Notes: Create a TypeLib from COM+ metadata.
-//---------------------------------------------------------------------------
-
-
-#ifndef FEATURE_COMINTEROP
-#error FEATURE_COMINTEROP is required for this file
-#endif // FEATURE_COMINTEROP
-
-class ITypeCreateTypeLib2;
-struct ICreateTypeInfo2;
-struct ITypeInfo;
-struct ITypeLibExporterNotifySink;
-
-class CDescPool;
-struct ComMTMethodProps;
-class ComMTMemberInfoMap;
-
-static LPCSTR szVariantClassFullQual = g_VariantClassName;
-
-//*************************************************************************
-// Helper functions.
-//*************************************************************************
-HRESULT Utf2Quick(
- LPCUTF8 pStr, // The string to convert.
- CQuickArray<WCHAR> &rStr, // The QuickArray<WCHAR> to convert it into.
- int iCurLen = 0); // Inital characters in the array to leave (default 0).
-
-//*****************************************************************************
-// Signature utilities.
-//*****************************************************************************
-class MetaSigExport : public MetaSig
-{
-public:
- MetaSigExport(MethodDesc *pMD) :
- MetaSig(pMD)
- {
- WRAPPER_NO_CONTRACT;
- }
-
- BOOL IsVbRefType()
- {
- CONTRACT (BOOL)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACT_END;
-
- // Get the arg, and skip decorations.
- SigPointer pt = GetArgProps();
- CorElementType mt;
- if (FAILED(pt.PeekElemType(&mt)))
- return FALSE;
-
- while (mt == ELEMENT_TYPE_BYREF || mt == ELEMENT_TYPE_PTR)
- {
- // Eat the one just examined, and peek at the next one.
- if (FAILED(pt.GetElemType(NULL)) || FAILED(pt.PeekElemType(&mt)))
- return FALSE;
- }
-
- // Is it just Object?
- if (mt == ELEMENT_TYPE_OBJECT)
- RETURN TRUE;
-
- // A particular class?
- if (mt == ELEMENT_TYPE_CLASS)
- {
- // Exclude "string".
- if (pt.IsStringType(m_pModule, GetSigTypeContext()))
- RETURN FALSE;
- RETURN TRUE;
- }
-
- // A particular valuetype?
- if (mt == ELEMENT_TYPE_VALUETYPE)
- {
- // Include "variant".
- if (pt.IsClass(m_pModule, szVariantClassFullQual, GetSigTypeContext()))
- RETURN TRUE;
- RETURN FALSE;
- }
-
- // An array, a string, or POD.
- RETURN FALSE;
- }
-}; // class MetaSigExport : public MetaSig
-
-
-//*************************************************************************
-// Class to convert COM+ metadata to a TypeLib.
-//*************************************************************************
-class TypeLibExporter
-{
-private:
- class CExportedTypesInfo
- {
- public:
- MethodTable* pClass; // The class being exported.
- ICreateTypeInfo2* pCTI; // The ICreateTypeInfo2 for the EE class.
- ICreateTypeInfo2* pCTIClassItf; // The ICreateTypeInfo2 for the IClassX.
- TYPEKIND tkind; // Typekind of the exported class.
- bool bAutoProxy; // If true, oleaut32 is the interface's proxy.
- };
-
- class CExportedTypesHash : public CClosedHashEx<CExportedTypesInfo, CExportedTypesHash>
- {
- protected:
- friend class CSortByToken;
- friend class CSortByName;
-
- class CSortByToken : public CQuickSort<CExportedTypesInfo*>
- {
- public:
- CSortByToken(CExportedTypesInfo **pBase, int iCount) :
- CQuickSort<CExportedTypesInfo*>(pBase, iCount)
- {
- WRAPPER_NO_CONTRACT;
- }
- virtual int Compare(CExportedTypesInfo **ps1, CExportedTypesInfo **ps2);
- };
-
- class CSortByName : public CQuickSort<CExportedTypesInfo*>
- {
- public:
- CSortByName(CExportedTypesInfo **pBase, int iCount) :
- CQuickSort<CExportedTypesInfo*>(pBase, iCount)
- {
- WRAPPER_NO_CONTRACT;
- }
- virtual int Compare(CExportedTypesInfo **ps1, CExportedTypesInfo **ps2);
- };
-
- public:
- typedef CClosedHashEx<CExportedTypesInfo, CExportedTypesHash> Base;
- typedef CExportedTypesInfo T;
-
- CExportedTypesHash() :
- Base(1009),
- m_iCount(0),
- m_Array(NULL)
- {
- WRAPPER_NO_CONTRACT;
- }
-
- ~CExportedTypesHash()
- {
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
- Clear();
- delete[] m_Array;
- }
-
- virtual void Clear();
-
- unsigned int Hash(const T *pData);
- unsigned int Compare(const T *p1, T *p2);
- ELEMENTSTATUS Status(T *p);
- void SetStatus(T *p, ELEMENTSTATUS s);
- void* GetKey(T *p);
-
- //@todo: move to CClosedHashEx
- T* GetFirst()
- {
- WRAPPER_NO_CONTRACT;
- return (T*)CClosedHashBase::GetFirst();
- }
- T* GetNext(T*prev)
- {
- WRAPPER_NO_CONTRACT;
- return (T*)CClosedHashBase::GetNext((BYTE*)prev);
- }
-
- void InitArray();
- void UpdateArray();
-
- T* operator[](ULONG ix)
- {
- CONTRACT (T*)
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- PRECONDITION(ix < m_iCount);
- POSTCONDITION(CheckPointer(RETVAL));
- }
- CONTRACT_END;
-
- RETURN m_Array[ix];
- }
- int Count()
- {
- LIMITED_METHOD_CONTRACT;
- return m_iCount;
- }
-
- void SortByName();
- void SortByToken();
-
- protected:
- CExportedTypesInfo** m_Array;
- ULONG m_iCount;
- };
-
-protected:
- struct CErrorContext;
-
- class CHrefOfTIHashKey
- {
- public:
- ITypeInfo* pITI;
- HREFTYPE href;
- };
-
- class CHrefOfTIHash : public CClosedHash<class CHrefOfTIHashKey>
- {
- public:
- typedef CHrefOfTIHashKey T;
-
- CHrefOfTIHash() :
- CClosedHash<class CHrefOfTIHashKey>(101)
- {
- WRAPPER_NO_CONTRACT;
- }
- ~CHrefOfTIHash()
- {
- CONTRACTL { NOTHROW; } CONTRACTL_END;
- Clear();
- }
-
- virtual void Clear();
-
- unsigned int Hash(const T *pData);
- unsigned int Hash(const void *pData)
- {
- WRAPPER_NO_CONTRACT;
- return Hash((const T*)pData);
- }
-
- unsigned int Compare(const T *p1, T *p2);
- unsigned int Compare(const void *p1, BYTE *p2)
- {
- WRAPPER_NO_CONTRACT;
- return Compare((const T*)p1, (T*)p2);
- }
-
- ELEMENTSTATUS Status(T *p);
- ELEMENTSTATUS Status(BYTE *p)
- {
- WRAPPER_NO_CONTRACT;
- return Status((T*)p);
- }
-
- void SetStatus(T *p, ELEMENTSTATUS s);
- void SetStatus(BYTE *p, ELEMENTSTATUS s)
- {
- WRAPPER_NO_CONTRACT;
- SetStatus((T*)p, s);
- }
-
- void *GetKey(T *p);
- void* GetKey(BYTE *p)
- {
- WRAPPER_NO_CONTRACT;
- return GetKey((T*)p);
- }
- };
-
- class CHrefOfClassHashKey
- {
- public:
- MethodTable* pClass;
- HREFTYPE href;
- };
-
- class CHrefOfClassHash : public CClosedHash<class CHrefOfClassHashKey>
- {
- public:
- typedef CHrefOfClassHashKey T;
-
- CHrefOfClassHash() :
- CClosedHash<class CHrefOfClassHashKey>(101)
- {
- WRAPPER_NO_CONTRACT;
- }
- ~CHrefOfClassHash()
- {
- WRAPPER_NO_CONTRACT;
- Clear();
- }
-
- virtual void Clear();
-
- unsigned int Hash(const T *pData);
- unsigned int Hash(const void *pData)
- {
- WRAPPER_NO_CONTRACT;
- return Hash((const T*)pData);
- }
-
-
- unsigned int Compare(const T *p1, T *p2);
- unsigned int Compare(const void *p1, BYTE *p2)
- {
- WRAPPER_NO_CONTRACT;
- return Compare((const T*)p1, (T*)p2);
- }
-
-
- ELEMENTSTATUS Status(T *p);
- ELEMENTSTATUS Status(BYTE *p)
- {
- WRAPPER_NO_CONTRACT;
- return Status((T*)p);
- }
-
-
- void SetStatus(T *p, ELEMENTSTATUS s);
- void SetStatus(BYTE *p, ELEMENTSTATUS s)
- {
- WRAPPER_NO_CONTRACT;
- SetStatus((T*)p, s);
- }
-
-
- void *GetKey(T *p);
- void* GetKey(BYTE *p)
- {
- WRAPPER_NO_CONTRACT;
- return GetKey((T*)p);
- }
- };
-
- struct CErrorContext
- {
- CErrorContext() :
- m_prev(0),
- m_szAssembly(0),
- m_tkType(mdTypeDefNil),
- m_pScope(0),
- m_szMember(0),
- m_szParam(0),
- m_ixParam(-1)
- {
- LIMITED_METHOD_CONTRACT;
- }
-
- // The following variables hold context info for error reporting.
- CErrorContext* m_prev; // A previous context.
- LPCUTF8 m_szAssembly; // Current assembly name.
- mdToken m_tkType; // Current type's metadata token.
- IMDInternalImport *m_pScope; // Current type's scope.
- LPCUTF8 m_szMember; // Current member's name.
- LPCUTF8 m_szParam; // Current param's name.
- int m_ixParam; // Current param index.
- };
-
-public:
- TypeLibExporter();
- ~TypeLibExporter();
-
- void Convert(Assembly *pAssembly, LPCWSTR szTlbName, ITypeLibExporterNotifySink *pNotify=0, int flags=0);
- void LayOut();
- HRESULT GetTypeLib(REFGUID iid, IUnknown **ppTlb);
- void ReleaseResources();
-
-protected:
- void PreLoadNames();
-
- void UpdateBitness(Assembly* pAssembly);
- HRESULT CheckBitness(Assembly* pAssembly);
-
- // TypeLib emit functions.
- HRESULT TokenToHref(ICreateTypeInfo2 *pTI, MethodTable *pClass, mdToken tk, BOOL bWarnOnUsingIUnknown, HREFTYPE *pHref);
- void GetWellKnownInterface(MethodTable *pClass, ITypeInfo **ppTI);
- HRESULT EEClassToHref(ICreateTypeInfo2 *pTI, MethodTable *pClass, BOOL bWarnOnUsingIUnknown, HREFTYPE *pHref);
- void StdOleTypeToHRef(ICreateTypeInfo2 *pCTI, REFGUID rGuid, HREFTYPE *pHref);
- void ExportReferencedAssembly(Assembly *pAssembly);
-
- // Metadata import functions.
- void AddModuleTypes(Module *pModule);
- void AddAssemblyTypes(Assembly *pAssembly);
-
- void ConvertAllTypeDefs();
- HRESULT ConvertOneTypeDef(MethodTable *pClass);
-
- HRESULT GetTypeLibImportClassName(MethodTable *pClass, SString& pszName);
-
- void CreateITypeInfo(CExportedTypesInfo *pData, bool bNamespace=false, bool bResolveDup=true);
- void CreateIClassXITypeInfo(CExportedTypesInfo *pData, bool bNamespace=false, bool bResolveDup=true);
- void ConvertImplTypes(CExportedTypesInfo *pData);
- void ConvertDetails(CExportedTypesInfo *pData);
-
- void ConvertInterfaceImplTypes(ICreateTypeInfo2 *pICTI, MethodTable *pClass);
- void ConvertInterfaceDetails(ICreateTypeInfo2 *pICTI, MethodTable *pClass, int bAutoProxy);
- void ConvertRecord(CExportedTypesInfo *pData);
- void ConvertRecordBaseClass(CExportedTypesInfo *pData, MethodTable *pSubClass, ULONG &ixVar);
- void ConvertEnum(ICreateTypeInfo2 *pICTI, MethodTable *pClass);
- void ConvertClassImplTypes(ICreateTypeInfo2 *pICTI, ICreateTypeInfo2 *pIDefault, MethodTable *pClass);
- void ConvertClassDetails(ICreateTypeInfo2 *pICTI, ICreateTypeInfo2 *pIDefault, MethodTable *pClass, int bAutoProxy);
-
- BOOL HasDefaultCtor(MethodTable *pMT);
-
- void ConvertIClassX(ICreateTypeInfo2 *pICTI, MethodTable *pClass, int bAutoProxy);
- BOOL ConvertMethod(ICreateTypeInfo2 *pTI, ComMTMethodProps *pProps, ULONG iMD, ULONG ulIface);
- BOOL ConvertFieldAsMethod(ICreateTypeInfo2 *pTI, ComMTMethodProps *pProps, ULONG iMD);
- BOOL ConvertVariable(ICreateTypeInfo2 *pTI, MethodTable *pClass, mdFieldDef md, SString& sName, ULONG iMD);
- BOOL ConvertEnumMember(ICreateTypeInfo2 *pTI, MethodTable *pClass, mdFieldDef md, SString& sName, ULONG iMD);
-
- // Error/status functions.
- void InternalThrowHRWithContext(HRESULT hr, ...);
- void FormatErrorContextString(CErrorContext *pContext, SString *pOut);
- void FormatErrorContextString(SString *pOut);
- void ReportError(HRESULT hr);
- void ReportEvent(int ev, int hr, ...);
- void ReportWarning(HRESULT hrReturn, HRESULT hrRpt, ...);
- void PostClassLoadError(LPCUTF8 pszName, SString& message);
-
- // Utility functions.
- void ClassHasIClassX(MethodTable *pClass, CorClassIfaceAttr *pRslt);
- MethodTable * LoadClass(Module *pModule, mdToken tk);
- TypeHandle LoadClass(Module *pModule, LPCUTF8 pszName);
- HRESULT CorSigToTypeDesc(ICreateTypeInfo2 *pTI, MethodTable *pClass, PCCOR_SIGNATURE pbSig, PCCOR_SIGNATURE pbNativeSig, ULONG cbNativeSig,
- ULONG *cbElem, TYPEDESC *ptdesc, CDescPool *ppool, BOOL bMethodSig, BOOL *pbByRef=0);
- BOOL IsVbRefType(PCCOR_SIGNATURE pbSig, IMDInternalImport *pInternalImport);
-
- BOOL IsExportingAs64Bit();
-
- void ArrayToTypeDesc(ICreateTypeInfo2 *pCTI, CDescPool *ppool, ArrayMarshalInfo *pArrayMarshalInfo, TYPEDESC *pElementTypeDesc);
-
- VARTYPE GetVtForIntPtr();
- VARTYPE GetVtForUIntPtr();
-
- //BOOL ValidateSafeArrayElemVT(VARTYPE vt);
-
- BOOL GetDescriptionString(MethodTable *pClass, mdToken tk, BSTR &bstrDescr);
- BOOL GetStringCustomAttribute(IMDInternalImport *pImport, LPCSTR szName, mdToken tk, BSTR &bstrDescr);
-
- BOOL GetAutomationProxyAttribute(IMDInternalImport *pImport, mdToken tk, int *bValue);
-
- TYPEKIND TKindFromClass(MethodTable *pClass);
-
-protected:
- void GetRefTypeInfo(ICreateTypeInfo2 *pContainer, ITypeInfo *pReferenced, HREFTYPE *pHref);
-
- CHrefOfTIHash m_HrefHash; // Hashed table of HREFTYPEs of ITypeInfos
- CHrefOfClassHash m_HrefOfClassHash; // Hashed table of HREFTYPEs of ITypeInfos
- CErrorContext m_ErrorContext;
-
-private:
- ClassLoader* m_pLoader; // Domain where the Module being converted was loaded
- ITypeInfo* m_pIUnknown; // TypeInfo for IUnknown.
- HREFTYPE m_hIUnknown; // href for IUnknown.
- ITypeInfo* m_pIDispatch; // TypeInfo for IDispatch.
- ITypeInfo* m_pGuid; // TypeInfo for GUID.
-
- ITypeLibExporterNotifySink* m_pNotify; // Notification callback.
-
- ICreateTypeLib2* m_pICreateTLB; // The created typelib.
-
- int m_flags; // Conversion flags.
- int m_bAutomationProxy; // Should interfaces be marked such that oleaut32 is the proxy?
- int m_bWarnedOfNonPublic;
-
- CExportedTypesHash m_Exports;
- CExportedTypesHash m_InjectedExports;
-};
-
-
-// eof ------------------------------------------------------------------------
diff --git a/src/vm/typeparse.cpp b/src/vm/typeparse.cpp
index 34bf9647e7..9db4e8c917 100644
--- a/src/vm/typeparse.cpp
+++ b/src/vm/typeparse.cpp
@@ -18,122 +18,6 @@
#include "assemblynative.hpp"
#include "fstring.h"
-//
-// TypeNameFactory
-//
-HRESULT STDMETHODCALLTYPE TypeNameFactory::QueryInterface(REFIID riid, void **ppUnk)
-{
- WRAPPER_NO_CONTRACT;
-
- *ppUnk = 0;
-
- if (riid == IID_IUnknown)
- *ppUnk = (IUnknown *)this;
- else if (riid == IID_ITypeNameFactory)
- *ppUnk = (ITypeNameFactory*)this;
- else
- return (E_NOINTERFACE);
-
- AddRef();
- return S_OK;
-}
-
-HRESULT TypeNameFactoryCreateObject(REFIID riid, void **ppUnk)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- }
- CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- TypeNameFactory *pTypeNameFactory = new (nothrow) TypeNameFactory();
-
- if (!pTypeNameFactory)
- return (E_OUTOFMEMORY);
-
- hr = pTypeNameFactory->QueryInterface(riid, ppUnk);
-
- if (FAILED(hr))
- delete pTypeNameFactory;
-
- return hr;
-}
-
-
-HRESULT STDMETHODCALLTYPE TypeNameFactory::ParseTypeName(LPCWSTR szTypeName, DWORD* pError, ITypeName** ppTypeName)
-{
- CONTRACTL
- {
- WRAPPER(THROWS);
- }CONTRACTL_END;
-
- if (!ppTypeName || !pError)
- return E_INVALIDARG;
-
- HRESULT hr = S_OK;
-
- *ppTypeName = NULL;
- *pError = (DWORD)-1;
-
- ITypeName* pTypeName = new (nothrow) TypeName(szTypeName, pError);
-
- if (! pTypeName)
- {
- hr = E_OUTOFMEMORY;
- }
- else
- {
- pTypeName->AddRef();
-
- if (*pError != (DWORD)-1)
- {
- pTypeName->Release();
- hr = S_FALSE;
- }
- else
- {
- *ppTypeName = pTypeName;
- }
- }
-
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE TypeNameFactory::GetTypeNameBuilder(ITypeNameBuilder** ppTypeNameBuilder)
-{
- CONTRACTL
- {
- THROWS; // operator new has EX_TRY/EX_CATCH or other contract transitions(s)
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- if (!ppTypeNameBuilder)
- return E_INVALIDARG;
-
- *ppTypeNameBuilder = NULL;
-
- HRESULT hr = S_OK;
-
- ITypeNameBuilder* pTypeNameBuilder = new (nothrow) TypeNameBuilderWrapper();
-
- if (pTypeNameBuilder)
- {
- pTypeNameBuilder->AddRef();
-
- *ppTypeNameBuilder = pTypeNameBuilder;
- }
- else
- {
- hr = E_OUTOFMEMORY;
- }
-
- return hr;
-}
//
// TypeName
@@ -153,7 +37,7 @@ SString* TypeName::ToString(SString* pBuf, BOOL bAssemblySpec, BOOL bSignature,
}
-DWORD STDMETHODCALLTYPE TypeName::AddRef()
+DWORD TypeName::AddRef()
{
LIMITED_METHOD_CONTRACT;
@@ -162,7 +46,7 @@ DWORD STDMETHODCALLTYPE TypeName::AddRef()
return m_count;
}
-DWORD STDMETHODCALLTYPE TypeName::Release()
+DWORD TypeName::Release()
{
CONTRACTL
{
@@ -193,149 +77,6 @@ TypeName::~TypeName()
m_genericArguments[i]->Release();
}
-HRESULT STDMETHODCALLTYPE TypeName::QueryInterface(REFIID riid, void **ppUnk)
-{
- WRAPPER_NO_CONTRACT;
-
- *ppUnk = 0;
-
- if (riid == IID_IUnknown)
- *ppUnk = (IUnknown *)this;
- else if (riid == IID_ITypeName)
- *ppUnk = (ITypeName*)this;
- else
- return (E_NOINTERFACE);
-
- AddRef();
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE TypeName::GetNameCount(DWORD* pCount)
-{
- WRAPPER_NO_CONTRACT;
-
- if (!pCount)
- return E_INVALIDARG;
-
- *pCount = m_names.GetCount();
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE TypeName::GetNames(DWORD count, BSTR* bszName, DWORD* pFetched)
-{
- CONTRACTL
- {
- WRAPPER(THROWS);
- }CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- if (!pFetched)
- return E_INVALIDARG;
-
- *pFetched = m_names.GetCount();
-
- if (m_names.GetCount() > count)
- return S_FALSE;
-
- if (!bszName)
- return E_INVALIDARG;
-
- for (COUNT_T i = 0; i < m_names.GetCount(); i ++)
- bszName[i] = SysAllocString(m_names[i]->GetUnicode());
-
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE TypeName::GetTypeArgumentCount(DWORD* pCount)
-{
- WRAPPER_NO_CONTRACT;
-
- if (!pCount)
- return E_INVALIDARG;
-
- *pCount = m_genericArguments.GetCount();
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE TypeName::GetTypeArguments(DWORD count, ITypeName** ppArguments, DWORD* pFetched)
-{
- WRAPPER_NO_CONTRACT;
-
- if (!pFetched)
- return E_INVALIDARG;
-
- *pFetched = m_genericArguments.GetCount();
-
- if (m_genericArguments.GetCount() > count)
- return S_FALSE;
-
- if (!ppArguments)
- return E_INVALIDARG;
-
- for (COUNT_T i = 0; i < m_genericArguments.GetCount(); i ++)
- {
- ppArguments[i] = m_genericArguments[i];
- m_genericArguments[i]->AddRef();
- }
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE TypeName::GetModifierLength(DWORD* pCount)
-{
- WRAPPER_NO_CONTRACT;
-
- if (pCount == NULL)
- return E_INVALIDARG;
-
- *pCount = m_signature.GetCount();
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE TypeName::GetModifiers(DWORD count, DWORD* pModifiers, DWORD* pFetched)
-{
- WRAPPER_NO_CONTRACT;
-
- if (!pFetched)
- return E_INVALIDARG;
-
- *pFetched = m_signature.GetCount();
-
- if (m_signature.GetCount() > count)
- return S_FALSE;
-
- if (!pModifiers)
- return E_INVALIDARG;
-
- for (COUNT_T i = 0; i < m_signature.GetCount(); i ++)
- pModifiers[i] = m_signature[i];
-
- return S_OK;
-}
-
-HRESULT STDMETHODCALLTYPE TypeName::GetAssemblyName(BSTR* pszAssemblyName)
-{
- CONTRACTL
- {
- WRAPPER(THROWS);
- }CONTRACTL_END;
-
- HRESULT hr = S_OK;
-
- if (pszAssemblyName == NULL)
- return E_INVALIDARG;
-
- *pszAssemblyName = SysAllocString(m_assembly.GetUnicode());
- if (*pszAssemblyName == NULL)
- hr = E_OUTOFMEMORY;
-
- return hr;
-}
-
#if!defined(CROSSGEN_COMPILE)
SAFEHANDLE TypeName::GetSafeHandle()
{
diff --git a/src/vm/typeparse.h b/src/vm/typeparse.h
index 171a22cac3..cf592d41d1 100644
--- a/src/vm/typeparse.h
+++ b/src/vm/typeparse.h
@@ -52,34 +52,7 @@ DomainAssembly * LoadDomainAssembly(
BOOL bThrowIfNotFound,
SString * pssOuterTypeName);
-class TypeNameFactory : public ITypeNameFactory
-{
-public:
- static HRESULT CreateObject(REFIID riid, void **ppUnk);
-
-public:
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppUnk);
- virtual ULONG STDMETHODCALLTYPE AddRef() { LIMITED_METHOD_CONTRACT; m_count++; return m_count; }
- virtual ULONG STDMETHODCALLTYPE Release() { LIMITED_METHOD_CONTRACT; SUPPORTS_DAC_HOST_ONLY; m_count--; ULONG count = m_count; if (count == 0) delete this; return count; }
-
-public:
- virtual HRESULT STDMETHODCALLTYPE ParseTypeName(LPCWSTR szName, DWORD* pError, ITypeName** ppTypeName);
- virtual HRESULT STDMETHODCALLTYPE GetTypeNameBuilder(ITypeNameBuilder** ppTypeBuilder);
-
-public:
- TypeNameFactory() : m_count(0)
- {
- WRAPPER_NO_CONTRACT;
- SString::Startup();
- }
-
- virtual ~TypeNameFactory() {}
-
-private:
- DWORD m_count;
-};
-
-class TypeName : public ITypeName
+class TypeName
{
private:
template<typename PRODUCT>
@@ -282,21 +255,11 @@ private:
TypeNameTokens m_nextToken;
};
friend class TypeName::TypeNameParser;
-
-public:
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppUnk);
- virtual ULONG STDMETHODCALLTYPE AddRef();
- virtual ULONG STDMETHODCALLTYPE Release();
public:
- virtual HRESULT STDMETHODCALLTYPE GetNameCount(DWORD* pCount);
- virtual HRESULT STDMETHODCALLTYPE GetNames(DWORD count, BSTR* rgbszNames, DWORD* pFetched);
- virtual HRESULT STDMETHODCALLTYPE GetTypeArgumentCount(DWORD* pCount);
- virtual HRESULT STDMETHODCALLTYPE GetTypeArguments(DWORD count, ITypeName** rgpArguments, DWORD* pFetched);
- virtual HRESULT STDMETHODCALLTYPE GetModifierLength(DWORD* pCount);
- virtual HRESULT STDMETHODCALLTYPE GetModifiers(DWORD count, DWORD* rgModifiers, DWORD* pFetched);
- virtual HRESULT STDMETHODCALLTYPE GetAssemblyName(BSTR* rgbszAssemblyNames);
-
+ ULONG AddRef();
+ ULONG Release();
+
public:
TypeName(LPCWSTR szTypeName, DWORD* pError) : m_bIsGenericArgument(FALSE), m_count(0)
{
diff --git a/src/vm/typestring.cpp b/src/vm/typestring.cpp
index bdf8cd9694..bc7737efa5 100644
--- a/src/vm/typestring.cpp
+++ b/src/vm/typestring.cpp
@@ -1388,218 +1388,3 @@ bool TypeString::ContainsReservedChar(LPCWSTR pTypeName)
return false;
}
-
-HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::QueryInterface(REFIID riid, void **ppUnk)
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- *ppUnk = 0;
-
- if (riid == IID_IUnknown)
- *ppUnk = (IUnknown *)this;
- else if (riid == IID_ITypeNameBuilder)
- *ppUnk = (ITypeNameBuilder*)this;
- else
- return (E_NOINTERFACE);
-
- AddRef();
- return S_OK;
-}
-
-ULONG STDMETHODCALLTYPE TypeNameBuilderWrapper::AddRef()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return InterlockedIncrement(&m_ref);
-}
-
-ULONG STDMETHODCALLTYPE TypeNameBuilderWrapper::Release()
-{
- CONTRACTL
- {
- NOTHROW;
- GC_NOTRIGGER;
- MODE_ANY;
- SUPPORTS_DAC_HOST_ONLY;
- }
- CONTRACTL_END;
-
- LONG ref = 0;
-
- ref = InterlockedDecrement(&m_ref);
- if (ref == 0)
- delete this;
-
- return ref;
-}
-
-
-HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::OpenGenericArguments()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- HRESULT hr;
- hr = m_tnb.OpenGenericArguments();
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::CloseGenericArguments()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- HRESULT hr;
- hr = m_tnb.CloseGenericArguments();
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::OpenGenericArgument()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- HRESULT hr;
- hr = m_tnb.OpenGenericArgument();
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::CloseGenericArgument()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- HRESULT hr;
- hr = m_tnb.CloseGenericArgument();
- return hr;
-}
-
-HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::AddName(LPCWSTR szName)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return m_tnb.AddName(szName);
-}
-
-HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::AddPointer()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return m_tnb.AddPointer();
-}
-
-HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::AddByRef()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return m_tnb.AddByRef();
-}
-
-HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::AddSzArray()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return m_tnb.AddSzArray();
-}
-
-HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::AddArray(DWORD rank)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return m_tnb.AddArray(rank);
-}
-
-HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::AddAssemblySpec(LPCWSTR szAssemblySpec)
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return m_tnb.AddAssemblySpec(szAssemblySpec);
-}
-
-HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::ToString(BSTR* pszStringRepresentation)
-{
- WRAPPER_NO_CONTRACT;
-
- return m_tnb.ToString(pszStringRepresentation);
-}
-
-HRESULT STDMETHODCALLTYPE TypeNameBuilderWrapper::Clear()
-{
- CONTRACTL
- {
- THROWS;
- GC_NOTRIGGER;
- MODE_ANY;
- }
- CONTRACTL_END;
-
- return m_tnb.Clear();
-}
diff --git a/src/vm/typestring.h b/src/vm/typestring.h
index 0ddec87671..4b75b84b67 100644
--- a/src/vm/typestring.h
+++ b/src/vm/typestring.h
@@ -28,13 +28,10 @@
#include "typeparse.h"
#include "field.h"
-class TypeLibExporter;
class TypeString;
class TypeNameBuilder
{
- friend class TypeNameBuilderWrapper;
-
public:
static void QCALLTYPE _ReleaseTypeNameBuilder(TypeNameBuilder * pTnb);
static TypeNameBuilder * QCALLTYPE _CreateTypeNameBuilder();
@@ -148,36 +145,6 @@ private:
Stack m_stack;
};
-// Class that's exposed to COM and wraps TypeNameBuilder (so that it can thunk
-// all the entry points in order to perform stack probes).
-class TypeNameBuilderWrapper : public ITypeNameBuilder
-{
-public:
- virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppUnk);
- virtual ULONG STDMETHODCALLTYPE AddRef();
- virtual ULONG STDMETHODCALLTYPE Release();
-
- virtual HRESULT STDMETHODCALLTYPE OpenGenericArguments();
- virtual HRESULT STDMETHODCALLTYPE CloseGenericArguments();
- virtual HRESULT STDMETHODCALLTYPE OpenGenericArgument();
- virtual HRESULT STDMETHODCALLTYPE CloseGenericArgument();
- virtual HRESULT STDMETHODCALLTYPE AddName(LPCWSTR szName);
- virtual HRESULT STDMETHODCALLTYPE AddPointer();
- virtual HRESULT STDMETHODCALLTYPE AddByRef();
- virtual HRESULT STDMETHODCALLTYPE AddSzArray();
- virtual HRESULT STDMETHODCALLTYPE AddArray(DWORD rank);
- virtual HRESULT STDMETHODCALLTYPE AddAssemblySpec(LPCWSTR szAssemblySpec);
- virtual HRESULT STDMETHODCALLTYPE ToString(BSTR* pszStringRepresentation);
- virtual HRESULT STDMETHODCALLTYPE Clear();
-
- TypeNameBuilderWrapper() : m_ref(0) { WRAPPER_NO_CONTRACT; }
- virtual ~TypeNameBuilderWrapper() {}
-
-private:
- LONG m_ref;
- TypeNameBuilder m_tnb;
-};
-
// --------------------------------------------------------------------------
// This type can generate names for types. It is used by reflection methods
// like System.RuntimeType.RuntimeTypeCache.ConstructName
@@ -249,7 +216,6 @@ public:
#endif
private:
- friend class TypeLibExporter;
friend class TypeNameBuilder;
static void AppendMethodImpl(SString& s, MethodDesc *pMD, Instantiation typeInstantiation, const DWORD format);
static void AppendTypeDef(TypeNameBuilder& tnb, IMDInternalImport *pImport, mdTypeDef td, DWORD format = FormatNamespace);
diff --git a/src/vm/util.hpp b/src/vm/util.hpp
index 06afda69b6..2bbca2cfe3 100644
--- a/src/vm/util.hpp
+++ b/src/vm/util.hpp
@@ -735,10 +735,6 @@ typedef Wrapper<void *, DoNothing, DoNothing> PALPEFileHolder;
void GetProcessMemoryLoad(LPMEMORYSTATUSEX pMSEX);
-void ProcessEventForHost(EClrEvent event, void *data);
-void ProcessSOEventForHost(EXCEPTION_POINTERS *pExceptionInfo, BOOL fInSoTolerant);
-BOOL IsHostRegisteredForEvent(EClrEvent event);
-
#define SetupThreadForComCall(OOMRetVal) \
MAKE_CURRENT_THREAD_AVAILABLE_EX(GetThreadNULLOk()); \
if (CURRENT_THREAD == NULL) \