]> git.saurik.com Git - apple/cf.git/blob - CFRuntime.h
CF-1153.18.tar.gz
[apple/cf.git] / CFRuntime.h
1 /*
2 * Copyright (c) 2015 Apple 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
24 /* CFRuntime.h
25 Copyright (c) 1999-2014, Apple Inc. All rights reserved.
26 */
27
28 #if !defined(__COREFOUNDATION_CFRUNTIME__)
29 #define __COREFOUNDATION_CFRUNTIME__ 1
30
31 #include <CoreFoundation/CFBase.h>
32 #include <CoreFoundation/CFDictionary.h>
33 #include <stddef.h>
34
35 CF_EXTERN_C_BEGIN
36
37 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
38
39 // GC: until we link against ObjC must use indirect functions. Overridden in CFSetupFoundationBridging
40 CF_EXPORT bool kCFUseCollectableAllocator;
41 CF_EXPORT bool (*__CFObjCIsCollectable)(void *);
42
43 CF_INLINE Boolean _CFAllocatorIsSystemDefault(CFAllocatorRef allocator) {
44 if (allocator == kCFAllocatorSystemDefault) return true;
45 if (NULL == allocator || kCFAllocatorDefault == allocator) {
46 return (kCFAllocatorSystemDefault == CFAllocatorGetDefault());
47 }
48 return false;
49 }
50
51 // is GC on?
52 #define CF_USING_COLLECTABLE_MEMORY (kCFUseCollectableAllocator)
53 // is GC on and is this the GC allocator?
54 #define CF_IS_COLLECTABLE_ALLOCATOR(allocator) (kCFUseCollectableAllocator && (NULL == (allocator) || kCFAllocatorSystemDefault == (allocator) || 0))
55 // is this allocated by the collector?
56 #define CF_IS_COLLECTABLE(obj) (__CFObjCIsCollectable ? __CFObjCIsCollectable((void*)obj) : false)
57
58 #else
59
60 #define kCFUseCollectableAllocator 0
61 #define __CFObjCIsCollectable 0
62
63 CF_INLINE Boolean _CFAllocatorIsSystemDefault(CFAllocatorRef allocator) {
64 if (allocator == kCFAllocatorSystemDefault) return true;
65 if (NULL == allocator || kCFAllocatorDefault == allocator) {
66 return (kCFAllocatorSystemDefault == CFAllocatorGetDefault());
67 }
68 return false;
69 }
70
71 #define CF_USING_COLLECTABLE_MEMORY 0
72 #define CF_IS_COLLECTABLE_ALLOCATOR(allocator) 0
73 #define CF_IS_COLLECTABLE(obj) 0
74 #endif
75
76 enum {
77 _kCFRuntimeNotATypeID = 0
78 };
79
80 enum { // Version field constants
81 _kCFRuntimeScannedObject = (1UL << 0),
82 _kCFRuntimeResourcefulObject = (1UL << 2), // tells CFRuntime to make use of the reclaim field
83 _kCFRuntimeCustomRefCount = (1UL << 3), // tells CFRuntime to make use of the refcount field
84 _kCFRuntimeRequiresAlignment = (1UL << 4), // tells CFRuntime to make use of the requiredAlignment field
85 };
86
87 typedef struct __CFRuntimeClass {
88 CFIndex version;
89 const char *className; // must be a pure ASCII string, nul-terminated
90 void (*init)(CFTypeRef cf);
91 CFTypeRef (*copy)(CFAllocatorRef allocator, CFTypeRef cf);
92 void (*finalize)(CFTypeRef cf);
93 Boolean (*equal)(CFTypeRef cf1, CFTypeRef cf2);
94 CFHashCode (*hash)(CFTypeRef cf);
95 CFStringRef (*copyFormattingDesc)(CFTypeRef cf, CFDictionaryRef formatOptions); // return str with retain
96 CFStringRef (*copyDebugDesc)(CFTypeRef cf); // return str with retain
97
98 #define CF_RECLAIM_AVAILABLE 1
99 void (*reclaim)(CFTypeRef cf); // Or in _kCFRuntimeResourcefulObject in the .version to indicate this field should be used
100
101 #define CF_REFCOUNT_AVAILABLE 1
102 uint32_t (*refcount)(intptr_t op, CFTypeRef cf); // Or in _kCFRuntimeCustomRefCount in the .version to indicate this field should be used
103 // this field must be non-NULL when _kCFRuntimeCustomRefCount is in the .version field
104 // - if the callback is passed 1 in 'op' it should increment the 'cf's reference count and return 0
105 // - if the callback is passed 0 in 'op' it should return the 'cf's reference count, up to 32 bits
106 // - if the callback is passed -1 in 'op' it should decrement the 'cf's reference count; if it is now zero, 'cf' should be cleaned up and deallocated (the finalize callback above will NOT be called unless the process is running under GC, and CF does not deallocate the memory for you; if running under GC, finalize should do the object tear-down and free the object memory); then return 0
107 // remember to use saturation arithmetic logic and stop incrementing and decrementing when the ref count hits UINT32_MAX, or you will have a security bug
108 // remember that reference count incrementing/decrementing must be done thread-safely/atomically
109 // objects should be created/initialized with a custom ref-count of 1 by the class creation functions
110 // do not attempt to use any bits within the CFRuntimeBase for your reference count; store that in some additional field in your CF object
111
112 #pragma GCC diagnostic push
113 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
114 #define CF_REQUIRED_ALIGNMENT_AVAILABLE 1
115 uintptr_t requiredAlignment; // Or in _kCFRuntimeRequiresAlignment in the .version field to indicate this field should be used; the allocator to _CFRuntimeCreateInstance() will be ignored in this case; if this is less than the minimum alignment the system supports, you'll get higher alignment; if this is not an alignment the system supports (e.g., most systems will only support powers of two, or if it is too high), the result (consequences) will be up to CF or the system to decide
116
117 } CFRuntimeClass;
118
119 #define RADAR_5115468_FIXED 1
120
121 /* Note that CF runtime class registration and unregistration is not currently
122 * thread-safe, which should not currently be a problem, as long as unregistration
123 * is done only when valid to do so.
124 */
125
126 CF_EXPORT CFTypeID _CFRuntimeRegisterClass(const CFRuntimeClass * const cls);
127 /* Registers a new class with the CF runtime. Pass in a
128 * pointer to a CFRuntimeClass structure. The pointer is
129 * remembered by the CF runtime -- the structure is NOT
130 * copied.
131 *
132 * - version field must be zero currently.
133 * - className field points to a null-terminated C string
134 * containing only ASCII (0 - 127) characters; this field
135 * may NOT be NULL.
136 * - init field points to a function which classes can use to
137 * apply some generic initialization to instances as they
138 * are created; this function is called by both
139 * _CFRuntimeCreateInstance and _CFRuntimeInitInstance; if
140 * this field is NULL, no function is called; the instance
141 * has been initialized enough that the polymorphic funcs
142 * CFGetTypeID(), CFRetain(), CFRelease(), CFGetRetainCount(),
143 * and CFGetAllocator() are valid on it when the init
144 * function if any is called.
145 * - copy field should always be NULL. Generic copying of CF
146 * objects has never been defined (and is unlikely).
147 * - finalize field points to a function which destroys an
148 * instance when the retain count has fallen to zero; if
149 * this is NULL, finalization does nothing. Note that if
150 * the class-specific functions which create or initialize
151 * instances more fully decide that a half-initialized
152 * instance must be destroyed, the finalize function for
153 * that class has to be able to deal with half-initialized
154 * instances. The finalize function should NOT destroy the
155 * memory for the instance itself; that is done by the
156 * CF runtime after this finalize callout returns.
157 * - equal field points to an equality-testing function; this
158 * field may be NULL, in which case only pointer/reference
159 * equality is performed on instances of this class.
160 * Pointer equality is tested, and the type IDs are checked
161 * for equality, before this function is called (so, the
162 * two instances are not pointer-equal but are of the same
163 * class before this function is called).
164 * NOTE: the equal function must implement an immutable
165 * equality relation, satisfying the reflexive, symmetric,
166 * and transitive properties, and remains the same across
167 * time and immutable operations (that is, if equal(A,B) at
168 * some point, then later equal(A,B) provided neither
169 * A or B has been mutated).
170 * - hash field points to a hash-code-computing function for
171 * instances of this class; this field may be NULL in which
172 * case the pointer value of an instance is converted into
173 * a hash.
174 * NOTE: the hash function and equal function must satisfy
175 * the relationship "equal(A,B) implies hash(A) == hash(B)";
176 * that is, if two instances are equal, their hash codes must
177 * be equal too. (However, the converse is not true!)
178 * - copyFormattingDesc field points to a function returning a
179 * CFStringRef with a human-readable description of the
180 * instance; if this is NULL, the type does not have special
181 * human-readable string-formats.
182 * - copyDebugDesc field points to a function returning a
183 * CFStringRef with a debugging description of the instance;
184 * if this is NULL, a simple description is generated.
185 *
186 * This function returns _kCFRuntimeNotATypeID on failure, or
187 * on success, returns the CFTypeID for the new class. This
188 * CFTypeID is what the class uses to allocate or initialize
189 * instances of the class. It is also returned from the
190 * conventional *GetTypeID() function, which returns the
191 * class's CFTypeID so that clients can compare the
192 * CFTypeID of instances with that of a class.
193 *
194 * The function to compute a human-readable string is very
195 * optional, and is really only interesting for classes,
196 * like strings or numbers, where it makes sense to format
197 * the instance using just its contents.
198 */
199
200 CF_EXPORT const CFRuntimeClass * _CFRuntimeGetClassWithTypeID(CFTypeID typeID);
201 /* Returns the pointer to the CFRuntimeClass which was
202 * assigned the specified CFTypeID.
203 */
204
205 CF_EXPORT void _CFRuntimeUnregisterClassWithTypeID(CFTypeID typeID);
206 /* Unregisters the class with the given type ID. It is
207 * undefined whether type IDs are reused or not (expect
208 * that they will be).
209 *
210 * Whether or not unregistering the class is a good idea or
211 * not is not CF's responsibility. In particular you must
212 * be quite sure all instances are gone, and there are no
213 * valid weak refs to such in other threads.
214 */
215
216 /* All CF "instances" start with this structure. Never refer to
217 * these fields directly -- they are for CF's use and may be added
218 * to or removed or change format without warning. Binary
219 * compatibility for uses of this struct is not guaranteed from
220 * release to release.
221 */
222 typedef struct __CFRuntimeBase {
223 uintptr_t _cfisa;
224 uint8_t _cfinfo[4];
225 #if __LP64__
226 uint32_t _rc;
227 #endif
228 } CFRuntimeBase;
229
230 #if __BIG_ENDIAN__
231 #define INIT_CFRUNTIME_BASE(...) {0, {0, 0, 0, 0x80}}
232 #else
233 #define INIT_CFRUNTIME_BASE(...) {0, {0x80, 0, 0, 0}}
234 #endif
235
236 CF_EXPORT CFTypeRef _CFRuntimeCreateInstance(CFAllocatorRef allocator, CFTypeID typeID, CFIndex extraBytes, unsigned char *category);
237 /* Creates a new CF instance of the class specified by the
238 * given CFTypeID, using the given allocator, and returns it.
239 * If the allocator returns NULL, this function returns NULL.
240 * A CFRuntimeBase structure is initialized at the beginning
241 * of the returned instance. extraBytes is the additional
242 * number of bytes to allocate for the instance (BEYOND that
243 * needed for the CFRuntimeBase). If the specified CFTypeID
244 * is unknown to the CF runtime, this function returns NULL.
245 * No part of the new memory other than base header is
246 * initialized (the extra bytes are not zeroed, for example).
247 * All instances created with this function must be destroyed
248 * only through use of the CFRelease() function -- instances
249 * must not be destroyed by using CFAllocatorDeallocate()
250 * directly, even in the initialization or creation functions
251 * of a class. Pass NULL for the category parameter.
252 */
253
254 CF_EXPORT void _CFRuntimeSetInstanceTypeID(CFTypeRef cf, CFTypeID typeID);
255 /* This function changes the typeID of the given instance.
256 * If the specified CFTypeID is unknown to the CF runtime,
257 * this function does nothing. This function CANNOT be used
258 * to initialize an instance. It is for advanced usages such
259 * as faulting. You cannot change the CFTypeID of an object
260 * of a _kCFRuntimeCustomRefCount class, or to a
261 * _kCFRuntimeCustomRefCount class.
262 */
263
264 CF_EXPORT void _CFRuntimeInitStaticInstance(void *memory, CFTypeID typeID);
265 /* This function initializes a memory block to be a constant
266 * (unreleaseable) CF object of the given typeID.
267 * If the specified CFTypeID is unknown to the CF runtime,
268 * this function does nothing. The memory block should
269 * be a chunk of in-binary writeable static memory, and at
270 * least as large as sizeof(CFRuntimeBase) on the platform
271 * the code is being compiled for. The init function of the
272 * CFRuntimeClass is invoked on the memory as well, if the
273 * class has one. Static instances cannot be initialized to
274 * _kCFRuntimeCustomRefCount classes.
275 */
276 #define CF_HAS_INIT_STATIC_INSTANCE 1
277
278 CF_EXTERN_C_END
279
280 #endif /* ! __COREFOUNDATION_CFRUNTIME__ */
281