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