* - Ludovic Henry <ludovic@xamarin.com>
*
* Copyright 2015 Xamarin, Inc. (www.xamarin.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#ifndef __MONO_HANDLE_H__
#include <config.h>
#include <glib.h>
-#include "object.h"
-#include "class.h"
-#include "class-internals.h"
-#include "threads-types.h"
-
-#include "mono/utils/mono-threads-coop.h"
+#include <mono/metadata/object.h>
+#include <mono/metadata/class.h>
+#include <mono/utils/mono-error.h>
+#include <mono/utils/checked-build.h>
G_BEGIN_DECLS
-typedef struct _MonoHandleStorage MonoHandleStorage;
-typedef MonoHandleStorage* MonoHandle;
-
/*
* DO NOT ACCESS DIRECTLY
* USE mono_handle_obj BELOW TO ACCESS OBJ
* The field obj is not private as there is no way to do that
* in C, but using a C++ template would simplify that a lot
*/
-struct _MonoHandleStorage {
- MonoObject *obj;
-};
+typedef struct {
+ MonoObject *__private_obj;
+} MonoHandleStorage;
+
+typedef MonoHandleStorage* MonoHandle;
+
+typedef struct _MonoHandleArena MonoHandleArena;
+
+gsize
+mono_handle_arena_size (void);
+
+MonoHandle
+mono_handle_arena_new (MonoHandleArena *arena, MonoObject *obj);
+
+MonoHandle
+mono_handle_arena_elevate (MonoHandleArena *arena, MonoHandle handle);
+
+void
+mono_handle_arena_stack_push (MonoHandleArena **arena_stack, MonoHandleArena *arena);
+
+void
+mono_handle_arena_stack_pop (MonoHandleArena **arena_stack, MonoHandleArena *arena);
+
+void
+mono_handle_arena_init (MonoHandleArena **arena_stack);
+
+void
+mono_handle_arena_cleanup (MonoHandleArena **arena_stack);
+
+MonoHandleArena*
+mono_handle_arena_current (void);
-#ifndef CHECKED_BUILD
+MonoHandleArena**
+mono_handle_arena_current_addr (void);
-#define mono_handle_obj(handle) ((handle)->obj)
+#define MONO_HANDLE_ARENA_PUSH() \
+ do { \
+ MonoHandleArena **__arena_stack = mono_handle_arena_current_addr (); \
+ MonoHandleArena *__arena = (MonoHandleArena*) g_alloca (mono_handle_arena_size ()); \
+ mono_handle_arena_stack_push (__arena_stack, __arena)
+
+#define MONO_HANDLE_ARENA_POP() \
+ mono_handle_arena_stack_pop (__arena_stack, __arena); \
+ } while (0)
-#define mono_handle_assign(handle,rawptr) do { (handle)->obj = (rawptr); } while(0)
+#define MONO_HANDLE_ARENA_POP_RETURN_UNSAFE(handle,ret) \
+ (ret) = (handle)->__private_obj; \
+ mono_handle_arena_stack_pop (__arena_stack, __arena); \
+ } while (0)
+
+#define MONO_HANDLE_ARENA_POP_RETURN(handle,ret_handle) \
+ *((MonoHandle**)(&(ret_handle))) = mono_handle_elevate ((MonoHandle*)(handle)); \
+ mono_handle_arena_stack_pop(__arena_stack, __arena); \
+ } while (0)
+
+static inline MonoHandle
+mono_handle_new (MonoObject *obj)
+{
+ return mono_handle_arena_new (mono_handle_arena_current (), obj);
+}
+
+static inline MonoHandle
+mono_handle_elevate (MonoHandle handle)
+{
+ return mono_handle_arena_elevate (mono_handle_arena_current (), handle);
+}
+
+#ifndef ENABLE_CHECKED_BUILD
+
+#define mono_handle_obj(handle) ((handle)->__private_obj)
+
+#define mono_handle_assign(handle,rawptr) do { (handle)->__private_obj = (rawptr); } while(0)
#else
static inline void
mono_handle_check_in_critical_section ()
{
- MONO_REQ_GC_UNSAFE_MODE;
+ MONO_REQ_GC_CRITICAL;
}
-#define mono_handle_obj(handle) (mono_handle_check_in_critical_section (), (handle)->obj)
+#define mono_handle_obj(handle) (mono_handle_check_in_critical_section (), (handle)->__private_obj)
-#define mono_handle_assign(handle,rawptr) do { mono_handle_check_in_critical_section (); (handle)->obj = (rawptr); } while (0)
+#define mono_handle_assign(handle,rawptr) do { mono_handle_check_in_critical_section (); (handle)->__private_obj = (rawptr); } while (0)
#endif
static inline MonoClass*
mono_handle_class (MonoHandle handle)
{
- return handle->obj->vtable->klass;
+ return mono_object_get_class (handle->__private_obj);
}
static inline MonoDomain*
mono_handle_domain (MonoHandle handle)
{
- return handle->obj->vtable->domain;
+ return mono_object_get_domain (handle->__private_obj);
}
-#define MONO_HANDLE_TYPE_DECL(type) typedef struct { type *obj; } type ## HandleStorage ; \
+#define mono_handle_obj_is_null(handle) ((handle)->__private_obj == NULL)
+
+#define MONO_HANDLE_TYPE_DECL(type) typedef struct { type *__private_obj; } type ## HandleStorage ; \
typedef type ## HandleStorage * type ## Handle
#define MONO_HANDLE_TYPE(type) type ## Handle
#define MONO_HANDLE_NEW(type,obj) ((type ## Handle) mono_handle_new ((MonoObject*) (obj)))
-#define MONO_HANDLE_ELEVATE(type,handle) ((type ## Handle) mono_handle_elevate ((MonoObject*) (handle)->obj))
+#define MONO_HANDLE_ELEVATE(type,handle) ((type ## Handle) mono_handle_elevate ((MonoObject*) (handle)->__private_obj))
#define MONO_HANDLE_ASSIGN(handle,rawptr) \
do { \
MONO_FINISH_GC_CRITICAL_REGION; \
} while (0)
+#define MONO_HANDLE_SETREF_NULL(handle,fieldname) \
+ do { \
+ MONO_PREPARE_GC_CRITICAL_REGION; \
+ MONO_OBJECT_SETREF (mono_handle_obj ((handle)), fieldname, NULL); \
+ MONO_FINISH_GC_CRITICAL_REGION; \
+ } while (0)
+
+
#define MONO_HANDLE_SET(handle,fieldname,value) \
do { \
MONO_PREPARE_GC_CRITICAL_REGION; \
MONO_FINISH_GC_CRITICAL_REGION; \
} while (0)
+#define MONO_HANDLE_ARRAY_SETREF_NULL(handle,index) \
+ do { \
+ MONO_PREPARE_GC_CRITICAL_REGION; \
+ mono_array_setref (mono_handle_obj ((handle)), (index), NULL); \
+ MONO_FINISH_GC_CRITICAL_REGION; \
+ } while (0)
+
+
#define MONO_HANDLE_ARRAY_SET(handle,type,index,value) \
do { \
MONO_PREPARE_GC_CRITICAL_REGION; \
- mono_array_set (mono_handle_obj ((handle)), (type), (index), (value)); \
+ mono_array_set (mono_handle_obj ((handle)), type, (index), (value)); \
MONO_FINISH_GC_CRITICAL_REGION; \
} while (0)
-/* handle arena specific functions */
-typedef struct _MonoHandleArena MonoHandleArena;
-gsize
-mono_handle_arena_size (gsize nb_handles);
-
-MonoHandle
-mono_handle_new (MonoObject *rawptr);
-
-MonoHandle
-mono_handle_elevate (MonoHandle handle);
/* Some common handle types */