summaryrefslogtreecommitdiff
path: root/src/mscorlib/src/System/Runtime/CompilerServices
diff options
context:
space:
mode:
Diffstat (limited to 'src/mscorlib/src/System/Runtime/CompilerServices')
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs31
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/AssemblyAttributesGoHere.cs43
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/AssemblySettingAttributes.cs94
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs1187
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs18
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CallerFilePathAttribute.cs17
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CallerLineNumberAttribute.cs17
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CallerMemberNameAttribute.cs17
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CallingConvention.cs30
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CompilationRelaxations.cs52
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs16
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs27
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CompilerMarshalOverride.cs23
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs795
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/CustomConstantAttribute.cs31
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/DateTimeConstantAttribute.cs48
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/DecimalConstantAttribute.cs98
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/DecoratedNameAttribute.cs18
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs18
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/DiscardableAttribute.cs19
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/ExtensionAttribute.cs13
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs14
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/FixedBufferAttribute.cs43
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/FormattableStringFactory.cs58
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/HasCopySemanticsAttribute.cs14
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IAsyncStateMachine.cs27
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/ICastable.cs82
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IDispatchConstantAttribute.cs26
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/INotifyCompletion.cs40
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IUnknownConstantAttribute.cs27
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IndexerNameAttribute.cs17
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs58
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsBoxed.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsByValue.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsConst.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsCopyConstructed.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsExplicitlyDereferenced.cs22
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsImplicitlyDereferenced.cs22
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsJitIntrinsic.cs12
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsLong.cs18
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsPinned.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsSignUnspecifiedByte.cs16
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsUdtReturn.cs11
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IsVolatile.cs13
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs18
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/MethodImplAttribute.cs77
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/NativeCppClassAttribute.cs16
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs39
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/RequiredAttributeAttribute.cs26
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs48
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs248
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/RuntimeWrappedException.cs52
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/ScopelessEnumAttribute.cs14
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/SpecialNameAttribute.cs27
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/StateMachineAttribute.cs20
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs19
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/SuppressMergeCheckAttribute.cs23
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/TaskAwaiter.cs531
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/TypeDependencyAttribute.cs29
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs35
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs47
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs14
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/YieldAwaitable.cs168
-rw-r--r--src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs224
64 files changed, 4862 insertions, 0 deletions
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs
new file mode 100644
index 0000000000..b0010fd7bd
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/AccessedThroughPropertyAttribute.cs
@@ -0,0 +1,31 @@
+// 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.Runtime.CompilerServices
+{
+ using System;
+
+ [AttributeUsage(AttributeTargets.Field)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class AccessedThroughPropertyAttribute : Attribute
+ {
+ private readonly string propertyName;
+
+ public AccessedThroughPropertyAttribute(string propertyName)
+ {
+ this.propertyName = propertyName;
+ }
+
+ public string PropertyName
+ {
+ get
+ {
+ return propertyName;
+ }
+ }
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/AssemblyAttributesGoHere.cs b/src/mscorlib/src/System/Runtime/CompilerServices/AssemblyAttributesGoHere.cs
new file mode 100644
index 0000000000..c021353475
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/AssemblyAttributesGoHere.cs
@@ -0,0 +1,43 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+namespace System.Runtime.CompilerServices {
+
+ using System;
+
+ // NOTE TO DEVELOPERS: These classes are used by ALink (the assembly linker).
+ // They're used for metadata tokens for making multi-module assemblies.
+ // Do not randomly touch these classes.
+ [System.Runtime.CompilerServices.FriendAccessAllowed]
+ internal sealed class AssemblyAttributesGoHere
+ {
+
+ internal AssemblyAttributesGoHere()
+ {
+ }
+ }
+ [System.Runtime.CompilerServices.FriendAccessAllowed]
+ internal sealed class AssemblyAttributesGoHereS
+ {
+ internal AssemblyAttributesGoHereS()
+ {
+ }
+ }
+ [System.Runtime.CompilerServices.FriendAccessAllowed]
+ internal sealed class AssemblyAttributesGoHereM
+ {
+ internal AssemblyAttributesGoHereM()
+ {
+ }
+ }
+ [System.Runtime.CompilerServices.FriendAccessAllowed]
+ internal sealed class AssemblyAttributesGoHereSM
+ {
+ internal AssemblyAttributesGoHereSM()
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/AssemblySettingAttributes.cs b/src/mscorlib/src/System/Runtime/CompilerServices/AssemblySettingAttributes.cs
new file mode 100644
index 0000000000..5251122629
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/AssemblySettingAttributes.cs
@@ -0,0 +1,94 @@
+// 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.Runtime.CompilerServices
+{
+
+ using System;
+ using System.Runtime.InteropServices;
+
+ /*
+ NGenHint is not supported in Whidbey
+
+ [Serializable]
+ public enum NGenHint
+ {
+ Default = 0x0000, // No preference specified
+
+ Eager = 0x0001, // NGen at install time
+ Lazy = 0x0002, // NGen after install time
+ Never = 0x0003, // Assembly should not be ngened
+ }
+ */
+
+ [Serializable]
+ public enum LoadHint
+ {
+ Default = 0x0000, // No preference specified
+
+ Always = 0x0001, // Dependency is always loaded
+ Sometimes = 0x0002, // Dependency is sometimes loaded
+ //Never = 0x0003, // Dependency is never loaded
+ }
+
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Assembly)]
+ public sealed class DefaultDependencyAttribute : Attribute
+ {
+ private LoadHint loadHint;
+
+ public DefaultDependencyAttribute (
+ LoadHint loadHintArgument
+ )
+ {
+ loadHint = loadHintArgument;
+ }
+
+ public LoadHint LoadHint
+ {
+ get
+ {
+ return loadHint;
+ }
+ }
+ }
+
+
+[Serializable]
+[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
+ public sealed class DependencyAttribute : Attribute
+ {
+ private String dependentAssembly;
+ private LoadHint loadHint;
+
+ public DependencyAttribute (
+ String dependentAssemblyArgument,
+ LoadHint loadHintArgument
+ )
+ {
+ dependentAssembly = dependentAssemblyArgument;
+ loadHint = loadHintArgument;
+ }
+
+ public String DependentAssembly
+ {
+ get
+ {
+ return dependentAssembly;
+ }
+ }
+
+ public LoadHint LoadHint
+ {
+ get
+ {
+ return loadHint;
+ }
+ }
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs b/src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs
new file mode 100644
index 0000000000..05850605b8
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/AsyncMethodBuilder.cs
@@ -0,0 +1,1187 @@
+// 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.
+
+// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+//
+//
+//
+// Compiler-targeted types that build tasks for use as the return types of asynchronous methods.
+//
+// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Runtime.ExceptionServices;
+using System.Security;
+using System.Security.Permissions;
+using System.Threading;
+using System.Threading.Tasks;
+
+#if FEATURE_COMINTEROP
+using System.Runtime.InteropServices.WindowsRuntime;
+#endif // FEATURE_COMINTEROP
+
+namespace System.Runtime.CompilerServices
+{
+ /// <summary>
+ /// Provides a builder for asynchronous methods that return void.
+ /// This type is intended for compiler use only.
+ /// </summary>
+ [HostProtection(Synchronization = true, ExternalThreading = true)]
+ public struct AsyncVoidMethodBuilder
+ {
+ /// <summary>The synchronization context associated with this operation.</summary>
+ private SynchronizationContext m_synchronizationContext;
+ /// <summary>State related to the IAsyncStateMachine.</summary>
+ private AsyncMethodBuilderCore m_coreState; // mutable struct: must not be readonly
+ /// <summary>Task used for debugging and logging purposes only. Lazily initialized.</summary>
+ private Task m_task;
+
+ /// <summary>Initializes a new <see cref="AsyncVoidMethodBuilder"/>.</summary>
+ /// <returns>The initialized <see cref="AsyncVoidMethodBuilder"/>.</returns>
+ public static AsyncVoidMethodBuilder Create()
+ {
+ // Capture the current sync context. If there isn't one, use the dummy s_noContextCaptured
+ // instance; this allows us to tell the state of no captured context apart from the state
+ // of an improperly constructed builder instance.
+ SynchronizationContext sc = SynchronizationContext.CurrentNoFlow;
+ if (sc != null)
+ sc.OperationStarted();
+ return new AsyncVoidMethodBuilder() { m_synchronizationContext = sc };
+ }
+
+ /// <summary>Initiates the builder's execution with the associated state machine.</summary>
+ /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
+ /// <param name="stateMachine">The state machine instance, passed by reference.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception>
+ [SecuritySafeCritical]
+ [DebuggerStepThrough]
+ public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
+ {
+ // See comment on AsyncMethodBuilderCore.Start
+ // AsyncMethodBuilderCore.Start(ref stateMachine);
+
+ if (stateMachine == null) throw new ArgumentNullException("stateMachine");
+ Contract.EndContractBlock();
+
+ // Run the MoveNext method within a copy-on-write ExecutionContext scope.
+ // This allows us to undo any ExecutionContext changes made in MoveNext,
+ // so that they won't "leak" out of the first await.
+
+ Thread currentThread = Thread.CurrentThread;
+ ExecutionContextSwitcher ecs = default(ExecutionContextSwitcher);
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ ExecutionContext.EstablishCopyOnWriteScope(currentThread, ref ecs);
+ stateMachine.MoveNext();
+ }
+ finally
+ {
+ ecs.Undo(currentThread);
+ }
+ }
+
+ /// <summary>Associates the builder with the state machine it represents.</summary>
+ /// <param name="stateMachine">The heap-allocated state machine object.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.InvalidOperationException">The builder is incorrectly initialized.</exception>
+ public void SetStateMachine(IAsyncStateMachine stateMachine)
+ {
+ m_coreState.SetStateMachine(stateMachine); // argument validation handled by AsyncMethodBuilderCore
+ }
+
+ /// <summary>
+ /// Schedules the specified state machine to be pushed forward when the specified awaiter completes.
+ /// </summary>
+ /// <typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
+ /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
+ /// <param name="awaiter">The awaiter.</param>
+ /// <param name="stateMachine">The state machine.</param>
+ public void AwaitOnCompleted<TAwaiter, TStateMachine>(
+ ref TAwaiter awaiter, ref TStateMachine stateMachine)
+ where TAwaiter : INotifyCompletion
+ where TStateMachine : IAsyncStateMachine
+ {
+ try
+ {
+ AsyncMethodBuilderCore.MoveNextRunner runnerToInitialize = null;
+ var continuation = m_coreState.GetCompletionAction(AsyncCausalityTracer.LoggingOn ? this.Task : null, ref runnerToInitialize);
+ Contract.Assert(continuation != null, "GetCompletionAction should always return a valid action.");
+
+ // If this is our first await, such that we've not yet boxed the state machine, do so now.
+ if (m_coreState.m_stateMachine == null)
+ {
+ if (AsyncCausalityTracer.LoggingOn)
+ AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, this.Task.Id, "Async: " + stateMachine.GetType().Name, 0);
+
+ // Box the state machine, then tell the boxed instance to call back into its own builder,
+ // so we can cache the boxed reference. NOTE: The language compiler may choose to use
+ // a class instead of a struct for the state machine for debugging purposes; in such cases,
+ // the stateMachine will already be an object.
+ m_coreState.PostBoxInitialization(stateMachine, runnerToInitialize, null);
+ }
+
+ awaiter.OnCompleted(continuation);
+ }
+ catch (Exception exc)
+ {
+ // Prevent exceptions from leaking to the call site, which could
+ // then allow multiple flows of execution through the same async method
+ // if the awaiter had already scheduled the continuation by the time
+ // the exception was thrown. We propagate the exception on the
+ // ThreadPool because we can trust it to not throw, unlike
+ // if we were to go to a user-supplied SynchronizationContext,
+ // whose Post method could easily throw.
+ AsyncMethodBuilderCore.ThrowAsync(exc, targetContext: null);
+ }
+ }
+
+ /// <summary>
+ /// Schedules the specified state machine to be pushed forward when the specified awaiter completes.
+ /// </summary>
+ /// <typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
+ /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
+ /// <param name="awaiter">The awaiter.</param>
+ /// <param name="stateMachine">The state machine.</param>
+ [SecuritySafeCritical]
+ public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
+ ref TAwaiter awaiter, ref TStateMachine stateMachine)
+ where TAwaiter : ICriticalNotifyCompletion
+ where TStateMachine : IAsyncStateMachine
+ {
+ try
+ {
+ AsyncMethodBuilderCore.MoveNextRunner runnerToInitialize = null;
+ var continuation = m_coreState.GetCompletionAction(AsyncCausalityTracer.LoggingOn ? this.Task : null, ref runnerToInitialize);
+ Contract.Assert(continuation != null, "GetCompletionAction should always return a valid action.");
+
+ // If this is our first await, such that we've not yet boxed the state machine, do so now.
+ if (m_coreState.m_stateMachine == null)
+ {
+ if (AsyncCausalityTracer.LoggingOn)
+ AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, this.Task.Id, "Async: " + stateMachine.GetType().Name, 0);
+
+ // Box the state machine, then tell the boxed instance to call back into its own builder,
+ // so we can cache the boxed reference. NOTE: The language compiler may choose to use
+ // a class instead of a struct for the state machine for debugging purposes; in such cases,
+ // the stateMachine will already be an object.
+ m_coreState.PostBoxInitialization(stateMachine, runnerToInitialize, null);
+ }
+
+ awaiter.UnsafeOnCompleted(continuation);
+ }
+ catch (Exception e)
+ {
+ AsyncMethodBuilderCore.ThrowAsync(e, targetContext: null);
+ }
+ }
+
+ /// <summary>Completes the method builder successfully.</summary>
+ public void SetResult()
+ {
+ if (AsyncCausalityTracer.LoggingOn)
+ AsyncCausalityTracer.TraceOperationCompletion(CausalityTraceLevel.Required, this.Task.Id, AsyncCausalityStatus.Completed);
+
+ if (m_synchronizationContext != null)
+ {
+ NotifySynchronizationContextOfCompletion();
+ }
+ }
+
+ /// <summary>Faults the method builder with an exception.</summary>
+ /// <param name="exception">The exception that is the cause of this fault.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="exception"/> argument is null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.InvalidOperationException">The builder is not initialized.</exception>
+ public void SetException(Exception exception)
+ {
+ if (exception == null) throw new ArgumentNullException("exception");
+ Contract.EndContractBlock();
+
+ if (AsyncCausalityTracer.LoggingOn)
+ AsyncCausalityTracer.TraceOperationCompletion(CausalityTraceLevel.Required, this.Task.Id, AsyncCausalityStatus.Error);
+
+ if (m_synchronizationContext != null)
+ {
+ // If we captured a synchronization context, Post the throwing of the exception to it
+ // and decrement its outstanding operation count.
+ try
+ {
+ AsyncMethodBuilderCore.ThrowAsync(exception, targetContext: m_synchronizationContext);
+ }
+ finally
+ {
+ NotifySynchronizationContextOfCompletion();
+ }
+ }
+ else
+ {
+ // Otherwise, queue the exception to be thrown on the ThreadPool. This will
+ // result in a crash unless legacy exception behavior is enabled by a config
+ // file or a CLR host.
+ AsyncMethodBuilderCore.ThrowAsync(exception, targetContext: null);
+ }
+ }
+
+ /// <summary>Notifies the current synchronization context that the operation completed.</summary>
+ private void NotifySynchronizationContextOfCompletion()
+ {
+ Contract.Assert(m_synchronizationContext != null, "Must only be used with a non-null context.");
+ try
+ {
+ m_synchronizationContext.OperationCompleted();
+ }
+ catch (Exception exc)
+ {
+ // If the interaction with the SynchronizationContext goes awry,
+ // fall back to propagating on the ThreadPool.
+ AsyncMethodBuilderCore.ThrowAsync(exc, targetContext: null);
+ }
+ }
+
+ // This property lazily instantiates the Task in a non-thread-safe manner.
+ private Task Task
+ {
+ get
+ {
+ if (m_task == null) m_task = new Task();
+ return m_task;
+ }
+ }
+
+ /// <summary>
+ /// Gets an object that may be used to uniquely identify this builder to the debugger.
+ /// </summary>
+ /// <remarks>
+ /// This property lazily instantiates the ID in a non-thread-safe manner.
+ /// It must only be used by the debugger and AsyncCausalityTracer in a single-threaded manner.
+ /// </remarks>
+ private object ObjectIdForDebugger { get { return this.Task; } }
+ }
+
+ /// <summary>
+ /// Provides a builder for asynchronous methods that return <see cref="System.Threading.Tasks.Task"/>.
+ /// This type is intended for compiler use only.
+ /// </summary>
+ /// <remarks>
+ /// AsyncTaskMethodBuilder is a value type, and thus it is copied by value.
+ /// Prior to being copied, one of its Task, SetResult, or SetException members must be accessed,
+ /// or else the copies may end up building distinct Task instances.
+ /// </remarks>
+ [HostProtection(Synchronization = true, ExternalThreading = true)]
+ public struct AsyncTaskMethodBuilder
+ {
+ /// <summary>A cached VoidTaskResult task used for builders that complete synchronously.</summary>
+ private readonly static Task<VoidTaskResult> s_cachedCompleted = AsyncTaskMethodBuilder<VoidTaskResult>.s_defaultResultTask;
+
+ /// <summary>The generic builder object to which this non-generic instance delegates.</summary>
+ private AsyncTaskMethodBuilder<VoidTaskResult> m_builder; // mutable struct: must not be readonly
+
+ /// <summary>Initializes a new <see cref="AsyncTaskMethodBuilder"/>.</summary>
+ /// <returns>The initialized <see cref="AsyncTaskMethodBuilder"/>.</returns>
+ public static AsyncTaskMethodBuilder Create()
+ {
+ return default(AsyncTaskMethodBuilder);
+ // Note: If ATMB<T>.Create is modified to do any initialization, this
+ // method needs to be updated to do m_builder = ATMB<T>.Create().
+ }
+
+ /// <summary>Initiates the builder's execution with the associated state machine.</summary>
+ /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
+ /// <param name="stateMachine">The state machine instance, passed by reference.</param>
+ [SecuritySafeCritical]
+ [DebuggerStepThrough]
+ public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
+ {
+ // See comment on AsyncMethodBuilderCore.Start
+ // AsyncMethodBuilderCore.Start(ref stateMachine);
+
+ if (stateMachine == null) throw new ArgumentNullException("stateMachine");
+ Contract.EndContractBlock();
+
+ // Run the MoveNext method within a copy-on-write ExecutionContext scope.
+ // This allows us to undo any ExecutionContext changes made in MoveNext,
+ // so that they won't "leak" out of the first await.
+
+ Thread currentThread = Thread.CurrentThread;
+ ExecutionContextSwitcher ecs = default(ExecutionContextSwitcher);
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ ExecutionContext.EstablishCopyOnWriteScope(currentThread, ref ecs);
+ stateMachine.MoveNext();
+ }
+ finally
+ {
+ ecs.Undo(currentThread);
+ }
+ }
+
+ /// <summary>Associates the builder with the state machine it represents.</summary>
+ /// <param name="stateMachine">The heap-allocated state machine object.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.InvalidOperationException">The builder is incorrectly initialized.</exception>
+ public void SetStateMachine(IAsyncStateMachine stateMachine)
+ {
+ m_builder.SetStateMachine(stateMachine); // argument validation handled by AsyncMethodBuilderCore
+ }
+
+ /// <summary>
+ /// Schedules the specified state machine to be pushed forward when the specified awaiter completes.
+ /// </summary>
+ /// <typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
+ /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
+ /// <param name="awaiter">The awaiter.</param>
+ /// <param name="stateMachine">The state machine.</param>
+ public void AwaitOnCompleted<TAwaiter, TStateMachine>(
+ ref TAwaiter awaiter, ref TStateMachine stateMachine)
+ where TAwaiter : INotifyCompletion
+ where TStateMachine : IAsyncStateMachine
+ {
+ m_builder.AwaitOnCompleted<TAwaiter, TStateMachine>(ref awaiter, ref stateMachine);
+ }
+
+ /// <summary>
+ /// Schedules the specified state machine to be pushed forward when the specified awaiter completes.
+ /// </summary>
+ /// <typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
+ /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
+ /// <param name="awaiter">The awaiter.</param>
+ /// <param name="stateMachine">The state machine.</param>
+ public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
+ ref TAwaiter awaiter, ref TStateMachine stateMachine)
+ where TAwaiter : ICriticalNotifyCompletion
+ where TStateMachine : IAsyncStateMachine
+ {
+ m_builder.AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(ref awaiter, ref stateMachine);
+ }
+
+ /// <summary>Gets the <see cref="System.Threading.Tasks.Task"/> for this builder.</summary>
+ /// <returns>The <see cref="System.Threading.Tasks.Task"/> representing the builder's asynchronous operation.</returns>
+ /// <exception cref="System.InvalidOperationException">The builder is not initialized.</exception>
+ public Task Task { get { return m_builder.Task; } }
+
+ /// <summary>
+ /// Completes the <see cref="System.Threading.Tasks.Task"/> in the
+ /// <see cref="System.Threading.Tasks.TaskStatus">RanToCompletion</see> state.
+ /// </summary>
+ /// <exception cref="System.InvalidOperationException">The builder is not initialized.</exception>
+ /// <exception cref="System.InvalidOperationException">The task has already completed.</exception>
+ public void SetResult()
+ {
+ // Accessing AsyncTaskMethodBuilder.s_cachedCompleted is faster than
+ // accessing AsyncTaskMethodBuilder<T>.s_defaultResultTask.
+ m_builder.SetResult(s_cachedCompleted);
+ }
+
+ /// <summary>
+ /// Completes the <see cref="System.Threading.Tasks.Task"/> in the
+ /// <see cref="System.Threading.Tasks.TaskStatus">Faulted</see> state with the specified exception.
+ /// </summary>
+ /// <param name="exception">The <see cref="System.Exception"/> to use to fault the task.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="exception"/> argument is null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.InvalidOperationException">The builder is not initialized.</exception>
+ /// <exception cref="System.InvalidOperationException">The task has already completed.</exception>
+ public void SetException(Exception exception) { m_builder.SetException(exception); }
+
+ /// <summary>
+ /// Called by the debugger to request notification when the first wait operation
+ /// (await, Wait, Result, etc.) on this builder's task completes.
+ /// </summary>
+ /// <param name="enabled">
+ /// true to enable notification; false to disable a previously set notification.
+ /// </param>
+ internal void SetNotificationForWaitCompletion(bool enabled)
+ {
+ m_builder.SetNotificationForWaitCompletion(enabled);
+ }
+
+ /// <summary>
+ /// Gets an object that may be used to uniquely identify this builder to the debugger.
+ /// </summary>
+ /// <remarks>
+ /// This property lazily instantiates the ID in a non-thread-safe manner.
+ /// It must only be used by the debugger and tracing pruposes, and only in a single-threaded manner
+ /// when no other threads are in the middle of accessing this property or this.Task.
+ /// </remarks>
+ private object ObjectIdForDebugger { get { return this.Task; } }
+ }
+
+ /// <summary>
+ /// Provides a builder for asynchronous methods that return <see cref="System.Threading.Tasks.Task{TResult}"/>.
+ /// This type is intended for compiler use only.
+ /// </summary>
+ /// <remarks>
+ /// AsyncTaskMethodBuilder{TResult} is a value type, and thus it is copied by value.
+ /// Prior to being copied, one of its Task, SetResult, or SetException members must be accessed,
+ /// or else the copies may end up building distinct Task instances.
+ /// </remarks>
+ [HostProtection(Synchronization = true, ExternalThreading = true)]
+ public struct AsyncTaskMethodBuilder<TResult>
+ {
+ /// <summary>A cached task for default(TResult).</summary>
+ internal readonly static Task<TResult> s_defaultResultTask = AsyncTaskCache.CreateCacheableTask(default(TResult));
+
+ // WARNING: For performance reasons, the m_task field is lazily initialized.
+ // For correct results, the struct AsyncTaskMethodBuilder<TResult> must
+ // always be used from the same location/copy, at least until m_task is
+ // initialized. If that guarantee is broken, the field could end up being
+ // initialized on the wrong copy.
+
+ /// <summary>State related to the IAsyncStateMachine.</summary>
+ private AsyncMethodBuilderCore m_coreState; // mutable struct: must not be readonly
+ /// <summary>The lazily-initialized built task.</summary>
+ private Task<TResult> m_task; // lazily-initialized: must not be readonly
+
+ /// <summary>Initializes a new <see cref="AsyncTaskMethodBuilder"/>.</summary>
+ /// <returns>The initialized <see cref="AsyncTaskMethodBuilder"/>.</returns>
+ public static AsyncTaskMethodBuilder<TResult> Create()
+ {
+ return default(AsyncTaskMethodBuilder<TResult>);
+ // NOTE: If this method is ever updated to perform more initialization,
+ // ATMB.Create must also be updated to call this Create method.
+ }
+
+ /// <summary>Initiates the builder's execution with the associated state machine.</summary>
+ /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
+ /// <param name="stateMachine">The state machine instance, passed by reference.</param>
+ [SecuritySafeCritical]
+ [DebuggerStepThrough]
+ public void Start<TStateMachine>(ref TStateMachine stateMachine) where TStateMachine : IAsyncStateMachine
+ {
+ // See comment on AsyncMethodBuilderCore.Start
+ // AsyncMethodBuilderCore.Start(ref stateMachine);
+
+ if (stateMachine == null) throw new ArgumentNullException("stateMachine");
+ Contract.EndContractBlock();
+
+ // Run the MoveNext method within a copy-on-write ExecutionContext scope.
+ // This allows us to undo any ExecutionContext changes made in MoveNext,
+ // so that they won't "leak" out of the first await.
+
+ Thread currentThread = Thread.CurrentThread;
+ ExecutionContextSwitcher ecs = default(ExecutionContextSwitcher);
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ ExecutionContext.EstablishCopyOnWriteScope(currentThread, ref ecs);
+ stateMachine.MoveNext();
+ }
+ finally
+ {
+ ecs.Undo(currentThread);
+ }
+ }
+
+ /// <summary>Associates the builder with the state machine it represents.</summary>
+ /// <param name="stateMachine">The heap-allocated state machine object.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.InvalidOperationException">The builder is incorrectly initialized.</exception>
+ public void SetStateMachine(IAsyncStateMachine stateMachine)
+ {
+ m_coreState.SetStateMachine(stateMachine); // argument validation handled by AsyncMethodBuilderCore
+ }
+
+ /// <summary>
+ /// Schedules the specified state machine to be pushed forward when the specified awaiter completes.
+ /// </summary>
+ /// <typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
+ /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
+ /// <param name="awaiter">The awaiter.</param>
+ /// <param name="stateMachine">The state machine.</param>
+ public void AwaitOnCompleted<TAwaiter, TStateMachine>(
+ ref TAwaiter awaiter, ref TStateMachine stateMachine)
+ where TAwaiter : INotifyCompletion
+ where TStateMachine : IAsyncStateMachine
+ {
+ try
+ {
+ AsyncMethodBuilderCore.MoveNextRunner runnerToInitialize = null;
+ var continuation = m_coreState.GetCompletionAction(AsyncCausalityTracer.LoggingOn ? this.Task : null, ref runnerToInitialize);
+ Contract.Assert(continuation != null, "GetCompletionAction should always return a valid action.");
+
+ // If this is our first await, such that we've not yet boxed the state machine, do so now.
+ if (m_coreState.m_stateMachine == null)
+ {
+ // Force the Task to be initialized prior to the first suspending await so
+ // that the original stack-based builder has a reference to the right Task.
+ var builtTask = this.Task;
+
+ // Box the state machine, then tell the boxed instance to call back into its own builder,
+ // so we can cache the boxed reference. NOTE: The language compiler may choose to use
+ // a class instead of a struct for the state machine for debugging purposes; in such cases,
+ // the stateMachine will already be an object.
+ m_coreState.PostBoxInitialization(stateMachine, runnerToInitialize, builtTask);
+ }
+
+ awaiter.OnCompleted(continuation);
+ }
+ catch (Exception e)
+ {
+ AsyncMethodBuilderCore.ThrowAsync(e, targetContext: null);
+ }
+ }
+
+ /// <summary>
+ /// Schedules the specified state machine to be pushed forward when the specified awaiter completes.
+ /// </summary>
+ /// <typeparam name="TAwaiter">Specifies the type of the awaiter.</typeparam>
+ /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
+ /// <param name="awaiter">The awaiter.</param>
+ /// <param name="stateMachine">The state machine.</param>
+ [SecuritySafeCritical]
+ public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
+ ref TAwaiter awaiter, ref TStateMachine stateMachine)
+ where TAwaiter : ICriticalNotifyCompletion
+ where TStateMachine : IAsyncStateMachine
+ {
+ try
+ {
+ AsyncMethodBuilderCore.MoveNextRunner runnerToInitialize = null;
+ var continuation = m_coreState.GetCompletionAction(AsyncCausalityTracer.LoggingOn ? this.Task : null, ref runnerToInitialize);
+ Contract.Assert(continuation != null, "GetCompletionAction should always return a valid action.");
+
+ // If this is our first await, such that we've not yet boxed the state machine, do so now.
+ if (m_coreState.m_stateMachine == null)
+ {
+ // Force the Task to be initialized prior to the first suspending await so
+ // that the original stack-based builder has a reference to the right Task.
+ var builtTask = this.Task;
+
+ // Box the state machine, then tell the boxed instance to call back into its own builder,
+ // so we can cache the boxed reference. NOTE: The language compiler may choose to use
+ // a class instead of a struct for the state machine for debugging purposes; in such cases,
+ // the stateMachine will already be an object.
+ m_coreState.PostBoxInitialization(stateMachine, runnerToInitialize, builtTask);
+ }
+
+ awaiter.UnsafeOnCompleted(continuation);
+ }
+ catch (Exception e)
+ {
+ AsyncMethodBuilderCore.ThrowAsync(e, targetContext: null);
+ }
+ }
+
+ /// <summary>Gets the <see cref="System.Threading.Tasks.Task{TResult}"/> for this builder.</summary>
+ /// <returns>The <see cref="System.Threading.Tasks.Task{TResult}"/> representing the builder's asynchronous operation.</returns>
+ public Task<TResult> Task
+ {
+ get
+ {
+ // Get and return the task. If there isn't one, first create one and store it.
+ var task = m_task;
+ if (task == null) { m_task = task = new Task<TResult>(); }
+ return task;
+ }
+ }
+
+ /// <summary>
+ /// Completes the <see cref="System.Threading.Tasks.Task{TResult}"/> in the
+ /// <see cref="System.Threading.Tasks.TaskStatus">RanToCompletion</see> state with the specified result.
+ /// </summary>
+ /// <param name="result">The result to use to complete the task.</param>
+ /// <exception cref="System.InvalidOperationException">The task has already completed.</exception>
+ public void SetResult(TResult result)
+ {
+ // Get the currently stored task, which will be non-null if get_Task has already been accessed.
+ // If there isn't one, get a task and store it.
+ var task = m_task;
+ if (task == null)
+ {
+ m_task = GetTaskForResult(result);
+ Contract.Assert(m_task != null, "GetTaskForResult should never return null");
+ }
+ // Slow path: complete the existing task.
+ else
+ {
+ if (AsyncCausalityTracer.LoggingOn)
+ AsyncCausalityTracer.TraceOperationCompletion(CausalityTraceLevel.Required, task.Id, AsyncCausalityStatus.Completed);
+
+ //only log if we have a real task that was previously created
+ if (System.Threading.Tasks.Task.s_asyncDebuggingEnabled)
+ {
+ System.Threading.Tasks.Task.RemoveFromActiveTasks(task.Id);
+ }
+
+ if (!task.TrySetResult(result))
+ {
+ throw new InvalidOperationException(Environment.GetResourceString("TaskT_TransitionToFinal_AlreadyCompleted"));
+ }
+ }
+ }
+
+ /// <summary>
+ /// Completes the builder by using either the supplied completed task, or by completing
+ /// the builder's previously accessed task using default(TResult).
+ /// </summary>
+ /// <param name="completedTask">A task already completed with the value default(TResult).</param>
+ /// <exception cref="System.InvalidOperationException">The task has already completed.</exception>
+ internal void SetResult(Task<TResult> completedTask)
+ {
+ Contract.Requires(completedTask != null, "Expected non-null task");
+ Contract.Requires(completedTask.Status == TaskStatus.RanToCompletion, "Expected a successfully completed task");
+
+ // Get the currently stored task, which will be non-null if get_Task has already been accessed.
+ // If there isn't one, store the supplied completed task.
+ var task = m_task;
+ if (task == null)
+ {
+ m_task = completedTask;
+ }
+ else
+ {
+ // Otherwise, complete the task that's there.
+ SetResult(default(TResult));
+ }
+ }
+
+ /// <summary>
+ /// Completes the <see cref="System.Threading.Tasks.Task{TResult}"/> in the
+ /// <see cref="System.Threading.Tasks.TaskStatus">Faulted</see> state with the specified exception.
+ /// </summary>
+ /// <param name="exception">The <see cref="System.Exception"/> to use to fault the task.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="exception"/> argument is null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.InvalidOperationException">The task has already completed.</exception>
+ public void SetException(Exception exception)
+ {
+ if (exception == null) throw new ArgumentNullException("exception");
+ Contract.EndContractBlock();
+
+
+ var task = m_task;
+ if (task == null)
+ {
+ // Get the task, forcing initialization if it hasn't already been initialized.
+ task = this.Task;
+ }
+
+ // If the exception represents cancellation, cancel the task. Otherwise, fault the task.
+ var oce = exception as OperationCanceledException;
+ bool successfullySet = oce != null ?
+ task.TrySetCanceled(oce.CancellationToken, oce) :
+ task.TrySetException(exception);
+
+ // Unlike with TaskCompletionSource, we do not need to spin here until m_task is completed,
+ // since AsyncTaskMethodBuilder.SetException should not be immediately followed by any code
+ // that depends on the task having completely completed. Moreover, with correct usage,
+ // SetResult or SetException should only be called once, so the Try* methods should always
+ // return true, so no spinning would be necessary anyway (the spinning in TCS is only relevant
+ // if another thread completes the task first).
+
+ if (!successfullySet)
+ {
+ throw new InvalidOperationException(Environment.GetResourceString("TaskT_TransitionToFinal_AlreadyCompleted"));
+ }
+ }
+
+ /// <summary>
+ /// Called by the debugger to request notification when the first wait operation
+ /// (await, Wait, Result, etc.) on this builder's task completes.
+ /// </summary>
+ /// <param name="enabled">
+ /// true to enable notification; false to disable a previously set notification.
+ /// </param>
+ /// <remarks>
+ /// This should only be invoked from within an asynchronous method,
+ /// and only by the debugger.
+ /// </remarks>
+ internal void SetNotificationForWaitCompletion(bool enabled)
+ {
+ // Get the task (forcing initialization if not already initialized), and set debug notification
+ this.Task.SetNotificationForWaitCompletion(enabled);
+ }
+
+ /// <summary>
+ /// Gets an object that may be used to uniquely identify this builder to the debugger.
+ /// </summary>
+ /// <remarks>
+ /// This property lazily instantiates the ID in a non-thread-safe manner.
+ /// It must only be used by the debugger and tracing purposes, and only in a single-threaded manner
+ /// when no other threads are in the middle of accessing this property or this.Task.
+ /// </remarks>
+ private object ObjectIdForDebugger { get { return this.Task; } }
+
+ /// <summary>
+ /// Gets a task for the specified result. This will either
+ /// be a cached or new task, never null.
+ /// </summary>
+ /// <param name="result">The result for which we need a task.</param>
+ /// <returns>The completed task containing the result.</returns>
+ [SecuritySafeCritical] // for JitHelpers.UnsafeCast
+ private Task<TResult> GetTaskForResult(TResult result)
+ {
+ Contract.Ensures(
+ EqualityComparer<TResult>.Default.Equals(result, Contract.Result<Task<TResult>>().Result),
+ "The returned task's Result must return the same value as the specified result value.");
+
+ // The goal of this function is to be give back a cached task if possible,
+ // or to otherwise give back a new task. To give back a cached task,
+ // we need to be able to evaluate the incoming result value, and we need
+ // to avoid as much overhead as possible when doing so, as this function
+ // is invoked as part of the return path from every async method.
+ // Most tasks won't be cached, and thus we need the checks for those that are
+ // to be as close to free as possible. This requires some trickiness given the
+ // lack of generic specialization in .NET.
+ //
+ // Be very careful when modifying this code. It has been tuned
+ // to comply with patterns recognized by both 32-bit and 64-bit JITs.
+ // If changes are made here, be sure to look at the generated assembly, as
+ // small tweaks can have big consequences for what does and doesn't get optimized away.
+ //
+ // Note that this code only ever accesses a static field when it knows it'll
+ // find a cached value, since static fields (even if readonly and integral types)
+ // require special access helpers in this NGEN'd and domain-neutral.
+
+ if (null != (object)default(TResult)) // help the JIT avoid the value type branches for ref types
+ {
+ // Special case simple value types:
+ // - Boolean
+ // - Byte, SByte
+ // - Char
+ // - Decimal
+ // - Int32, UInt32
+ // - Int64, UInt64
+ // - Int16, UInt16
+ // - IntPtr, UIntPtr
+ // As of .NET 4.5, the (Type)(object)result pattern used below
+ // is recognized and optimized by both 32-bit and 64-bit JITs.
+
+ // For Boolean, we cache all possible values.
+ if (typeof(TResult) == typeof(Boolean)) // only the relevant branches are kept for each value-type generic instantiation
+ {
+ Boolean value = (Boolean)(object)result;
+ Task<Boolean> task = value ? AsyncTaskCache.TrueTask : AsyncTaskCache.FalseTask;
+ return JitHelpers.UnsafeCast<Task<TResult>>(task); // UnsafeCast avoids type check we know will succeed
+ }
+ // For Int32, we cache a range of common values, e.g. [-1,4).
+ else if (typeof(TResult) == typeof(Int32))
+ {
+ // Compare to constants to avoid static field access if outside of cached range.
+ // We compare to the upper bound first, as we're more likely to cache miss on the upper side than on the
+ // lower side, due to positive values being more common than negative as return values.
+ Int32 value = (Int32)(object)result;
+ if (value < AsyncTaskCache.EXCLUSIVE_INT32_MAX &&
+ value >= AsyncTaskCache.INCLUSIVE_INT32_MIN)
+ {
+ Task<Int32> task = AsyncTaskCache.Int32Tasks[value - AsyncTaskCache.INCLUSIVE_INT32_MIN];
+ return JitHelpers.UnsafeCast<Task<TResult>>(task); // UnsafeCast avoids a type check we know will succeed
+ }
+ }
+ // For other known value types, we only special-case 0 / default(TResult).
+ else if (
+ (typeof(TResult) == typeof(UInt32) && default(UInt32) == (UInt32)(object)result) ||
+ (typeof(TResult) == typeof(Byte) && default(Byte) == (Byte)(object)result) ||
+ (typeof(TResult) == typeof(SByte) && default(SByte) == (SByte)(object)result) ||
+ (typeof(TResult) == typeof(Char) && default(Char) == (Char)(object)result) ||
+ (typeof(TResult) == typeof(Decimal) && default(Decimal) == (Decimal)(object)result) ||
+ (typeof(TResult) == typeof(Int64) && default(Int64) == (Int64)(object)result) ||
+ (typeof(TResult) == typeof(UInt64) && default(UInt64) == (UInt64)(object)result) ||
+ (typeof(TResult) == typeof(Int16) && default(Int16) == (Int16)(object)result) ||
+ (typeof(TResult) == typeof(UInt16) && default(UInt16) == (UInt16)(object)result) ||
+ (typeof(TResult) == typeof(IntPtr) && default(IntPtr) == (IntPtr)(object)result) ||
+ (typeof(TResult) == typeof(UIntPtr) && default(UIntPtr) == (UIntPtr)(object)result))
+ {
+ return s_defaultResultTask;
+ }
+ }
+ else if (result == null) // optimized away for value types
+ {
+ return s_defaultResultTask;
+ }
+
+ // No cached task is available. Manufacture a new one for this result.
+ return new Task<TResult>(result);
+ }
+ }
+
+ /// <summary>Provides a cache of closed generic tasks for async methods.</summary>
+ internal static class AsyncTaskCache
+ {
+ // All static members are initialized inline to ensure type is beforefieldinit
+
+ /// <summary>A cached Task{Boolean}.Result == true.</summary>
+ internal readonly static Task<Boolean> TrueTask = CreateCacheableTask(true);
+ /// <summary>A cached Task{Boolean}.Result == false.</summary>
+ internal readonly static Task<Boolean> FalseTask = CreateCacheableTask(false);
+
+ /// <summary>The cache of Task{Int32}.</summary>
+ internal readonly static Task<Int32>[] Int32Tasks = CreateInt32Tasks();
+ /// <summary>The minimum value, inclusive, for which we want a cached task.</summary>
+ internal const Int32 INCLUSIVE_INT32_MIN = -1;
+ /// <summary>The maximum value, exclusive, for which we want a cached task.</summary>
+ internal const Int32 EXCLUSIVE_INT32_MAX = 9;
+ /// <summary>Creates an array of cached tasks for the values in the range [INCLUSIVE_MIN,EXCLUSIVE_MAX).</summary>
+ private static Task<Int32>[] CreateInt32Tasks()
+ {
+ Contract.Assert(EXCLUSIVE_INT32_MAX >= INCLUSIVE_INT32_MIN, "Expected max to be at least min");
+ var tasks = new Task<Int32>[EXCLUSIVE_INT32_MAX - INCLUSIVE_INT32_MIN];
+ for (int i = 0; i < tasks.Length; i++)
+ {
+ tasks[i] = CreateCacheableTask(i + INCLUSIVE_INT32_MIN);
+ }
+ return tasks;
+ }
+
+ /// <summary>Creates a non-disposable task.</summary>
+ /// <typeparam name="TResult">Specifies the result type.</typeparam>
+ /// <param name="result">The result for the task.</param>
+ /// <returns>The cacheable task.</returns>
+ internal static Task<TResult> CreateCacheableTask<TResult>(TResult result)
+ {
+ return new Task<TResult>(false, result, (TaskCreationOptions)InternalTaskOptions.DoNotDispose, default(CancellationToken));
+ }
+ }
+
+ /// <summary>Holds state related to the builder's IAsyncStateMachine.</summary>
+ /// <remarks>This is a mutable struct. Be very delicate with it.</remarks>
+ internal struct AsyncMethodBuilderCore
+ {
+ /// <summary>A reference to the heap-allocated state machine object associated with this builder.</summary>
+ internal IAsyncStateMachine m_stateMachine;
+ /// <summary>A cached Action delegate used when dealing with a default ExecutionContext.</summary>
+ internal Action m_defaultContextAction;
+
+ // This method is copy&pasted into the public Start methods to avoid size overhead of valuetype generic instantiations.
+ // Ideally, we would build intrinsics to get the raw ref address and raw code address of MoveNext, and just use the shared implementation.
+#if false
+ /// <summary>Initiates the builder's execution with the associated state machine.</summary>
+ /// <typeparam name="TStateMachine">Specifies the type of the state machine.</typeparam>
+ /// <param name="stateMachine">The state machine instance, passed by reference.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="stateMachine"/> argument is null (Nothing in Visual Basic).</exception>
+ [SecuritySafeCritical]
+ [DebuggerStepThrough]
+ internal static void Start<TStateMachine>(ref TStateMachine stateMachine)
+ where TStateMachine : IAsyncStateMachine
+ {
+ if (stateMachine == null) throw new ArgumentNullException("stateMachine");
+ Contract.EndContractBlock();
+
+ // Run the MoveNext method within a copy-on-write ExecutionContext scope.
+ // This allows us to undo any ExecutionContext changes made in MoveNext,
+ // so that they won't "leak" out of the first await.
+
+ Thread currentThread = Thread.CurrentThread;
+ ExecutionContextSwitcher ecs = default(ExecutionContextSwitcher);
+ RuntimeHelpers.PrepareConstrainedRegions();
+ try
+ {
+ ExecutionContext.EstablishCopyOnWriteScope(currentThread, ref ecs);
+ stateMachine.MoveNext();
+ }
+ finally
+ {
+ ecs.Undo(currentThread);
+ }
+ }
+#endif
+
+ /// <summary>Associates the builder with the state machine it represents.</summary>
+ /// <param name="stateMachine">The heap-allocated state machine object.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="stateMachine"/> argument was null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.InvalidOperationException">The builder is incorrectly initialized.</exception>
+ public void SetStateMachine(IAsyncStateMachine stateMachine)
+ {
+ if (stateMachine == null) throw new ArgumentNullException("stateMachine");
+ Contract.EndContractBlock();
+ if (m_stateMachine != null) throw new InvalidOperationException(Environment.GetResourceString("AsyncMethodBuilder_InstanceNotInitialized"));
+ m_stateMachine = stateMachine;
+ }
+
+ /// <summary>
+ /// Gets the Action to use with an awaiter's OnCompleted or UnsafeOnCompleted method.
+ /// On first invocation, the supplied state machine will be boxed.
+ /// </summary>
+ /// <typeparam name="TMethodBuilder">Specifies the type of the method builder used.</typeparam>
+ /// <typeparam name="TStateMachine">Specifies the type of the state machine used.</typeparam>
+ /// <param name="builder">The builder.</param>
+ /// <param name="stateMachine">The state machine.</param>
+ /// <returns>An Action to provide to the awaiter.</returns>
+ [SecuritySafeCritical]
+ internal Action GetCompletionAction(Task taskForTracing, ref MoveNextRunner runnerToInitialize)
+ {
+ Contract.Assert(m_defaultContextAction == null || m_stateMachine != null,
+ "Expected non-null m_stateMachine on non-null m_defaultContextAction");
+
+ // Alert a listening debugger that we can't make forward progress unless it slips threads.
+ // If we don't do this, and a method that uses "await foo;" is invoked through funceval,
+ // we could end up hooking up a callback to push forward the async method's state machine,
+ // the debugger would then abort the funceval after it takes too long, and then continuing
+ // execution could result in another callback being hooked up. At that point we have
+ // multiple callbacks registered to push the state machine, which could result in bad behavior.
+ Debugger.NotifyOfCrossThreadDependency();
+
+ // The builder needs to flow ExecutionContext, so capture it.
+ var capturedContext = ExecutionContext.FastCapture(); // ok to use FastCapture as we haven't made any permission demands/asserts
+
+ // If the ExecutionContext is the default context, try to use a cached delegate, creating one if necessary.
+ Action action;
+ MoveNextRunner runner;
+ if (capturedContext != null && capturedContext.IsPreAllocatedDefault)
+ {
+ // Get the cached delegate, and if it's non-null, return it.
+ action = m_defaultContextAction;
+ if (action != null)
+ {
+ Contract.Assert(m_stateMachine != null, "If the delegate was set, the state machine should have been as well.");
+ return action;
+ }
+
+ // There wasn't a cached delegate, so create one and cache it.
+ // The delegate won't be usable until we set the MoveNextRunner's target state machine.
+ runner = new MoveNextRunner(m_stateMachine);
+
+ action = new Action(runner.RunWithDefaultContext);
+ if (taskForTracing != null)
+ {
+ action = OutputAsyncCausalityEvents(taskForTracing, action);
+ }
+ m_defaultContextAction = action;
+ }
+ // Otherwise, create an Action that flows this context. The context may be null.
+ // The delegate won't be usable until we set the MoveNextRunner's target state machine.
+ else
+ {
+ var runnerWithContext = new MoveNextRunnerWithContext(capturedContext, m_stateMachine);
+ runner = runnerWithContext;
+ action = new Action(runnerWithContext.RunWithCapturedContext);
+
+ if (taskForTracing != null)
+ {
+ action = OutputAsyncCausalityEvents(taskForTracing, action);
+ }
+
+ // NOTE: If capturedContext is null, we could create the Action to point directly
+ // to m_stateMachine.MoveNext. However, that follows a much more expensive
+ // delegate creation path.
+ }
+
+ if (m_stateMachine == null)
+ runnerToInitialize = runner;
+
+ return action;
+ }
+
+ private Action OutputAsyncCausalityEvents(Task innerTask, Action continuation)
+ {
+ return CreateContinuationWrapper(continuation, () =>
+ {
+ AsyncCausalityTracer.TraceSynchronousWorkStart(CausalityTraceLevel.Required, innerTask.Id, CausalitySynchronousWork.Execution);
+
+ // Invoke the original continuation
+ continuation.Invoke();
+
+ AsyncCausalityTracer.TraceSynchronousWorkCompletion(CausalityTraceLevel.Required, CausalitySynchronousWork.Execution);
+ }, innerTask);
+ }
+
+ internal void PostBoxInitialization(IAsyncStateMachine stateMachine, MoveNextRunner runner, Task builtTask)
+ {
+ if (builtTask != null)
+ {
+ if (AsyncCausalityTracer.LoggingOn)
+ AsyncCausalityTracer.TraceOperationCreation(CausalityTraceLevel.Required, builtTask.Id, "Async: " + stateMachine.GetType().Name, 0);
+
+ if (System.Threading.Tasks.Task.s_asyncDebuggingEnabled)
+ System.Threading.Tasks.Task.AddToActiveTasks(builtTask);
+ }
+
+ m_stateMachine = stateMachine;
+ m_stateMachine.SetStateMachine(m_stateMachine);
+
+ Contract.Assert(runner.m_stateMachine == null, "The runner's state machine should not yet have been populated.");
+ Contract.Assert(m_stateMachine != null, "The builder's state machine field should have been initialized.");
+
+ // Now that we have the state machine, store it into the runner that the action delegate points to.
+ // And return the action.
+ runner.m_stateMachine = m_stateMachine; // only after this line is the Action delegate usable
+ }
+
+ /// <summary>Throws the exception on the ThreadPool.</summary>
+ /// <param name="exception">The exception to propagate.</param>
+ /// <param name="targetContext">The target context on which to propagate the exception. Null to use the ThreadPool.</param>
+ internal static void ThrowAsync(Exception exception, SynchronizationContext targetContext)
+ {
+ // Capture the exception into an ExceptionDispatchInfo so that its
+ // stack trace and Watson bucket info will be preserved
+ var edi = ExceptionDispatchInfo.Capture(exception);
+
+ // If the user supplied a SynchronizationContext...
+ if (targetContext != null)
+ {
+ try
+ {
+ // Post the throwing of the exception to that context, and return.
+ targetContext.Post(state => ((ExceptionDispatchInfo)state).Throw(), edi);
+ return;
+ }
+ catch (Exception postException)
+ {
+ // If something goes horribly wrong in the Post, we'll
+ // propagate both exceptions on the ThreadPool
+ edi = ExceptionDispatchInfo.Capture(new AggregateException(exception, postException));
+ }
+ }
+
+ // If we have the new error reporting APIs, report this error. Otherwise, Propagate the exception(s) on the ThreadPool
+#if FEATURE_COMINTEROP
+ if (!WindowsRuntimeMarshal.ReportUnhandledError(edi.SourceException))
+#endif // FEATURE_COMINTEROP
+ {
+ ThreadPool.QueueUserWorkItem(state => ((ExceptionDispatchInfo)state).Throw(), edi);
+ }
+ }
+
+ /// <summary>Provides the ability to invoke a state machine's MoveNext method under a supplied ExecutionContext.</summary>
+ internal sealed class MoveNextRunnerWithContext : MoveNextRunner
+ {
+ /// <summary>The context with which to run MoveNext.</summary>
+ private readonly ExecutionContext m_context;
+
+ /// <summary>Initializes the runner.</summary>
+ /// <param name="context">The context with which to run MoveNext.</param>
+ [SecurityCritical] // Run needs to be SSC to map to Action delegate, so to prevent misuse, we only allow construction through SC
+ internal MoveNextRunnerWithContext(ExecutionContext context, IAsyncStateMachine stateMachine) : base(stateMachine)
+ {
+ m_context = context;
+ }
+
+ /// <summary>Invokes MoveNext under the provided context.</summary>
+ [SecuritySafeCritical]
+ internal void RunWithCapturedContext()
+ {
+ Contract.Assert(m_stateMachine != null, "The state machine must have been set before calling Run.");
+
+ if (m_context != null)
+ {
+ try
+ {
+ // Use the context and callback to invoke m_stateMachine.MoveNext.
+ ExecutionContext.Run(m_context, InvokeMoveNextCallback, m_stateMachine, preserveSyncCtx: true);
+ }
+ finally { m_context.Dispose(); }
+ }
+ else
+ {
+ m_stateMachine.MoveNext();
+ }
+ }
+ }
+
+ /// <summary>Provides the ability to invoke a state machine's MoveNext method.</summary>
+ internal class MoveNextRunner
+ {
+ /// <summary>The state machine whose MoveNext method should be invoked.</summary>
+ internal IAsyncStateMachine m_stateMachine;
+
+ /// <summary>Initializes the runner.</summary>
+ [SecurityCritical] // Run needs to be SSC to map to Action delegate, so to prevent misuse, we only allow construction through SC
+ internal MoveNextRunner(IAsyncStateMachine stateMachine)
+ {
+ m_stateMachine = stateMachine;
+ }
+
+ /// <summary>Invokes MoveNext under the default context.</summary>
+ [SecuritySafeCritical]
+ internal void RunWithDefaultContext()
+ {
+ Contract.Assert(m_stateMachine != null, "The state machine must have been set before calling Run.");
+ ExecutionContext.Run(ExecutionContext.PreAllocatedDefault, InvokeMoveNextCallback, m_stateMachine, preserveSyncCtx: true);
+ }
+
+ /// <summary>Gets a delegate to the InvokeMoveNext method.</summary>
+ protected static ContextCallback InvokeMoveNextCallback
+ {
+ [SecuritySafeCritical]
+ get { return s_invokeMoveNext ?? (s_invokeMoveNext = InvokeMoveNext); }
+ }
+
+ /// <summary>Cached delegate used with ExecutionContext.Run.</summary>
+ [SecurityCritical]
+ private static ContextCallback s_invokeMoveNext; // lazily-initialized due to SecurityCritical attribution
+
+ /// <summary>Invokes the MoveNext method on the supplied IAsyncStateMachine.</summary>
+ /// <param name="stateMachine">The IAsyncStateMachine machine instance.</param>
+ [SecurityCritical] // necessary for ContextCallback in CoreCLR
+ private static void InvokeMoveNext(object stateMachine)
+ {
+ ((IAsyncStateMachine)stateMachine).MoveNext();
+ }
+ }
+
+ /// <summary>
+ /// Logically we pass just an Action (delegate) to a task for its action to 'ContinueWith' when it completes.
+ /// However debuggers and profilers need more information about what that action is. (In particular what
+ /// the action after that is and after that. To solve this problem we create a 'ContinuationWrapper
+ /// which when invoked just does the original action (the invoke action), but also remembers other information
+ /// (like the action after that (which is also a ContinuationWrapper and thus form a linked list).
+ // We also store that task if the action is associate with at task.
+ /// </summary>
+ private class ContinuationWrapper
+ {
+ internal readonly Action m_continuation; // This is continuation which will happen after m_invokeAction (and is probably a ContinuationWrapper)
+ private readonly Action m_invokeAction; // This wrapper is an action that wraps another action, this is that Action.
+ internal readonly Task m_innerTask; // If the continuation is logically going to invoke a task, this is that task (may be null)
+
+ internal ContinuationWrapper(Action continuation, Action invokeAction, Task innerTask)
+ {
+ Contract.Requires(continuation != null, "Expected non-null continuation");
+
+ // If we don't have a task, see if our continuation is a wrapper and use that.
+ if (innerTask == null)
+ innerTask = TryGetContinuationTask(continuation);
+
+ m_continuation = continuation;
+ m_innerTask = innerTask;
+ m_invokeAction = invokeAction;
+ }
+
+ internal void Invoke()
+ {
+ m_invokeAction();
+ }
+ }
+
+ internal static Action CreateContinuationWrapper(Action continuation, Action invokeAction, Task innerTask = null)
+ {
+ return new ContinuationWrapper(continuation, invokeAction, innerTask).Invoke;
+ }
+
+ internal static Action TryGetStateMachineForDebugger(Action action)
+ {
+ object target = action.Target;
+ var runner = target as AsyncMethodBuilderCore.MoveNextRunner;
+ if (runner != null)
+ {
+ return new Action(runner.m_stateMachine.MoveNext);
+ }
+
+ var continuationWrapper = target as ContinuationWrapper;
+ if (continuationWrapper != null)
+ {
+ return TryGetStateMachineForDebugger(continuationWrapper.m_continuation);
+ }
+
+ return action;
+ }
+
+ ///<summary>
+ /// Given an action, see if it is a contiunation wrapper and has a Task associated with it. If so return it (null otherwise)
+ ///</summary>
+ internal static Task TryGetContinuationTask(Action action)
+ {
+ if (action != null)
+ {
+ var asWrapper = action.Target as ContinuationWrapper;
+ if (asWrapper != null)
+ return asWrapper.m_innerTask;
+ }
+ return null;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs
new file mode 100644
index 0000000000..f1fc9ced82
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/AsyncStateMachineAttribute.cs
@@ -0,0 +1,18 @@
+// 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;
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable, AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
+ public sealed class AsyncStateMachineAttribute : StateMachineAttribute
+ {
+ public AsyncStateMachineAttribute(Type stateMachineType)
+ : base(stateMachineType)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CallerFilePathAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CallerFilePathAttribute.cs
new file mode 100644
index 0000000000..330934cf95
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/CallerFilePathAttribute.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;
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ public sealed class CallerFilePathAttribute : Attribute
+ {
+ public CallerFilePathAttribute()
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CallerLineNumberAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CallerLineNumberAttribute.cs
new file mode 100644
index 0000000000..9c87e8e25f
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/CallerLineNumberAttribute.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;
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ public sealed class CallerLineNumberAttribute : Attribute
+ {
+ public CallerLineNumberAttribute()
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CallerMemberNameAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CallerMemberNameAttribute.cs
new file mode 100644
index 0000000000..4fc70908fb
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/CallerMemberNameAttribute.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;
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
+ public sealed class CallerMemberNameAttribute : Attribute
+ {
+ public CallerMemberNameAttribute()
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CallingConvention.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CallingConvention.cs
new file mode 100644
index 0000000000..f44251d480
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/CallingConvention.cs
@@ -0,0 +1,30 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+namespace System.Runtime.CompilerServices
+{
+ // Types used in Custom Modifier to specify calling conventions.
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public class CallConvCdecl
+ {
+ }
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public class CallConvStdcall
+ {
+ }
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public class CallConvThiscall
+ {
+ }
+
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public class CallConvFastcall
+ {
+ }
+
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CompilationRelaxations.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CompilationRelaxations.cs
new file mode 100644
index 0000000000..5e4f19410b
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/CompilationRelaxations.cs
@@ -0,0 +1,52 @@
+// 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.Runtime.CompilerServices
+{
+
+ using System;
+
+ /// IMPORTANT: Keep this in sync with corhdr.h
+[Serializable]
+[Flags]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public enum CompilationRelaxations : int
+ {
+ NoStringInterning = 0x0008, // Start in 0x0008, we had other non public flags in this enum before,
+ // so we'll start here just in case somebody used them. This flag is only
+ // valid when set for Assemblies.
+ };
+
+[Serializable]
+[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Method)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public class CompilationRelaxationsAttribute : Attribute
+ {
+ private int m_relaxations; // The relaxations.
+
+ public CompilationRelaxationsAttribute (
+ int relaxations)
+ {
+ m_relaxations = relaxations;
+ }
+
+ public CompilationRelaxationsAttribute (
+ CompilationRelaxations relaxations)
+ {
+ m_relaxations = (int) relaxations;
+ }
+
+ public int CompilationRelaxations
+ {
+ get
+ {
+ return m_relaxations;
+ }
+ }
+ }
+
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs
new file mode 100644
index 0000000000..1778506c7c
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/CompilerGeneratedAttribute.cs
@@ -0,0 +1,16 @@
+// 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.Runtime.CompilerServices {
+
+[Serializable]
+[AttributeUsage(AttributeTargets.All, Inherited = true)]
+ public sealed class CompilerGeneratedAttribute : Attribute
+ {
+ public CompilerGeneratedAttribute () {}
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs
new file mode 100644
index 0000000000..65755f6baa
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/CompilerGlobalScopeAttribute.cs
@@ -0,0 +1,27 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*============================================================
+**
+**
+**
+** Purpose: Attribute used to communicate to the VS7 debugger
+** that a class should be treated as if it has
+** global scope.
+**
+**
+===========================================================*/
+
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Class)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public class CompilerGlobalScopeAttribute : Attribute
+ {
+ public CompilerGlobalScopeAttribute () {}
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CompilerMarshalOverride.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CompilerMarshalOverride.cs
new file mode 100644
index 0000000000..a7b4aca480
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/CompilerMarshalOverride.cs
@@ -0,0 +1,23 @@
+// 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.Runtime.CompilerServices
+{
+ // The CLR data marshaler has some behaviors that are incompatible with
+ // C++. Specifically, C++ treats boolean variables as byte size, whereas
+ // the marshaller treats them as 4-byte size. Similarly, C++ treats
+ // wchar_t variables as 4-byte size, whereas the marshaller treats them
+ // as single byte size under certain conditions. In order to work around
+ // such issues, the C++ compiler will emit a type that the marshaller will
+ // marshal using the correct sizes. In addition, the compiler will place
+ // this modopt onto the variables to indicate that the specified type is
+ // not the true type. Any compiler that needed to deal with similar
+ // marshalling incompatibilities could use this attribute as well.
+ //
+ // Indicates that the modified instance differs from its true type for
+ // correct marshalling.
+ public static class CompilerMarshalOverride
+ {
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs b/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs
new file mode 100644
index 0000000000..21d677241d
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/ConditionalWeakTable.cs
@@ -0,0 +1,795 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*============================================================
+**
+**
+** Description: Compiler support for runtime-generated "object fields."
+**
+** Lets DLR and other language compilers expose the ability to
+** attach arbitrary "properties" to instanced managed objects at runtime.
+**
+** We expose this support as a dictionary whose keys are the
+** instanced objects and the values are the "properties."
+**
+** Unlike a regular dictionary, ConditionalWeakTables will not
+** keep keys alive.
+**
+**
+** Lifetimes of keys and values:
+**
+** Inserting a key and value into the dictonary will not
+** prevent the key from dying, even if the key is strongly reachable
+** from the value.
+**
+** Prior to ConditionalWeakTable, the CLR did not expose
+** the functionality needed to implement this guarantee.
+**
+** Once the key dies, the dictionary automatically removes
+** the key/value entry.
+**
+**
+** Relationship between ConditionalWeakTable and Dictionary:
+**
+** ConditionalWeakTable mirrors the form and functionality
+** of the IDictionary interface for the sake of api consistency.
+**
+** Unlike Dictionary, ConditionalWeakTable is fully thread-safe
+** and requires no additional locking to be done by callers.
+**
+** ConditionalWeakTable defines equality as Object.ReferenceEquals().
+** ConditionalWeakTable does not invoke GetHashCode() overrides.
+**
+** It is not intended to be a general purpose collection
+** and it does not formally implement IDictionary or
+** expose the full public surface area.
+**
+**
+**
+** Thread safety guarantees:
+**
+** ConditionalWeakTable is fully thread-safe and requires no
+** additional locking to be done by callers.
+**
+**
+** OOM guarantees:
+**
+** Will not corrupt unmanaged handle table on OOM. No guarantees
+** about managed weak table consistency. Native handles reclamation
+** may be delayed until appdomain shutdown.
+===========================================================*/
+
+namespace System.Runtime.CompilerServices
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Runtime.Versioning;
+ using System.Runtime.InteropServices;
+
+
+ #region ConditionalWeakTable
+ [System.Runtime.InteropServices.ComVisible(false)]
+ public sealed class ConditionalWeakTable<TKey, TValue>
+ where TKey : class
+ where TValue : class
+ {
+
+ #region Constructors
+ [System.Security.SecuritySafeCritical]
+ public ConditionalWeakTable()
+ {
+ _buckets = Array.Empty<int>();
+ _entries = Array.Empty<Entry>();
+ _freeList = -1;
+ _lock = new Object();
+
+ Resize(); // Resize at once (so won't need "if initialized" checks all over)
+ }
+ #endregion
+
+ #region Public Members
+ //--------------------------------------------------------------------------------------------
+ // key: key of the value to find. Cannot be null.
+ // value: if the key is found, contains the value associated with the key upon method return.
+ // if the key is not found, contains default(TValue).
+ //
+ // Method returns "true" if key was found, "false" otherwise.
+ //
+ // Note: The key may get garbaged collected during the TryGetValue operation. If so, TryGetValue
+ // may at its discretion, return "false" and set "value" to the default (as if the key was not present.)
+ //--------------------------------------------------------------------------------------------
+ [System.Security.SecuritySafeCritical]
+ public bool TryGetValue(TKey key, out TValue value)
+ {
+ if (key == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ }
+ lock(_lock)
+ {
+ VerifyIntegrity();
+ return TryGetValueWorker(key, out value);
+ }
+ }
+
+ //--------------------------------------------------------------------------------------------
+ // key: key to add. May not be null.
+ // value: value to associate with key.
+ //
+ // If the key is already entered into the dictionary, this method throws an exception.
+ //
+ // Note: The key may get garbage collected during the Add() operation. If so, Add()
+ // has the right to consider any prior entries successfully removed and add a new entry without
+ // throwing an exception.
+ //--------------------------------------------------------------------------------------------
+ [System.Security.SecuritySafeCritical]
+ public void Add(TKey key, TValue value)
+ {
+ if (key == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ }
+
+ lock(_lock)
+ {
+ VerifyIntegrity();
+ _invalid = true;
+
+ int entryIndex = FindEntry(key);
+ if (entryIndex != -1)
+ {
+ _invalid = false;
+ ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
+ }
+
+ CreateEntry(key, value);
+ _invalid = false;
+ }
+
+ }
+
+ //--------------------------------------------------------------------------------------------
+ // key: key to remove. May not be null.
+ //
+ // Returns true if the key is found and removed. Returns false if the key was not in the dictionary.
+ //
+ // Note: The key may get garbage collected during the Remove() operation. If so,
+ // Remove() will not fail or throw, however, the return value can be either true or false
+ // depending on the race condition.
+ //--------------------------------------------------------------------------------------------
+ [System.Security.SecuritySafeCritical]
+ public bool Remove(TKey key)
+ {
+ if (key == null)
+ {
+ ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ }
+
+ lock(_lock)
+ {
+ VerifyIntegrity();
+ _invalid = true;
+
+ int hashCode = RuntimeHelpers.GetHashCode(key) & Int32.MaxValue;
+ int bucket = hashCode % _buckets.Length;
+ int last = -1;
+ for (int entriesIndex = _buckets[bucket]; entriesIndex != -1; entriesIndex = _entries[entriesIndex].next)
+ {
+ if (_entries[entriesIndex].hashCode == hashCode && _entries[entriesIndex].depHnd.GetPrimary() == key)
+ {
+ if (last == -1)
+ {
+ _buckets[bucket] = _entries[entriesIndex].next;
+ }
+ else
+ {
+ _entries[last].next = _entries[entriesIndex].next;
+ }
+
+ _entries[entriesIndex].depHnd.Free();
+ _entries[entriesIndex].next = _freeList;
+
+ _freeList = entriesIndex;
+
+ _invalid = false;
+ return true;
+
+ }
+ last = entriesIndex;
+ }
+ _invalid = false;
+ return false;
+ }
+ }
+
+
+ //--------------------------------------------------------------------------------------------
+ // key: key of the value to find. Cannot be null.
+ // createValueCallback: callback that creates value for key. Cannot be null.
+ //
+ // Atomically tests if key exists in table. If so, returns corresponding value. If not,
+ // invokes createValueCallback() passing it the key. The returned value is bound to the key in the table
+ // and returned as the result of GetValue().
+ //
+ // If multiple threads try to initialize the same key, the table may invoke createValueCallback
+ // multiple times with the same key. Exactly one of these calls will succeed and the returned
+ // value of that call will be the one added to the table and returned by all the racing GetValue() calls.
+ //
+ // This rule permits the table to invoke createValueCallback outside the internal table lock
+ // to prevent deadlocks.
+ //--------------------------------------------------------------------------------------------
+ [System.Security.SecuritySafeCritical]
+ public TValue GetValue(TKey key, CreateValueCallback createValueCallback)
+ {
+ // Our call to TryGetValue() validates key so no need for us to.
+ //
+ // if (key == null)
+ // {
+ // ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
+ // }
+
+ if (createValueCallback == null)
+ {
+ throw new ArgumentNullException("createValueCallback");
+ }
+
+ TValue existingValue;
+ if (TryGetValue(key, out existingValue))
+ {
+ return existingValue;
+ }
+
+ // If we got here, the key is not currently in table. Invoke the callback (outside the lock)
+ // to generate the new value for the key.
+ TValue newValue = createValueCallback(key);
+
+ lock(_lock)
+ {
+ VerifyIntegrity();
+ _invalid = true;
+
+ // Now that we've retaken the lock, must recheck in case there was a race condition to add the key.
+ if (TryGetValueWorker(key, out existingValue))
+ {
+ _invalid = false;
+ return existingValue;
+ }
+ else
+ {
+ CreateEntry(key, newValue);
+ _invalid = false;
+ return newValue;
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------------------------------
+ // key: key of the value to find. Cannot be null.
+ //
+ // Helper method to call GetValue without passing a creation delegate. Uses Activator.CreateInstance
+ // to create new instances as needed. If TValue does not have a default constructor, this will
+ // throw.
+ //--------------------------------------------------------------------------------------------
+ public TValue GetOrCreateValue(TKey key)
+ {
+ return GetValue(key, k => Activator.CreateInstance<TValue>());
+ }
+
+ public delegate TValue CreateValueCallback(TKey key);
+
+ #endregion
+
+ #region internal members
+
+ //--------------------------------------------------------------------------------------------
+ // Find a key that equals (value equality) with the given key - don't use in perf critical path
+ // Note that it calls out to Object.Equals which may calls the override version of Equals
+ // and that may take locks and leads to deadlock
+ // Currently it is only used by WinRT event code and you should only use this function
+ // if you know for sure that either you won't run into dead locks or you need to live with the
+ // possiblity
+ //--------------------------------------------------------------------------------------------
+ [System.Security.SecuritySafeCritical]
+ [FriendAccessAllowed]
+ internal TKey FindEquivalentKeyUnsafe(TKey key, out TValue value)
+ {
+ lock (_lock)
+ {
+ for (int bucket = 0; bucket < _buckets.Length; ++bucket)
+ {
+ for (int entriesIndex = _buckets[bucket]; entriesIndex != -1; entriesIndex = _entries[entriesIndex].next)
+ {
+ object thisKey, thisValue;
+ _entries[entriesIndex].depHnd.GetPrimaryAndSecondary(out thisKey, out thisValue);
+ if (Object.Equals(thisKey, key))
+ {
+ value = (TValue) thisValue;
+ return (TKey) thisKey;
+ }
+ }
+ }
+ }
+
+ value = default(TValue);
+ return null;
+ }
+
+ //--------------------------------------------------------------------------------------------
+ // Returns a collection of keys - don't use in perf critical path
+ //--------------------------------------------------------------------------------------------
+ internal ICollection<TKey> Keys
+ {
+ [System.Security.SecuritySafeCritical]
+ get
+ {
+ List<TKey> list = new List<TKey>();
+ lock (_lock)
+ {
+ for (int bucket = 0; bucket < _buckets.Length; ++bucket)
+ {
+ for (int entriesIndex = _buckets[bucket]; entriesIndex != -1; entriesIndex = _entries[entriesIndex].next)
+ {
+ TKey thisKey = (TKey) _entries[entriesIndex].depHnd.GetPrimary();
+ if (thisKey != null)
+ {
+ list.Add(thisKey);
+ }
+ }
+ }
+ }
+
+ return list;
+ }
+ }
+
+ //--------------------------------------------------------------------------------------------
+ // Returns a collection of values - don't use in perf critical path
+ //--------------------------------------------------------------------------------------------
+ internal ICollection<TValue> Values
+ {
+ [System.Security.SecuritySafeCritical]
+ get
+ {
+ List<TValue> list = new List<TValue>();
+ lock (_lock)
+ {
+ for (int bucket = 0; bucket < _buckets.Length; ++bucket)
+ {
+ for (int entriesIndex = _buckets[bucket]; entriesIndex != -1; entriesIndex = _entries[entriesIndex].next)
+ {
+ Object primary = null;
+ Object secondary = null;
+
+ _entries[entriesIndex].depHnd.GetPrimaryAndSecondary(out primary, out secondary);
+
+ // Now that we've secured a strong reference to the secondary, must check the primary again
+ // to ensure it didn't expire (otherwise, we open a race condition where TryGetValue misreports an
+ // expired key as a live key with a null value.)
+ if (primary != null)
+ {
+ list.Add((TValue)secondary);
+ }
+ }
+ }
+ }
+
+ return list;
+ }
+ }
+
+ //--------------------------------------------------------------------------------------------
+ // Clear all the key/value pairs
+ //--------------------------------------------------------------------------------------------
+ [System.Security.SecuritySafeCritical]
+ internal void Clear()
+ {
+ lock (_lock)
+ {
+ // Clear the buckets
+ for (int bucketIndex = 0; bucketIndex < _buckets.Length; bucketIndex++)
+ {
+ _buckets[bucketIndex] = -1;
+ }
+
+ // Clear the entries and link them backwards together as part of free list
+ int entriesIndex;
+ for (entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
+ {
+ if (_entries[entriesIndex].depHnd.IsAllocated)
+ {
+ _entries[entriesIndex].depHnd.Free();
+ }
+
+ // Link back wards as free list
+ _entries[entriesIndex].next = entriesIndex - 1;
+ }
+
+ _freeList = entriesIndex - 1;
+ }
+ }
+
+ #endregion
+
+ #region Private Members
+ [System.Security.SecurityCritical]
+ //----------------------------------------------------------------------------------------
+ // Worker for finding a key/value pair
+ //
+ // Preconditions:
+ // Must hold _lock.
+ // Key already validated as non-null
+ //----------------------------------------------------------------------------------------
+ private bool TryGetValueWorker(TKey key, out TValue value)
+ {
+ int entryIndex = FindEntry(key);
+ if (entryIndex != -1)
+ {
+ Object primary = null;
+ Object secondary = null;
+ _entries[entryIndex].depHnd.GetPrimaryAndSecondary(out primary, out secondary);
+ // Now that we've secured a strong reference to the secondary, must check the primary again
+ // to ensure it didn't expire (otherwise, we open a race condition where TryGetValue misreports an
+ // expired key as a live key with a null value.)
+ if (primary != null)
+ {
+ value = (TValue)secondary;
+ return true;
+ }
+ }
+
+ value = default(TValue);
+ return false;
+ }
+
+ //----------------------------------------------------------------------------------------
+ // Worker for adding a new key/value pair.
+ //
+ // Preconditions:
+ // Must hold _lock.
+ // Key already validated as non-null and not already in table.
+ //----------------------------------------------------------------------------------------
+ [System.Security.SecurityCritical]
+ private void CreateEntry(TKey key, TValue value)
+ {
+ if (_freeList == -1)
+ {
+ Resize();
+ }
+
+ int hashCode = RuntimeHelpers.GetHashCode(key) & Int32.MaxValue;
+ int bucket = hashCode % _buckets.Length;
+
+ int newEntry = _freeList;
+ _freeList = _entries[newEntry].next;
+
+ _entries[newEntry].hashCode = hashCode;
+ _entries[newEntry].depHnd = new DependentHandle(key, value);
+ _entries[newEntry].next = _buckets[bucket];
+
+ _buckets[bucket] = newEntry;
+
+ }
+
+ //----------------------------------------------------------------------------------------
+ // This does two things: resize and scrub expired keys off bucket lists.
+ //
+ // Precondition:
+ // Must hold _lock.
+ //
+ // Postcondition:
+ // _freeList is non-empty on exit.
+ //----------------------------------------------------------------------------------------
+ [System.Security.SecurityCritical]
+ private void Resize()
+ {
+ // Start by assuming we won't resize.
+ int newSize = _buckets.Length;
+
+ // If any expired keys exist, we won't resize.
+ bool hasExpiredEntries = false;
+ int entriesIndex;
+ for (entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
+ {
+ if ( _entries[entriesIndex].depHnd.IsAllocated && _entries[entriesIndex].depHnd.GetPrimary() == null)
+ {
+ hasExpiredEntries = true;
+ break;
+ }
+ }
+
+ if (!hasExpiredEntries)
+ {
+ newSize = System.Collections.HashHelpers.GetPrime(_buckets.Length == 0 ? _initialCapacity + 1 : _buckets.Length * 2);
+ }
+
+
+ // Reallocate both buckets and entries and rebuild the bucket and freelists from scratch.
+ // This serves both to scrub entries with expired keys and to put the new entries in the proper bucket.
+ int newFreeList = -1;
+ int[] newBuckets = new int[newSize];
+ for (int bucketIndex = 0; bucketIndex < newSize; bucketIndex++)
+ {
+ newBuckets[bucketIndex] = -1;
+ }
+ Entry[] newEntries = new Entry[newSize];
+
+ // Migrate existing entries to the new table.
+ for (entriesIndex = 0; entriesIndex < _entries.Length; entriesIndex++)
+ {
+ DependentHandle depHnd = _entries[entriesIndex].depHnd;
+ if (depHnd.IsAllocated && depHnd.GetPrimary() != null)
+ {
+ // Entry is used and has not expired. Link it into the appropriate bucket list.
+ int bucket = _entries[entriesIndex].hashCode % newSize;
+ newEntries[entriesIndex].depHnd = depHnd;
+ newEntries[entriesIndex].hashCode = _entries[entriesIndex].hashCode;
+ newEntries[entriesIndex].next = newBuckets[bucket];
+ newBuckets[bucket] = entriesIndex;
+ }
+ else
+ {
+ // Entry has either expired or was on the freelist to begin with. Either way
+ // insert it on the new freelist.
+ _entries[entriesIndex].depHnd.Free();
+ newEntries[entriesIndex].depHnd = new DependentHandle();
+ newEntries[entriesIndex].next = newFreeList;
+ newFreeList = entriesIndex;
+ }
+ }
+
+ // Add remaining entries to freelist.
+ while (entriesIndex != newEntries.Length)
+ {
+ newEntries[entriesIndex].depHnd = new DependentHandle();
+ newEntries[entriesIndex].next = newFreeList;
+ newFreeList = entriesIndex;
+ entriesIndex++;
+ }
+
+ _buckets = newBuckets;
+ _entries = newEntries;
+ _freeList = newFreeList;
+ }
+
+ //----------------------------------------------------------------------------------------
+ // Returns -1 if not found (if key expires during FindEntry, this can be treated as "not found.")
+ //
+ // Preconditions:
+ // Must hold _lock.
+ // Key already validated as non-null.
+ //----------------------------------------------------------------------------------------
+ [System.Security.SecurityCritical]
+ private int FindEntry(TKey key)
+ {
+ int hashCode = RuntimeHelpers.GetHashCode(key) & Int32.MaxValue;
+ for (int entriesIndex = _buckets[hashCode % _buckets.Length]; entriesIndex != -1; entriesIndex = _entries[entriesIndex].next)
+ {
+ if (_entries[entriesIndex].hashCode == hashCode && _entries[entriesIndex].depHnd.GetPrimary() == key)
+ {
+ return entriesIndex;
+ }
+ }
+ return -1;
+ }
+
+ //----------------------------------------------------------------------------------------
+ // Precondition:
+ // Must hold _lock.
+ //----------------------------------------------------------------------------------------
+ private void VerifyIntegrity()
+ {
+ if (_invalid)
+ {
+ throw new InvalidOperationException(Environment.GetResourceString("CollectionCorrupted"));
+ }
+ }
+
+ //----------------------------------------------------------------------------------------
+ // Finalizer.
+ //----------------------------------------------------------------------------------------
+ [System.Security.SecuritySafeCritical]
+ ~ConditionalWeakTable()
+ {
+
+ // We're just freeing per-appdomain unmanaged handles here. If we're already shutting down the AD,
+ // don't bother.
+ //
+ // (Despite its name, Environment.HasShutdownStart also returns true if the current AD is finalizing.)
+ if (Environment.HasShutdownStarted)
+ {
+ return;
+ }
+
+ if (_lock != null)
+ {
+ lock(_lock)
+ {
+ if (_invalid)
+ {
+ return;
+ }
+ Entry[] entries = _entries;
+
+ // Make sure anyone sneaking into the table post-resurrection
+ // gets booted before they can damage the native handle table.
+ _invalid = true;
+ _entries = null;
+ _buckets = null;
+
+ for (int entriesIndex = 0; entriesIndex < entries.Length; entriesIndex++)
+ {
+ entries[entriesIndex].depHnd.Free();
+ }
+ }
+ }
+ }
+ #endregion
+
+ #region Private Data Members
+ //--------------------------------------------------------------------------------------------
+ // Entry can be in one of three states:
+ //
+ // - Linked into the freeList (_freeList points to first entry)
+ // depHnd.IsAllocated == false
+ // hashCode == <dontcare>
+ // next links to next Entry on freelist)
+ //
+ // - Used with live key (linked into a bucket list where _buckets[hashCode % _buckets.Length] points to first entry)
+ // depHnd.IsAllocated == true, depHnd.GetPrimary() != null
+ // hashCode == RuntimeHelpers.GetHashCode(depHnd.GetPrimary()) & Int32.MaxValue
+ // next links to next Entry in bucket.
+ //
+ // - Used with dead key (linked into a bucket list where _buckets[hashCode % _buckets.Length] points to first entry)
+ // depHnd.IsAllocated == true, depHnd.GetPrimary() == null
+ // hashCode == <notcare>
+ // next links to next Entry in bucket.
+ //
+ // The only difference between "used with live key" and "used with dead key" is that
+ // depHnd.GetPrimary() returns null. The transition from "used with live key" to "used with dead key"
+ // happens asynchronously as a result of normal garbage collection. The dictionary itself
+ // receives no notification when this happens.
+ //
+ // When the dictionary grows the _entries table, it scours it for expired keys and puts those
+ // entries back on the freelist.
+ //--------------------------------------------------------------------------------------------
+ private struct Entry
+ {
+ public DependentHandle depHnd; // Holds key and value using a weak reference for the key and a strong reference
+ // for the value that is traversed only if the key is reachable without going through the value.
+ public int hashCode; // Cached copy of key's hashcode
+ public int next; // Index of next entry, -1 if last
+ }
+
+ private int[] _buckets; // _buckets[hashcode & _buckets.Length] contains index of first entry in bucket (-1 if empty)
+ private Entry[] _entries;
+ private int _freeList; // -1 = empty, else index of first unused Entry
+ private const int _initialCapacity = 5;
+ private readonly Object _lock; // this could be a ReaderWriterLock but CoreCLR does not support RWLocks.
+ private bool _invalid; // flag detects if OOM or other background exception threw us out of the lock.
+ #endregion
+ }
+ #endregion
+
+
+
+
+ #region DependentHandle
+ //=========================================================================================
+ // This struct collects all operations on native DependentHandles. The DependentHandle
+ // merely wraps an IntPtr so this struct serves mainly as a "managed typedef."
+ //
+ // DependentHandles exist in one of two states:
+ //
+ // IsAllocated == false
+ // No actual handle is allocated underneath. Illegal to call GetPrimary
+ // or GetPrimaryAndSecondary(). Ok to call Free().
+ //
+ // Initializing a DependentHandle using the nullary ctor creates a DependentHandle
+ // that's in the !IsAllocated state.
+ // (! Right now, we get this guarantee for free because (IntPtr)0 == NULL unmanaged handle.
+ // ! If that assertion ever becomes false, we'll have to add an _isAllocated field
+ // ! to compensate.)
+ //
+ //
+ // IsAllocated == true
+ // There's a handle allocated underneath. You must call Free() on this eventually
+ // or you cause a native handle table leak.
+ //
+ // This struct intentionally does no self-synchronization. It's up to the caller to
+ // to use DependentHandles in a thread-safe way.
+ //=========================================================================================
+ [ComVisible(false)]
+ struct DependentHandle
+ {
+ #region Constructors
+ #if FEATURE_CORECLR
+ [System.Security.SecuritySafeCritical] // auto-generated
+ #else
+ [System.Security.SecurityCritical]
+ #endif
+ public DependentHandle(Object primary, Object secondary)
+ {
+ IntPtr handle = (IntPtr)0;
+ nInitialize(primary, secondary, out handle);
+ // no need to check for null result: nInitialize expected to throw OOM.
+ _handle = handle;
+ }
+ #endregion
+
+ #region Public Members
+ public bool IsAllocated
+ {
+ get
+ {
+ return _handle != (IntPtr)0;
+ }
+ }
+
+ // Getting the secondary object is more expensive than getting the first so
+ // we provide a separate primary-only accessor for those times we only want the
+ // primary.
+ #if FEATURE_CORECLR
+ [System.Security.SecuritySafeCritical] // auto-generated
+ #else
+ [System.Security.SecurityCritical]
+ #endif
+ public Object GetPrimary()
+ {
+ Object primary;
+ nGetPrimary(_handle, out primary);
+ return primary;
+ }
+
+ #if FEATURE_CORECLR
+ [System.Security.SecuritySafeCritical] // auto-generated
+ #else
+ [System.Security.SecurityCritical]
+ #endif
+ public void GetPrimaryAndSecondary(out Object primary, out Object secondary)
+ {
+ nGetPrimaryAndSecondary(_handle, out primary, out secondary);
+ }
+
+ //----------------------------------------------------------------------
+ // Forces dependentHandle back to non-allocated state (if not already there)
+ // and frees the handle if needed.
+ //----------------------------------------------------------------------
+ [System.Security.SecurityCritical]
+ public void Free()
+ {
+ if (_handle != (IntPtr)0)
+ {
+ IntPtr handle = _handle;
+ _handle = (IntPtr)0;
+ nFree(handle);
+ }
+ }
+ #endregion
+
+ #region Private Members
+ [System.Security.SecurityCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void nInitialize(Object primary, Object secondary, out IntPtr dependentHandle);
+
+ [System.Security.SecurityCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void nGetPrimary(IntPtr dependentHandle, out Object primary);
+
+ [System.Security.SecurityCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void nGetPrimaryAndSecondary(IntPtr dependentHandle, out Object primary, out Object secondary);
+
+ [System.Security.SecurityCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void nFree(IntPtr dependentHandle);
+ #endregion
+
+ #region Private Data Member
+ private IntPtr _handle;
+ #endregion
+
+ } // struct DependentHandle
+ #endregion
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/CustomConstantAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/CustomConstantAttribute.cs
new file mode 100644
index 0000000000..c912095bda
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/CustomConstantAttribute.cs
@@ -0,0 +1,31 @@
+// 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.Reflection;
+using System.Collections.Generic;
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited=false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public abstract class CustomConstantAttribute : Attribute
+ {
+ public abstract Object Value { get; }
+
+ internal static object GetRawConstant(CustomAttributeData attr)
+ {
+ foreach (CustomAttributeNamedArgument namedArgument in attr.NamedArguments)
+ {
+ if (namedArgument.MemberInfo.Name.Equals("Value"))
+ return namedArgument.TypedValue.Value;
+ }
+
+ // Return DBNull to indicate that no default value is available.
+ // Not to be confused with a null return which indicates a null default value.
+ return DBNull.Value;
+ }
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/DateTimeConstantAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/DateTimeConstantAttribute.cs
new file mode 100644
index 0000000000..4362aa84a1
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/DateTimeConstantAttribute.cs
@@ -0,0 +1,48 @@
+// 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.Reflection;
+using System.Diagnostics.Contracts;
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited=false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class DateTimeConstantAttribute : CustomConstantAttribute
+ {
+ public DateTimeConstantAttribute(long ticks)
+ {
+ date = new System.DateTime(ticks);
+ }
+
+ public override Object Value
+ {
+ get
+ {
+ return date;
+ }
+ }
+
+ internal static DateTime GetRawDateTimeConstant(CustomAttributeData attr)
+ {
+ Contract.Requires(attr.Constructor.DeclaringType == typeof(DateTimeConstantAttribute));
+ Contract.Requires(attr.ConstructorArguments.Count == 1);
+
+ foreach (CustomAttributeNamedArgument namedArgument in attr.NamedArguments)
+ {
+ if (namedArgument.MemberInfo.Name.Equals("Value"))
+ {
+ return new DateTime((long)namedArgument.TypedValue.Value);
+ }
+ }
+
+ // Look at the ctor argument if the "Value" property was not explicitly defined.
+ return new DateTime((long)attr.ConstructorArguments[0].Value);
+ }
+
+ private System.DateTime date;
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/DecimalConstantAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/DecimalConstantAttribute.cs
new file mode 100644
index 0000000000..39a4c86b72
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/DecimalConstantAttribute.cs
@@ -0,0 +1,98 @@
+// 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.
+
+
+// Note: If you add a new ctor overloads you need to update ParameterInfo.RawDefaultValue
+
+using System.Reflection;
+using System.Diagnostics.Contracts;
+using System.Collections.Generic;
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited=false)]
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class DecimalConstantAttribute : Attribute
+ {
+ [CLSCompliant(false)]
+ public DecimalConstantAttribute(
+ byte scale,
+ byte sign,
+ uint hi,
+ uint mid,
+ uint low
+ )
+ {
+ dec = new System.Decimal((int) low, (int)mid, (int)hi, (sign != 0), scale);
+ }
+
+ public DecimalConstantAttribute(
+ byte scale,
+ byte sign,
+ int hi,
+ int mid,
+ int low
+ )
+ {
+ dec = new System.Decimal(low, mid, hi, (sign != 0), scale);
+ }
+
+
+ public System.Decimal Value
+ {
+ get
+ {
+ return dec;
+ }
+ }
+
+ internal static Decimal GetRawDecimalConstant(CustomAttributeData attr)
+ {
+ Contract.Requires(attr.Constructor.DeclaringType == typeof(DecimalConstantAttribute));
+
+ foreach (CustomAttributeNamedArgument namedArgument in attr.NamedArguments)
+ {
+ if (namedArgument.MemberInfo.Name.Equals("Value"))
+ {
+ // This is not possible because Decimal cannot be represented directly in the metadata.
+ Contract.Assert(false, "Decimal cannot be represented directly in the metadata.");
+ return (Decimal)namedArgument.TypedValue.Value;
+ }
+ }
+
+ ParameterInfo[] parameters = attr.Constructor.GetParameters();
+ Contract.Assert(parameters.Length == 5);
+
+ System.Collections.Generic.IList<CustomAttributeTypedArgument> args = attr.ConstructorArguments;
+ Contract.Assert(args.Count == 5);
+
+ if (parameters[2].ParameterType == typeof(uint))
+ {
+ // DecimalConstantAttribute(byte scale, byte sign, uint hi, uint mid, uint low)
+ int low = (int)(UInt32)args[4].Value;
+ int mid = (int)(UInt32)args[3].Value;
+ int hi = (int)(UInt32)args[2].Value;
+ byte sign = (byte)args[1].Value;
+ byte scale = (byte)args[0].Value;
+
+ return new System.Decimal(low, mid, hi, (sign != 0), scale);
+ }
+ else
+ {
+ // DecimalConstantAttribute(byte scale, byte sign, int hi, int mid, int low)
+ int low = (int)args[4].Value;
+ int mid = (int)args[3].Value;
+ int hi = (int)args[2].Value;
+ byte sign = (byte)args[1].Value;
+ byte scale = (byte)args[0].Value;
+
+ return new System.Decimal(low, mid, hi, (sign != 0), scale);
+ }
+ }
+
+ private System.Decimal dec;
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/DecoratedNameAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/DecoratedNameAttribute.cs
new file mode 100644
index 0000000000..75558d4e7e
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/DecoratedNameAttribute.cs
@@ -0,0 +1,18 @@
+// 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;
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.All),
+ ComVisible(false)]
+ internal sealed class DecoratedNameAttribute : Attribute
+ {
+ public DecoratedNameAttribute(string decoratedName)
+ {}
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs
new file mode 100644
index 0000000000..46dae10fdd
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/DisablePrivateReflectionAttribute.cs
@@ -0,0 +1,18 @@
+// 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.Runtime.CompilerServices
+{
+ using System;
+
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=false, Inherited=false)]
+ public sealed class DisablePrivateReflectionAttribute : Attribute
+ {
+ public DisablePrivateReflectionAttribute() {}
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/DiscardableAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/DiscardableAttribute.cs
new file mode 100644
index 0000000000..303151f576
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/DiscardableAttribute.cs
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+namespace System.Runtime.CompilerServices {
+
+ using System;
+
+ // Custom attribute to indicating a TypeDef is a discardable attribute
+[System.Runtime.InteropServices.ComVisible(true)]
+ public class DiscardableAttribute : Attribute
+ {
+ public DiscardableAttribute()
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/ExtensionAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/ExtensionAttribute.cs
new file mode 100644
index 0000000000..6ec8fa04f5
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/ExtensionAttribute.cs
@@ -0,0 +1,13 @@
+// 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;
+
+namespace System.Runtime.CompilerServices
+{
+ /// <summary>
+ /// Indicates that a method is an extension method, or that a class or assembly contains extension methods.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class | AttributeTargets.Assembly)]
+ public sealed class ExtensionAttribute : Attribute { }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs
new file mode 100644
index 0000000000..679e304ad1
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/FixedAddressValueTypeAttribute.cs
@@ -0,0 +1,14 @@
+// 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.Runtime.CompilerServices
+{
+ using System;
+
+[Serializable]
+[AttributeUsage(AttributeTargets.Field)]
+ sealed public class FixedAddressValueTypeAttribute : Attribute
+ {
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/FixedBufferAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/FixedBufferAttribute.cs
new file mode 100644
index 0000000000..a7d01b12c4
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/FixedBufferAttribute.cs
@@ -0,0 +1,43 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+/*============================================================
+**
+**
+** Purpose: Used by a compiler for generating value types
+** in-place within other value types containing a certain
+** number of elements of the given (primitive) type. Somewhat
+** similar to P/Invoke's ByValTStr attribute.
+** Used by C# with this syntax: "fixed int buffer[10];"
+**
+===========================================================*/
+using System;
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Field, Inherited=false)]
+ public sealed class FixedBufferAttribute : Attribute
+ {
+ private Type elementType;
+ private int length;
+
+ public FixedBufferAttribute(Type elementType, int length)
+ {
+ this.elementType = elementType;
+ this.length = length;
+ }
+
+ public Type ElementType {
+ get {
+ return elementType;
+ }
+ }
+
+ public int Length {
+ get {
+ return length;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/FormattableStringFactory.cs b/src/mscorlib/src/System/Runtime/CompilerServices/FormattableStringFactory.cs
new file mode 100644
index 0000000000..aee3bc2230
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/FormattableStringFactory.cs
@@ -0,0 +1,58 @@
+// 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.
+
+/*============================================================
+**
+** Class: FormattableStringFactory
+**
+**
+** Purpose: implementation of the FormattableStringFactory
+** class.
+**
+===========================================================*/
+namespace System.Runtime.CompilerServices
+{
+ /// <summary>
+ /// A factory type used by compilers to create instances of the type <see cref="FormattableString"/>.
+ /// </summary>
+ public static class FormattableStringFactory
+ {
+ /// <summary>
+ /// Create a <see cref="FormattableString"/> from a composite format string and object
+ /// array containing zero or more objects to format.
+ /// </summary>
+ public static FormattableString Create(string format, params object[] arguments)
+ {
+ if (format == null)
+ {
+ throw new ArgumentNullException("format");
+ }
+
+ if (arguments == null)
+ {
+ throw new ArgumentNullException("arguments");
+ }
+
+ return new ConcreteFormattableString(format, arguments);
+ }
+
+ private sealed class ConcreteFormattableString : FormattableString
+ {
+ private readonly string _format;
+ private readonly object[] _arguments;
+
+ internal ConcreteFormattableString(string format, object[] arguments)
+ {
+ _format = format;
+ _arguments = arguments;
+ }
+
+ public override string Format { get { return _format; } }
+ public override object[] GetArguments() { return _arguments; }
+ public override int ArgumentCount { get { return _arguments.Length; } }
+ public override object GetArgument(int index) { return _arguments[index]; }
+ public override string ToString(IFormatProvider formatProvider) { return string.Format(formatProvider, _format, _arguments); }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/HasCopySemanticsAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/HasCopySemanticsAttribute.cs
new file mode 100644
index 0000000000..944a2868f2
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/HasCopySemanticsAttribute.cs
@@ -0,0 +1,14 @@
+// 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.Runtime.CompilerServices
+{
+[Serializable]
+[AttributeUsage(AttributeTargets.Struct)]
+ public sealed class HasCopySemanticsAttribute : Attribute
+ {
+ public HasCopySemanticsAttribute()
+ {}
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IAsyncStateMachine.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IAsyncStateMachine.cs
new file mode 100644
index 0000000000..7fb7ea5395
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IAsyncStateMachine.cs
@@ -0,0 +1,27 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+//
+//
+//
+// Represents state machines generated for asynchronous methods.
+//
+// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+namespace System.Runtime.CompilerServices
+{
+ /// <summary>
+ /// Represents state machines generated for asynchronous methods.
+ /// This type is intended for compiler use only.
+ /// </summary>
+ public interface IAsyncStateMachine
+ {
+ /// <summary>Moves the state machine to its next state.</summary>
+ void MoveNext();
+ /// <summary>Configures the state machine with a heap-allocated replica.</summary>
+ /// <param name="stateMachine">The heap-allocated replica.</param>
+ void SetStateMachine(IAsyncStateMachine stateMachine);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/ICastable.cs b/src/mscorlib/src/System/Runtime/CompilerServices/ICastable.cs
new file mode 100644
index 0000000000..7ba9434575
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/ICastable.cs
@@ -0,0 +1,82 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+
+
+//
+// Support for dynamic interface casting. Specifically implementing this interface on a type will allow the
+// type to support interfaces (for the purposes of casting and interface dispatch) that do not appear in its
+// interface map.
+//
+
+using System;
+
+namespace System.Runtime.CompilerServices
+{
+ public interface ICastable
+ {
+ // This is called if casting this object to the given interface type would otherwise fail. Casting
+ // here means the IL isinst and castclass instructions in the case where they are given an interface
+ // type as the target type.
+ //
+ // A return value of true indicates the cast is valid.
+ //
+ // If false is returned when this is called as part of a castclass then the usual InvalidCastException
+ // will be thrown unless an alternate exception is assigned to the castError output parameter. This
+ // parameter is ignored on successful casts or during the evaluation of an isinst (which returns null
+ // rather than throwing on error).
+ //
+ // No exception should be thrown from this method (it will cause unpredictable effects, including the
+ // possibility of an immediate failfast).
+ //
+ // The results of this call are not cached, so it is advisable to provide a performant implementation.
+ //
+ // The results of this call should be invariant for the same class, interface type pair. That is
+ // because this is the only guard placed before an interface invocation at runtime. If a type decides
+ // it no longer wants to implement a given interface it has no way to synchronize with callers that
+ // have already cached this relationship and can invoke directly via the interface pointer.
+ bool IsInstanceOfInterface(RuntimeTypeHandle interfaceType, out Exception castError);
+
+ // This is called as part of the interface dispatch mechanism when the dispatcher logic cannot find
+ // the given interface type in the interface map of this object.
+ //
+ // It allows the implementor to return an alternate class type which does implement the interface. The
+ // interface lookup shall be performed again on this type (failure to find the interface this time
+ // resulting in a fail fast) and the corresponding implemented method on that class called instead.
+ //
+ // Naturally, since the call is dispatched to a method on a class which does not match the type of the
+ // this pointer, extreme care must be taken in the implementation of the interface methods of this
+ // surrogate type.
+ //
+ // No exception should be thrown from this method (it will cause unpredictable effects, including the
+ // possibility of an immediate failfast).
+ //
+ // There is no error path defined here. By construction all interface dispatches will already have
+ // been verified via the castclass/isinst mechanism (and thus a call to IsInstanceOfInterface above)
+ // so this method is expected to succeed in all cases. The contract for interface dispatch does not
+ // include any errors from the infrastructure, of which this is a part.
+ //
+ // The results of this lookup are cached so computation of the result is not as perf-sensitive as
+ // IsInstanceOfInterface.
+ RuntimeTypeHandle GetImplType(RuntimeTypeHandle interfaceType);
+ }
+
+ /// <summary>
+ /// Helpers that allows VM to call into ICastable methods without having to deal with RuntimeTypeHandle.
+ /// RuntimeTypeHandle is a struct and is always passed in stack in x86, which our VM call helpers don't
+ /// particularly like.
+ /// </summary>
+ class ICastableHelpers
+ {
+ internal static bool IsInstanceOfInterface(ICastable castable, RuntimeType type, out Exception castError)
+ {
+ return castable.IsInstanceOfInterface(new RuntimeTypeHandle(type), out castError);
+ }
+
+ internal static RuntimeType GetImplType(ICastable castable, RuntimeType interfaceType)
+ {
+ return castable.GetImplType(new RuntimeTypeHandle(interfaceType)).GetRuntimeType();
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IDispatchConstantAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IDispatchConstantAttribute.cs
new file mode 100644
index 0000000000..d6dfcbbbb9
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IDispatchConstantAttribute.cs
@@ -0,0 +1,26 @@
+// 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.InteropServices;
+
+namespace System.Runtime.CompilerServices
+{
+[Serializable]
+[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited=false)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class IDispatchConstantAttribute : CustomConstantAttribute
+ {
+ public IDispatchConstantAttribute()
+ {
+ }
+
+ public override Object Value
+ {
+ get
+ {
+ return new DispatchWrapper(null);
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/INotifyCompletion.cs b/src/mscorlib/src/System/Runtime/CompilerServices/INotifyCompletion.cs
new file mode 100644
index 0000000000..872a79b72b
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/INotifyCompletion.cs
@@ -0,0 +1,40 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
+//
+//
+//
+// Interfaces used to represent instances that notify listeners of their completion via continuations.
+// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+using System;
+using System.Security;
+
+namespace System.Runtime.CompilerServices
+{
+ /// <summary>
+ /// Represents an operation that will schedule continuations when the operation completes.
+ /// </summary>
+ public interface INotifyCompletion
+ {
+ /// <summary>Schedules the continuation action to be invoked when the instance completes.</summary>
+ /// <param name="continuation">The action to invoke when the operation completes.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
+ void OnCompleted(Action continuation);
+ }
+
+ /// <summary>
+ /// Represents an awaiter used to schedule continuations when an await operation completes.
+ /// </summary>
+ public interface ICriticalNotifyCompletion : INotifyCompletion
+ {
+ /// <summary>Schedules the continuation action to be invoked when the instance completes.</summary>
+ /// <param name="continuation">The action to invoke when the operation completes.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
+ /// <remarks>Unlike OnCompleted, UnsafeOnCompleted need not propagate ExecutionContext information.</remarks>
+ [SecurityCritical]
+ void UnsafeOnCompleted(Action continuation);
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IUnknownConstantAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IUnknownConstantAttribute.cs
new file mode 100644
index 0000000000..f8717cff52
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IUnknownConstantAttribute.cs
@@ -0,0 +1,27 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+
+namespace System.Runtime.CompilerServices
+{
+[Serializable]
+[AttributeUsage(AttributeTargets.Field | AttributeTargets.Parameter, Inherited=false)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class IUnknownConstantAttribute : CustomConstantAttribute
+ {
+ public IUnknownConstantAttribute()
+ {
+ }
+
+ public override Object Value
+ {
+ get
+ {
+ return new UnknownWrapper(null);
+ }
+ }
+
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IndexerNameAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IndexerNameAttribute.cs
new file mode 100644
index 0000000000..0323fe0cf6
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IndexerNameAttribute.cs
@@ -0,0 +1,17 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Runtime.CompilerServices
+{
+ using System;
+
+[Serializable]
+[AttributeUsage(AttributeTargets.Property, Inherited = true)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class IndexerNameAttribute: Attribute
+ {
+ public IndexerNameAttribute(String indexerName)
+ {}
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs
new file mode 100644
index 0000000000..ee7807a5dd
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/InternalsVisibleToAttribute.cs
@@ -0,0 +1,58 @@
+// 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.Runtime.CompilerServices
+{
+ using System;
+
+
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=true, Inherited=false)]
+ public sealed class InternalsVisibleToAttribute : Attribute
+ {
+ private string _assemblyName;
+ private bool _allInternalsVisible = true;
+
+ public InternalsVisibleToAttribute(string assemblyName)
+ {
+ this._assemblyName = assemblyName;
+ }
+
+ public string AssemblyName
+ {
+ get
+ {
+ return _assemblyName;
+ }
+ }
+
+ public bool AllInternalsVisible
+ {
+ get { return _allInternalsVisible; }
+ set { _allInternalsVisible = value; }
+ }
+ }
+
+ /// <summary>
+ /// If AllInternalsVisible is not true for a friend assembly, the FriendAccessAllowed attribute
+ /// indicates which internals are shared with that friend assembly.
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Class |
+ AttributeTargets.Constructor |
+ AttributeTargets.Enum |
+ AttributeTargets.Event |
+ AttributeTargets.Field |
+ AttributeTargets.Interface |
+ AttributeTargets.Method |
+ AttributeTargets.Property |
+ AttributeTargets.Struct,
+ AllowMultiple = false,
+ Inherited = false)]
+ [FriendAccessAllowed]
+ internal sealed class FriendAccessAllowedAttribute : Attribute {
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsBoxed.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsBoxed.cs
new file mode 100644
index 0000000000..8b6691c09d
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IsBoxed.cs
@@ -0,0 +1,11 @@
+// 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.Runtime.CompilerServices
+{
+ // Indicates that the modified reference type is a boxed valuetype
+ public static class IsBoxed
+ {
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsByValue.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsByValue.cs
new file mode 100644
index 0000000000..d16a853597
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IsByValue.cs
@@ -0,0 +1,11 @@
+// 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.Runtime.CompilerServices
+{
+ // Indicates that the modified method argument is passed by value
+ public static class IsByValue
+ {
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsConst.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsConst.cs
new file mode 100644
index 0000000000..210e5997a7
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IsConst.cs
@@ -0,0 +1,11 @@
+// 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.Runtime.CompilerServices
+{
+ // Indicates that the modified type is const (i.e. has a const modifier)
+ public static class IsConst
+ {
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsCopyConstructed.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsCopyConstructed.cs
new file mode 100644
index 0000000000..ee40ee7b02
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IsCopyConstructed.cs
@@ -0,0 +1,11 @@
+// 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.Runtime.CompilerServices
+{
+ [System.Runtime.InteropServices.ComVisible(true)]
+ public static class IsCopyConstructed
+ {}
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsExplicitlyDereferenced.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsExplicitlyDereferenced.cs
new file mode 100644
index 0000000000..480a62175d
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IsExplicitlyDereferenced.cs
@@ -0,0 +1,22 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Runtime.CompilerServices
+{
+ // Consider the following C++ method prototypes:
+ // 1) int foo(int ^arg);
+ // 2) int foo(int &arg);
+ //
+ // Both of these methods will have a .NET type signature that looks the
+ // same, but when importing a method from a metadata scope, the compiler
+ // needs to know what the calling syntax should be. This modopt and its
+ // partner "IsImplicitlyDereferenced" disambiguate reference versus
+ // pointer arguments.
+ //
+ // Indicates that the modified GC reference represents a pointer in a
+ // method signature.
+ public static class IsExplicitlyDereferenced
+ {
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsImplicitlyDereferenced.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsImplicitlyDereferenced.cs
new file mode 100644
index 0000000000..ea81cb8ec5
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IsImplicitlyDereferenced.cs
@@ -0,0 +1,22 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Runtime.CompilerServices
+{
+ // Consider the following C++ method prototypes:
+ // 1) int foo(int ^arg);
+ // 2) int foo(int &arg);
+ //
+ // Both of these methods will have a .NET type signature that looks the
+ // same, but when importing a method from a metadata scope, the compiler
+ // needs to know what the calling syntax should be. This modopt and its
+ // partner "IsExplicitlyDereferenced" disambiguate reference versus
+ // pointer arguments.
+ //
+ // Indicates that the modified GC reference represents a reference in a
+ // method signature.
+ public static class IsImplicitlyDereferenced
+ {
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsJitIntrinsic.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsJitIntrinsic.cs
new file mode 100644
index 0000000000..013e50f3ea
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IsJitIntrinsic.cs
@@ -0,0 +1,12 @@
+// 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.Runtime.CompilerServices
+{
+ // Indicates that the modified method is an intrinsic for which the JIT
+ // can perform special code generation.
+ public static class IsJitIntrinsic
+ {
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsLong.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsLong.cs
new file mode 100644
index 0000000000..e8bebfb2d3
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IsLong.cs
@@ -0,0 +1,18 @@
+// 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.Runtime.CompilerServices
+{
+ // The C++ standard indicates that a long is always 4-bytes, whereas the
+ // size of an integer is system dependent (not exceedign sizeof(long)).
+ // The CLR does not offer a mechanism for encoding this distinction,
+ // but it is critically important for maintaining language level type
+ // safety.
+ //
+ // Indicates that the modified integer is a standard C++ long.
+ // Could also be called IsAlternateIntegerType or something else.
+ public static class IsLong
+ {
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsPinned.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsPinned.cs
new file mode 100644
index 0000000000..e796d1a1e7
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IsPinned.cs
@@ -0,0 +1,11 @@
+// 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.Runtime.CompilerServices
+{
+ // Indicates that the modified instance is pinned in memory.
+ public static class IsPinned
+ {
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsSignUnspecifiedByte.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsSignUnspecifiedByte.cs
new file mode 100644
index 0000000000..e68f4d7751
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IsSignUnspecifiedByte.cs
@@ -0,0 +1,16 @@
+// 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.Runtime.CompilerServices
+{
+ // C++ recognizes three char types: signed char, unsigned char, and char.
+ // When a char is neither signed nor unsigned, it is a char.
+ // This modopt indicates that the modified instance is a char.
+ //
+ // Any compiler could use this to indicate that the user has not specified
+ // Sign behavior for the given byte.
+ public static class IsSignUnspecifiedByte
+ {
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsUdtReturn.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsUdtReturn.cs
new file mode 100644
index 0000000000..dd85914b53
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IsUdtReturn.cs
@@ -0,0 +1,11 @@
+// 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.Runtime.CompilerServices
+{
+ // Indicates that the return type is a user defined type
+ public static class IsUdtReturn
+ {
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IsVolatile.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IsVolatile.cs
new file mode 100644
index 0000000000..ea2fe032c6
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IsVolatile.cs
@@ -0,0 +1,13 @@
+// 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.Runtime.CompilerServices
+{
+[System.Runtime.InteropServices.ComVisible(true)]
+ public static class IsVolatile
+ {
+ // no instantiation, please!
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs
new file mode 100644
index 0000000000..4bb9b4eb8f
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/IteratorStateMachineAttribute.cs
@@ -0,0 +1,18 @@
+// 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;
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable, AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
+ public sealed class IteratorStateMachineAttribute : StateMachineAttribute
+ {
+ public IteratorStateMachineAttribute(Type stateMachineType)
+ : base(stateMachineType)
+ {
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/MethodImplAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/MethodImplAttribute.cs
new file mode 100644
index 0000000000..d081d70070
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/MethodImplAttribute.cs
@@ -0,0 +1,77 @@
+// 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.Runtime.CompilerServices {
+
+ using System;
+ using System.Reflection;
+
+ // This Enum matchs the miImpl flags defined in corhdr.h. It is used to specify
+ // certain method properties.
+
+ [Serializable]
+ [Flags]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public enum MethodImplOptions
+ {
+ Unmanaged = System.Reflection.MethodImplAttributes.Unmanaged,
+ ForwardRef = System.Reflection.MethodImplAttributes.ForwardRef,
+ PreserveSig = System.Reflection.MethodImplAttributes.PreserveSig,
+ InternalCall = System.Reflection.MethodImplAttributes.InternalCall,
+ Synchronized = System.Reflection.MethodImplAttributes.Synchronized,
+ NoInlining = System.Reflection.MethodImplAttributes.NoInlining,
+ [System.Runtime.InteropServices.ComVisible(false)]
+ AggressiveInlining = System.Reflection.MethodImplAttributes.AggressiveInlining,
+ NoOptimization = System.Reflection.MethodImplAttributes.NoOptimization,
+ // **** If you add something, update internal MethodImplAttribute(MethodImplAttributes methodImplAttributes)! ****
+ }
+
+ [Serializable]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public enum MethodCodeType
+ {
+ IL = System.Reflection.MethodImplAttributes.IL,
+ Native = System.Reflection.MethodImplAttributes.Native,
+ /// <internalonly/>
+ OPTIL = System.Reflection.MethodImplAttributes.OPTIL,
+ Runtime = System.Reflection.MethodImplAttributes.Runtime
+ }
+
+ // Custom attribute to specify additional method properties.
+[Serializable]
+[AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ sealed public class MethodImplAttribute : Attribute
+ {
+ internal MethodImplOptions _val;
+ public MethodCodeType MethodCodeType;
+
+ internal MethodImplAttribute(MethodImplAttributes methodImplAttributes)
+ {
+ MethodImplOptions all =
+ MethodImplOptions.Unmanaged | MethodImplOptions.ForwardRef | MethodImplOptions.PreserveSig |
+ MethodImplOptions.InternalCall | MethodImplOptions.Synchronized |
+ MethodImplOptions.NoInlining | MethodImplOptions.AggressiveInlining |
+ MethodImplOptions.NoOptimization;
+ _val = ((MethodImplOptions)methodImplAttributes) & all;
+ }
+
+ public MethodImplAttribute(MethodImplOptions methodImplOptions)
+ {
+ _val = methodImplOptions;
+ }
+
+ public MethodImplAttribute(short value)
+ {
+ _val = (MethodImplOptions)value;
+ }
+
+ public MethodImplAttribute()
+ {
+ }
+
+ public MethodImplOptions Value { get {return _val;} }
+ }
+
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/NativeCppClassAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/NativeCppClassAttribute.cs
new file mode 100644
index 0000000000..0d6c759d76
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/NativeCppClassAttribute.cs
@@ -0,0 +1,16 @@
+// 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;
+
+namespace System.Runtime.CompilerServices {
+[Serializable]
+[AttributeUsage(AttributeTargets.Struct, Inherited = true),
+ System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class NativeCppClassAttribute : Attribute
+ {
+ public NativeCppClassAttribute () {}
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs
new file mode 100644
index 0000000000..d5e64a1177
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/ReferenceAssemblyAttribute.cs
@@ -0,0 +1,39 @@
+// 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.
+
+/*============================================================
+**
+** Attribute: ReferenceAssemblyAttribute
+**
+** Purpose: Identifies an assembly as being a "reference
+** assembly", meaning it contains public surface area but
+** no usable implementation. Reference assemblies
+** should be loadable for introspection, but not execution.
+**
+============================================================*/
+namespace System.Runtime.CompilerServices
+{
+ using System;
+
+ [Serializable]
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=false)]
+ public sealed class ReferenceAssemblyAttribute : Attribute
+ {
+ private String _description; // Maybe ".NET FX v4.0 SP1, partial trust"?
+
+ public ReferenceAssemblyAttribute()
+ {
+ }
+
+ public ReferenceAssemblyAttribute(String description)
+ {
+ _description = description;
+ }
+
+ public String Description
+ {
+ get { return _description; }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/RequiredAttributeAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/RequiredAttributeAttribute.cs
new file mode 100644
index 0000000000..f363696ebd
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/RequiredAttributeAttribute.cs
@@ -0,0 +1,26 @@
+// 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;
+
+namespace System.Runtime.CompilerServices
+{
+[Serializable]
+[AttributeUsage (AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface,
+ AllowMultiple=true, Inherited=false)]
+[System.Runtime.InteropServices.ComVisible(true)]
+ public sealed class RequiredAttributeAttribute : Attribute
+ {
+ private Type requiredContract;
+
+ public RequiredAttributeAttribute (Type requiredContract)
+ {
+ this.requiredContract= requiredContract;
+ }
+ public Type RequiredContract
+ {
+ get { return this.requiredContract; }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs
new file mode 100644
index 0000000000..40a9b7c568
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeCompatibilityAttribute.cs
@@ -0,0 +1,48 @@
+// 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: Mark up the program to indicate various legacy or new opt-in behaviors.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.CompilerServices
+{
+
+ using System;
+
+[Serializable]
+[AttributeUsage(AttributeTargets.Assembly, Inherited=false, AllowMultiple=false)]
+ public sealed class RuntimeCompatibilityAttribute : Attribute
+ {
+ // fields
+ private bool m_wrapNonExceptionThrows;
+
+ // constructors
+ public RuntimeCompatibilityAttribute() {
+ // legacy behavior is the default, and m_wrapNonExceptionThrows is implicitly
+ // false thanks to the CLR's guarantee of zeroed memory.
+ }
+
+ // properties
+
+ // If a non-CLSCompliant exception (i.e. one that doesn't derive from System.Exception) is
+ // thrown, should it be wrapped up in a System.Runtime.CompilerServices.RuntimeWrappedException
+ // instance when presented to catch handlers?
+ public bool WrapNonExceptionThrows {
+ get {
+ return m_wrapNonExceptionThrows;
+ }
+ set {
+ m_wrapNonExceptionThrows = value;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs
new file mode 100644
index 0000000000..d20fe0bffd
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeHelpers.cs
@@ -0,0 +1,248 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+//
+// RuntimeHelpers
+// This class defines a set of static methods that provide support for compilers.
+//
+//
+namespace System.Runtime.CompilerServices {
+
+ using System;
+ using System.Security;
+ using System.Runtime;
+ using System.Runtime.CompilerServices;
+ using System.Runtime.InteropServices;
+ using System.Runtime.ConstrainedExecution;
+ using System.Runtime.Serialization;
+ using System.Security.Permissions;
+ using System.Threading;
+ using System.Runtime.Versioning;
+ using System.Diagnostics.Contracts;
+
+ public static class RuntimeHelpers
+ {
+#if FEATURE_CORECLR
+ // 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);
+ }
+#endif // FEATURE_CORECLR
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern void InitializeArray(Array array,RuntimeFieldHandle fldHandle);
+
+ // GetObjectValue is intended to allow value classes to be manipulated as 'Object'
+ // but have aliasing behavior of a value class. The intent is that you would use
+ // this function just before an assignment to a variable of type 'Object'. If the
+ // value being assigned is a mutable value class, then a shallow copy is returned
+ // (because value classes have copy semantics), but otherwise the object itself
+ // is returned.
+ //
+ // Note: VB calls this method when they're about to assign to an Object
+ // or pass it as a parameter. The goal is to make sure that boxed
+ // value types work identical to unboxed value types - ie, they get
+ // cloned when you pass them around, and are always passed by value.
+ // Of course, reference types are not cloned.
+ //
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern Object GetObjectValue(Object obj);
+
+ // RunClassConstructor causes the class constructor for the given type to be triggered
+ // in the current domain. After this call returns, the class constructor is guaranteed to
+ // have at least been started by some thread. In the absence of class constructor
+ // deadlock conditions, the call is further guaranteed to have completed.
+ //
+ // This call will generate an exception if the specified class constructor threw an
+ // exception when it ran.
+
+ [System.Security.SecuritySafeCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void _RunClassConstructor(RuntimeType type);
+
+ public static void RunClassConstructor(RuntimeTypeHandle type)
+ {
+ _RunClassConstructor(type.GetRuntimeType());
+ }
+
+ // RunModuleConstructor causes the module constructor for the given type to be triggered
+ // in the current domain. After this call returns, the module constructor is guaranteed to
+ // have at least been started by some thread. In the absence of module constructor
+ // deadlock conditions, the call is further guaranteed to have completed.
+ //
+ // This call will generate an exception if the specified module constructor threw an
+ // exception when it ran.
+
+ [System.Security.SecuritySafeCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static extern void _RunModuleConstructor(System.Reflection.RuntimeModule module);
+
+ public static void RunModuleConstructor(ModuleHandle module)
+ {
+ _RunModuleConstructor(module.GetRuntimeModule());
+ }
+
+ [System.Security.SecurityCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ private static unsafe extern void _PrepareMethod(IRuntimeMethodInfo method, IntPtr* pInstantiation, int cInstantiation);
+
+ [System.Security.SecurityCritical] // auto-generated
+ [DllImport(JitHelpers.QCall, CharSet = CharSet.Unicode), SuppressUnmanagedCodeSecurity]
+ internal static extern void _CompileMethod(IRuntimeMethodInfo method);
+
+ // Simple (instantiation not required) method.
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void PrepareMethod(RuntimeMethodHandle method)
+ {
+ unsafe
+ {
+ _PrepareMethod(method.GetMethodInfo(), null, 0);
+ }
+ }
+
+ // Generic method or method with generic class with specific instantiation.
+ [System.Security.SecurityCritical] // auto-generated_required
+ public static void PrepareMethod(RuntimeMethodHandle method, RuntimeTypeHandle[] instantiation)
+ {
+ unsafe
+ {
+ int length;
+ IntPtr[] instantiationHandles = RuntimeTypeHandle.CopyRuntimeTypeHandles(instantiation, out length);
+ fixed (IntPtr* pInstantiation = instantiationHandles)
+ {
+ _PrepareMethod(method.GetMethodInfo(), pInstantiation, length);
+ GC.KeepAlive(instantiation);
+ }
+ }
+ }
+
+ // This method triggers a given delegate to be prepared. This involves preparing the
+ // delegate's Invoke method and preparing the target of that Invoke. In the case of
+ // a multi-cast delegate, we rely on the fact that each individual component was prepared
+ // prior to the Combine. In other words, this service does not navigate through the
+ // entire multicasting list.
+ // If our own reliable event sinks perform the Combine (for example AppDomain.DomainUnload),
+ // then the result is fully prepared. But if a client calls Combine himself and then
+ // then adds that combination to e.g. AppDomain.DomainUnload, then the client is responsible
+ // for his own preparation.
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern void PrepareDelegate(Delegate d);
+
+ // See comment above for PrepareDelegate
+ //
+ // PrepareContractedDelegate weakens this a bit by only assuring that we prepare
+ // delegates which also have a ReliabilityContract. This is useful for services that
+ // want to provide opt-in reliability, generally some random event sink providing
+ // always reliable semantics to random event handlers that are likely to have not
+ // been written with relability in mind is a lost cause anyway.
+ //
+ // NOTE: that for the NGen case you can sidestep the required ReliabilityContract
+ // by using the [PrePrepareMethod] attribute.
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern void PrepareContractedDelegate(Delegate d);
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern int GetHashCode(Object o);
+
+ [System.Security.SecuritySafeCritical] // auto-generated
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public new static extern bool Equals(Object o1, Object o2);
+
+ public static int OffsetToStringData
+ {
+ // This offset is baked in by string indexer intrinsic, so there is no harm
+ // in getting it baked in here as well.
+ [System.Runtime.Versioning.NonVersionable]
+ get {
+ // Number of bytes from the address pointed to by a reference to
+ // a String to the first 16-bit character in the String. Skip
+ // over the MethodTable pointer, & String
+ // length. Of course, the String reference points to the memory
+ // after the sync block, so don't count that.
+ // This property allows C#'s fixed statement to work on Strings.
+ // On 64 bit platforms, this should be 12 (8+4) and on 32 bit 8 (4+4).
+#if BIT64
+ return 12;
+#else // 32
+ return 8;
+#endif // BIT64
+ }
+ }
+
+ // This method ensures that there is sufficient stack to execute the average Framework function.
+ // If there is not enough stack, then it throws System.InsufficientExecutionStackException.
+ // Note: this method is not part of the CER support, and is not to be confused with ProbeForSufficientStack
+ // below.
+ [System.Security.SecuritySafeCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ public static extern void EnsureSufficientExecutionStack();
+
+#if FEATURE_CORECLR
+ // This method ensures that there is sufficient stack to execute the average Framework function.
+ // If there is not enough stack, then it return false.
+ // Note: this method is not part of the CER support, and is not to be confused with ProbeForSufficientStack
+ // below.
+ [System.Security.SecuritySafeCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+ internal static extern bool TryEnsureSufficientExecutionStack();
+#endif
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ public static extern 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.
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ 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.
+ [System.Security.SecurityCritical] // auto-generated_required
+ [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
+ public static void PrepareConstrainedRegionsNoOP()
+ {
+ }
+
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ public delegate void TryCode(Object userData);
+
+ #if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+ #endif
+ public delegate void CleanupCode(Object userData, bool exceptionThrown);
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public static extern void ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData);
+
+#if FEATURE_CORECLR
+ [System.Security.SecurityCritical] // auto-generated
+#endif
+ [PrePrepareMethod]
+ internal static void ExecuteBackoutCodeHelper(Object backoutCode, Object userData, bool exceptionThrown)
+ {
+ ((CleanupCode)backoutCode)(userData, exceptionThrown);
+ }
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeWrappedException.cs b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeWrappedException.cs
new file mode 100644
index 0000000000..2751d61db7
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/RuntimeWrappedException.cs
@@ -0,0 +1,52 @@
+// 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: The exception class uses to wrap all non-CLS compliant exceptions.
+**
+**
+=============================================================================*/
+
+namespace System.Runtime.CompilerServices {
+ using System;
+ using System.Runtime.Serialization;
+ using System.Runtime.Remoting;
+ using System.Security.Permissions;
+ using System.Diagnostics.Contracts;
+
+ [Serializable]
+ public sealed class RuntimeWrappedException : Exception
+ {
+ private RuntimeWrappedException(Object thrownObject)
+ : base(Environment.GetResourceString("RuntimeWrappedException")) {
+ SetErrorCode(System.__HResults.COR_E_RUNTIMEWRAPPED);
+ m_wrappedException = thrownObject;
+ }
+
+ public Object WrappedException {
+ get { return m_wrappedException; }
+ }
+
+ private Object m_wrappedException;
+
+ [System.Security.SecurityCritical] // auto-generated_required
+ public override void GetObjectData(SerializationInfo info, StreamingContext context) {
+ if (info==null) {
+ throw new ArgumentNullException("info");
+ }
+ Contract.EndContractBlock();
+ base.GetObjectData(info, context);
+ info.AddValue("WrappedException", m_wrappedException, typeof(Object));
+ }
+
+ internal RuntimeWrappedException(SerializationInfo info, StreamingContext context)
+ : base(info, context) {
+ m_wrappedException = info.GetValue("WrappedException", typeof(Object));
+ }
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/ScopelessEnumAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/ScopelessEnumAttribute.cs
new file mode 100644
index 0000000000..91769187cc
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/ScopelessEnumAttribute.cs
@@ -0,0 +1,14 @@
+// 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.Runtime.CompilerServices
+{
+[Serializable]
+[AttributeUsage(AttributeTargets.Enum)]
+ public sealed class ScopelessEnumAttribute : Attribute
+ {
+ public ScopelessEnumAttribute()
+ {}
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/SpecialNameAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/SpecialNameAttribute.cs
new file mode 100644
index 0000000000..38e5538b44
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/SpecialNameAttribute.cs
@@ -0,0 +1,27 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+
+using System;
+using System.Reflection;
+using System.Runtime.InteropServices;
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Class |
+ AttributeTargets.Method |
+ AttributeTargets.Property |
+ AttributeTargets.Field |
+ AttributeTargets.Event |
+ AttributeTargets.Struct)]
+
+
+ public sealed class SpecialNameAttribute : Attribute
+ {
+ public SpecialNameAttribute() { }
+ }
+}
+
+
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/StateMachineAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/StateMachineAttribute.cs
new file mode 100644
index 0000000000..7c84009e1f
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/StateMachineAttribute.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.
+
+
+using System;
+
+namespace System.Runtime.CompilerServices
+{
+ [Serializable, AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
+ public class StateMachineAttribute : Attribute
+ {
+ public Type StateMachineType { get; private set; }
+
+ public StateMachineAttribute(Type stateMachineType)
+ {
+ this.StateMachineType = stateMachineType;
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs
new file mode 100644
index 0000000000..eb019eecbf
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/SuppressIldasmAttribute.cs
@@ -0,0 +1,19 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+namespace System.Runtime.CompilerServices
+{
+ using System;
+
+ [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module)]
+ public sealed class SuppressIldasmAttribute : Attribute
+ {
+ public SuppressIldasmAttribute()
+ {
+ }
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/SuppressMergeCheckAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/SuppressMergeCheckAttribute.cs
new file mode 100644
index 0000000000..6bb36c4bf5
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/SuppressMergeCheckAttribute.cs
@@ -0,0 +1,23 @@
+// 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.InteropServices;
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Class |
+ AttributeTargets.Constructor |
+ AttributeTargets.Method |
+ AttributeTargets.Field |
+ AttributeTargets.Event |
+ AttributeTargets.Property)]
+
+ internal sealed class SuppressMergeCheckAttribute : Attribute
+ {
+ public SuppressMergeCheckAttribute()
+ {}
+ }
+}
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/TaskAwaiter.cs b/src/mscorlib/src/System/Runtime/CompilerServices/TaskAwaiter.cs
new file mode 100644
index 0000000000..ea6bb96e16
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/TaskAwaiter.cs
@@ -0,0 +1,531 @@
+// 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.
+
+// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+//
+//
+//
+// Types for awaiting Task and Task<T>. These types are emitted from Task{<T>}.GetAwaiter
+// and Task{<T>}.ConfigureAwait. They are meant to be used only by the compiler, e.g.
+//
+// await nonGenericTask;
+// =====================
+// var $awaiter = nonGenericTask.GetAwaiter();
+// if (!$awaiter.IsCompleted)
+// {
+// SPILL:
+// $builder.AwaitUnsafeOnCompleted(ref $awaiter, ref this);
+// return;
+// Label:
+// UNSPILL;
+// }
+// $awaiter.GetResult();
+//
+// result += await genericTask.ConfigureAwait(false);
+// ===================================================================================
+// var $awaiter = genericTask.ConfigureAwait(false).GetAwaiter();
+// if (!$awaiter.IsCompleted)
+// {
+// SPILL;
+// $builder.AwaitUnsafeOnCompleted(ref $awaiter, ref this);
+// return;
+// Label:
+// UNSPILL;
+// }
+// result += $awaiter.GetResult();
+//
+// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+using System;
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Diagnostics.Contracts;
+using System.Security;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Security.Permissions;
+using System.Diagnostics.Tracing;
+
+// NOTE: For performance reasons, initialization is not verified. If a developer
+// incorrectly initializes a task awaiter, which should only be done by the compiler,
+// NullReferenceExceptions may be generated (the alternative would be for us to detect
+// this case and then throw a different exception instead). This is the same tradeoff
+// that's made with other compiler-focused value types like List<T>.Enumerator.
+
+namespace System.Runtime.CompilerServices
+{
+ /// <summary>Provides an awaiter for awaiting a <see cref="System.Threading.Tasks.Task"/>.</summary>
+ /// <remarks>This type is intended for compiler use only.</remarks>
+ [HostProtection(Synchronization = true, ExternalThreading = true)]
+ public struct TaskAwaiter : ICriticalNotifyCompletion
+ {
+ /// <summary>The task being awaited.</summary>
+ private readonly Task m_task;
+
+ /// <summary>Initializes the <see cref="TaskAwaiter"/>.</summary>
+ /// <param name="task">The <see cref="System.Threading.Tasks.Task"/> to be awaited.</param>
+ internal TaskAwaiter(Task task)
+ {
+ Contract.Requires(task != null, "Constructing an awaiter requires a task to await.");
+ m_task = task;
+ }
+
+ /// <summary>Gets whether the task being awaited is completed.</summary>
+ /// <remarks>This property is intended for compiler user rather than use directly in code.</remarks>
+ /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
+ public bool IsCompleted
+ {
+ get { return m_task.IsCompleted; }
+ }
+
+ /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
+ /// <param name="continuation">The action to invoke when the await operation completes.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.InvalidOperationException">The awaiter was not properly initialized.</exception>
+ /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
+ [SecuritySafeCritical]
+ public void OnCompleted(Action continuation)
+ {
+ OnCompletedInternal(m_task, continuation, continueOnCapturedContext:true, flowExecutionContext:true);
+ }
+
+ /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
+ /// <param name="continuation">The action to invoke when the await operation completes.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.InvalidOperationException">The awaiter was not properly initialized.</exception>
+ /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
+ [SecurityCritical]
+ public void UnsafeOnCompleted(Action continuation)
+ {
+ OnCompletedInternal(m_task, continuation, continueOnCapturedContext:true, flowExecutionContext:false);
+ }
+
+ /// <summary>Ends the await on the completed <see cref="System.Threading.Tasks.Task"/>.</summary>
+ /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
+ /// <exception cref="System.Threading.Tasks.TaskCanceledException">The task was canceled.</exception>
+ /// <exception cref="System.Exception">The task completed in a Faulted state.</exception>
+ public void GetResult()
+ {
+ ValidateEnd(m_task);
+ }
+
+ /// <summary>
+ /// Fast checks for the end of an await operation to determine whether more needs to be done
+ /// prior to completing the await.
+ /// </summary>
+ /// <param name="task">The awaited task.</param>
+ internal static void ValidateEnd(Task task)
+ {
+ // Fast checks that can be inlined.
+ if (task.IsWaitNotificationEnabledOrNotRanToCompletion)
+ {
+ // If either the end await bit is set or we're not completed successfully,
+ // fall back to the slower path.
+ HandleNonSuccessAndDebuggerNotification(task);
+ }
+ }
+
+ /// <summary>
+ /// Ensures the task is completed, triggers any necessary debugger breakpoints for completing
+ /// the await on the task, and throws an exception if the task did not complete successfully.
+ /// </summary>
+ /// <param name="task">The awaited task.</param>
+ private static void HandleNonSuccessAndDebuggerNotification(Task task)
+ {
+ // NOTE: The JIT refuses to inline ValidateEnd when it contains the contents
+ // of HandleNonSuccessAndDebuggerNotification, hence the separation.
+
+ // Synchronously wait for the task to complete. When used by the compiler,
+ // the task will already be complete. This code exists only for direct GetResult use,
+ // for cases where the same exception propagation semantics used by "await" are desired,
+ // but where for one reason or another synchronous rather than asynchronous waiting is needed.
+ if (!task.IsCompleted)
+ {
+ bool taskCompleted = task.InternalWait(Timeout.Infinite, default(CancellationToken));
+ Contract.Assert(taskCompleted, "With an infinite timeout, the task should have always completed.");
+ }
+
+ // Now that we're done, alert the debugger if so requested
+ task.NotifyDebuggerOfWaitCompletionIfNecessary();
+
+ // And throw an exception if the task is faulted or canceled.
+ if (!task.IsRanToCompletion) ThrowForNonSuccess(task);
+ }
+
+ /// <summary>Throws an exception to handle a task that completed in a state other than RanToCompletion.</summary>
+ private static void ThrowForNonSuccess(Task task)
+ {
+ Contract.Requires(task.IsCompleted, "Task must have been completed by now.");
+ Contract.Requires(task.Status != TaskStatus.RanToCompletion, "Task should not be completed successfully.");
+
+ // Handle whether the task has been canceled or faulted
+ switch (task.Status)
+ {
+ // If the task completed in a canceled state, throw an OperationCanceledException.
+ // This will either be the OCE that actually caused the task to cancel, or it will be a new
+ // TaskCanceledException. TCE derives from OCE, and by throwing it we automatically pick up the
+ // completed task's CancellationToken if it has one, including that CT in the OCE.
+ case TaskStatus.Canceled:
+ var oceEdi = task.GetCancellationExceptionDispatchInfo();
+ if (oceEdi != null)
+ {
+ oceEdi.Throw();
+ Contract.Assert(false, "Throw() should have thrown");
+ }
+ throw new TaskCanceledException(task);
+
+ // If the task faulted, throw its first exception,
+ // even if it contained more than one.
+ case TaskStatus.Faulted:
+ var edis = task.GetExceptionDispatchInfos();
+ if (edis.Count > 0)
+ {
+ edis[0].Throw();
+ Contract.Assert(false, "Throw() should have thrown");
+ break; // Necessary to compile: non-reachable, but compiler can't determine that
+ }
+ else
+ {
+ Contract.Assert(false, "There should be exceptions if we're Faulted.");
+ throw task.Exception;
+ }
+ }
+ }
+
+ /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
+ /// <param name="task">The task being awaited.</param>
+ /// <param name="continuation">The action to invoke when the await operation completes.</param>
+ /// <param name="continueOnCapturedContext">Whether to capture and marshal back to the current context.</param>
+ /// <param name="flowExecutionContext">Whether to flow ExecutionContext across the await.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
+ /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
+ [MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var have to be marked non-inlineable
+ [SecurityCritical]
+ internal static void OnCompletedInternal(Task task, Action continuation, bool continueOnCapturedContext, bool flowExecutionContext)
+ {
+ if (continuation == null) throw new ArgumentNullException("continuation");
+ StackCrawlMark stackMark = StackCrawlMark.LookForMyCaller;
+
+ // If TaskWait* ETW events are enabled, trace a beginning event for this await
+ // and set up an ending event to be traced when the asynchronous await completes.
+ if ( TplEtwProvider.Log.IsEnabled() || Task.s_asyncDebuggingEnabled)
+ {
+ continuation = OutputWaitEtwEvents(task, continuation);
+ }
+
+ // Set the continuation onto the awaited task.
+ task.SetContinuationForAwait(continuation, continueOnCapturedContext, flowExecutionContext, ref stackMark);
+ }
+
+ /// <summary>
+ /// Outputs a WaitBegin ETW event, and augments the continuation action to output a WaitEnd ETW event.
+ /// </summary>
+ /// <param name="task">The task being awaited.</param>
+ /// <param name="continuation">The action to invoke when the await operation completes.</param>
+ /// <returns>The action to use as the actual continuation.</returns>
+ private static Action OutputWaitEtwEvents(Task task, Action continuation)
+ {
+ Contract.Requires(task != null, "Need a task to wait on");
+ Contract.Requires(continuation != null, "Need a continuation to invoke when the wait completes");
+
+ if (Task.s_asyncDebuggingEnabled)
+ {
+ Task.AddToActiveTasks(task);
+ }
+
+ var etwLog = TplEtwProvider.Log;
+
+ if (etwLog.IsEnabled())
+ {
+ // ETW event for Task Wait Begin
+ var currentTaskAtBegin = Task.InternalCurrent;
+
+ // If this task's continuation is another task, get it.
+ var continuationTask = AsyncMethodBuilderCore.TryGetContinuationTask(continuation);
+ etwLog.TaskWaitBegin(
+ (currentTaskAtBegin != null ? currentTaskAtBegin.m_taskScheduler.Id : TaskScheduler.Default.Id),
+ (currentTaskAtBegin != null ? currentTaskAtBegin.Id : 0),
+ task.Id, TplEtwProvider.TaskWaitBehavior.Asynchronous,
+ (continuationTask != null ? continuationTask.Id : 0), System.Threading.Thread.GetDomainID());
+ }
+
+ // Create a continuation action that outputs the end event and then invokes the user
+ // provided delegate. This incurs the allocations for the closure/delegate, but only if the event
+ // is enabled, and in doing so it allows us to pass the awaited task's information into the end event
+ // in a purely pay-for-play manner (the alternatively would be to increase the size of TaskAwaiter
+ // just for this ETW purpose, not pay-for-play, since GetResult would need to know whether a real yield occurred).
+ return AsyncMethodBuilderCore.CreateContinuationWrapper(continuation, () =>
+ {
+ if (Task.s_asyncDebuggingEnabled)
+ {
+ Task.RemoveFromActiveTasks(task.Id);
+ }
+
+ // ETW event for Task Wait End.
+ Guid prevActivityId = new Guid();
+ bool bEtwLogEnabled = etwLog.IsEnabled();
+ if (bEtwLogEnabled)
+ {
+ var currentTaskAtEnd = Task.InternalCurrent;
+ etwLog.TaskWaitEnd(
+ (currentTaskAtEnd != null ? currentTaskAtEnd.m_taskScheduler.Id : TaskScheduler.Default.Id),
+ (currentTaskAtEnd != null ? currentTaskAtEnd.Id : 0),
+ task.Id);
+
+ // Ensure the continuation runs under the activity ID of the task that completed for the
+ // case the antecendent is a promise (in the other cases this is already the case).
+ if (etwLog.TasksSetActivityIds && (task.Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0)
+ EventSource.SetCurrentThreadActivityId(TplEtwProvider.CreateGuidForTaskID(task.Id), out prevActivityId);
+ }
+ // Invoke the original continuation provided to OnCompleted.
+ continuation();
+
+ if (bEtwLogEnabled)
+ {
+ etwLog.TaskWaitContinuationComplete(task.Id);
+ if (etwLog.TasksSetActivityIds && (task.Options & (TaskCreationOptions)InternalTaskOptions.PromiseTask) != 0)
+ EventSource.SetCurrentThreadActivityId(prevActivityId);
+ }
+ });
+ }
+ }
+
+ /// <summary>Provides an awaiter for awaiting a <see cref="System.Threading.Tasks.Task{TResult}"/>.</summary>
+ /// <remarks>This type is intended for compiler use only.</remarks>
+ [HostProtection(Synchronization = true, ExternalThreading = true)]
+ public struct TaskAwaiter<TResult> : ICriticalNotifyCompletion
+ {
+ /// <summary>The task being awaited.</summary>
+ private readonly Task<TResult> m_task;
+
+ /// <summary>Initializes the <see cref="TaskAwaiter{TResult}"/>.</summary>
+ /// <param name="task">The <see cref="System.Threading.Tasks.Task{TResult}"/> to be awaited.</param>
+ internal TaskAwaiter(Task<TResult> task)
+ {
+ Contract.Requires(task != null, "Constructing an awaiter requires a task to await.");
+ m_task = task;
+ }
+
+ /// <summary>Gets whether the task being awaited is completed.</summary>
+ /// <remarks>This property is intended for compiler user rather than use directly in code.</remarks>
+ /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
+ public bool IsCompleted
+ {
+ get { return m_task.IsCompleted; }
+ }
+
+ /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
+ /// <param name="continuation">The action to invoke when the await operation completes.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
+ /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
+ [SecuritySafeCritical]
+ public void OnCompleted(Action continuation)
+ {
+ TaskAwaiter.OnCompletedInternal(m_task, continuation, continueOnCapturedContext:true, flowExecutionContext:true);
+ }
+
+ /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
+ /// <param name="continuation">The action to invoke when the await operation completes.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
+ /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
+ [SecurityCritical]
+ public void UnsafeOnCompleted(Action continuation)
+ {
+ TaskAwaiter.OnCompletedInternal(m_task, continuation, continueOnCapturedContext:true, flowExecutionContext:false);
+ }
+
+ /// <summary>Ends the await on the completed <see cref="System.Threading.Tasks.Task{TResult}"/>.</summary>
+ /// <returns>The result of the completed <see cref="System.Threading.Tasks.Task{TResult}"/>.</returns>
+ /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
+ /// <exception cref="System.Threading.Tasks.TaskCanceledException">The task was canceled.</exception>
+ /// <exception cref="System.Exception">The task completed in a Faulted state.</exception>
+ public TResult GetResult()
+ {
+ TaskAwaiter.ValidateEnd(m_task);
+ return m_task.ResultOnSuccess;
+ }
+ }
+
+ /// <summary>Provides an awaitable object that allows for configured awaits on <see cref="System.Threading.Tasks.Task"/>.</summary>
+ /// <remarks>This type is intended for compiler use only.</remarks>
+ public struct ConfiguredTaskAwaitable
+ {
+ /// <summary>The task being awaited.</summary>
+ private readonly ConfiguredTaskAwaitable.ConfiguredTaskAwaiter m_configuredTaskAwaiter;
+
+ /// <summary>Initializes the <see cref="ConfiguredTaskAwaitable"/>.</summary>
+ /// <param name="task">The awaitable <see cref="System.Threading.Tasks.Task"/>.</param>
+ /// <param name="continueOnCapturedContext">
+ /// true to attempt to marshal the continuation back to the original context captured; otherwise, false.
+ /// </param>
+ internal ConfiguredTaskAwaitable(Task task, bool continueOnCapturedContext)
+ {
+ Contract.Requires(task != null, "Constructing an awaitable requires a task to await.");
+ m_configuredTaskAwaiter = new ConfiguredTaskAwaitable.ConfiguredTaskAwaiter(task, continueOnCapturedContext);
+ }
+
+ /// <summary>Gets an awaiter for this awaitable.</summary>
+ /// <returns>The awaiter.</returns>
+ public ConfiguredTaskAwaitable.ConfiguredTaskAwaiter GetAwaiter()
+ {
+ return m_configuredTaskAwaiter;
+ }
+
+ /// <summary>Provides an awaiter for a <see cref="ConfiguredTaskAwaitable"/>.</summary>
+ /// <remarks>This type is intended for compiler use only.</remarks>
+ [HostProtection(Synchronization = true, ExternalThreading = true)]
+ public struct ConfiguredTaskAwaiter : ICriticalNotifyCompletion
+ {
+ /// <summary>The task being awaited.</summary>
+ private readonly Task m_task;
+ /// <summary>Whether to attempt marshaling back to the original context.</summary>
+ private readonly bool m_continueOnCapturedContext;
+
+ /// <summary>Initializes the <see cref="ConfiguredTaskAwaiter"/>.</summary>
+ /// <param name="task">The <see cref="System.Threading.Tasks.Task"/> to await.</param>
+ /// <param name="continueOnCapturedContext">
+ /// true to attempt to marshal the continuation back to the original context captured
+ /// when BeginAwait is called; otherwise, false.
+ /// </param>
+ internal ConfiguredTaskAwaiter(Task task, bool continueOnCapturedContext)
+ {
+ Contract.Requires(task != null, "Constructing an awaiter requires a task to await.");
+ m_task = task;
+ m_continueOnCapturedContext = continueOnCapturedContext;
+ }
+
+ /// <summary>Gets whether the task being awaited is completed.</summary>
+ /// <remarks>This property is intended for compiler user rather than use directly in code.</remarks>
+ /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
+ public bool IsCompleted
+ {
+ get { return m_task.IsCompleted; }
+ }
+
+ /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
+ /// <param name="continuation">The action to invoke when the await operation completes.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
+ /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
+ [SecuritySafeCritical]
+ public void OnCompleted(Action continuation)
+ {
+ TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext:true);
+ }
+
+ /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
+ /// <param name="continuation">The action to invoke when the await operation completes.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
+ /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
+ [SecurityCritical]
+ public void UnsafeOnCompleted(Action continuation)
+ {
+ TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext:false);
+ }
+
+ /// <summary>Ends the await on the completed <see cref="System.Threading.Tasks.Task"/>.</summary>
+ /// <returns>The result of the completed <see cref="System.Threading.Tasks.Task{TResult}"/>.</returns>
+ /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
+ /// <exception cref="System.Threading.Tasks.TaskCanceledException">The task was canceled.</exception>
+ /// <exception cref="System.Exception">The task completed in a Faulted state.</exception>
+ public void GetResult()
+ {
+ TaskAwaiter.ValidateEnd(m_task);
+ }
+ }
+ }
+
+ /// <summary>Provides an awaitable object that allows for configured awaits on <see cref="System.Threading.Tasks.Task{TResult}"/>.</summary>
+ /// <remarks>This type is intended for compiler use only.</remarks>
+ public struct ConfiguredTaskAwaitable<TResult>
+ {
+ /// <summary>The underlying awaitable on whose logic this awaitable relies.</summary>
+ private readonly ConfiguredTaskAwaitable<TResult>.ConfiguredTaskAwaiter m_configuredTaskAwaiter;
+
+ /// <summary>Initializes the <see cref="ConfiguredTaskAwaitable{TResult}"/>.</summary>
+ /// <param name="task">The awaitable <see cref="System.Threading.Tasks.Task{TResult}"/>.</param>
+ /// <param name="continueOnCapturedContext">
+ /// true to attempt to marshal the continuation back to the original context captured; otherwise, false.
+ /// </param>
+ internal ConfiguredTaskAwaitable(Task<TResult> task, bool continueOnCapturedContext)
+ {
+ m_configuredTaskAwaiter = new ConfiguredTaskAwaitable<TResult>.ConfiguredTaskAwaiter(task, continueOnCapturedContext);
+ }
+
+ /// <summary>Gets an awaiter for this awaitable.</summary>
+ /// <returns>The awaiter.</returns>
+ public ConfiguredTaskAwaitable<TResult>.ConfiguredTaskAwaiter GetAwaiter()
+ {
+ return m_configuredTaskAwaiter;
+ }
+
+ /// <summary>Provides an awaiter for a <see cref="ConfiguredTaskAwaitable{TResult}"/>.</summary>
+ /// <remarks>This type is intended for compiler use only.</remarks>
+ [HostProtection(Synchronization = true, ExternalThreading = true)]
+ public struct ConfiguredTaskAwaiter : ICriticalNotifyCompletion
+ {
+ /// <summary>The task being awaited.</summary>
+ private readonly Task<TResult> m_task;
+ /// <summary>Whether to attempt marshaling back to the original context.</summary>
+ private readonly bool m_continueOnCapturedContext;
+
+ /// <summary>Initializes the <see cref="ConfiguredTaskAwaiter"/>.</summary>
+ /// <param name="task">The awaitable <see cref="System.Threading.Tasks.Task{TResult}"/>.</param>
+ /// <param name="continueOnCapturedContext">
+ /// true to attempt to marshal the continuation back to the original context captured; otherwise, false.
+ /// </param>
+ internal ConfiguredTaskAwaiter(Task<TResult> task, bool continueOnCapturedContext)
+ {
+ Contract.Requires(task != null, "Constructing an awaiter requires a task to await.");
+ m_task = task;
+ m_continueOnCapturedContext = continueOnCapturedContext;
+ }
+
+ /// <summary>Gets whether the task being awaited is completed.</summary>
+ /// <remarks>This property is intended for compiler user rather than use directly in code.</remarks>
+ /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
+ public bool IsCompleted
+ {
+ get { return m_task.IsCompleted; }
+ }
+
+ /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
+ /// <param name="continuation">The action to invoke when the await operation completes.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
+ /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
+ [SecuritySafeCritical]
+ public void OnCompleted(Action continuation)
+ {
+ TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext:true);
+ }
+
+ /// <summary>Schedules the continuation onto the <see cref="System.Threading.Tasks.Task"/> associated with this <see cref="TaskAwaiter"/>.</summary>
+ /// <param name="continuation">The action to invoke when the await operation completes.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
+ /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
+ /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
+ [SecurityCritical]
+ public void UnsafeOnCompleted(Action continuation)
+ {
+ TaskAwaiter.OnCompletedInternal(m_task, continuation, m_continueOnCapturedContext, flowExecutionContext:false);
+ }
+
+ /// <summary>Ends the await on the completed <see cref="System.Threading.Tasks.Task{TResult}"/>.</summary>
+ /// <returns>The result of the completed <see cref="System.Threading.Tasks.Task{TResult}"/>.</returns>
+ /// <exception cref="System.NullReferenceException">The awaiter was not properly initialized.</exception>
+ /// <exception cref="System.Threading.Tasks.TaskCanceledException">The task was canceled.</exception>
+ /// <exception cref="System.Exception">The task completed in a Faulted state.</exception>
+ public TResult GetResult()
+ {
+ TaskAwaiter.ValidateEnd(m_task);
+ return m_task.ResultOnSuccess;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/TypeDependencyAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/TypeDependencyAttribute.cs
new file mode 100644
index 0000000000..db04eb9348
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/TypeDependencyAttribute.cs
@@ -0,0 +1,29 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+namespace System.Runtime.CompilerServices
+{
+ using System;
+ using System.Diagnostics.Contracts;
+
+ // We might want to make this inherited someday. But I suspect it shouldn't
+ // be necessary.
+ [AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = true, Inherited = false)]
+ internal sealed class TypeDependencyAttribute: Attribute
+ {
+
+ private string typeName;
+
+ public TypeDependencyAttribute (string typeName)
+ {
+ if(typeName == null) throw new ArgumentNullException("typeName");
+ Contract.EndContractBlock();
+ this.typeName = typeName;
+ }
+ }
+
+}
+
+
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs
new file mode 100644
index 0000000000..c1656dcf99
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedFromAttribute.cs
@@ -0,0 +1,35 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+
+namespace System.Runtime.CompilerServices
+{
+ [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false, AllowMultiple = false)]
+ public sealed class TypeForwardedFromAttribute : Attribute
+ {
+ string assemblyFullName;
+
+ private TypeForwardedFromAttribute()
+ {
+ // Disallow default constructor
+ }
+
+
+ public TypeForwardedFromAttribute(string assemblyFullName)
+ {
+ if (String.IsNullOrEmpty(assemblyFullName))
+ {
+ throw new ArgumentNullException("assemblyFullName");
+ }
+ this.assemblyFullName = assemblyFullName;
+ }
+
+ public string AssemblyFullName
+ {
+ get {
+ return assemblyFullName;
+ }
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs
new file mode 100644
index 0000000000..034dad1afe
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/TypeForwardedToAttribute.cs
@@ -0,0 +1,47 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+
+using System;
+using System.Reflection;
+
+namespace System.Runtime.CompilerServices
+{
+ using System;
+ [AttributeUsage(AttributeTargets.Assembly, AllowMultiple=true, Inherited=false)]
+ public sealed class TypeForwardedToAttribute : Attribute
+ {
+ private Type _destination;
+
+ public TypeForwardedToAttribute(Type destination)
+ {
+ _destination = destination;
+ }
+
+ public Type Destination
+ {
+ get {
+ return _destination;
+ }
+ }
+
+ [System.Security.SecurityCritical]
+ internal static TypeForwardedToAttribute[] GetCustomAttribute(RuntimeAssembly assembly)
+ {
+ Type[] types = null;
+ RuntimeAssembly.GetForwardedTypes(assembly.GetNativeHandle(), JitHelpers.GetObjectHandleOnStack(ref types));
+
+ TypeForwardedToAttribute[] attributes = new TypeForwardedToAttribute[types.Length];
+ for (int i = 0; i < types.Length; ++i)
+ attributes[i] = new TypeForwardedToAttribute(types[i]);
+
+ return attributes;
+ }
+
+ }
+}
+
+
+
+
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs b/src/mscorlib/src/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs
new file mode 100644
index 0000000000..bc210ccb71
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/UnsafeValueTypeAttribute.cs
@@ -0,0 +1,14 @@
+// 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.Runtime.CompilerServices
+{
+ using System;
+
+[Serializable]
+[AttributeUsage(AttributeTargets.Struct)]
+ sealed public class UnsafeValueTypeAttribute : Attribute
+ {
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/YieldAwaitable.cs b/src/mscorlib/src/System/Runtime/CompilerServices/YieldAwaitable.cs
new file mode 100644
index 0000000000..b29b39c5bf
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/YieldAwaitable.cs
@@ -0,0 +1,168 @@
+// 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.
+
+// =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
+//
+//
+//
+// Compiler-targeted type for switching back into the current execution context, e.g.
+//
+// await Task.Yield();
+// =====================
+// var $awaiter = Task.Yield().GetAwaiter();
+// if (!$awaiter.IsCompleted)
+// {
+// $builder.AwaitUnsafeOnCompleted(ref $awaiter, ref this);
+// return;
+// Label:
+// }
+// $awaiter.GetResult();
+//
+// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+using System;
+using System.Security;
+using System.Diagnostics;
+using System.Diagnostics.Contracts;
+using System.Diagnostics.Tracing;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Security.Permissions;
+
+namespace System.Runtime.CompilerServices
+{
+ // NOTE: YieldAwaitable currently has no state; while developers are encouraged to use Task.Yield() to produce one,
+ // no validation is performed to ensure that the developer isn't doing "await new YieldAwaitable()". Such validation
+ // would require additional, useless state to be stored, and as this is a type in the CompilerServices namespace, and
+ // as the above example isn't harmful, we take the cheaper approach of not validating anything.
+
+ /// <summary>Provides an awaitable context for switching into a target environment.</summary>
+ /// <remarks>This type is intended for compiler use only.</remarks>
+ public struct YieldAwaitable
+ {
+ /// <summary>Gets an awaiter for this <see cref="YieldAwaitable"/>.</summary>
+ /// <returns>An awaiter for this awaitable.</returns>
+ /// <remarks>This method is intended for compiler user rather than use directly in code.</remarks>
+ public YieldAwaiter GetAwaiter() { return new YieldAwaiter(); }
+
+ /// <summary>Provides an awaiter that switches into a target environment.</summary>
+ /// <remarks>This type is intended for compiler use only.</remarks>
+ [HostProtection(Synchronization = true, ExternalThreading = true)]
+ public struct YieldAwaiter : ICriticalNotifyCompletion
+ {
+ /// <summary>Gets whether a yield is not required.</summary>
+ /// <remarks>This property is intended for compiler user rather than use directly in code.</remarks>
+ public bool IsCompleted { get { return false; } } // yielding is always required for YieldAwaiter, hence false
+
+ /// <summary>Posts the <paramref name="continuation"/> back to the current context.</summary>
+ /// <param name="continuation">The action to invoke asynchronously.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
+ [SecuritySafeCritical]
+ public void OnCompleted(Action continuation)
+ {
+ QueueContinuation(continuation, flowContext: true);
+ }
+
+ /// <summary>Posts the <paramref name="continuation"/> back to the current context.</summary>
+ /// <param name="continuation">The action to invoke asynchronously.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
+ [SecurityCritical]
+ public void UnsafeOnCompleted(Action continuation)
+ {
+ QueueContinuation(continuation, flowContext: false);
+ }
+
+ /// <summary>Posts the <paramref name="continuation"/> back to the current context.</summary>
+ /// <param name="continuation">The action to invoke asynchronously.</param>
+ /// <param name="flowContext">true to flow ExecutionContext; false if flowing is not required.</param>
+ /// <exception cref="System.ArgumentNullException">The <paramref name="continuation"/> argument is null (Nothing in Visual Basic).</exception>
+ [SecurityCritical]
+ private static void QueueContinuation(Action continuation, bool flowContext)
+ {
+ // Validate arguments
+ if (continuation == null) throw new ArgumentNullException("continuation");
+ Contract.EndContractBlock();
+
+ if (TplEtwProvider.Log.IsEnabled())
+ {
+ continuation = OutputCorrelationEtwEvent(continuation);
+ }
+ // Get the current SynchronizationContext, and if there is one,
+ // post the continuation to it. However, treat the base type
+ // as if there wasn't a SynchronizationContext, since that's what it
+ // logically represents.
+ var syncCtx = SynchronizationContext.CurrentNoFlow;
+ if (syncCtx != null && syncCtx.GetType() != typeof(SynchronizationContext))
+ {
+ syncCtx.Post(s_sendOrPostCallbackRunAction, continuation);
+ }
+ else
+ {
+ // If we're targeting the default scheduler, queue to the thread pool, so that we go into the global
+ // queue. As we're going into the global queue, we might as well use QUWI, which for the global queue is
+ // just a tad faster than task, due to a smaller object getting allocated and less work on the execution path.
+ TaskScheduler scheduler = TaskScheduler.Current;
+ if (scheduler == TaskScheduler.Default)
+ {
+ if (flowContext)
+ {
+ ThreadPool.QueueUserWorkItem(s_waitCallbackRunAction, continuation);
+ }
+ else
+ {
+ ThreadPool.UnsafeQueueUserWorkItem(s_waitCallbackRunAction, continuation);
+ }
+ }
+ // We're targeting a custom scheduler, so queue a task.
+ else
+ {
+ Task.Factory.StartNew(continuation, default(CancellationToken), TaskCreationOptions.PreferFairness, scheduler);
+ }
+ }
+ }
+
+ private static Action OutputCorrelationEtwEvent(Action continuation)
+ {
+ int continuationId = Task.NewId();
+ Task currentTask = Task.InternalCurrent;
+ // fire the correlation ETW event
+ TplEtwProvider.Log.AwaitTaskContinuationScheduled(TaskScheduler.Current.Id, (currentTask != null) ? currentTask.Id : 0, continuationId);
+
+ return AsyncMethodBuilderCore.CreateContinuationWrapper(continuation, () =>
+ {
+ var etwLog = TplEtwProvider.Log;
+ etwLog.TaskWaitContinuationStarted(continuationId);
+
+ // ETW event for Task Wait End.
+ Guid prevActivityId = new Guid();
+ // Ensure the continuation runs under the correlated activity ID generated above
+ if (etwLog.TasksSetActivityIds)
+ EventSource.SetCurrentThreadActivityId(TplEtwProvider.CreateGuidForTaskID(continuationId), out prevActivityId);
+
+ // Invoke the original continuation provided to OnCompleted.
+ continuation();
+ // Restore activity ID
+
+ if (etwLog.TasksSetActivityIds)
+ EventSource.SetCurrentThreadActivityId(prevActivityId);
+
+ etwLog.TaskWaitContinuationComplete(continuationId);
+ });
+
+ }
+
+ /// <summary>WaitCallback that invokes the Action supplied as object state.</summary>
+ private static readonly WaitCallback s_waitCallbackRunAction = RunAction;
+ /// <summary>SendOrPostCallback that invokes the Action supplied as object state.</summary>
+ private static readonly SendOrPostCallback s_sendOrPostCallbackRunAction = RunAction;
+
+ /// <summary>Runs an Action delegate provided as state.</summary>
+ /// <param name="state">The Action delegate to invoke.</param>
+ private static void RunAction(object state) { ((Action)state)(); }
+
+ /// <summary>Ends the await operation.</summary>
+ public void GetResult() {} // Nop. It exists purely because the compiler pattern demands it.
+ }
+ }
+}
diff --git a/src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs b/src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs
new file mode 100644
index 0000000000..8ee50da290
--- /dev/null
+++ b/src/mscorlib/src/System/Runtime/CompilerServices/jithelpers.cs
@@ -0,0 +1,224 @@
+// 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.
+
+////////////////////////////////////////////////////////////////////////////////
+// JitHelpers
+// Low-level Jit Helpers
+////////////////////////////////////////////////////////////////////////////////
+
+using System;
+using System.Threading;
+using System.Runtime;
+using System.Runtime.Versioning;
+using System.Diagnostics.Contracts;
+using System.Runtime.InteropServices;
+using System.Security;
+
+namespace System.Runtime.CompilerServices {
+
+ // Wrapper for address of a string variable on stack
+ internal struct StringHandleOnStack
+ {
+ private IntPtr m_ptr;
+
+ internal StringHandleOnStack(IntPtr pString)
+ {
+ m_ptr = pString;
+ }
+ }
+
+ // Wrapper for address of a object variable on stack
+ internal struct ObjectHandleOnStack
+ {
+ private IntPtr m_ptr;
+
+ internal ObjectHandleOnStack(IntPtr pObject)
+ {
+ m_ptr = pObject;
+ }
+ }
+
+ // Wrapper for StackCrawlMark
+ internal struct StackCrawlMarkHandle
+ {
+ private IntPtr m_ptr;
+
+ internal StackCrawlMarkHandle(IntPtr stackMark)
+ {
+ m_ptr = stackMark;
+ }
+ }
+
+ // Helper class to assist with unsafe pinning of arbitrary objects. The typical usage pattern is:
+ // fixed (byte * pData = &JitHelpers.GetPinningHelper(value).m_data)
+ // {
+ // ... pData is what Object::GetData() returns in VM ...
+ // }
+ internal class PinningHelper
+ {
+ public byte m_data;
+ }
+
+ [FriendAccessAllowed]
+ internal static class JitHelpers
+ {
+ // The special dll name to be used for DllImport of QCalls
+ internal const string QCall = "QCall";
+
+ // Wraps object variable into a handle. Used to return managed strings from QCalls.
+ // s has to be a local variable on the stack.
+ [SecurityCritical]
+ static internal StringHandleOnStack GetStringHandleOnStack(ref string s)
+ {
+ return new StringHandleOnStack(UnsafeCastToStackPointer(ref s));
+ }
+
+ // Wraps object variable into a handle. Used to pass managed object references in and out of QCalls.
+ // o has to be a local variable on the stack.
+ [SecurityCritical]
+ static internal ObjectHandleOnStack GetObjectHandleOnStack<T>(ref T o) where T : class
+ {
+ return new ObjectHandleOnStack(UnsafeCastToStackPointer(ref o));
+ }
+
+ // Wraps StackCrawlMark into a handle. Used to pass StackCrawlMark to QCalls.
+ // stackMark has to be a local variable on the stack.
+ [SecurityCritical]
+ static internal StackCrawlMarkHandle GetStackCrawlMarkHandle(ref StackCrawlMark stackMark)
+ {
+ return new StackCrawlMarkHandle(UnsafeCastToStackPointer(ref stackMark));
+ }
+
+#if _DEBUG
+ [SecurityCritical]
+ [FriendAccessAllowed]
+ static internal T UnsafeCast<T>(Object o) where T : class
+ {
+ T ret = UnsafeCastInternal<T>(o);
+ Contract.Assert(ret == (o as T), "Invalid use of JitHelpers.UnsafeCast!");
+ return ret;
+ }
+
+ // The IL body of this method is not critical, but its body will be replaced with unsafe code, so
+ // this method is effectively critical
+ [SecurityCritical]
+ static private T UnsafeCastInternal<T>(Object o) where T : class
+ {
+ // The body of this function will be replaced by the EE with unsafe code that just returns o!!!
+ // See getILIntrinsicImplementation for how this happens.
+ throw new InvalidOperationException();
+ }
+
+ static internal int UnsafeEnumCast<T>(T val) where T : struct // Actually T must be 4 byte (or less) enum
+ {
+ Contract.Assert(typeof(T).IsEnum
+ && (Enum.GetUnderlyingType(typeof(T)) == typeof(int)
+ || Enum.GetUnderlyingType(typeof(T)) == typeof(uint)
+ || Enum.GetUnderlyingType(typeof(T)) == typeof(short)
+ || Enum.GetUnderlyingType(typeof(T)) == typeof(ushort)
+ || Enum.GetUnderlyingType(typeof(T)) == typeof(byte)
+ || Enum.GetUnderlyingType(typeof(T)) == typeof(sbyte)),
+ "Error, T must be an 4 byte (or less) enum JitHelpers.UnsafeEnumCast!");
+ return UnsafeEnumCastInternal<T>(val);
+ }
+
+ static private int UnsafeEnumCastInternal<T>(T val) where T : struct // Actually T must be 4 (or less) byte enum
+ {
+ // should be return (int) val; but C# does not allow, runtime does this magically
+ // See getILIntrinsicImplementation for how this happens.
+ throw new InvalidOperationException();
+ }
+
+ static internal long UnsafeEnumCastLong<T>(T val) where T : struct // Actually T must be 8 byte enum
+ {
+ Contract.Assert(typeof(T).IsEnum
+ && (Enum.GetUnderlyingType(typeof(T)) == typeof(long)
+ || Enum.GetUnderlyingType(typeof(T)) == typeof(ulong)),
+ "Error, T must be an 8 byte enum JitHelpers.UnsafeEnumCastLong!");
+ return UnsafeEnumCastLongInternal<T>(val);
+ }
+
+ static private long UnsafeEnumCastLongInternal<T>(T val) where T : struct // Actually T must be 8 byte enum
+ {
+ // should be return (int) val; but C# does not allow, runtime does this magically
+ // See getILIntrinsicImplementation for how this happens.
+ throw new InvalidOperationException();
+ }
+
+ // Internal method for getting a raw pointer for handles in JitHelpers.
+ // The reference has to point into a local stack variable in order so it can not be moved by the GC.
+ [SecurityCritical]
+ static internal IntPtr UnsafeCastToStackPointer<T>(ref T val)
+ {
+ IntPtr p = UnsafeCastToStackPointerInternal<T>(ref val);
+ Contract.Assert(IsAddressInStack(p), "Pointer not in the stack!");
+ return p;
+ }
+
+ [SecurityCritical]
+ static private IntPtr UnsafeCastToStackPointerInternal<T>(ref T val)
+ {
+ // The body of this function will be replaced by the EE with unsafe code that just returns val!!!
+ // See getILIntrinsicImplementation for how this happens.
+ throw new InvalidOperationException();
+ }
+#else // _DEBUG
+ // The IL body of this method is not critical, but its body will be replaced with unsafe code, so
+ // this method is effectively critical
+ [SecurityCritical]
+ [FriendAccessAllowed]
+ static internal T UnsafeCast<T>(Object o) where T : class
+ {
+ // The body of this function will be replaced by the EE with unsafe code that just returns o!!!
+ // See getILIntrinsicImplementation for how this happens.
+ throw new InvalidOperationException();
+ }
+
+ static internal int UnsafeEnumCast<T>(T val) where T : struct // Actually T must be 4 byte (or less) enum
+ {
+ // should be return (int) val; but C# does not allow, runtime does this magically
+ // See getILIntrinsicImplementation for how this happens.
+ throw new InvalidOperationException();
+ }
+
+ static internal long UnsafeEnumCastLong<T>(T val) where T : struct // Actually T must be 8 byte enum
+ {
+ // should be return (long) val; but C# does not allow, runtime does this magically
+ // See getILIntrinsicImplementation for how this happens.
+ throw new InvalidOperationException();
+ }
+
+ [SecurityCritical]
+ static internal IntPtr UnsafeCastToStackPointer<T>(ref T val)
+ {
+ // The body of this function will be replaced by the EE with unsafe code that just returns o!!!
+ // See getILIntrinsicImplementation for how this happens.
+ throw new InvalidOperationException();
+ }
+#endif // _DEBUG
+
+ // Set the given element in the array without any type or range checks
+ [SecurityCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ extern static internal void UnsafeSetArrayElement(Object[] target, int index, Object element);
+
+ // Used for unsafe pinning of arbitrary objects.
+ [System.Security.SecurityCritical] // auto-generated
+ static internal PinningHelper GetPinningHelper(Object o)
+ {
+ // This cast is really unsafe - call the private version that does not assert in debug
+#if _DEBUG
+ return UnsafeCastInternal<PinningHelper>(o);
+#else
+ return UnsafeCast<PinningHelper>(o);
+#endif
+ }
+
+#if _DEBUG
+ [SecurityCritical]
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ extern static bool IsAddressInStack(IntPtr ptr);
+#endif
+ }
+}