]> git.buserror.net Git - polintos/scott/priv.git/blob - include/c++/orb.h
716b18617837c17e70b3fb4dfa0b2b91c689a80e
[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 MarshCtx {
127                         GrowableArray<uint8_t, ORBMM> &buf;
128                         GrowableArray<ID, ORBMM> &objlist;
129                         GrowableArray<NewObject, ORBMM> &newobjlist;
130                         ParamInfoBlock::Segment *segs;
131                         int nsegs;
132                 };
133
134                 struct VStructInfo {
135                         // List of GUIDs of the struct and its superstructs,
136                         // starting with System.VStruct and ending with
137                         // the concrete struct.
138                         
139                         const unsigned long *const *const guids;
140
141                         // Length of inheritance chain; 1 for System.VStruct
142                         
143                         const int chainlen;
144
145                         int (*marshall)(MarshCtx &ctx);
146                         void (*unmarshall)(MarshCtx &ctx);
147                 };
148
149                 namespace Priv {
150                         // Return the caller's PC.  It'd be nice if GCC had a builtin for
151                         // the current PC, so that a simple relocation could be used rather
152                         // than a function call.  OPT: put this in lowlevel-lib, so that
153                         // architectures can provide a faster version.
154                         
155                         unsigned long get_pc();
156
157                         static inline bool in_kernel()
158                         {
159 #ifdef _KERNEL
160                                 return true;
161 #else
162                                 return false;
163 #endif
164                         }
165
166                 }
167         };
168 }
169
170 inline void *operator new(size_t len, ::System::RunTime::ORBMM orbmm,
171                           int refs = 1)
172 {
173         return ::System::RunTime::ORBMM::alloc(len, refs);
174 }
175
176 inline void *operator new[](size_t len, ::System::RunTime::ORBMM orbmm,
177                             int refs = 1)
178 {
179         return ::System::RunTime::ORBMM::alloc(len, refs);
180 }
181
182 // This is a macro rather than an inline template function so that the
183 // caller shows up as file/line number in the debugging information rather
184 // than this header file, and so that a variable argument list can be
185 // passed to a fixed arg ctor.
186 //
187 // To throw an IDL exception of type Foo, do this:
188 // throw_idl(Foo, args, to, foo);
189
190 #ifndef POLINTOS_NO_THROW_IDL
191 #define throw_idl(T, args...) do { \
192         throw T(NULL, NULL, \
193                 new(::System::RunTime::ORBMM()) \
194                    ::System::Exceptions::NativeCodeExceptionOriginInfo \
195                    (::System::RunTime::Priv::get_pc()), \
196                 ::System::RunTime::Priv::in_kernel(), ##args); \
197 } while (0)
198
199 #define rethrow_idl(oldex, T, args...) do { \
200         throw T(new(::System::RunTime::ORBMM()) typeof(oldex)(oldex), NULL, \
201                 new(::System::RunTime::ORBMM()) \
202                    ::System::Exceptions::NativeCodeExceptionOriginInfo \
203                    (::System::RunTime::Priv::get_pc()), \
204                 ::System::RunTime::Priv::in_kernel(), ##args); \
205 } while (0)
206 #endif
207
208 #endif