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