2 * handle.h: Handle to object in native code
5 * - Ludovic Henry <ludovic@xamarin.com>
7 * Copyright 2015 Xamarin, Inc. (www.xamarin.com)
8 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
11 #ifndef __MONO_HANDLE_H__
12 #define __MONO_HANDLE_H__
17 #include <mono/metadata/object.h>
18 #include <mono/metadata/class.h>
19 #include <mono/utils/mono-error.h>
20 #include <mono/utils/checked-build.h>
25 * DO NOT ACCESS DIRECTLY
26 * USE mono_handle_obj BELOW TO ACCESS OBJ
28 * The field obj is not private as there is no way to do that
29 * in C, but using a C++ template would simplify that a lot
32 MonoObject *__private_obj;
35 typedef MonoHandleStorage* MonoHandle;
37 typedef struct _MonoHandleArena MonoHandleArena;
40 mono_handle_arena_size (void);
43 mono_handle_arena_new (MonoHandleArena *arena, MonoObject *obj);
46 mono_handle_arena_elevate (MonoHandleArena *arena, MonoHandle handle);
49 mono_handle_arena_stack_push (MonoHandleArena **arena_stack, MonoHandleArena *arena);
52 mono_handle_arena_stack_pop (MonoHandleArena **arena_stack, MonoHandleArena *arena);
55 mono_handle_arena_init (MonoHandleArena **arena_stack);
58 mono_handle_arena_cleanup (MonoHandleArena **arena_stack);
61 mono_handle_arena_current (void);
64 mono_handle_arena_current_addr (void);
66 #define MONO_HANDLE_ARENA_PUSH() \
68 MonoHandleArena **__arena_stack = mono_handle_arena_current_addr (); \
69 MonoHandleArena *__arena = (MonoHandleArena*) g_alloca (mono_handle_arena_size ()); \
70 mono_handle_arena_stack_push (__arena_stack, __arena)
72 #define MONO_HANDLE_ARENA_POP() \
73 mono_handle_arena_stack_pop (__arena_stack, __arena); \
76 #define MONO_HANDLE_ARENA_POP_RETURN_UNSAFE(handle,ret) \
77 (ret) = (handle)->__private_obj; \
78 mono_handle_arena_stack_pop (__arena_stack, __arena); \
81 #define MONO_HANDLE_ARENA_POP_RETURN(handle,ret_handle) \
82 *((MonoHandle**)(&(ret_handle))) = mono_handle_elevate ((MonoHandle*)(handle)); \
83 mono_handle_arena_stack_pop(__arena_stack, __arena); \
86 static inline MonoHandle
87 mono_handle_new (MonoObject *obj)
89 return mono_handle_arena_new (mono_handle_arena_current (), obj);
92 static inline MonoHandle
93 mono_handle_elevate (MonoHandle handle)
95 return mono_handle_arena_elevate (mono_handle_arena_current (), handle);
98 #ifndef ENABLE_CHECKED_BUILD
100 #define mono_handle_obj(handle) ((handle)->__private_obj)
102 #define mono_handle_assign(handle,rawptr) do { (handle)->__private_obj = (rawptr); } while(0)
107 mono_handle_check_in_critical_section ()
109 MONO_REQ_GC_CRITICAL;
112 #define mono_handle_obj(handle) (mono_handle_check_in_critical_section (), (handle)->__private_obj)
114 #define mono_handle_assign(handle,rawptr) do { mono_handle_check_in_critical_section (); (handle)->__private_obj = (rawptr); } while (0)
118 static inline MonoClass*
119 mono_handle_class (MonoHandle handle)
121 return mono_object_get_class (handle->__private_obj);
124 static inline MonoDomain*
125 mono_handle_domain (MonoHandle handle)
127 return mono_object_get_domain (handle->__private_obj);
130 #define mono_handle_obj_is_null(handle) ((handle)->__private_obj == NULL)
132 #define MONO_HANDLE_TYPE_DECL(type) typedef struct { type *__private_obj; } type ## HandleStorage ; \
133 typedef type ## HandleStorage * type ## Handle
134 #define MONO_HANDLE_TYPE(type) type ## Handle
135 #define MONO_HANDLE_NEW(type,obj) ((type ## Handle) mono_handle_new ((MonoObject*) (obj)))
136 #define MONO_HANDLE_ELEVATE(type,handle) ((type ## Handle) mono_handle_elevate ((MonoObject*) (handle)->__private_obj))
138 #define MONO_HANDLE_ASSIGN(handle,rawptr) \
140 mono_handle_assign ((handle), (rawptr)); \
143 #define MONO_HANDLE_SETREF(handle,fieldname,value) \
145 MonoHandle __value = (MonoHandle) (value); \
146 MONO_PREPARE_GC_CRITICAL_REGION; \
147 MONO_OBJECT_SETREF (mono_handle_obj ((handle)), fieldname, mono_handle_obj (__value)); \
148 MONO_FINISH_GC_CRITICAL_REGION; \
151 #define MONO_HANDLE_SETREF_NULL(handle,fieldname) \
153 MONO_PREPARE_GC_CRITICAL_REGION; \
154 MONO_OBJECT_SETREF (mono_handle_obj ((handle)), fieldname, NULL); \
155 MONO_FINISH_GC_CRITICAL_REGION; \
159 #define MONO_HANDLE_SET(handle,fieldname,value) \
161 MONO_PREPARE_GC_CRITICAL_REGION; \
162 mono_handle_obj ((handle))->fieldname = (value); \
163 MONO_FINISH_GC_CRITICAL_REGION; \
166 #define MONO_HANDLE_ARRAY_SETREF(handle,index,value) \
168 MonoHandle __value = (MonoHandle) (value); \
169 MONO_PREPARE_GC_CRITICAL_REGION; \
170 mono_array_setref (mono_handle_obj ((handle)), (index), mono_handle_obj (__value)); \
171 MONO_FINISH_GC_CRITICAL_REGION; \
174 #define MONO_HANDLE_ARRAY_SETREF_NULL(handle,index) \
176 MONO_PREPARE_GC_CRITICAL_REGION; \
177 mono_array_setref (mono_handle_obj ((handle)), (index), NULL); \
178 MONO_FINISH_GC_CRITICAL_REGION; \
182 #define MONO_HANDLE_ARRAY_SET(handle,type,index,value) \
184 MONO_PREPARE_GC_CRITICAL_REGION; \
185 mono_array_set (mono_handle_obj ((handle)), type, (index), (value)); \
186 MONO_FINISH_GC_CRITICAL_REGION; \
192 /* Some common handle types */
194 MONO_HANDLE_TYPE_DECL (MonoArray);
195 MONO_HANDLE_TYPE_DECL (MonoString);
199 #endif /* __MONO_HANDLE_H__ */