]> git.saurik.com Git - apple/xnu.git/blob - libkern/libkern/c++/OSMetaClass.h
b46fce46466e2275158444b7d56bb9b0543d902a
[apple/xnu.git] / libkern / libkern / c++ / OSMetaClass.h
1 /*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
14 * agreement.
15 *
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
18 * file.
19 *
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
27 *
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
29 */
30 #ifndef _LIBKERN_OSMETACLASS_H
31 #define _LIBKERN_OSMETACLASS_H
32
33 #include <sys/types.h>
34
35 #include <libkern/OSReturn.h>
36 #include <kern/debug.h>
37
38 class OSMetaClass;
39 class OSObject;
40 class OSString;
41 class OSSymbol;
42 class OSDictionary;
43 class OSSerialize;
44
45 #if __GNUC__ < 3
46 #define APPLE_KEXT_COMPATIBILITY
47 #else
48 #define APPLE_KEXT_COMPATIBILITY __attribute__ ((apple_kext_compatibility))
49 #endif
50
51 class OSMetaClassBase
52 {
53 public:
54 /*! @function OSTypeAlloc
55 @abstract Allocate an instance of the desired object.
56 @discussion The OSTypeAlloc macro can be used to break the binary compatibility difficulties presented by new. The problem is that C++ compiles the knowledge of the size of the class into the cade calling new. If you use the alloc code however the class size is determined by the callee not the caller.
57 @param type Name of the desired type to be created.
58 @result 'this' if object cas been successfully created.
59 */
60 #define OSTypeAlloc(type) ((type *) ((type::metaClass)->alloc()))
61
62 /*! @function OSTypeID
63 @abstract Given the name of a class return it's typeID
64 @param type Name of the desired type, eg. OSObject.
65 @result A unique Type ID for the class.
66 */
67 #define OSTypeID(type) (type::metaClass)
68
69 /*! @function OSTypeIDInst
70 @abstract Given a pointer to an object return it's typeID
71 @param typeinst An instance of an OSObject subclass.
72 @result The typeID, ie. OSMetaClass *.
73 */
74 #define OSTypeIDInst(typeinst) ((typeinst)->getMetaClass())
75
76 /*! @function OSDynamicCast
77 @abstract Roughly analogous to (type *) inst, but check if valid first.
78 @discussion OSDynamicCast is an attempt to implement a rudimentary equivalent to rtti's dynamic_cast<T> operator. Embedded-C++ doesn't allow the use of rtti. OSDynamicCast is build on the OSMetaClass mechanism. Note it is safe to call this with a 0 parameter.
79 @param type name of desired class name. Notice that it is assumed that you desire to cast to a pointer to an object of this type. Also type qualifiers, like const, are not recognized and will cause an, usually obscure, compile error.
80 @param inst Pointer to object that you wish to attempt to type cast. May be 0.
81 @result inst if object non-zero and it is of the desired type, otherwise 0.
82 */
83 #define OSDynamicCast(type, inst) \
84 ((type *) OSMetaClassBase::safeMetaCast((inst), OSTypeID(type)))
85
86 /*! @function OSCheckTypeInst
87 @abstract Is the target object a subclass of the reference object?
88 @param typeinst Reference instance of an object, desired type.
89 @param inst Instance of object to check for type compatibility.
90 @result false if typeinst or inst are 0 or inst is not a subclass of typeinst's class. true otherwise.
91 */
92 #define OSCheckTypeInst(typeinst, inst) \
93 OSMetaClassBase::checkTypeInst(inst, typeinst)
94
95
96 // Arcane evil code interprets a C++ pointer to function as specified in the
97 // -fapple-kext ABI, i.e. the gcc-2.95 generated code. IT DOES NOT ALLOW
98 // the conversion of functions that are from MULTIPLY inherited classes.
99
100 typedef void (*_ptf_t)(void);
101
102 static inline _ptf_t
103 _ptmf2ptf(const OSMetaClassBase *self, void (OSMetaClassBase::*func)(void))
104 {
105 union {
106 void (OSMetaClassBase::*fIn)(void);
107 struct { // Pointer to member function 2.95
108 unsigned short fToff;
109 short fVInd;
110 union {
111 _ptf_t fPFN;
112 short fVOff;
113 } u;
114 } fptmf2;
115 } map;
116
117 map.fIn = func;
118 if (map.fptmf2.fToff)
119 panic("Multiple inheritance is not supported");
120 else if (map.fptmf2.fVInd < 0) {
121 // Not virtual, i.e. plain member func
122 return map.fptmf2.u.fPFN;
123 } else {
124 union {
125 const OSMetaClassBase *fObj;
126 _ptf_t **vtablep;
127 } u;
128 u.fObj = self;
129
130 // Virtual member function so dereference vtable
131 return (*u.vtablep)[map.fptmf2.fVInd - 1];
132 }
133 }
134
135 /*! @function OSMemberFunctionCast
136 @abstract Convert a pointer to a member function to a c-style pointer to function. No warnings are generated.
137 @param type The type of pointer function desired.
138 @param self The this pointer of the object whose function you wish to cache.
139 @param func The pointer to member function itself, something like &Base::func.
140 @result A pointer to function of the given type. This function will panic if an attempt is made to call it with a multiply inherited class.
141 */
142
143 #define OSMemberFunctionCast(cptrtype, self, func) \
144 (cptrtype) OSMetaClassBase:: \
145 _ptmf2ptf(self, (void (OSMetaClassBase::*)(void)) func)
146
147 protected:
148 OSMetaClassBase();
149 virtual ~OSMetaClassBase();
150
151 private:
152 // Disable copy constructors of OSMetaClassBase based objects
153 /*! @function operator =
154 @abstract Disable implicit copy constructor by making private
155 @param src Reference to source object that isn't allowed to be copied
156 */
157 void operator =(OSMetaClassBase &src);
158
159 /*! @function OSMetaClassBase
160 @abstract Disable implicit copy constructor by making private
161 @param src Reference to source object that isn't allowed to be copied
162 */
163 OSMetaClassBase(OSMetaClassBase &src);
164
165 public:
166 /*! @function release
167 @abstract Primary implementation of the release mechanism.
168 @discussion If $link retainCount <= the when argument then call $link free(). This indirect implementation of $link release allows the developer to break reference circularity. An example of this sort of problem is a parent/child mutual reference, either the parent or child can implement: void release() { release(2); } thus breaking the cirularity.
169 @param when When retainCount == when then call free(). */
170 virtual void release(int when) const = 0;
171
172 /*! @function getRetainCount
173 @abstract How many times has this object been retained?
174 @result Current retain count
175 */
176 virtual int getRetainCount() const = 0;
177
178 /*! @function retain
179 @abstract Retain a reference in this object.
180 */
181 virtual void retain() const = 0;
182 /*! @function release
183 @abstract Release a reference to this object
184 */
185 virtual void release() const = 0;
186
187 /*! @function serialize
188 @abstract
189 @discussion
190 @param s
191 @result
192 */
193 virtual bool serialize(OSSerialize *s) const = 0;
194
195 virtual const OSMetaClass * getMetaClass() const = 0;
196
197 /*! @function isEqualTo
198 @abstract Is this == anObj?
199 @discussion OSMetaClassBase::isEqualTo implements this as a shallow pointer comparison. The OS container classes do a more meaningful comparison. Your mileage may vary.
200 @param anObj Object to compare 'this' to.
201 @result true if the objects are equivalent, false otherwise.
202 */
203 virtual bool isEqualTo(const OSMetaClassBase *anObj) const;
204
205 /*! @function metaCast
206 @abstract Check to see if this object is or inherits from the given type.
207 @discussion This function is the guts of the OSMetaClass system. IODynamicCast, qv, is implemented using this function.
208 @param toMeta Pointer to a constant OSMetaClass for the desired target type.
209 @result 'this' if object is of desired type, otherwise 0.
210 */
211 OSMetaClassBase *metaCast(const OSMetaClass *toMeta) const;
212
213
214 /*! @function metaCast
215 @abstract See OSMetaClassBase::metaCast(const OSMetaClass *)
216 @param toMeta OSSymbol of the desired class' name.
217 @result 'this' if object is of desired type, otherwise 0.
218 */
219 OSMetaClassBase *metaCast(const OSSymbol *toMeta) const;
220
221 /*! @function metaCast
222 @abstract See OSMetaClassBase::metaCast(const OSMetaClass *)
223 @param toMeta OSString of the desired class' name.
224 @result 'this' if object is of desired type, otherwise 0.
225 */
226 OSMetaClassBase *metaCast(const OSString *toMeta) const;
227
228 /*! @function metaCast
229 @abstract See OSMetaClassBase::metaCast(const OSMetaClass *)
230 @param toMeta const char * C String of the desired class' name.
231 @result 'this' if object is of desired type, otherwise 0.
232 */
233 OSMetaClassBase *metaCast(const char *toMeta) const;
234
235 // Helper inlines for runtime type preprocessor macros
236 static OSMetaClassBase *
237 safeMetaCast(const OSMetaClassBase *me, const OSMetaClass *toType);
238
239 static bool
240 checkTypeInst(const OSMetaClassBase *inst, const OSMetaClassBase *typeinst);
241
242 public:
243
244 /*! @function taggedRetain
245 @abstract Retain a tagged reference in this object.
246 */
247 // WAS: virtual void _RESERVEDOSMetaClassBase0();
248 virtual void taggedRetain(const void *tag = 0) const = 0;
249
250 /*! @function taggedRelease
251 @abstract Release a tagged reference to this object
252 */
253 // WAS: virtual void _RESERVEDOSMetaClassBase1();
254 virtual void taggedRelease(const void *tag = 0) const = 0;
255
256 protected:
257 /*! @function taggedRelease
258 @abstract Release a tagged reference to this object and free if retainCount == when on entry
259 */
260 // WAS: virtual void _RESERVEDOSMetaClassBase2();
261 virtual void taggedRelease(const void *tag, const int when) const = 0;
262
263 private:
264 // Virtual Padding
265 virtual void _RESERVEDOSMetaClassBase3();
266 virtual void _RESERVEDOSMetaClassBase4();
267 virtual void _RESERVEDOSMetaClassBase5();
268 virtual void _RESERVEDOSMetaClassBase6();
269 virtual void _RESERVEDOSMetaClassBase7();
270 } APPLE_KEXT_COMPATIBILITY;
271
272 /*!
273 @class OSMetaClass : OSMetaClassBase
274 @abstract An instance of a OSMetaClass represents one class then the kernel's runtime type information system is aware of.
275 */
276 class OSMetaClass : private OSMetaClassBase
277 {
278
279 private:
280 // Can never be allocated must be created at compile time
281 static void *operator new(size_t size);
282
283 struct ExpansionData { };
284
285 /*! @var reserved Reserved for future use. (Internal use only) */
286 ExpansionData *reserved;
287
288 /*! @var superClass Handle to the superclass' meta class. */
289 const OSMetaClass *superClassLink;
290
291 /*! @var className OSSymbol of the class' name. */
292 const OSSymbol *className;
293
294 /*! @var classSize How big is a single instancde of this class. */
295 unsigned int classSize;
296
297 /*! @var instanceCount Roughly number of instances of the object. Used primarily as a code in use flag. */
298 mutable unsigned int instanceCount;
299
300 /*! @function OSMetaClass
301 @abstract Private the default constructor */
302 OSMetaClass();
303
304 // Called by postModLoad
305 /*! @function logError
306 @abstract Given an error code log an error string using printf */
307 static void logError(OSReturn result);
308
309 public:
310
311 /*! @function getMetaClassWithName
312 @abstract Lookup a meta-class in the runtime type information system
313 @param name Name of the desired class's meta-class.
314 @result pointer to a meta-class object if found, 0 otherwise. */
315
316 static const OSMetaClass *getMetaClassWithName(const OSSymbol *name);
317
318 protected:
319 /*! @function retain
320 @abstract Implement abstract but should no dynamic allocation is allowed */
321 virtual void retain() const;
322
323 /*! @function release
324 @abstract Implement abstract but should no dynamic allocation is allowed */
325 virtual void release() const;
326
327 /*! @function release
328 @abstract Implement abstract but should no dynamic allocation is allowed
329 @param when ignored. */
330 virtual void release(int when) const;
331
332 /*! @function taggedRetain
333 @abstract Retain a tagged reference in this object.
334 */
335 virtual void taggedRetain(const void *tag = 0) const;
336
337 /*! @function release
338 @abstract Release a tagged reference to this object
339 */
340 virtual void taggedRelease(const void *tag = 0) const;
341
342 /*! @function release
343 @abstract Release a tagged reference to this object
344 */
345 virtual void taggedRelease(const void *tag, const int when) const;
346
347 /*! @function getRetainCount
348 @abstract Implement abstract but should no dynamic allocation is allowed */
349 virtual int getRetainCount() const;
350
351 virtual const OSMetaClass * getMetaClass() const;
352
353 /*! @function OSMetaClass
354 @abstract Constructor for OSMetaClass objects
355 @discussion This constructor is protected and cannot not be used to instantiate an OSMetaClass object, i.e. OSMetaClass is an abstract class. This function stores the currently constructing OSMetaClass instance away for later processing. See preModLoad and postModLoad.
356 @param inClassName cString of the name of the class this meta-class represents.
357 @param inSuperClassName cString of the name of the super class.
358 @param inClassSize sizeof the class. */
359 OSMetaClass(const char *inClassName,
360 const OSMetaClass *inSuperClass,
361 unsigned int inClassSize);
362
363 /*! @function ~OSMetaClass
364 @abstract Destructor for OSMetaClass objects
365 @discussion If this function is called it means that the object code that implemented this class is actually in the process of unloading. The destructor removes all reference's to the subclass from the runtime type information system. */
366 virtual ~OSMetaClass();
367
368 // Needs to be overriden as NULL as all OSMetaClass objects are allocated
369 // statically at compile time, don't accidently try to free them.
370 void operator delete(void *mem, size_t size) { };
371
372 public:
373 static const OSMetaClass * const metaClass;
374
375 /*! @function preModLoad
376 @abstract Prepare the runtime type system for the load of a module.
377 @discussion Prepare the runtime type information system for the loading of new all meta-classes constructed between now and the next postModLoad. preModLoad grab's a lock so that the runtime type information system loading can be protected, the lock is released by the postModLoad function. Any OSMetaClass that is constructed between the bracketing pre and post calls will be assosiated with the module name.
378 @param kmodName globally unique cString name of the kernel module being loaded.
379 @result If success full return a handle to be used in later calls 0 otherwise. */
380 static void *preModLoad(const char *kmodName);
381
382 /*! @function checkModLoad
383 @abstract Check if the current load attempt is still OK.
384 @param loadHandle Handle returned when a successful call to preModLoad is made.
385 @result true if no error's are outstanding and the system is primed to recieve more objects. */
386 static bool checkModLoad(void *loadHandle);
387
388 /*! @function postModLoad
389 @abstract Finish postprocessing on a kernel module's meta-classes.
390 @discussion As the order of static object construction is undefined it is necessary to process the constructors in two phases. These phases rely on global information that is created be the preparation step, preModLoad, which also guarantees single threading between multiple modules. Phase one was the static construction of each meta-class object one by one withing the context prepared by the preModLoad call. postModLoad is the second phase of processing. Inserts links all of the super class inheritance chains up, inserts the meta-classes into the global register of classes and records for each meta-class which kernel module caused it's construction. Finally it cleans up the temporary storage and releases the single threading lock and returns whatever error has been recorded in during the construction phase or the post processing phase.
391 @param loadHandle Handle returned when a successful call to preModLoad is made.
392 @result Error code of the first error encountered. */
393 static OSReturn postModLoad(void *loadHandle);
394
395 /*! @function modHasInstance
396 @abstract Do any of the objects represented by OSMetaClass and associated with the given kernel module name have instances?
397 @discussion Check all meta-classes associated with the module name and check their instance counts. This function is used to check to see if a module can be unloaded. Obviously if an instance is still outstanding it isn't safe to unload the code that relies on that object.
398 @param kmodName cString of the kernel module name.
399 @result true if there are any current instances of any class in the module.
400 */
401 static bool modHasInstance(const char *kmodName);
402
403 /*! @function reportModInstances
404 @abstract Log any object that has instances in a module.
405 @discussion When a developer ask for a module to be unloaded but the unload fails due to outstanding instances. This function will report which classes still have instances. It is intended mostly for developers to find problems with unloading classes and will be called automatically by 'verbose' unloads.
406 @param kmodName cString of the kernel module name. */
407 static void reportModInstances(const char *kmodName);
408
409 /*! @function considerUnloads
410 @abstract Schedule module unloading.
411 @discussion Schedule unused modules to be unloaded; called when IOKit matching goes idle. */
412
413 static void considerUnloads();
414
415 /*! @function allocClassWithName
416 @abstract Lookup a meta-class in the runtime type information system and return the results of an alloc call.
417 @param name Name of the desired class.
418 @result pointer to an new object, 0 if not found or so memory. */
419 static OSObject *allocClassWithName(const OSSymbol *name);
420
421 /*! @function allocClassWithName
422 @abstract Lookup a meta-class in the runtime type information system and return the results of an alloc call.
423 @param name Name of the desired class.
424 @result pointer to an new object, 0 if not found or so memory. */
425 static OSObject *allocClassWithName(const OSString *name);
426
427 /*! @function allocClassWithName
428 @abstract Lookup a meta-class in the runtime type information system and return the results of an alloc call.
429 @param name Name of the desired class.
430 @result pointer to an new object, 0 if not found or so memory. */
431 static OSObject *allocClassWithName(const char *name);
432
433 /*! @function checkMetaCastWithName
434 @abstract Introspect an objects inheritance tree looking for a class of the given name. Basis of MacOSX's kernel dynamic casting mechanism.
435 @param name Name of the desired class or super class.
436 @param in object to be introspected.
437 @result in parameter if cast valid, 0 otherwise. */
438 static OSMetaClassBase *
439 checkMetaCastWithName(const OSSymbol *name, const OSMetaClassBase *in);
440
441 /*! @function checkMetaCastWithName
442 @abstract Introspect an objects inheritance tree looking for a class of the given name. Basis of MacOSX's kernel dynamic casting mechanism.
443 @param name Name of the desired class or super class.
444 @param in object to be introspected.
445 @result in parameter if cast valid, 0 otherwise. */
446 static OSMetaClassBase *
447 checkMetaCastWithName(const OSString *name, const OSMetaClassBase *in);
448
449 /*! @function checkMetaCastWithName
450 @abstract Introspect an objects inheritance tree looking for a class of the given name. Basis of MacOSX's kernel dynamic casting mechanism.
451 @param name Name of the desired class or super class.
452 @param in object to be introspected.
453 @result in parameter if cast valid, 0 otherwise. */
454 static OSMetaClassBase *
455 checkMetaCastWithName(const char *name, const OSMetaClassBase *in);
456
457
458 /*! @function instanceConstructed
459 @abstract Counts the instances of the class behind this metaclass.
460 @discussion Every non-abstract class that inherits from OSObject has a default constructor that calls it's own meta-class' instanceConstructed function. This constructor is defined by the OSDefineMetaClassAndStructors macro (qv) that all OSObject subclasses must use. Also if the instance count goes from 0 to 1, ie the first instance, then increment the instance count of the super class */
461 void instanceConstructed() const;
462
463 /*! @function instanceDestructed
464 @abstract Removes one instance of the class behind this metaclass.
465 @discussion OSObject's free function calls this method just before it does a 'delete this' on itself. If the instance count transitions from 1 to 0, i.e. the last object, then one instance of the superclasses is also removed. */
466 void instanceDestructed() const;
467
468
469 /*! @function checkMetaCast
470 @abstract Ask a OSMetaClass instance if the given object is either an instance of it or an instance of a subclass of it.
471 @param check Pointer of object to introspect.
472 @result check parameter if cast valid, 0 otherwise. */
473 OSMetaClassBase *checkMetaCast(const OSMetaClassBase *check) const;
474
475
476 /*! @function getInstanceCount
477 @abstract How many instances of the class have been created.
478 @result Count of the number of instances. */
479 unsigned int getInstanceCount() const;
480
481
482 /*! @function getSuperClass
483 @abstract 'Get'ter for the super class.
484 @result Pointer to superclass, chain ends with 0 for OSObject. */
485 const OSMetaClass *getSuperClass() const;
486
487 /*! @function getKmodName
488 @abstract 'Get'ter for the name of the kmod.
489 @result OSSymbol representing the kmod name. */
490 const OSSymbol *getKmodName() const;
491
492 /*! @function getClassName
493 @abstract 'Get'ter for class name.
494 @result cString of the class name. */
495 const char *getClassName() const;
496
497 /*! @function getClassSize
498 @abstract 'Get'ter for sizeof(class).
499 @result sizeof of class that this OSMetaClass instance represents. */
500 unsigned int getClassSize() const;
501
502 /*! @function alloc
503 @abstract Allocate an instance of the class that this OSMetaClass instance represents.
504 @discussion This alloc function is analogous to the old ObjC class alloc method. Typically not used by clients as the static function allocClassWithName is more generally useful. Infact that function is implemented in terms of this virtual function. All subclass's of OSMetaClass must implement this function but that is what the OSDefineMetaClassAndStructor's families of macros does for the developer automatically.
505 @result Pointer to a new object with a retain count of 1. */
506 virtual OSObject *alloc() const = 0;
507
508 /*! @function OSDeclareCommonStructors
509 @abstract Basic helper macro for the OSDeclare for Default and Abstract macros, qv. DO NOT USE.
510 @param className Name of class. NO QUOTES. */
511 #define OSDeclareCommonStructors(className) \
512 private: \
513 static const OSMetaClass * const superClass; \
514 public: \
515 static const OSMetaClass * const metaClass; \
516 static class MetaClass : public OSMetaClass { \
517 public: \
518 MetaClass(); \
519 virtual OSObject *alloc() const; \
520 } gMetaClass; \
521 friend class className ::MetaClass; \
522 virtual const OSMetaClass * getMetaClass() const; \
523 protected: \
524 className (const OSMetaClass *); \
525 virtual ~ className ()
526
527
528 /*! @function OSDeclareDefaultStructors
529 @abstract One of the macro's used in the class declaration of all subclasses of OSObject, declares runtime type information data and interfaces.
530 @discussion Macro used in the class declaration all subclasses of OSObject, declares runtime type information data and interfaces. By convention it should be 'called' immediately after the opening brace in a class declaration. It leaves the current privacy state as 'protected:'.
531 @param className Name of class. NO QUOTES. */
532 #define OSDeclareDefaultStructors(className) \
533 OSDeclareCommonStructors(className); \
534 public: \
535 className (); \
536 protected:
537
538
539 /*! @function OSDeclareAbstractStructors
540 @abstract One of the macro's used in the class declaration of all subclasses of OSObject, declares runtime type information data and interfaces.
541 @discussion This macro is used when the class being declared has one or more '= 0' pure virtual methods and thus it is illegal to create an instance of this class. It leaves the current privacy state as 'protected:'.
542 @param className Name of class. NO QUOTES. */
543 #define OSDeclareAbstractStructors(className) \
544 OSDeclareCommonStructors(className); \
545 private: \
546 className (); /* Make primary constructor private in abstract */ \
547 protected:
548
549 /*! @function OSDefineMetaClassWithInit
550 @abstract Basic helper macro for the OSDefineMetaClass for the default and Abstract macros, qv. DO NOT USE.
551 @param className Name of class. NO QUOTES and NO MACROS.
552 @param superClassName Name of super class. NO QUOTES and NO MACROS.
553 @param init Name of a function to call after the OSMetaClass is constructed. */
554 #define OSDefineMetaClassWithInit(className, superClassName, init) \
555 /* Class global data */ \
556 className ::MetaClass className ::gMetaClass; \
557 const OSMetaClass * const className ::metaClass = \
558 & className ::gMetaClass; \
559 const OSMetaClass * const className ::superClass = \
560 & superClassName ::gMetaClass; \
561 /* Class member functions */ \
562 className :: className(const OSMetaClass *meta) \
563 : superClassName (meta) { } \
564 className ::~ className() { } \
565 const OSMetaClass * className ::getMetaClass() const \
566 { return &gMetaClass; } \
567 /* The ::MetaClass constructor */ \
568 className ::MetaClass::MetaClass() \
569 : OSMetaClass(#className, className::superClass, sizeof(className)) \
570 { init; }
571
572 /*! @function OSDefineAbstractStructors
573 @abstract Basic helper macro for the OSDefineMetaClass for the default and Abstract macros, qv. DO NOT USE.
574 @param className Name of class. NO QUOTES and NO MACROS.
575 @param superClassName Name of super class. NO QUOTES and NO MACROS. */
576 #define OSDefineAbstractStructors(className, superClassName) \
577 OSObject * className ::MetaClass::alloc() const { return 0; }
578
579 /*! @function OSDefineDefaultStructors
580 @abstract Basic helper macro for the OSDefineMetaClass for the default and Abstract macros, qv. DO NOT USE.
581 @param className Name of class. NO QUOTES and NO MACROS.
582 @param superClassName Name of super class. NO QUOTES and NO MACROS. */
583 #define OSDefineDefaultStructors(className, superClassName) \
584 OSObject * className ::MetaClass::alloc() const \
585 { return new className; } \
586 className :: className () : superClassName (&gMetaClass) \
587 { gMetaClass.instanceConstructed(); }
588
589
590 /*! @function OSDefineMetaClassAndAbstractStructorsWithInit
591 @abstract Primary definition macro for all abstract classes that a subclasses of OSObject.
592 @discussion Define an OSMetaClass subclass and the primary constructors and destructors for a subclass of OSObject that is an abstract class. In general this 'function' is 'called' at the top of the file just before the first function is implemented for a particular class. Once the OSMetaClass has been constructed, at load time, call the init routine. NB you can not rely on the order of execution of the init routines.
593 @param className Name of class. NO QUOTES and NO MACROS.
594 @param superClassName Name of super class. NO QUOTES and NO MACROS.
595 @param init Name of a function to call after the OSMetaClass is constructed. */
596 #define OSDefineMetaClassAndAbstractStructorsWithInit(className, superClassName, init) \
597 OSDefineMetaClassWithInit(className, superClassName, init) \
598 OSDefineAbstractStructors(className, superClassName)
599
600 /*! @function OSDefineMetaClassAndStructorsWithInit
601 @abstract See OSDefineMetaClassAndStructors
602 @discussion Define an OSMetaClass subclass and the primary constructors and destructors for a subclass of OSObject that isn't an abstract class. In general this 'function' is 'called' at the top of the file just before the first function is implemented for a particular class. Once the OSMetaClass has been constructed, at load time, call the init routine. NB you can not rely on the order of execution of the init routines.
603 @param className Name of class. NO QUOTES and NO MACROS.
604 @param superClassName Name of super class. NO QUOTES and NO MACROS.
605 @param init Name of a function to call after the OSMetaClass is constructed. */
606 #define OSDefineMetaClassAndStructorsWithInit(className, superClassName, init) \
607 OSDefineMetaClassWithInit(className, superClassName, init) \
608 OSDefineDefaultStructors(className, superClassName)
609
610 /* Helpers */
611 /*! @function OSDefineMetaClass
612 @abstract Define an OSMetaClass instance, used for backward compatiblility only.
613 @param className Name of class. NO QUOTES and NO MACROS.
614 @param superClassName Name of super class. NO QUOTES and NO MACROS. */
615 #define OSDefineMetaClass(className, superClassName) \
616 OSDefineMetaClassWithInit(className, superClassName, )
617
618 /*! @function OSDefineMetaClassAndStructors
619 @abstract Define an OSMetaClass subclass and the runtime system routines.
620 @discussion Define an OSMetaClass subclass and the primary constructors and destructors for a subclass of OSObject that isn't an abstract class. In general this 'function' is 'called' at the top of the file just before the first function is implemented for a particular class.
621 @param className Name of class. NO QUOTES and NO MACROS.
622 @param superClassName Name of super class. NO QUOTES and NO MACROS. */
623 #define OSDefineMetaClassAndStructors(className, superClassName) \
624 OSDefineMetaClassAndStructorsWithInit(className, superClassName, )
625
626 /*! @function OSDefineMetaClassAndAbstractStructors
627 @abstract Define an OSMetaClass subclass and the runtime system routines.
628 @discussion Define an OSMetaClass subclass and the primary constructors and destructors for a subclass of OSObject that is an abstract class. In general this 'function' is 'called' at the top of the file just before the first function is implemented for a particular class.
629 @param className Name of class. NO QUOTES and NO MACROS.
630 @param superClassName Name of super class. NO QUOTES and NO MACROS. */
631 #define OSDefineMetaClassAndAbstractStructors(className, superClassName) \
632 OSDefineMetaClassAndAbstractStructorsWithInit (className, superClassName, )
633
634 // Dynamic vtable patchup support routines and types
635 void reservedCalled(int ind) const;
636
637 #define OSMetaClassDeclareReservedUnused(classname, index) \
638 private: \
639 virtual void _RESERVED ## classname ## index ()
640
641 #define OSMetaClassDeclareReservedUsed(classname, index)
642
643 #define OSMetaClassDefineReservedUnused(classname, index) \
644 void classname ::_RESERVED ## classname ## index () \
645 { gMetaClass.reservedCalled(index); }
646
647 #define OSMetaClassDefineReservedUsed(classname, index)
648
649 // IOKit debug internal routines.
650 static void printInstanceCounts();
651 static void serializeClassDictionary(OSDictionary *dict);
652
653 private:
654 // Obsolete APIs
655 static OSDictionary *getClassDictionary();
656 virtual bool serialize(OSSerialize *s) const;
657
658 // Virtual Padding functions for MetaClass's
659 OSMetaClassDeclareReservedUnused(OSMetaClass, 0);
660 OSMetaClassDeclareReservedUnused(OSMetaClass, 1);
661 OSMetaClassDeclareReservedUnused(OSMetaClass, 2);
662 OSMetaClassDeclareReservedUnused(OSMetaClass, 3);
663 OSMetaClassDeclareReservedUnused(OSMetaClass, 4);
664 OSMetaClassDeclareReservedUnused(OSMetaClass, 5);
665 OSMetaClassDeclareReservedUnused(OSMetaClass, 6);
666 OSMetaClassDeclareReservedUnused(OSMetaClass, 7);
667 };
668
669 #endif /* !_LIBKERN_OSMETACLASS_H */