2 * Copyright (c) 2014 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
24 /* CoreFoundation_Prefix.h
25 Copyright (c) 2005-2013, Apple Inc. All rights reserved.
29 #define _DARWIN_UNLIMITED_SELECT 1
31 #include <CoreFoundation/CFBase.h>
38 #if DEPLOYMENT_TARGET_WINDOWS && defined(__cplusplus)
42 #define SystemIntegrityCheck(A, B) do {} while (0)
46 #include <objc/objc.h>
48 typedef signed char BOOL
;
56 #define CRSetCrashLogMessage(A) do {} while (0)
57 #define CRSetCrashLogMessage2(A) do {} while (0)
59 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
60 #import <libkern/OSAtomic.h>
64 /* This macro creates some helper functions which are useful in dealing with libdispatch:
65 * __ PREFIX Queue -- manages and returns a singleton serial queue
67 * Use the macro like this:
68 * DISPATCH_HELPER_FUNCTIONS(fh, NSFileHandle)
71 #define DISPATCH_HELPER_FUNCTIONS(PREFIX, QNAME) \
72 static dispatch_queue_t __ ## PREFIX ## Queue(void) { \
73 static volatile dispatch_queue_t __ ## PREFIX ## dq = NULL; \
74 if (!__ ## PREFIX ## dq) { \
75 dispatch_queue_t dq = dispatch_queue_create(# QNAME, NULL); \
76 void * volatile *loc = (void * volatile *)&__ ## PREFIX ## dq; \
77 if (!OSAtomicCompareAndSwapPtrBarrier(NULL, dq, loc)) { \
78 dispatch_release(dq); \
81 return __ ## PREFIX ## dq; \
85 #define LIBAUTO_STUB 1
89 #if DEPLOYMENT_TARGET_MACOSX
90 #include <auto_zone.h>
92 #if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
93 #include <objc/objc-auto.h>
96 #endif // LIBAUTO_STUB
98 #if DEPLOYMENT_TARGET_WINDOWS
99 // Compatibility with boolean.h
100 #if defined(__x86_64__)
101 typedef unsigned int boolean_t
;
103 typedef int boolean_t
;
107 #if DEPLOYMENT_TARGET_LINUX
113 #define strtod_l(a,b,locale) strtod(a,b)
114 #define strtoul_l(a,b,c,locale) strtoul(a,b,c)
115 #define strtol_l(a,b,c,locale) strtol(a,b,c)
116 #define strtoll_l(a,b,c,locale) strtoll(a,b,c)
117 #define strncasecmp_l(a, b, c, d) strncasecmp(a, b, c)
119 #define fprintf_l(a,locale,b,...) fprintf(a, b, __VA_ARGS__)
124 strlcpy(char * dst
, const char * src
, size_t maxlen
) {
125 const size_t srclen
= strlen(src
);
126 if (srclen
< maxlen
) {
127 memcpy(dst
, src
, srclen
+1);
128 } else if (maxlen
!= 0) {
129 memcpy(dst
, src
, maxlen
-1);
130 dst
[maxlen
-1] = '\0';
136 strlcat(char * dst
, const char * src
, size_t maxlen
) {
137 const size_t srclen
= strlen(src
);
138 const size_t dstlen
= strnlen(dst
, maxlen
);
139 if (dstlen
== maxlen
) return maxlen
+srclen
;
140 if (srclen
< maxlen
-dstlen
) {
141 memcpy(dst
+dstlen
, src
, srclen
+1);
143 memcpy(dst
+dstlen
, src
, maxlen
-dstlen
-1);
144 dst
[maxlen
-1] = '\0';
146 return dstlen
+ srclen
;
149 #define issetugid() 0
151 // Implemented in CFPlatform.c
152 bool OSAtomicCompareAndSwapPtr(void *oldp
, void *newp
, void *volatile *dst
);
153 bool OSAtomicCompareAndSwapLong(long oldl
, long newl
, long volatile *dst
);
154 bool OSAtomicCompareAndSwapPtrBarrier(void *oldp
, void *newp
, void *volatile *dst
);
155 bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue
, int64_t __newValue
, volatile int64_t *__theValue
);
157 int32_t OSAtomicDecrement32Barrier(volatile int32_t *dst
);
158 int32_t OSAtomicIncrement32Barrier(volatile int32_t *dst
);
159 int32_t OSAtomicIncrement32(volatile int32_t *theValue
);
160 int32_t OSAtomicDecrement32(volatile int32_t *theValue
);
162 int32_t OSAtomicAdd32( int32_t theAmount
, volatile int32_t *theValue
);
163 int32_t OSAtomicAdd32Barrier( int32_t theAmount
, volatile int32_t *theValue
);
164 bool OSAtomicCompareAndSwap32Barrier( int32_t oldValue
, int32_t newValue
, volatile int32_t *theValue
);
166 void OSMemoryBarrier();
169 CF_INLINE
size_t malloc_size(void *memblock
) {
170 return malloc_usable_size(memblock
);
173 // substitute for dispatch_once
174 typedef pthread_once_t dispatch_once_t
;
175 typedef void (^dispatch_block_t
)(void);
176 void dispatch_once(dispatch_once_t
*predicate
, dispatch_block_t block
);
180 #if DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
182 #define MIN(A,B) ((A) < (B) ? (A) : (B))
186 #define MAX(A,B) ((A) > (B) ? (A) : (B))
190 #define ABS(A) ((A) < 0 ? (-(A)) : (A))
194 #if DEPLOYMENT_TARGET_WINDOWS
196 #define MAXPATHLEN MAX_PATH
198 #undef INVALID_HANDLE_VALUE
200 // Defined for source compatibility
203 #define mode_t uint16_t
205 // This works because things aren't actually exported from the DLL unless they have a __declspec(dllexport) on them... so extern by itself is closest to __private_extern__ on Mac OS
206 #define CF_PRIVATE extern
208 #define __builtin_expect(P1,P2) P1
210 // These are replacements for POSIX calls on Windows, ensuring that the UTF8 parameters are converted to UTF16 before being passed to Windows
211 CF_EXPORT
int _NS_stat(const char *name
, struct _stat
*st
);
212 CF_EXPORT
int _NS_mkdir(const char *name
);
213 CF_EXPORT
int _NS_rmdir(const char *name
);
214 CF_EXPORT
int _NS_chmod(const char *name
, int mode
);
215 CF_EXPORT
int _NS_unlink(const char *name
);
216 CF_EXPORT
char *_NS_getcwd(char *dstbuf
, size_t size
); // Warning: this doesn't support dstbuf as null even though 'getcwd' does
217 CF_EXPORT
char *_NS_getenv(const char *name
);
218 CF_EXPORT
int _NS_rename(const char *oldName
, const char *newName
);
219 CF_EXPORT
int _NS_open(const char *name
, int oflag
, int pmode
= 0);
220 CF_EXPORT
int _NS_chdir(const char *name
);
221 CF_EXPORT
int _NS_mkstemp(char *name
, int bufSize
);
222 CF_EXPORT
int _NS_access(const char *name
, int amode
);
224 #define BOOL WINDOWS_BOOL
226 #define WIN32_LEAN_AND_MEAN
229 #define WINVER 0x0501
233 #define _WIN32_WINNT 0x0501
236 // The order of these includes is important
237 #define FD_SETSIZE 1024
238 #include <winsock2.h>
244 #ifndef HAVE_STRUCT_TIMESPEC
245 #define HAVE_STRUCT_TIMESPEC 1
250 #endif /* HAVE_STRUCT_TIMESPEC */
252 #define __PRETTY_FUNCTION__ __FUNCTION__
254 #define malloc_default_zone() (void *)0
255 #define malloc_zone_from_ptr(a) (void *)0
256 #define malloc_zone_malloc(zone,size) malloc(size)
257 #define malloc_zone_memalign(zone,align,size) malloc(size)
258 #define malloc_zone_calloc(zone,count,size) calloc(count,size)
259 #define bcopy(b1,b2,len) memmove(b2, b1, (size_t)(len))
260 typedef int malloc_zone_t
;
267 #define scalbn(A, B) _scalb(A, B)
269 #define fsync(a) _commit(a)
270 #define malloc_create_zone(a,b) 123
271 #define malloc_set_zone_name(zone,name)
272 #define malloc_zone_realloc(zone,ptr,size) realloc(ptr,size)
273 #define malloc_zone_free(zone,ptr) free(ptr)
275 // implemented in CFInternal.h
276 #define OSSpinLockLock(A) __CFSpinLock(A)
277 #define OSSpinLockUnlock(A) __CFSpinUnlock(A)
279 typedef int32_t OSSpinLock
;
281 #define OS_SPINLOCK_INIT 0
288 CF_INLINE
size_t malloc_size(void *memblock
) {
289 return _msize(memblock
);
292 CF_INLINE
uint64_t mach_absolute_time() {
294 QueryPerformanceCounter(&count
);
295 // mach_absolute_time is unsigned, but this function returns a signed value.
296 return (uint64_t)count
.QuadPart
;
299 CF_INLINE
long long llabs(long long v
) {
300 if (v
< 0) return -v
;
304 #define strtod_l(a,b,locale) strtod(a,b)
305 #define strtoul_l(a,b,c,locale) strtoul(a,b,c)
306 #define strtol_l(a,b,c,locale) strtol(a,b,c)
307 #define strtoll_l(a,b,c,locale) _strtoi64(a,b,c)
308 #define strncasecmp(a, b, c) _strnicmp(a, b, c)
309 #define strncasecmp_l(a, b, c, d) _strnicmp(a, b, c)
310 #define snprintf _snprintf
312 #define fprintf_l(a,locale,b,...) fprintf(a, b, __VA_ARGS__)
315 strlcpy(char * dst
, const char * src
, size_t maxlen
) {
316 const size_t srclen
= strlen(src
);
317 if (srclen
< maxlen
) {
318 memcpy(dst
, src
, srclen
+1);
319 } else if (maxlen
!= 0) {
320 memcpy(dst
, src
, maxlen
-1);
321 dst
[maxlen
-1] = '\0';
327 strlcat(char * dst
, const char * src
, size_t maxlen
) {
328 const size_t srclen
= strlen(src
);
329 const size_t dstlen
= strnlen(dst
, maxlen
);
330 if (dstlen
== maxlen
) return maxlen
+srclen
;
331 if (srclen
< maxlen
-dstlen
) {
332 memcpy(dst
+dstlen
, src
, srclen
+1);
334 memcpy(dst
+dstlen
, src
, maxlen
-dstlen
-1);
335 dst
[maxlen
-1] = '\0';
337 return dstlen
+ srclen
;
340 #define sleep(x) Sleep(1000*x)
342 #define issetugid() 0
344 // CF exports these useful atomic operation functions on Windows
345 CF_EXPORT
bool OSAtomicCompareAndSwapPtr(void *oldp
, void *newp
, void *volatile *dst
);
346 CF_EXPORT
bool OSAtomicCompareAndSwapLong(long oldl
, long newl
, long volatile *dst
);
347 CF_EXPORT
bool OSAtomicCompareAndSwapPtrBarrier(void *oldp
, void *newp
, void *volatile *dst
);
349 CF_EXPORT
int32_t OSAtomicDecrement32Barrier(volatile int32_t *dst
);
350 CF_EXPORT
int32_t OSAtomicIncrement32Barrier(volatile int32_t *dst
);
351 CF_EXPORT
int32_t OSAtomicIncrement32(volatile int32_t *theValue
);
352 CF_EXPORT
int32_t OSAtomicDecrement32(volatile int32_t *theValue
);
354 CF_EXPORT
int32_t OSAtomicAdd32( int32_t theAmount
, volatile int32_t *theValue
);
355 CF_EXPORT
int32_t OSAtomicAdd32Barrier( int32_t theAmount
, volatile int32_t *theValue
);
356 CF_EXPORT
bool OSAtomicCompareAndSwap32Barrier( int32_t oldValue
, int32_t newValue
, volatile int32_t *theValue
);
359 CF_EXPORT bool OSAtomicCompareAndSwap64( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue );
360 CF_EXPORT bool OSAtomicCompareAndSwap64Barrier( int64_t __oldValue, int64_t __newValue, volatile int64_t *__theValue );
362 CF_EXPORT int64_t OSAtomicAdd64( int64_t __theAmount, volatile int64_t *__theValue );
363 CF_EXPORT int64_t OSAtomicAdd64Barrier( int64_t __theAmount, volatile int64_t *__theValue );
366 //#ifndef NTDDI_VERSION
367 //#define NTDDI_VERSION NTDDI_WINXP
376 #if !defined(CF_PRIVATE)
377 #define CF_PRIVATE __attribute__((__visibility__("hidden")))
380 #if DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_WINDOWS
384 CF_INLINE
int flsl( long mask
) {
386 while (mask
!= 0) mask
= (unsigned long)mask
>> 1, idx
++;
390 CF_INLINE
int popcountll(long long x
) {
394 x
&= x
- 1; // reset LS1B
399 CF_PRIVATE
int asprintf(char **ret
, const char *format
, ...);
407 /* Stubs for functions in libauto. */
409 enum {OBJC_GENERATIONAL
= (1 << 0)};
412 OBJC_RATIO_COLLECTION
= (0 << 0),
413 OBJC_GENERATIONAL_COLLECTION
= (1 << 0),
414 OBJC_FULL_COLLECTION
= (2 << 0),
415 OBJC_EXHAUSTIVE_COLLECTION
= (3 << 0),
416 OBJC_COLLECT_IF_NEEDED
= (1 << 3),
417 OBJC_WAIT_UNTIL_DONE
= (1 << 4),
422 AUTO_TYPE_UNKNOWN
= -1,
423 AUTO_UNSCANNED
= (1 << 0),
424 AUTO_OBJECT
= (1 << 1),
425 AUTO_POINTERS_ONLY
= (1 << 2),
426 AUTO_MEMORY_SCANNED
= !AUTO_UNSCANNED
,
427 AUTO_MEMORY_UNSCANNED
= AUTO_UNSCANNED
,
428 AUTO_MEMORY_ALL_POINTERS
= AUTO_POINTERS_ONLY
,
429 AUTO_MEMORY_ALL_WEAK_POINTERS
= (AUTO_UNSCANNED
| AUTO_POINTERS_ONLY
),
430 AUTO_OBJECT_SCANNED
= AUTO_OBJECT
,
431 AUTO_OBJECT_UNSCANNED
= AUTO_OBJECT
| AUTO_UNSCANNED
,
432 AUTO_OBJECT_ALL_POINTERS
= AUTO_OBJECT
| AUTO_POINTERS_ONLY
434 typedef unsigned long auto_memory_type_t
;
435 typedef struct _auto_zone_t auto_zone_t
;
436 typedef struct auto_weak_callback_block
{
437 struct auto_weak_callback_block
*next
;
438 void (*callback_function
)(void *arg1
, void *arg2
);
441 } auto_weak_callback_block_t
;
443 CF_INLINE
void *objc_memmove_collectable(void *a
, const void *b
, size_t c
) { return memmove(a
, b
, c
); }
444 CF_INLINE
void *objc_collectableZone(void) { return 0; }
446 CF_INLINE
void *auto_zone_allocate_object(void *zone
, size_t size
, auto_memory_type_t type
, int rc
, int clear
) { return 0; }
447 CF_INLINE
const void *auto_zone_base_pointer(void *zone
, const void *ptr
) { return 0; }
448 CF_INLINE
void auto_zone_set_scan_exactly(void *zone
, void *ptr
) {}
449 CF_INLINE
void auto_zone_retain(void *zone
, void *ptr
) {}
450 CF_INLINE
unsigned int auto_zone_release(void *zone
, void *ptr
) { return 0; }
451 CF_INLINE
unsigned int auto_zone_retain_count(void *zone
, const void *ptr
) { return 0; }
452 CF_INLINE
void auto_zone_set_unscanned(void *zone
, void *ptr
) {}
453 CF_INLINE
void auto_zone_set_nofinalize(void *zone
, void *ptr
) {}
454 CF_INLINE
int auto_zone_is_finalized(void *zone
, const void *ptr
) { return 0; }
455 CF_INLINE
size_t auto_zone_size(void *zone
, const void *ptr
) { return 0; }
456 CF_INLINE
void auto_register_weak_reference(void *zone
, const void *referent
, void **referrer
, uintptr_t *counter
, void **listHead
, void **listElement
) {}
457 CF_INLINE
void auto_unregister_weak_reference(void *zone
, const void *referent
, void **referrer
) {}
458 CF_INLINE
int auto_zone_is_valid_pointer(void *zone
, const void *ptr
) { return 0; }
459 CF_INLINE BOOL
objc_isAuto(id object
) { return 0; }
460 CF_INLINE
void* auto_read_weak_reference(void *zone
, void **referrer
) { void *result
= *referrer
; return result
; }
461 CF_INLINE
void auto_assign_weak_reference(void *zone
, const void *value
, const void **location
, auto_weak_callback_block_t
*block
) { *location
= (void *)value
; }
462 CF_INLINE auto_memory_type_t
auto_zone_get_layout_type(void *zone
, void *ptr
) { return AUTO_UNSCANNED
; }
463 CF_INLINE
int auto_zone_set_write_barrier(void *zone
, const void *dest
, const void *new_value
) { return false; }
465 CF_INLINE
void objc_assertRegisteredThreadWithCollector(void) {}
466 CF_INLINE
void objc_registerThreadWithCollector(void) {}
468 CF_INLINE
uintptr_t _object_getExternalHash(id obj
) {
469 return (uintptr_t)obj
;
474 CF_INLINE BOOL
objc_atomicCompareAndSwapPtr(id predicate
, id replacement
, volatile id
*objectLocation
)
475 { return OSAtomicCompareAndSwapPtr((void *)predicate
, (void *)replacement
, (void * volatile *)objectLocation
); }
477 CF_INLINE BOOL
objc_atomicCompareAndSwapPtrBarrier(id predicate
, id replacement
, volatile id
*objectLocation
)
478 { return OSAtomicCompareAndSwapPtrBarrier((void *)predicate
, (void *)replacement
, (void * volatile *)objectLocation
); }
480 CF_INLINE BOOL
objc_atomicCompareAndSwapGlobal(id predicate
, id replacement
, volatile id
*objectLocation
)
481 { return OSAtomicCompareAndSwapPtr((void *)predicate
, (void *)replacement
, (void * volatile *)objectLocation
); }
483 CF_INLINE BOOL
objc_atomicCompareAndSwapGlobalBarrier(id predicate
, id replacement
, volatile id
*objectLocation
)
484 { return OSAtomicCompareAndSwapPtrBarrier((void *)predicate
, (void *)replacement
, (void * volatile *)objectLocation
); }
486 CF_INLINE BOOL
objc_atomicCompareAndSwapInstanceVariable(id predicate
, id replacement
, volatile id
*objectLocation
)
487 { return OSAtomicCompareAndSwapPtr((void *)predicate
, (void *)replacement
, (void * volatile *)objectLocation
); }
489 CF_INLINE BOOL
objc_atomicCompareAndSwapInstanceVariableBarrier(id predicate
, id replacement
, volatile id
*objectLocation
)
490 { return OSAtomicCompareAndSwapPtrBarrier((void *)predicate
, (void *)replacement
, (void * volatile *)objectLocation
); }
492 CF_INLINE id
objc_assign_strongCast(id val
, id
*dest
)
493 { return (*dest
= val
); }
495 CF_INLINE id
objc_assign_global(id val
, id
*dest
)
496 { return (*dest
= val
); }
498 CF_INLINE id
objc_assign_ivar(id val
, id dest
, ptrdiff_t offset
)
499 { return (*(id
*)((char *)dest
+offset
) = val
); }
501 //CF_INLINE void *objc_memmove_collectable(void *dst, const void *src, size_t size) { return memmove(dst, src, size); }
503 CF_INLINE id
objc_read_weak(id
*location
)
504 { return *location
; }
506 CF_INLINE id
objc_assign_weak(id value
, id
*location
)
507 { return (*location
= value
); }
510 CF_INLINE
void objc_finalizeOnMainThread(Class cls
) { }
511 CF_INLINE BOOL
objc_is_finalized(void *ptr
) { return NO
; }
512 CF_INLINE
void objc_clear_stack(unsigned long options
) { }
514 CF_INLINE BOOL
objc_collectingEnabled(void) { return NO
; }
515 CF_INLINE
void objc_start_collector_thread(void) { }
517 CF_INLINE
void objc_collect(unsigned long options
) { }
521 #if DEPLOYMENT_TARGET_WINDOWS && defined(__cplusplus)