]> git.buserror.net Git - polintos/scott/priv.git/blob - idlcomp/compileddef.h
Add first draft of marshalling spec
[polintos/scott/priv.git] / idlcomp / compileddef.h
1 #ifndef IDLC_COMPILEDDEFS_H
2 #define IDLC_COMPILEDDEFS_H
3
4 #include <stdint.h>
5
6 #if !defined(BITFIELD_LE) && !defined(BITFIELD_BE)
7 #error Please define your bitfield endianness (BITFIELD_LE or BITFIELD_BE).
8 #endif
9
10 // This is the compiled representation of definitions when stored on
11 // a legacy filesystem (as opposed to native object storage). 
12 // Normally, a standard encoding would be used to map objects to
13 // directories and files; however, such encodings cannot be used
14 // before they exist.  This special mapping allows the system to be
15 // bootstrapped from a legacy system.
16 //
17 // As this is a transitional representation, and IDL management is
18 // not performance critical, emphasis has been placed on simplicity
19 // rather than efficiency.  In particular, I don't want to write
20 // throw-away code to compensate for most filesystems' inability to
21 // deal with small files efficiently, nor do I want to muck around
22 // with storing the compiled definitions in textual form (thus
23 // needing to parse them *again*; I want to keep that out of the
24 // ORB).  Dot files and directories are used rather than the more
25 // straightforward way of keeping the namespace under its own member
26 // in order to make the compiled definitions easier to browse with
27 // normal utilities (in the final system, you'll be able to use a
28 // custom view that arranges it however you want; however, Unix
29 // doesn't have custom filesystem views).
30 //
31 // I have tried to make the definitions close to what could be
32 // emitted by an IDL compiler, minus the hierarchical relationship
33 // (which won't exist on a legacy filesystem).  These definitions
34 // require C++ (plus C99 stdint.h); C will choke on the assumed
35 // struct namespace behavior (among other things).
36 //
37 // Each definition is represented by a directory.  If the definition is
38 // for a non-generic namespace (i.e. it is for a struct, interface,
39 // bitfield, etc.), the definition itself is placed in a file called
40 // ".self" inside the directory.  The file contains a CompiledDefHeader
41 // struct followed by the appropriate type-specific struct.
42 //
43 // The non-dotted contents of the directory are the contents of the
44 // definition's namespace, if any.  Anonymous types are given the
45 // name "_anon_<unique>", where <unique> is an arbitrary non-conflicting
46 // name.
47 // 
48 // A compiled definition file may be either big or little endian; if
49 // magic_reversed is found, then all integers in the file must be
50 // reversed prior to usage.
51 //
52 // Bitfields, on the other hand, must be arranged in a little endian
53 // format (i.e. the first field gets the least significant bits; the byte
54 // order of the containing integer is the same as for non-bitfield
55 // integers).  Bitfields generated by idlc will contain padding and
56 // reversed members if the target has big-endian bitfields.
57
58 struct CompiledDefHeader {
59         static const uint32_t magic_normal = 0x2d29c8a9;
60         static const uint32_t magic_reversed = 0xa9c8292d;
61
62         uint32_t magic;        // magic_normal or magic_reversed
63
64         enum Type {
65                 NameSpace,
66                 BasicType,
67                 Datum,
68                 Interface,
69                 Method,
70                 Param,
71                 Struct,
72                 Enum,
73                 BitField,
74                 Alias,
75                 TypeDef
76         };
77         
78         // One of the above types; the enum isn't used directly, as the
79         // size is not guaranteed.
80         int32_t type;
81 };
82
83 struct CompiledNameSpace {
84         // The length of the string in bytes (not characters), excluding
85         // the null terminator.
86
87         int32_t length;
88         
89         // The fully qualified name of the namespace follows, as a
90         // null-terminated UTF-8 string.  This allows the namespace
91         // to be mounted by merely supplying its filesystem path,
92         // without having to specify the mount point.
93 };
94
95 // This struct does not appear standalone, but is included in various
96 // structs that can refer to arrays.
97 struct CompiledArray {
98         // Inclusive lower and upper bounds of the array.  If the
99         // array has no upper bound, [1] should be -1.  If the array
100         // has no lower bound, [0] should be 0.  If this is not an
101         // array, both should be 0.
102         
103         int64_t bounds[2];
104 };
105
106 struct CompiledBasicType {
107         // Size of the type, as follows:
108         //   Byte: 8
109         //   Short: 16
110         //   Int: 32
111         //   Long: 64
112         //   FShort: 32
113         //   FLong: 64
114         //   Bool: 0 (actual size is implementation defined)
115         //
116         // Other sizes may be used within bitfields (up to a max of 64 bits).
117
118         int32_t bits;
119
120         // Unsigned, Float, and Bool are mutually exclusive.
121
122         union Flags {
123                 struct Field {
124 #ifdef BITFIELD_LE
125                         unsigned int Unsigned:1;
126                         unsigned int Float:1;
127                         unsigned int Bool:1;
128                         unsigned int TypeDef:1;
129 #else
130                         unsigned int _pad:28;
131
132                         unsigned int TypeDef:1;
133                         unsigned int Bool:1;
134                         unsigned int Float:1;
135                         unsigned int Unsigned:1;
136 #endif
137                 } field;
138
139                 uint32_t raw;
140                 
141                 struct init {
142                         static const uint32_t Unsigned = 1 << 0;
143                         static const uint32_t Float = 1 << 1;
144                         static const uint32_t Bool = 1 << 2;
145                         static const uint32_t TypeDef = 1 << 3;
146                 };
147         } flags;
148         
149         uint64_t guid[2];
150         
151         CompiledArray array;
152 };
153
154
155 struct CompiledAlias {
156         // The length of the string in bytes (not characters), excluding
157         // the null terminator.
158
159         int32_t length;
160         
161         // The name of the aliased symbol follows, as a null-terminated
162         // UTF-8 string.  This will be the final symbol, and not an alias.
163 };
164
165 // A CompiledDatum is used for data fields in a structure, bitfield, or
166 // enumeration.
167
168 struct CompiledDatum {
169         // This is a description of the datum's type, if it is not a named type.
170         // This is ignored (except the array part) if "type" is non-empty.
171
172         CompiledBasicType basictype;
173         
174         // Const value(s); cast to the appropriate type.  For Bool, cast to
175         // Byte; 0 is false, 1 is true.  Extend all types to 64-bits.
176         // ucon is also used for bitfield element sizes.
177
178         union {
179                 int64_t icon;
180                 uint64_t ucon;
181                 double fcon;
182                 char data[8];
183         };
184
185         // Const can only be used for basic types (both named and unnamed);
186         // Immutable is used for non-initialized const fields.  Invalid is
187         // only used internally by idlc; it is reserved in the file format.
188         
189         union Flags {
190                 struct Field {
191 #ifdef BITFIELD_LE
192                         unsigned int Const:1;
193                         unsigned int Invalid:1;
194                         unsigned int Inline:1;
195                         unsigned int Immutable:1;
196 #else
197                         unsigned int _pad:28;
198
199                         unsigned int Immutable:1;
200                         unsigned int Inline:1;
201                         unsigned int Invalid:1;
202                         unsigned int Const:1;
203 #endif
204                 } field;
205
206                 uint32_t raw;
207
208                 struct init {
209                         static const uint32_t Const = 1 << 0;
210                         static const uint32_t Invalid = 1 << 1;
211                         static const uint32_t Inline = 1 << 2;
212                         static const uint32_t Immutable = 1 << 3;
213                 };
214         } flags;
215
216         // If it's a named type, this points to the type.
217         CompiledAlias type;
218 };
219
220 // Methods, member types, member constants, etc. go in the namespace. 
221 // Methods are ordered; all others are unordered. 
222
223 struct CompiledInterface {
224         int32_t num_methods;
225         int32_t num_supers;
226         
227         uint64_t guid[2];
228         
229         // An array of num_methods + num_supers length of CompiledAliases
230         // representing methods in declared order follows, and then
231         // superclasses in declared order, follows.  The names of metods shall
232         // consist only of the final component, with no namespaces prepended. 
233         // The names of superclasses are fully namespace-qualified.  Each
234         // CompiledAlias shall begin on a 4-byte boundary.
235 };
236
237 // Parameters go in the namespace, and are ordered according to the
238 // list contained in this struct.  Exceptions thrown are unordered
239 // Aliases in a subdirectory called ".exceptions", with arbitrary
240 // names.
241
242 struct CompiledMethod {
243         union Flags {
244                 struct Field {
245 #ifdef BITFIELD_LE
246                         unsigned int Async:1;
247 #else
248                         unsigned int _pad:31;
249
250                         unsigned int Async:1;
251 #endif
252                 } field;
253
254                 uint32_t raw;
255
256                 struct init {
257                         static const uint32_t Async = 1 << 0;
258                 };
259         } flags;
260
261         int32_t num_entries;
262         
263         // An array of num_entries length of CompiledAliases representing
264         // parameters in declared order follows.  Each name shall be as in
265         // CompiledInterface, without namespace qualification.
266 };
267
268 // A param isn't a namespace; however, it is a directory.  In addition to
269 // the ".self" file, the directory contains a "type" Alias file.
270 struct CompiledParam {
271         // This is a description of the parameter's type, if it is not a
272         // named type.  This is ignored (except the array part) if "type"
273         // is non-empty.
274
275         CompiledBasicType basictype;
276
277         union Flags {
278                 struct Field {
279 #ifdef BITFIELD_LE
280                         unsigned int In:1;
281                         unsigned int Out:1;
282                         
283                         unsigned int Shared:1;
284                         unsigned int Push:1;
285                         unsigned int Inline:1;
286                         unsigned int Immutable:1;
287 #else
288                         unsigned int _pad:26;
289
290                         unsigned int Immutable:1;
291                         unsigned int Inline:1;
292                         unsigned int Push:1;
293                         unsigned int Shared:1;
294
295                         unsigned int Out:1;
296                         unsigned int In:1;
297 #endif
298                 } field;
299                 
300                 uint32_t raw;
301
302                 struct init {
303                         static const uint32_t In = 1 << 0;
304                         static const uint32_t Out = 1 << 1;
305                         static const uint32_t Shared = 1 << 2;
306                         static const uint32_t Push = 1 << 3;
307                         static const uint32_t Inline = 1 << 4;
308                         static const uint32_t Immutable = 1 << 5;
309                 };
310         } flags;
311
312         
313         // If it's a named type, this points to the type.
314         CompiledAlias type;
315 };
316
317 // Fields, member types, member constants, etc. go in the namespace. 
318 // All but fields are unordered.
319
320 struct CompiledStruct {
321         union Flags {
322                 struct Field {
323 #ifdef BITFIELD_LE
324                         // Struct has a superstruct.
325
326                         unsigned int Super:1;
327
328                         // Struct has run-time type information.  This requires that
329                         // Super be set.
330
331                         unsigned int Virtual:1;
332                         
333                         // Struct defaults to "inline" when declared in a struct.
334                         // This is mandatory for anonymous structs.
335                         
336                         unsigned int Inline:1;
337 #else
338                         unsigned int _pad:29;
339
340                         unsigned int Inline:1;
341                         unsigned int Virtual:1;
342                         unsigned int Super:1;
343 #endif
344                 } field;
345                 
346                 uint32_t raw;
347
348                 struct init {
349                         static const uint32_t Super = 1 << 0;
350                         static const uint32_t Virtual = 1 << 1;
351                         static const uint32_t Inline = 1 << 2;
352                 };
353         } flags;
354
355         int32_t num_entries;
356
357         uint64_t guid[2];
358         
359         // An array of num_entries length of CompiledAliases representing
360         // fields in declared order follows.  Each name shall be as in
361         // CompiledMethod.  If the Super flag is set, then another
362         // fully-qualified CompiledAlias is placed at the end of the array.
363 };
364
365 // Enum entries are unsigned BasicDatums of the specified size.
366
367 struct CompiledEnum {
368         // Size of enumeration type
369         int32_t bits;
370         
371         int32_t num_entries;
372         
373         uint64_t guid[2];
374
375         // An array of num_entries length of CompiledAliases representing
376         // values in declared order follows.  Each name shall be as in
377         // CompiledMethod.
378 };
379
380 // BitField fields are unsigned BasicDatums and Enum Datums of
381 // arbitrary size, which must add up to at most "bits".
382
383 struct CompiledBitField {
384         // Width of bitfield
385         int32_t bits;
386         
387         int32_t num_entries;
388
389         uint64_t guid[2];
390
391         // An array of num_entries length of CompiledAliases representing
392         // fields in declared order follows.  Each name shall be as in
393         // CompiledMethod.
394 };
395
396 #endif