First set of licensing changes
[mono.git] / mono / metadata / handle.h
1 /*
2  * handle.h: Handle to object in native code
3  *
4  * Authors:
5  *  - Ludovic Henry <ludovic@xamarin.com>
6  *
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.
9  */
10
11 #ifndef __MONO_HANDLE_H__
12 #define __MONO_HANDLE_H__
13
14 #include <config.h>
15 #include <glib.h>
16
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>
21
22 G_BEGIN_DECLS
23
24 /*
25  * DO NOT ACCESS DIRECTLY
26  * USE mono_handle_obj BELOW TO ACCESS OBJ
27  *
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
30  */
31 typedef struct {
32         MonoObject *__private_obj;
33 } MonoHandleStorage;
34
35 typedef MonoHandleStorage* MonoHandle;
36
37 typedef struct _MonoHandleArena MonoHandleArena;
38
39 gsize
40 mono_handle_arena_size (void);
41
42 MonoHandle
43 mono_handle_arena_new (MonoHandleArena *arena, MonoObject *obj);
44
45 MonoHandle
46 mono_handle_arena_elevate (MonoHandleArena *arena, MonoHandle handle);
47
48 void
49 mono_handle_arena_stack_push (MonoHandleArena **arena_stack, MonoHandleArena *arena);
50
51 void
52 mono_handle_arena_stack_pop (MonoHandleArena **arena_stack, MonoHandleArena *arena);
53
54 void
55 mono_handle_arena_init (MonoHandleArena **arena_stack);
56
57 void
58 mono_handle_arena_cleanup (MonoHandleArena **arena_stack);
59
60 MonoHandleArena*
61 mono_handle_arena_current (void);
62
63 MonoHandleArena**
64 mono_handle_arena_current_addr (void);
65
66 #define MONO_HANDLE_ARENA_PUSH()        \
67         do {    \
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)
71
72 #define MONO_HANDLE_ARENA_POP() \
73                 mono_handle_arena_stack_pop (__arena_stack, __arena);   \
74         } while (0)
75
76 #define MONO_HANDLE_ARENA_POP_RETURN_UNSAFE(handle,ret) \
77                 (ret) = (handle)->__private_obj;        \
78                 mono_handle_arena_stack_pop (__arena_stack, __arena);   \
79         } while (0)
80
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);    \
84         } while (0)
85
86 static inline MonoHandle
87 mono_handle_new (MonoObject *obj)
88 {
89         return mono_handle_arena_new (mono_handle_arena_current (), obj);
90 }
91
92 static inline MonoHandle
93 mono_handle_elevate (MonoHandle handle)
94 {
95         return mono_handle_arena_elevate (mono_handle_arena_current (), handle);
96 }
97
98 #ifndef ENABLE_CHECKED_BUILD
99
100 #define mono_handle_obj(handle) ((handle)->__private_obj)
101
102 #define mono_handle_assign(handle,rawptr) do { (handle)->__private_obj = (rawptr); } while(0)
103
104 #else
105
106 static inline void
107 mono_handle_check_in_critical_section ()
108 {
109         MONO_REQ_GC_CRITICAL;
110 }
111
112 #define mono_handle_obj(handle) (mono_handle_check_in_critical_section (), (handle)->__private_obj)
113
114 #define mono_handle_assign(handle,rawptr) do { mono_handle_check_in_critical_section (); (handle)->__private_obj = (rawptr); } while (0)
115
116 #endif
117
118 static inline MonoClass*
119 mono_handle_class (MonoHandle handle)
120 {
121         return mono_object_get_class (handle->__private_obj);
122 }
123
124 static inline MonoDomain*
125 mono_handle_domain (MonoHandle handle)
126 {
127         return mono_object_get_domain (handle->__private_obj);
128 }
129
130 #define mono_handle_obj_is_null(handle) ((handle)->__private_obj == NULL)
131
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))
137
138 #define MONO_HANDLE_ASSIGN(handle,rawptr)       \
139         do {    \
140                 mono_handle_assign ((handle), (rawptr));        \
141         } while (0)
142
143 #define MONO_HANDLE_SETREF(handle,fieldname,value)                      \
144         do {                                                            \
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;                                 \
149         } while (0)
150
151 #define MONO_HANDLE_SETREF_NULL(handle,fieldname)                       \
152         do {                                                            \
153                 MONO_PREPARE_GC_CRITICAL_REGION;                        \
154                 MONO_OBJECT_SETREF (mono_handle_obj ((handle)), fieldname, NULL); \
155                 MONO_FINISH_GC_CRITICAL_REGION;                         \
156         } while (0)
157
158
159 #define MONO_HANDLE_SET(handle,fieldname,value) \
160         do {    \
161                 MONO_PREPARE_GC_CRITICAL_REGION;        \
162                 mono_handle_obj ((handle))->fieldname = (value);        \
163                 MONO_FINISH_GC_CRITICAL_REGION; \
164         } while (0)
165
166 #define MONO_HANDLE_ARRAY_SETREF(handle,index,value)                    \
167         do {                                                            \
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;                                 \
172         } while (0)
173
174 #define MONO_HANDLE_ARRAY_SETREF_NULL(handle,index)                     \
175         do {                                                            \
176                 MONO_PREPARE_GC_CRITICAL_REGION;                        \
177                 mono_array_setref (mono_handle_obj ((handle)), (index), NULL); \
178                 MONO_FINISH_GC_CRITICAL_REGION;                         \
179         } while (0)
180         
181
182 #define MONO_HANDLE_ARRAY_SET(handle,type,index,value)  \
183         do {    \
184                 MONO_PREPARE_GC_CRITICAL_REGION;        \
185                 mono_array_set (mono_handle_obj ((handle)), type, (index), (value));    \
186                 MONO_FINISH_GC_CRITICAL_REGION; \
187         } while (0)
188
189
190
191
192 /* Some common handle types */
193
194 MONO_HANDLE_TYPE_DECL (MonoArray);
195 MONO_HANDLE_TYPE_DECL (MonoString);
196
197 G_END_DECLS
198
199 #endif /* __MONO_HANDLE_H__ */