├── .gitignore ├── APPLE_LICENSE ├── README.md ├── ReleaseNotes.rtf ├── debug-objc └── main.m ├── include ├── Block_private.h ├── CrashReporterClient.h ├── System │ ├── machine │ │ └── cpu_capabilities.h │ └── pthread_machdep.h ├── _simple.h ├── mach-o │ └── dyld_priv.h ├── objc-shared-cache.h ├── os │ └── tsd.h ├── pthread │ ├── qos_private.h │ ├── spinlock_private.h │ ├── tsd_private.h │ └── workqueue_private.h └── sys │ ├── qos_private.h │ └── reason.h ├── libobjc.order ├── markgc.cpp ├── objc.sln ├── objc.suo ├── objc.vcproj ├── objc.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── objcrt └── objcrt.vcproj ├── prebuild.bat ├── runtime ├── Messengers.subproj │ ├── objc-msg-arm.s │ ├── objc-msg-arm64.s │ ├── objc-msg-i386.s │ ├── objc-msg-simulator-i386.s │ ├── objc-msg-simulator-x86_64.s │ ├── objc-msg-win32.m │ └── objc-msg-x86_64.s ├── NSObjCRuntime.h ├── NSObject.h ├── NSObject.mm ├── Object.h ├── Object.mm ├── OldClasses.subproj │ ├── List.h │ └── List.m ├── Protocol.h ├── Protocol.mm ├── a1a2-blocktramps-arm.s ├── a1a2-blocktramps-arm64.s ├── a1a2-blocktramps-i386.s ├── a1a2-blocktramps-x86_64.s ├── a2a3-blocktramps-arm.s ├── a2a3-blocktramps-i386.s ├── a2a3-blocktramps-x86_64.s ├── hashtable.h ├── hashtable2.h ├── hashtable2.mm ├── llvm-AlignOf.h ├── llvm-DenseMap.h ├── llvm-DenseMapInfo.h ├── llvm-MathExtras.h ├── llvm-type_traits.h ├── maptable.h ├── maptable.mm ├── message.h ├── objc-abi.h ├── objc-accessors.mm ├── objc-api.h ├── objc-auto.h ├── objc-auto.mm ├── objc-block-trampolines.mm ├── objc-cache-old.h ├── objc-cache-old.mm ├── objc-cache.h ├── objc-cache.mm ├── objc-class-old.mm ├── objc-class.h ├── objc-class.mm ├── objc-config.h ├── objc-env.h ├── objc-errors.mm ├── objc-exception.h ├── objc-exception.mm ├── objc-file-old.h ├── objc-file-old.mm ├── objc-file.h ├── objc-file.mm ├── objc-gdb.h ├── objc-initialize.h ├── objc-initialize.mm ├── objc-internal.h ├── objc-layout.mm ├── objc-load.h ├── objc-load.mm ├── objc-loadmethod.h ├── objc-loadmethod.mm ├── objc-lockdebug.h ├── objc-lockdebug.mm ├── objc-object.h ├── objc-opt.mm ├── objc-os.h ├── objc-os.mm ├── objc-private.h ├── objc-probes.d ├── objc-references.h ├── objc-references.mm ├── objc-runtime-new.h ├── objc-runtime-new.mm ├── objc-runtime-old.h ├── objc-runtime-old.mm ├── objc-runtime.h ├── objc-runtime.mm ├── objc-sel-old.mm ├── objc-sel-set.h ├── objc-sel-set.mm ├── objc-sel-table.s ├── objc-sel.mm ├── objc-sync.h ├── objc-sync.mm ├── objc-typeencoding.mm ├── objc-weak.h ├── objc-weak.mm ├── objc.h ├── objcrt.c ├── objcrt.h └── runtime.h ├── unexported_symbols ├── version.bat └── version.rc /.gitignore: -------------------------------------------------------------------------------- 1 | debug-objc/Foo.cpp 2 | 3 | 4 | #################### Mac OS X & Xcode #################### 5 | 6 | .DS_Store 7 | *.swp 8 | *.lock 9 | profile 10 | 11 | 12 | *~.nib 13 | 14 | 15 | DerivedData/ 16 | 17 | 18 | build/ 19 | 20 | 21 | *.pbxuser 22 | *.mode1v3 23 | *.mode2v3 24 | *.perspectivev3 25 | # NB: also, whitelist the default ones, some projects need to use these 26 | !default.pbxuser 27 | !default.mode1v3 28 | !default.mode2v3 29 | !default.perspectivev3 30 | 31 | 32 | xcuserdata 33 | UserInterfaceState.xcuserstate 34 | 35 | 36 | *.moved-aside 37 | 38 | Pods/ 39 | Podfile.lock 40 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | [How to build libobjc (objc4-680)](http://blog.csdn.net/wotors/article/details/52489464) (Chinese Version) 3 | 4 | [How to build libobjc (objc4-706)](http://blog.csdn.net/wotors/article/details/54426316) (Chinese Version) 5 | 6 | -------------------------------------------------------------------------------- /debug-objc/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // debug-objc 4 | // 5 | // Created by suchavision on 1/24/17. 6 | // 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, const char * argv[]) { 12 | @autoreleasepool { 13 | // insert code here... 14 | NSLog(@"Hello, World!"); 15 | } 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /include/CrashReporterClient.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010 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 | /*********************************************************************** 25 | * Not to be installed in /usr/local/include 26 | ***********************************************************************/ 27 | 28 | #ifndef _LIBC_CRASHREPORTERCLIENT_H 29 | #define _LIBC_CRASHREPORTERCLIENT_H 30 | 31 | #ifdef LIBC_NO_LIBCRASHREPORTERCLIENT 32 | 33 | /* Fake the CrashReporterClient API */ 34 | #define CRGetCrashLogMessage() 0 35 | #define CRSetCrashLogMessage(x) /* nothing */ 36 | 37 | #else /* !LIBC_NO_LIBCRASHREPORTERCLIENT */ 38 | 39 | /* Include the real CrashReporterClient.h */ 40 | #include_next 41 | 42 | #endif /* !LIBC_NO_LIBCRASHREPORTERCLIENT */ 43 | 44 | #endif /* _LIBC_CRASHREPORTERCLIENT_H */ 45 | -------------------------------------------------------------------------------- /include/System/machine/cpu_capabilities.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000-2007 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_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. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | #ifdef PRIVATE 29 | 30 | #ifndef _MACHINE_CPU_CAPABILITIES_H 31 | #define _MACHINE_CPU_CAPABILITIES_H 32 | 33 | #ifdef KERNEL_PRIVATE 34 | #if defined (__i386__) || defined (__x86_64__) 35 | #include "i386/cpu_capabilities.h" 36 | #else 37 | #error architecture not supported 38 | #endif 39 | 40 | #else /* !KERNEL_PRIVATE -- System Framework header */ 41 | #if defined (__i386__) || defined(__x86_64__) 42 | #include 43 | #else 44 | #error architecture not supported 45 | #endif 46 | #endif /* KERNEL_PRIVATE */ 47 | 48 | #endif /* _MACHINE_CPU_CAPABILITIES_H */ 49 | #endif /* PRIVATE */ 50 | -------------------------------------------------------------------------------- /include/_simple.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006, 2010 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 | #include 24 | #include 25 | #include 26 | 27 | typedef void *_SIMPLE_STRING; 28 | typedef const char *_esc_func(unsigned char); 29 | 30 | __BEGIN_DECLS 31 | /* 32 | * A simplified vfprintf variant. The format string is interpreted with 33 | * arguments from the va_list, and the results are written to the given 34 | * file descriptor. 35 | */ 36 | void _simple_vdprintf(int __fd, const char *__fmt, va_list __ap); 37 | 38 | /* 39 | * A simplified fprintf variant. The format string is interpreted with 40 | * arguments from the variable argument list, and the results are written 41 | * to the given file descriptor. 42 | */ 43 | void _simple_dprintf(int __fd, const char *__fmt, ...); 44 | 45 | /* 46 | * A simplified string allocate routine. Pass the opaque pointer to structure 47 | * to _simple_*sprintf() routines. Use _simple_string() to retrieve the 48 | * current string (the string is guaranteed to be null terminated only on 49 | * the call to _simple_string()). Use _simple_sfree() to free the structure 50 | * and string memory. 51 | */ 52 | _SIMPLE_STRING _simple_salloc(void); 53 | 54 | /* 55 | * The format string is interpreted with arguments from the va_list, and the 56 | * results are appended to the string maintained by the opaque structure, as 57 | * returned by a previous call to _simple_salloc(). Non-zero is returned on 58 | * out-of-memory error. 59 | */ 60 | int _simple_vsprintf(_SIMPLE_STRING __b, const char *__fmt, va_list __ap); 61 | 62 | /* 63 | * The format string is interpreted with arguments from the variable argument 64 | * list, and the results are appended to the string maintained by the opaque 65 | * structure, as returned by a previous call to _simple_salloc(). Non-zero is 66 | * returned on out-of-memory error. 67 | */ 68 | int _simple_sprintf(_SIMPLE_STRING __b, const char *__fmt, ...); 69 | 70 | /* 71 | * Like _simple_vsprintf(), except __esc is a function to call on each 72 | * character; the function returns NULL if the character should be passed 73 | * as is, otherwise, the returned character string is used instead. 74 | */ 75 | int _simple_vesprintf(_SIMPLE_STRING __b, _esc_func __esc, const char *__fmt, va_list __ap); 76 | 77 | /* 78 | * Like _simple_sprintf(), except __esc is a function to call on each 79 | * character; the function returns NULL if the character should be passed 80 | * as is, otherwise, the returned character string is used instead. 81 | */ 82 | int _simple_esprintf(_SIMPLE_STRING __b, _esc_func __esc, const char *__fmt, ...); 83 | 84 | /* 85 | * Return the null terminated string from the opaque structure, as returned 86 | * by a previous call to _simple_salloc(). 87 | */ 88 | char *_simple_string(_SIMPLE_STRING __b); 89 | 90 | /* 91 | * Reposition the pointer to the first null in the buffer. After a call to 92 | * _simple_string, the buffer can be modified, and shrunk. 93 | */ 94 | void _simple_sresize(_SIMPLE_STRING __b); 95 | 96 | /* 97 | * Append the null-terminated string to the string associated with the opaque 98 | * structure. Non-zero is returned on out-of-memory error. 99 | */ 100 | int _simple_sappend(_SIMPLE_STRING __b, const char *__str); 101 | 102 | /* 103 | * Like _simple_sappend(), except __esc is a function to call on each 104 | * character; the function returns NULL if the character should be passed 105 | * as is, otherwise, the returned character string is used instead. 106 | */ 107 | int _simple_esappend(_SIMPLE_STRING __b, _esc_func __esc, const char *__str); 108 | 109 | /* 110 | * Write the string associated with the opaque structure to the file descriptor. 111 | */ 112 | void _simple_put(_SIMPLE_STRING __b, int __fd); 113 | 114 | /* 115 | * Write the string associated with the opaque structure and a trailing newline, 116 | * to the file descriptor. 117 | */ 118 | void _simple_putline(_SIMPLE_STRING __b, int __fd); 119 | 120 | /* 121 | * Free the opaque structure, and the associated string. 122 | */ 123 | void _simple_sfree(_SIMPLE_STRING __b); 124 | 125 | /* 126 | * Simplified ASL log interface; does not use malloc. Unfortunately, this 127 | * requires knowledge of the format used by ASL. 128 | */ 129 | void _simple_asl_log(int __level, const char *__facility, const char *__message); 130 | void _simple_asl_log_prog(int level, const char *facility, const char *message, const char *progname); 131 | __END_DECLS 132 | -------------------------------------------------------------------------------- /include/os/tsd.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 Apple Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_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. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | 29 | #ifndef OS_TSD_H 30 | #define OS_TSD_H 31 | 32 | #include 33 | 34 | /* The low nine slots of the TSD are reserved for libsyscall usage. */ 35 | #define __TSD_RESERVED_BASE 0 36 | #define __TSD_RESERVED_MAX 9 37 | 38 | #define __TSD_THREAD_SELF 0 39 | #define __TSD_ERRNO 1 40 | #define __TSD_MIG_REPLY 2 41 | #define __TSD_SEMAPHORE_CACHE 9 42 | 43 | 44 | __attribute__((always_inline)) 45 | static __inline__ unsigned int 46 | _os_cpu_number(void) 47 | { 48 | /* Not yet implemented */ 49 | return 0; 50 | } 51 | 52 | #if defined(__i386__) || defined(__x86_64__) 53 | 54 | #if defined(__has_attribute) 55 | #if __has_attribute(address_space) 56 | #define OS_GS_RELATIVE __attribute__((address_space(256))) 57 | #endif 58 | #endif 59 | 60 | #ifdef OS_GS_RELATIVE 61 | #define _os_tsd_get_base() ((void * OS_GS_RELATIVE *)0) 62 | #else 63 | __attribute__((always_inline)) 64 | static __inline__ void* 65 | _os_tsd_get_direct(unsigned long slot) 66 | { 67 | void *ret; 68 | __asm__("mov %%gs:%1, %0" : "=r" (ret) : "m" (*(void **)(slot * sizeof(void *)))); 69 | return ret; 70 | } 71 | 72 | __attribute__((always_inline)) 73 | static __inline__ int 74 | _os_tsd_set_direct(unsigned long slot, void *val) 75 | { 76 | #if defined(__i386__) && defined(__PIC__) 77 | __asm__("movl %1, %%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val)); 78 | #elif defined(__i386__) && !defined(__PIC__) 79 | __asm__("movl %1, %%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "ri" (val)); 80 | #else 81 | __asm__("movq %1, %%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val)); 82 | #endif 83 | return 0; 84 | } 85 | #endif 86 | 87 | #else 88 | #error _os_tsd_get_base not implemented on this architecture 89 | #endif 90 | 91 | #ifdef _os_tsd_get_base 92 | __attribute__((always_inline)) 93 | static __inline__ void* 94 | _os_tsd_get_direct(unsigned long slot) 95 | { 96 | return _os_tsd_get_base()[slot]; 97 | } 98 | 99 | __attribute__((always_inline)) 100 | static __inline__ int 101 | _os_tsd_set_direct(unsigned long slot, void *val) 102 | { 103 | _os_tsd_get_base()[slot] = val; 104 | return 0; 105 | } 106 | #endif 107 | 108 | extern void _thread_set_tsd_base(void *tsd_base); 109 | 110 | #endif 111 | -------------------------------------------------------------------------------- /include/pthread/qos_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 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 | #ifndef _QOS_PRIVATE_H 25 | #define _QOS_PRIVATE_H 26 | 27 | #include 28 | #include 29 | 30 | #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL 31 | // allow __DARWIN_C_LEVEL to turn off the use of mach_port_t 32 | #include 33 | #endif 34 | 35 | // pthread_priority_t is an on opaque integer that is guaranteed to be ordered such that 36 | // combations of QoS classes and relative priorities are ordered numerically, according to 37 | // their combined priority. 38 | typedef unsigned long pthread_priority_t; 39 | 40 | // masks for splitting the handling the contents of a pthread_priority_t, the mapping from 41 | // qos_class_t to the class bits, however, is intentionally not exposed. 42 | #define _PTHREAD_PRIORITY_FLAGS_MASK 0xff000000 43 | #define _PTHREAD_PRIORITY_FLAGS_SHIFT (24ull) 44 | #define _PTHREAD_PRIORITY_ENCODING_MASK 0x00a00000 45 | #define _PTHREAD_PRIORITY_ENCODING_SHIFT (22ull) 46 | #define _PTHREAD_PRIORITY_ENCODING_V0 0x00000000 47 | #define _PTHREAD_PRIORITY_ENCODING_V1 0x00400000 /* unused */ 48 | #define _PTHREAD_PRIORITY_ENCODING_V2 0x00800000 /* unused */ 49 | #define _PTHREAD_PRIORITY_ENCODING_V3 0x00a00000 /* unused */ 50 | #define _PTHREAD_PRIORITY_QOS_CLASS_MASK 0x003fff00 51 | #define _PTHREAD_PRIORITY_QOS_CLASS_SHIFT (8ull) 52 | #define _PTHREAD_PRIORITY_PRIORITY_MASK 0x000000ff 53 | #define _PTHREAD_PRIORITY_PRIORITY_SHIFT (0) 54 | 55 | #define _PTHREAD_PRIORITY_OVERCOMMIT_FLAG 0x80000000 56 | #define _PTHREAD_PRIORITY_INHERIT_FLAG 0x40000000 57 | #define _PTHREAD_PRIORITY_ROOTQUEUE_FLAG 0x20000000 58 | // Used to indicate to the pthread kext that the provided event manager thread 59 | // priority is actually a scheduling priority not a QoS. We can have ROOTQUEUE_FLAG 60 | // perform double duty because it's never provided to the kernel. 61 | #define _PTHREAD_PRIORITY_SCHED_PRI_FLAG 0x20000000 62 | #define _PTHREAD_PRIORITY_ENFORCE_FLAG 0x10000000 63 | #define _PTHREAD_PRIORITY_OVERRIDE_FLAG 0x08000000 64 | 65 | // libdispatch defines the following, so it's not safe to use for anything we 66 | // expect to be passed in from userspace 67 | //#define _PTHREAD_PRIORITY_DEFAULTQUEUE_FLAG 0x04000000 68 | 69 | // The event manager flag indicates that this thread/request is for a event 70 | // manager thread. There can only ever be one event manager thread at a time and 71 | // it is brought up at the highest of all event manager priorities passed to the 72 | // kext. 73 | #define _PTHREAD_PRIORITY_EVENT_MANAGER_FLAG 0x02000000 74 | #define _PTHREAD_PRIORITY_NEEDS_UNBIND_FLAG 0x01000000 75 | 76 | // redeffed here to avoid leaving __QOS_ENUM defined in the public header 77 | #define __QOS_ENUM(name, type, ...) enum { __VA_ARGS__ }; typedef type name##_t 78 | #define __QOS_AVAILABLE_10_10 79 | #define __QOS_AVAILABLE_10_11 80 | #define __QOS_AVAILABLE_10_12 81 | 82 | #if defined(__has_feature) && defined(__has_extension) 83 | #if __has_feature(objc_fixed_enum) || __has_extension(cxx_strong_enums) 84 | #undef __QOS_ENUM 85 | #define __QOS_ENUM(name, type, ...) typedef enum : type { __VA_ARGS__ } name##_t 86 | #endif 87 | #if __has_feature(enumerator_attributes) 88 | #undef __QOS_AVAILABLE_10_10 89 | #define __QOS_AVAILABLE_10_10 __OSX_AVAILABLE(10.10) __IOS_AVAILABLE(8.0) 90 | #undef __QOS_AVAILABLE_10_11 91 | #define __QOS_AVAILABLE_10_11 __OSX_AVAILABLE(10.11) __IOS_AVAILABLE(9.0) __WATCHOS_AVAILABLE(2.0) __TVOS_AVAILABLE(9.0) 92 | #undef __QOS_AVAILABLE_10_12 93 | #define __QOS_AVAILABLE_10_12 __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) __TVOS_AVAILABLE(10.0) 94 | #endif 95 | #endif 96 | 97 | __QOS_ENUM(_pthread_set_flags, unsigned int, 98 | _PTHREAD_SET_SELF_QOS_FLAG __QOS_AVAILABLE_10_10 = 0x1, 99 | _PTHREAD_SET_SELF_VOUCHER_FLAG __QOS_AVAILABLE_10_10 = 0x2, 100 | _PTHREAD_SET_SELF_FIXEDPRIORITY_FLAG __QOS_AVAILABLE_10_11 = 0x4, 101 | _PTHREAD_SET_SELF_TIMESHARE_FLAG __QOS_AVAILABLE_10_11 = 0x8, 102 | _PTHREAD_SET_SELF_WQ_KEVENT_UNBIND __QOS_AVAILABLE_10_12 = 0x10, 103 | ); 104 | 105 | #undef __QOS_ENUM 106 | #undef __QOS_AVAILABLE_10_10 107 | #undef __QOS_AVAILABLE_10_11 108 | #undef __QOS_AVAILABLE_10_12 109 | 110 | #ifndef KERNEL 111 | 112 | __BEGIN_DECLS 113 | 114 | /*! 115 | * @function pthread_set_qos_class_np 116 | * 117 | * @abstract 118 | * Sets the requested QOS class and relative priority of the current thread. 119 | * 120 | * @discussion 121 | * The QOS class and relative priority represent an overall combination of 122 | * system quality of service attributes on a thread. 123 | * 124 | * Subsequent calls to interfaces such as pthread_setschedparam() that are 125 | * incompatible or in conflict with the QOS class system will unset the QOS 126 | * class requested with this interface and pthread_get_qos_class_np() will 127 | * return QOS_CLASS_UNSPECIFIED thereafter. A thread so modified is permanently 128 | * opted-out of the QOS class system and calls to this function to request a QOS 129 | * class for such a thread will fail and return EPERM. 130 | * 131 | * @param __pthread 132 | * The current thread as returned by pthread_self(). 133 | * EINVAL will be returned if any other thread is provided. 134 | * 135 | * @param __qos_class 136 | * A QOS class value: 137 | * - QOS_CLASS_USER_INTERACTIVE 138 | * - QOS_CLASS_USER_INITIATED 139 | * - QOS_CLASS_DEFAULT 140 | * - QOS_CLASS_UTILITY 141 | * - QOS_CLASS_BACKGROUND 142 | * - QOS_CLASS_MAINTENANCE 143 | * EINVAL will be returned if any other value is provided. 144 | * 145 | * @param __relative_priority 146 | * A relative priority within the QOS class. This value is a negative offset 147 | * from the maximum supported scheduler priority for the given class. 148 | * EINVAL will be returned if the value is greater than zero or less than 149 | * QOS_MIN_RELATIVE_PRIORITY. 150 | * 151 | * @return 152 | * Zero if successful, othwerise an errno value. 153 | */ 154 | __OSX_AVAILABLE_BUT_DEPRECATED_MSG(__MAC_10_10, __MAC_10_10, __IPHONE_8_0, __IPHONE_8_0, \ 155 | "Use pthread_set_qos_class_self_np() instead") 156 | int 157 | pthread_set_qos_class_np(pthread_t __pthread, 158 | qos_class_t __qos_class, 159 | int __relative_priority); 160 | 161 | /* Private interfaces for libdispatch to encode/decode specific values of pthread_priority_t. */ 162 | 163 | // Encode a class+priority pair into a pthread_priority_t, 164 | __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) 165 | pthread_priority_t 166 | _pthread_qos_class_encode(qos_class_t qos_class, int relative_priority, unsigned long flags); 167 | 168 | // Decode a pthread_priority_t into a class+priority pair. 169 | __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) 170 | qos_class_t 171 | _pthread_qos_class_decode(pthread_priority_t priority, int *relative_priority, unsigned long *flags); 172 | 173 | // Encode a legacy workqueue API priority into a pthread_priority_t 174 | __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) 175 | pthread_priority_t 176 | _pthread_qos_class_encode_workqueue(int queue_priority, unsigned long flags); 177 | 178 | #if __DARWIN_C_LEVEL >= __DARWIN_C_FULL 179 | // Set QoS or voucher, or both, on pthread_self() 180 | __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) 181 | int 182 | _pthread_set_properties_self(_pthread_set_flags_t flags, pthread_priority_t priority, mach_port_t voucher); 183 | 184 | // Set self to fixed priority without disturbing QoS or priority 185 | __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) 186 | int 187 | pthread_set_fixedpriority_self(void); 188 | 189 | // Inverse of pthread_set_fixedpriority_self() 190 | __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0) 191 | int 192 | pthread_set_timeshare_self(void); 193 | 194 | #endif 195 | 196 | __END_DECLS 197 | 198 | #endif // KERNEL 199 | 200 | #endif //_QOS_PRIVATE_H 201 | -------------------------------------------------------------------------------- /include/pthread/spinlock_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2003, 2013 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. Please obtain a copy of the License at 10 | * http://www.opensource.apple.com/apsl/ and read it before using this 11 | * file. 12 | * 13 | * The Original Code and all software distributed under the License are 14 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 | * Please see the License for the specific language governing rights and 19 | * limitations under the License. 20 | * 21 | * @APPLE_LICENSE_HEADER_END@ 22 | */ 23 | /* 24 | * Copyright 1996 1995 by Open Software Foundation, Inc. 1997 1996 1995 1994 1993 1992 1991 25 | * All Rights Reserved 26 | * 27 | * Permission to use, copy, modify, and distribute this software and 28 | * its documentation for any purpose and without fee is hereby granted, 29 | * provided that the above copyright notice appears in all copies and 30 | * that both the copyright notice and this permission notice appear in 31 | * supporting documentation. 32 | * 33 | * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE 34 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 35 | * FOR A PARTICULAR PURPOSE. 36 | * 37 | * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR 38 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 39 | * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT, 40 | * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 41 | * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 42 | * 43 | */ 44 | /* 45 | * MkLinux 46 | */ 47 | 48 | /* 49 | * POSIX Threads - IEEE 1003.1c 50 | */ 51 | 52 | #ifndef _POSIX_PTHREAD_SPINLOCK_H 53 | #define _POSIX_PTHREAD_SPINLOCK_H 54 | 55 | #include 56 | #include 57 | #include 58 | 59 | typedef volatile OSSpinLock pthread_lock_t __deprecated_msg("Use instead"); 60 | 61 | #define LOCK_INIT(l) ((l) = OS_SPINLOCK_INIT) 62 | #define LOCK_INITIALIZER OS_SPINLOCK_INIT 63 | 64 | #define _DO_SPINLOCK_LOCK(v) OSSpinLockLock(v) 65 | #define _DO_SPINLOCK_UNLOCK(v) OSSpinLockUnlock(v) 66 | 67 | #define TRY_LOCK(v) OSSpinLockTry((volatile OSSpinLock *)&(v)) 68 | #define LOCK(v) OSSpinLockLock((volatile OSSpinLock *)&(v)) 69 | #define UNLOCK(v) OSSpinLockUnlock((volatile OSSpinLock *)&(v)) 70 | 71 | extern void _spin_lock(pthread_lock_t *lockp) __deprecated_msg("Use instead"); 72 | extern int _spin_lock_try(pthread_lock_t *lockp) __deprecated_msg("Use instead"); 73 | extern void _spin_unlock(pthread_lock_t *lockp) __deprecated_msg("Use instead"); 74 | 75 | extern void spin_lock(pthread_lock_t *lockp) __deprecated_msg("Use instead"); 76 | extern int spin_lock_try(pthread_lock_t *lockp) __deprecated_msg("Use instead"); 77 | extern void spin_unlock(pthread_lock_t *lockp) __deprecated_msg("Use instead"); 78 | 79 | #endif /* _POSIX_PTHREAD_SPINLOCK_H */ 80 | -------------------------------------------------------------------------------- /include/pthread/workqueue_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2007, 2012 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 | #ifndef __PTHREAD_WORKQUEUE_H__ 25 | #define __PTHREAD_WORKQUEUE_H__ 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #ifndef _PTHREAD_BUILDING_PTHREAD_ 33 | #include 34 | #endif 35 | 36 | #define PTHREAD_WORKQUEUE_SPI_VERSION 20160427 37 | 38 | /* Feature checking flags, returned by _pthread_workqueue_supported() 39 | * 40 | * Note: These bits should match the definition of PTHREAD_FEATURE_* 41 | * bits defined in libpthread/kern/kern_internal.h */ 42 | 43 | #define WORKQ_FEATURE_DISPATCHFUNC 0x01 // pthread_workqueue_setdispatch_np is supported (or not) 44 | #define WORKQ_FEATURE_FINEPRIO 0x02 // fine grained pthread workq priorities 45 | #define WORKQ_FEATURE_MAINTENANCE 0x10 // QOS class maintenance 46 | #define WORKQ_FEATURE_KEVENT 0x40 // Support for direct kevent delivery 47 | 48 | /* Legacy dispatch priority bands */ 49 | 50 | #define WORKQ_NUM_PRIOQUEUE 4 51 | 52 | #define WORKQ_HIGH_PRIOQUEUE 0 // high priority queue 53 | #define WORKQ_DEFAULT_PRIOQUEUE 1 // default priority queue 54 | #define WORKQ_LOW_PRIOQUEUE 2 // low priority queue 55 | #define WORKQ_BG_PRIOQUEUE 3 // background priority queue 56 | #define WORKQ_NON_INTERACTIVE_PRIOQUEUE 128 // libdispatch SPI level 57 | 58 | /* Legacy dispatch workqueue function flags */ 59 | #define WORKQ_ADDTHREADS_OPTION_OVERCOMMIT 0x00000001 60 | 61 | __BEGIN_DECLS 62 | 63 | // Legacy callback prototype, used with pthread_workqueue_setdispatch_np 64 | typedef void (*pthread_workqueue_function_t)(int queue_priority, int options, void *ctxt); 65 | // New callback prototype, used with pthread_workqueue_init 66 | typedef void (*pthread_workqueue_function2_t)(pthread_priority_t priority); 67 | 68 | // Newer callback prototype, used in conjection with function2 when there are kevents to deliver 69 | // both parameters are in/out parameters 70 | #define WORKQ_KEVENT_EVENT_BUFFER_LEN 16 71 | typedef void (*pthread_workqueue_function_kevent_t)(void **events, int *nevents); 72 | 73 | // Initialises the pthread workqueue subsystem, passing the new-style callback prototype, 74 | // the dispatchoffset and an unused flags field. 75 | __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) 76 | int 77 | _pthread_workqueue_init(pthread_workqueue_function2_t func, int offset, int flags); 78 | 79 | __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0) 80 | int 81 | _pthread_workqueue_init_with_kevent(pthread_workqueue_function2_t queue_func, pthread_workqueue_function_kevent_t kevent_func, int offset, int flags); 82 | 83 | // Non-zero enables kill on current thread, zero disables it. 84 | __OSX_AVAILABLE_STARTING(__MAC_10_6, __IPHONE_3_2) 85 | int 86 | __pthread_workqueue_setkill(int); 87 | 88 | // Dispatch function to be called when new worker threads are created. 89 | __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0) 90 | int 91 | pthread_workqueue_setdispatch_np(pthread_workqueue_function_t worker_func); 92 | 93 | // Dispatch offset to be set in the kernel. 94 | __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0) 95 | void 96 | pthread_workqueue_setdispatchoffset_np(int offset); 97 | 98 | // Request additional worker threads. 99 | __OSX_AVAILABLE_STARTING(__MAC_10_8, __IPHONE_6_0) 100 | int 101 | pthread_workqueue_addthreads_np(int queue_priority, int options, int numthreads); 102 | 103 | // Retrieve the supported pthread feature set 104 | __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) 105 | int 106 | _pthread_workqueue_supported(void); 107 | 108 | // Request worker threads (fine grained priority) 109 | __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) 110 | int 111 | _pthread_workqueue_addthreads(int numthreads, pthread_priority_t priority); 112 | 113 | __OSX_AVAILABLE_STARTING(__MAC_10_11, __IPHONE_9_0) 114 | int 115 | _pthread_workqueue_set_event_manager_priority(pthread_priority_t priority); 116 | 117 | // Apply a QoS override without allocating userspace memory 118 | __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) 119 | __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) 120 | int 121 | _pthread_qos_override_start_direct(mach_port_t thread, pthread_priority_t priority, void *resource); 122 | 123 | // Drop a corresponding QoS override made above, if the resource matches 124 | __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) 125 | __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) 126 | int 127 | _pthread_qos_override_end_direct(mach_port_t thread, void *resource); 128 | 129 | // Apply a QoS override without allocating userspace memory 130 | __OSX_DEPRECATED(10.10, 10.12, "use _pthread_qos_override_start_direct()") 131 | __IOS_DEPRECATED(8.0, 10.0, "use _pthread_qos_override_start_direct()") 132 | __TVOS_DEPRECATED(8.0, 10.0, "use _pthread_qos_override_start_direct()") 133 | __WATCHOS_DEPRECATED(1.0, 3.0, "use _pthread_qos_override_start_direct()") 134 | int 135 | _pthread_override_qos_class_start_direct(mach_port_t thread, pthread_priority_t priority); 136 | 137 | // Drop a corresponding QoS override made above. 138 | __OSX_DEPRECATED(10.10, 10.12, "use _pthread_qos_override_end_direct()") 139 | __IOS_DEPRECATED(8.0, 10.0, "use _pthread_qos_override_end_direct()") 140 | __TVOS_DEPRECATED(8.0, 10.0, "use _pthread_qos_override_end_direct()") 141 | __WATCHOS_DEPRECATED(1.0, 3.0, "use _pthread_qos_override_end_direct()") 142 | int 143 | _pthread_override_qos_class_end_direct(mach_port_t thread); 144 | 145 | // Apply a QoS override on a given workqueue thread. 146 | __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) 147 | int 148 | _pthread_workqueue_override_start_direct(mach_port_t thread, pthread_priority_t priority); 149 | 150 | // Apply a QoS override on a given workqueue thread. 151 | __OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) 152 | __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) 153 | int 154 | _pthread_workqueue_override_start_direct_check_owner(mach_port_t thread, pthread_priority_t priority, mach_port_t *ulock_addr); 155 | 156 | // Drop all QoS overrides on the current workqueue thread. 157 | __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) 158 | int 159 | _pthread_workqueue_override_reset(void); 160 | 161 | // Apply a QoS override on a given thread (can be non-workqueue as well) with a resource/queue token 162 | __OSX_AVAILABLE_STARTING(__MAC_10_10_2, __IPHONE_NA) 163 | int 164 | _pthread_workqueue_asynchronous_override_add(mach_port_t thread, pthread_priority_t priority, void *resource); 165 | 166 | // Reset overrides for the given resource for the current thread 167 | __OSX_AVAILABLE_STARTING(__MAC_10_10_2, __IPHONE_NA) 168 | int 169 | _pthread_workqueue_asynchronous_override_reset_self(void *resource); 170 | 171 | // Reset overrides for all resources for the current thread 172 | __OSX_AVAILABLE_STARTING(__MAC_10_10_2, __IPHONE_NA) 173 | int 174 | _pthread_workqueue_asynchronous_override_reset_all_self(void); 175 | 176 | __END_DECLS 177 | 178 | #endif // __PTHREAD_WORKQUEUE_H__ 179 | -------------------------------------------------------------------------------- /include/sys/qos_private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 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 | #ifndef _QOS_SYS_PRIVATE_H 25 | #define _QOS_SYS_PRIVATE_H 26 | 27 | /*! 28 | * @constant QOS_CLASS_MAINTENANCE 29 | * @abstract A QOS class which indicates work performed by this thread was not 30 | * initiated by the user and that the user may be unaware of the results. 31 | * @discussion Such work is requested to run at a priority far below other work 32 | * including significant I/O throttling. The use of this QOS class indicates 33 | * the work should be run in the most energy and thermally-efficient manner 34 | * possible, and may be deferred for a long time in order to preserve 35 | * system responsiveness for the user. 36 | * This is SPI for use by Spotlight and Time Machine only. 37 | */ 38 | #define QOS_CLASS_MAINTENANCE 0x05 39 | 40 | #endif //_QOS_SYS_PRIVATE_H 41 | -------------------------------------------------------------------------------- /objc.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 9.00 3 | # Visual C++ Express 2005 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "objc", "objc.vcproj", "{B3408263-0CF1-47BE-83CC-56070EFC9BC1}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "objcrt", "objcrt\objcrt.vcproj", "{E38C1996-8B3D-4050-A4B2-DC85957B047D}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {B3408263-0CF1-47BE-83CC-56070EFC9BC1} = {B3408263-0CF1-47BE-83CC-56070EFC9BC1} 9 | EndProjectSection 10 | EndProject 11 | Global 12 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 13 | Debug|Win32 = Debug|Win32 14 | DebugDLL|Win32 = DebugDLL|Win32 15 | Release|Win32 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {B3408263-0CF1-47BE-83CC-56070EFC9BC1}.Debug|Win32.ActiveCfg = Debug|Win32 19 | {B3408263-0CF1-47BE-83CC-56070EFC9BC1}.Debug|Win32.Build.0 = Debug|Win32 20 | {B3408263-0CF1-47BE-83CC-56070EFC9BC1}.DebugDLL|Win32.ActiveCfg = DebugDLL|Win32 21 | {B3408263-0CF1-47BE-83CC-56070EFC9BC1}.DebugDLL|Win32.Build.0 = DebugDLL|Win32 22 | {B3408263-0CF1-47BE-83CC-56070EFC9BC1}.Release|Win32.ActiveCfg = Release|Win32 23 | {B3408263-0CF1-47BE-83CC-56070EFC9BC1}.Release|Win32.Build.0 = Release|Win32 24 | {E38C1996-8B3D-4050-A4B2-DC85957B047D}.Debug|Win32.ActiveCfg = Debug|Win32 25 | {E38C1996-8B3D-4050-A4B2-DC85957B047D}.Debug|Win32.Build.0 = Debug|Win32 26 | {E38C1996-8B3D-4050-A4B2-DC85957B047D}.DebugDLL|Win32.ActiveCfg = Debug|Win32 27 | {E38C1996-8B3D-4050-A4B2-DC85957B047D}.DebugDLL|Win32.Build.0 = Debug|Win32 28 | {E38C1996-8B3D-4050-A4B2-DC85957B047D}.Release|Win32.ActiveCfg = Release|Win32 29 | {E38C1996-8B3D-4050-A4B2-DC85957B047D}.Release|Win32.Build.0 = Release|Win32 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /objc.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/isaacselement/objc4-706/c3b9d93de72989e4747f5546d8d0a6103898f6e2/objc.suo -------------------------------------------------------------------------------- /objc.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /objcrt/objcrt.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 24 | 28 | 31 | 34 | 38 | 39 | 47 | 51 | 54 | 57 | 61 | 62 | 63 | 64 | 65 | 66 | 71 | 74 | 75 | 76 | 81 | 84 | 85 | 86 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /prebuild.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | echo prebuild: installing headers 4 | xcopy /Y "%ProjectDir%runtime\objc.h" "%DSTROOT%\AppleInternal\include\objc\" 5 | xcopy /Y "%ProjectDir%runtime\objc-api.h" "%DSTROOT%\AppleInternal\include\objc\" 6 | xcopy /Y "%ProjectDir%runtime\objc-auto.h" "%DSTROOT%\AppleInternal\include\objc\" 7 | xcopy /Y "%ProjectDir%runtime\objc-exception.h" "%DSTROOT%\AppleInternal\include\objc\" 8 | xcopy /Y "%ProjectDir%runtime\message.h" "%DSTROOT%\AppleInternal\include\objc\" 9 | xcopy /Y "%ProjectDir%runtime\runtime.h" "%DSTROOT%\AppleInternal\include\objc\" 10 | xcopy /Y "%ProjectDir%runtime\hashtable.h" "%DSTROOT%\AppleInternal\include\objc\" 11 | xcopy /Y "%ProjectDir%runtime\hashtable2.h" "%DSTROOT%\AppleInternal\include\objc\" 12 | xcopy /Y "%ProjectDir%runtime\maptable.h" "%DSTROOT%\AppleInternal\include\objc\" 13 | 14 | echo prebuild: setting version 15 | version 16 | -------------------------------------------------------------------------------- /runtime/NSObjCRuntime.h: -------------------------------------------------------------------------------- 1 | /* NSObjCRuntime.h 2 | Copyright (c) 1994-2012, Apple Inc. All rights reserved. 3 | */ 4 | 5 | #ifndef _OBJC_NSOBJCRUNTIME_H_ 6 | #define _OBJC_NSOBJCRUNTIME_H_ 7 | 8 | #include 9 | #include 10 | 11 | #if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64 12 | typedef long NSInteger; 13 | typedef unsigned long NSUInteger; 14 | #else 15 | typedef int NSInteger; 16 | typedef unsigned int NSUInteger; 17 | #endif 18 | 19 | #define NSIntegerMax LONG_MAX 20 | #define NSIntegerMin LONG_MIN 21 | #define NSUIntegerMax ULONG_MAX 22 | 23 | #define NSINTEGER_DEFINED 1 24 | 25 | #ifndef NS_DESIGNATED_INITIALIZER 26 | #if __has_attribute(objc_designated_initializer) 27 | #define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) 28 | #else 29 | #define NS_DESIGNATED_INITIALIZER 30 | #endif 31 | #endif 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /runtime/NSObject.h: -------------------------------------------------------------------------------- 1 | /* NSObject.h 2 | Copyright (c) 1994-2012, Apple Inc. All rights reserved. 3 | */ 4 | 5 | #ifndef _OBJC_NSOBJECT_H_ 6 | #define _OBJC_NSOBJECT_H_ 7 | 8 | #if __OBJC__ 9 | 10 | #include 11 | #include 12 | 13 | @class NSString, NSMethodSignature, NSInvocation; 14 | 15 | @protocol NSObject 16 | 17 | - (BOOL)isEqual:(id)object; 18 | @property (readonly) NSUInteger hash; 19 | 20 | @property (readonly) Class superclass; 21 | - (Class)class OBJC_SWIFT_UNAVAILABLE("use 'anObject.dynamicType' instead"); 22 | - (instancetype)self; 23 | 24 | - (id)performSelector:(SEL)aSelector; 25 | - (id)performSelector:(SEL)aSelector withObject:(id)object; 26 | - (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2; 27 | 28 | - (BOOL)isProxy; 29 | 30 | - (BOOL)isKindOfClass:(Class)aClass; 31 | - (BOOL)isMemberOfClass:(Class)aClass; 32 | - (BOOL)conformsToProtocol:(Protocol *)aProtocol; 33 | 34 | - (BOOL)respondsToSelector:(SEL)aSelector; 35 | 36 | - (instancetype)retain OBJC_ARC_UNAVAILABLE; 37 | - (oneway void)release OBJC_ARC_UNAVAILABLE; 38 | - (instancetype)autorelease OBJC_ARC_UNAVAILABLE; 39 | - (NSUInteger)retainCount OBJC_ARC_UNAVAILABLE; 40 | 41 | - (struct _NSZone *)zone OBJC_ARC_UNAVAILABLE; 42 | 43 | @property (readonly, copy) NSString *description; 44 | @optional 45 | @property (readonly, copy) NSString *debugDescription; 46 | 47 | @end 48 | 49 | 50 | OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) 51 | OBJC_ROOT_CLASS 52 | OBJC_EXPORT 53 | @interface NSObject { 54 | Class isa OBJC_ISA_AVAILABILITY; 55 | } 56 | 57 | + (void)load; 58 | 59 | + (void)initialize; 60 | - (instancetype)init 61 | #if NS_ENFORCE_NSOBJECT_DESIGNATED_INITIALIZER 62 | NS_DESIGNATED_INITIALIZER 63 | #endif 64 | ; 65 | 66 | + (instancetype)new OBJC_SWIFT_UNAVAILABLE("use object initializers instead"); 67 | + (instancetype)allocWithZone:(struct _NSZone *)zone OBJC_SWIFT_UNAVAILABLE("use object initializers instead"); 68 | + (instancetype)alloc OBJC_SWIFT_UNAVAILABLE("use object initializers instead"); 69 | - (void)dealloc OBJC_SWIFT_UNAVAILABLE("use 'deinit' to define a de-initializer"); 70 | 71 | - (void)finalize OBJC_DEPRECATED("Objective-C garbage collection is no longer supported"); 72 | 73 | - (id)copy; 74 | - (id)mutableCopy; 75 | 76 | + (id)copyWithZone:(struct _NSZone *)zone OBJC_ARC_UNAVAILABLE; 77 | + (id)mutableCopyWithZone:(struct _NSZone *)zone OBJC_ARC_UNAVAILABLE; 78 | 79 | + (BOOL)instancesRespondToSelector:(SEL)aSelector; 80 | + (BOOL)conformsToProtocol:(Protocol *)protocol; 81 | - (IMP)methodForSelector:(SEL)aSelector; 82 | + (IMP)instanceMethodForSelector:(SEL)aSelector; 83 | - (void)doesNotRecognizeSelector:(SEL)aSelector; 84 | 85 | - (id)forwardingTargetForSelector:(SEL)aSelector OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); 86 | - (void)forwardInvocation:(NSInvocation *)anInvocation OBJC_SWIFT_UNAVAILABLE(""); 87 | - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector OBJC_SWIFT_UNAVAILABLE(""); 88 | 89 | + (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector OBJC_SWIFT_UNAVAILABLE(""); 90 | 91 | - (BOOL)allowsWeakReference UNAVAILABLE_ATTRIBUTE; 92 | - (BOOL)retainWeakReference UNAVAILABLE_ATTRIBUTE; 93 | 94 | + (BOOL)isSubclassOfClass:(Class)aClass; 95 | 96 | + (BOOL)resolveClassMethod:(SEL)sel OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); 97 | + (BOOL)resolveInstanceMethod:(SEL)sel OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); 98 | 99 | + (NSUInteger)hash; 100 | + (Class)superclass; 101 | + (Class)class OBJC_SWIFT_UNAVAILABLE("use 'aClass.self' instead"); 102 | + (NSString *)description; 103 | + (NSString *)debugDescription; 104 | 105 | @end 106 | 107 | #endif 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /runtime/Object.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2003, 2005-2007 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 | Object.h 25 | Copyright 1988-1996 NeXT Software, Inc. 26 | 27 | DEFINED AS: A common class 28 | HEADER FILES: 29 | 30 | */ 31 | 32 | #ifndef _OBJC_OBJECT_H_ 33 | #define _OBJC_OBJECT_H_ 34 | 35 | #include 36 | #include 37 | 38 | #if __OBJC__ && !__OBJC2__ 39 | 40 | __OSX_AVAILABLE(10.0) 41 | __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE 42 | OBJC_ROOT_CLASS 43 | @interface Object 44 | { 45 | Class isa; /* A pointer to the instance's class structure */ 46 | } 47 | 48 | /* Initializing classes and instances */ 49 | 50 | + (id)initialize; 51 | - (id)init; 52 | 53 | /* Creating, copying, and freeing instances */ 54 | 55 | + (id)new; 56 | + (id)free; 57 | - (id)free; 58 | + (id)alloc; 59 | - (id)copy; 60 | + (id)allocFromZone:(void *)zone; 61 | - (id)copyFromZone:(void *)zone; 62 | - (void *)zone; 63 | 64 | /* Identifying classes */ 65 | 66 | + (id)class; 67 | + (id)superclass; 68 | + (const char *) name; 69 | - (id)class; 70 | - (id)superclass; 71 | - (const char *) name; 72 | 73 | /* Identifying and comparing instances */ 74 | 75 | - (id)self; 76 | - (unsigned int) hash; 77 | - (BOOL) isEqual:anObject; 78 | 79 | /* Testing inheritance relationships */ 80 | 81 | - (BOOL) isKindOf: aClassObject; 82 | - (BOOL) isMemberOf: aClassObject; 83 | - (BOOL) isKindOfClassNamed: (const char *)aClassName; 84 | - (BOOL) isMemberOfClassNamed: (const char *)aClassName; 85 | 86 | /* Testing class functionality */ 87 | 88 | + (BOOL) instancesRespondTo:(SEL)aSelector; 89 | - (BOOL) respondsTo:(SEL)aSelector; 90 | 91 | /* Testing protocol conformance */ 92 | 93 | - (BOOL) conformsTo: (Protocol *)aProtocolObject; 94 | + (BOOL) conformsTo: (Protocol *)aProtocolObject; 95 | 96 | /* Obtaining method descriptors from protocols */ 97 | 98 | - (struct objc_method_description *) descriptionForMethod:(SEL)aSel; 99 | + (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel; 100 | 101 | /* Obtaining method handles */ 102 | 103 | - (IMP) methodFor:(SEL)aSelector; 104 | + (IMP) instanceMethodFor:(SEL)aSelector; 105 | 106 | /* Sending messages determined at run time */ 107 | 108 | - (id)perform:(SEL)aSelector; 109 | - (id)perform:(SEL)aSelector with:anObject; 110 | - (id)perform:(SEL)aSelector with:object1 with:object2; 111 | 112 | /* Posing */ 113 | 114 | + (id)poseAs: aClassObject; 115 | 116 | /* Enforcing intentions */ 117 | 118 | - (id)subclassResponsibility:(SEL)aSelector; 119 | - (id)notImplemented:(SEL)aSelector; 120 | 121 | /* Error handling */ 122 | 123 | - (id)doesNotRecognize:(SEL)aSelector; 124 | - (id)error:(const char *)aString, ...; 125 | 126 | /* Debugging */ 127 | 128 | - (void) printForDebugger:(void *)stream; 129 | 130 | /* Archiving */ 131 | 132 | - (id)awake; 133 | - (id)write:(void *)stream; 134 | - (id)read:(void *)stream; 135 | + (int) version; 136 | + (id)setVersion: (int) aVersion; 137 | 138 | /* Forwarding */ 139 | 140 | - (id)forward: (SEL)sel : (marg_list)args; 141 | - (id)performv: (SEL)sel : (marg_list)args; 142 | 143 | @end 144 | 145 | /* Abstract Protocol for Archiving */ 146 | 147 | @interface Object (Archiving) 148 | 149 | - (id)startArchiving: (void *)stream; 150 | - (id)finishUnarchiving; 151 | 152 | @end 153 | 154 | /* Abstract Protocol for Dynamic Loading */ 155 | 156 | @interface Object (DynamicLoading) 157 | 158 | //+ finishLoading:(headerType *)header; 159 | struct mach_header; 160 | + (id)finishLoading:(struct mach_header *)header; 161 | + (id)startUnloading; 162 | 163 | @end 164 | 165 | #endif 166 | 167 | #endif /* _OBJC_OBJECT_H_ */ 168 | -------------------------------------------------------------------------------- /runtime/OldClasses.subproj/List.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2002, 2005-2007 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 | List.h 25 | Copyright 1988-1996 NeXT Software, Inc. 26 | 27 | DEFINED AS: A common class 28 | HEADER FILES: objc/List.h 29 | 30 | */ 31 | 32 | #ifndef _OBJC_LIST_H_ 33 | #define _OBJC_LIST_H_ 34 | 35 | #if __OBJC__ && !__OBJC2__ && !__cplusplus && !__has_feature(objc_arc) 36 | 37 | #include 38 | #include 39 | 40 | DEPRECATED_ATTRIBUTE 41 | @interface List : Object 42 | { 43 | @public 44 | id *dataPtr DEPRECATED_ATTRIBUTE; /* data of the List object */ 45 | unsigned numElements DEPRECATED_ATTRIBUTE; /* Actual number of elements */ 46 | unsigned maxElements DEPRECATED_ATTRIBUTE; /* Total allocated elements */ 47 | } 48 | 49 | /* Creating, freeing */ 50 | 51 | - (id)free DEPRECATED_ATTRIBUTE; 52 | - (id)freeObjects DEPRECATED_ATTRIBUTE; 53 | - (id)copyFromZone:(void *)z DEPRECATED_ATTRIBUTE; 54 | 55 | /* Initializing */ 56 | 57 | - (id)init DEPRECATED_ATTRIBUTE; 58 | - (id)initCount:(unsigned)numSlots DEPRECATED_ATTRIBUTE; 59 | 60 | /* Comparing two lists */ 61 | 62 | - (BOOL)isEqual: anObject DEPRECATED_ATTRIBUTE; 63 | 64 | /* Managing the storage capacity */ 65 | 66 | - (unsigned)capacity DEPRECATED_ATTRIBUTE; 67 | - (id)setAvailableCapacity:(unsigned)numSlots DEPRECATED_ATTRIBUTE; 68 | 69 | /* Manipulating objects by index */ 70 | 71 | - (unsigned)count DEPRECATED_ATTRIBUTE; 72 | - (id)objectAt:(unsigned)index DEPRECATED_ATTRIBUTE; 73 | - (id)lastObject DEPRECATED_ATTRIBUTE; 74 | - (id)addObject:anObject DEPRECATED_ATTRIBUTE; 75 | - (id)insertObject:anObject at:(unsigned)index DEPRECATED_ATTRIBUTE; 76 | - (id)removeObjectAt:(unsigned)index DEPRECATED_ATTRIBUTE; 77 | - (id)removeLastObject DEPRECATED_ATTRIBUTE; 78 | - (id)replaceObjectAt:(unsigned)index with:newObject DEPRECATED_ATTRIBUTE; 79 | - (id)appendList: (List *)otherList DEPRECATED_ATTRIBUTE; 80 | 81 | /* Manipulating objects by id */ 82 | 83 | - (unsigned)indexOf:anObject DEPRECATED_ATTRIBUTE; 84 | - (id)addObjectIfAbsent:anObject DEPRECATED_ATTRIBUTE; 85 | - (id)removeObject:anObject DEPRECATED_ATTRIBUTE; 86 | - (id)replaceObject:anObject with:newObject DEPRECATED_ATTRIBUTE; 87 | 88 | /* Emptying the list */ 89 | 90 | - (id)empty DEPRECATED_ATTRIBUTE; 91 | 92 | /* Sending messages to elements of the list */ 93 | 94 | - (id)makeObjectsPerform:(SEL)aSelector DEPRECATED_ATTRIBUTE; 95 | - (id)makeObjectsPerform:(SEL)aSelector with:anObject DEPRECATED_ATTRIBUTE; 96 | 97 | /* 98 | * The following new... methods are now obsolete. They remain in this 99 | * interface file for backward compatibility only. Use Object's alloc method 100 | * and the init... methods defined in this class instead. 101 | */ 102 | 103 | + (id)new DEPRECATED_ATTRIBUTE; 104 | + (id)newCount:(unsigned)numSlots DEPRECATED_ATTRIBUTE; 105 | 106 | @end 107 | 108 | typedef struct { 109 | @defs(List); 110 | } NXListId DEPRECATED_ATTRIBUTE; 111 | 112 | #define NX_ADDRESS(x) (((NXListId *)(x))->dataPtr) 113 | 114 | #define NX_NOT_IN_LIST 0xffffffff 115 | 116 | #endif 117 | 118 | #endif /* _OBJC_LIST_H_ */ 119 | -------------------------------------------------------------------------------- /runtime/OldClasses.subproj/List.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2001, 2005-2006 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 | List.m 25 | Copyright 1988-1996 NeXT Software, Inc. 26 | Written by: Bryan Yamamoto 27 | Responsibility: Bertrand Serlet 28 | */ 29 | 30 | #ifndef __OBJC2__ 31 | 32 | #include 33 | #include 34 | #include 35 | 36 | #include 37 | 38 | #define DATASIZE(count) ((count) * sizeof(id)) 39 | 40 | @implementation List 41 | 42 | + (id)initialize 43 | { 44 | [self setVersion: 1]; 45 | return self; 46 | } 47 | 48 | - (id)initCount:(unsigned)numSlots 49 | { 50 | maxElements = numSlots; 51 | if (maxElements) 52 | dataPtr = (id *)malloc(DATASIZE(maxElements)); 53 | return self; 54 | } 55 | 56 | + (id)newCount:(unsigned)numSlots 57 | { 58 | return [[self alloc] initCount:numSlots]; 59 | } 60 | 61 | + (id)new 62 | { 63 | return [self newCount:0]; 64 | } 65 | 66 | - (id)init 67 | { 68 | return [self initCount:0]; 69 | } 70 | 71 | - (id)free 72 | { 73 | free(dataPtr); 74 | return [super free]; 75 | } 76 | 77 | - (id)freeObjects 78 | { 79 | id element; 80 | while ((element = [self removeLastObject])) 81 | [element free]; 82 | return self; 83 | } 84 | 85 | - (id)copyFromZone:(void *)z 86 | { 87 | List *new = [[[self class] alloc] initCount: numElements]; 88 | new->numElements = numElements; 89 | bcopy ((const char*)dataPtr, (char*)new->dataPtr, DATASIZE(numElements)); 90 | return new; 91 | } 92 | 93 | - (BOOL) isEqual: anObject 94 | { 95 | List *other; 96 | if (! [anObject isKindOf: [self class]]) return NO; 97 | other = (List *) anObject; 98 | return (numElements == other->numElements) 99 | && (bcmp ((const char*)dataPtr, (const char*)other->dataPtr, DATASIZE(numElements)) == 0); 100 | } 101 | 102 | - (unsigned)capacity 103 | { 104 | return maxElements; 105 | } 106 | 107 | - (unsigned)count 108 | { 109 | return numElements; 110 | } 111 | 112 | - (id)objectAt:(unsigned)index 113 | { 114 | if (index >= numElements) 115 | return nil; 116 | return dataPtr[index]; 117 | } 118 | 119 | - (unsigned)indexOf:anObject 120 | { 121 | register id *this = dataPtr; 122 | register id *last = this + numElements; 123 | while (this < last) { 124 | if (*this == anObject) 125 | return this - dataPtr; 126 | this++; 127 | } 128 | return NX_NOT_IN_LIST; 129 | } 130 | 131 | - (id)lastObject 132 | { 133 | if (! numElements) 134 | return nil; 135 | return dataPtr[numElements - 1]; 136 | } 137 | 138 | - (id)setAvailableCapacity:(unsigned)numSlots 139 | { 140 | volatile id *tempDataPtr; 141 | if (numSlots < numElements) return nil; 142 | tempDataPtr = (id *) realloc (dataPtr, DATASIZE(numSlots)); 143 | dataPtr = (id *)tempDataPtr; 144 | maxElements = numSlots; 145 | return self; 146 | } 147 | 148 | - (id)insertObject:anObject at:(unsigned)index 149 | { 150 | register id *this, *last, *prev; 151 | if (! anObject) return nil; 152 | if (index > numElements) 153 | return nil; 154 | if ((numElements + 1) > maxElements) { 155 | volatile id *tempDataPtr; 156 | /* we double the capacity, also a good size for malloc */ 157 | maxElements += maxElements + 1; 158 | tempDataPtr = (id *) realloc (dataPtr, DATASIZE(maxElements)); 159 | dataPtr = (id*)tempDataPtr; 160 | } 161 | this = dataPtr + numElements; 162 | prev = this - 1; 163 | last = dataPtr + index; 164 | while (this > last) 165 | *this-- = *prev--; 166 | *last = anObject; 167 | numElements++; 168 | return self; 169 | } 170 | 171 | - (id)addObject:anObject 172 | { 173 | return [self insertObject:anObject at:numElements]; 174 | 175 | } 176 | 177 | 178 | - (id)addObjectIfAbsent:anObject 179 | { 180 | register id *this, *last; 181 | if (! anObject) return nil; 182 | this = dataPtr; 183 | last = dataPtr + numElements; 184 | while (this < last) { 185 | if (*this == anObject) 186 | return self; 187 | this++; 188 | } 189 | return [self insertObject:anObject at:numElements]; 190 | 191 | } 192 | 193 | 194 | - (id)removeObjectAt:(unsigned)index 195 | { 196 | register id *this, *last, *next; 197 | id retval; 198 | if (index >= numElements) 199 | return nil; 200 | this = dataPtr + index; 201 | last = dataPtr + numElements; 202 | next = this + 1; 203 | retval = *this; 204 | while (next < last) 205 | *this++ = *next++; 206 | numElements--; 207 | return retval; 208 | } 209 | 210 | - (id)removeObject:anObject 211 | { 212 | register id *this, *last; 213 | this = dataPtr; 214 | last = dataPtr + numElements; 215 | while (this < last) { 216 | if (*this == anObject) 217 | return [self removeObjectAt:this - dataPtr]; 218 | this++; 219 | } 220 | return nil; 221 | } 222 | 223 | - (id)removeLastObject 224 | { 225 | if (! numElements) 226 | return nil; 227 | return [self removeObjectAt: numElements - 1]; 228 | } 229 | 230 | - (id)empty 231 | { 232 | numElements = 0; 233 | return self; 234 | } 235 | 236 | - (id)replaceObject:anObject with:newObject 237 | { 238 | register id *this, *last; 239 | if (! newObject) 240 | return nil; 241 | this = dataPtr; 242 | last = dataPtr + numElements; 243 | while (this < last) { 244 | if (*this == anObject) { 245 | *this = newObject; 246 | return anObject; 247 | } 248 | this++; 249 | } 250 | return nil; 251 | } 252 | 253 | - (id)replaceObjectAt:(unsigned)index with:newObject 254 | { 255 | register id *this; 256 | id retval; 257 | if (! newObject) 258 | return nil; 259 | if (index >= numElements) 260 | return nil; 261 | this = dataPtr + index; 262 | retval = *this; 263 | *this = newObject; 264 | return retval; 265 | } 266 | 267 | - (id)makeObjectsPerform:(SEL)aSelector 268 | { 269 | unsigned count = numElements; 270 | while (count--) 271 | [dataPtr[count] perform: aSelector]; 272 | return self; 273 | } 274 | 275 | - (id)makeObjectsPerform:(SEL)aSelector with:anObject 276 | { 277 | unsigned count = numElements; 278 | while (count--) 279 | [dataPtr[count] perform: aSelector with: anObject]; 280 | return self; 281 | } 282 | 283 | -(id)appendList: (List *)otherList 284 | { 285 | unsigned i, count; 286 | 287 | for (i = 0, count = [otherList count]; i < count; i++) 288 | [self addObject: [otherList objectAt: i]]; 289 | return self; 290 | } 291 | 292 | @end 293 | 294 | #endif 295 | -------------------------------------------------------------------------------- /runtime/Protocol.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2003, 2006-2007 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 | Protocol.h 25 | Copyright 1991-1996 NeXT Software, Inc. 26 | */ 27 | 28 | #ifndef _OBJC_PROTOCOL_H_ 29 | #define _OBJC_PROTOCOL_H_ 30 | 31 | #if !__OBJC__ 32 | 33 | // typedef Protocol is here: 34 | #include 35 | 36 | 37 | #elif __OBJC2__ 38 | 39 | #include 40 | 41 | // All methods of class Protocol are unavailable. 42 | // Use the functions in objc/runtime.h instead. 43 | 44 | OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) 45 | @interface Protocol : NSObject 46 | @end 47 | 48 | 49 | #else 50 | 51 | #include 52 | 53 | OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0) 54 | @interface Protocol : Object 55 | { 56 | @private 57 | char *protocol_name OBJC2_UNAVAILABLE; 58 | struct objc_protocol_list *protocol_list OBJC2_UNAVAILABLE; 59 | struct objc_method_description_list *instance_methods OBJC2_UNAVAILABLE; 60 | struct objc_method_description_list *class_methods OBJC2_UNAVAILABLE; 61 | } 62 | 63 | /* Obtaining attributes intrinsic to the protocol */ 64 | 65 | - (const char *)name OBJC2_UNAVAILABLE; 66 | 67 | /* Testing protocol conformance */ 68 | 69 | - (BOOL) conformsTo: (Protocol *)aProtocolObject OBJC2_UNAVAILABLE; 70 | 71 | /* Looking up information specific to a protocol */ 72 | 73 | - (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel 74 | __OSX_DEPRECATED(10.0, 10.5, "use protocol_getMethodDescription instead") 75 | __IOS_DEPRECATED(2.0, 2.0, "use protocol_getMethodDescription instead") 76 | __TVOS_DEPRECATED(9.0, 9.0, "use protocol_getMethodDescription instead") 77 | __WATCHOS_DEPRECATED(1.0, 1.0, "use protocol_getMethodDescription instead"); 78 | - (struct objc_method_description *) descriptionForClassMethod:(SEL)aSel 79 | __OSX_DEPRECATED(10.0, 10.5, "use protocol_getMethodDescription instead") 80 | __IOS_DEPRECATED(2.0, 2.0, "use protocol_getMethodDescription instead") 81 | __TVOS_DEPRECATED(9.0, 9.0, "use protocol_getMethodDescription instead") 82 | __WATCHOS_DEPRECATED(1.0, 1.0, "use protocol_getMethodDescription instead"); 83 | 84 | @end 85 | 86 | #endif 87 | 88 | #endif /* _OBJC_PROTOCOL_H_ */ 89 | -------------------------------------------------------------------------------- /runtime/Protocol.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2001, 2005-2007 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 | Protocol.h 25 | Copyright 1991-1996 NeXT Software, Inc. 26 | */ 27 | 28 | #include "objc-private.h" 29 | 30 | #undef id 31 | #undef Class 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include "Protocol.h" 39 | #include "NSObject.h" 40 | 41 | // __IncompleteProtocol is used as the return type of objc_allocateProtocol(). 42 | 43 | // Old ABI uses NSObject as the superclass even though Protocol uses Object 44 | // because the R/R implementation for class Protocol is added at runtime 45 | // by CF, so __IncompleteProtocol would be left without an R/R implementation 46 | // otherwise, which would break ARC. 47 | 48 | @interface __IncompleteProtocol : NSObject @end 49 | @implementation __IncompleteProtocol 50 | #if __OBJC2__ 51 | // fixme hack - make __IncompleteProtocol a non-lazy class 52 | + (void) load { } 53 | #endif 54 | @end 55 | 56 | 57 | @implementation Protocol 58 | 59 | #if __OBJC2__ 60 | // fixme hack - make Protocol a non-lazy class 61 | + (void) load { } 62 | #endif 63 | 64 | 65 | - (BOOL) conformsTo: (Protocol *)aProtocolObj 66 | { 67 | return protocol_conformsToProtocol(self, aProtocolObj); 68 | } 69 | 70 | - (struct objc_method_description *) descriptionForInstanceMethod:(SEL)aSel 71 | { 72 | #if !__OBJC2__ 73 | return lookup_protocol_method((struct old_protocol *)self, aSel, 74 | YES/*required*/, YES/*instance*/, 75 | YES/*recursive*/); 76 | #else 77 | return method_getDescription(protocol_getMethod((struct protocol_t *)self, 78 | aSel, YES, YES, YES)); 79 | #endif 80 | } 81 | 82 | - (struct objc_method_description *) descriptionForClassMethod:(SEL)aSel 83 | { 84 | #if !__OBJC2__ 85 | return lookup_protocol_method((struct old_protocol *)self, aSel, 86 | YES/*required*/, NO/*instance*/, 87 | YES/*recursive*/); 88 | #else 89 | return method_getDescription(protocol_getMethod((struct protocol_t *)self, 90 | aSel, YES, NO, YES)); 91 | #endif 92 | } 93 | 94 | - (const char *)name 95 | { 96 | return protocol_getName(self); 97 | } 98 | 99 | - (BOOL)isEqual:other 100 | { 101 | #if __OBJC2__ 102 | // check isKindOf: 103 | Class cls; 104 | Class protoClass = objc_getClass("Protocol"); 105 | for (cls = object_getClass(other); cls; cls = cls->superclass) { 106 | if (cls == protoClass) break; 107 | } 108 | if (!cls) return NO; 109 | // check equality 110 | return protocol_isEqual(self, other); 111 | #else 112 | return [other isKindOf:[Protocol class]] && [self conformsTo: other] && [other conformsTo: self]; 113 | #endif 114 | } 115 | 116 | #if __OBJC2__ 117 | - (NSUInteger)hash 118 | { 119 | return 23; 120 | } 121 | #else 122 | - (unsigned)hash 123 | { 124 | return 23; 125 | } 126 | #endif 127 | 128 | @end 129 | -------------------------------------------------------------------------------- /runtime/a1a2-blocktramps-arm.s: -------------------------------------------------------------------------------- 1 | #if __arm__ 2 | 3 | #include 4 | #include 5 | 6 | .syntax unified 7 | 8 | .text 9 | 10 | .private_extern __a1a2_tramphead 11 | .private_extern __a1a2_firsttramp 12 | .private_extern __a1a2_trampend 13 | 14 | // Trampoline machinery assumes the trampolines are Thumb function pointers 15 | #if !__thumb2__ 16 | # error sorry 17 | #endif 18 | 19 | .thumb 20 | .thumb_func __a1a2_tramphead 21 | .thumb_func __a1a2_firsttramp 22 | .thumb_func __a1a2_trampend 23 | 24 | .align PAGE_MAX_SHIFT 25 | __a1a2_tramphead: 26 | /* 27 | r0 == self 28 | r12 == pc of trampoline's first instruction + PC bias 29 | lr == original return address 30 | */ 31 | 32 | mov r1, r0 // _cmd = self 33 | 34 | // Trampoline's data is one page before the trampoline text. 35 | // Also correct PC bias of 4 bytes. 36 | sub r12, #PAGE_MAX_SIZE 37 | ldr r0, [r12, #-4] // self = block object 38 | ldr pc, [r0, #12] // tail call block->invoke 39 | // not reached 40 | 41 | // Align trampolines to 8 bytes 42 | .align 3 43 | 44 | .macro TrampolineEntry 45 | mov r12, pc 46 | b __a1a2_tramphead 47 | .align 3 48 | .endmacro 49 | 50 | .macro TrampolineEntryX16 51 | TrampolineEntry 52 | TrampolineEntry 53 | TrampolineEntry 54 | TrampolineEntry 55 | 56 | TrampolineEntry 57 | TrampolineEntry 58 | TrampolineEntry 59 | TrampolineEntry 60 | 61 | TrampolineEntry 62 | TrampolineEntry 63 | TrampolineEntry 64 | TrampolineEntry 65 | 66 | TrampolineEntry 67 | TrampolineEntry 68 | TrampolineEntry 69 | TrampolineEntry 70 | .endmacro 71 | 72 | .macro TrampolineEntryX256 73 | TrampolineEntryX16 74 | TrampolineEntryX16 75 | TrampolineEntryX16 76 | TrampolineEntryX16 77 | 78 | TrampolineEntryX16 79 | TrampolineEntryX16 80 | TrampolineEntryX16 81 | TrampolineEntryX16 82 | 83 | TrampolineEntryX16 84 | TrampolineEntryX16 85 | TrampolineEntryX16 86 | TrampolineEntryX16 87 | 88 | TrampolineEntryX16 89 | TrampolineEntryX16 90 | TrampolineEntryX16 91 | TrampolineEntryX16 92 | .endmacro 93 | 94 | .private_extern __a1a2_firsttramp 95 | __a1a2_firsttramp: 96 | // 2048-2 trampolines to fill 16K page 97 | TrampolineEntryX256 98 | TrampolineEntryX256 99 | TrampolineEntryX256 100 | TrampolineEntryX256 101 | 102 | TrampolineEntryX256 103 | TrampolineEntryX256 104 | TrampolineEntryX256 105 | 106 | TrampolineEntryX16 107 | TrampolineEntryX16 108 | TrampolineEntryX16 109 | TrampolineEntryX16 110 | 111 | TrampolineEntryX16 112 | TrampolineEntryX16 113 | TrampolineEntryX16 114 | TrampolineEntryX16 115 | 116 | TrampolineEntryX16 117 | TrampolineEntryX16 118 | TrampolineEntryX16 119 | TrampolineEntryX16 120 | 121 | TrampolineEntryX16 122 | TrampolineEntryX16 123 | TrampolineEntryX16 124 | 125 | TrampolineEntry 126 | TrampolineEntry 127 | TrampolineEntry 128 | TrampolineEntry 129 | 130 | TrampolineEntry 131 | TrampolineEntry 132 | TrampolineEntry 133 | TrampolineEntry 134 | 135 | TrampolineEntry 136 | TrampolineEntry 137 | TrampolineEntry 138 | TrampolineEntry 139 | 140 | TrampolineEntry 141 | TrampolineEntry 142 | // TrampolineEntry 143 | // TrampolineEntry 144 | 145 | .private_extern __a1a2_trampend 146 | __a1a2_trampend: 147 | 148 | #endif 149 | -------------------------------------------------------------------------------- /runtime/a1a2-blocktramps-arm64.s: -------------------------------------------------------------------------------- 1 | #if __arm64__ 2 | 3 | #include 4 | 5 | .text 6 | 7 | .private_extern __a1a2_tramphead 8 | .private_extern __a1a2_firsttramp 9 | .private_extern __a1a2_trampend 10 | 11 | .align PAGE_MAX_SHIFT 12 | __a1a2_tramphead: 13 | L_a1a2_tramphead: 14 | /* 15 | x0 == self 16 | x17 == address of called trampoline's data (1 page before its code) 17 | lr == original return address 18 | */ 19 | 20 | mov x1, x0 // _cmd = self 21 | ldr x0, [x17] // self = block object 22 | ldr x16, [x0, #16] // tail call block->invoke 23 | br x16 24 | 25 | // pad up to TrampolineBlockPagePair header size 26 | nop 27 | nop 28 | 29 | .macro TrampolineEntry 30 | // load address of trampoline data (one page before this instruction) 31 | adr x17, -PAGE_MAX_SIZE 32 | b L_a1a2_tramphead 33 | .endmacro 34 | 35 | .macro TrampolineEntryX16 36 | TrampolineEntry 37 | TrampolineEntry 38 | TrampolineEntry 39 | TrampolineEntry 40 | 41 | TrampolineEntry 42 | TrampolineEntry 43 | TrampolineEntry 44 | TrampolineEntry 45 | 46 | TrampolineEntry 47 | TrampolineEntry 48 | TrampolineEntry 49 | TrampolineEntry 50 | 51 | TrampolineEntry 52 | TrampolineEntry 53 | TrampolineEntry 54 | TrampolineEntry 55 | .endmacro 56 | 57 | .macro TrampolineEntryX256 58 | TrampolineEntryX16 59 | TrampolineEntryX16 60 | TrampolineEntryX16 61 | TrampolineEntryX16 62 | 63 | TrampolineEntryX16 64 | TrampolineEntryX16 65 | TrampolineEntryX16 66 | TrampolineEntryX16 67 | 68 | TrampolineEntryX16 69 | TrampolineEntryX16 70 | TrampolineEntryX16 71 | TrampolineEntryX16 72 | 73 | TrampolineEntryX16 74 | TrampolineEntryX16 75 | TrampolineEntryX16 76 | TrampolineEntryX16 77 | .endmacro 78 | 79 | .align 3 80 | .private_extern __a1a2_firsttramp 81 | __a1a2_firsttramp: 82 | // 2048-3 trampolines to fill 16K page 83 | TrampolineEntryX256 84 | TrampolineEntryX256 85 | TrampolineEntryX256 86 | TrampolineEntryX256 87 | 88 | TrampolineEntryX256 89 | TrampolineEntryX256 90 | TrampolineEntryX256 91 | 92 | TrampolineEntryX16 93 | TrampolineEntryX16 94 | TrampolineEntryX16 95 | TrampolineEntryX16 96 | 97 | TrampolineEntryX16 98 | TrampolineEntryX16 99 | TrampolineEntryX16 100 | TrampolineEntryX16 101 | 102 | TrampolineEntryX16 103 | TrampolineEntryX16 104 | TrampolineEntryX16 105 | TrampolineEntryX16 106 | 107 | TrampolineEntryX16 108 | TrampolineEntryX16 109 | TrampolineEntryX16 110 | 111 | TrampolineEntry 112 | TrampolineEntry 113 | TrampolineEntry 114 | TrampolineEntry 115 | 116 | TrampolineEntry 117 | TrampolineEntry 118 | TrampolineEntry 119 | TrampolineEntry 120 | 121 | TrampolineEntry 122 | TrampolineEntry 123 | TrampolineEntry 124 | TrampolineEntry 125 | 126 | TrampolineEntry 127 | // TrampolineEntry 128 | // TrampolineEntry 129 | // TrampolineEntry 130 | 131 | .private_extern __a1a2_trampend 132 | __a1a2_trampend: 133 | 134 | #endif 135 | -------------------------------------------------------------------------------- /runtime/a2a3-blocktramps-arm.s: -------------------------------------------------------------------------------- 1 | #if __arm__ 2 | 3 | #include 4 | #include 5 | 6 | .syntax unified 7 | 8 | .text 9 | 10 | .private_extern __a2a3_tramphead 11 | .private_extern __a2a3_firsttramp 12 | .private_extern __a2a3_trampend 13 | 14 | // Trampoline machinery assumes the trampolines are Thumb function pointers 15 | #if !__thumb2__ 16 | # error sorry 17 | #endif 18 | 19 | .thumb 20 | .thumb_func __a2a3_tramphead 21 | .thumb_func __a2a3_firsttramp 22 | .thumb_func __a2a3_trampend 23 | 24 | .align PAGE_MAX_SHIFT 25 | __a2a3_tramphead: 26 | /* 27 | r1 == self 28 | r12 == pc of trampoline's first instruction + PC bias 29 | lr == original return address 30 | */ 31 | 32 | mov r2, r1 // _cmd = self 33 | 34 | // Trampoline's data is one page before the trampoline text. 35 | // Also correct PC bias of 4 bytes. 36 | sub r12, #PAGE_MAX_SIZE 37 | ldr r1, [r12, #-4] // self = block object 38 | ldr pc, [r1, #12] // tail call block->invoke 39 | // not reached 40 | 41 | // Align trampolines to 8 bytes 42 | .align 3 43 | 44 | .macro TrampolineEntry 45 | mov r12, pc 46 | b __a2a3_tramphead 47 | .align 3 48 | .endmacro 49 | 50 | .macro TrampolineEntryX16 51 | TrampolineEntry 52 | TrampolineEntry 53 | TrampolineEntry 54 | TrampolineEntry 55 | 56 | TrampolineEntry 57 | TrampolineEntry 58 | TrampolineEntry 59 | TrampolineEntry 60 | 61 | TrampolineEntry 62 | TrampolineEntry 63 | TrampolineEntry 64 | TrampolineEntry 65 | 66 | TrampolineEntry 67 | TrampolineEntry 68 | TrampolineEntry 69 | TrampolineEntry 70 | .endmacro 71 | 72 | .macro TrampolineEntryX256 73 | TrampolineEntryX16 74 | TrampolineEntryX16 75 | TrampolineEntryX16 76 | TrampolineEntryX16 77 | 78 | TrampolineEntryX16 79 | TrampolineEntryX16 80 | TrampolineEntryX16 81 | TrampolineEntryX16 82 | 83 | TrampolineEntryX16 84 | TrampolineEntryX16 85 | TrampolineEntryX16 86 | TrampolineEntryX16 87 | 88 | TrampolineEntryX16 89 | TrampolineEntryX16 90 | TrampolineEntryX16 91 | TrampolineEntryX16 92 | .endmacro 93 | 94 | .private_extern __a2a3_firsttramp 95 | __a2a3_firsttramp: 96 | // 2048-2 trampolines to fill 16K page 97 | TrampolineEntryX256 98 | TrampolineEntryX256 99 | TrampolineEntryX256 100 | TrampolineEntryX256 101 | 102 | TrampolineEntryX256 103 | TrampolineEntryX256 104 | TrampolineEntryX256 105 | 106 | TrampolineEntryX16 107 | TrampolineEntryX16 108 | TrampolineEntryX16 109 | TrampolineEntryX16 110 | 111 | TrampolineEntryX16 112 | TrampolineEntryX16 113 | TrampolineEntryX16 114 | TrampolineEntryX16 115 | 116 | TrampolineEntryX16 117 | TrampolineEntryX16 118 | TrampolineEntryX16 119 | TrampolineEntryX16 120 | 121 | TrampolineEntryX16 122 | TrampolineEntryX16 123 | TrampolineEntryX16 124 | 125 | TrampolineEntry 126 | TrampolineEntry 127 | TrampolineEntry 128 | TrampolineEntry 129 | 130 | TrampolineEntry 131 | TrampolineEntry 132 | TrampolineEntry 133 | TrampolineEntry 134 | 135 | TrampolineEntry 136 | TrampolineEntry 137 | TrampolineEntry 138 | TrampolineEntry 139 | 140 | TrampolineEntry 141 | TrampolineEntry 142 | // TrampolineEntry 143 | // TrampolineEntry 144 | 145 | .private_extern __a2a3_trampend 146 | __a2a3_trampend: 147 | 148 | #endif 149 | -------------------------------------------------------------------------------- /runtime/hashtable.h: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | -------------------------------------------------------------------------------- /runtime/llvm-AlignOf.h: -------------------------------------------------------------------------------- 1 | //===--- AlignOf.h - Portable calculation of type alignment -----*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file defines the AlignOf function that computes alignments for 11 | // arbitrary types. 12 | // 13 | //===----------------------------------------------------------------------===// 14 | 15 | // Taken from llvmCore-3425.0.31. 16 | 17 | #ifndef LLVM_SUPPORT_ALIGNOF_H 18 | #define LLVM_SUPPORT_ALIGNOF_H 19 | 20 | #include 21 | 22 | namespace objc { 23 | 24 | template 25 | struct AlignmentCalcImpl { 26 | char x; 27 | T t; 28 | private: 29 | AlignmentCalcImpl() {} // Never instantiate. 30 | }; 31 | 32 | /// AlignOf - A templated class that contains an enum value representing 33 | /// the alignment of the template argument. For example, 34 | /// AlignOf::Alignment represents the alignment of type "int". The 35 | /// alignment calculated is the minimum alignment, and not necessarily 36 | /// the "desired" alignment returned by GCC's __alignof__ (for example). Note 37 | /// that because the alignment is an enum value, it can be used as a 38 | /// compile-time constant (e.g., for template instantiation). 39 | template 40 | struct AlignOf { 41 | enum { Alignment = 42 | static_cast(sizeof(AlignmentCalcImpl) - sizeof(T)) }; 43 | 44 | enum { Alignment_GreaterEqual_2Bytes = Alignment >= 2 ? 1 : 0 }; 45 | enum { Alignment_GreaterEqual_4Bytes = Alignment >= 4 ? 1 : 0 }; 46 | enum { Alignment_GreaterEqual_8Bytes = Alignment >= 8 ? 1 : 0 }; 47 | enum { Alignment_GreaterEqual_16Bytes = Alignment >= 16 ? 1 : 0 }; 48 | 49 | enum { Alignment_LessEqual_2Bytes = Alignment <= 2 ? 1 : 0 }; 50 | enum { Alignment_LessEqual_4Bytes = Alignment <= 4 ? 1 : 0 }; 51 | enum { Alignment_LessEqual_8Bytes = Alignment <= 8 ? 1 : 0 }; 52 | enum { Alignment_LessEqual_16Bytes = Alignment <= 16 ? 1 : 0 }; 53 | 54 | }; 55 | 56 | /// alignOf - A templated function that returns the minimum alignment of 57 | /// of a type. This provides no extra functionality beyond the AlignOf 58 | /// class besides some cosmetic cleanliness. Example usage: 59 | /// alignOf() returns the alignment of an int. 60 | template 61 | inline unsigned alignOf() { return AlignOf::Alignment; } 62 | 63 | 64 | /// \brief Helper for building an aligned character array type. 65 | /// 66 | /// This template is used to explicitly build up a collection of aligned 67 | /// character types. We have to build these up using a macro and explicit 68 | /// specialization to cope with old versions of MSVC and GCC where only an 69 | /// integer literal can be used to specify an alignment constraint. Once built 70 | /// up here, we can then begin to indirect between these using normal C++ 71 | /// template parameters. 72 | template struct AlignedCharArrayImpl; 73 | 74 | // MSVC requires special handling here. 75 | #ifndef _MSC_VER 76 | 77 | #if __has_feature(cxx_alignas) 78 | #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ 79 | template <> struct AlignedCharArrayImpl { \ 80 | char aligned alignas(x); \ 81 | } 82 | #elif defined(__GNUC__) 83 | #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ 84 | template <> struct AlignedCharArrayImpl { \ 85 | char aligned __attribute__((aligned(x))); \ 86 | } 87 | #else 88 | # error No supported align as directive. 89 | #endif 90 | 91 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1); 92 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2); 93 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4); 94 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8); 95 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16); 96 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32); 97 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64); 98 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128); 99 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512); 100 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024); 101 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048); 102 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096); 103 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192); 104 | 105 | #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT 106 | 107 | #else // _MSC_VER 108 | 109 | // We provide special variations of this template for the most common 110 | // alignments because __declspec(align(...)) doesn't actually work when it is 111 | // a member of a by-value function argument in MSVC, even if the alignment 112 | // request is something reasonably like 8-byte or 16-byte. 113 | template <> struct AlignedCharArrayImpl<1> { char aligned; }; 114 | template <> struct AlignedCharArrayImpl<2> { short aligned; }; 115 | template <> struct AlignedCharArrayImpl<4> { int aligned; }; 116 | template <> struct AlignedCharArrayImpl<8> { double aligned; }; 117 | 118 | #define LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(x) \ 119 | template <> struct AlignedCharArrayImpl { \ 120 | __declspec(align(x)) char aligned; \ 121 | } 122 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(16); 123 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(32); 124 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(64); 125 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(128); 126 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(512); 127 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(1024); 128 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(2048); 129 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(4096); 130 | LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT(8192); 131 | // Any larger and MSVC complains. 132 | #undef LLVM_ALIGNEDCHARARRAY_TEMPLATE_ALIGNMENT 133 | 134 | #endif // _MSC_VER 135 | 136 | /// \brief This union template exposes a suitably aligned and sized character 137 | /// array member which can hold elements of any of up to four types. 138 | /// 139 | /// These types may be arrays, structs, or any other types. The goal is to 140 | /// produce a union type containing a character array which, when used, forms 141 | /// storage suitable to placement new any of these types over. Support for more 142 | /// than four types can be added at the cost of more boiler plate. 143 | template 145 | union AlignedCharArrayUnion { 146 | private: 147 | class AlignerImpl { 148 | T1 t1; T2 t2; T3 t3; T4 t4; 149 | 150 | AlignerImpl(); // Never defined or instantiated. 151 | }; 152 | union SizerImpl { 153 | char arr1[sizeof(T1)], arr2[sizeof(T2)], arr3[sizeof(T3)], arr4[sizeof(T4)]; 154 | }; 155 | 156 | public: 157 | /// \brief The character array buffer for use by clients. 158 | /// 159 | /// No other member of this union should be referenced. The exist purely to 160 | /// constrain the layout of this character array. 161 | char buffer[sizeof(SizerImpl)]; 162 | 163 | private: 164 | // Tests seem to indicate that both Clang and GCC will properly register the 165 | // alignment of a struct containing an aligned member, and this alignment 166 | // should carry over to the character array in the union. 167 | AlignedCharArrayImpl::Alignment> nonce_member; 168 | }; 169 | 170 | } // end namespace objc 171 | #endif 172 | -------------------------------------------------------------------------------- /runtime/llvm-DenseMapInfo.h: -------------------------------------------------------------------------------- 1 | //===- llvm/ADT/DenseMapInfo.h - Type traits for DenseMap -------*- C++ -*-===// 2 | // 3 | // The LLVM Compiler Infrastructure 4 | // 5 | // This file is distributed under the University of Illinois Open Source 6 | // License. See LICENSE.TXT for details. 7 | // 8 | //===----------------------------------------------------------------------===// 9 | // 10 | // This file defines DenseMapInfo traits for DenseMap. 11 | // 12 | //===----------------------------------------------------------------------===// 13 | 14 | // Taken from llvmCore-3425.0.31. 15 | 16 | #ifndef LLVM_ADT_DENSEMAPINFO_H 17 | #define LLVM_ADT_DENSEMAPINFO_H 18 | 19 | #include "objc-private.h" 20 | #include "llvm-type_traits.h" 21 | 22 | namespace objc { 23 | 24 | template 25 | struct DenseMapInfo { 26 | //static inline T getEmptyKey(); 27 | //static inline T getTombstoneKey(); 28 | //static unsigned getHashValue(const T &Val); 29 | //static bool isEqual(const T &LHS, const T &RHS); 30 | }; 31 | 32 | // Provide DenseMapInfo for all pointers. 33 | template 34 | struct DenseMapInfo { 35 | static inline T* getEmptyKey() { 36 | uintptr_t Val = static_cast(-1); 37 | return reinterpret_cast(Val); 38 | } 39 | static inline T* getTombstoneKey() { 40 | uintptr_t Val = static_cast(-2); 41 | return reinterpret_cast(Val); 42 | } 43 | static unsigned getHashValue(const T *PtrVal) { 44 | return ptr_hash((uintptr_t)PtrVal); 45 | } 46 | static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; } 47 | }; 48 | 49 | // Provide DenseMapInfo for disguised pointers. 50 | template 51 | struct DenseMapInfo> { 52 | static inline DisguisedPtr getEmptyKey() { 53 | return DisguisedPtr((T*)(uintptr_t)-1); 54 | } 55 | static inline DisguisedPtr getTombstoneKey() { 56 | return DisguisedPtr((T*)(uintptr_t)-2); 57 | } 58 | static unsigned getHashValue(const T *PtrVal) { 59 | return ptr_hash((uintptr_t)PtrVal); 60 | } 61 | static bool isEqual(const DisguisedPtr &LHS, const DisguisedPtr &RHS) { 62 | return LHS == RHS; 63 | } 64 | }; 65 | 66 | // Provide DenseMapInfo for cstrings. 67 | template<> struct DenseMapInfo { 68 | static inline const char* getEmptyKey() { 69 | return reinterpret_cast((intptr_t)-1); 70 | } 71 | static inline const char* getTombstoneKey() { 72 | return reinterpret_cast((intptr_t)-2); 73 | } 74 | static unsigned getHashValue(const char* const &Val) { 75 | return _objc_strhash(Val); 76 | } 77 | static bool isEqual(const char* const &LHS, const char* const &RHS) { 78 | return 0 == strcmp(LHS, RHS); 79 | } 80 | }; 81 | 82 | // Provide DenseMapInfo for chars. 83 | template<> struct DenseMapInfo { 84 | static inline char getEmptyKey() { return ~0; } 85 | static inline char getTombstoneKey() { return ~0 - 1; } 86 | static unsigned getHashValue(const char& Val) { return Val * 37U; } 87 | static bool isEqual(const char &LHS, const char &RHS) { 88 | return LHS == RHS; 89 | } 90 | }; 91 | 92 | // Provide DenseMapInfo for unsigned ints. 93 | template<> struct DenseMapInfo { 94 | static inline unsigned getEmptyKey() { return ~0U; } 95 | static inline unsigned getTombstoneKey() { return ~0U - 1; } 96 | static unsigned getHashValue(const unsigned& Val) { return Val * 37U; } 97 | static bool isEqual(const unsigned& LHS, const unsigned& RHS) { 98 | return LHS == RHS; 99 | } 100 | }; 101 | 102 | // Provide DenseMapInfo for unsigned longs. 103 | template<> struct DenseMapInfo { 104 | static inline unsigned long getEmptyKey() { return ~0UL; } 105 | static inline unsigned long getTombstoneKey() { return ~0UL - 1L; } 106 | static unsigned getHashValue(const unsigned long& Val) { 107 | return (unsigned)(Val * 37UL); 108 | } 109 | static bool isEqual(const unsigned long& LHS, const unsigned long& RHS) { 110 | return LHS == RHS; 111 | } 112 | }; 113 | 114 | // Provide DenseMapInfo for unsigned long longs. 115 | template<> struct DenseMapInfo { 116 | static inline unsigned long long getEmptyKey() { return ~0ULL; } 117 | static inline unsigned long long getTombstoneKey() { return ~0ULL - 1ULL; } 118 | static unsigned getHashValue(const unsigned long long& Val) { 119 | return (unsigned)(Val * 37ULL); 120 | } 121 | static bool isEqual(const unsigned long long& LHS, 122 | const unsigned long long& RHS) { 123 | return LHS == RHS; 124 | } 125 | }; 126 | 127 | // Provide DenseMapInfo for ints. 128 | template<> struct DenseMapInfo { 129 | static inline int getEmptyKey() { return 0x7fffffff; } 130 | static inline int getTombstoneKey() { return -0x7fffffff - 1; } 131 | static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37U); } 132 | static bool isEqual(const int& LHS, const int& RHS) { 133 | return LHS == RHS; 134 | } 135 | }; 136 | 137 | // Provide DenseMapInfo for longs. 138 | template<> struct DenseMapInfo { 139 | static inline long getEmptyKey() { 140 | return (1UL << (sizeof(long) * 8 - 1)) - 1UL; 141 | } 142 | static inline long getTombstoneKey() { return getEmptyKey() - 1L; } 143 | static unsigned getHashValue(const long& Val) { 144 | return (unsigned)(Val * 37UL); 145 | } 146 | static bool isEqual(const long& LHS, const long& RHS) { 147 | return LHS == RHS; 148 | } 149 | }; 150 | 151 | // Provide DenseMapInfo for long longs. 152 | template<> struct DenseMapInfo { 153 | static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; } 154 | static inline long long getTombstoneKey() { return -0x7fffffffffffffffLL-1; } 155 | static unsigned getHashValue(const long long& Val) { 156 | return (unsigned)(Val * 37ULL); 157 | } 158 | static bool isEqual(const long long& LHS, 159 | const long long& RHS) { 160 | return LHS == RHS; 161 | } 162 | }; 163 | 164 | // Provide DenseMapInfo for all pairs whose members have info. 165 | template 166 | struct DenseMapInfo > { 167 | typedef std::pair Pair; 168 | typedef DenseMapInfo FirstInfo; 169 | typedef DenseMapInfo SecondInfo; 170 | 171 | static inline Pair getEmptyKey() { 172 | return std::make_pair(FirstInfo::getEmptyKey(), 173 | SecondInfo::getEmptyKey()); 174 | } 175 | static inline Pair getTombstoneKey() { 176 | return std::make_pair(FirstInfo::getTombstoneKey(), 177 | SecondInfo::getTombstoneKey()); 178 | } 179 | static unsigned getHashValue(const Pair& PairVal) { 180 | uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32 181 | | (uint64_t)SecondInfo::getHashValue(PairVal.second); 182 | key += ~(key << 32); 183 | key ^= (key >> 22); 184 | key += ~(key << 13); 185 | key ^= (key >> 8); 186 | key += (key << 3); 187 | key ^= (key >> 15); 188 | key += ~(key << 27); 189 | key ^= (key >> 31); 190 | return (unsigned)key; 191 | } 192 | static bool isEqual(const Pair &LHS, const Pair &RHS) { 193 | return FirstInfo::isEqual(LHS.first, RHS.first) && 194 | SecondInfo::isEqual(LHS.second, RHS.second); 195 | } 196 | }; 197 | 198 | } // end namespace objc 199 | 200 | #endif 201 | -------------------------------------------------------------------------------- /runtime/maptable.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2003, 2006-2007 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 | /* maptable.h 24 | Scalable hash table of mappings. 25 | Bertrand, August 1990 26 | Copyright 1990-1996 NeXT Software, Inc. 27 | */ 28 | 29 | #ifndef _OBJC_MAPTABLE_H_ 30 | #define _OBJC_MAPTABLE_H_ 31 | 32 | #ifndef _OBJC_PRIVATE_H_ 33 | # define OBJC_MAP_AVAILABILITY \ 34 | __OSX_DEPRECATED(10.0, 10.1, "NXMapTable is deprecated") \ 35 | __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE 36 | #else 37 | # define OBJC_MAP_AVAILABILITY 38 | #endif 39 | 40 | #include 41 | 42 | __BEGIN_DECLS 43 | 44 | /*************** Definitions ***************/ 45 | 46 | /* This module allows hashing of arbitrary associations [key -> value]. Keys and values must be pointers or integers, and client is responsible for allocating/deallocating this data. A deallocation call-back is provided. 47 | NX_MAPNOTAKEY (-1) is used internally as a marker, and therefore keys must always be different from -1. 48 | As well-behaved scalable data structures, hash tables double in size when they start becoming full, thus guaranteeing both average constant time access and linear size. */ 49 | 50 | typedef struct _NXMapTable { 51 | /* private data structure; may change */ 52 | const struct _NXMapTablePrototype *prototype; 53 | unsigned count; 54 | unsigned nbBucketsMinusOne; 55 | void *buckets; 56 | } NXMapTable OBJC_MAP_AVAILABILITY; 57 | 58 | typedef struct _NXMapTablePrototype { 59 | unsigned (*hash)(NXMapTable *, const void *key); 60 | int (*isEqual)(NXMapTable *, const void *key1, const void *key2); 61 | void (*free)(NXMapTable *, void *key, void *value); 62 | int style; /* reserved for future expansion; currently 0 */ 63 | } NXMapTablePrototype OBJC_MAP_AVAILABILITY; 64 | 65 | /* invariants assumed by the implementation: 66 | A - key != -1 67 | B - key1 == key2 => hash(key1) == hash(key2) 68 | when key varies over time, hash(key) must remain invariant 69 | e.g. if string key, the string must not be changed 70 | C - isEqual(key1, key2) => key1 == key2 71 | */ 72 | 73 | #define NX_MAPNOTAKEY ((void *)(-1)) 74 | 75 | /*************** Functions ***************/ 76 | 77 | OBJC_EXPORT NXMapTable *NXCreateMapTableFromZone(NXMapTablePrototype prototype, unsigned capacity, void *z) OBJC_MAP_AVAILABILITY; 78 | OBJC_EXPORT NXMapTable *NXCreateMapTable(NXMapTablePrototype prototype, unsigned capacity) OBJC_MAP_AVAILABILITY; 79 | /* capacity is only a hint; 0 creates a small table */ 80 | 81 | OBJC_EXPORT void NXFreeMapTable(NXMapTable *table) OBJC_MAP_AVAILABILITY; 82 | /* call free for each pair, and recovers table */ 83 | 84 | OBJC_EXPORT void NXResetMapTable(NXMapTable *table) OBJC_MAP_AVAILABILITY; 85 | /* free each pair; keep current capacity */ 86 | 87 | OBJC_EXPORT BOOL NXCompareMapTables(NXMapTable *table1, NXMapTable *table2) OBJC_MAP_AVAILABILITY; 88 | /* Returns YES if the two sets are equal (each member of table1 in table2, and table have same size) */ 89 | 90 | OBJC_EXPORT unsigned NXCountMapTable(NXMapTable *table) OBJC_MAP_AVAILABILITY; 91 | /* current number of data in table */ 92 | 93 | OBJC_EXPORT void *NXMapMember(NXMapTable *table, const void *key, void **value) OBJC_MAP_AVAILABILITY; 94 | /* return original table key or NX_MAPNOTAKEY. If key is found, value is set */ 95 | 96 | OBJC_EXPORT void *NXMapGet(NXMapTable *table, const void *key) OBJC_MAP_AVAILABILITY; 97 | /* return original corresponding value or NULL. When NULL need be stored as value, NXMapMember can be used to test for presence */ 98 | 99 | OBJC_EXPORT void *NXMapInsert(NXMapTable *table, const void *key, const void *value) OBJC_MAP_AVAILABILITY; 100 | /* override preexisting pair; Return previous value or NULL. */ 101 | 102 | OBJC_EXPORT void *NXMapRemove(NXMapTable *table, const void *key) OBJC_MAP_AVAILABILITY; 103 | /* previous value or NULL is returned */ 104 | 105 | /* Iteration over all elements of a table consists in setting up an iteration state and then to progress until all entries have been visited. An example of use for counting elements in a table is: 106 | unsigned count = 0; 107 | const MyKey *key; 108 | const MyValue *value; 109 | NXMapState state = NXInitMapState(table); 110 | while(NXNextMapState(table, &state, &key, &value)) { 111 | count++; 112 | } 113 | */ 114 | 115 | typedef struct {int index;} NXMapState OBJC_MAP_AVAILABILITY; 116 | /* callers should not rely on actual contents of the struct */ 117 | 118 | OBJC_EXPORT NXMapState NXInitMapState(NXMapTable *table) OBJC_MAP_AVAILABILITY; 119 | 120 | OBJC_EXPORT int NXNextMapState(NXMapTable *table, NXMapState *state, const void **key, const void **value) OBJC_MAP_AVAILABILITY; 121 | /* returns 0 when all elements have been visited */ 122 | 123 | /*************** Conveniences ***************/ 124 | 125 | OBJC_EXPORT const NXMapTablePrototype NXPtrValueMapPrototype OBJC_MAP_AVAILABILITY; 126 | /* hashing is pointer/integer hashing; 127 | isEqual is identity; 128 | free is no-op. */ 129 | OBJC_EXPORT const NXMapTablePrototype NXStrValueMapPrototype OBJC_MAP_AVAILABILITY; 130 | /* hashing is string hashing; 131 | isEqual is strcmp; 132 | free is no-op. */ 133 | OBJC_EXPORT const NXMapTablePrototype NXObjectMapPrototype OBJC2_UNAVAILABLE; 134 | /* for objects; uses methods: hash, isEqual:, free, all for key. */ 135 | 136 | __END_DECLS 137 | 138 | #endif /* _OBJC_MAPTABLE_H_ */ 139 | -------------------------------------------------------------------------------- /runtime/objc-accessors.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2006-2008 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 | #include 25 | #include 26 | 27 | #include 28 | 29 | #include "objc-private.h" 30 | #include "runtime.h" 31 | 32 | // stub interface declarations to make compiler happy. 33 | 34 | @interface __NSCopyable 35 | - (id)copyWithZone:(void *)zone; 36 | @end 37 | 38 | @interface __NSMutableCopyable 39 | - (id)mutableCopyWithZone:(void *)zone; 40 | @end 41 | 42 | // These locks must not be at function scope. 43 | static StripedMap PropertyLocks; 44 | static StripedMap StructLocks; 45 | static StripedMap CppObjectLocks; 46 | 47 | #define MUTABLE_COPY 2 48 | 49 | id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) { 50 | if (offset == 0) { 51 | return object_getClass(self); 52 | } 53 | 54 | // Retain release world 55 | id *slot = (id*) ((char*)self + offset); 56 | if (!atomic) return *slot; 57 | 58 | // Atomic retain release world 59 | spinlock_t& slotlock = PropertyLocks[slot]; 60 | slotlock.lock(); 61 | id value = objc_retain(*slot); 62 | slotlock.unlock(); 63 | 64 | // for performance, we (safely) issue the autorelease OUTSIDE of the spinlock. 65 | return objc_autoreleaseReturnValue(value); 66 | } 67 | 68 | 69 | static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy) __attribute__((always_inline)); 70 | 71 | static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy) 72 | { 73 | if (offset == 0) { 74 | object_setClass(self, newValue); 75 | return; 76 | } 77 | 78 | id oldValue; 79 | id *slot = (id*) ((char*)self + offset); 80 | 81 | if (copy) { 82 | newValue = [newValue copyWithZone:nil]; 83 | } else if (mutableCopy) { 84 | newValue = [newValue mutableCopyWithZone:nil]; 85 | } else { 86 | if (*slot == newValue) return; 87 | newValue = objc_retain(newValue); 88 | } 89 | 90 | if (!atomic) { 91 | oldValue = *slot; 92 | *slot = newValue; 93 | } else { 94 | spinlock_t& slotlock = PropertyLocks[slot]; 95 | slotlock.lock(); 96 | oldValue = *slot; 97 | *slot = newValue; 98 | slotlock.unlock(); 99 | } 100 | 101 | objc_release(oldValue); 102 | } 103 | 104 | void objc_setProperty(id self, SEL _cmd, ptrdiff_t offset, id newValue, BOOL atomic, signed char shouldCopy) 105 | { 106 | bool copy = (shouldCopy && shouldCopy != MUTABLE_COPY); 107 | bool mutableCopy = (shouldCopy == MUTABLE_COPY); 108 | reallySetProperty(self, _cmd, newValue, offset, atomic, copy, mutableCopy); 109 | } 110 | 111 | void objc_setProperty_atomic(id self, SEL _cmd, id newValue, ptrdiff_t offset) 112 | { 113 | reallySetProperty(self, _cmd, newValue, offset, true, false, false); 114 | } 115 | 116 | void objc_setProperty_nonatomic(id self, SEL _cmd, id newValue, ptrdiff_t offset) 117 | { 118 | reallySetProperty(self, _cmd, newValue, offset, false, false, false); 119 | } 120 | 121 | 122 | void objc_setProperty_atomic_copy(id self, SEL _cmd, id newValue, ptrdiff_t offset) 123 | { 124 | reallySetProperty(self, _cmd, newValue, offset, true, true, false); 125 | } 126 | 127 | void objc_setProperty_nonatomic_copy(id self, SEL _cmd, id newValue, ptrdiff_t offset) 128 | { 129 | reallySetProperty(self, _cmd, newValue, offset, false, true, false); 130 | } 131 | 132 | 133 | // This entry point was designed wrong. When used as a getter, src needs to be locked so that 134 | // if simultaneously used for a setter then there would be contention on src. 135 | // So we need two locks - one of which will be contended. 136 | void objc_copyStruct(void *dest, const void *src, ptrdiff_t size, BOOL atomic, BOOL hasStrong __unused) { 137 | spinlock_t *srcLock = nil; 138 | spinlock_t *dstLock = nil; 139 | if (atomic) { 140 | srcLock = &StructLocks[src]; 141 | dstLock = &StructLocks[dest]; 142 | spinlock_t::lockTwo(srcLock, dstLock); 143 | } 144 | 145 | memmove(dest, src, size); 146 | 147 | if (atomic) { 148 | spinlock_t::unlockTwo(srcLock, dstLock); 149 | } 150 | } 151 | 152 | void objc_copyCppObjectAtomic(void *dest, const void *src, void (*copyHelper) (void *dest, const void *source)) { 153 | spinlock_t *srcLock = &CppObjectLocks[src]; 154 | spinlock_t *dstLock = &CppObjectLocks[dest]; 155 | spinlock_t::lockTwo(srcLock, dstLock); 156 | 157 | // let C++ code perform the actual copy. 158 | copyHelper(dest, src); 159 | 160 | spinlock_t::unlockTwo(srcLock, dstLock); 161 | } 162 | -------------------------------------------------------------------------------- /runtime/objc-api.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2006 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 | // Copyright 1988-1996 NeXT Software, Inc. 24 | 25 | #ifndef _OBJC_OBJC_API_H_ 26 | #define _OBJC_OBJC_API_H_ 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #ifndef __has_feature 33 | # define __has_feature(x) 0 34 | #endif 35 | 36 | #ifndef __has_extension 37 | # define __has_extension __has_feature 38 | #endif 39 | 40 | #ifndef __has_attribute 41 | # define __has_attribute(x) 0 42 | #endif 43 | 44 | 45 | /* 46 | * OBJC_API_VERSION 0 or undef: Tiger and earlier API only 47 | * OBJC_API_VERSION 2: Leopard and later API available 48 | */ 49 | #if !defined(OBJC_API_VERSION) 50 | # if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_5 51 | # define OBJC_API_VERSION 0 52 | # else 53 | # define OBJC_API_VERSION 2 54 | # endif 55 | #endif 56 | 57 | 58 | /* 59 | * OBJC_NO_GC 1: GC is not supported 60 | * OBJC_NO_GC undef: GC is supported. This SDK no longer supports this mode. 61 | * 62 | * OBJC_NO_GC_API undef: Libraries must export any symbols that 63 | * dual-mode code may links to. 64 | * OBJC_NO_GC_API 1: Libraries need not export GC-related symbols. 65 | */ 66 | #if defined(__OBJC_GC__) 67 | # error Objective-C garbage collection is not supported. 68 | #elif TARGET_OS_OSX 69 | /* GC is unsupported. GC API symbols are exported. */ 70 | # define OBJC_NO_GC 1 71 | # undef OBJC_NO_GC_API 72 | #else 73 | /* GC is unsupported. GC API symbols are not exported. */ 74 | # define OBJC_NO_GC 1 75 | # define OBJC_NO_GC_API 1 76 | #endif 77 | 78 | 79 | /* NS_ENFORCE_NSOBJECT_DESIGNATED_INITIALIZER == 1 80 | * marks -[NSObject init] as a designated initializer. */ 81 | #if !defined(NS_ENFORCE_NSOBJECT_DESIGNATED_INITIALIZER) 82 | # define NS_ENFORCE_NSOBJECT_DESIGNATED_INITIALIZER 1 83 | #endif 84 | 85 | 86 | /* OBJC_OLD_DISPATCH_PROTOTYPES == 0 enforces the rule that the dispatch 87 | * functions must be cast to an appropriate function pointer type. */ 88 | #if !defined(OBJC_OLD_DISPATCH_PROTOTYPES) 89 | # define OBJC_OLD_DISPATCH_PROTOTYPES 1 90 | #endif 91 | 92 | 93 | /* OBJC_AVAILABLE: shorthand for all-OS availability */ 94 | #if !defined(OBJC_AVAILABLE) 95 | # define OBJC_AVAILABLE(x, i, t, w) \ 96 | __OSX_AVAILABLE(x) __IOS_AVAILABLE(i) \ 97 | __TVOS_AVAILABLE(t) __WATCHOS_AVAILABLE(w) 98 | #endif 99 | 100 | 101 | /* OBJC_ISA_AVAILABILITY: `isa` will be deprecated or unavailable 102 | * in the future */ 103 | #if !defined(OBJC_ISA_AVAILABILITY) 104 | # if __OBJC2__ 105 | # define OBJC_ISA_AVAILABILITY __attribute__((deprecated)) 106 | # else 107 | # define OBJC_ISA_AVAILABILITY /* still available */ 108 | # endif 109 | #endif 110 | 111 | 112 | /* OBJC2_UNAVAILABLE: unavailable in objc 2.0, deprecated in Leopard */ 113 | #if !defined(OBJC2_UNAVAILABLE) 114 | # if __OBJC2__ 115 | # define OBJC2_UNAVAILABLE UNAVAILABLE_ATTRIBUTE 116 | # else 117 | /* plain C code also falls here, but this is close enough */ 118 | # define OBJC2_UNAVAILABLE \ 119 | __OSX_DEPRECATED(10.5, 10.5, "not available in __OBJC2__") \ 120 | __IOS_DEPRECATED(2.0, 2.0, "not available in __OBJC2__") \ 121 | __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE 122 | # endif 123 | #endif 124 | 125 | /* OBJC_UNAVAILABLE: unavailable, with a message where supported */ 126 | #if !defined(OBJC_UNAVAILABLE) 127 | # if __has_extension(attribute_unavailable_with_message) 128 | # define OBJC_UNAVAILABLE(_msg) __attribute__((unavailable(_msg))) 129 | # else 130 | # define OBJC_UNAVAILABLE(_msg) __attribute__((unavailable)) 131 | # endif 132 | #endif 133 | 134 | /* OBJC_DEPRECATED: deprecated, with a message where supported */ 135 | #if !defined(OBJC_DEPRECATED) 136 | # if __has_extension(attribute_deprecated_with_message) 137 | # define OBJC_DEPRECATED(_msg) __attribute__((deprecated(_msg))) 138 | # else 139 | # define OBJC_DEPRECATED(_msg) __attribute__((deprecated)) 140 | # endif 141 | #endif 142 | 143 | /* OBJC_ARC_UNAVAILABLE: unavailable with -fobjc-arc */ 144 | #if !defined(OBJC_ARC_UNAVAILABLE) 145 | # if __has_feature(objc_arc) 146 | # define OBJC_ARC_UNAVAILABLE OBJC_UNAVAILABLE("not available in automatic reference counting mode") 147 | # else 148 | # define OBJC_ARC_UNAVAILABLE 149 | # endif 150 | #endif 151 | 152 | /* OBJC_SWIFT_UNAVAILABLE: unavailable in Swift */ 153 | #if !defined(OBJC_SWIFT_UNAVAILABLE) 154 | # if __has_feature(attribute_availability_swift) 155 | # define OBJC_SWIFT_UNAVAILABLE(_msg) __attribute__((availability(swift, unavailable, message=_msg))) 156 | # else 157 | # define OBJC_SWIFT_UNAVAILABLE(_msg) 158 | # endif 159 | #endif 160 | 161 | /* OBJC_ARM64_UNAVAILABLE: unavailable on arm64 (i.e. stret dispatch) */ 162 | #if !defined(OBJC_ARM64_UNAVAILABLE) 163 | # if defined(__arm64__) 164 | # define OBJC_ARM64_UNAVAILABLE OBJC_UNAVAILABLE("not available in arm64") 165 | # else 166 | # define OBJC_ARM64_UNAVAILABLE 167 | # endif 168 | #endif 169 | 170 | /* OBJC_GC_UNAVAILABLE: unavailable with -fobjc-gc or -fobjc-gc-only */ 171 | #if !defined(OBJC_GC_UNAVAILABLE) 172 | # define OBJC_GC_UNAVAILABLE 173 | #endif 174 | 175 | #if !defined(OBJC_EXTERN) 176 | # if defined(__cplusplus) 177 | # define OBJC_EXTERN extern "C" 178 | # else 179 | # define OBJC_EXTERN extern 180 | # endif 181 | #endif 182 | 183 | #if !defined(OBJC_VISIBLE) 184 | # if TARGET_OS_WIN32 185 | # if defined(BUILDING_OBJC) 186 | # define OBJC_VISIBLE __declspec(dllexport) 187 | # else 188 | # define OBJC_VISIBLE __declspec(dllimport) 189 | # endif 190 | # else 191 | # define OBJC_VISIBLE __attribute__((visibility("default"))) 192 | # endif 193 | #endif 194 | 195 | #if !defined(OBJC_EXPORT) 196 | # define OBJC_EXPORT OBJC_EXTERN OBJC_VISIBLE 197 | #endif 198 | 199 | #if !defined(OBJC_IMPORT) 200 | # define OBJC_IMPORT extern 201 | #endif 202 | 203 | #if !defined(OBJC_ROOT_CLASS) 204 | # if __has_attribute(objc_root_class) 205 | # define OBJC_ROOT_CLASS __attribute__((objc_root_class)) 206 | # else 207 | # define OBJC_ROOT_CLASS 208 | # endif 209 | #endif 210 | 211 | #ifndef __DARWIN_NULL 212 | #define __DARWIN_NULL NULL 213 | #endif 214 | 215 | #if !defined(OBJC_INLINE) 216 | # define OBJC_INLINE __inline 217 | #endif 218 | 219 | // Declares an enum type or option bits type as appropriate for each language. 220 | #if (__cplusplus && __cplusplus >= 201103L && (__has_extension(cxx_strong_enums) || __has_feature(objc_fixed_enum))) || (!__cplusplus && __has_feature(objc_fixed_enum)) 221 | #define OBJC_ENUM(_type, _name) enum _name : _type _name; enum _name : _type 222 | #if (__cplusplus) 223 | #define OBJC_OPTIONS(_type, _name) _type _name; enum : _type 224 | #else 225 | #define OBJC_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type 226 | #endif 227 | #else 228 | #define OBJC_ENUM(_type, _name) _type _name; enum 229 | #define OBJC_OPTIONS(_type, _name) _type _name; enum 230 | #endif 231 | 232 | #endif 233 | -------------------------------------------------------------------------------- /runtime/objc-auto.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004-2007 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 | #include "objc-private.h" 25 | 26 | // GC is no longer supported. 27 | 28 | #if OBJC_NO_GC_API 29 | 30 | // No GC and no GC symbols needed. We're done here. 31 | # if SUPPORT_GC_COMPAT 32 | # error inconsistent config settings 33 | # endif 34 | 35 | #else 36 | 37 | // No GC but we do need to export GC symbols. 38 | // These are mostly the same as the OBJC_NO_GC inline versions in objc-auto.h. 39 | 40 | # if !SUPPORT_GC_COMPAT 41 | # error inconsistent config settings 42 | # endif 43 | 44 | OBJC_EXPORT void objc_collect(unsigned long options __unused) { } 45 | OBJC_EXPORT BOOL objc_collectingEnabled(void) { return NO; } 46 | OBJC_EXPORT void objc_setCollectionThreshold(size_t threshold __unused) { } 47 | OBJC_EXPORT void objc_setCollectionRatio(size_t ratio __unused) { } 48 | OBJC_EXPORT void objc_startCollectorThread(void) { } 49 | 50 | #if TARGET_OS_WIN32 51 | OBJC_EXPORT BOOL objc_atomicCompareAndSwapPtr(id predicate, id replacement, volatile id *objectLocation) 52 | { void *original = InterlockedCompareExchangePointer((void * volatile *)objectLocation, (void *)replacement, (void *)predicate); return (original == predicate); } 53 | 54 | OBJC_EXPORT BOOL objc_atomicCompareAndSwapPtrBarrier(id predicate, id replacement, volatile id *objectLocation) 55 | { void *original = InterlockedCompareExchangePointer((void * volatile *)objectLocation, (void *)replacement, (void *)predicate); return (original == predicate); } 56 | #else 57 | OBJC_EXPORT BOOL objc_atomicCompareAndSwapPtr(id predicate, id replacement, volatile id *objectLocation) 58 | { return OSAtomicCompareAndSwapPtr((void *)predicate, (void *)replacement, (void * volatile *)objectLocation); } 59 | 60 | OBJC_EXPORT BOOL objc_atomicCompareAndSwapPtrBarrier(id predicate, id replacement, volatile id *objectLocation) 61 | { return OSAtomicCompareAndSwapPtrBarrier((void *)predicate, (void *)replacement, (void * volatile *)objectLocation); } 62 | #endif 63 | 64 | OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobal(id predicate, id replacement, volatile id *objectLocation) 65 | { return objc_atomicCompareAndSwapPtr(predicate, replacement, objectLocation); } 66 | 67 | OBJC_EXPORT BOOL objc_atomicCompareAndSwapGlobalBarrier(id predicate, id replacement, volatile id *objectLocation) 68 | { return objc_atomicCompareAndSwapPtrBarrier(predicate, replacement, objectLocation); } 69 | 70 | OBJC_EXPORT BOOL objc_atomicCompareAndSwapInstanceVariable(id predicate, id replacement, volatile id *objectLocation) 71 | { return objc_atomicCompareAndSwapPtr(predicate, replacement, objectLocation); } 72 | 73 | OBJC_EXPORT BOOL objc_atomicCompareAndSwapInstanceVariableBarrier(id predicate, id replacement, volatile id *objectLocation) 74 | { return objc_atomicCompareAndSwapPtrBarrier(predicate, replacement, objectLocation); } 75 | 76 | OBJC_EXPORT id objc_assign_strongCast(id val, id *dest) 77 | { return (*dest = val); } 78 | 79 | OBJC_EXPORT id objc_assign_global(id val, id *dest) 80 | { return (*dest = val); } 81 | 82 | OBJC_EXPORT id objc_assign_threadlocal(id val, id *dest) 83 | { return (*dest = val); } 84 | 85 | OBJC_EXPORT id objc_assign_ivar(id val, id dest, ptrdiff_t offset) 86 | { return (*(id*)((char *)dest+offset) = val); } 87 | 88 | OBJC_EXPORT id objc_read_weak(id *location) 89 | { return *location; } 90 | 91 | OBJC_EXPORT id objc_assign_weak(id value, id *location) 92 | { return (*location = value); } 93 | 94 | OBJC_EXPORT void *objc_memmove_collectable(void *dst, const void *src, size_t size) 95 | { return memmove(dst, src, size); } 96 | 97 | OBJC_EXPORT void objc_finalizeOnMainThread(Class cls __unused) { } 98 | OBJC_EXPORT BOOL objc_is_finalized(void *ptr __unused) { return NO; } 99 | OBJC_EXPORT void objc_clear_stack(unsigned long options __unused) { } 100 | 101 | OBJC_EXPORT BOOL objc_collecting_enabled(void) { return NO; } 102 | OBJC_EXPORT void objc_set_collection_threshold(size_t threshold __unused) { } 103 | OBJC_EXPORT void objc_set_collection_ratio(size_t ratio __unused) { } 104 | OBJC_EXPORT void objc_start_collector_thread(void) { } 105 | 106 | OBJC_EXPORT id objc_allocate_object(Class cls, int extra) 107 | { return class_createInstance(cls, extra); } 108 | 109 | OBJC_EXPORT void objc_registerThreadWithCollector() { } 110 | OBJC_EXPORT void objc_unregisterThreadWithCollector() { } 111 | OBJC_EXPORT void objc_assertRegisteredThreadWithCollector() { } 112 | 113 | OBJC_EXPORT malloc_zone_t* objc_collect_init(int(*callback)() __unused) { return nil; } 114 | OBJC_EXPORT void* objc_collectableZone() { return nil; } 115 | 116 | OBJC_EXPORT BOOL objc_isAuto(id object __unused) { return NO; } 117 | OBJC_EXPORT BOOL objc_dumpHeap(char *filename __unused, unsigned long length __unused) 118 | { return NO; } 119 | 120 | // not OBJC_NO_GC_API 121 | #endif 122 | -------------------------------------------------------------------------------- /runtime/objc-cache-old.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 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 | #ifndef _OBJC_CACHE_OLD_H 25 | #define _OBJC_CACHE_OLD_H 26 | 27 | #include "objc-private.h" 28 | 29 | __BEGIN_DECLS 30 | 31 | extern IMP _cache_getImp(Class cls, SEL sel); 32 | extern Method _cache_getMethod(Class cls, SEL sel, IMP objc_msgForward_internal_imp); 33 | 34 | extern void flush_cache(Class cls); 35 | extern bool _cache_fill(Class cls, Method meth, SEL sel); 36 | extern void _cache_addForwardEntry(Class cls, SEL sel); 37 | extern IMP _cache_addIgnoredEntry(Class cls, SEL sel); 38 | extern void _cache_free(Cache cache); 39 | extern void _cache_collect(bool collectALot); 40 | 41 | __END_DECLS 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /runtime/objc-cache.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _OBJC_CACHE_H 3 | #define _OBJC_CACHE_H 4 | 5 | #include "objc-private.h" 6 | 7 | __BEGIN_DECLS 8 | 9 | extern IMP cache_getImp(Class cls, SEL sel); 10 | 11 | extern void cache_fill(Class cls, SEL sel, IMP imp, id receiver); 12 | 13 | extern void cache_erase_nolock(Class cls); 14 | 15 | extern void cache_delete(Class cls); 16 | 17 | extern void cache_collect(bool collectALot); 18 | 19 | __END_DECLS 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /runtime/objc-class.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | -------------------------------------------------------------------------------- /runtime/objc-config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2002, 2005-2008 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 | #ifndef _OBJC_CONFIG_H_ 25 | #define _OBJC_CONFIG_H_ 26 | 27 | #include 28 | 29 | // Avoid the !NDEBUG double negative. 30 | #if !NDEBUG 31 | # define DEBUG 1 32 | #else 33 | # define DEBUG 0 34 | #endif 35 | 36 | // Define SUPPORT_GC_COMPAT=1 to enable compatibility where GC once was. 37 | // OBJC_NO_GC and OBJC_NO_GC_API in objc-api.h mean something else. 38 | #if !TARGET_OS_OSX 39 | # define SUPPORT_GC_COMPAT 0 40 | #else 41 | # define SUPPORT_GC_COMPAT 1 42 | #endif 43 | 44 | // Define SUPPORT_ZONES=1 to enable malloc zone support in NXHashTable. 45 | #if !TARGET_OS_OSX 46 | # define SUPPORT_ZONES 0 47 | #else 48 | # define SUPPORT_ZONES 1 49 | #endif 50 | 51 | // Define SUPPORT_MOD=1 to use the mod operator in NXHashTable and objc-sel-set 52 | #if defined(__arm__) 53 | # define SUPPORT_MOD 0 54 | #else 55 | # define SUPPORT_MOD 1 56 | #endif 57 | 58 | // Define SUPPORT_PREOPT=1 to enable dyld shared cache optimizations 59 | #if TARGET_OS_WIN32 || TARGET_OS_SIMULATOR 60 | # define SUPPORT_PREOPT 0 61 | #else 62 | # define SUPPORT_PREOPT 1 63 | #endif 64 | 65 | // Define SUPPORT_TAGGED_POINTERS=1 to enable tagged pointer objects 66 | // Be sure to edit tagged pointer SPI in objc-internal.h as well. 67 | #if !(__OBJC2__ && __LP64__) 68 | # define SUPPORT_TAGGED_POINTERS 0 69 | #else 70 | # define SUPPORT_TAGGED_POINTERS 1 71 | #endif 72 | 73 | // Define SUPPORT_MSB_TAGGED_POINTERS to use the MSB 74 | // as the tagged pointer marker instead of the LSB. 75 | // Be sure to edit tagged pointer SPI in objc-internal.h as well. 76 | #if !SUPPORT_TAGGED_POINTERS || !TARGET_OS_IPHONE 77 | # define SUPPORT_MSB_TAGGED_POINTERS 0 78 | #else 79 | # define SUPPORT_MSB_TAGGED_POINTERS 1 80 | #endif 81 | 82 | // Define SUPPORT_INDEXED_ISA=1 on platforms that store the class in the isa 83 | // field as an index into a class table. 84 | // Note, keep this in sync with any .s files which also define it. 85 | // Be sure to edit objc-abi.h as well. 86 | #if __ARM_ARCH_7K__ >= 2 87 | # define SUPPORT_INDEXED_ISA 1 88 | #else 89 | # define SUPPORT_INDEXED_ISA 0 90 | #endif 91 | 92 | // Define SUPPORT_PACKED_ISA=1 on platforms that store the class in the isa 93 | // field as a maskable pointer with other data around it. 94 | #if (!__LP64__ || TARGET_OS_WIN32 || TARGET_OS_SIMULATOR) 95 | # define SUPPORT_PACKED_ISA 0 96 | #else 97 | # define SUPPORT_PACKED_ISA 1 98 | #endif 99 | 100 | // Define SUPPORT_NONPOINTER_ISA=1 on any platform that may store something 101 | // in the isa field that is not a raw pointer. 102 | #if !SUPPORT_INDEXED_ISA && !SUPPORT_PACKED_ISA 103 | # define SUPPORT_NONPOINTER_ISA 0 104 | #else 105 | # define SUPPORT_NONPOINTER_ISA 1 106 | #endif 107 | 108 | // Define SUPPORT_FIXUP=1 to repair calls sites for fixup dispatch. 109 | // Fixup messaging itself is no longer supported. 110 | // Be sure to edit objc-abi.h as well (objc_msgSend*_fixup) 111 | #if !(defined(__x86_64__) && (TARGET_OS_OSX || TARGET_OS_SIMULATOR)) 112 | # define SUPPORT_FIXUP 0 113 | #else 114 | # define SUPPORT_FIXUP 1 115 | #endif 116 | 117 | // Define SUPPORT_ZEROCOST_EXCEPTIONS to use "zero-cost" exceptions for OBJC2. 118 | // Be sure to edit objc-exception.h as well (objc_add/removeExceptionHandler) 119 | #if !__OBJC2__ || (defined(__arm__) && __USING_SJLJ_EXCEPTIONS__) 120 | # define SUPPORT_ZEROCOST_EXCEPTIONS 0 121 | #else 122 | # define SUPPORT_ZEROCOST_EXCEPTIONS 1 123 | #endif 124 | 125 | // Define SUPPORT_ALT_HANDLERS if you're using zero-cost exceptions 126 | // but also need to support AppKit's alt-handler scheme 127 | // Be sure to edit objc-exception.h as well (objc_add/removeExceptionHandler) 128 | #if !SUPPORT_ZEROCOST_EXCEPTIONS || TARGET_OS_IPHONE || TARGET_OS_EMBEDDED 129 | # define SUPPORT_ALT_HANDLERS 0 130 | #else 131 | # define SUPPORT_ALT_HANDLERS 1 132 | #endif 133 | 134 | // Define SUPPORT_RETURN_AUTORELEASE to optimize autoreleased return values 135 | #if TARGET_OS_WIN32 136 | # define SUPPORT_RETURN_AUTORELEASE 0 137 | #else 138 | # define SUPPORT_RETURN_AUTORELEASE 1 139 | #endif 140 | 141 | // Define SUPPORT_STRET on architectures that need separate struct-return ABI. 142 | #if defined(__arm64__) 143 | # define SUPPORT_STRET 0 144 | #else 145 | # define SUPPORT_STRET 1 146 | #endif 147 | 148 | // Define SUPPORT_MESSAGE_LOGGING to enable NSObjCMessageLoggingEnabled 149 | #if TARGET_OS_WIN32 || TARGET_OS_EMBEDDED 150 | # define SUPPORT_MESSAGE_LOGGING 0 151 | #else 152 | # define SUPPORT_MESSAGE_LOGGING 1 153 | #endif 154 | 155 | // Define SUPPORT_QOS_HACK to work around deadlocks due to QoS bugs. 156 | #if !__OBJC2__ || TARGET_OS_WIN32 157 | # define SUPPORT_QOS_HACK 0 158 | #else 159 | # define SUPPORT_QOS_HACK 1 160 | #endif 161 | 162 | // OBJC_INSTRUMENTED controls whether message dispatching is dynamically 163 | // monitored. Monitoring introduces substantial overhead. 164 | // NOTE: To define this condition, do so in the build command, NOT by 165 | // uncommenting the line here. This is because objc-class.h heeds this 166 | // condition, but objc-class.h can not #include this file (objc-config.h) 167 | // because objc-class.h is public and objc-config.h is not. 168 | //#define OBJC_INSTRUMENTED 169 | 170 | #endif 171 | -------------------------------------------------------------------------------- /runtime/objc-env.h: -------------------------------------------------------------------------------- 1 | // -*- truncate-lines: t; -*- 2 | 3 | // OPTION(var, env, help) 4 | 5 | OPTION( PrintImages, OBJC_PRINT_IMAGES, "log image and library names as they are loaded") 6 | OPTION( PrintImageTimes, OBJC_PRINT_IMAGE_TIMES, "measure duration of image loading steps") 7 | OPTION( PrintLoading, OBJC_PRINT_LOAD_METHODS, "log calls to class and category +load methods") 8 | OPTION( PrintInitializing, OBJC_PRINT_INITIALIZE_METHODS, "log calls to class +initialize methods") 9 | OPTION( PrintResolving, OBJC_PRINT_RESOLVED_METHODS, "log methods created by +resolveClassMethod: and +resolveInstanceMethod:") 10 | OPTION( PrintConnecting, OBJC_PRINT_CLASS_SETUP, "log progress of class and category setup") 11 | OPTION( PrintProtocols, OBJC_PRINT_PROTOCOL_SETUP, "log progress of protocol setup") 12 | OPTION( PrintIvars, OBJC_PRINT_IVAR_SETUP, "log processing of non-fragile ivars") 13 | OPTION( PrintVtables, OBJC_PRINT_VTABLE_SETUP, "log processing of class vtables") 14 | OPTION( PrintVtableImages, OBJC_PRINT_VTABLE_IMAGES, "print vtable images showing overridden methods") 15 | OPTION( PrintCaches, OBJC_PRINT_CACHE_SETUP, "log processing of method caches") 16 | OPTION( PrintFuture, OBJC_PRINT_FUTURE_CLASSES, "log use of future classes for toll-free bridging") 17 | OPTION( PrintPreopt, OBJC_PRINT_PREOPTIMIZATION, "log preoptimization courtesy of dyld shared cache") 18 | OPTION( PrintCxxCtors, OBJC_PRINT_CXX_CTORS, "log calls to C++ ctors and dtors for instance variables") 19 | OPTION( PrintExceptions, OBJC_PRINT_EXCEPTIONS, "log exception handling") 20 | OPTION( PrintExceptionThrow, OBJC_PRINT_EXCEPTION_THROW, "log backtrace of every objc_exception_throw()") 21 | OPTION( PrintAltHandlers, OBJC_PRINT_ALT_HANDLERS, "log processing of exception alt handlers") 22 | OPTION( PrintReplacedMethods, OBJC_PRINT_REPLACED_METHODS, "log methods replaced by category implementations") 23 | OPTION( PrintDeprecation, OBJC_PRINT_DEPRECATION_WARNINGS, "warn about calls to deprecated runtime functions") 24 | OPTION( PrintPoolHiwat, OBJC_PRINT_POOL_HIGHWATER, "log high-water marks for autorelease pools") 25 | OPTION( PrintCustomRR, OBJC_PRINT_CUSTOM_RR, "log classes with un-optimized custom retain/release methods") 26 | OPTION( PrintCustomAWZ, OBJC_PRINT_CUSTOM_AWZ, "log classes with un-optimized custom allocWithZone methods") 27 | OPTION( PrintRawIsa, OBJC_PRINT_RAW_ISA, "log classes that require raw pointer isa fields") 28 | 29 | OPTION( DebugUnload, OBJC_DEBUG_UNLOAD, "warn about poorly-behaving bundles when unloaded") 30 | OPTION( DebugFragileSuperclasses, OBJC_DEBUG_FRAGILE_SUPERCLASSES, "warn about subclasses that may have been broken by subsequent changes to superclasses") 31 | OPTION( DebugNilSync, OBJC_DEBUG_NIL_SYNC, "warn about @synchronized(nil), which does no synchronization") 32 | OPTION( DebugNonFragileIvars, OBJC_DEBUG_NONFRAGILE_IVARS, "capriciously rearrange non-fragile ivars") 33 | OPTION( DebugAltHandlers, OBJC_DEBUG_ALT_HANDLERS, "record more info about bad alt handler use") 34 | OPTION( DebugMissingPools, OBJC_DEBUG_MISSING_POOLS, "warn about autorelease with no pool in place, which may be a leak") 35 | OPTION( DebugPoolAllocation, OBJC_DEBUG_POOL_ALLOCATION, "halt when autorelease pools are popped out of order, and allow heap debuggers to track autorelease pools") 36 | OPTION( DebugDuplicateClasses, OBJC_DEBUG_DUPLICATE_CLASSES, "halt when multiple classes with the same name are present") 37 | OPTION( DebugDontCrash, OBJC_DEBUG_DONT_CRASH, "halt the process by exiting instead of crashing") 38 | 39 | OPTION( DisableVtables, OBJC_DISABLE_VTABLES, "disable vtable dispatch") 40 | OPTION( DisablePreopt, OBJC_DISABLE_PREOPTIMIZATION, "disable preoptimization courtesy of dyld shared cache") 41 | OPTION( DisableTaggedPointers, OBJC_DISABLE_TAGGED_POINTERS, "disable tagged pointer optimization of NSNumber et al.") 42 | OPTION( DisableNonpointerIsa, OBJC_DISABLE_NONPOINTER_ISA, "disable non-pointer isa fields") 43 | -------------------------------------------------------------------------------- /runtime/objc-errors.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2003, 2005-2007 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 | * objc-errors.m 25 | * Copyright 1988-2001, NeXT Software, Inc., Apple Computer, Inc. 26 | */ 27 | 28 | #include "objc-private.h" 29 | 30 | #if TARGET_OS_WIN32 31 | 32 | #include 33 | 34 | void _objc_inform_on_crash(const char *fmt, ...) 35 | { 36 | } 37 | 38 | void _objc_inform(const char *fmt, ...) 39 | { 40 | va_list args; 41 | va_start(args, fmt); 42 | _vcprintf(fmt, args); 43 | va_end(args); 44 | _cprintf("\n"); 45 | } 46 | 47 | void _objc_fatal(const char *fmt, ...) 48 | { 49 | va_list args; 50 | va_start(args, fmt); 51 | _vcprintf(fmt, args); 52 | va_end(args); 53 | _cprintf("\n"); 54 | 55 | abort(); 56 | } 57 | 58 | void __objc_error(id rcv, const char *fmt, ...) 59 | { 60 | va_list args; 61 | va_start(args, fmt); 62 | _vcprintf(fmt, args); 63 | va_end(args); 64 | 65 | abort(); 66 | } 67 | 68 | void _objc_error(id rcv, const char *fmt, va_list args) 69 | { 70 | _vcprintf(fmt, args); 71 | 72 | abort(); 73 | } 74 | 75 | #else 76 | 77 | #include <_simple.h> 78 | 79 | OBJC_EXPORT void (*_error)(id, const char *, va_list); 80 | 81 | // Return true if c is a UTF8 continuation byte 82 | static bool isUTF8Continuation(char c) 83 | { 84 | return (c & 0xc0) == 0x80; // continuation byte is 0b10xxxxxx 85 | } 86 | 87 | // Add "message" to any forthcoming crash log. 88 | static mutex_t crashlog_lock; 89 | static void _objc_crashlog(const char *message) 90 | { 91 | char *newmsg; 92 | 93 | #if 0 94 | { 95 | // for debugging at BOOT time. 96 | extern char **_NSGetProgname(void); 97 | FILE *crashlog = fopen("/_objc_crash.log", "a"); 98 | setbuf(crashlog, NULL); 99 | fprintf(crashlog, "[%s] %s\n", *_NSGetProgname(), message); 100 | fclose(crashlog); 101 | sync(); 102 | } 103 | #endif 104 | 105 | mutex_locker_t lock(crashlog_lock); 106 | 107 | char *oldmsg = (char *)CRGetCrashLogMessage(); 108 | size_t oldlen; 109 | const size_t limit = 8000; 110 | 111 | if (!oldmsg) { 112 | newmsg = strdup(message); 113 | } else if ((oldlen = strlen(oldmsg)) > limit) { 114 | // limit total length by dropping old contents 115 | char *truncmsg = oldmsg + oldlen - limit; 116 | // advance past partial UTF-8 bytes 117 | while (isUTF8Continuation(*truncmsg)) truncmsg++; 118 | asprintf(&newmsg, "... %s\n%s", truncmsg, message); 119 | } else { 120 | asprintf(&newmsg, "%s\n%s", oldmsg, message); 121 | } 122 | 123 | if (newmsg) { 124 | // Strip trailing newline 125 | char *c = &newmsg[strlen(newmsg)-1]; 126 | if (*c == '\n') *c = '\0'; 127 | 128 | if (oldmsg) free(oldmsg); 129 | CRSetCrashLogMessage(newmsg); 130 | } 131 | } 132 | 133 | // Returns true if logs should be sent to stderr as well as syslog. 134 | // Copied from CFUtilities.c 135 | static bool also_do_stderr(void) 136 | { 137 | struct stat st; 138 | int ret = fstat(STDERR_FILENO, &st); 139 | if (ret < 0) return false; 140 | mode_t m = st.st_mode & S_IFMT; 141 | if (m == S_IFREG || m == S_IFSOCK || m == S_IFIFO || m == S_IFCHR) { 142 | return true; 143 | } 144 | return false; 145 | } 146 | 147 | // Print "message" to the console. 148 | static void _objc_syslog(const char *message) 149 | { 150 | _simple_asl_log(ASL_LEVEL_ERR, nil, message); 151 | 152 | if (also_do_stderr()) { 153 | write(STDERR_FILENO, message, strlen(message)); 154 | } 155 | } 156 | 157 | /* 158 | * _objc_error is the default *_error handler. 159 | */ 160 | #if !__OBJC2__ 161 | // used by ExceptionHandling.framework 162 | #endif 163 | __attribute__((noreturn)) 164 | void _objc_error(id self, const char *fmt, va_list ap) 165 | { 166 | char *buf; 167 | vasprintf(&buf, fmt, ap); 168 | _objc_fatal("%s: %s", object_getClassName(self), buf); 169 | } 170 | 171 | /* 172 | * this routine handles errors that involve an object (or class). 173 | */ 174 | void __objc_error(id rcv, const char *fmt, ...) 175 | { 176 | va_list vp; 177 | 178 | va_start(vp,fmt); 179 | #if !__OBJC2__ 180 | (*_error)(rcv, fmt, vp); 181 | #endif 182 | _objc_error (rcv, fmt, vp); /* In case (*_error)() returns. */ 183 | va_end(vp); 184 | } 185 | 186 | static __attribute__((noreturn)) 187 | void _objc_fatalv(uint64_t reason, uint64_t flags, const char *fmt, va_list ap) 188 | { 189 | char *buf1; 190 | vasprintf(&buf1, fmt, ap); 191 | 192 | char *buf2; 193 | asprintf(&buf2, "objc[%d]: %s\n", getpid(), buf1); 194 | _objc_syslog(buf2); 195 | 196 | if (DebugDontCrash) { 197 | char *buf3; 198 | asprintf(&buf3, "objc[%d]: HALTED\n", getpid()); 199 | _objc_syslog(buf3); 200 | _Exit(1); 201 | } 202 | else { 203 | abort_with_reason(OS_REASON_OBJC, reason, buf1, flags); 204 | } 205 | } 206 | 207 | void _objc_fatal_with_reason(uint64_t reason, uint64_t flags, 208 | const char *fmt, ...) 209 | { 210 | va_list ap; 211 | va_start(ap, fmt); 212 | _objc_fatalv(reason, flags, fmt, ap); 213 | } 214 | 215 | void _objc_fatal(const char *fmt, ...) 216 | { 217 | va_list ap; 218 | va_start(ap,fmt); 219 | _objc_fatalv(OBJC_EXIT_REASON_UNSPECIFIED, 220 | OS_REASON_FLAG_ONE_TIME_FAILURE, 221 | fmt, ap); 222 | } 223 | 224 | /* 225 | * this routine handles soft runtime errors...like not being able 226 | * add a category to a class (because it wasn't linked in). 227 | */ 228 | void _objc_inform(const char *fmt, ...) 229 | { 230 | va_list ap; 231 | char *buf1; 232 | char *buf2; 233 | 234 | va_start (ap,fmt); 235 | vasprintf(&buf1, fmt, ap); 236 | va_end (ap); 237 | 238 | asprintf(&buf2, "objc[%d]: %s\n", getpid(), buf1); 239 | _objc_syslog(buf2); 240 | 241 | free(buf2); 242 | free(buf1); 243 | } 244 | 245 | 246 | /* 247 | * Like _objc_inform(), but prints the message only in any 248 | * forthcoming crash log, not to the console. 249 | */ 250 | void _objc_inform_on_crash(const char *fmt, ...) 251 | { 252 | va_list ap; 253 | char *buf1; 254 | char *buf2; 255 | 256 | va_start (ap,fmt); 257 | vasprintf(&buf1, fmt, ap); 258 | va_end (ap); 259 | 260 | asprintf(&buf2, "objc[%d]: %s\n", getpid(), buf1); 261 | _objc_crashlog(buf2); 262 | 263 | free(buf2); 264 | free(buf1); 265 | } 266 | 267 | 268 | /* 269 | * Like calling both _objc_inform and _objc_inform_on_crash. 270 | */ 271 | void _objc_inform_now_and_on_crash(const char *fmt, ...) 272 | { 273 | va_list ap; 274 | char *buf1; 275 | char *buf2; 276 | 277 | va_start (ap,fmt); 278 | vasprintf(&buf1, fmt, ap); 279 | va_end (ap); 280 | 281 | asprintf(&buf2, "objc[%d]: %s\n", getpid(), buf1); 282 | _objc_crashlog(buf2); 283 | _objc_syslog(buf2); 284 | 285 | free(buf2); 286 | free(buf1); 287 | } 288 | 289 | #endif 290 | 291 | 292 | BREAKPOINT_FUNCTION( 293 | void _objc_warn_deprecated(void) 294 | ); 295 | 296 | void _objc_inform_deprecated(const char *oldf, const char *newf) 297 | { 298 | if (PrintDeprecation) { 299 | if (newf) { 300 | _objc_inform("The function %s is obsolete. Use %s instead. Set a breakpoint on _objc_warn_deprecated to find the culprit.", oldf, newf); 301 | } else { 302 | _objc_inform("The function %s is obsolete. Do not use it. Set a breakpoint on _objc_warn_deprecated to find the culprit.", oldf); 303 | } 304 | } 305 | _objc_warn_deprecated(); 306 | } 307 | -------------------------------------------------------------------------------- /runtime/objc-exception.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2002-2003, 2006-2007 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 | #ifndef __OBJC_EXCEPTION_H_ 25 | #define __OBJC_EXCEPTION_H_ 26 | 27 | #include 28 | #include 29 | 30 | #if !__OBJC2__ 31 | 32 | // compiler reserves a setjmp buffer + 4 words as localExceptionData 33 | 34 | OBJC_EXPORT void objc_exception_throw(id exception) 35 | __OSX_AVAILABLE(10.3) 36 | __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; 37 | OBJC_EXPORT void objc_exception_try_enter(void *localExceptionData) 38 | __OSX_AVAILABLE(10.3) 39 | __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; 40 | OBJC_EXPORT void objc_exception_try_exit(void *localExceptionData) 41 | __OSX_AVAILABLE(10.3) 42 | __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; 43 | OBJC_EXPORT id objc_exception_extract(void *localExceptionData) 44 | __OSX_AVAILABLE(10.3) 45 | __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; 46 | OBJC_EXPORT int objc_exception_match(Class exceptionClass, id exception) 47 | __OSX_AVAILABLE(10.3) 48 | __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; 49 | 50 | 51 | typedef struct { 52 | int version; 53 | void (*throw_exc)(id); // version 0 54 | void (*try_enter)(void *); // version 0 55 | void (*try_exit)(void *); // version 0 56 | id (*extract)(void *); // version 0 57 | int (*match)(Class, id); // version 0 58 | } objc_exception_functions_t; 59 | 60 | // get table; version tells how many 61 | OBJC_EXPORT void objc_exception_get_functions(objc_exception_functions_t *table) 62 | __OSX_AVAILABLE(10.3) 63 | __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; 64 | 65 | // set table 66 | OBJC_EXPORT void objc_exception_set_functions(objc_exception_functions_t *table) 67 | __OSX_AVAILABLE(10.3) 68 | __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; 69 | 70 | 71 | // !__OBJC2__ 72 | #else 73 | // __OBJC2__ 74 | 75 | typedef id (*objc_exception_preprocessor)(id exception); 76 | typedef int (*objc_exception_matcher)(Class catch_type, id exception); 77 | typedef void (*objc_uncaught_exception_handler)(id exception); 78 | typedef void (*objc_exception_handler)(id unused, void *context); 79 | 80 | /** 81 | * Throw a runtime exception. This function is inserted by the compiler 82 | * where \c @throw would otherwise be. 83 | * 84 | * @param exception The exception to be thrown. 85 | */ 86 | OBJC_EXPORT void objc_exception_throw(id exception) 87 | OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); 88 | OBJC_EXPORT void objc_exception_rethrow(void) 89 | OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); 90 | OBJC_EXPORT id objc_begin_catch(void *exc_buf) 91 | OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); 92 | OBJC_EXPORT void objc_end_catch(void) 93 | OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); 94 | OBJC_EXPORT void objc_terminate(void) 95 | OBJC_AVAILABLE(10.8, 6.0, 9.0, 1.0); 96 | 97 | OBJC_EXPORT objc_exception_preprocessor objc_setExceptionPreprocessor(objc_exception_preprocessor fn) 98 | OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); 99 | OBJC_EXPORT objc_exception_matcher objc_setExceptionMatcher(objc_exception_matcher fn) 100 | OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); 101 | OBJC_EXPORT objc_uncaught_exception_handler objc_setUncaughtExceptionHandler(objc_uncaught_exception_handler fn) 102 | OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0); 103 | 104 | // Not for iOS. 105 | OBJC_EXPORT uintptr_t objc_addExceptionHandler(objc_exception_handler fn, void *context) 106 | __OSX_AVAILABLE(10.5) 107 | __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; 108 | OBJC_EXPORT void objc_removeExceptionHandler(uintptr_t token) 109 | __OSX_AVAILABLE(10.5) 110 | __IOS_UNAVAILABLE __TVOS_UNAVAILABLE __WATCHOS_UNAVAILABLE; 111 | 112 | // __OBJC2__ 113 | #endif 114 | 115 | #endif // __OBJC_EXCEPTION_H_ 116 | 117 | -------------------------------------------------------------------------------- /runtime/objc-file-old.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009 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 | #ifndef _OBJC_FILE_OLD_H 25 | #define _OBJC_FILE_OLD_H 26 | 27 | #if !__OBJC2__ 28 | 29 | #include "objc-os.h" 30 | 31 | struct objc_module; 32 | struct old_protocol; 33 | struct old_class; 34 | 35 | __BEGIN_DECLS 36 | 37 | extern struct objc_module *_getObjcModules(const header_info *hi, size_t *nmodules); 38 | extern SEL *_getObjcSelectorRefs(const header_info *hi, size_t *nmess); 39 | extern struct old_protocol **_getObjcProtocols(const header_info *hi, size_t *nprotos); 40 | extern Class *_getObjcClassRefs(const header_info *hi, size_t *nclasses); 41 | extern const char *_getObjcClassNames(const header_info *hi, size_t *size); 42 | 43 | using Initializer = void(*)(void); 44 | extern Initializer* getLibobjcInitializers(const headerType *mhdr, size_t *count); 45 | 46 | __END_DECLS 47 | 48 | #endif 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /runtime/objc-file-old.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2007 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 | // Copyright 1988-1996 NeXT Software, Inc. 24 | 25 | #if !__OBJC2__ 26 | 27 | #include "objc-private.h" 28 | #include "objc-runtime-old.h" 29 | #include "objc-file-old.h" 30 | 31 | #if TARGET_OS_WIN32 32 | 33 | /* 34 | Module 35 | _getObjcModules(const header_info *hi, size_t *nmodules) 36 | { 37 | if (nmodules) *nmodules = hi->moduleCount; 38 | return hi->modules; 39 | } 40 | */ 41 | SEL * 42 | _getObjcSelectorRefs(const header_info *hi, size_t *nmess) 43 | { 44 | if (nmess) *nmess = hi->selrefCount; 45 | return hi->selrefs; 46 | } 47 | 48 | struct old_protocol ** 49 | _getObjcProtocols(const header_info *hi, size_t *nprotos) 50 | { 51 | if (nprotos) *nprotos = hi->protocolCount; 52 | return hi->protocols; 53 | } 54 | 55 | Class* 56 | _getObjcClassRefs(const header_info *hi, size_t *nclasses) 57 | { 58 | if (nclasses) *nclasses = hi->clsrefCount; 59 | return (Class*)hi->clsrefs; 60 | } 61 | 62 | // __OBJC,__class_names section only emitted by CodeWarrior rdar://4951638 63 | const char * 64 | _getObjcClassNames(const header_info *hi, size_t *size) 65 | { 66 | if (size) *size = 0; 67 | return NULL; 68 | } 69 | 70 | #else 71 | 72 | #define GETSECT(name, type, segname, sectname) \ 73 | type *name(const headerType *mhdr, size_t *outCount) \ 74 | { \ 75 | unsigned long byteCount = 0; \ 76 | type *data = (type *) \ 77 | getsectiondata(mhdr, segname, sectname, &byteCount); \ 78 | *outCount = byteCount / sizeof(type); \ 79 | return data; \ 80 | } \ 81 | type *name(const header_info *hi, size_t *outCount) \ 82 | { \ 83 | return name(hi->mhdr(), outCount); \ 84 | } 85 | 86 | GETSECT(_getObjcModules, objc_module, "__OBJC", "__module_info"); 87 | GETSECT(_getObjcSelectorRefs, SEL, "__OBJC", "__message_refs"); 88 | GETSECT(_getObjcClassRefs, Class, "__OBJC", "__cls_refs"); 89 | GETSECT(_getObjcClassNames, const char, "__OBJC", "__class_names"); 90 | // __OBJC,__class_names section only emitted by CodeWarrior rdar://4951638 91 | GETSECT(getLibobjcInitializers, Initializer, "__DATA", "__objc_init_func"); 92 | 93 | 94 | objc_image_info * 95 | _getObjcImageInfo(const headerType *mhdr, size_t *outBytes) 96 | { 97 | unsigned long byteCount = 0; 98 | objc_image_info *info = (objc_image_info *) 99 | getsectiondata(mhdr, SEG_OBJC, "__image_info", &byteCount); 100 | *outBytes = byteCount; 101 | return info; 102 | } 103 | 104 | 105 | struct old_protocol ** 106 | _getObjcProtocols(const header_info *hi, size_t *nprotos) 107 | { 108 | unsigned long size = 0; 109 | struct old_protocol *protos = (struct old_protocol *) 110 | getsectiondata(hi->mhdr(), SEG_OBJC, "__protocol", &size); 111 | *nprotos = size / sizeof(struct old_protocol); 112 | 113 | if (!hi->proto_refs && *nprotos) { 114 | size_t i; 115 | header_info *whi = (header_info *)hi; 116 | whi->proto_refs = (struct old_protocol **) 117 | malloc(*nprotos * sizeof(*hi->proto_refs)); 118 | for (i = 0; i < *nprotos; i++) { 119 | hi->proto_refs[i] = protos+i; 120 | } 121 | } 122 | 123 | return hi->proto_refs; 124 | } 125 | 126 | 127 | static const segmentType * 128 | getsegbynamefromheader(const headerType *head, const char *segname) 129 | { 130 | const segmentType *sgp; 131 | unsigned long i; 132 | 133 | sgp = (const segmentType *) (head + 1); 134 | for (i = 0; i < head->ncmds; i++){ 135 | if (sgp->cmd == SEGMENT_CMD) { 136 | if (strncmp(sgp->segname, segname, sizeof(sgp->segname)) == 0) { 137 | return sgp; 138 | } 139 | } 140 | sgp = (const segmentType *)((char *)sgp + sgp->cmdsize); 141 | } 142 | return NULL; 143 | } 144 | 145 | bool 146 | _hasObjcContents(const header_info *hi) 147 | { 148 | // Look for an __OBJC,* section other than __OBJC,__image_info 149 | const segmentType *seg = getsegbynamefromheader(hi->mhdr(), "__OBJC"); 150 | const sectionType *sect; 151 | uint32_t i; 152 | for (i = 0; i < seg->nsects; i++) { 153 | sect = ((const sectionType *)(seg+1))+i; 154 | if (0 != strncmp(sect->sectname, "__image_info", 12)) { 155 | return YES; 156 | } 157 | } 158 | 159 | return NO; 160 | } 161 | 162 | 163 | #endif 164 | 165 | #endif 166 | -------------------------------------------------------------------------------- /runtime/objc-file.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2009 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 | #ifndef _OBJC_FILE_NEW_H 25 | #define _OBJC_FILE_NEW_H 26 | 27 | #if __OBJC2__ 28 | 29 | #include "objc-runtime-new.h" 30 | 31 | // classref_t is not fixed up at launch; use remapClass() to convert 32 | 33 | extern SEL *_getObjc2SelectorRefs(const header_info *hi, size_t *count); 34 | extern message_ref_t *_getObjc2MessageRefs(const header_info *hi, size_t *count); 35 | extern Class*_getObjc2ClassRefs(const header_info *hi, size_t *count); 36 | extern Class*_getObjc2SuperRefs(const header_info *hi, size_t *count); 37 | extern classref_t *_getObjc2ClassList(const header_info *hi, size_t *count); 38 | extern classref_t *_getObjc2NonlazyClassList(const header_info *hi, size_t *count); 39 | extern category_t **_getObjc2CategoryList(const header_info *hi, size_t *count); 40 | extern category_t **_getObjc2NonlazyCategoryList(const header_info *hi, size_t *count); 41 | extern protocol_t **_getObjc2ProtocolList(const header_info *hi, size_t *count); 42 | extern protocol_t **_getObjc2ProtocolRefs(const header_info *hi, size_t *count); 43 | using Initializer = void(*)(void); 44 | extern Initializer* getLibobjcInitializers(const header_info *hi, size_t *count); 45 | 46 | extern classref_t *_getObjc2NonlazyClassList(const headerType *mhdr, size_t *count); 47 | extern category_t **_getObjc2NonlazyCategoryList(const headerType *mhdr, size_t *count); 48 | extern Initializer* getLibobjcInitializers(const headerType *mhdr, size_t *count); 49 | 50 | #endif 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /runtime/objc-file.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2007 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 | #if __OBJC2__ 25 | 26 | #include "objc-private.h" 27 | #include "objc-file.h" 28 | 29 | 30 | // Look for a __DATA or __DATA_CONST or __DATA_DIRTY section 31 | // with the given name that stores an array of T. 32 | template 33 | T* getDataSection(const headerType *mhdr, const char *sectname, 34 | size_t *outBytes, size_t *outCount) 35 | { 36 | unsigned long byteCount = 0; 37 | T* data = (T*)getsectiondata(mhdr, "__DATA", sectname, &byteCount); 38 | if (!data) { 39 | data = (T*)getsectiondata(mhdr, "__DATA_CONST", sectname, &byteCount); 40 | } 41 | if (!data) { 42 | data = (T*)getsectiondata(mhdr, "__DATA_DIRTY", sectname, &byteCount); 43 | } 44 | if (outBytes) *outBytes = byteCount; 45 | if (outCount) *outCount = byteCount / sizeof(T); 46 | return data; 47 | } 48 | 49 | #define GETSECT(name, type, sectname) \ 50 | type *name(const headerType *mhdr, size_t *outCount) { \ 51 | return getDataSection(mhdr, sectname, nil, outCount); \ 52 | } \ 53 | type *name(const header_info *hi, size_t *outCount) { \ 54 | return getDataSection(hi->mhdr(), sectname, nil, outCount); \ 55 | } 56 | 57 | // function name content type section name 58 | GETSECT(_getObjc2SelectorRefs, SEL, "__objc_selrefs"); 59 | GETSECT(_getObjc2MessageRefs, message_ref_t, "__objc_msgrefs"); 60 | GETSECT(_getObjc2ClassRefs, Class, "__objc_classrefs"); 61 | GETSECT(_getObjc2SuperRefs, Class, "__objc_superrefs"); 62 | GETSECT(_getObjc2ClassList, classref_t, "__objc_classlist"); 63 | GETSECT(_getObjc2NonlazyClassList, classref_t, "__objc_nlclslist"); 64 | GETSECT(_getObjc2CategoryList, category_t *, "__objc_catlist"); 65 | GETSECT(_getObjc2NonlazyCategoryList, category_t *, "__objc_nlcatlist"); 66 | GETSECT(_getObjc2ProtocolList, protocol_t *, "__objc_protolist"); 67 | GETSECT(_getObjc2ProtocolRefs, protocol_t *, "__objc_protorefs"); 68 | GETSECT(getLibobjcInitializers, Initializer, "__objc_init_func"); 69 | 70 | 71 | objc_image_info * 72 | _getObjcImageInfo(const headerType *mhdr, size_t *outBytes) 73 | { 74 | return getDataSection(mhdr, "__objc_imageinfo", 75 | outBytes, nil); 76 | } 77 | 78 | 79 | static const segmentType * 80 | getsegbynamefromheader(const headerType *mhdr, const char *segname) 81 | { 82 | const segmentType *seg = (const segmentType *) (mhdr + 1); 83 | for (unsigned long i = 0; i < mhdr->ncmds; i++){ 84 | if (seg->cmd == SEGMENT_CMD && segnameEquals(seg->segname, segname)) { 85 | return seg; 86 | } 87 | seg = (const segmentType *)((char *)seg + seg->cmdsize); 88 | } 89 | return nil; 90 | } 91 | 92 | // Look for an __objc* section other than __objc_imageinfo 93 | static bool segmentHasObjcContents(const segmentType *seg) 94 | { 95 | if (seg) { 96 | for (uint32_t i = 0; i < seg->nsects; i++) { 97 | const sectionType *sect = ((const sectionType *)(seg+1))+i; 98 | if (sectnameStartsWith(sect->sectname, "__objc_") && 99 | !sectnameEquals(sect->sectname, "__objc_imageinfo")) 100 | { 101 | return true; 102 | } 103 | } 104 | } 105 | 106 | return false; 107 | } 108 | 109 | // Look for an __objc* section other than __objc_imageinfo 110 | bool 111 | _hasObjcContents(const header_info *hi) 112 | { 113 | const segmentType *data = 114 | getsegbynamefromheader(hi->mhdr(), "__DATA"); 115 | const segmentType *data_const = 116 | getsegbynamefromheader(hi->mhdr(), "__DATA_CONST"); 117 | const segmentType *data_dirty = 118 | getsegbynamefromheader(hi->mhdr(), "__DATA_DIRTY"); 119 | 120 | return segmentHasObjcContents(data) 121 | || segmentHasObjcContents(data_const) 122 | || segmentHasObjcContents(data_dirty); 123 | } 124 | 125 | 126 | // OBJC2 127 | #endif 128 | -------------------------------------------------------------------------------- /runtime/objc-initialize.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2005-2006 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 | #ifndef _OBJC_INITIALIZE_H 25 | #define _OBJC_INITIALIZE_H 26 | 27 | #include "objc-private.h" 28 | 29 | __BEGIN_DECLS 30 | 31 | struct _objc_initializing_classes; 32 | 33 | extern void _class_initialize(Class cls); 34 | 35 | extern void _destroyInitializingClassList(struct _objc_initializing_classes *list); 36 | 37 | extern bool _thisThreadIsInitializingClass(Class cls); 38 | 39 | __END_DECLS 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /runtime/objc-load.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2001, 2005-2006 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 | * objc-load.h 25 | * Copyright 1988-1996, NeXT Software, Inc. 26 | */ 27 | 28 | #ifndef _OBJC_LOAD_H_ 29 | #define _OBJC_LOAD_H_ 30 | 31 | #include 32 | 33 | #include 34 | 35 | /* dynamically loading Mach-O object files that contain Objective-C code */ 36 | 37 | OBJC_EXPORT long objc_loadModules ( 38 | char *modlist[], 39 | void *errStream, 40 | void (*class_callback) (Class, Category), 41 | /*headerType*/ struct mach_header **hdr_addr, 42 | char *debug_file 43 | ) OBJC2_UNAVAILABLE; 44 | OBJC_EXPORT int objc_loadModule ( 45 | char * moduleName, 46 | void (*class_callback) (Class, Category), 47 | int * errorCode 48 | ) OBJC2_UNAVAILABLE; 49 | OBJC_EXPORT long objc_unloadModules( 50 | void *errorStream, /* input (optional) */ 51 | void (*unloadCallback)(Class, Category) /* input (optional) */ 52 | ) OBJC2_UNAVAILABLE; 53 | 54 | #endif /* _OBJC_LOAD_H_ */ 55 | -------------------------------------------------------------------------------- /runtime/objc-load.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2001, 2004-2007 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 | /* 25 | * objc-load.m 26 | * Copyright 1988-1996, NeXT Software, Inc. 27 | * Author: s. naroff 28 | * 29 | */ 30 | 31 | #include "objc-private.h" 32 | #include "objc-load.h" 33 | 34 | #if !__OBJC2__ && !TARGET_OS_WIN32 35 | 36 | extern void (*callbackFunction)( Class, Category ); 37 | 38 | 39 | /********************************************************************************** 40 | * objc_loadModule. 41 | * 42 | * NOTE: Loading isn't really thread safe. If a load message recursively calls 43 | * objc_loadModules() both sets will be loaded correctly, but if the original 44 | * caller calls objc_unloadModules() it will probably unload the wrong modules. 45 | * If a load message calls objc_unloadModules(), then it will unload 46 | * the modules currently being loaded, which will probably cause a crash. 47 | * 48 | * Error handling is still somewhat crude. If we encounter errors while 49 | * linking up classes or categories, we will not recover correctly. 50 | * 51 | * I removed attempts to lock the class hashtable, since this introduced 52 | * deadlock which was hard to remove. The only way you can get into trouble 53 | * is if one thread loads a module while another thread tries to access the 54 | * loaded classes (using objc_lookUpClass) before the load is complete. 55 | **********************************************************************************/ 56 | int objc_loadModule(char *moduleName, void (*class_callback) (Class, Category), int *errorCode) 57 | { 58 | int successFlag = 1; 59 | int locErrorCode; 60 | NSObjectFileImage objectFileImage; 61 | NSObjectFileImageReturnCode code; 62 | 63 | // So we don't have to check this everywhere 64 | if (errorCode == NULL) 65 | errorCode = &locErrorCode; 66 | 67 | if (moduleName == NULL) 68 | { 69 | *errorCode = NSObjectFileImageInappropriateFile; 70 | return 0; 71 | } 72 | 73 | if (_dyld_present () == 0) 74 | { 75 | *errorCode = NSObjectFileImageFailure; 76 | return 0; 77 | } 78 | 79 | callbackFunction = class_callback; 80 | code = NSCreateObjectFileImageFromFile (moduleName, &objectFileImage); 81 | if (code != NSObjectFileImageSuccess) 82 | { 83 | *errorCode = code; 84 | return 0; 85 | } 86 | 87 | if (NSLinkModule(objectFileImage, moduleName, NSLINKMODULE_OPTION_RETURN_ON_ERROR) == NULL) { 88 | NSLinkEditErrors error; 89 | int errorNum; 90 | const char *fileName, *errorString; 91 | NSLinkEditError(&error, &errorNum, &fileName, &errorString); 92 | // These errors may overlap with other errors that objc_loadModule returns in other failure cases. 93 | *errorCode = error; 94 | return 0; 95 | } 96 | callbackFunction = NULL; 97 | 98 | 99 | return successFlag; 100 | } 101 | 102 | /********************************************************************************** 103 | * objc_loadModules. 104 | **********************************************************************************/ 105 | /* Lock for dynamic loading and unloading. */ 106 | // static OBJC_DECLARE_LOCK (loadLock); 107 | 108 | 109 | long objc_loadModules (char * modlist[], 110 | void * errStream, 111 | void (*class_callback) (Class, Category), 112 | headerType ** hdr_addr, 113 | char * debug_file) 114 | { 115 | char ** modules; 116 | int code; 117 | int itWorked; 118 | 119 | if (modlist == 0) 120 | return 0; 121 | 122 | for (modules = &modlist[0]; *modules != 0; modules++) 123 | { 124 | itWorked = objc_loadModule (*modules, class_callback, &code); 125 | if (itWorked == 0) 126 | { 127 | //if (errStream) 128 | // NXPrintf ((NXStream *) errStream, "objc_loadModules(%s) code = %d\n", *modules, code); 129 | return 1; 130 | } 131 | 132 | if (hdr_addr) 133 | *(hdr_addr++) = 0; 134 | } 135 | 136 | return 0; 137 | } 138 | 139 | /********************************************************************************** 140 | * objc_unloadModules. 141 | * 142 | * NOTE: Unloading isn't really thread safe. If an unload message calls 143 | * objc_loadModules() or objc_unloadModules(), then the current call 144 | * to objc_unloadModules() will probably unload the wrong stuff. 145 | **********************************************************************************/ 146 | 147 | long objc_unloadModules (void * errStream, 148 | void (*unload_callback) (Class, Category)) 149 | { 150 | headerType * header_addr = 0; 151 | int errflag = 0; 152 | 153 | // TODO: to make unloading work, should get the current header 154 | 155 | if (header_addr) 156 | { 157 | ; // TODO: unload the current header 158 | } 159 | else 160 | { 161 | errflag = 1; 162 | } 163 | 164 | return errflag; 165 | } 166 | 167 | #endif 168 | -------------------------------------------------------------------------------- /runtime/objc-loadmethod.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004-2006 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 | /*********************************************************************** 25 | * objc-loadmethod.h 26 | * Support for +load methods. 27 | **********************************************************************/ 28 | 29 | #ifndef _OBJC_LOADMETHOD_H 30 | #define _OBJC_LOADMETHOD_H 31 | 32 | #include "objc-private.h" 33 | 34 | __BEGIN_DECLS 35 | 36 | extern void add_class_to_loadable_list(Class cls); 37 | extern void add_category_to_loadable_list(Category cat); 38 | extern void remove_class_from_loadable_list(Class cls); 39 | extern void remove_category_from_loadable_list(Category cat); 40 | 41 | extern void call_load_methods(void); 42 | 43 | __END_DECLS 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /runtime/objc-lockdebug.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 | extern void lockdebug_mutex_lock(mutex_tt *lock); 25 | extern void lockdebug_mutex_try_lock(mutex_tt *lock); 26 | extern void lockdebug_mutex_unlock(mutex_tt *lock); 27 | extern void lockdebug_mutex_assert_locked(mutex_tt *lock); 28 | extern void lockdebug_mutex_assert_unlocked(mutex_tt *lock); 29 | 30 | static inline void lockdebug_mutex_lock(mutex_tt *lock) { } 31 | static inline void lockdebug_mutex_try_lock(mutex_tt *lock) { } 32 | static inline void lockdebug_mutex_unlock(mutex_tt *lock) { } 33 | static inline void lockdebug_mutex_assert_locked(mutex_tt *lock) { } 34 | static inline void lockdebug_mutex_assert_unlocked(mutex_tt *lock) { } 35 | 36 | 37 | extern void lockdebug_monitor_enter(monitor_tt *lock); 38 | extern void lockdebug_monitor_leave(monitor_tt *lock); 39 | extern void lockdebug_monitor_wait(monitor_tt *lock); 40 | extern void lockdebug_monitor_assert_locked(monitor_tt *lock); 41 | extern void lockdebug_monitor_assert_unlocked(monitor_tt *lock); 42 | 43 | static inline void lockdebug_monitor_enter(monitor_tt *lock) { } 44 | static inline void lockdebug_monitor_leave(monitor_tt *lock) { } 45 | static inline void lockdebug_monitor_wait(monitor_tt *lock) { } 46 | static inline void lockdebug_monitor_assert_locked(monitor_tt *lock) { } 47 | static inline void lockdebug_monitor_assert_unlocked(monitor_tt *lock) {} 48 | 49 | 50 | extern void 51 | lockdebug_recursive_mutex_lock(recursive_mutex_tt *lock); 52 | extern void 53 | lockdebug_recursive_mutex_unlock(recursive_mutex_tt *lock); 54 | extern void 55 | lockdebug_recursive_mutex_assert_locked(recursive_mutex_tt *lock); 56 | extern void 57 | lockdebug_recursive_mutex_assert_unlocked(recursive_mutex_tt *lock); 58 | 59 | static inline void 60 | lockdebug_recursive_mutex_lock(recursive_mutex_tt *lock) { } 61 | static inline void 62 | lockdebug_recursive_mutex_unlock(recursive_mutex_tt *lock) { } 63 | static inline void 64 | lockdebug_recursive_mutex_assert_locked(recursive_mutex_tt *lock) { } 65 | static inline void 66 | lockdebug_recursive_mutex_assert_unlocked(recursive_mutex_tt *lock) { } 67 | 68 | 69 | extern void lockdebug_rwlock_read(rwlock_tt *lock); 70 | extern void lockdebug_rwlock_try_read_success(rwlock_tt *lock); 71 | extern void lockdebug_rwlock_unlock_read(rwlock_tt *lock); 72 | extern void lockdebug_rwlock_write(rwlock_tt *lock); 73 | extern void lockdebug_rwlock_try_write_success(rwlock_tt *lock); 74 | extern void lockdebug_rwlock_unlock_write(rwlock_tt *lock); 75 | extern void lockdebug_rwlock_assert_reading(rwlock_tt *lock); 76 | extern void lockdebug_rwlock_assert_writing(rwlock_tt *lock); 77 | extern void lockdebug_rwlock_assert_locked(rwlock_tt *lock); 78 | extern void lockdebug_rwlock_assert_unlocked(rwlock_tt *lock); 79 | 80 | static inline void lockdebug_rwlock_read(rwlock_tt *) { } 81 | static inline void lockdebug_rwlock_try_read_success(rwlock_tt *) { } 82 | static inline void lockdebug_rwlock_unlock_read(rwlock_tt *) { } 83 | static inline void lockdebug_rwlock_write(rwlock_tt *) { } 84 | static inline void lockdebug_rwlock_try_write_success(rwlock_tt *) { } 85 | static inline void lockdebug_rwlock_unlock_write(rwlock_tt *) { } 86 | static inline void lockdebug_rwlock_assert_reading(rwlock_tt *) { } 87 | static inline void lockdebug_rwlock_assert_writing(rwlock_tt *) { } 88 | static inline void lockdebug_rwlock_assert_locked(rwlock_tt *) { } 89 | static inline void lockdebug_rwlock_assert_unlocked(rwlock_tt *) { } 90 | -------------------------------------------------------------------------------- /runtime/objc-probes.d: -------------------------------------------------------------------------------- 1 | provider objc_runtime 2 | { 3 | probe objc_exception_throw(void *id); 4 | probe objc_exception_rethrow(); 5 | }; 6 | -------------------------------------------------------------------------------- /runtime/objc-references.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 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 | * objc-references.h 25 | */ 26 | 27 | #ifndef _OBJC_REFERENCES_H_ 28 | #define _OBJC_REFERENCES_H_ 29 | 30 | #include "objc-api.h" 31 | #include "objc-config.h" 32 | 33 | __BEGIN_DECLS 34 | 35 | extern void _object_set_associative_reference(id object, void *key, id value, uintptr_t policy); 36 | extern id _object_get_associative_reference(id object, void *key); 37 | extern void _object_remove_assocations(id object); 38 | 39 | __END_DECLS 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /runtime/objc-runtime.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | -------------------------------------------------------------------------------- /runtime/objc-sel-old.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2007 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 | /* 25 | * Utilities for registering and looking up selectors. The sole 26 | * purpose of the selector tables is a registry whereby there is 27 | * exactly one address (selector) associated with a given string 28 | * (method name). 29 | */ 30 | 31 | #if !__OBJC2__ 32 | 33 | #include "objc-private.h" 34 | #include "objc-sel-set.h" 35 | 36 | #if SUPPORT_PREOPT 37 | #include 38 | static const objc_selopt_t *builtins = NULL; 39 | #endif 40 | 41 | __BEGIN_DECLS 42 | 43 | static size_t SelrefCount = 0; 44 | 45 | static const char *_objc_empty_selector = ""; 46 | static struct __objc_sel_set *_objc_selectors = NULL; 47 | 48 | 49 | static SEL _objc_search_builtins(const char *key) 50 | { 51 | #if defined(DUMP_SELECTORS) 52 | if (NULL != key) printf("\t\"%s\",\n", key); 53 | #endif 54 | 55 | if (!key) return (SEL)0; 56 | if ('\0' == *key) return (SEL)_objc_empty_selector; 57 | 58 | #if SUPPORT_PREOPT 59 | if (builtins) return (SEL)builtins->get(key); 60 | #endif 61 | 62 | return (SEL)0; 63 | } 64 | 65 | 66 | const char *sel_getName(SEL sel) { 67 | return sel ? (const char *)sel : ""; 68 | } 69 | 70 | 71 | BOOL sel_isMapped(SEL name) 72 | { 73 | SEL sel; 74 | 75 | if (!name) return NO; 76 | 77 | sel = _objc_search_builtins((const char *)name); 78 | if (sel) return YES; 79 | 80 | rwlock_reader_t lock(selLock); 81 | if (_objc_selectors) { 82 | sel = __objc_sel_set_get(_objc_selectors, name); 83 | } 84 | return bool(sel); 85 | } 86 | 87 | static SEL __sel_registerName(const char *name, int lock, int copy) 88 | { 89 | SEL result = 0; 90 | 91 | if (lock) selLock.assertUnlocked(); 92 | else selLock.assertWriting(); 93 | 94 | if (!name) return (SEL)0; 95 | result = _objc_search_builtins(name); 96 | if (result) return result; 97 | 98 | if (lock) selLock.read(); 99 | if (_objc_selectors) { 100 | result = __objc_sel_set_get(_objc_selectors, (SEL)name); 101 | } 102 | if (lock) selLock.unlockRead(); 103 | if (result) return result; 104 | 105 | // No match. Insert. 106 | 107 | if (lock) selLock.write(); 108 | 109 | if (!_objc_selectors) { 110 | _objc_selectors = __objc_sel_set_create(SelrefCount); 111 | } 112 | if (lock) { 113 | // Rescan in case it was added while we dropped the lock 114 | result = __objc_sel_set_get(_objc_selectors, (SEL)name); 115 | } 116 | if (!result) { 117 | result = (SEL)(copy ? strdup(name) : name); 118 | __objc_sel_set_add(_objc_selectors, result); 119 | #if defined(DUMP_UNKNOWN_SELECTORS) 120 | printf("\t\"%s\",\n", name); 121 | #endif 122 | } 123 | 124 | if (lock) selLock.unlockWrite(); 125 | return result; 126 | } 127 | 128 | 129 | SEL sel_registerName(const char *name) { 130 | return __sel_registerName(name, 1, 1); // YES lock, YES copy 131 | } 132 | 133 | SEL sel_registerNameNoLock(const char *name, bool copy) { 134 | return __sel_registerName(name, 0, copy); // NO lock, maybe copy 135 | } 136 | 137 | void sel_lock(void) 138 | { 139 | selLock.write(); 140 | } 141 | 142 | void sel_unlock(void) 143 | { 144 | selLock.unlockWrite(); 145 | } 146 | 147 | 148 | // 2001/1/24 149 | // the majority of uses of this function (which used to return NULL if not found) 150 | // did not check for NULL, so, in fact, never return NULL 151 | // 152 | SEL sel_getUid(const char *name) { 153 | return __sel_registerName(name, 2, 1); // YES lock, YES copy 154 | } 155 | 156 | 157 | BOOL sel_isEqual(SEL lhs, SEL rhs) 158 | { 159 | return bool(lhs == rhs); 160 | } 161 | 162 | 163 | /*********************************************************************** 164 | * sel_init 165 | * Initialize selector tables and register selectors used internally. 166 | **********************************************************************/ 167 | void sel_init(size_t selrefCount) 168 | { 169 | // save this value for later 170 | SelrefCount = selrefCount; 171 | 172 | #if SUPPORT_PREOPT 173 | builtins = preoptimizedSelectors(); 174 | #endif 175 | 176 | // Register selectors used by libobjc 177 | 178 | #define s(x) SEL_##x = sel_registerNameNoLock(#x, NO) 179 | #define t(x,y) SEL_##y = sel_registerNameNoLock(#x, NO) 180 | 181 | sel_lock(); 182 | 183 | s(load); 184 | s(initialize); 185 | t(resolveInstanceMethod:, resolveInstanceMethod); 186 | t(resolveClassMethod:, resolveClassMethod); 187 | t(.cxx_construct, cxx_construct); 188 | t(.cxx_destruct, cxx_destruct); 189 | s(retain); 190 | s(release); 191 | s(autorelease); 192 | s(retainCount); 193 | s(alloc); 194 | t(allocWithZone:, allocWithZone); 195 | s(dealloc); 196 | s(copy); 197 | s(new); 198 | t(forwardInvocation:, forwardInvocation); 199 | t(_tryRetain, tryRetain); 200 | t(_isDeallocating, isDeallocating); 201 | s(retainWeakReference); 202 | s(allowsWeakReference); 203 | 204 | extern SEL FwdSel; 205 | FwdSel = sel_registerNameNoLock("forward::", NO); 206 | 207 | sel_unlock(); 208 | 209 | #undef s 210 | #undef t 211 | } 212 | 213 | __END_DECLS 214 | 215 | #endif 216 | -------------------------------------------------------------------------------- /runtime/objc-sel-set.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2004 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 | /* 25 | * objc-sel-set.h 26 | * A set of SELs used for SEL uniquing. 27 | */ 28 | 29 | #ifndef _OBJC_SEL_SET_H_ 30 | #define _OBJC_SEL_SET_H_ 31 | 32 | #if !__OBJC2__ 33 | 34 | #include 35 | #include "objc-os.h" 36 | 37 | __BEGIN_DECLS 38 | 39 | struct __objc_sel_set; 40 | 41 | extern struct __objc_sel_set *__objc_sel_set_create(size_t selrefCount); 42 | extern SEL __objc_sel_set_get(struct __objc_sel_set *sset, SEL candidate); 43 | extern void __objc_sel_set_add(struct __objc_sel_set *sset, SEL value); 44 | 45 | __END_DECLS 46 | 47 | #endif 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /runtime/objc-sel-set.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2004,2008 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 | /* 25 | * objc-sel-set.h 26 | * A cut-down copy of CFSet used for SEL uniquing. 27 | */ 28 | 29 | 30 | // NOTE: even on a 64-bit system, the implementation is still limited 31 | // to 32-bit integers (like, the count), but SEL can be any size. 32 | 33 | #include 34 | #include "objc-private.h" 35 | #include "objc-sel-set.h" 36 | 37 | #if !__OBJC2__ 38 | 39 | 40 | #if !SUPPORT_MOD 41 | // mod-free power of 2 version 42 | 43 | #define CONSTRAIN(val, range) ((val) & ((range)-1)) 44 | #define SIZE 27 45 | 46 | static const uint32_t __objc_sel_set_capacities[SIZE+1] = { 47 | 3, 6, 12, 24, 48, 96, 192, 384, 768, 1536, 3072, 6144, 12288, 24576, 48 | 49152, 98304, 196608, 393216, 786432, 1572864, 3145728, 6291456, 49 | 12582912, 25165824, 50331648, 100663296, 201326592, UINT32_MAX 50 | }; 51 | 52 | static const uint32_t __objc_sel_set_buckets[SIZE] = { // powers of 2 53 | 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 54 | 65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608, 55 | 16777216, 33554432, 67108864, 134217728, 268435456 56 | }; 57 | 58 | #else 59 | // prime version 60 | 61 | #define CONSTRAIN(val, range) ((val) % (range)) 62 | #define SIZE 42 63 | 64 | static const uint32_t __objc_sel_set_capacities[SIZE+1] = { 65 | 4, 8, 17, 29, 47, 76, 123, 199, 322, 521, 843, 1364, 2207, 3571, 66 | 5778, 9349, 15127, 24476, 39603, 64079, 103682, 167761, 271443, 67 | 439204, 710647, 1149851, 1860498, 3010349, 4870847, 7881196, 12752043, 68 | 20633239, 33385282, 54018521, 87403803, 141422324, 228826127, 370248451, 69 | 599074578, 969323029, 1568397607, 2537720636U, UINT32_MAX 70 | }; 71 | 72 | static const uint32_t __objc_sel_set_buckets[SIZE] = { // primes 73 | 5, 11, 23, 41, 67, 113, 199, 317, 521, 839, 1361, 2207, 3571, 5779, 74 | 9349, 15121, 24473, 39607, 64081, 103681, 167759, 271429, 439199, 75 | 710641, 1149857, 1860503, 3010349, 4870843, 7881193, 12752029, 20633237, 76 | 33385273, 54018521, 87403763, 141422317, 228826121, 370248451, 599074561, 77 | 969323023, 1568397599, 2537720629U, 4106118251U 78 | }; 79 | 80 | #endif 81 | 82 | struct __objc_sel_set { 83 | uint32_t _count; /* number of slots used */ 84 | uint32_t _capacity; /* maximum number of used slots */ 85 | uint32_t _bucketsNum; /* number of slots */ 86 | SEL *_buckets; /* can be NULL if not allocated yet */ 87 | }; 88 | 89 | struct __objc_sel_set_finds { 90 | SEL match; 91 | uint32_t nomatch; 92 | }; 93 | 94 | // candidate may not be 0; match is 0 if not present 95 | static struct __objc_sel_set_finds __objc_sel_set_findBuckets(struct __objc_sel_set *sset, SEL candidate) { 96 | struct __objc_sel_set_finds ret = {0, 0xffffffff}; 97 | uint32_t probe = CONSTRAIN((uint32_t)_objc_strhash((const char *)candidate), sset->_bucketsNum); 98 | for (;;) { 99 | SEL currentSel = sset->_buckets[probe]; 100 | if (!currentSel) { 101 | ret.nomatch = probe; 102 | return ret; 103 | } else if (!ret.match && 0 == strcmp((const char *)currentSel, (const char *)candidate)) { 104 | ret.match = currentSel; 105 | } 106 | probe++; 107 | if (sset->_bucketsNum <= probe) { 108 | probe -= sset->_bucketsNum; 109 | } 110 | } 111 | } 112 | 113 | // create a set with given starting capacity, will resize as needed 114 | struct __objc_sel_set *__objc_sel_set_create(size_t selrefs) { 115 | uint32_t idx; 116 | 117 | struct __objc_sel_set *sset = (struct __objc_sel_set *) 118 | malloc(sizeof(struct __objc_sel_set)); 119 | if (!sset) _objc_fatal("objc_sel_set failure"); 120 | sset->_count = 0; 121 | 122 | // heuristic to convert executable's selrefs count to table size 123 | #if TARGET_OS_IPHONE 124 | for (idx = 0; __objc_sel_set_capacities[idx] < selrefs; idx++); 125 | if (idx > 0 && selrefs < 1536) idx--; 126 | #else 127 | if (selrefs < 1024) selrefs = 1024; 128 | for (idx = 0; __objc_sel_set_capacities[idx] < selrefs; idx++); 129 | idx++; 130 | #endif 131 | 132 | if (SIZE <= idx) _objc_fatal("objc_sel_set failure"); 133 | sset->_capacity = __objc_sel_set_capacities[idx]; 134 | sset->_bucketsNum = __objc_sel_set_buckets[idx]; 135 | sset->_buckets = (SEL *)calloc(sset->_bucketsNum, sizeof(SEL)); 136 | if (!sset->_buckets) _objc_fatal("objc_sel_set failure"); 137 | return sset; 138 | } 139 | 140 | // returns 0 on failure; candidate may not be 0 141 | SEL __objc_sel_set_get(struct __objc_sel_set *sset, SEL candidate) { 142 | return __objc_sel_set_findBuckets(sset, candidate).match; 143 | } 144 | 145 | // value may not be 0; should not be called unless it is known the value is not in the set 146 | void __objc_sel_set_add(struct __objc_sel_set *sset, SEL value) { 147 | if (sset->_count == sset->_capacity) { 148 | SEL *oldbuckets = sset->_buckets; 149 | uint32_t oldnbuckets = sset->_bucketsNum; 150 | uint32_t idx, capacity = sset->_count + 1; 151 | for (idx = 0; __objc_sel_set_capacities[idx] < capacity; idx++); 152 | if (SIZE <= idx) _objc_fatal("objc_sel_set failure"); 153 | sset->_capacity = __objc_sel_set_capacities[idx]; 154 | sset->_bucketsNum = __objc_sel_set_buckets[idx]; 155 | sset->_buckets = (SEL *) 156 | calloc(sset->_bucketsNum, sizeof(SEL)); 157 | if (!sset->_buckets) _objc_fatal("objc_sel_set failure"); 158 | for (idx = 0; idx < oldnbuckets; idx++) { 159 | SEL currentSel = oldbuckets[idx]; 160 | if (currentSel) { 161 | uint32_t nomatch = __objc_sel_set_findBuckets(sset, currentSel).nomatch; 162 | sset->_buckets[nomatch] = currentSel; 163 | } 164 | } 165 | free(oldbuckets); 166 | } 167 | { 168 | uint32_t nomatch = __objc_sel_set_findBuckets(sset, value).nomatch; 169 | sset->_buckets[nomatch] = value; 170 | sset->_count++; 171 | } 172 | } 173 | 174 | 175 | // !__OBJC2__ 176 | #endif 177 | -------------------------------------------------------------------------------- /runtime/objc-sel-table.s: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #if __LP64__ 5 | # define PTR(x) .quad x 6 | #else 7 | # define PTR(x) .long x 8 | #endif 9 | 10 | .section __TEXT,__objc_opt_ro 11 | .align 3 12 | .private_extern __objc_opt_data 13 | __objc_opt_data: 14 | .long 15 /* table.version */ 15 | .long 0 /* table.flags */ 16 | .long 0 /* table.selopt_offset */ 17 | .long 0 /* table.headeropt_ro_offset */ 18 | .long 0 /* table.clsopt_offset */ 19 | .long 0 /* table.protocolopt_offset */ 20 | .long 0 /* table.headeropt_rw_offset */ 21 | .space PAGE_MAX_SIZE-28 22 | 23 | /* space for selopt, smax/capacity=524288, blen/mask=262143+1 */ 24 | .space 262144 /* mask tab */ 25 | .space 524288 /* checkbytes */ 26 | .space 524288*4 /* offsets */ 27 | 28 | /* space for clsopt, smax/capacity=65536, blen/mask=16383+1 */ 29 | .space 16384 /* mask tab */ 30 | .space 65536 /* checkbytes */ 31 | .space 65536*12 /* offsets to name and class and header_info */ 32 | .space PAGE_MAX_SIZE /* some duplicate classes */ 33 | 34 | /* space for protocolopt, smax/capacity=8192, blen/mask=4095+1 */ 35 | .space 4096 /* mask tab */ 36 | .space 8192 /* checkbytes */ 37 | .space 8192*4 /* offsets */ 38 | 39 | /* space for header_info (RO) structures */ 40 | .space 16384 41 | 42 | .section __DATA,__objc_opt_rw 43 | .align 3 44 | .private_extern __objc_opt_rw_data 45 | __objc_opt_rw_data: 46 | /* space for header_info (RW) structures */ 47 | .space 16384 48 | 49 | /* space for 8192 protocols */ 50 | #if __LP64__ 51 | .space 8192 * 11 * 8 52 | #else 53 | .space 8192 * 11 * 4 54 | #endif 55 | 56 | 57 | /* section of pointers that the shared cache optimizer wants to know about */ 58 | .section __DATA,__objc_opt_ptrs 59 | .align 3 60 | 61 | #if TARGET_OS_OSX && __i386__ 62 | // old ABI 63 | .globl .objc_class_name_Protocol 64 | PTR(.objc_class_name_Protocol) 65 | #else 66 | // new ABI 67 | .globl _OBJC_CLASS_$_Protocol 68 | PTR(_OBJC_CLASS_$_Protocol) 69 | #endif 70 | -------------------------------------------------------------------------------- /runtime/objc-sel.mm: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 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 | #if __OBJC2__ 25 | 26 | #include "objc-private.h" 27 | #include "objc-cache.h" 28 | 29 | #if SUPPORT_PREOPT 30 | static const objc_selopt_t *builtins = NULL; 31 | #endif 32 | 33 | 34 | static size_t SelrefCount = 0; 35 | 36 | static NXMapTable *namedSelectors; 37 | 38 | static SEL search_builtins(const char *key); 39 | 40 | 41 | /*********************************************************************** 42 | * sel_init 43 | * Initialize selector tables and register selectors used internally. 44 | **********************************************************************/ 45 | void sel_init(size_t selrefCount) 46 | { 47 | // save this value for later 48 | SelrefCount = selrefCount; 49 | 50 | #if SUPPORT_PREOPT 51 | builtins = preoptimizedSelectors(); 52 | 53 | if (PrintPreopt && builtins) { 54 | uint32_t occupied = builtins->occupied; 55 | uint32_t capacity = builtins->capacity; 56 | 57 | _objc_inform("PREOPTIMIZATION: using selopt at %p", builtins); 58 | _objc_inform("PREOPTIMIZATION: %u selectors", occupied); 59 | _objc_inform("PREOPTIMIZATION: %u/%u (%u%%) hash table occupancy", 60 | occupied, capacity, 61 | (unsigned)(occupied/(double)capacity*100)); 62 | } 63 | #endif 64 | 65 | // Register selectors used by libobjc 66 | 67 | #define s(x) SEL_##x = sel_registerNameNoLock(#x, NO) 68 | #define t(x,y) SEL_##y = sel_registerNameNoLock(#x, NO) 69 | 70 | sel_lock(); 71 | 72 | s(load); 73 | s(initialize); 74 | t(resolveInstanceMethod:, resolveInstanceMethod); 75 | t(resolveClassMethod:, resolveClassMethod); 76 | t(.cxx_construct, cxx_construct); 77 | t(.cxx_destruct, cxx_destruct); 78 | s(retain); 79 | s(release); 80 | s(autorelease); 81 | s(retainCount); 82 | s(alloc); 83 | t(allocWithZone:, allocWithZone); 84 | s(dealloc); 85 | s(copy); 86 | s(new); 87 | t(forwardInvocation:, forwardInvocation); 88 | t(_tryRetain, tryRetain); 89 | t(_isDeallocating, isDeallocating); 90 | s(retainWeakReference); 91 | s(allowsWeakReference); 92 | 93 | sel_unlock(); 94 | 95 | #undef s 96 | #undef t 97 | } 98 | 99 | 100 | static SEL sel_alloc(const char *name, bool copy) 101 | { 102 | selLock.assertWriting(); 103 | return (SEL)(copy ? strdupIfMutable(name) : name); 104 | } 105 | 106 | 107 | const char *sel_getName(SEL sel) 108 | { 109 | if (!sel) return ""; 110 | return (const char *)(const void*)sel; 111 | } 112 | 113 | 114 | BOOL sel_isMapped(SEL sel) 115 | { 116 | if (!sel) return NO; 117 | 118 | const char *name = (const char *)(void *)sel; 119 | 120 | if (sel == search_builtins(name)) return YES; 121 | 122 | rwlock_reader_t lock(selLock); 123 | if (namedSelectors) { 124 | return (sel == (SEL)NXMapGet(namedSelectors, name)); 125 | } 126 | return false; 127 | } 128 | 129 | 130 | static SEL search_builtins(const char *name) 131 | { 132 | #if SUPPORT_PREOPT 133 | if (builtins) return (SEL)builtins->get(name); 134 | #endif 135 | return nil; 136 | } 137 | 138 | 139 | static SEL __sel_registerName(const char *name, int lock, int copy) 140 | { 141 | SEL result = 0; 142 | 143 | if (lock) selLock.assertUnlocked(); 144 | else selLock.assertWriting(); 145 | 146 | if (!name) return (SEL)0; 147 | 148 | result = search_builtins(name); 149 | if (result) return result; 150 | 151 | if (lock) selLock.read(); 152 | if (namedSelectors) { 153 | result = (SEL)NXMapGet(namedSelectors, name); 154 | } 155 | if (lock) selLock.unlockRead(); 156 | if (result) return result; 157 | 158 | // No match. Insert. 159 | 160 | if (lock) selLock.write(); 161 | 162 | if (!namedSelectors) { 163 | namedSelectors = NXCreateMapTable(NXStrValueMapPrototype, 164 | (unsigned)SelrefCount); 165 | } 166 | if (lock) { 167 | // Rescan in case it was added while we dropped the lock 168 | result = (SEL)NXMapGet(namedSelectors, name); 169 | } 170 | if (!result) { 171 | result = sel_alloc(name, copy); 172 | // fixme choose a better container (hash not map for starters) 173 | NXMapInsert(namedSelectors, sel_getName(result), result); 174 | } 175 | 176 | if (lock) selLock.unlockWrite(); 177 | return result; 178 | } 179 | 180 | 181 | SEL sel_registerName(const char *name) { 182 | return __sel_registerName(name, 1, 1); // YES lock, YES copy 183 | } 184 | 185 | SEL sel_registerNameNoLock(const char *name, bool copy) { 186 | return __sel_registerName(name, 0, copy); // NO lock, maybe copy 187 | } 188 | 189 | void sel_lock(void) 190 | { 191 | selLock.write(); 192 | } 193 | 194 | void sel_unlock(void) 195 | { 196 | selLock.unlockWrite(); 197 | } 198 | 199 | 200 | // 2001/1/24 201 | // the majority of uses of this function (which used to return NULL if not found) 202 | // did not check for NULL, so, in fact, never return NULL 203 | // 204 | SEL sel_getUid(const char *name) { 205 | return __sel_registerName(name, 2, 1); // YES lock, YES copy 206 | } 207 | 208 | 209 | BOOL sel_isEqual(SEL lhs, SEL rhs) 210 | { 211 | return bool(lhs == rhs); 212 | } 213 | 214 | 215 | #endif 216 | -------------------------------------------------------------------------------- /runtime/objc-sync.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2002, 2006 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 | #ifndef __OBJC_SNYC_H_ 25 | #define __OBJC_SNYC_H_ 26 | 27 | #include 28 | 29 | 30 | /** 31 | * Begin synchronizing on 'obj'. 32 | * Allocates recursive pthread_mutex associated with 'obj' if needed. 33 | * 34 | * @param obj The object to begin synchronizing on. 35 | * 36 | * @return OBJC_SYNC_SUCCESS once lock is acquired. 37 | */ 38 | OBJC_EXPORT int objc_sync_enter(id obj) 39 | OBJC_AVAILABLE(10.3, 2.0, 9.0, 1.0); 40 | 41 | /** 42 | * End synchronizing on 'obj'. 43 | * 44 | * @param obj The objet to end synchronizing on. 45 | * 46 | * @return OBJC_SYNC_SUCCESS or OBJC_SYNC_NOT_OWNING_THREAD_ERROR 47 | */ 48 | OBJC_EXPORT int objc_sync_exit(id obj) 49 | OBJC_AVAILABLE(10.3, 2.0, 9.0, 1.0); 50 | 51 | // The wait/notify functions have never worked correctly and no longer exist. 52 | OBJC_EXPORT int objc_sync_wait(id obj, long long milliSecondsMaxWait) 53 | UNAVAILABLE_ATTRIBUTE; 54 | OBJC_EXPORT int objc_sync_notify(id obj) 55 | UNAVAILABLE_ATTRIBUTE; 56 | OBJC_EXPORT int objc_sync_notifyAll(id obj) 57 | UNAVAILABLE_ATTRIBUTE; 58 | 59 | enum { 60 | OBJC_SYNC_SUCCESS = 0, 61 | OBJC_SYNC_NOT_OWNING_THREAD_ERROR = -1, 62 | OBJC_SYNC_TIMED_OUT = -2, 63 | OBJC_SYNC_NOT_INITIALIZED = -3 64 | }; 65 | 66 | 67 | #endif // __OBJC_SNYC_H_ 68 | -------------------------------------------------------------------------------- /runtime/objc-weak.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2010-2011 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 | #ifndef _OBJC_WEAK_H_ 25 | #define _OBJC_WEAK_H_ 26 | 27 | #include 28 | #include "objc-config.h" 29 | 30 | __BEGIN_DECLS 31 | 32 | /* 33 | The weak table is a hash table governed by a single spin lock. 34 | An allocated blob of memory, most often an object, but under GC any such 35 | allocation, may have its address stored in a __weak marked storage location 36 | through use of compiler generated write-barriers or hand coded uses of the 37 | register weak primitive. Associated with the registration can be a callback 38 | block for the case when one of the allocated chunks of memory is reclaimed. 39 | The table is hashed on the address of the allocated memory. When __weak 40 | marked memory changes its reference, we count on the fact that we can still 41 | see its previous reference. 42 | 43 | So, in the hash table, indexed by the weakly referenced item, is a list of 44 | all locations where this address is currently being stored. 45 | 46 | For ARC, we also keep track of whether an arbitrary object is being 47 | deallocated by briefly placing it in the table just prior to invoking 48 | dealloc, and removing it via objc_clear_deallocating just prior to memory 49 | reclamation. 50 | 51 | */ 52 | 53 | // The address of a __weak variable. 54 | // These pointers are stored disguised so memory analysis tools 55 | // don't see lots of interior pointers from the weak table into objects. 56 | typedef DisguisedPtr weak_referrer_t; 57 | 58 | #if __LP64__ 59 | #define PTR_MINUS_2 62 60 | #else 61 | #define PTR_MINUS_2 30 62 | #endif 63 | 64 | /** 65 | * The internal structure stored in the weak references table. 66 | * It maintains and stores 67 | * a hash set of weak references pointing to an object. 68 | * If out_of_line_ness != REFERRERS_OUT_OF_LINE then the set 69 | * is instead a small inline array. 70 | */ 71 | #define WEAK_INLINE_COUNT 4 72 | 73 | // out_of_line_ness field overlaps with the low two bits of inline_referrers[1]. 74 | // inline_referrers[1] is a DisguisedPtr of a pointer-aligned address. 75 | // The low two bits of a pointer-aligned DisguisedPtr will always be 0b00 76 | // (disguised nil or 0x80..00) or 0b11 (any other address). 77 | // Therefore out_of_line_ness == 0b10 is used to mark the out-of-line state. 78 | #define REFERRERS_OUT_OF_LINE 2 79 | 80 | struct weak_entry_t { 81 | DisguisedPtr referent; 82 | union { 83 | struct { 84 | weak_referrer_t *referrers; 85 | uintptr_t out_of_line_ness : 2; 86 | uintptr_t num_refs : PTR_MINUS_2; 87 | uintptr_t mask; 88 | uintptr_t max_hash_displacement; 89 | }; 90 | struct { 91 | // out_of_line_ness field is low bits of inline_referrers[1] 92 | weak_referrer_t inline_referrers[WEAK_INLINE_COUNT]; 93 | }; 94 | }; 95 | 96 | bool out_of_line() { 97 | return (out_of_line_ness == REFERRERS_OUT_OF_LINE); 98 | } 99 | 100 | weak_entry_t& operator=(const weak_entry_t& other) { 101 | memcpy(this, &other, sizeof(other)); 102 | return *this; 103 | } 104 | 105 | weak_entry_t(objc_object *newReferent, objc_object **newReferrer) 106 | : referent(newReferent) 107 | { 108 | inline_referrers[0] = newReferrer; 109 | for (int i = 1; i < WEAK_INLINE_COUNT; i++) { 110 | inline_referrers[i] = nil; 111 | } 112 | } 113 | }; 114 | 115 | /** 116 | * The global weak references table. Stores object ids as keys, 117 | * and weak_entry_t structs as their values. 118 | */ 119 | struct weak_table_t { 120 | weak_entry_t *weak_entries; 121 | size_t num_entries; 122 | uintptr_t mask; 123 | uintptr_t max_hash_displacement; 124 | }; 125 | 126 | /// Adds an (object, weak pointer) pair to the weak table. 127 | id weak_register_no_lock(weak_table_t *weak_table, id referent, 128 | id *referrer, bool crashIfDeallocating); 129 | 130 | /// Removes an (object, weak pointer) pair from the weak table. 131 | void weak_unregister_no_lock(weak_table_t *weak_table, id referent, id *referrer); 132 | 133 | #if DEBUG 134 | /// Returns true if an object is weakly referenced somewhere. 135 | bool weak_is_registered_no_lock(weak_table_t *weak_table, id referent); 136 | #endif 137 | 138 | /// Called on object destruction. Sets all remaining weak pointers to nil. 139 | void weak_clear_no_lock(weak_table_t *weak_table, id referent); 140 | 141 | __END_DECLS 142 | 143 | #endif /* _OBJC_WEAK_H_ */ 144 | -------------------------------------------------------------------------------- /runtime/objc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999-2007 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 | * objc.h 25 | * Copyright 1988-1996, NeXT Software, Inc. 26 | */ 27 | 28 | #ifndef _OBJC_OBJC_H_ 29 | #define _OBJC_OBJC_H_ 30 | 31 | #include // for __DARWIN_NULL 32 | #include 33 | #include 34 | #include 35 | 36 | #if !OBJC_TYPES_DEFINED 37 | /// An opaque type that represents an Objective-C class. 38 | typedef struct objc_class *Class; 39 | 40 | /// Represents an instance of a class. 41 | struct objc_object { 42 | Class isa OBJC_ISA_AVAILABILITY; 43 | }; 44 | 45 | /// A pointer to an instance of a class. 46 | typedef struct objc_object *id; 47 | #endif 48 | 49 | /// An opaque type that represents a method selector. 50 | typedef struct objc_selector *SEL; 51 | 52 | /// A pointer to the function of a method implementation. 53 | #if !OBJC_OLD_DISPATCH_PROTOTYPES 54 | typedef void (*IMP)(void /* id, SEL, ... */ ); 55 | #else 56 | typedef id (*IMP)(id, SEL, ...); 57 | #endif 58 | 59 | #define OBJC_BOOL_DEFINED 60 | 61 | /// Type to represent a boolean value. 62 | #if (TARGET_OS_IPHONE && __LP64__) || TARGET_OS_WATCH 63 | #define OBJC_BOOL_IS_BOOL 1 64 | typedef bool BOOL; 65 | #else 66 | #define OBJC_BOOL_IS_CHAR 1 67 | typedef signed char BOOL; 68 | // BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 69 | // even if -funsigned-char is used. 70 | #endif 71 | 72 | #if __has_feature(objc_bool) 73 | #define YES __objc_yes 74 | #define NO __objc_no 75 | #else 76 | #define YES ((BOOL)1) 77 | #define NO ((BOOL)0) 78 | #endif 79 | 80 | #ifndef Nil 81 | # if __has_feature(cxx_nullptr) 82 | # define Nil nullptr 83 | # else 84 | # define Nil __DARWIN_NULL 85 | # endif 86 | #endif 87 | 88 | #ifndef nil 89 | # if __has_feature(cxx_nullptr) 90 | # define nil nullptr 91 | # else 92 | # define nil __DARWIN_NULL 93 | # endif 94 | #endif 95 | 96 | #ifndef __strong 97 | # if !__has_feature(objc_arc) 98 | # define __strong /* empty */ 99 | # endif 100 | #endif 101 | 102 | #ifndef __unsafe_unretained 103 | # if !__has_feature(objc_arc) 104 | # define __unsafe_unretained /* empty */ 105 | # endif 106 | #endif 107 | 108 | #ifndef __autoreleasing 109 | # if !__has_feature(objc_arc) 110 | # define __autoreleasing /* empty */ 111 | # endif 112 | #endif 113 | 114 | 115 | /** 116 | * Returns the name of the method specified by a given selector. 117 | * 118 | * @param sel A pointer of type \c SEL. Pass the selector whose name you wish to determine. 119 | * 120 | * @return A C string indicating the name of the selector. 121 | */ 122 | OBJC_EXPORT const char *sel_getName(SEL sel) 123 | OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); 124 | 125 | /** 126 | * Registers a method with the Objective-C runtime system, maps the method 127 | * name to a selector, and returns the selector value. 128 | * 129 | * @param str A pointer to a C string. Pass the name of the method you wish to register. 130 | * 131 | * @return A pointer of type SEL specifying the selector for the named method. 132 | * 133 | * @note You must register a method name with the Objective-C runtime system to obtain the 134 | * method’s selector before you can add the method to a class definition. If the method name 135 | * has already been registered, this function simply returns the selector. 136 | */ 137 | OBJC_EXPORT SEL sel_registerName(const char *str) 138 | OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); 139 | 140 | /** 141 | * Returns the class name of a given object. 142 | * 143 | * @param obj An Objective-C object. 144 | * 145 | * @return The name of the class of which \e obj is an instance. 146 | */ 147 | OBJC_EXPORT const char *object_getClassName(id obj) 148 | OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); 149 | 150 | /** 151 | * Returns a pointer to any extra bytes allocated with an instance given object. 152 | * 153 | * @param obj An Objective-C object. 154 | * 155 | * @return A pointer to any extra bytes allocated with \e obj. If \e obj was 156 | * not allocated with any extra bytes, then dereferencing the returned pointer is undefined. 157 | * 158 | * @note This function returns a pointer to any extra bytes allocated with the instance 159 | * (as specified by \c class_createInstance with extraBytes>0). This memory follows the 160 | * object's ordinary ivars, but may not be adjacent to the last ivar. 161 | * @note The returned pointer is guaranteed to be pointer-size aligned, even if the area following 162 | * the object's last ivar is less aligned than that. Alignment greater than pointer-size is never 163 | * guaranteed, even if the area following the object's last ivar is more aligned than that. 164 | * @note In a garbage-collected environment, the memory is scanned conservatively. 165 | */ 166 | OBJC_EXPORT void *object_getIndexedIvars(id obj) 167 | OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); 168 | 169 | /** 170 | * Identifies a selector as being valid or invalid. 171 | * 172 | * @param sel The selector you want to identify. 173 | * 174 | * @return YES if selector is valid and has a function implementation, NO otherwise. 175 | * 176 | * @warning On some platforms, an invalid reference (to invalid memory addresses) can cause 177 | * a crash. 178 | */ 179 | OBJC_EXPORT BOOL sel_isMapped(SEL sel) 180 | OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); 181 | 182 | /** 183 | * Registers a method name with the Objective-C runtime system. 184 | * 185 | * @param str A pointer to a C string. Pass the name of the method you wish to register. 186 | * 187 | * @return A pointer of type SEL specifying the selector for the named method. 188 | * 189 | * @note The implementation of this method is identical to the implementation of \c sel_registerName. 190 | * @note Prior to OS X version 10.0, this method tried to find the selector mapped to the given name 191 | * and returned \c NULL if the selector was not found. This was changed for safety, because it was 192 | * observed that many of the callers of this function did not check the return value for \c NULL. 193 | */ 194 | OBJC_EXPORT SEL sel_getUid(const char *str) 195 | OBJC_AVAILABLE(10.0, 2.0, 9.0, 1.0); 196 | 197 | typedef const void* objc_objectptr_t; 198 | 199 | 200 | // Obsolete ARC conversions. 201 | 202 | OBJC_EXPORT id objc_retainedObject(objc_objectptr_t obj) 203 | OBJC_UNAVAILABLE("use CFBridgingRelease() or a (__bridge_transfer id) cast instead"); 204 | OBJC_EXPORT id objc_unretainedObject(objc_objectptr_t obj) 205 | OBJC_UNAVAILABLE("use a (__bridge id) cast instead"); 206 | OBJC_EXPORT objc_objectptr_t objc_unretainedPointer(id obj) 207 | OBJC_UNAVAILABLE("use a __bridge cast instead"); 208 | 209 | 210 | #if !__OBJC2__ 211 | 212 | // The following declarations are provided here for source compatibility. 213 | 214 | #if defined(__LP64__) 215 | typedef long arith_t; 216 | typedef unsigned long uarith_t; 217 | # define ARITH_SHIFT 32 218 | #else 219 | typedef int arith_t; 220 | typedef unsigned uarith_t; 221 | # define ARITH_SHIFT 16 222 | #endif 223 | 224 | typedef char *STR; 225 | 226 | #define ISSELECTOR(sel) sel_isMapped(sel) 227 | #define SELNAME(sel) sel_getName(sel) 228 | #define SELUID(str) sel_getUid(str) 229 | #define NAMEOF(obj) object_getClassName(obj) 230 | #define IV(obj) object_getIndexedIvars(obj) 231 | 232 | #endif 233 | 234 | #endif /* _OBJC_OBJC_H_ */ 235 | -------------------------------------------------------------------------------- /runtime/objcrt.c: -------------------------------------------------------------------------------- 1 | #define WIN32_LEAN_AND_MEAN 2 | #include 3 | #include 4 | #include 5 | #include "objcrt.h" 6 | 7 | // Boundary symbols for metadata sections 8 | 9 | #pragma section(".objc_module_info$A",long,read,write) 10 | #pragma data_seg(".objc_module_info$A") 11 | static uintptr_t __objc_modStart = 0; 12 | #pragma section(".objc_module_info$C",long,read,write) 13 | #pragma data_seg(".objc_module_info$C") 14 | static uintptr_t __objc_modEnd = 0; 15 | 16 | #pragma section(".objc_protocol$A",long,read,write) 17 | #pragma data_seg(".objc_protocol$A") 18 | static uintptr_t __objc_protoStart = 0; 19 | #pragma section(".objc_protocol$C",long,read,write) 20 | #pragma data_seg(".objc_protocol$C") 21 | static uintptr_t __objc_protoEnd = 0; 22 | 23 | #pragma section(".objc_image_info$A",long,read,write) 24 | #pragma data_seg(".objc_image_info$A") 25 | static uintptr_t __objc_iiStart = 0; 26 | #pragma section(".objc_image_info$C",long,read,write) 27 | #pragma data_seg(".objc_image_info$C") 28 | static uintptr_t __objc_iiEnd = 0; 29 | 30 | #pragma section(".objc_message_refs$A",long,read,write) 31 | #pragma data_seg(".objc_message_refs$A") 32 | static uintptr_t __objc_selrefsStart = 0; 33 | #pragma section(".objc_message_refs$C",long,read,write) 34 | #pragma data_seg(".objc_message_refs$C") 35 | static uintptr_t __objc_selrefsEnd = 0; 36 | 37 | #pragma section(".objc_class_refs$A",long,read,write) 38 | #pragma data_seg(".objc_class_refs$A") 39 | static uintptr_t __objc_clsrefsStart = 0; 40 | #pragma section(".objc_class_refs$C",long,read,write) 41 | #pragma data_seg(".objc_class_refs$C") 42 | static uintptr_t __objc_clsrefsEnd = 0; 43 | 44 | #pragma data_seg() 45 | 46 | // Merge all metadata into .data 47 | // fixme order these by usage? 48 | #pragma comment(linker, "/MERGE:.objc_module_info=.data") 49 | #pragma comment(linker, "/MERGE:.objc_protocol=.data") 50 | #pragma comment(linker, "/MERGE:.objc_image_info=.data") 51 | #pragma comment(linker, "/MERGE:.objc_message_refs=.data") 52 | #pragma comment(linker, "/MERGE:.objc_class_refs=.data") 53 | 54 | 55 | // Image initializers 56 | 57 | static void *__hinfo = NULL; // cookie from runtime 58 | extern IMAGE_DOS_HEADER __ImageBase; // this image's header 59 | 60 | static int __objc_init(void) 61 | { 62 | objc_sections sections = { 63 | 5, 64 | &__objc_modStart, &__objc_modEnd, 65 | &__objc_protoStart, &__objc_protoEnd, 66 | &__objc_iiStart, &__objc_iiEnd, 67 | &__objc_selrefsStart, &__objc_selrefsEnd, 68 | &__objc_clsrefsStart, &__objc_clsrefsEnd, 69 | }; 70 | __hinfo = _objc_init_image((HMODULE)&__ImageBase, §ions); 71 | return 0; 72 | } 73 | 74 | static void __objc_unload(void) 75 | { 76 | _objc_unload_image((HMODULE)&__ImageBase, __hinfo); 77 | } 78 | 79 | static int __objc_load(void) 80 | { 81 | _objc_load_image((HMODULE)&__ImageBase, __hinfo); 82 | return 0; 83 | } 84 | 85 | // run _objc_init_image ASAP 86 | #pragma section(".CRT$XIAA",long,read,write) 87 | #pragma data_seg(".CRT$XIAA") 88 | static void *__objc_init_fn = &__objc_init; 89 | 90 | // run _objc_load_image (+load methods) after all other initializers; 91 | // otherwise constant NSStrings are not initialized yet 92 | #pragma section(".CRT$XCUO",long,read,write) 93 | #pragma data_seg(".CRT$XCUO") 94 | static void *__objc_load_fn = &__objc_load; 95 | 96 | // _objc_unload_image is called by atexit(), not by an image terminator 97 | 98 | #pragma data_seg() 99 | -------------------------------------------------------------------------------- /runtime/objcrt.h: -------------------------------------------------------------------------------- 1 | #ifndef _OBJC_RT_H_ 2 | #define _OBJC_RT_H_ 3 | 4 | #include 5 | 6 | 7 | typedef struct { 8 | int count; // number of pointer pairs that follow 9 | void *modStart; 10 | void *modEnd; 11 | void *protoStart; 12 | void *protoEnd; 13 | void *iiStart; 14 | void *iiEnd; 15 | void *selrefsStart; 16 | void *selrefsEnd; 17 | void *clsrefsStart; 18 | void *clsrefsEnd; 19 | } objc_sections; 20 | 21 | OBJC_EXPORT void *_objc_init_image(HMODULE image, const objc_sections *sects); 22 | OBJC_EXPORT void _objc_load_image(HMODULE image, void *hinfo); 23 | OBJC_EXPORT void _objc_unload_image(HMODULE image, void *hinfo); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /unexported_symbols: -------------------------------------------------------------------------------- 1 | .objc_class_name___IncompleteProtocol 2 | __Znam 3 | __ZnamRKSt9nothrow_t 4 | __Znwm 5 | __ZnwmRKSt9nothrow_t 6 | __ZdaPv 7 | __ZdaPvRKSt9nothrow_t 8 | __ZdlPv 9 | __ZdlPvRKSt9nothrow_t 10 | __ZTISt9bad_alloc 11 | __ZTISt9exception 12 | __ZTISt11logic_error 13 | __ZTISt12length_error 14 | __ZTSSt9bad_alloc 15 | __ZTSSt9exception 16 | __ZTSSt11logic_error 17 | __ZTSSt12length_error 18 | -------------------------------------------------------------------------------- /version.bat: -------------------------------------------------------------------------------- 1 | :: version.bat 2 | :: Writes version numbers from B&I into version.h for use by version.rc. 3 | 4 | @ECHO OFF 5 | 6 | :: Set default values for environment variables if not set by B&I 7 | IF "%OBJROOT%"=="" SET OBJROOT=. 8 | IF "%RC_PROJECTSOURCEVERSION%"=="" SET RC_PROJECTSOURCEVERSION=0.0 9 | IF "%RC_PROJECTBUILDVERSION%"=="" SET RC_PROJECTBUILDVERSION=0 10 | 11 | :: Get version numbers from environment variables 12 | SET major=1 13 | SET patch=0 14 | FOR /F "tokens=1* eol= delims=." %%i IN ("%RC_PROJECTSOURCEVERSION%") DO ( 15 | SET minor=%%i 16 | IF NOT "%%j"=="" SET patch=%%j 17 | ) 18 | SET build=%RC_PROJECTBUILDVERSION% 19 | 20 | ECHO version %major% . %minor% . %patch% . %build% 21 | 22 | :: Write version.h 23 | ECHO // This file is automatically generated by version.bat. > "%OBJROOT%\version.h" 24 | ECHO // DO NOT EDIT >> "%OBJROOT%\version.h" 25 | ECHO #define major %major% >> "%OBJROOT%\version.h" 26 | ECHO #define minor %minor% >> "%OBJROOT%\version.h" 27 | ECHO #define patch %patch% >> "%OBJROOT%\version.h" 28 | ECHO #define build %build% >> "%OBJROOT%\version.h" 29 | ECHO #define string "%major%,%minor%,%patch%,%build%" >> "%OBJROOT%\version.h" 30 | -------------------------------------------------------------------------------- /version.rc: -------------------------------------------------------------------------------- 1 | #include "Winver.h" 2 | 3 | // built by version.bat; sets variables major, minor, patch, build, string 4 | #include "version.h" 5 | 6 | VS_VERSION_INFO VERSIONINFO 7 | FILEVERSION major,minor,patch,build 8 | PRODUCTVERSION major,minor,patch,build 9 | FILEFLAGSMASK 0x17L 10 | #ifdef _DEBUG 11 | FILEFLAGS VS_FF_DEBUG 12 | #else 13 | FILEFLAGS 0x0L 14 | #endif 15 | FILEOS VOS_NT_WINDOWS32 16 | FILETYPE VFT_DLL 17 | FILESUBTYPE VFT2_UNKNOWN 18 | BEGIN 19 | BLOCK "StringFileInfo" 20 | BEGIN 21 | BLOCK "040904b0" 22 | BEGIN 23 | VALUE "CompanyName", "Apple Inc." 24 | VALUE "FileDescription", "Objective-C Runtime Library" 25 | VALUE "FileVersion", string 26 | VALUE "ProductVersion", string 27 | VALUE "ProductName", "objc4" 28 | VALUE "InternalName", "objc4" 29 | VALUE "LegalCopyright", "Copyright (C) 2007-2009, Apple Inc." 30 | VALUE "OriginalFilename", "objc.dll" 31 | END 32 | END 33 | BLOCK "VarFileInfo" 34 | BEGIN 35 | VALUE "Translation", 0x409, 1200 36 | END 37 | END 38 | 39 | --------------------------------------------------------------------------------