Merge pull request #1898 from alexanderkyte/debugger_variable_reflection
[mono.git] / mcs / class / corlib / System.Runtime.CompilerServices / RuntimeHelpers.cs
index aba41780aa536da566c498c79c047d49d606abfb..0e182e3143c27066feadf8ce0e9434d71eabe8f8 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_2_0
+using System.Runtime.Versioning;
 using System.Runtime.ConstrainedExecution;
-#endif
+using System.Reflection;
 
 namespace System.Runtime.CompilerServices
 {
-#if NET_2_0
        public static class RuntimeHelpers
-#else
-       [Serializable]
-       public sealed class RuntimeHelpers
-#endif
        {
-#if NET_2_0
                public delegate void TryCode (Object userData);
 
                public delegate void CleanupCode (Object userData, bool exceptionThrown);
-#endif
-
-#if !NET_2_0
-               private RuntimeHelpers () {}
-#endif
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                static extern void InitializeArray (Array array, IntPtr fldHandle);
 
                public static void InitializeArray (Array array, RuntimeFieldHandle fldHandle)
                {
+                       if ((array == null) || (fldHandle.Value == IntPtr.Zero))
+                               throw new ArgumentNullException ();
+
                        InitializeArray (array, fldHandle.Value);
                }
 
@@ -64,7 +56,6 @@ namespace System.Runtime.CompilerServices
                        get;
                }
 
-#if NET_1_1
                public static int GetHashCode (object o) {
                        return Object.InternalGetHashCode (o);
                }
@@ -83,7 +74,6 @@ namespace System.Runtime.CompilerServices
                        else
                                return Object.Equals (o1, o2);
                }
-#endif
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public static extern object GetObjectValue (object obj);
@@ -93,54 +83,101 @@ namespace System.Runtime.CompilerServices
 
                public static void RunClassConstructor (RuntimeTypeHandle type)
                {
+                       if (type.Value == IntPtr.Zero)
+                               throw new ArgumentException ("Handle is not initialized.", "type");
+
                        RunClassConstructor (type.Value);
                }
 
-#if NET_2_0
-               [MonoTODO]
-               public static void ExecuteCodeWithGuaranteedCleanup (TryCode code, CleanupCode backoutCode, Object userData) {
-                       throw new NotImplementedException ();
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               static extern bool SufficientExecutionStack ();
+
+               [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
+               public static void EnsureSufficientExecutionStack ()
+               {
+                       if (SufficientExecutionStack ())
+                               return;
+                       throw new InsufficientExecutionStackException ();
+               }
+
+               [MonoTODO("Currently a no-op")]
+               public static void ExecuteCodeWithGuaranteedCleanup (TryCode code, CleanupCode backoutCode, Object userData)
+               {
                }
 
-               [MonoTODO]
+               [MonoTODO("Currently a no-op")]
                [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
-               public static void PrepareConstrainedRegions () {
-                       throw new NotImplementedException ();
+               public static void PrepareConstrainedRegions ()
+               {
                }
 
-               [MonoTODO]
+               [MonoTODO("Currently a no-op")]
                [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
-               public static void PrepareConstrainedRegionsNoOP () {
-                       throw new NotImplementedException ();
+               public static void PrepareConstrainedRegionsNoOP ()
+               {
                }
 
-               [MonoTODO]
+               [MonoTODO("Currently a no-op")]
                [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
-               public static void ProbeForSufficientStack() {
-                       throw new NotImplementedException ();
+               public static void ProbeForSufficientStack()
+               {
                }
 
-               [MonoTODO]
-               public static void PrepareDelegate (Delegate d) {
+               // 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
+               [MonoTODO("Currently a no-op")]
+               public static void PrepareDelegate (Delegate d)
+               {
                        if (d == null)
                                throw new ArgumentNullException ("d");
-                       throw new NotImplementedException ();
                }
 
-               [MonoTODO]
-               public static void PrepareMethod (RuntimeMethodHandle method) {
-                       throw new NotImplementedException ();
+               // extracted from ../../../../external/referencesource/mscorlib/system/runtime/compilerservices/runtimehelpers.cs
+               //
+               // 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
+               [ResourceExposure(ResourceScope.None)]
+               [MonoTODO("Currently a no-op")]
+               public static void PrepareContractedDelegate(Delegate d)
+               {
+               }
+
+               [MonoTODO("Currently a no-op")]
+               public static void PrepareMethod (RuntimeMethodHandle method)
+               {
                }
 
-               [MonoTODO]
-               public static void PrepareMethod (RuntimeMethodHandle method, RuntimeTypeHandle[] instantiation) {
-                       throw new NotImplementedException ();
+               [MonoTODO("Currently a no-op")]
+               public static void PrepareMethod (RuntimeMethodHandle method, RuntimeTypeHandle[] instantiation)
+               {
                }
 
-               [MonoTODO]
-               public static void RunModuleConstructor (ModuleHandle module) {
-                       throw new NotImplementedException ();
+               public static void RunModuleConstructor (ModuleHandle module)
+               {
+                       if (module == ModuleHandle.EmptyHandle)
+                               throw new ArgumentException ("Handle is not initialized.", "module");
+
+                       RunModuleConstructor (module.Value);
                }
-#endif
+
+               [MethodImplAttribute (MethodImplOptions.InternalCall)]
+               static extern void RunModuleConstructor (IntPtr module);
        }
 }