[coop handles] Macros to access a handle via a MonoClassField
authorAleksey Kliger <aleksey@xamarin.com>
Wed, 31 May 2017 20:02:53 +0000 (16:02 -0400)
committerAleksey Kliger <aleksey@xamarin.com>
Mon, 5 Jun 2017 19:01:46 +0000 (15:01 -0400)
mono/metadata/handle.h

index 398f7d57cbab7771d4d278d00bf099d67728e8ce..d453cbd592d405a0ae22a41c57dae698d11ab597 100644 (file)
@@ -409,6 +409,19 @@ This is why we evaluate index and value before any call to MONO_HANDLE_RAW or ot
 
 #define MONO_HANDLE_DOMAIN(HANDLE) (mono_object_domain (MONO_HANDLE_RAW (MONO_HANDLE_CAST (MonoObject, HANDLE))))
 
+/* Given an object and a MonoClassField, return the value (must be non-object)
+ * of the field.  It's the caller's responsibility to check that the object is
+ * of the correct class. */
+#define MONO_HANDLE_GET_FIELD_VAL(HANDLE,TYPE,FIELD) *(TYPE *)(mono_handle_unsafe_field_addr (MONO_HANDLE_CAST (MonoObject, (HANDLE)), (FIELD)))
+
+#define MONO_HANDLE_NEW_GET_FIELD(HANDLE,TYPE,FIELD) MONO_HANDLE_NEW (TYPE, *(TYPE**)(mono_handle_unsafe_field_addr (MONO_HANDLE_CAST (MonoObject, (HANDLE)), (FIELD))))
+
+#define MONO_HANDLE_SET_FIELD_VAL(HANDLE,TYPE,FIELD,VAL) do {          \
+               MonoObjectHandle __obj = (HANDLE);                      \
+               MonoClassField *__field = (FIELD);                      \
+               TYPE __value = (VAL);                                   \
+               *(TYPE*)(mono_handle_unsafe_field_addr (__obj, __field)) = __value; \
+       } while (0)
 
 /* Baked typed handles we all want */
 TYPED_HANDLE_DECL (MonoString);
@@ -431,6 +444,13 @@ mono_handle_assign (MonoObjectHandleOut dest, MonoObjectHandle src)
        mono_gc_wbarrier_generic_store (&dest->__raw, src ? MONO_HANDLE_RAW(src) : NULL);
 }
 
+/* It is unsafe to call this function directly - it does not pin the handle!  Use MONO_HANDLE_GET_FIELD_VAL(). */
+static inline gchar*
+mono_handle_unsafe_field_addr (MonoObjectHandle h, MonoClassField *field)
+{
+       return ((gchar *)MONO_HANDLE_RAW (h)) + field->offset;
+}
+
 //FIXME this should go somewhere else
 MonoStringHandle mono_string_new_handle (MonoDomain *domain, const char *data, MonoError *error);
 MonoArrayHandle mono_array_new_handle (MonoDomain *domain, MonoClass *eclass, uintptr_t n, MonoError *error);