[coop] Change handles to be pointers (#3249)
authorAleksey Kliger (λgeek) <akliger@gmail.com>
Fri, 8 Jul 2016 14:36:04 +0000 (10:36 -0400)
committerGitHub <noreply@github.com>
Fri, 8 Jul 2016 14:36:04 +0000 (10:36 -0400)
Previously handles were pointer-sized structs.  Unfortunately not all
calling conventions treat pointer-sized structs as pointers, so if we
wanted to interact with handles from wrappers, we would have to do
something complicated.

With the new design, `TYPED_HANDLE_DECL(MonoFoo)` will expand to:
```c
    typedef struct {
        MonoFoo *__obj;
    } MonoFooHandlePayload;
    typedef MonoFooHandlePayload *MonoFooHandle;
```

mono/metadata/handle.c
mono/metadata/handle.h

index 4b4239eb66f7cfbd3b08ac9da26439b27bf64993..bf538fa6d285f2d5a58a4e46989081bdcbc146a1 100644 (file)
@@ -45,8 +45,7 @@ Combine: MonoDefaults, GENERATE_GET_CLASS_WITH_CACHE, TYPED_HANDLE_DECL and frie
        We could then generate neat type safe wrappers.
 */
 
-const MonoObject *null_cell = { NULL };
-const MonoObjectHandle mono_null_value_handle = { (MonoObject**)&null_cell };
+const MonoObjectHandle mono_null_value_handle = NULL;
 
 #define THIS_IS_AN_OK_NUMBER_OF_HANDLES 100
 
index 3d48c0648580442e50dde4272fa6b130f434f60c..b34036958110e02635f658282157dafad6848134 100644 (file)
@@ -180,22 +180,30 @@ Handle macros/functions
 
 #ifdef ENABLE_CHECKED_BUILD
 void mono_handle_verify (MonoRawHandle handle);
-#define HANDLE_INVARIANTS(H) mono_handle_verify((void*)(H).__obj)
+#define HANDLE_INVARIANTS(H) mono_handle_verify((void*)(H))
 #else
 #define HANDLE_INVARIANTS(H) (0)
 #endif
 
+#define TYPED_HANDLE_PAYLOAD_NAME(TYPE) TYPE ## HandlePayload
 #define TYPED_HANDLE_NAME(TYPE) TYPE ## Handle
-#define TYPED_HANDLE_DECL(TYPE) typedef struct { TYPE **__obj; } TYPED_HANDLE_NAME (TYPE) ;
+/*
+ * typedef struct {
+ *   MonoObject *__obj;
+ * } MonoObjectHandlePayload;
+ *
+ * typedef MonoObjectHandlePayload* MonoObjectHandle;
+ */
+#define TYPED_HANDLE_DECL(TYPE) typedef struct { TYPE *__obj; } TYPED_HANDLE_PAYLOAD_NAME (TYPE) ; typedef TYPED_HANDLE_PAYLOAD_NAME (TYPE) * TYPED_HANDLE_NAME (TYPE);
 
-#define MONO_HANDLE_INIT { (void*)mono_null_value_handle.__obj }
+#define MONO_HANDLE_INIT ((void*) mono_null_value_handle)
 #define NULL_HANDLE mono_null_value_handle
 
 //XXX add functions to get/set raw, set field, set field to null, set array, set array to null
-#define MONO_HANDLE_RAW(HANDLE) (HANDLE_INVARIANTS (HANDLE), (*(HANDLE).__obj))
-#define MONO_HANDLE_DCL(TYPE, NAME) TYPED_HANDLE_NAME(TYPE) NAME = { mono_handle_new ((MonoObject*)(NAME ## _raw)) }
-#define MONO_HANDLE_NEW(TYPE, VALUE) (TYPED_HANDLE_NAME(TYPE)){ mono_handle_new ((MonoObject*)(VALUE)) }
-#define MONO_HANDLE_CAST(TYPE, VALUE) (TYPED_HANDLE_NAME(TYPE)){ (TYPE**)((VALUE).__obj) }
+#define MONO_HANDLE_RAW(HANDLE) (HANDLE_INVARIANTS (HANDLE), ((HANDLE)->__obj))
+#define MONO_HANDLE_DCL(TYPE, NAME) TYPED_HANDLE_NAME(TYPE) NAME = (TYPED_HANDLE_NAME(TYPE))(mono_handle_new ((MonoObject*)(NAME ## _raw)))
+#define MONO_HANDLE_NEW(TYPE, VALUE) (TYPED_HANDLE_NAME(TYPE))( mono_handle_new ((MonoObject*)(VALUE)) )
+#define MONO_HANDLE_CAST(TYPE, VALUE) (TYPED_HANDLE_NAME(TYPE))( VALUE )
 
 /*
 WARNING WARNING WARNING