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