]> git.saurik.com Git - apple/cf.git/blame - CFBase.c
CF-476.18.tar.gz
[apple/cf.git] / CFBase.c
CommitLineData
9ce05555 1/*
bd5b749c 2 * Copyright (c) 2008 Apple Inc. All rights reserved.
9ce05555
A
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
9ce05555
A
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/* CFBase.c
24 Copyright 1998-2002, Apple, Inc. All rights reserved.
25 Responsibility: Christopher Kane
26*/
27
28#include <CoreFoundation/CFBase.h>
29#include "CFInternal.h"
bd5b749c
A
30#include <pthread.h>
31#include <malloc/malloc.h>
32extern size_t malloc_good_size(size_t size);
33#include <mach/mach.h>
34#include <dlfcn.h>
9ce05555
A
35#include <stdlib.h>
36#include <string.h>
37
d8925383
A
38#if defined(__CYGWIN32__) || defined (D__CYGWIN_)
39#error CoreFoundation is currently built with the Microsoft C Runtime, which is incompatible with the Cygwin DLL. You must either use the -mno-cygwin flag, or complete a port of CF to the Cygwin environment.
40#endif
9ce05555
A
41
42// -------- -------- -------- -------- -------- -------- -------- --------
43
9ce05555
A
44// CFAllocator structure must match struct _malloc_zone_t!
45// The first two reserved fields in struct _malloc_zone_t are for us with CFRuntimeBase
9ce05555
A
46struct __CFAllocator {
47 CFRuntimeBase _base;
9ce05555
A
48 size_t (*size)(struct _malloc_zone_t *zone, const void *ptr); /* returns the size of a block or 0 if not in this zone; must be fast, especially for negative answers */
49 void *(*malloc)(struct _malloc_zone_t *zone, size_t size);
50 void *(*calloc)(struct _malloc_zone_t *zone, size_t num_items, size_t size); /* same as malloc, but block returned is set to zero */
51 void *(*valloc)(struct _malloc_zone_t *zone, size_t size); /* same as malloc, but block returned is set to zero and is guaranteed to be page aligned */
52 void (*free)(struct _malloc_zone_t *zone, void *ptr);
53 void *(*realloc)(struct _malloc_zone_t *zone, void *ptr, size_t size);
54 void (*destroy)(struct _malloc_zone_t *zone); /* zone is destroyed and all memory reclaimed */
55 const char *zone_name;
56 unsigned (*batch_malloc)(struct _malloc_zone_t *zone, size_t size, void **results, unsigned num_requested); /* given a size, returns pointers capable of holding that size; returns the number of pointers allocated (maybe 0 or less than num_requested) */
57 void (*batch_free)(struct _malloc_zone_t *zone, void **to_be_freed, unsigned num_to_be_freed); /* frees all the pointers in to_be_freed; note that to_be_freed may be overwritten during the process */
58 struct malloc_introspection_t *introspect;
59 void *reserved5;
9ce05555
A
60 CFAllocatorRef _allocator;
61 CFAllocatorContext _context;
62};
63
64CF_INLINE CFAllocatorRetainCallBack __CFAllocatorGetRetainFunction(const CFAllocatorContext *context) {
65 CFAllocatorRetainCallBack retval = NULL;
66 retval = context->retain;
67 return retval;
68}
69
70CF_INLINE CFAllocatorReleaseCallBack __CFAllocatorGetReleaseFunction(const CFAllocatorContext *context) {
71 CFAllocatorReleaseCallBack retval = NULL;
72 retval = context->release;
73 return retval;
74}
75
76CF_INLINE CFAllocatorCopyDescriptionCallBack __CFAllocatorGetCopyDescriptionFunction(const CFAllocatorContext *context) {
77 CFAllocatorCopyDescriptionCallBack retval = NULL;
78 retval = context->copyDescription;
79 return retval;
80}
81
82CF_INLINE CFAllocatorAllocateCallBack __CFAllocatorGetAllocateFunction(const CFAllocatorContext *context) {
83 CFAllocatorAllocateCallBack retval = NULL;
84 retval = context->allocate;
85 return retval;
86}
87
88CF_INLINE CFAllocatorReallocateCallBack __CFAllocatorGetReallocateFunction(const CFAllocatorContext *context) {
89 CFAllocatorReallocateCallBack retval = NULL;
90 retval = context->reallocate;
91 return retval;
92}
93
94CF_INLINE CFAllocatorDeallocateCallBack __CFAllocatorGetDeallocateFunction(const CFAllocatorContext *context) {
95 CFAllocatorDeallocateCallBack retval = NULL;
96 retval = context->deallocate;
97 return retval;
98}
99
100CF_INLINE CFAllocatorPreferredSizeCallBack __CFAllocatorGetPreferredSizeFunction(const CFAllocatorContext *context) {
101 CFAllocatorPreferredSizeCallBack retval = NULL;
102 retval = context->preferredSize;
103 return retval;
104}
105
bd5b749c 106#if DEPLOYMENT_TARGET_MACOSX
9ce05555
A
107
108__private_extern__ void __CFAllocatorDeallocate(CFTypeRef cf);
109
110static kern_return_t __CFAllocatorZoneIntrospectNoOp(void) {
111 return 0;
112}
113
114static boolean_t __CFAllocatorZoneIntrospectTrue(void) {
115 return 1;
116}
117
118static size_t __CFAllocatorCustomSize(malloc_zone_t *zone, const void *ptr) {
119 return 0;
120
121 // The only way to implement this with a version 0 allocator would be
122 // for CFAllocator to keep track of all blocks allocated itself, which
123 // could be done, but would be bad for performance, so we don't do it.
124 // size_t (*size)(struct _malloc_zone_t *zone, const void *ptr);
125 /* returns the size of a block or 0 if not in this zone;
126 * must be fast, especially for negative answers */
127}
128
129static void *__CFAllocatorCustomMalloc(malloc_zone_t *zone, size_t size) {
130 CFAllocatorRef allocator = (CFAllocatorRef)zone;
131 return CFAllocatorAllocate(allocator, size, 0);
132}
133
134static void *__CFAllocatorCustomCalloc(malloc_zone_t *zone, size_t num_items, size_t size) {
135 CFAllocatorRef allocator = (CFAllocatorRef)zone;
136 void *newptr = CFAllocatorAllocate(allocator, size, 0);
137 if (newptr) memset(newptr, 0, size);
138 return newptr;
139}
140
141static void *__CFAllocatorCustomValloc(malloc_zone_t *zone, size_t size) {
142 CFAllocatorRef allocator = (CFAllocatorRef)zone;
143 void *newptr = CFAllocatorAllocate(allocator, size + vm_page_size, 0);
bd5b749c 144 newptr = (void *)round_page((uintptr_t)newptr);
9ce05555
A
145 return newptr;
146}
147
148static void __CFAllocatorCustomFree(malloc_zone_t *zone, void *ptr) {
149 CFAllocatorRef allocator = (CFAllocatorRef)zone;
150 CFAllocatorDeallocate(allocator, ptr);
151}
152
153static void *__CFAllocatorCustomRealloc(malloc_zone_t *zone, void *ptr, size_t size) {
154 CFAllocatorRef allocator = (CFAllocatorRef)zone;
155 return CFAllocatorReallocate(allocator, ptr, size, 0);
156}
157
158static void __CFAllocatorCustomDestroy(malloc_zone_t *zone) {
159 CFAllocatorRef allocator = (CFAllocatorRef)zone;
160 // !!! we do it, and caller of malloc_destroy_zone() assumes
161 // COMPLETE responsibility for the result; NO Apple library
162 // code should be modified as a result of discovering that
163 // some activity results in inconveniences to developers
164 // trying to use malloc_destroy_zone() with a CFAllocatorRef;
165 // that's just too bad for them.
166 __CFAllocatorDeallocate(allocator);
167}
168
169static size_t __CFAllocatorCustomGoodSize(malloc_zone_t *zone, size_t size) {
170 CFAllocatorRef allocator = (CFAllocatorRef)zone;
171 return CFAllocatorGetPreferredSizeForSize(allocator, size, 0);
172}
173
174static struct malloc_introspection_t __CFAllocatorZoneIntrospect = {
175 (void *)__CFAllocatorZoneIntrospectNoOp,
176 (void *)__CFAllocatorCustomGoodSize,
177 (void *)__CFAllocatorZoneIntrospectTrue,
178 (void *)__CFAllocatorZoneIntrospectNoOp,
179 (void *)__CFAllocatorZoneIntrospectNoOp,
180 (void *)__CFAllocatorZoneIntrospectNoOp,
181 (void *)__CFAllocatorZoneIntrospectNoOp,
182 (void *)__CFAllocatorZoneIntrospectNoOp
183};
184
185static size_t __CFAllocatorNullSize(malloc_zone_t *zone, const void *ptr) {
186 return 0;
187}
188
189static void * __CFAllocatorNullMalloc(malloc_zone_t *zone, size_t size) {
190 return NULL;
191}
192
193static void * __CFAllocatorNullCalloc(malloc_zone_t *zone, size_t num_items, size_t size) {
194 return NULL;
195}
196
197static void * __CFAllocatorNullValloc(malloc_zone_t *zone, size_t size) {
198 return NULL;
199}
200
201static void __CFAllocatorNullFree(malloc_zone_t *zone, void *ptr) {
202}
203
204static void * __CFAllocatorNullRealloc(malloc_zone_t *zone, void *ptr, size_t size) {
205 return NULL;
206}
207
208static void __CFAllocatorNullDestroy(malloc_zone_t *zone) {
209}
210
211static size_t __CFAllocatorNullGoodSize(malloc_zone_t *zone, size_t size) {
212 return size;
213}
214
215static struct malloc_introspection_t __CFAllocatorNullZoneIntrospect = {
216 (void *)__CFAllocatorZoneIntrospectNoOp,
217 (void *)__CFAllocatorNullGoodSize,
218 (void *)__CFAllocatorZoneIntrospectTrue,
219 (void *)__CFAllocatorZoneIntrospectNoOp,
220 (void *)__CFAllocatorZoneIntrospectNoOp,
221 (void *)__CFAllocatorZoneIntrospectNoOp,
222 (void *)__CFAllocatorZoneIntrospectNoOp,
223 (void *)__CFAllocatorZoneIntrospectNoOp
224};
225
226static void *__CFAllocatorSystemAllocate(CFIndex size, CFOptionFlags hint, void *info) {
227 return malloc_zone_malloc(info, size);
228}
229
230static void *__CFAllocatorSystemReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info) {
231 return malloc_zone_realloc(info, ptr, newsize);
232}
233
234static void __CFAllocatorSystemDeallocate(void *ptr, void *info) {
d8925383
A
235#if defined(DEBUG)
236 size_t size = malloc_size(ptr);
237 if (size) memset(ptr, 0xCC, size);
238#endif
9ce05555
A
239 malloc_zone_free(info, ptr);
240}
241
242#endif
243
bd5b749c 244#if defined(__WIN32__) || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
9ce05555
A
245static void *__CFAllocatorSystemAllocate(CFIndex size, CFOptionFlags hint, void *info) {
246 return malloc(size);
247}
248
249static void *__CFAllocatorSystemReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info) {
250 return realloc(ptr, newsize);
251}
252
253static void __CFAllocatorSystemDeallocate(void *ptr, void *info) {
254 free(ptr);
255}
256#endif
257
258static void *__CFAllocatorNullAllocate(CFIndex size, CFOptionFlags hint, void *info) {
259 return NULL;
260}
261
262static void *__CFAllocatorNullReallocate(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info) {
263 return NULL;
264}
265
bd5b749c
A
266#if defined (__cplusplus)
267static void * __CFAllocatorCPPMalloc(CFIndex allocSize, CFOptionFlags hint, void *info)
268{
269 return malloc(allocSize);
270}
271static void * __CFAllocatorCPPReAlloc(void *ptr, CFIndex newsize, CFOptionFlags hint, void *info)
272{
273 return realloc(ptr, newsize);
274}
275static void __CFAllocatorCPPFree(void *ptr, void *info)
276{
277 free(ptr);
278}
279#endif // C++
280
281
9ce05555 282static struct __CFAllocator __kCFAllocatorMalloc = {
bd5b749c
A
283 INIT_CFRUNTIME_BASE(),
284#if DEPLOYMENT_TARGET_MACOSX
9ce05555
A
285 __CFAllocatorCustomSize,
286 __CFAllocatorCustomMalloc,
287 __CFAllocatorCustomCalloc,
288 __CFAllocatorCustomValloc,
289 __CFAllocatorCustomFree,
290 __CFAllocatorCustomRealloc,
291 __CFAllocatorNullDestroy,
292 "kCFAllocatorMalloc",
293 NULL,
294 NULL,
295 &__CFAllocatorZoneIntrospect,
296 NULL,
297#endif
298 NULL, // _allocator
299 // Using the malloc functions directly is a total cheat, but works (in C)
300 // because the function signatures match in their common prefix of arguments.
301 // This saves us one hop through an adaptor function.
bd5b749c
A
302#if !defined (__cplusplus)
303 {0, NULL, NULL, NULL, NULL, (void *)malloc, (void *)realloc, (void *)free, NULL}
304#else
305 {0, NULL, NULL, NULL, NULL, __CFAllocatorCPPMalloc,__CFAllocatorCPPReAlloc, __CFAllocatorCPPFree, NULL}
306#endif // __cplusplus
9ce05555
A
307};
308
d8925383 309static struct __CFAllocator __kCFAllocatorMallocZone = {
bd5b749c
A
310 INIT_CFRUNTIME_BASE(),
311#if DEPLOYMENT_TARGET_MACOSX
d8925383
A
312 __CFAllocatorCustomSize,
313 __CFAllocatorCustomMalloc,
314 __CFAllocatorCustomCalloc,
315 __CFAllocatorCustomValloc,
316 __CFAllocatorCustomFree,
317 __CFAllocatorCustomRealloc,
318 __CFAllocatorNullDestroy,
319 "kCFAllocatorMallocZone",
320 NULL,
321 NULL,
322 &__CFAllocatorZoneIntrospect,
323 NULL,
324#endif
325 NULL, // _allocator
326 {0, NULL, NULL, NULL, NULL, __CFAllocatorSystemAllocate, __CFAllocatorSystemReallocate, __CFAllocatorSystemDeallocate, NULL}
327};
328
9ce05555 329static struct __CFAllocator __kCFAllocatorSystemDefault = {
bd5b749c
A
330 INIT_CFRUNTIME_BASE(),
331#if DEPLOYMENT_TARGET_MACOSX
9ce05555
A
332 __CFAllocatorCustomSize,
333 __CFAllocatorCustomMalloc,
334 __CFAllocatorCustomCalloc,
335 __CFAllocatorCustomValloc,
336 __CFAllocatorCustomFree,
337 __CFAllocatorCustomRealloc,
338 __CFAllocatorNullDestroy,
339 "kCFAllocatorSystemDefault",
340 NULL,
341 NULL,
342 &__CFAllocatorZoneIntrospect,
343 NULL,
344#endif
345 NULL, // _allocator
346 {0, NULL, NULL, NULL, NULL, __CFAllocatorSystemAllocate, __CFAllocatorSystemReallocate, __CFAllocatorSystemDeallocate, NULL}
347};
348
349static struct __CFAllocator __kCFAllocatorNull = {
bd5b749c
A
350 INIT_CFRUNTIME_BASE(),
351#if DEPLOYMENT_TARGET_MACOSX
9ce05555
A
352 __CFAllocatorNullSize,
353 __CFAllocatorNullMalloc,
354 __CFAllocatorNullCalloc,
355 __CFAllocatorNullValloc,
356 __CFAllocatorNullFree,
357 __CFAllocatorNullRealloc,
358 __CFAllocatorNullDestroy,
359 "kCFAllocatorNull",
360 NULL,
361 NULL,
362 &__CFAllocatorNullZoneIntrospect,
363 NULL,
364#endif
365 NULL, // _allocator
366 {0, NULL, NULL, NULL, NULL, __CFAllocatorNullAllocate, __CFAllocatorNullReallocate, NULL, NULL}
367};
368
369const CFAllocatorRef kCFAllocatorDefault = NULL;
370const CFAllocatorRef kCFAllocatorSystemDefault = &__kCFAllocatorSystemDefault;
371const CFAllocatorRef kCFAllocatorMalloc = &__kCFAllocatorMalloc;
d8925383 372const CFAllocatorRef kCFAllocatorMallocZone = &__kCFAllocatorMallocZone;
9ce05555 373const CFAllocatorRef kCFAllocatorNull = &__kCFAllocatorNull;
bd5b749c 374const CFAllocatorRef kCFAllocatorUseContext = (CFAllocatorRef)0x0257;
d8925383 375
9ce05555 376static CFStringRef __CFAllocatorCopyDescription(CFTypeRef cf) {
bd5b749c 377 CFAllocatorRef self = (CFAllocatorRef)cf;
9ce05555 378 CFAllocatorRef allocator = (kCFAllocatorUseContext == self->_allocator) ? self : self->_allocator;
bd5b749c 379 return CFStringCreateWithFormat(allocator, NULL, CFSTR("<CFAllocator %p [%p]>{info = %p}"), cf, allocator, self->_context.info);
9ce05555
A
380// CF: should use copyDescription function here to describe info field
381// remember to release value returned from copydescr function when this happens
382}
383
384__private_extern__ CFAllocatorRef __CFAllocatorGetAllocator(CFTypeRef cf) {
bd5b749c 385 CFAllocatorRef allocator = (CFAllocatorRef)cf;
9ce05555
A
386 return (kCFAllocatorUseContext == allocator->_allocator) ? allocator : allocator->_allocator;
387}
388
389__private_extern__ void __CFAllocatorDeallocate(CFTypeRef cf) {
bd5b749c 390 CFAllocatorRef self = (CFAllocatorRef)cf;
9ce05555
A
391 CFAllocatorRef allocator = self->_allocator;
392 CFAllocatorReleaseCallBack releaseFunc = __CFAllocatorGetReleaseFunction(&self->_context);
393 if (kCFAllocatorUseContext == allocator) {
394 /* Rather a chicken and egg problem here, so we do things
395 in the reverse order from what was done at create time. */
396 CFAllocatorDeallocateCallBack deallocateFunc = __CFAllocatorGetDeallocateFunction(&self->_context);
397 void *info = self->_context.info;
398 if (NULL != deallocateFunc) {
399 INVOKE_CALLBACK2(deallocateFunc, (void *)self, info);
400 }
401 if (NULL != releaseFunc) {
402 INVOKE_CALLBACK1(releaseFunc, info);
403 }
404 } else {
405 if (NULL != releaseFunc) {
406 INVOKE_CALLBACK1(releaseFunc, self->_context.info);
407 }
bd5b749c 408 _CFAllocatorDeallocateGC(allocator, (void *)self);
9ce05555
A
409 }
410}
411
412static CFTypeID __kCFAllocatorTypeID = _kCFRuntimeNotATypeID;
413
414static const CFRuntimeClass __CFAllocatorClass = {
415 0,
416 "CFAllocator",
417 NULL, // init
418 NULL, // copy
419 __CFAllocatorDeallocate,
420 NULL, // equal
421 NULL, // hash
422 NULL, //
423 __CFAllocatorCopyDescription
424};
425
426__private_extern__ void __CFAllocatorInitialize(void) {
427 __kCFAllocatorTypeID = _CFRuntimeRegisterClass(&__CFAllocatorClass);
428
429 _CFRuntimeSetInstanceTypeID(&__kCFAllocatorSystemDefault, __kCFAllocatorTypeID);
bd5b749c
A
430 __kCFAllocatorSystemDefault._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
431#if DEPLOYMENT_TARGET_MACOSX
d8925383 432 __kCFAllocatorSystemDefault._context.info = (CF_USING_COLLECTABLE_MEMORY ? __CFCollectableZone : malloc_default_zone());
bd5b749c 433 memset(malloc_default_zone(), 0, 2 * sizeof(void *));
9ce05555
A
434#endif
435 __kCFAllocatorSystemDefault._allocator = kCFAllocatorSystemDefault;
9ce05555
A
436
437 _CFRuntimeSetInstanceTypeID(&__kCFAllocatorMalloc, __kCFAllocatorTypeID);
bd5b749c 438 __kCFAllocatorMalloc._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
9ce05555
A
439 __kCFAllocatorMalloc._allocator = kCFAllocatorSystemDefault;
440
bd5b749c
A
441#if DEPLOYMENT_TARGET_MACOSX
442 _CFRuntimeSetInstanceTypeID(&__kCFAllocatorMallocZone, __kCFAllocatorTypeID);
443 __kCFAllocatorMallocZone._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
d8925383
A
444 __kCFAllocatorMallocZone._allocator = kCFAllocatorSystemDefault;
445 __kCFAllocatorMallocZone._context.info = malloc_default_zone();
bd5b749c 446#endif //__MACH__
d8925383 447
9ce05555 448 _CFRuntimeSetInstanceTypeID(&__kCFAllocatorNull, __kCFAllocatorTypeID);
bd5b749c 449 __kCFAllocatorNull._base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
9ce05555
A
450 __kCFAllocatorNull._allocator = kCFAllocatorSystemDefault;
451
452}
453
454CFTypeID CFAllocatorGetTypeID(void) {
455 return __kCFAllocatorTypeID;
456}
457
458CFAllocatorRef CFAllocatorGetDefault(void) {
bd5b749c 459 CFAllocatorRef allocator = (CFAllocatorRef)__CFGetThreadSpecificData_inline()->_allocator;
9ce05555
A
460 if (NULL == allocator) {
461 allocator = kCFAllocatorSystemDefault;
462 }
463 return allocator;
464}
465
466void CFAllocatorSetDefault(CFAllocatorRef allocator) {
bd5b749c 467 CFAllocatorRef current = (CFAllocatorRef)__CFGetThreadSpecificData_inline()->_allocator;
9ce05555
A
468#if defined(DEBUG)
469 if (NULL != allocator) {
470 __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
471 }
472#endif
bd5b749c
A
473#if DEPLOYMENT_TARGET_MACOSX
474 if (allocator && allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) { // malloc_zone_t *
9ce05555
A
475 return; // require allocator to this function to be an allocator
476 }
477#endif
478 if (NULL != allocator && allocator != current) {
479 if (current) CFRelease(current);
480 CFRetain(allocator);
481 // We retain an extra time so that anything set as the default
482 // allocator never goes away.
483 CFRetain(allocator);
484 __CFGetThreadSpecificData_inline()->_allocator = (void *)allocator;
485 }
486}
487
d8925383
A
488static CFAllocatorRef __CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorContext *context) {
489 struct __CFAllocator *memory = NULL;
9ce05555
A
490 CFAllocatorRetainCallBack retainFunc;
491 CFAllocatorAllocateCallBack allocateFunc;
492 void *retainedInfo;
bd5b749c
A
493#if DEPLOYMENT_TARGET_MACOSX
494 if (allocator && kCFAllocatorUseContext != allocator && allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) { // malloc_zone_t *
9ce05555
A
495 return NULL; // require allocator to this function to be an allocator
496 }
497#endif
498 retainFunc = context->retain;
499 FAULT_CALLBACK((void **)&retainFunc);
500 allocateFunc = context->allocate;
501 FAULT_CALLBACK((void **)&allocateFunc);
502 if (NULL != retainFunc) {
503 retainedInfo = (void *)INVOKE_CALLBACK1(retainFunc, context->info);
504 } else {
505 retainedInfo = context->info;
506 }
507 // We don't use _CFRuntimeCreateInstance()
508 if (kCFAllocatorUseContext == allocator) {
d8925383
A
509 memory = NULL;
510 if (allocateFunc) {
bd5b749c 511 memory = (struct __CFAllocator *)INVOKE_CALLBACK3(allocateFunc, sizeof(struct __CFAllocator), 0, retainedInfo);
d8925383 512 }
9ce05555
A
513 if (NULL == memory) {
514 return NULL;
515 }
516 } else {
517 allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
bd5b749c 518 memory = (struct __CFAllocator *)CFAllocatorAllocate(allocator, sizeof(struct __CFAllocator), __kCFAllocatorGCObjectMemory);
9ce05555
A
519 if (__CFOASafe) __CFSetLastAllocationEventName(memory, "CFAllocator");
520 if (NULL == memory) {
521 return NULL;
522 }
523 }
bd5b749c
A
524 memory->_base._cfisa = 0;
525#if __LP64__
9ce05555 526 memory->_base._rc = 1;
bd5b749c
A
527#else
528 memory->_base._cfinfo[CF_RC_BITS] = 1;
529#endif
530 memory->_base._cfinfo[CF_INFO_BITS] = 0;
9ce05555 531 _CFRuntimeSetInstanceTypeID(memory, __kCFAllocatorTypeID);
bd5b749c
A
532 memory->_base._cfisa = __CFISAForTypeID(__kCFAllocatorTypeID);
533#if DEPLOYMENT_TARGET_MACOSX
9ce05555
A
534 memory->size = __CFAllocatorCustomSize;
535 memory->malloc = __CFAllocatorCustomMalloc;
536 memory->calloc = __CFAllocatorCustomCalloc;
537 memory->valloc = __CFAllocatorCustomValloc;
538 memory->free = __CFAllocatorCustomFree;
539 memory->realloc = __CFAllocatorCustomRealloc;
540 memory->destroy = __CFAllocatorCustomDestroy;
541 memory->zone_name = "Custom CFAllocator";
542 memory->batch_malloc = NULL;
543 memory->batch_free = NULL;
544 memory->introspect = &__CFAllocatorZoneIntrospect;
545 memory->reserved5 = NULL;
546#endif
547 memory->_allocator = allocator;
548 memory->_context.version = context->version;
549 memory->_context.info = retainedInfo;
550 memory->_context.retain = retainFunc;
551 memory->_context.release = context->release;
552 FAULT_CALLBACK((void **)&(memory->_context.release));
553 memory->_context.copyDescription = context->copyDescription;
554 FAULT_CALLBACK((void **)&(memory->_context.copyDescription));
555 memory->_context.allocate = allocateFunc;
556 memory->_context.reallocate = context->reallocate;
557 FAULT_CALLBACK((void **)&(memory->_context.reallocate));
558 memory->_context.deallocate = context->deallocate;
559 FAULT_CALLBACK((void **)&(memory->_context.deallocate));
560 memory->_context.preferredSize = context->preferredSize;
561 FAULT_CALLBACK((void **)&(memory->_context.preferredSize));
562
563 return memory;
564}
565
d8925383
A
566CFAllocatorRef CFAllocatorCreate(CFAllocatorRef allocator, CFAllocatorContext *context) {
567 CFAssert1(!CF_USING_COLLECTABLE_MEMORY, __kCFLogAssertion, "%s(): Shouldn't be called when GC is enabled!", __PRETTY_FUNCTION__);
568#if defined(DEBUG)
569 if (CF_USING_COLLECTABLE_MEMORY)
570 HALT;
571#endif
572 return __CFAllocatorCreate(allocator, context);
573}
574
575CFAllocatorRef _CFAllocatorCreateGC(CFAllocatorRef allocator, CFAllocatorContext *context) {
576 return __CFAllocatorCreate(allocator, context);
577}
578
9ce05555
A
579void *CFAllocatorAllocate(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint) {
580 CFAllocatorAllocateCallBack allocateFunc;
d8925383 581 void *newptr = NULL;
9ce05555 582 allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
bd5b749c
A
583#if (DEPLOYMENT_TARGET_MACOSX) && defined(DEBUG)
584 if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
9ce05555
A
585 __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
586 }
587#else
588 __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
589#endif
590 if (0 == size) return NULL;
bd5b749c
A
591#if DEPLOYMENT_TARGET_MACOSX
592 if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) { // malloc_zone_t *
9ce05555
A
593 return malloc_zone_malloc((malloc_zone_t *)allocator, size);
594 }
595#endif
d8925383 596 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
bd5b749c 597 newptr = auto_zone_allocate_object((auto_zone_t*)allocator->_context.info, size, CF_GET_GC_MEMORY_TYPE(hint), true, false);
d8925383
A
598 } else {
599 newptr = NULL;
600 allocateFunc = __CFAllocatorGetAllocateFunction(&allocator->_context);
601 if (allocateFunc) {
602 newptr = (void *)INVOKE_CALLBACK3(allocateFunc, size, hint, allocator->_context.info);
603 }
604 }
9ce05555
A
605 return newptr;
606}
607
608void *CFAllocatorReallocate(CFAllocatorRef allocator, void *ptr, CFIndex newsize, CFOptionFlags hint) {
609 CFAllocatorAllocateCallBack allocateFunc;
610 CFAllocatorReallocateCallBack reallocateFunc;
611 CFAllocatorDeallocateCallBack deallocateFunc;
612 void *newptr;
613 allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
bd5b749c
A
614#if (DEPLOYMENT_TARGET_MACOSX) && defined(DEBUG)
615 if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
9ce05555
A
616 __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
617 }
618#else
619 __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
620#endif
621 if (NULL == ptr && 0 < newsize) {
bd5b749c
A
622#if DEPLOYMENT_TARGET_MACOSX
623 if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) { // malloc_zone_t *
9ce05555
A
624 return malloc_zone_malloc((malloc_zone_t *)allocator, newsize);
625 }
626#endif
d8925383 627 newptr = NULL;
9ce05555 628 allocateFunc = __CFAllocatorGetAllocateFunction(&allocator->_context);
d8925383
A
629 if (allocateFunc) {
630 newptr = (void *)INVOKE_CALLBACK3(allocateFunc, newsize, hint, allocator->_context.info);
631 }
9ce05555
A
632 return newptr;
633 }
634 if (NULL != ptr && 0 == newsize) {
bd5b749c
A
635#if DEPLOYMENT_TARGET_MACOSX
636 if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) { // malloc_zone_t *
d8925383
A
637#if defined(DEBUG)
638 size_t size = malloc_size(ptr);
639 if (size) memset(ptr, 0xCC, size);
640#endif
9ce05555
A
641 malloc_zone_free((malloc_zone_t *)allocator, ptr);
642 return NULL;
643 }
644#endif
645 deallocateFunc = __CFAllocatorGetDeallocateFunction(&allocator->_context);
646 if (NULL != deallocateFunc) {
647 INVOKE_CALLBACK2(deallocateFunc, ptr, allocator->_context.info);
648 }
649 return NULL;
650 }
651 if (NULL == ptr && 0 == newsize) return NULL;
bd5b749c
A
652#if DEPLOYMENT_TARGET_MACOSX
653 if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) { // malloc_zone_t *
9ce05555
A
654 return malloc_zone_realloc((malloc_zone_t *)allocator, ptr, newsize);
655 }
656#endif
657 reallocateFunc = __CFAllocatorGetReallocateFunction(&allocator->_context);
658 if (NULL == reallocateFunc) return NULL;
659 newptr = (void *)INVOKE_CALLBACK4(reallocateFunc, ptr, newsize, hint, allocator->_context.info);
660 return newptr;
661}
662
663void CFAllocatorDeallocate(CFAllocatorRef allocator, void *ptr) {
664 CFAllocatorDeallocateCallBack deallocateFunc;
665 allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
bd5b749c
A
666#if (DEPLOYMENT_TARGET_MACOSX) && defined(DEBUG)
667 if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
9ce05555
A
668 __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
669 }
670#else
671 __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
672#endif
bd5b749c
A
673#if DEPLOYMENT_TARGET_MACOSX
674 if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) { // malloc_zone_t *
d8925383
A
675#if defined(DEBUG)
676 size_t size = malloc_size(ptr);
677 if (size) memset(ptr, 0xCC, size);
678#endif
9ce05555
A
679 return malloc_zone_free((malloc_zone_t *)allocator, ptr);
680 }
681#endif
682 deallocateFunc = __CFAllocatorGetDeallocateFunction(&allocator->_context);
683 if (NULL != ptr && NULL != deallocateFunc) {
684 INVOKE_CALLBACK2(deallocateFunc, ptr, allocator->_context.info);
685 }
686}
687
688CFIndex CFAllocatorGetPreferredSizeForSize(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint) {
689 CFAllocatorPreferredSizeCallBack prefFunc;
690 CFIndex newsize = 0;
691 allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
bd5b749c
A
692#if (DEPLOYMENT_TARGET_MACOSX) && defined(DEBUG)
693 if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
9ce05555
A
694 __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
695 }
696#else
697 __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
698#endif
bd5b749c
A
699#if DEPLOYMENT_TARGET_MACOSX
700 if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) { // malloc_zone_t *
9ce05555
A
701 return malloc_good_size(size);
702 }
703#endif
704 prefFunc = __CFAllocatorGetPreferredSizeFunction(&allocator->_context);
705 if (0 < size && NULL != prefFunc) {
706 newsize = (CFIndex)(INVOKE_CALLBACK3(prefFunc, size, hint, allocator->_context.info));
707 }
708 if (newsize < size) newsize = size;
709 return newsize;
710}
711
712void CFAllocatorGetContext(CFAllocatorRef allocator, CFAllocatorContext *context) {
713 allocator = (NULL == allocator) ? __CFGetDefaultAllocator() : allocator;
bd5b749c
A
714#if (DEPLOYMENT_TARGET_MACOSX) && defined(DEBUG)
715 if (allocator->_base._cfisa == __CFISAForTypeID(__kCFAllocatorTypeID)) {
9ce05555
A
716 __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
717 }
718#else
719 __CFGenericValidateType(allocator, __kCFAllocatorTypeID);
720#endif
721 CFAssert1(0 == context->version, __kCFLogAssertion, "%s(): context version not initialized to 0", __PRETTY_FUNCTION__);
bd5b749c
A
722#if DEPLOYMENT_TARGET_MACOSX
723 if (allocator->_base._cfisa != __CFISAForTypeID(__kCFAllocatorTypeID)) { // malloc_zone_t *
9ce05555
A
724 return;
725 }
726#endif
727 context->version = 0;
728 context->info = allocator->_context.info;
729 context->retain = __CFAllocatorGetRetainFunction(&allocator->_context);
730 context->release = __CFAllocatorGetReleaseFunction(&allocator->_context);
731 context->copyDescription = __CFAllocatorGetCopyDescriptionFunction(&allocator->_context);
732 context->allocate = __CFAllocatorGetAllocateFunction(&allocator->_context);
733 context->reallocate = __CFAllocatorGetReallocateFunction(&allocator->_context);
734 context->deallocate = __CFAllocatorGetDeallocateFunction(&allocator->_context);
735 context->preferredSize = __CFAllocatorGetPreferredSizeFunction(&allocator->_context);
bd5b749c 736#if (DEPLOYMENT_TARGET_MACOSX) && defined(__ppc__)
9ce05555
A
737 context->retain = (void *)((uintptr_t)context->retain & ~0x3);
738 context->release = (void *)((uintptr_t)context->release & ~0x3);
739 context->copyDescription = (void *)((uintptr_t)context->copyDescription & ~0x3);
740 context->allocate = (void *)((uintptr_t)context->allocate & ~0x3);
741 context->reallocate = (void *)((uintptr_t)context->reallocate & ~0x3);
742 context->deallocate = (void *)((uintptr_t)context->deallocate & ~0x3);
743 context->preferredSize = (void *)((uintptr_t)context->preferredSize & ~0x3);
4c91a73d 744#endif
9ce05555
A
745}
746
d8925383
A
747void *_CFAllocatorAllocateGC(CFAllocatorRef allocator, CFIndex size, CFOptionFlags hint)
748{
749 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator))
bd5b749c 750 return auto_zone_allocate_object((auto_zone_t*)kCFAllocatorSystemDefault->_context.info, size, CF_GET_GC_MEMORY_TYPE(hint), false, false);
d8925383
A
751 else
752 return CFAllocatorAllocate(allocator, size, hint);
753}
754
755void *_CFAllocatorReallocateGC(CFAllocatorRef allocator, void *ptr, CFIndex newsize, CFOptionFlags hint)
756{
757 if (CF_IS_COLLECTABLE_ALLOCATOR(allocator)) {
758 if (ptr && (newsize == 0)) {
759 return NULL; // equivalent to _CFAllocatorDeallocateGC.
760 }
761 if (ptr == NULL) {
bd5b749c 762 return auto_zone_allocate_object((auto_zone_t*)kCFAllocatorSystemDefault->_context.info, newsize, CF_GET_GC_MEMORY_TYPE(hint), false, false); // eq. to _CFAllocator
d8925383
A
763 }
764 }
765 // otherwise, auto_realloc() now preserves layout type and refCount.
766 return CFAllocatorReallocate(allocator, ptr, newsize, hint);
767}
768
769void _CFAllocatorDeallocateGC(CFAllocatorRef allocator, void *ptr)
770{
771 // when running GC, don't deallocate.
772 if (!CF_IS_COLLECTABLE_ALLOCATOR(allocator)) CFAllocatorDeallocate(allocator, ptr);
773}
774
9ce05555
A
775// -------- -------- -------- -------- -------- -------- -------- --------
776
bd5b749c 777#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
9ce05555
A
778__private_extern__ pthread_key_t __CFTSDKey = (pthread_key_t)NULL;
779#endif
bd5b749c 780#if 0
9ce05555
A
781__private_extern__ DWORD __CFTSDKey = 0xFFFFFFFF;
782#endif
783
bd5b749c
A
784extern void _CFRunLoop1(void);
785
9ce05555 786// Called for each thread as it exits
d8925383 787__private_extern__ void __CFFinalizeThreadData(void *arg) {
bd5b749c 788#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
9ce05555 789 __CFThreadSpecificData *tsd = (__CFThreadSpecificData *)arg;
bd5b749c
A
790#elif defined(__WIN32__)
791 __CFThreadSpecificData *tsd = (__CFThreadSpecificData*)TlsGetValue(__CFTSDKey);
d8925383
A
792 TlsSetValue(__CFTSDKey, NULL);
793#endif
9ce05555
A
794 if (NULL == tsd) return;
795 if (tsd->_allocator) CFRelease(tsd->_allocator);
bd5b749c
A
796#if DEPLOYMENT_TARGET_MACOSX
797 _CFRunLoop1();
798#endif
799#if 0 || 0
800
801 if (tsd->_messageHook) UnhookWindowsHookEx(tsd->_messageHook);
802
803#endif
804
9ce05555
A
805 CFAllocatorDeallocate(kCFAllocatorSystemDefault, tsd);
806}
807
808__private_extern__ __CFThreadSpecificData *__CFGetThreadSpecificData(void) {
bd5b749c 809#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
9ce05555
A
810 __CFThreadSpecificData *data;
811 data = pthread_getspecific(__CFTSDKey);
812 if (data) {
813 return data;
814 }
815 data = CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(__CFThreadSpecificData), 0);
816 if (__CFOASafe) __CFSetLastAllocationEventName(data, "CFUtilities (thread-data)");
817 memset(data, 0, sizeof(__CFThreadSpecificData));
818 pthread_setspecific(__CFTSDKey, data);
819 return data;
820#elif defined(__WIN32__)
821 __CFThreadSpecificData *data;
bd5b749c 822 data = (__CFThreadSpecificData *)TlsGetValue(__CFTSDKey);
9ce05555
A
823 if (data) {
824 return data;
825 }
bd5b749c 826 data = (__CFThreadSpecificData *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(__CFThreadSpecificData), 0);
9ce05555
A
827 if (__CFOASafe) __CFSetLastAllocationEventName(data, "CFUtilities (thread-data)");
828 memset(data, 0, sizeof(__CFThreadSpecificData));
829 TlsSetValue(__CFTSDKey, data);
830 return data;
831#endif
832}
833
834__private_extern__ void __CFBaseInitialize(void) {
bd5b749c 835#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_LINUX || DEPLOYMENT_TARGET_FREEBSD
9ce05555
A
836 pthread_key_create(&__CFTSDKey, __CFFinalizeThreadData);
837#endif
bd5b749c 838#if 0 || 0
9ce05555
A
839 __CFTSDKey = TlsAlloc();
840#endif
d8925383
A
841}
842
bd5b749c 843#if 0 || 0
d8925383
A
844__private_extern__ void __CFBaseCleanup(void) {
845 TlsFree(__CFTSDKey);
9ce05555 846}
d8925383 847#endif
9ce05555
A
848
849
bd5b749c
A
850static CFBadErrorCallBack __CFOutOfMemoryCallBack = NULL;
851
852CFBadErrorCallBack _CFGetOutOfMemoryErrorCallBack(void) {
853 return __CFOutOfMemoryCallBack;
854}
855
856void _CFSetOutOfMemoryErrorCallBack(CFBadErrorCallBack callBack) {
857 __CFOutOfMemoryCallBack = callBack;
858}
859
860
9ce05555
A
861CFRange __CFRangeMake(CFIndex loc, CFIndex len) {
862 CFRange range;
863 range.location = loc;
864 range.length = len;
865 return range;
866}
867
9ce05555
A
868
869struct __CFNull {
870 CFRuntimeBase _base;
871};
872
873static struct __CFNull __kCFNull = {
bd5b749c 874 INIT_CFRUNTIME_BASE()
9ce05555
A
875};
876const CFNullRef kCFNull = &__kCFNull;
877
878static CFStringRef __CFNullCopyDescription(CFTypeRef cf) {
bd5b749c 879 return CFStringCreateWithFormat(kCFAllocatorSystemDefault, NULL, CFSTR("<CFNull %p [%p]>"), cf, CFGetAllocator(cf));
9ce05555
A
880}
881
882static CFStringRef __CFNullCopyFormattingDescription(CFTypeRef cf, CFDictionaryRef formatOptions) {
bd5b749c 883 return (CFStringRef)CFRetain(CFSTR("null"));
9ce05555
A
884}
885
886static void __CFNullDeallocate(CFTypeRef cf) {
887 CFAssert(false, __kCFLogAssertion, "Deallocated CFNull!");
888}
889
890static CFTypeID __kCFNullTypeID = _kCFRuntimeNotATypeID;
891
892static const CFRuntimeClass __CFNullClass = {
893 0,
894 "CFNull",
895 NULL, // init
896 NULL, // copy
897 __CFNullDeallocate,
898 NULL,
899 NULL,
900 __CFNullCopyFormattingDescription,
901 __CFNullCopyDescription
902};
903
904__private_extern__ void __CFNullInitialize(void) {
905 __kCFNullTypeID = _CFRuntimeRegisterClass(&__CFNullClass);
906 _CFRuntimeSetInstanceTypeID(&__kCFNull, __kCFNullTypeID);
bd5b749c 907 __kCFNull._base._cfisa = __CFISAForTypeID(__kCFNullTypeID);
9ce05555
A
908}
909
910CFTypeID CFNullGetTypeID(void) {
911 return __kCFNullTypeID;
912}
913
bd5b749c
A
914void CFCollection_non_gc_storage_error(void) { }
915
9ce05555
A
916
917static int hasCFM = 0;
918
d8925383 919void _CFRuntimeSetCFMPresent(void *addr) {
9ce05555
A
920 hasCFM = 1;
921}
922
bd5b749c 923#if (DEPLOYMENT_TARGET_MACOSX) && defined(__ppc__)
9ce05555
A
924
925/* See comments below */
926__private_extern__ void __CF_FAULT_CALLBACK(void **ptr) {
927 uintptr_t p = (uintptr_t)*ptr;
928 if ((0 == p) || (p & 0x1)) return;
d8925383 929 if (0 == hasCFM || (0x90000000 <= p && p < 0xA0000000)) {
9ce05555
A
930 *ptr = (void *)(p | 0x1);
931 } else {
bd5b749c
A
932 static CFMutableDictionaryRef cache = NULL;
933 static CFSpinLock_t lock = CFSpinLockInit;
934 uintptr_t known = ~0;
935 __CFSpinLock(&lock);
936 if (!cache || !CFDictionaryGetValueIfPresent(cache, (const void *)p, (const void **)&known)) {
937 if (!cache) {
938 cache = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0, NULL, NULL);
939 }
940 Dl_info info;
941 known = dladdr((void *)p, &info);
942 CFDictionarySetValue(cache, (const void *)p, (const void *)known);
943 }
944 __CFSpinUnlock(&lock);
945 *ptr = (void *)(p | (known ? 0x1 : 0x3));
9ce05555
A
946 }
947}
948
949/*
950Jump to callback function. r2 is not saved and restored
951in the jump-to-CFM case, since we assume that dyld code
952never uses that register and that CF is dyld.
953
954There are three states for (ptr & 0x3):
955 0b00: check not yet done (or not going to be done, and is a dyld func ptr)
956 0b01: check done, dyld function pointer
957 0b11: check done, CFM tvector pointer
958(but a NULL callback just stays NULL)
959
960There may be up to 5 word-sized arguments. Floating point
961arguments can be done, but count as two word arguments.
962Return value can be integral or real.
963*/
964
965/* Keep this assembly at the bottom of the source file! */
966
967__asm__ (
968".text\n"
969" .align 2\n"
970".private_extern ___CF_INVOKE_CALLBACK\n"
971"___CF_INVOKE_CALLBACK:\n"
972 "rlwinm r12,r3,0,0,29\n"
973 "andi. r0,r3,0x2\n"
974 "or r3,r4,r4\n"
975 "or r4,r5,r5\n"
976 "or r5,r6,r6\n"
977 "or r6,r7,r7\n"
978 "or r7,r8,r8\n"
979 "beq- Lcall\n"
980 "lwz r2,0x4(r12)\n"
981 "lwz r12,0x0(r12)\n"
982"Lcall: mtspr ctr,r12\n"
983 "bctr\n");
984
985#endif
986
987
988// void __HALT(void);
989
d8925383 990#if defined(__ppc__) || defined(__ppc64__)
9ce05555
A
991__asm__ (
992".text\n"
993" .align 2\n"
bd5b749c 994#if DEPLOYMENT_TARGET_MACOSX
9ce05555
A
995".private_extern ___HALT\n"
996#else
997".globl ___HALT\n"
998#endif
999"___HALT:\n"
1000" trap\n"
1001);
1002#endif
1003
bd5b749c
A
1004#if defined(__i386__) || defined(__x86_64__)
1005#if defined(_MSC_VER)
1006void __HALT() {
d8925383
A
1007 __asm int 3;
1008}
1009#else
9ce05555
A
1010__asm__ (
1011".text\n"
1012" .align 2, 0x90\n"
bd5b749c 1013#if DEPLOYMENT_TARGET_MACOSX
9ce05555
A
1014".private_extern ___HALT\n"
1015#else
1016".globl ___HALT\n"
1017#endif
1018"___HALT:\n"
1019" int3\n"
1020);
1021#endif
d8925383 1022#endif
9ce05555 1023
bd5b749c 1024