2 * handle.h: Handle to object in native code
5 * - Ludovic Henry <ludovic@xamarin.com>
7 * Copyright 2015 Xamarin, Inc. (www.xamarin.com)
10 #ifndef __MONO_HANDLE_H__
11 #define __MONO_HANDLE_H__
16 #include <mono/metadata/object.h>
17 #include <mono/metadata/class.h>
18 #include <mono/utils/mono-error.h>
19 #include <mono/utils/checked-build.h>
24 * DO NOT ACCESS DIRECTLY
25 * USE mono_handle_obj BELOW TO ACCESS OBJ
27 * The field obj is not private as there is no way to do that
28 * in C, but using a C++ template would simplify that a lot
31 MonoObject *__private_obj;
34 typedef MonoHandleStorage* MonoHandle;
36 typedef struct _MonoHandleArena MonoHandleArena;
39 mono_handle_arena_size (void);
42 mono_handle_arena_new (MonoHandleArena *arena, MonoObject *obj);
45 mono_handle_arena_elevate (MonoHandleArena *arena, MonoHandle handle);
48 mono_handle_arena_stack_push (MonoHandleArena **arena_stack, MonoHandleArena *arena);
51 mono_handle_arena_stack_pop (MonoHandleArena **arena_stack, MonoHandleArena *arena);
54 mono_handle_arena_init (MonoHandleArena **arena_stack);
57 mono_handle_arena_cleanup (MonoHandleArena **arena_stack);
60 mono_handle_arena_current (void);
63 mono_handle_arena_current_addr (void);
65 #define MONO_HANDLE_ARENA_PUSH() \
67 MonoHandleArena **__arena_stack = mono_handle_arena_current_addr (); \
68 MonoHandleArena *__arena = (MonoHandleArena*) g_alloca (mono_handle_arena_size ()); \
69 mono_handle_arena_stack_push (__arena_stack, __arena)
71 #define MONO_HANDLE_ARENA_POP() \
72 mono_handle_arena_stack_pop (__arena_stack, __arena); \
75 #define MONO_HANDLE_ARENA_POP_RETURN_UNSAFE(handle,ret) \
76 (ret) = (handle)->__private_obj; \
77 mono_handle_arena_stack_pop (__arena_stack, __arena); \
80 #define MONO_HANDLE_ARENA_POP_RETURN(handle,ret_handle) \
81 *((MonoHandle**)(&(ret_handle))) = mono_handle_elevate ((MonoHandle*)(handle)); \
82 mono_handle_arena_stack_pop(__arena_stack, __arena); \
85 static inline MonoHandle
86 mono_handle_new (MonoObject *obj)
88 return mono_handle_arena_new (mono_handle_arena_current (), obj);
91 static inline MonoHandle
92 mono_handle_elevate (MonoHandle handle)
94 return mono_handle_arena_elevate (mono_handle_arena_current (), handle);
97 #ifndef ENABLE_CHECKED_BUILD
99 #define mono_handle_obj(handle) ((handle)->__private_obj)
101 #define mono_handle_assign(handle,rawptr) do { (handle)->__private_obj = (rawptr); } while(0)
106 mono_handle_check_in_critical_section ()
108 MONO_REQ_GC_CRITICAL;
111 #define mono_handle_obj(handle) (mono_handle_check_in_critical_section (), (handle)->__private_obj)
113 #define mono_handle_assign(handle,rawptr) do { mono_handle_check_in_critical_section (); (handle)->__private_obj = (rawptr); } while (0)
117 static inline MonoClass*
118 mono_handle_class (MonoHandle handle)
120 return mono_object_get_class (handle->__private_obj);
123 static inline MonoDomain*
124 mono_handle_domain (MonoHandle handle)
126 return mono_object_get_domain (handle->__private_obj);
129 #define mono_handle_obj_is_null(handle) ((handle)->__private_obj == NULL)
131 #define MONO_HANDLE_TYPE_DECL(type) typedef struct { type *__private_obj; } type ## HandleStorage ; \
132 typedef type ## HandleStorage * type ## Handle
133 #define MONO_HANDLE_TYPE(type) type ## Handle
134 #define MONO_HANDLE_NEW(type,obj) ((type ## Handle) mono_handle_new ((MonoObject*) (obj)))
135 #define MONO_HANDLE_ELEVATE(type,handle) ((type ## Handle) mono_handle_elevate ((MonoObject*) (handle)->__private_obj))
137 #define MONO_HANDLE_ASSIGN(handle,rawptr) \
139 mono_handle_assign ((handle), (rawptr)); \
142 #define MONO_HANDLE_SETREF(handle,fieldname,value) \
144 MonoHandle __value = (MonoHandle) (value); \
145 MONO_PREPARE_GC_CRITICAL_REGION; \
146 MONO_OBJECT_SETREF (mono_handle_obj ((handle)), fieldname, mono_handle_obj (__value)); \
147 MONO_FINISH_GC_CRITICAL_REGION; \
150 #define MONO_HANDLE_SETREF_NULL(handle,fieldname) \
152 MONO_PREPARE_GC_CRITICAL_REGION; \
153 MONO_OBJECT_SETREF (mono_handle_obj ((handle)), fieldname, NULL); \
154 MONO_FINISH_GC_CRITICAL_REGION; \
158 #define MONO_HANDLE_SET(handle,fieldname,value) \
160 MONO_PREPARE_GC_CRITICAL_REGION; \
161 mono_handle_obj ((handle))->fieldname = (value); \
162 MONO_FINISH_GC_CRITICAL_REGION; \
165 #define MONO_HANDLE_ARRAY_SETREF(handle,index,value) \
167 MonoHandle __value = (MonoHandle) (value); \
168 MONO_PREPARE_GC_CRITICAL_REGION; \
169 mono_array_setref (mono_handle_obj ((handle)), (index), mono_handle_obj (__value)); \
170 MONO_FINISH_GC_CRITICAL_REGION; \
173 #define MONO_HANDLE_ARRAY_SETREF_NULL(handle,index) \
175 MONO_PREPARE_GC_CRITICAL_REGION; \
176 mono_array_setref (mono_handle_obj ((handle)), (index), NULL); \
177 MONO_FINISH_GC_CRITICAL_REGION; \
181 #define MONO_HANDLE_ARRAY_SET(handle,type,index,value) \
183 MONO_PREPARE_GC_CRITICAL_REGION; \
184 mono_array_set (mono_handle_obj ((handle)), type, (index), (value)); \
185 MONO_FINISH_GC_CRITICAL_REGION; \
191 /* Some common handle types */
193 MONO_HANDLE_TYPE_DECL (MonoArray);
194 MONO_HANDLE_TYPE_DECL (MonoString);
198 #endif /* __MONO_HANDLE_H__ */