]> git.buserror.net Git - polintos/scott/priv.git/blob - include/c++/orb.h
Move arrays to Util namespace, add parametric allocator.
[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 #include <limits.h>
8
9 #include <lowlevel/barriers.h>
10 #include <lowlevel/bitops.h>
11
12 #include <util/array.h>
13
14 namespace System {
15         struct _i_Object;
16
17         namespace Mem {
18                 struct Region;
19         }
20
21         namespace RunTime {
22                 using namespace ::Util::Arrays;
23                 
24                 class ORBMM {
25                         static void *priv;
26                         
27                 public:
28                         typedef ::System::Mem::Region Region;
29                         
30                         static void *alloc(size_t size, int refs = 1);
31                         static void retain(void *ptr, int refs = 1);
32                         static void release(void *ptr, int refs = 1);
33                         static void add_region(Region region, bool unmap_orig, int refs = 1);
34                 };
35                 
36                 struct IFaceInfo;
37                 typedef uint32_t ID;
38
39                 struct IFaceTable {
40                         const IFaceInfo *info;
41                         const ptrdiff_t offset;
42                 };
43                 
44                 union GUID {
45                         unsigned char c[16];
46                         unsigned long l[];
47                 };
48
49                 uintptr_t downcast(::System::_i_Object *obj, const GUID *new_guid);
50
51                 // FIXME: use above typedef
52                 static inline bool guids_equal(const unsigned long *guid1,
53                                                const unsigned long *guid2)
54                 {
55                         return (guid1[0] == guid2[0] && 
56                                 guid1[1] == guid2[1] &&
57                                 (sizeof(long) == 8 ||
58                                  (guid1[2] == guid2[2] &&
59                                   guid1[3] == guid2[3])));
60                 }
61                 
62                 struct ParamInfoBlock {
63                         uint32_t buffer_size;
64                         uint32_t copy_size;
65                         ID *objlist, *newobj;
66                         uint32_t objlist_len, newobj_len;
67                         uint32_t num_segments;
68
69                         struct Segment {
70                                 uint8_t *ptr;
71                                 uintptr_t len;
72                                 uintptr_t flags;
73                                 uintptr_t reserved;
74                                 
75                                 enum {
76                                         In = 1,
77                                         Out = 2,
78                                         Inline = 4,
79                                         Copy = 8
80                                 };
81                         } segments[0];
82                 };
83                 
84                 struct Segment0 {
85                         enum {
86                                 InvokeMethod = 0,
87                                 GetIFaces = 1,
88                                 ReturnIFaces = 2,
89                         };
90                 
91                         union {
92                                 struct {
93                                         uint8_t opcode;
94                                 };
95                                 
96                                 unsigned long pad;
97                         };
98                 };
99                         
100                 struct InvokeMethod {
101                         Segment0 seg0;
102                         uint32_t iface;
103                         uint32_t method;
104                         uint8_t args[0];
105                 };
106                 
107                 union Message {
108                         Segment0 seg0;
109                         InvokeMethod invoke;
110                 };
111
112                 struct IFaceInfo {
113                         const GUID *guid;
114                         void (*invoke)(Array<ID, ORBMM> objlist,
115                                        ParamInfoBlock::Segment *segs,
116                                        int nsegs);
117                         ::System::_i_Object *(*wrapper)(ID id);
118                 };
119                 
120                 struct NewObject {
121                         uint32_t guid_hash[5]; // SHA-1 hash of Interface GUIDs
122                         uint32_t id;
123                         uint32_t reserved[3]; // must be zero
124                 };
125
126                 struct VStructInfo {
127                         // List of GUIDs of the struct and its superstructs,
128                         // starting with System.VStruct and ending with
129                         // the concrete struct.
130                         
131                         const unsigned long *const *const guids;
132
133                         // Length of inheritance chain; 1 for System.VStruct
134                         
135                         const int chainlen;
136
137                         int (*marshall)(GrowableArray<uint8_t, ORBMM> &buf,
138                                         GrowableArray<ID, ORBMM> &objlist,
139                                         GrowableArray<NewObject, ORBMM> &newobjlist,
140                                         ParamInfoBlock::Segment *segs,
141                                         int nsegs);
142                         void (*unmarshall)(Array<uint8_t, ORBMM> buf,
143                                            Array< ::System::_i_Object *, ORBMM> objlist,
144                                            ParamInfoBlock::Segment *segs,
145                                            int nsegs);
146                 };
147                 
148                 namespace Priv {
149                         // Return the caller's PC.  It'd be nice if GCC had a builtin for
150                         // the current PC, so that a simple relocation could be used rather
151                         // than a function call.  OPT: put this in lowlevel-lib, so that
152                         // architectures can provide a faster version.
153                         
154                         unsigned long get_pc();
155
156                         static inline bool in_kernel()
157                         {
158 #ifdef _KERNEL
159                                 return true;
160 #else
161                                 return false;
162 #endif
163                         }
164                 }
165         };
166 }
167
168 inline void *operator new(size_t len, ::System::RunTime::ORBMM orbmm,
169                           int refs = 1)
170 {
171         return ::System::RunTime::ORBMM::alloc(len, refs);
172 }
173
174 inline void *operator new[](size_t len, ::System::RunTime::ORBMM orbmm,
175                             int refs = 1)
176 {
177         return ::System::RunTime::ORBMM::alloc(len, refs);
178 }
179
180 // This is a macro rather than an inline template function so that the
181 // caller shows up as file/line number in the debugging information rather
182 // than this header file, and so that a variable argument list can be
183 // passed to a fixed arg ctor.
184 //
185 // To throw an IDL exception of type Foo, do this:
186 // throw_idl(Foo, args, to, foo);
187
188 #ifndef POLINTOS_NO_THROW_IDL
189 #define throw_idl(T, args...) do { \
190         throw T(NULL, NULL, \
191                 new(::System::RunTime::ORBMM()) \
192                    ::System::Exceptions::NativeCodeExceptionOriginInfo \
193                    (::System::RunTime::Priv::get_pc()), \
194                 ::System::RunTime::Priv::in_kernel(), ##args); \
195 } while (0)
196
197 #define rethrow_idl(oldex, T, args...) do { \
198         throw T(new(::System::RunTime::ORBMM()) typeof(oldex)(oldex), NULL, \
199                 new(::System::RunTime::ORBMM()) \
200                    ::System::Exceptions::NativeCodeExceptionOriginInfo \
201                    (::System::RunTime::Priv::get_pc()), \
202                 ::System::RunTime::Priv::in_kernel(), ##args); \
203 } while (0)
204 #endif
205
206 #endif