]> git.buserror.net Git - polintos/scott/priv.git/blob - include/c++/orb.h
cba58491b4bc24ba02c52c58adbfee6ec22491b5
[polintos/scott/priv.git] / include / c++ / orb.h
1 #ifndef _CPP_ORB_H
2 #define _CPP_ORB_H
3
4 #include <stdint.h>
5 #include <stddef.h>
6 #include <string.h>
7
8 namespace System {
9         struct _i_Object;
10
11         namespace Mem {
12                 struct Region;
13         }
14
15         namespace RunTime {
16                 class ORBMM {
17                         void *priv;
18                         
19                 public:
20                         class AllocGroup {
21                                 friend class ORBMM;
22                         };
23                         
24                         typedef ::System::Mem::Region Region;
25                         
26                         ORBMM();
27                         
28                         void *alloc(size_t size, AllocGroup *group = NULL);
29                         
30                         void retain(Region region);
31                         void release(Region region);
32                         void super_retain(Region region);
33                         void super_release(Region region);
34                         AllocGroup *create_group();
35                         void destroy_group(AllocGroup *group);
36                         void *add_region(Region region);
37                 };
38                 
39                 extern ORBMM *orbmm;
40                 
41                 // FIXME: should be an IDL exception
42                 struct ArrayException
43                 {
44                 };
45                 
46                 class NullArray {
47                 };
48                 
49                 static const NullArray nullarray = {};
50                 
51                 template<typename T> struct MutableArray {
52                         T *ptr;
53                         size_t count;
54                 
55                         bool valid_index(size_t index)
56                         {
57                                 return index >= 0 && index < count;
58                         }
59                         
60                         T &operator[](size_t index)
61                         {
62 #ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
63                                 if (!valid_index(index))
64                                         throw ArrayException();
65 #endif
66                 
67                                 return ptr[index];
68                         }
69                         
70                         MutableArray()
71                         {
72                                 ptr = NULL;
73                                 count = 0;
74                         }
75                         
76                         MutableArray(NullArray na)
77                         {
78                                 ptr = NULL;
79                                 count = 0;
80                         }
81                         
82                         MutableArray(T *PTR, size_t COUNT)
83                         {
84                                 ptr = PTR;
85                                 count = COUNT;
86                         }
87                         
88                         MutableArray &slice_nocheck(size_t first, size_t newcount)
89                         {
90                                 MutableArray ret;
91                                 ret.ptr = ptr + first;
92                                 ret.count = newcount;
93                                 return ret;
94                         }
95
96                         MutableArray &slice_nocheck(size_t first)
97                         {
98                                 MutableArray ret;
99                                 ret.ptr = ptr + first;
100                                 ret.count = count - first;
101                                 return ret;
102                         }
103
104                         MutableArray &slice(size_t first, size_t count)
105                         {
106 #ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
107                                 if (!valid_index(first) || !valid_index(first + count - 1))
108                                         throw ArrayException();
109 #endif
110                                 
111                                 return slice_nocheck(first, count);
112                         }
113
114                         MutableArray &slice(size_t first)
115                         {
116 #ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
117                                 if (!valid_index(first))
118                                         throw ArrayException();
119 #endif
120                                 
121                                 return slice_nocheck(first);
122                         }
123                         
124                         MutableArray copy()
125                         {
126                                 MutableArray new_arr;
127                                 new_arr.ptr = new(orbmm) T[count];
128                                 new_arr.count = count;
129                                 memcpy(new_arr.ptr, ptr, count);
130                                 return new_arr;
131                         }
132                 };
133
134                 template<typename T> struct Array {
135                         const T *ptr;
136                         size_t count;
137                 
138                         bool valid_index(size_t index)
139                         {
140                                 return index >= 0 && index < count;
141                         }
142                         
143                         const T &operator[](size_t index)
144                         {
145 #ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
146                                 if (!valid_index(index))
147                                         throw ArrayException();
148 #endif
149                 
150                                 return ptr[index];
151                         }
152                         
153                         Array()
154                         {
155                                 ptr = NULL;
156                                 count = 0;
157                         }
158                         
159                         Array(NullArray na)
160                         {
161                                 ptr = NULL;
162                                 count = 0;
163                         }
164                         
165                         Array(const T *PTR, size_t COUNT)
166                         {
167                                 ptr = PTR;
168                                 count = COUNT;
169                         }
170                         
171                         Array(MutableArray<T> ma)
172                         {
173                                 ptr = ma.ptr;
174                                 count = ma.count;
175                         }
176                         
177                         MutableArray<T> constcast()
178                         {
179                                 MutableArray<T> ma;
180                                 ma.ptr = const_cast<T>(ptr);
181                                 ma.count = count;
182                                 return ma;
183                         }
184                         
185                         Array &slice_nocheck(size_t first, size_t newcount)
186                         {
187                                 Array ret;
188                                 ret.ptr = ptr + first;
189                                 ret.count = newcount;
190                                 return ret;
191                         }
192
193                         Array &slice_nocheck(size_t first)
194                         {
195                                 Array ret;
196                                 ret.ptr = ptr + first;
197                                 ret.count = count - first;
198                                 return ret;
199                         }
200
201                         Array &slice(size_t first, size_t count)
202                         {
203 #ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
204                                 if (!valid_index(first) || !valid_index(first + count - 1))
205                                         throw ArrayException();
206 #endif
207                                 
208                                 return slice_nocheck(first, count);
209                         }
210
211                         Array &slice(size_t first)
212                         {
213 #ifndef POLINTOS_NO_ARRAY_BOUNDS_CHECK
214                                 if (!valid_index(first))
215                                         throw ArrayException();
216 #endif
217                                 
218                                 return slice_nocheck(first);
219                         }
220                         
221                         MutableArray<T> copy()
222                         {
223                                 MutableArray<T> new_arr;
224                                 new_arr.ptr = new(orbmm) T[count];
225                                 new_arr.count = count;
226                                 memcpy(new_arr.ptr, ptr, count);
227                                 return new_arr;
228                         }
229                 };
230
231                 static inline Array<uint8_t> countarray(const char *ptr)
232                 {
233                         Array<uint8_t> ret;
234                         ret.ptr = reinterpret_cast<const uint8_t *>(ptr);
235                         ret.count = strlen(ptr);
236                         return ret;
237                 }
238
239                 static inline MutableArray<uint8_t> countarray(char *ptr)
240                 {
241                         MutableArray<uint8_t> ret;
242                         ret.ptr = reinterpret_cast<uint8_t *>(ptr);
243                         ret.count = strlen(ptr);
244                         return ret;
245                 }
246                 
247                 struct IFaceTable {
248                         const unsigned long *const guid;
249                         const ptrdiff_t offset;
250                 };
251                 
252                 struct VStructInfo {
253                         // List of GUIDs of the struct and its superstructs,
254                         // starting with System.VStruct and ending with
255                         // the concrete struct.
256                         
257                         const unsigned long *const *const guids;
258
259                         // Length of inheritance chain; 1 for System.VStruct
260                         
261                         const int chainlen;
262                 };
263                 
264                 uintptr_t downcast(::System::_i_Object *obj,
265                                    const unsigned long *new_guid);
266
267                 static inline bool guids_equal(const unsigned long *guid1,
268                                                const unsigned long *guid2)
269                 {
270                         return (guid1[0] == guid2[0] && 
271                                 guid1[1] == guid2[1] &&
272                                 (sizeof(long) == 8 ||
273                                  (guid1[2] == guid2[2] &&
274                                   guid1[3] == guid2[3])));
275                 }
276                 
277                 // Return the caller's PC.  It'd be nice if GCC had a builtin for
278                 // the current PC, so that a simple relocation could be used rather
279                 // than a function call.  OPT: put this in lowlevel-lib, so that
280                 // architectures can provide a faster version.
281                 
282                 unsigned long get_pc();
283                 
284                 struct ParamInfoBlock {
285                         uintptr_t buffer_size;
286                         void **objlist_ptr;
287                         uintptr_t objlist_len;
288                         void **ptrlist_ptr;
289                         uintptr_t ptrlist_len;
290                         uintptr_t num_segments;
291
292                         struct Segment {
293                                 void *ptr;
294                                 uintptr_t len;
295                                 uintptr_t flags;
296                         } segments[0];
297                 };
298         }
299 }
300
301 inline void *operator new(size_t len, ::System::RunTime::ORBMM *orbmm,
302                           ::System::RunTime::ORBMM::AllocGroup *group = NULL)
303 {
304         return orbmm->alloc(len, group);
305 }
306
307 inline void *operator new[](size_t len, ::System::RunTime::ORBMM *orbmm,
308                             ::System::RunTime::ORBMM::AllocGroup *group = NULL)
309 {
310         return orbmm->alloc(len, group);
311 }
312
313 // This is a macro rather than an inline template function so that the
314 // caller shows up as file/line number in the debugging information rather
315 // than this header file, and so that a variable argument list can be
316 // passed to a fixed arg ctor.
317 //
318 // To throw an IDL exception of type Foo, do this:
319 // throw_idl(Foo, args, to, foo);
320
321 #ifndef POLINTOS_NO_THROW_IDL
322 #define throw_idl(T, args...) do { \
323         throw T(NULL, NULL, \
324                 new(::System::RunTime::orbmm) \
325                    ::System::Exceptions::NativeCodeExceptionOriginInfo \
326                    (::System::RunTime::get_pc()), \
327                 _KERNEL ? 1 : 0, ##args); \
328 } while (0)
329
330 #define rethrow_idl(oldex, T, args...) do { \
331         throw T(new(::System::RunTime::orbmm) typeof(oldex)(oldex), NULL, \
332                 new(::System::RunTime::orbmm) \
333                    ::System::Exceptions::NativeCodeExceptionOriginInfo \
334                    (::System::RunTime::get_pc()), \
335                 _KERNEL ? 1 : 0, ##args); \
336 } while (0)
337 #endif
338
339 #endif