<Compile Include="$(BclSourcesRoot)\System\Collections\Generic\EqualityComparer.cs" />
<Compile Include="$(BclSourcesRoot)\System\Collections\ObjectModel\ReadOnlyDictionary.cs" />
<Compile Include="$(BclSourcesRoot)\System\Currency.cs" />
- <Compile Include="$(BclSourcesRoot)\System\DateTime.CoreCLR.cs" />
<Compile Include="$(BclSourcesRoot)\System\DefaultBinder.CanConvert.cs" />
<Compile Include="$(BclSourcesRoot)\System\Delegate.cs" />
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\Contracts\Contracts.cs" />
<Compile Include="$(BclSourcesRoot)\System\Variant.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsUnix)' == 'true'">
+ <Compile Include="$(BclSourcesRoot)\System\DateTime.Unix.cs" />
<Compile Include="$(BclSourcesRoot)\Interop\Unix\Interop.Libraries.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\CultureInfo.Unix.cs" />
<Compile Include="$(BclSourcesRoot)\System\Globalization\GlobalizationMode.Unix.cs" />
<Compile Include="$(BclSourcesRoot)\System\Threading\ClrThreadPoolBoundHandle.Unix.cs" />
</ItemGroup>
<ItemGroup Condition="'$(TargetsWindows)' == 'true'">
+ <Compile Include="$(BclSourcesRoot)\System\DateTime.Windows.cs" />
<Compile Include="$(BclSourcesRoot)\Interop\Windows\Kernel32\Interop.GetSystemDirectoryW.cs" />
<Compile Include="$(BclSourcesRoot)\System\ApplicationModel.Windows.cs" />
<Compile Include="$(BclSourcesRoot)\System\Diagnostics\DebugProvider.Windows.cs" />
--- /dev/null
+// 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 partial class Interop
+{
+ internal partial class NtDll
+ {
+ [DllImport(Libraries.NtDll)]
+ internal static unsafe extern int NtQuerySystemInformation(int SystemInformationClass, void* SystemInformation, int SystemInformationLength, uint* ReturnLength);
+
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct SYSTEM_LEAP_SECOND_INFORMATION
+ {
+ public bool Enabled;
+ public uint Flags;
+ }
+
+ internal const int SystemLeapSecondInformation = 206;
+ }
+}
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Kernel32\Interop.WriteFile_SafeHandle_NativeOverlapped.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Normaliz\Interop.Idna.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Normaliz\Interop.Normalization.cs" Condition="'$(EnableDummyGlobalizationImplementation)' != 'true'" />
+ <Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\NtDll\Interop.NtQuerySystemInformation.cs" Condition="'$(EnableWinRT)' != 'true'" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\Ole32\Interop.CoCreateGuid.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\OleAut32\Interop.SysAllocStringLen.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Interop\Windows\OleAut32\Interop.SysFreeString.cs" />
//
public DateTime(int year, int month, int day, int hour, int minute, int second)
{
+ if (second == 60 && s_systemSupportsLeapSeconds && IsValidTimeWithLeapSeconds(year, month, day, hour, minute, second, DateTimeKind.Unspecified))
+ {
+ // if we have leap second (second = 60) then we'll need to check if it is valid time.
+ // if it is valid, then we adjust the second to 59 so DateTime will consider this second is last second
+ // in the specified minute.
+ // if it is not valid time, we'll eventually throw.
+ second = 59;
+ }
_dateData = (ulong)(DateToTicks(year, month, day) + TimeToTicks(hour, minute, second));
}
{
throw new ArgumentException(SR.Argument_InvalidDateTimeKind, nameof(kind));
}
+
+ if (second == 60 && s_systemSupportsLeapSeconds && IsValidTimeWithLeapSeconds(year, month, day, hour, minute, second, kind))
+ {
+ // if we have leap second (second = 60) then we'll need to check if it is valid time.
+ // if it is valid, then we adjust the second to 59 so DateTime will consider this second is last second
+ // in the specified minute.
+ // if it is not valid time, we'll eventually throw.
+ second = 59;
+ }
+
long ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
_dateData = ((ulong)ticks | ((ulong)kind << KindShift));
}
{
if (calendar == null)
throw new ArgumentNullException(nameof(calendar));
+
+ int originalSecond = second;
+ if (second == 60 && s_systemSupportsLeapSeconds)
+ {
+ // Reset the second value now and then we'll validate it later when we get the final Gregorian date.
+ second = 59;
+ }
+
_dateData = (ulong)calendar.ToDateTime(year, month, day, hour, minute, second, 0).Ticks;
+
+ if (originalSecond == 60)
+ {
+ DateTime dt = new DateTime(_dateData);
+ if (!IsValidTimeWithLeapSeconds(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 60, DateTimeKind.Unspecified))
+ {
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
+ }
+ }
}
// Constructs a DateTime from a given year, month, day, hour,
{
throw new ArgumentOutOfRangeException(nameof(millisecond), SR.Format(SR.ArgumentOutOfRange_Range, 0, MillisPerSecond - 1));
}
+
+ if (second == 60 && s_systemSupportsLeapSeconds && IsValidTimeWithLeapSeconds(year, month, day, hour, minute, second, DateTimeKind.Unspecified))
+ {
+ // if we have leap second (second = 60) then we'll need to check if it is valid time.
+ // if it is valid, then we adjust the second to 59 so DateTime will consider this second is last second
+ // in the specified minute.
+ // if it is not valid time, we'll eventually throw.
+ second = 59;
+ }
+
long ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
ticks += millisecond * TicksPerMillisecond;
if (ticks < MinTicks || ticks > MaxTicks)
{
throw new ArgumentException(SR.Argument_InvalidDateTimeKind, nameof(kind));
}
+
+ if (second == 60 && s_systemSupportsLeapSeconds && IsValidTimeWithLeapSeconds(year, month, day, hour, minute, second, kind))
+ {
+ // if we have leap second (second = 60) then we'll need to check if it is valid time.
+ // if it is valid, then we adjust the second to 59 so DateTime will consider this second is last second
+ // in the specified minute.
+ // if it is not valid time, we'll eventually throw.
+ second = 59;
+ }
+
long ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
ticks += millisecond * TicksPerMillisecond;
if (ticks < MinTicks || ticks > MaxTicks)
{
throw new ArgumentOutOfRangeException(nameof(millisecond), SR.Format(SR.ArgumentOutOfRange_Range, 0, MillisPerSecond - 1));
}
+
+ int originalSecond = second;
+ if (second == 60 && s_systemSupportsLeapSeconds)
+ {
+ // Reset the second value now and then we'll validate it later when we get the final Gregorian date.
+ second = 59;
+ }
+
long ticks = calendar.ToDateTime(year, month, day, hour, minute, second, 0).Ticks;
ticks += millisecond * TicksPerMillisecond;
if (ticks < MinTicks || ticks > MaxTicks)
throw new ArgumentException(SR.Arg_DateTimeRange);
_dateData = (ulong)ticks;
+
+ if (originalSecond == 60)
+ {
+ DateTime dt = new DateTime(_dateData);
+ if (!IsValidTimeWithLeapSeconds(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 60, DateTimeKind.Unspecified))
+ {
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
+ }
+ }
}
public DateTime(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar, DateTimeKind kind)
{
throw new ArgumentException(SR.Argument_InvalidDateTimeKind, nameof(kind));
}
+
+ int originalSecond = second;
+ if (second == 60 && s_systemSupportsLeapSeconds)
+ {
+ // Reset the second value now and then we'll validate it later when we get the final Gregorian date.
+ second = 59;
+ }
+
long ticks = calendar.ToDateTime(year, month, day, hour, minute, second, 0).Ticks;
ticks += millisecond * TicksPerMillisecond;
if (ticks < MinTicks || ticks > MaxTicks)
throw new ArgumentException(SR.Arg_DateTimeRange);
_dateData = ((ulong)ticks | ((ulong)kind << KindShift));
+
+ if (originalSecond == 60)
+ {
+ DateTime dt = new DateTime(_dateData);
+ if (!IsValidTimeWithLeapSeconds(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 60, kind))
+ {
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
+ }
+ }
}
private DateTime(SerializationInfo info, StreamingContext context)
}
}
-
-
internal long InternalTicks
{
get
throw new ArgumentOutOfRangeException(nameof(fileTime), SR.ArgumentOutOfRange_FileTimeInvalid);
}
+ if (s_systemSupportsLeapSeconds)
+ {
+ return FromFileTimeLeapSecondsAware(fileTime);
+ }
+
// This is the ticks in Universal time for this fileTime.
long universalTicks = fileTime + FileTimeOffset;
return new DateTime(universalTicks, DateTimeKind.Utc);
{
// Treats the input as universal if it is not specified
long ticks = ((InternalKind & LocalMask) != 0) ? ToUniversalTime().InternalTicks : this.InternalTicks;
+
+ if (s_systemSupportsLeapSeconds)
+ {
+ return ToFileTimeLeapSecondsAware(ticks);
+ }
+
ticks -= FileTimeOffset;
if (ticks < 0)
{
throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_FileTimeInvalid);
}
+
return ticks;
}
{
return false;
}
- if (hour < 0 || hour >= 24 || minute < 0 || minute >= 60 || second < 0 || second >= 60)
+ if (hour < 0 || hour >= 24 || minute < 0 || minute >= 60 || second < 0 || second > 60)
{
return false;
}
{
return false;
}
+
+ if (second == 60)
+ {
+ if (s_systemSupportsLeapSeconds && IsValidTimeWithLeapSeconds(year, month, day, hour, minute, second, DateTimeKind.Unspecified))
+ {
+ // if we have leap second (second = 60) then we'll need to check if it is valid time.
+ // if it is valid, then we adjust the second to 59 so DateTime will consider this second is last second
+ // of this minute.
+ // if it is not valid time, we'll eventually throw.
+ // although this is unspecified datetime kind, we'll assume the passed time is UTC to check the leap seconds.
+ second = 59;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
long ticks = DateToTicks(year, month, day) + TimeToTicks(hour, minute, second);
ticks += millisecond * TicksPerMillisecond;
namespace System
{
- // DateTimeOffset is a value type that consists of a DateTime and a time zone offset,
+ // DateTimeOffset is a value type that consists of a DateTime and a time zone offset,
// ie. how far away the time is from GMT. The DateTime is stored whole, and the offset
- // is stored as an Int16 internally to save space, but presented as a TimeSpan.
+ // is stored as an Int16 internally to save space, but presented as a TimeSpan.
//
// The range is constrained so that both the represented clock time and the represented
// UTC time fit within the boundaries of MaxValue. This gives it the same range as DateTime
// for actual UTC times, and a slightly constrained range on one end when an offset is
- // present.
+ // present.
//
// This class should be substitutable for date time in most cases; so most operations
// effectively work on the clock time. However, the underlying UTC time is what counts
[StructLayout(LayoutKind.Auto)]
[Serializable]
- [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
+ [System.Runtime.CompilerServices.TypeForwardedFrom("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089")]
public readonly struct DateTimeOffset : IComparable, IFormattable, IComparable<DateTimeOffset>, IEquatable<DateTimeOffset>, ISerializable, IDeserializationCallback, ISpanFormattable
{
// Constants
public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, TimeSpan offset)
{
_offsetMinutes = ValidateOffset(offset);
+
+ int originalSecond = second;
+ if (second == 60 && DateTime.s_systemSupportsLeapSeconds)
+ {
+ // Reset the leap second to 59 for now and then we'll validate it after getting the final UTC time.
+ second = 59;
+ }
+
_dateTime = ValidateDate(new DateTime(year, month, day, hour, minute, second), offset);
+
+ if (originalSecond == 60 &&
+ !DateTime.IsValidTimeWithLeapSeconds(_dateTime.Year, _dateTime.Month, _dateTime.Day, _dateTime.Hour, _dateTime.Minute, 60, DateTimeKind.Utc))
+ {
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
+ }
}
// Constructs a DateTimeOffset from a given year, month, day, hour,
public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, int millisecond, TimeSpan offset)
{
_offsetMinutes = ValidateOffset(offset);
+
+ int originalSecond = second;
+ if (second == 60 && DateTime.s_systemSupportsLeapSeconds)
+ {
+ // Reset the leap second to 59 for now and then we'll validate it after getting the final UTC time.
+ second = 59;
+ }
+
_dateTime = ValidateDate(new DateTime(year, month, day, hour, minute, second, millisecond), offset);
+
+ if (originalSecond == 60 &&
+ !DateTime.IsValidTimeWithLeapSeconds(_dateTime.Year, _dateTime.Month, _dateTime.Day, _dateTime.Hour, _dateTime.Minute, 60, DateTimeKind.Utc))
+ {
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
+ }
}
// Constructs a DateTimeOffset from a given year, month, day, hour,
public DateTimeOffset(int year, int month, int day, int hour, int minute, int second, int millisecond, Calendar calendar, TimeSpan offset)
{
_offsetMinutes = ValidateOffset(offset);
+
+ int originalSecond = second;
+ if (second == 60 && DateTime.s_systemSupportsLeapSeconds)
+ {
+ // Reset the leap second to 59 for now and then we'll validate it after getting the final UTC time.
+ second = 59;
+ }
+
_dateTime = ValidateDate(new DateTime(year, month, day, hour, minute, second, millisecond, calendar), offset);
+
+ if (originalSecond == 60 &&
+ !DateTime.IsValidTimeWithLeapSeconds(_dateTime.Year, _dateTime.Month, _dateTime.Day, _dateTime.Hour, _dateTime.Minute, 60, DateTimeKind.Utc))
+ {
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_BadHourMinuteSecond);
+ }
}
// Returns a DateTimeOffset representing the current date and time. The
// Constructs a DateTimeOffset from a string. The string must specify a
// date and optionally a time in a culture-specific or universal format.
// Leading and trailing whitespace characters are allowed.
- //
+ //
public static DateTimeOffset Parse(string input)
{
if (input == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.input);
// Constructs a DateTimeOffset from a string. The string must specify a
// date and optionally a time in a culture-specific or universal format.
// Leading and trailing whitespace characters are allowed.
- //
+ //
public static DateTimeOffset Parse(string input, IFormatProvider formatProvider)
{
if (input == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.input);
// Constructs a DateTimeOffset from a string. The string must specify a
// date and optionally a time in a culture-specific or universal format.
// Leading and trailing whitespace characters are allowed.
- //
+ //
public static DateTimeOffset ParseExact(string input, string format, IFormatProvider formatProvider)
{
if (input == null) ThrowHelper.ThrowArgumentNullException(ExceptionArgument.input);
// Constructs a DateTimeOffset from a string. The string must specify a
// date and optionally a time in a culture-specific or universal format.
// Leading and trailing whitespace characters are allowed.
- //
+ //
public static DateTimeOffset ParseExact(string input, string format, IFormatProvider formatProvider, DateTimeStyles styles)
{
styles = ValidateStyles(styles, nameof(styles));
// RoundtripKind does not make sense for DateTimeOffset; ignore this flag for backward compatibility with DateTime
style &= ~DateTimeStyles.RoundtripKind;
- // AssumeLocal is also ignored as that is what we do by default with DateTimeOffset.Parse
+ // AssumeLocal is also ignored as that is what we do by default with DateTimeOffset.Parse
style &= ~DateTimeStyles.AssumeLocal;
return style;
+++ /dev/null
-// 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
-{
- public readonly partial struct DateTime
- {
- public static DateTime UtcNow
- {
- get
- {
- // following code is tuned for speed. Don't change it without running benchmark.
- long ticks = 0;
- ticks = GetSystemTimeAsFileTime();
-
- return new DateTime(((ulong)(ticks + FileTimeOffset)) | KindUtc);
- }
- }
-
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- internal static extern long GetSystemTimeAsFileTime();
- }
-}
--- /dev/null
+// 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
+{
+ public readonly partial struct DateTime
+ {
+ internal const bool s_systemSupportsLeapSeconds = false;
+
+ public static DateTime UtcNow
+ {
+ get
+ {
+ return new DateTime(((ulong)(GetSystemTimeAsFileTime() + FileTimeOffset)) | KindUtc);
+ }
+ }
+
+ internal static DateTime FromFileTimeLeapSecondsAware(long fileTime) => default(DateTime);
+ internal static long ToFileTimeLeapSecondsAware(long ticks) => default(long);
+
+ // IsValidTimeWithLeapSeconds is not expected to be called at all for now on non-Windows platforms
+ internal static bool IsValidTimeWithLeapSeconds(int year, int month, int day, int hour, int minute, int second, DateTimeKind kind) => false;
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern long GetSystemTimeAsFileTime();
+ }
+}
--- /dev/null
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+namespace System
+{
+ public readonly partial struct DateTime
+ {
+ internal static readonly bool s_systemSupportsLeapSeconds = SystemSupportsLeapSeconds();
+
+ public static DateTime UtcNow
+ {
+ get
+ {
+ if (s_systemSupportsLeapSeconds)
+ {
+ GetSystemTimeWithLeapSecondsHandling(out FullSystemTime time);
+ return CreateDateTimeFromSystemTime(in time);
+ }
+
+ return new DateTime(((ulong)(GetSystemTimeAsFileTime() + FileTimeOffset)) | KindUtc);
+ }
+ }
+
+ internal static bool IsValidTimeWithLeapSeconds(int year, int month, int day, int hour, int minute, int second, DateTimeKind kind)
+ {
+ DateTime dt = new DateTime(year, month, day);
+ FullSystemTime time = new FullSystemTime(year, month, dt.DayOfWeek, day, hour, minute, second);
+
+ switch (kind)
+ {
+ case DateTimeKind.Local: return ValidateSystemTime(in time.systemTime, localTime: true);
+ case DateTimeKind.Utc: return ValidateSystemTime(in time.systemTime, localTime: false);
+ default:
+ return ValidateSystemTime(in time.systemTime, localTime: true) || ValidateSystemTime(in time.systemTime, localTime: false);
+ }
+ }
+
+ internal static DateTime FromFileTimeLeapSecondsAware(long fileTime)
+ {
+ if (FileTimeToSystemTime(fileTime, out FullSystemTime time))
+ {
+ return CreateDateTimeFromSystemTime(in time);
+ }
+
+ throw new ArgumentOutOfRangeException("fileTime", SR.ArgumentOutOfRange_DateTimeBadTicks);
+ }
+
+ internal static long ToFileTimeLeapSecondsAware(long ticks)
+ {
+ FullSystemTime time = new FullSystemTime(ticks);
+ if (SystemTimeToFileTime(in time.systemTime, out long fileTime))
+ {
+ return fileTime + ticks % TicksPerMillisecond;
+ }
+
+ throw new ArgumentOutOfRangeException(null, SR.ArgumentOutOfRange_FileTimeInvalid);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal static DateTime CreateDateTimeFromSystemTime(in FullSystemTime time)
+ {
+ long ticks = DateToTicks(time.systemTime.Year, time.systemTime.Month, time.systemTime.Day);
+ ticks += TimeToTicks(time.systemTime.Hour, time.systemTime.Minute, time.systemTime.Second);
+ ticks += time.systemTime.Milliseconds * TicksPerMillisecond;
+ ticks += time.hundredNanoSecond;
+ return new DateTime( ((UInt64)(ticks)) | KindUtc);
+ }
+
+ private static unsafe bool SystemSupportsLeapSeconds()
+ {
+ Interop.NtDll.SYSTEM_LEAP_SECOND_INFORMATION slsi = new Interop.NtDll.SYSTEM_LEAP_SECOND_INFORMATION();
+ return Interop.NtDll.NtQuerySystemInformation(
+ Interop.NtDll.SystemLeapSecondInformation,
+ (void *) &slsi,
+ sizeof(Interop.NtDll.SYSTEM_LEAP_SECOND_INFORMATION),
+ null) == 0 && slsi.Enabled;
+ }
+
+ // FullSystemTime struct is the SYSTEMTIME struct with extra hundredNanoSecond field to store more precise time.
+ [StructLayout(LayoutKind.Sequential)]
+ internal struct FullSystemTime
+ {
+ internal Interop.Kernel32.SYSTEMTIME systemTime;
+ internal long hundredNanoSecond;
+
+ internal FullSystemTime(int year, int month, DayOfWeek dayOfWeek, int day, int hour, int minute, int second)
+ {
+ systemTime.Year = (ushort) year;
+ systemTime.Month = (ushort) month;
+ systemTime.DayOfWeek = (ushort) dayOfWeek;
+ systemTime.Day = (ushort) day;
+ systemTime.Hour = (ushort) hour;
+ systemTime.Minute = (ushort) minute;
+ systemTime.Second = (ushort) second;
+ systemTime.Milliseconds = 0;
+ hundredNanoSecond = 0;
+ }
+
+ internal FullSystemTime(long ticks)
+ {
+ DateTime dt = new DateTime(ticks);
+
+ int year, month, day;
+ dt.GetDatePart(out year, out month, out day);
+
+ systemTime.Year = (ushort) year;
+ systemTime.Month = (ushort) month;
+ systemTime.DayOfWeek = (ushort) dt.DayOfWeek;
+ systemTime.Day = (ushort) day;
+ systemTime.Hour = (ushort) dt.Hour;
+ systemTime.Minute = (ushort) dt.Minute;
+ systemTime.Second = (ushort) dt.Second;
+ systemTime.Milliseconds = (ushort) dt.Millisecond;
+ hundredNanoSecond = 0;
+ }
+ };
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern bool ValidateSystemTime(in Interop.Kernel32.SYSTEMTIME time, bool localTime);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern bool FileTimeToSystemTime(long fileTime, out FullSystemTime time);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern void GetSystemTimeWithLeapSecondsHandling(out FullSystemTime time);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern bool SystemTimeToFileTime(in Interop.Kernel32.SYSTEMTIME time, out long fileTime);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern long GetSystemTimeAsFileTime();
+ }
+}
{
func = &::GetSystemTimeAsFileTime;
}
-
+
g_pfnGetSystemTimeAsFileTime = func;
func(lpSystemTimeAsFileTime);
}
FCIMPLEND;
+#ifndef FEATURE_PAL
+
+FCIMPL1(VOID, SystemNative::GetSystemTimeWithLeapSecondsHandling, FullSystemTime *time)
+{
+ FCALL_CONTRACT;
+ INT64 timestamp;
+
+ g_pfnGetSystemTimeAsFileTime((FILETIME*)×tamp);
+
+ if (::FileTimeToSystemTime((FILETIME*)×tamp, &(time->systemTime)))
+ {
+ // to keep the time precision
+ time->hundredNanoSecond = timestamp % 10000; // 10000 is the number of 100-nano seconds per Millisecond
+ }
+ else
+ {
+ ::GetSystemTime(&(time->systemTime));
+ time->hundredNanoSecond = 0;
+ }
+
+ if (time->systemTime.wSecond > 59)
+ {
+ // we have a leap second, force it to last second in the minute as DateTime doesn't account for leap seconds in its calculation.
+ // we use the maxvalue from the milliseconds and the 100-nano seconds to avoid reporting two out of order 59 seconds
+ time->systemTime.wSecond = 59;
+ time->systemTime.wMilliseconds = 999;
+ time->hundredNanoSecond = 9999;
+ }
+}
+FCIMPLEND;
+
+FCIMPL2(FC_BOOL_RET, SystemNative::FileTimeToSystemTime, INT64 fileTime, FullSystemTime *time)
+{
+ FCALL_CONTRACT;
+ if (::FileTimeToSystemTime((FILETIME*)&fileTime, (LPSYSTEMTIME) time))
+ {
+ // to keep the time precision
+ time->hundredNanoSecond = fileTime % 10000; // 10000 is the number of 100-nano seconds per Millisecond
+ if (time->systemTime.wSecond > 59)
+ {
+ // we have a leap second, force it to last second in the minute as DateTime doesn't account for leap seconds in its calculation.
+ // we use the maxvalue from the milliseconds and the 100-nano seconds to avoid reporting two out of order 59 seconds
+ time->systemTime.wSecond = 59;
+ time->systemTime.wMilliseconds = 999;
+ time->hundredNanoSecond = 9999;
+ }
+ FC_RETURN_BOOL(TRUE);
+ }
+ FC_RETURN_BOOL(FALSE);
+}
+FCIMPLEND;
+
+FCIMPL2(FC_BOOL_RET, SystemNative::ValidateSystemTime, SYSTEMTIME *time, CLR_BOOL localTime)
+{
+ FCALL_CONTRACT;
+
+ if (localTime)
+ {
+ SYSTEMTIME st;
+ FC_RETURN_BOOL(::TzSpecificLocalTimeToSystemTime(NULL, time, &st));
+ }
+ else
+ {
+ FILETIME timestamp;
+ FC_RETURN_BOOL(::SystemTimeToFileTime(time, ×tamp));
+ }
+}
+FCIMPLEND;
+
+FCIMPL2(FC_BOOL_RET, SystemNative::SystemTimeToFileTime, SYSTEMTIME *time, INT64 *pFileTime)
+{
+ FCALL_CONTRACT;
+
+ BOOL ret = ::SystemTimeToFileTime(time, (LPFILETIME) pFileTime);
+ FC_RETURN_BOOL(ret);
+}
+FCIMPLEND;
+#endif // FEATURE_PAL
FCIMPL0(UINT32, SystemNative::GetTickCount)
{
FCALL_CONTRACT;
-
+
return ::GetTickCount();
}
FCIMPLEND;
FCIMPL1(VOID,SystemNative::SetExitCode,INT32 exitcode)
{
FCALL_CONTRACT;
-
+
// The exit code for the process is communicated in one of two ways. If the
// entrypoint returns an 'int' we take that. Otherwise we take a latched
// process exit code. This can be modified by the app via setting
FCIMPL0(INT32, SystemNative::GetExitCode)
{
FCALL_CONTRACT;
-
+
// Return whatever has been latched so far. This is uninitialized to 0.
return GetLatchedExitCode();
}
commandLine = WszGetCommandLine();
if (commandLine==NULL)
COMPlusThrowOM();
-
+
retString.Set(commandLine);
END_QCALL;
COMPlusThrowOM();
_ASSERTE(numArgs > 0);
-
+
strArray = (PTRARRAYREF) AllocateObjectArray(numArgs, g_pStringClass);
// Copy each argument into new Strings.
- for(unsigned int i=0; i<numArgs; i++)
+ for(unsigned int i=0; i<numArgs; i++)
{
STRINGREF str = StringObject::NewString(argv[i]);
STRINGREF * destData = ((STRINGREF*)(strArray->GetDataPtr())) + i;
HELPER_METHOD_FRAME_END();
- return OBJECTREFToObject(strArray);
+ return OBJECTREFToObject(strArray);
}
FCIMPLEND
FCIMPL1(ReflectMethodObject*, SystemNative::GetMethodFromStackTrace, ArrayBase* pStackTraceUNSAFE)
{
FCALL_CONTRACT;
-
+
I1ARRAYREF pArray(static_cast<I1Array *>(pStackTraceUNSAFE));
StackTraceArray stackArray(pArray);
{
FCALL_CONTRACT;
- // Return true if the EE has started to shutdown and is now going to
+ // Return true if the EE has started to shutdown and is now going to
// aggressively finalize objects referred to by static variables OR
// if someone is unloading the current AppDomain AND we have started
// finalizing objects referred to by static variables.
SO_TOLERANT;
}CONTRACTL_END;
- struct
+ struct
{
STRINGREF refMesgString;
EXCEPTIONREF refExceptionForWatsonBucketing;
ZeroMemory(&gc, sizeof(gc));
GCPROTECT_BEGIN(gc);
-
+
gc.refMesgString = refMesgString;
gc.refExceptionForWatsonBucketing = refExceptionForWatsonBucketing;
gc.refErrorSourceString = refErrorSourceString;
WCHAR * errorSourceString = NULL;
- if (gc.refErrorSourceString != NULL)
+ if (gc.refErrorSourceString != NULL)
{
DWORD cchErrorSource = gc.refErrorSourceString->GetStringLength();
errorSourceString = new (nothrow) WCHAR[cchErrorSource + 1];
- if (errorSourceString != NULL)
+ if (errorSourceString != NULL)
{
memcpyNoGCRefs(errorSourceString, gc.refErrorSourceString->GetBuffer(), cchErrorSource * sizeof(WCHAR));
errorSourceString[cchErrorSource] = W('\0');
pszMessage = g_szFailFastBuffer;
}
}
-
+
if (cchMessage > 0)
memcpyNoGCRefs(pszMessage, gc.refMesgString->GetBuffer(), cchMessage * sizeof(WCHAR));
pszMessage[cchMessage] = W('\0');
Thread *pThread = GetThread();
-#ifndef FEATURE_PAL
+#ifndef FEATURE_PAL
// If we have the exception object, then try to setup
// the watson bucket if it has any details.
// On CoreCLR, Watson may not be enabled. Thus, we should
}
// Note: Do not merge this FCALL method with any other FailFast overloads.
-// Watson uses the managed FailFast method with one String for crash dump bucketization.
+// Watson uses the managed FailFast method with one String for crash dump bucketization.
FCIMPL1(VOID, SystemNative::FailFast, StringObject* refMessageUNSAFE)
-{
+{
FCALL_CONTRACT;
STRINGREF refMessage = (STRINGREF)refMessageUNSAFE;
-
+
HELPER_METHOD_FRAME_BEGIN_1(refMessage);
// The HelperMethodFrame knows how to get the return address.
UINT_PTR retaddr = HELPER_METHOD_FRAME_GET_RETURN_ADDRESS();
-
+
// Call the actual worker to perform failfast
GenericFailFast(refMessage, NULL, retaddr, COR_E_FAILFAST, NULL);
FCIMPLEND
FCIMPL2(VOID, SystemNative::FailFastWithExitCode, StringObject* refMessageUNSAFE, UINT exitCode)
-{
+{
FCALL_CONTRACT;
STRINGREF refMessage = (STRINGREF)refMessageUNSAFE;
-
+
HELPER_METHOD_FRAME_BEGIN_1(refMessage);
// The HelperMethodFrame knows how to get the return address.
UINT_PTR retaddr = HELPER_METHOD_FRAME_GET_RETURN_ADDRESS();
-
+
// Call the actual worker to perform failfast
GenericFailFast(refMessage, NULL, retaddr, exitCode, NULL);
FCIMPLEND
FCIMPL2(VOID, SystemNative::FailFastWithException, StringObject* refMessageUNSAFE, ExceptionObject* refExceptionUNSAFE)
-{
+{
FCALL_CONTRACT;
STRINGREF refMessage = (STRINGREF)refMessageUNSAFE;
// The HelperMethodFrame knows how to get the return address.
UINT_PTR retaddr = HELPER_METHOD_FRAME_GET_RETURN_ADDRESS();
-
+
// Call the actual worker to perform failfast
GenericFailFast(refMessage, refException, retaddr, COR_E_FAILFAST, NULL);
// The HelperMethodFrame knows how to get the return address.
UINT_PTR retaddr = HELPER_METHOD_FRAME_GET_RETURN_ADDRESS();
-
+
// Call the actual worker to perform failfast
GenericFailFast(refMessage, refException, retaddr, COR_E_FAILFAST, errorSource);
-
+
#include "fcall.h"
#include "qcall.h"
+struct FullSystemTime
+{
+ SYSTEMTIME systemTime;
+ INT64 hundredNanoSecond;
+};
+
class SystemNative
{
friend class DebugStackTrace;
public:
// Functions on the System.Environment class
+#ifndef FEATURE_PAL
+ static FCDECL1(VOID, GetSystemTimeWithLeapSecondsHandling, FullSystemTime *time);
+ static FCDECL2(FC_BOOL_RET, ValidateSystemTime, SYSTEMTIME *time, CLR_BOOL localTime);
+ static FCDECL2(FC_BOOL_RET, FileTimeToSystemTime, INT64 fileTime, FullSystemTime *time);
+ static FCDECL2(FC_BOOL_RET, SystemTimeToFileTime, SYSTEMTIME *time, INT64 *pFileTime);
+#endif // FEATURE_PAL
static FCDECL0(INT64, __GetSystemTimeAsFileTime);
static FCDECL0(UINT32, GetTickCount);
QCFuncElement("GetEnumValuesAndNames", ReflectionEnum::GetEnumValuesAndNames)
FCFuncElement("InternalBoxEnum", ReflectionEnum::InternalBoxEnum)
FCFuncElement("Equals", ReflectionEnum::InternalEquals)
- FCFuncElement("InternalCompareTo", ReflectionEnum::InternalCompareTo)
+ FCFuncElement("InternalCompareTo", ReflectionEnum::InternalCompareTo)
FCFuncElement("InternalHasFlag", ReflectionEnum::InternalHasFlag)
FCFuncEnd()
FCFuncEnd()
FCFuncStart(gDateTimeFuncs)
+#if !defined(FEATURE_PAL)
+ FCFuncElement("GetSystemTimeWithLeapSecondsHandling", SystemNative::GetSystemTimeWithLeapSecondsHandling)
+ FCFuncElement("ValidateSystemTime", SystemNative::ValidateSystemTime)
+ FCFuncElement("FileTimeToSystemTime", SystemNative::FileTimeToSystemTime)
+ FCFuncElement("SystemTimeToFileTime", SystemNative::SystemTimeToFileTime)
+#endif // FEATURE_PAL
FCFuncElement("GetSystemTimeAsFileTime", SystemNative::__GetSystemTimeAsFileTime)
FCFuncEnd()
FCFuncElement("IsTypeExportedToWindowsRuntime", RuntimeTypeHandle::IsTypeExportedToWindowsRuntime)
#endif
FCFuncElement("IsWindowsRuntimeObjectType", RuntimeTypeHandle::IsWindowsRuntimeObjectType)
-#endif // defined(FEATURE_COMINTEROP)
+#endif // defined(FEATURE_COMINTEROP)
FCFuncEnd()
FCFuncStart(gJitHelpers)
FCFuncEnd()
FCFuncStart(gMetaDataImport)
- FCFuncElement("_GetDefaultValue", MetaDataImport::GetDefaultValue)
- FCFuncElement("_GetName", MetaDataImport::GetName)
- FCFuncElement("_GetUserString", MetaDataImport::GetUserString)
- FCFuncElement("_GetScopeProps", MetaDataImport::GetScopeProps)
- FCFuncElement("_GetClassLayout", MetaDataImport::GetClassLayout)
- FCFuncElement("_GetSignatureFromToken", MetaDataImport::GetSignatureFromToken)
- FCFuncElement("_GetNamespace", MetaDataImport::GetNamespace)
+ FCFuncElement("_GetDefaultValue", MetaDataImport::GetDefaultValue)
+ FCFuncElement("_GetName", MetaDataImport::GetName)
+ FCFuncElement("_GetUserString", MetaDataImport::GetUserString)
+ FCFuncElement("_GetScopeProps", MetaDataImport::GetScopeProps)
+ FCFuncElement("_GetClassLayout", MetaDataImport::GetClassLayout)
+ FCFuncElement("_GetSignatureFromToken", MetaDataImport::GetSignatureFromToken)
+ FCFuncElement("_GetNamespace", MetaDataImport::GetNamespace)
FCFuncElement("_GetEventProps", MetaDataImport::GetEventProps)
FCFuncElement("_GetFieldDefProps", MetaDataImport::GetFieldDefProps)
- FCFuncElement("_GetPropertyProps", MetaDataImport::GetPropertyProps)
- FCFuncElement("_GetParentToken", MetaDataImport::GetParentToken)
- FCFuncElement("_GetParamDefProps", MetaDataImport::GetParamDefProps)
- FCFuncElement("_GetGenericParamProps", MetaDataImport::GetGenericParamProps)
-
- FCFuncElement("_Enum", MetaDataImport::Enum)
- FCFuncElement("_GetMemberRefProps", MetaDataImport::GetMemberRefProps)
- FCFuncElement("_GetCustomAttributeProps", MetaDataImport::GetCustomAttributeProps)
- FCFuncElement("_GetFieldOffset", MetaDataImport::GetFieldOffset)
-
- FCFuncElement("_GetSigOfFieldDef", MetaDataImport::GetSigOfFieldDef)
- FCFuncElement("_GetSigOfMethodDef", MetaDataImport::GetSigOfMethodDef)
- FCFuncElement("_GetFieldMarshal", MetaDataImport::GetFieldMarshal)
- FCFuncElement("_GetPInvokeMap", MetaDataImport::GetPinvokeMap)
- FCFuncElement("_IsValidToken", MetaDataImport::IsValidToken)
- FCFuncElement("_GetMarshalAs", MetaDataImport::GetMarshalAs)
+ FCFuncElement("_GetPropertyProps", MetaDataImport::GetPropertyProps)
+ FCFuncElement("_GetParentToken", MetaDataImport::GetParentToken)
+ FCFuncElement("_GetParamDefProps", MetaDataImport::GetParamDefProps)
+ FCFuncElement("_GetGenericParamProps", MetaDataImport::GetGenericParamProps)
+
+ FCFuncElement("_Enum", MetaDataImport::Enum)
+ FCFuncElement("_GetMemberRefProps", MetaDataImport::GetMemberRefProps)
+ FCFuncElement("_GetCustomAttributeProps", MetaDataImport::GetCustomAttributeProps)
+ FCFuncElement("_GetFieldOffset", MetaDataImport::GetFieldOffset)
+
+ FCFuncElement("_GetSigOfFieldDef", MetaDataImport::GetSigOfFieldDef)
+ FCFuncElement("_GetSigOfMethodDef", MetaDataImport::GetSigOfMethodDef)
+ FCFuncElement("_GetFieldMarshal", MetaDataImport::GetFieldMarshal)
+ FCFuncElement("_GetPInvokeMap", MetaDataImport::GetPinvokeMap)
+ FCFuncElement("_IsValidToken", MetaDataImport::IsValidToken)
+ FCFuncElement("_GetMarshalAs", MetaDataImport::GetMarshalAs)
FCFuncEnd()
FCFuncStart(gSignatureNative)
FCFuncElement("GetStubIfNeeded", RuntimeMethodHandle::GetStubIfNeeded)
FCFuncElement("GetMethodFromCanonical", RuntimeMethodHandle::GetMethodFromCanonical)
FCFuncElement("IsDynamicMethod", RuntimeMethodHandle::IsDynamicMethod)
- FCFuncElement("GetMethodBody", RuntimeMethodHandle::GetMethodBody)
+ FCFuncElement("GetMethodBody", RuntimeMethodHandle::GetMethodBody)
QCFuncElement("IsCAVisibleFromDecoratedType", RuntimeMethodHandle::IsCAVisibleFromDecoratedType)
- FCFuncElement("IsConstructor", RuntimeMethodHandle::IsConstructor)
+ FCFuncElement("IsConstructor", RuntimeMethodHandle::IsConstructor)
QCFuncElement("Destroy", RuntimeMethodHandle::Destroy)
FCFuncElement("GetResolver", RuntimeMethodHandle::GetResolver)
FCFuncElement("GetLoaderAllocator", RuntimeMethodHandle::GetLoaderAllocator)
FCFuncElement("GetTypes", COMModule::GetTypes)
QCFuncElement("GetFullyQualifiedName", COMModule::GetFullyQualifiedName)
QCFuncElement("nIsTransientInternal", COMModule::IsTransient)
- FCFuncElement("IsResource", COMModule::IsResource)
+ FCFuncElement("IsResource", COMModule::IsResource)
FCFuncEnd()
FCFuncStart(gCOMModuleBuilderFuncs)
FCFuncElement("GetInMemoryAssemblyModule", AssemblyNative::GetInMemoryAssemblyModule)
FCFuncEnd()
-#ifdef MDA_SUPPORTED
+#ifdef MDA_SUPPORTED
FCFuncStart(gMda)
FCFuncElement("MemberInfoCacheCreation", MdaManagedSupport::MemberInfoCacheCreation)
FCFuncElement("DateTimeInvalidLocalFormat", MdaManagedSupport::DateTimeInvalidLocalFormat)
FCFuncElement("NotifyWorkItemComplete", ThreadPoolNative::NotifyRequestComplete)
FCFuncElement("NotifyWorkItemProgressNative", ThreadPoolNative::NotifyRequestProgress)
QCFuncElement("InitializeVMTp", ThreadPoolNative::InitializeVMTp)
- FCFuncElement("ReportThreadStatus", ThreadPoolNative::ReportThreadStatus)
+ FCFuncElement("ReportThreadStatus", ThreadPoolNative::ReportThreadStatus)
QCFuncElement("RequestWorkerThread", ThreadPoolNative::RequestWorkerThread)
FCFuncEnd()
FCFuncElement("_SuppressFinalize", GCInterface::SuppressFinalize)
FCFuncElement("_ReRegisterForFinalize", GCInterface::ReRegisterForFinalize)
-
+
FCFuncElement("_GetAllocatedBytesForCurrentThread", GCInterface::GetAllocatedBytesForCurrentThread)
FCFuncEnd()
FCFuncElement("GetObjectsForNativeVariants", MarshalNative::GetObjectsForNativeVariants)
FCFuncElement("GetStartComSlot", MarshalNative::GetStartComSlot)
FCFuncElement("GetEndComSlot", MarshalNative::GetEndComSlot)
-
+
FCFuncElement("InitializeManagedWinRTFactoryObject", MarshalNative::InitializeManagedWinRTFactoryObject)
FCFuncElement("GetNativeActivationFactory", MarshalNative::GetNativeActivationFactory)
FCFuncStart(gInterlockedFuncs)
FCIntrinsicSig("Exchange", &gsig_SM_RefInt_Int_RetInt, COMInterlocked::Exchange, CORINFO_INTRINSIC_InterlockedXchg32)
- FCIntrinsicSig("Exchange", &gsig_SM_RefLong_Long_RetLong, COMInterlocked::Exchange64, CORINFO_INTRINSIC_InterlockedXchg64)
+ FCIntrinsicSig("Exchange", &gsig_SM_RefLong_Long_RetLong, COMInterlocked::Exchange64, CORINFO_INTRINSIC_InterlockedXchg64)
FCFuncElementSig("Exchange", &gsig_SM_RefDbl_Dbl_RetDbl, COMInterlocked::ExchangeDouble)
FCFuncElementSig("Exchange", &gsig_SM_RefFlt_Flt_RetFlt, COMInterlocked::ExchangeFloat)
FCFuncElementSig("Exchange", &gsig_SM_RefObj_Obj_RetObj, COMInterlocked::ExchangeObject)
FCFuncElement("ConvertContentsToManaged", MngdHiddenLengthArrayMarshaler::ConvertContentsToManaged)
FCFuncElement("ClearNativeContents", MngdHiddenLengthArrayMarshaler::ClearNativeContents)
FCFuncEnd()
-
+
FCFuncStart(gWinRTTypeNameConverterFuncs)
FCFuncElement("ConvertToWinRTTypeName", StubHelpers::WinRTTypeNameConverter__ConvertToWinRTTypeName)
FCFuncElement("GetTypeFromWinRTTypeName", StubHelpers::WinRTTypeNameConverter__GetTypeFromWinRTTypeName)
#ifdef MDA_SUPPORTED
FCFuncElement("CheckCollectedDelegateMDA", StubHelpers::CheckCollectedDelegateMDA)
#endif // MDA_SUPPORTED
-#ifdef PROFILING_SUPPORTED
+#ifdef PROFILING_SUPPORTED
FCFuncElement("ProfilerBeginTransitionCallback", StubHelpers::ProfilerBeginTransitionCallback)
FCFuncElement("ProfilerEndTransitionCallback", StubHelpers::ProfilerEndTransitionCallback)
-#endif
+#endif
FCFuncElement("CreateCustomMarshalerHelper", StubHelpers::CreateCustomMarshalerHelper)
FCFuncElement("FmtClassUpdateNativeInternal", StubHelpers::FmtClassUpdateNativeInternal)
FCFuncElement("FmtClassUpdateCLRInternal", StubHelpers::FmtClassUpdateCLRInternal)
FCFuncElement("LayoutDestroyNativeInternal", StubHelpers::LayoutDestroyNativeInternal)
FCFuncElement("AllocateInternal", StubHelpers::AllocateInternal)
- FCFuncElement("strlen", StubHelpers::AnsiStrlen)
+ FCFuncElement("strlen", StubHelpers::AnsiStrlen)
FCFuncElement("MarshalToUnmanagedVaListInternal", StubHelpers::MarshalToUnmanagedVaListInternal)
FCFuncElement("MarshalToManagedVaListInternal", StubHelpers::MarshalToManagedVaListInternal)
FCFuncElement("CalcVaListSize", StubHelpers::CalcVaListSize)
FCClassElement("Marshal", "System.Runtime.InteropServices", gInteropMarshalFuncs)
FCClassElement("Math", "System", gMathFuncs)
FCClassElement("MathF", "System", gMathFFuncs)
-#ifdef MDA_SUPPORTED
+#ifdef MDA_SUPPORTED
FCClassElement("Mda", "System", gMda)
#endif
FCClassElement("MdUtf8String", "System", gMdUtf8String)
#ifdef FEATURE_COMINTEROP
FCClassElement("MngdHiddenLengthArrayMarshaler", "System.StubHelpers", gMngdHiddenLengthArrayMarshalerFuncs)
#endif // FEATURE_COMINTEROP
-FCClassElement("MngdNativeArrayMarshaler", "System.StubHelpers", gMngdNativeArrayMarshalerFuncs)
-FCClassElement("MngdRefCustomMarshaler", "System.StubHelpers", gMngdRefCustomMarshalerFuncs)
+FCClassElement("MngdNativeArrayMarshaler", "System.StubHelpers", gMngdNativeArrayMarshalerFuncs)
+FCClassElement("MngdRefCustomMarshaler", "System.StubHelpers", gMngdRefCustomMarshalerFuncs)
#ifdef FEATURE_COMINTEROP
-FCClassElement("MngdSafeArrayMarshaler", "System.StubHelpers", gMngdSafeArrayMarshalerFuncs)
+FCClassElement("MngdSafeArrayMarshaler", "System.StubHelpers", gMngdSafeArrayMarshalerFuncs)
#endif // FEATURE_COMINTEROP
FCClassElement("ModuleBuilder", "System.Reflection.Emit", gCOMModuleBuilderFuncs)
FCClassElement("ModuleHandle", "System", gCOMModuleHandleFuncs)
#endif // FEATURE_COMINTEROP
FCClassElement("RuntimeAssembly", "System.Reflection", gRuntimeAssemblyFuncs)
-#ifdef FEATURE_COMINTEROP
+#ifdef FEATURE_COMINTEROP
FCClassElement("RuntimeClass", "System.Runtime.InteropServices.WindowsRuntime", gRuntimeClassFuncs)
-#endif // FEATURE_COMINTEROP
+#endif // FEATURE_COMINTEROP
FCClassElement("RuntimeFieldHandle", "System", gCOMFieldHandleNewFuncs)
FCClassElement("RuntimeHelpers", "System.Runtime.CompilerServices", gCompilerFuncs)
FCClassElement("RuntimeImports", "System.Runtime", gRuntimeImportsFuncs)