[corlib] Default FieldInfo Get|SetValueDirect should throw NotSupportedException
authorMarek Safar <marek.safar@gmail.com>
Thu, 19 Mar 2015 11:42:43 +0000 (12:42 +0100)
committerMarek Safar <marek.safar@gmail.com>
Thu, 19 Mar 2015 11:42:43 +0000 (12:42 +0100)
mcs/class/corlib/System.Reflection/FieldInfo.cs
mcs/class/corlib/System.Reflection/MonoField.cs
mcs/class/corlib/System/IntPtr.cs
mcs/class/corlib/System/RuntimeFieldHandle.cs
mcs/class/corlib/System/TypedReference.cs

index 9621fac3f77074a5a9a91136c50fc734de070df9..47021a3ffef65488a8f8281550a145b9d9186b2e 100644 (file)
@@ -179,17 +179,15 @@ namespace System.Reflection {
                }
 
                [CLSCompliant(false)]
-               [MonoTODO("Not implemented")]
                public virtual object GetValueDirect (TypedReference obj)
                {
-                       throw new NotImplementedException ();
+                       throw new NotSupportedException(Environment.GetResourceString("NotSupported_AbstractNonCLS"));
                }
 
                [CLSCompliant(false)]
-               [MonoTODO("Not implemented")]
                public virtual void SetValueDirect (TypedReference obj, object value)
                {
-                       throw new NotImplementedException ();
+                       throw new NotSupportedException(Environment.GetResourceString("NotSupported_AbstractNonCLS"));
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
index 1afdd03b0646c6412fcd8dca4589d7fd12bbd0ee..2674192f7cc49fa27ea0dc01f1692cb2e08f6404 100644 (file)
@@ -39,6 +39,7 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 using System.Runtime.Serialization;
 using System.Diagnostics;
+using System.Diagnostics.Contracts;
 
 namespace System.Reflection {
 
@@ -89,6 +90,36 @@ namespace System.Reflection {
                        bool domainInitialized = false;
                        RuntimeFieldHandle.SetValue (this, obj, value, null, Attributes, null, ref domainInitialized);
                }
+
+        [DebuggerStepThroughAttribute]
+        [Diagnostics.DebuggerHidden]
+        public override void SetValueDirect(TypedReference obj, Object value)
+        {
+            if (obj.IsNull)
+                throw new ArgumentException(Environment.GetResourceString("Arg_TypedReference_Null"));
+            Contract.EndContractBlock();
+
+            unsafe
+            {
+                // Passing TypedReference by reference is easier to make correct in native code
+                RuntimeFieldHandle.SetValueDirect(this, (RuntimeType)FieldType, &obj, value, (RuntimeType)DeclaringType);
+            }
+        }
+
+        [DebuggerStepThroughAttribute]
+        [Diagnostics.DebuggerHidden]
+        public override Object GetValueDirect(TypedReference obj)
+        {
+            if (obj.IsNull)
+                throw new ArgumentException(Environment.GetResourceString("Arg_TypedReference_Null"));
+            Contract.EndContractBlock();
+
+            unsafe
+            {
+                // Passing TypedReference by reference is easier to make correct in native code
+                return RuntimeFieldHandle.GetValueDirect(this, (RuntimeType)FieldType, &obj, (RuntimeType)DeclaringType);
+            }
+        }
        }
 
        [Serializable]
index e594d49bbb90907f87642d9eaefbc53af8327b71..c449de83997a3b308b1df8fbe881eb053f166dc3 100644 (file)
@@ -45,6 +45,7 @@
 using System.Globalization;
 using System.Runtime.Serialization;
 using System.Runtime.ConstrainedExecution;
+using System.Diagnostics.Contracts;
 
 namespace System
 {
@@ -223,5 +224,13 @@ namespace System
                {
                        return (IntPtr) (unchecked (((byte *) pointer) - offset));
                }
+
+               // fast way to compare IntPtr to (IntPtr)0 while IntPtr.Zero doesn't work due to slow statics access
+               [Pure]
+               [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+               internal unsafe bool IsNull()
+               {
+                       return m_value == null;
+               }
        }
 }
index c6cd9f006f360935e5d96b40d2ef0d2f63425f16..8901fa36a414a8f77dd9e1444645b5da01a512ef 100644 (file)
@@ -115,5 +115,15 @@ namespace System
                {
                        SetValueInternal (field, obj, value);
                }
+
+               unsafe internal static Object GetValueDirect (RtFieldInfo field, RuntimeType fieldType, void *pTypedRef, RuntimeType contextType)
+               {
+                       throw new NotImplementedException ("GetValueDirect");
+               }
+
+               unsafe internal static void SetValueDirect (RtFieldInfo field, RuntimeType fieldType, void* pTypedRef, Object value, RuntimeType contextType)
+               {
+                       throw new NotImplementedException ("SetValueDirect");
+               }
        }
 }
index bbdb2c41510c5a00144d5310ac26116303b31db3..fe529f9dd7e9832f9016c88d75d4109bdcef146f 100644 (file)
@@ -96,6 +96,12 @@ namespace System
                        return value.type;
                }
 
+               internal bool IsNull {
+                       get {
+                               return value.IsNull () && klass.IsNull ();
+                       }
+               }
+
                [MethodImpl (MethodImplOptions.InternalCall)]
                public extern static object ToObject (TypedReference value);