objc-class.mm 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262
  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-class.m
  25. * Copyright 1988-1997, Apple Computer, Inc.
  26. * Author: s. naroff
  27. **********************************************************************/
  28. /***********************************************************************
  29. * Lazy method list arrays and method list locking (2004-10-19)
  30. *
  31. * cls->methodLists may be in one of three forms:
  32. * 1. nil: The class has no methods.
  33. * 2. non-nil, with CLS_NO_METHOD_ARRAY set: cls->methodLists points
  34. * to a single method list, which is the class's only method list.
  35. * 3. non-nil, with CLS_NO_METHOD_ARRAY clear: cls->methodLists points to
  36. * an array of method list pointers. The end of the array's block
  37. * is set to -1. If the actual number of method lists is smaller
  38. * than that, the rest of the array is nil.
  39. *
  40. * Attaching categories and adding and removing classes may change
  41. * the form of the class list. In addition, individual method lists
  42. * may be reallocated when fixed up.
  43. *
  44. * Classes are initially read as #1 or #2. If a category is attached
  45. * or other methods added, the class is changed to #3. Once in form #3,
  46. * the class is never downgraded to #1 or #2, even if methods are removed.
  47. * Classes added with objc_addClass are initially either #1 or #3.
  48. *
  49. * Accessing and manipulating a class's method lists are synchronized,
  50. * to prevent races when one thread restructures the list. However,
  51. * if the class is not yet in use (i.e. not in class_hash), then the
  52. * thread loading the class may access its method lists without locking.
  53. *
  54. * The following functions acquire methodListLock:
  55. * class_getInstanceMethod
  56. * class_getClassMethod
  57. * class_nextMethodList
  58. * class_addMethods
  59. * class_removeMethods
  60. * class_respondsToMethod
  61. * _class_lookupMethodAndLoadCache
  62. * lookupMethodInClassAndLoadCache
  63. * _objc_add_category_flush_caches
  64. *
  65. * The following functions don't acquire methodListLock because they
  66. * only access method lists during class load and unload:
  67. * _objc_register_category
  68. * _resolve_categories_for_class (calls _objc_add_category)
  69. * add_class_to_loadable_list
  70. * _objc_addClass
  71. * _objc_remove_classes_in_image
  72. *
  73. * The following functions use method lists without holding methodListLock.
  74. * The caller must either hold methodListLock, or be loading the class.
  75. * _getMethod (called by class_getInstanceMethod, class_getClassMethod,
  76. * and class_respondsToMethod)
  77. * _findMethodInClass (called by _class_lookupMethodAndLoadCache,
  78. * lookupMethodInClassAndLoadCache, _getMethod)
  79. * _findMethodInList (called by _findMethodInClass)
  80. * nextMethodList (called by _findMethodInClass and class_nextMethodList
  81. * fixupSelectorsInMethodList (called by nextMethodList)
  82. * _objc_add_category (called by _objc_add_category_flush_caches,
  83. * resolve_categories_for_class and _objc_register_category)
  84. * _objc_insertMethods (called by class_addMethods and _objc_add_category)
  85. * _objc_removeMethods (called by class_removeMethods)
  86. * _objcTweakMethodListPointerForClass (called by _objc_insertMethods)
  87. * get_base_method_list (called by add_class_to_loadable_list)
  88. * lookupNamedMethodInMethodList (called by add_class_to_loadable_list)
  89. ***********************************************************************/
  90. /***********************************************************************
  91. * Thread-safety of class info bits (2004-10-19)
  92. *
  93. * Some class info bits are used to store mutable runtime state.
  94. * Modifications of the info bits at particular times need to be
  95. * synchronized to prevent races.
  96. *
  97. * Three thread-safe modification functions are provided:
  98. * cls->setInfo() // atomically sets some bits
  99. * cls->clearInfo() // atomically clears some bits
  100. * cls->changeInfo() // atomically sets some bits and clears others
  101. * These replace CLS_SETINFO() for the multithreaded cases.
  102. *
  103. * Three modification windows are defined:
  104. * - compile time
  105. * - class construction or image load (before +load) in one thread
  106. * - multi-threaded messaging and method caches
  107. *
  108. * Info bit modification at compile time and class construction do not
  109. * need to be locked, because only one thread is manipulating the class.
  110. * Info bit modification during messaging needs to be locked, because
  111. * there may be other threads simultaneously messaging or otherwise
  112. * manipulating the class.
  113. *
  114. * Modification windows for each flag:
  115. *
  116. * CLS_CLASS: compile-time and class load
  117. * CLS_META: compile-time and class load
  118. * CLS_INITIALIZED: +initialize
  119. * CLS_POSING: messaging
  120. * CLS_MAPPED: compile-time
  121. * CLS_FLUSH_CACHE: class load and messaging
  122. * CLS_GROW_CACHE: messaging
  123. * CLS_NEED_BIND: unused
  124. * CLS_METHOD_ARRAY: unused
  125. * CLS_JAVA_HYBRID: JavaBridge only
  126. * CLS_JAVA_CLASS: JavaBridge only
  127. * CLS_INITIALIZING: messaging
  128. * CLS_FROM_BUNDLE: class load
  129. * CLS_HAS_CXX_STRUCTORS: compile-time and class load
  130. * CLS_NO_METHOD_ARRAY: class load and messaging
  131. * CLS_HAS_LOAD_METHOD: class load
  132. *
  133. * CLS_INITIALIZED and CLS_INITIALIZING have additional thread-safety
  134. * constraints to support thread-safe +initialize. See "Thread safety
  135. * during class initialization" for details.
  136. *
  137. * CLS_JAVA_HYBRID and CLS_JAVA_CLASS are set immediately after JavaBridge
  138. * calls objc_addClass(). The JavaBridge does not use an atomic update,
  139. * but the modification counts as "class construction" unless some other
  140. * thread quickly finds the class via the class list. This race is
  141. * small and unlikely in well-behaved code.
  142. *
  143. * Most info bits that may be modified during messaging are also never
  144. * read without a lock. There is no general read lock for the info bits.
  145. * CLS_INITIALIZED: classInitLock
  146. * CLS_FLUSH_CACHE: cacheUpdateLock
  147. * CLS_GROW_CACHE: cacheUpdateLock
  148. * CLS_NO_METHOD_ARRAY: methodListLock
  149. * CLS_INITIALIZING: classInitLock
  150. ***********************************************************************/
  151. /***********************************************************************
  152. * Imports.
  153. **********************************************************************/
  154. #include "objc-private.h"
  155. #include "objc-abi.h"
  156. #include <objc/message.h>
  157. /***********************************************************************
  158. * Information about multi-thread support:
  159. *
  160. * Since we do not lock many operations which walk the superclass, method
  161. * and ivar chains, these chains must remain intact once a class is published
  162. * by inserting it into the class hashtable. All modifications must be
  163. * atomic so that someone walking these chains will always geta valid
  164. * result.
  165. ***********************************************************************/
  166. /***********************************************************************
  167. * object_getClass.
  168. * Locking: None. If you add locking, tell gdb (rdar://7516456).
  169. **********************************************************************/
  170. Class object_getClass(id obj)
  171. {
  172. if (obj) return obj->getIsa();
  173. else return Nil;
  174. }
  175. /***********************************************************************
  176. * object_setClass.
  177. **********************************************************************/
  178. Class object_setClass(id obj, Class cls)
  179. {
  180. if (!obj) return nil;
  181. // Prevent a deadlock between the weak reference machinery
  182. // and the +initialize machinery by ensuring that no
  183. // weakly-referenced object has an un-+initialized isa.
  184. // Unresolved future classes are not so protected.
  185. if (!cls->isFuture() && !cls->isInitialized()) {
  186. _class_initialize(_class_getNonMetaClass(cls, nil));
  187. }
  188. return obj->changeIsa(cls);
  189. }
  190. /***********************************************************************
  191. * object_isClass.
  192. **********************************************************************/
  193. BOOL object_isClass(id obj)
  194. {
  195. if (!obj) return NO;
  196. return obj->isClass();
  197. }
  198. /***********************************************************************
  199. * object_getClassName.
  200. **********************************************************************/
  201. const char *object_getClassName(id obj)
  202. {
  203. return class_getName(obj ? obj->getIsa() : nil);
  204. }
  205. /***********************************************************************
  206. * object_getMethodImplementation.
  207. **********************************************************************/
  208. IMP object_getMethodImplementation(id obj, SEL name)
  209. {
  210. Class cls = (obj ? obj->getIsa() : nil);
  211. return class_getMethodImplementation(cls, name);
  212. }
  213. /***********************************************************************
  214. * object_getMethodImplementation_stret.
  215. **********************************************************************/
  216. #if SUPPORT_STRET
  217. IMP object_getMethodImplementation_stret(id obj, SEL name)
  218. {
  219. Class cls = (obj ? obj->getIsa() : nil);
  220. return class_getMethodImplementation_stret(cls, name);
  221. }
  222. #endif
  223. static bool isScanned(ptrdiff_t ivar_offset, const uint8_t *layout)
  224. {
  225. if (!layout) return NO;
  226. ptrdiff_t index = 0, ivar_index = ivar_offset / sizeof(void*);
  227. uint8_t byte;
  228. while ((byte = *layout++)) {
  229. unsigned skips = (byte >> 4);
  230. unsigned scans = (byte & 0x0F);
  231. index += skips;
  232. if (index > ivar_index) return NO;
  233. index += scans;
  234. if (index > ivar_index) return YES;
  235. }
  236. return NO;
  237. }
  238. /***********************************************************************
  239. * _class_lookUpIvar
  240. * Given an object and an ivar in it, look up some data about that ivar:
  241. * - its offset
  242. * - its memory management behavior
  243. * The ivar is assumed to be word-aligned and of of object type.
  244. **********************************************************************/
  245. static void
  246. _class_lookUpIvar(Class cls, Ivar ivar, ptrdiff_t& ivarOffset,
  247. objc_ivar_memory_management_t& memoryManagement)
  248. {
  249. ivarOffset = ivar_getOffset(ivar);
  250. // Look for ARC variables and ARC-style weak.
  251. // Preflight the hasAutomaticIvars check
  252. // because _class_getClassForIvar() may need to take locks.
  253. bool hasAutomaticIvars = NO;
  254. for (Class c = cls; c; c = c->superclass) {
  255. if (c->hasAutomaticIvars()) {
  256. hasAutomaticIvars = YES;
  257. break;
  258. }
  259. }
  260. if (hasAutomaticIvars) {
  261. Class ivarCls = _class_getClassForIvar(cls, ivar);
  262. if (ivarCls->hasAutomaticIvars()) {
  263. // ARC layout bitmaps encode the class's own ivars only.
  264. // Use alignedInstanceStart() because unaligned bytes at the start
  265. // of this class's ivars are not represented in the layout bitmap.
  266. ptrdiff_t localOffset =
  267. ivarOffset - ivarCls->alignedInstanceStart();
  268. if (isScanned(localOffset, class_getIvarLayout(ivarCls))) {
  269. memoryManagement = objc_ivar_memoryStrong;
  270. return;
  271. }
  272. if (isScanned(localOffset, class_getWeakIvarLayout(ivarCls))) {
  273. memoryManagement = objc_ivar_memoryWeak;
  274. return;
  275. }
  276. // Unretained is only for true ARC classes.
  277. if (ivarCls->isARC()) {
  278. memoryManagement = objc_ivar_memoryUnretained;
  279. return;
  280. }
  281. }
  282. }
  283. memoryManagement = objc_ivar_memoryUnknown;
  284. }
  285. /***********************************************************************
  286. * _class_getIvarMemoryManagement
  287. * SPI for KVO and others to decide what memory management to use
  288. * when setting instance variables directly.
  289. **********************************************************************/
  290. objc_ivar_memory_management_t
  291. _class_getIvarMemoryManagement(Class cls, Ivar ivar)
  292. {
  293. ptrdiff_t offset;
  294. objc_ivar_memory_management_t memoryManagement;
  295. _class_lookUpIvar(cls, ivar, offset, memoryManagement);
  296. return memoryManagement;
  297. }
  298. static ALWAYS_INLINE
  299. void _object_setIvar(id obj, Ivar ivar, id value, bool assumeStrong)
  300. {
  301. if (!obj || !ivar || obj->isTaggedPointer()) return;
  302. ptrdiff_t offset;
  303. objc_ivar_memory_management_t memoryManagement;
  304. _class_lookUpIvar(obj->ISA(), ivar, offset, memoryManagement);
  305. if (memoryManagement == objc_ivar_memoryUnknown) {
  306. if (assumeStrong) memoryManagement = objc_ivar_memoryStrong;
  307. else memoryManagement = objc_ivar_memoryUnretained;
  308. }
  309. id *location = (id *)((char *)obj + offset);
  310. switch (memoryManagement) {
  311. case objc_ivar_memoryWeak: objc_storeWeak(location, value); break;
  312. case objc_ivar_memoryStrong: objc_storeStrong(location, value); break;
  313. case objc_ivar_memoryUnretained: *location = value; break;
  314. case objc_ivar_memoryUnknown: _objc_fatal("impossible");
  315. }
  316. }
  317. void object_setIvar(id obj, Ivar ivar, id value)
  318. {
  319. return _object_setIvar(obj, ivar, value, false /*not strong default*/);
  320. }
  321. void object_setIvarWithStrongDefault(id obj, Ivar ivar, id value)
  322. {
  323. return _object_setIvar(obj, ivar, value, true /*strong default*/);
  324. }
  325. id object_getIvar(id obj, Ivar ivar)
  326. {
  327. if (!obj || !ivar || obj->isTaggedPointer()) return nil;
  328. ptrdiff_t offset;
  329. objc_ivar_memory_management_t memoryManagement;
  330. _class_lookUpIvar(obj->ISA(), ivar, offset, memoryManagement);
  331. id *location = (id *)((char *)obj + offset);
  332. if (memoryManagement == objc_ivar_memoryWeak) {
  333. return objc_loadWeak(location);
  334. } else {
  335. return *location;
  336. }
  337. }
  338. static ALWAYS_INLINE
  339. Ivar _object_setInstanceVariable(id obj, const char *name, void *value,
  340. bool assumeStrong)
  341. {
  342. Ivar ivar = nil;
  343. if (obj && name && !obj->isTaggedPointer()) {
  344. if ((ivar = _class_getVariable(obj->ISA(), name))) {
  345. _object_setIvar(obj, ivar, (id)value, assumeStrong);
  346. }
  347. }
  348. return ivar;
  349. }
  350. Ivar object_setInstanceVariable(id obj, const char *name, void *value)
  351. {
  352. return _object_setInstanceVariable(obj, name, value, false);
  353. }
  354. Ivar object_setInstanceVariableWithStrongDefault(id obj, const char *name,
  355. void *value)
  356. {
  357. return _object_setInstanceVariable(obj, name, value, true);
  358. }
  359. Ivar object_getInstanceVariable(id obj, const char *name, void **value)
  360. {
  361. if (obj && name && !obj->isTaggedPointer()) {
  362. Ivar ivar;
  363. if ((ivar = class_getInstanceVariable(obj->ISA(), name))) {
  364. if (value) *value = (void *)object_getIvar(obj, ivar);
  365. return ivar;
  366. }
  367. }
  368. if (value) *value = nil;
  369. return nil;
  370. }
  371. /***********************************************************************
  372. * object_cxxDestructFromClass.
  373. * Call C++ destructors on obj, starting with cls's
  374. * dtor method (if any) followed by superclasses' dtors (if any),
  375. * stopping at cls's dtor (if any).
  376. * Uses methodListLock and cacheUpdateLock. The caller must hold neither.
  377. **********************************************************************/
  378. static void object_cxxDestructFromClass(id obj, Class cls)
  379. {
  380. void (*dtor)(id);
  381. // Call cls's dtor first, then superclasses's dtors.
  382. for ( ; cls; cls = cls->superclass) {
  383. if (!cls->hasCxxDtor()) return;
  384. dtor = (void(*)(id))
  385. lookupMethodInClassAndLoadCache(cls, SEL_cxx_destruct);
  386. if (dtor != (void(*)(id))_objc_msgForward_impcache) {
  387. if (PrintCxxCtors) {
  388. _objc_inform("CXX: calling C++ destructors for class %s",
  389. cls->nameForLogging());
  390. }
  391. (*dtor)(obj);
  392. }
  393. }
  394. }
  395. /***********************************************************************
  396. * object_cxxDestruct.
  397. * Call C++ destructors on obj, if any.
  398. * Uses methodListLock and cacheUpdateLock. The caller must hold neither.
  399. **********************************************************************/
  400. void object_cxxDestruct(id obj)
  401. {
  402. if (!obj) return;
  403. if (obj->isTaggedPointer()) return;
  404. object_cxxDestructFromClass(obj, obj->ISA());
  405. }
  406. /***********************************************************************
  407. * object_cxxConstructFromClass.
  408. * Recursively call C++ constructors on obj, starting with base class's
  409. * ctor method (if any) followed by subclasses' ctors (if any), stopping
  410. * at cls's ctor (if any).
  411. * Does not check cls->hasCxxCtor(). The caller should preflight that.
  412. * Returns self if construction succeeded.
  413. * Returns nil if some constructor threw an exception. The exception is
  414. * caught and discarded. Any partial construction is destructed.
  415. * Uses methodListLock and cacheUpdateLock. The caller must hold neither.
  416. *
  417. * .cxx_construct returns id. This really means:
  418. * return self: construction succeeded
  419. * return nil: construction failed because a C++ constructor threw an exception
  420. **********************************************************************/
  421. id
  422. object_cxxConstructFromClass(id obj, Class cls)
  423. {
  424. assert(cls->hasCxxCtor()); // required for performance, not correctness
  425. id (*ctor)(id);
  426. Class supercls;
  427. supercls = cls->superclass;
  428. // Call superclasses' ctors first, if any.
  429. if (supercls && supercls->hasCxxCtor()) {
  430. bool ok = object_cxxConstructFromClass(obj, supercls);
  431. if (!ok) return nil; // some superclass's ctor failed - give up
  432. }
  433. // Find this class's ctor, if any.
  434. ctor = (id(*)(id))lookupMethodInClassAndLoadCache(cls, SEL_cxx_construct);
  435. if (ctor == (id(*)(id))_objc_msgForward_impcache) return obj; // no ctor - ok
  436. // Call this class's ctor.
  437. if (PrintCxxCtors) {
  438. _objc_inform("CXX: calling C++ constructors for class %s",
  439. cls->nameForLogging());
  440. }
  441. if ((*ctor)(obj)) return obj; // ctor called and succeeded - ok
  442. // This class's ctor was called and failed.
  443. // Call superclasses's dtors to clean up.
  444. if (supercls) object_cxxDestructFromClass(obj, supercls);
  445. return nil;
  446. }
  447. /***********************************************************************
  448. * fixupCopiedIvars
  449. * Fix up ARC strong and ARC-style weak variables
  450. * after oldObject was memcpy'd to newObject.
  451. **********************************************************************/
  452. void fixupCopiedIvars(id newObject, id oldObject)
  453. {
  454. for (Class cls = oldObject->ISA(); cls; cls = cls->superclass) {
  455. if (cls->hasAutomaticIvars()) {
  456. // Use alignedInstanceStart() because unaligned bytes at the start
  457. // of this class's ivars are not represented in the layout bitmap.
  458. size_t instanceStart = cls->alignedInstanceStart();
  459. const uint8_t *strongLayout = class_getIvarLayout(cls);
  460. if (strongLayout) {
  461. id *newPtr = (id *)((char*)newObject + instanceStart);
  462. unsigned char byte;
  463. while ((byte = *strongLayout++)) {
  464. unsigned skips = (byte >> 4);
  465. unsigned scans = (byte & 0x0F);
  466. newPtr += skips;
  467. while (scans--) {
  468. // ensure strong references are properly retained.
  469. id value = *newPtr++;
  470. if (value) objc_retain(value);
  471. }
  472. }
  473. }
  474. const uint8_t *weakLayout = class_getWeakIvarLayout(cls);
  475. // fix up weak references if any.
  476. if (weakLayout) {
  477. id *newPtr = (id *)((char*)newObject + instanceStart), *oldPtr = (id *)((char*)oldObject + instanceStart);
  478. unsigned char byte;
  479. while ((byte = *weakLayout++)) {
  480. unsigned skips = (byte >> 4);
  481. unsigned weaks = (byte & 0x0F);
  482. newPtr += skips, oldPtr += skips;
  483. while (weaks--) {
  484. objc_copyWeak(newPtr, oldPtr);
  485. ++newPtr, ++oldPtr;
  486. }
  487. }
  488. }
  489. }
  490. }
  491. }
  492. /***********************************************************************
  493. * _class_resolveClassMethod
  494. * Call +resolveClassMethod, looking for a method to be added to class cls.
  495. * cls should be a metaclass.
  496. * Does not check if the method already exists.
  497. **********************************************************************/
  498. static void _class_resolveClassMethod(Class cls, SEL sel, id inst)
  499. {
  500. assert(cls->isMetaClass());
  501. if (! lookUpImpOrNil(cls, SEL_resolveClassMethod, inst,
  502. NO/*initialize*/, YES/*cache*/, NO/*resolver*/))
  503. {
  504. // Resolver not implemented.
  505. return;
  506. }
  507. BOOL (*msg)(Class, SEL, SEL) = (typeof(msg))objc_msgSend;
  508. bool resolved = msg(_class_getNonMetaClass(cls, inst),
  509. SEL_resolveClassMethod, sel);
  510. // Cache the result (good or bad) so the resolver doesn't fire next time.
  511. // +resolveClassMethod adds to self->ISA() a.k.a. cls
  512. IMP imp = lookUpImpOrNil(cls, sel, inst,
  513. NO/*initialize*/, YES/*cache*/, NO/*resolver*/);
  514. if (resolved && PrintResolving) {
  515. if (imp) {
  516. _objc_inform("RESOLVE: method %c[%s %s] "
  517. "dynamically resolved to %p",
  518. cls->isMetaClass() ? '+' : '-',
  519. cls->nameForLogging(), sel_getName(sel), imp);
  520. }
  521. else {
  522. // Method resolver didn't add anything?
  523. _objc_inform("RESOLVE: +[%s resolveClassMethod:%s] returned YES"
  524. ", but no new implementation of %c[%s %s] was found",
  525. cls->nameForLogging(), sel_getName(sel),
  526. cls->isMetaClass() ? '+' : '-',
  527. cls->nameForLogging(), sel_getName(sel));
  528. }
  529. }
  530. }
  531. /***********************************************************************
  532. * _class_resolveInstanceMethod
  533. * Call +resolveInstanceMethod, looking for a method to be added to class cls.
  534. * cls may be a metaclass or a non-meta class.
  535. * Does not check if the method already exists.
  536. **********************************************************************/
  537. static void _class_resolveInstanceMethod(Class cls, SEL sel, id inst)
  538. {
  539. if (! lookUpImpOrNil(cls->ISA(), SEL_resolveInstanceMethod, cls,
  540. NO/*initialize*/, YES/*cache*/, NO/*resolver*/))
  541. {
  542. // Resolver not implemented.
  543. return;
  544. }
  545. BOOL (*msg)(Class, SEL, SEL) = (typeof(msg))objc_msgSend;
  546. bool resolved = msg(cls, SEL_resolveInstanceMethod, sel);
  547. // Cache the result (good or bad) so the resolver doesn't fire next time.
  548. // +resolveInstanceMethod adds to self a.k.a. cls
  549. IMP imp = lookUpImpOrNil(cls, sel, inst,
  550. NO/*initialize*/, YES/*cache*/, NO/*resolver*/);
  551. if (resolved && PrintResolving) {
  552. if (imp) {
  553. _objc_inform("RESOLVE: method %c[%s %s] "
  554. "dynamically resolved to %p",
  555. cls->isMetaClass() ? '+' : '-',
  556. cls->nameForLogging(), sel_getName(sel), imp);
  557. }
  558. else {
  559. // Method resolver didn't add anything?
  560. _objc_inform("RESOLVE: +[%s resolveInstanceMethod:%s] returned YES"
  561. ", but no new implementation of %c[%s %s] was found",
  562. cls->nameForLogging(), sel_getName(sel),
  563. cls->isMetaClass() ? '+' : '-',
  564. cls->nameForLogging(), sel_getName(sel));
  565. }
  566. }
  567. }
  568. /***********************************************************************
  569. * _class_resolveMethod
  570. * Call +resolveClassMethod or +resolveInstanceMethod.
  571. * Returns nothing; any result would be potentially out-of-date already.
  572. * Does not check if the method already exists.
  573. **********************************************************************/
  574. void _class_resolveMethod(Class cls, SEL sel, id inst)
  575. {
  576. if (! cls->isMetaClass()) {
  577. // try [cls resolveInstanceMethod:sel]
  578. _class_resolveInstanceMethod(cls, sel, inst);
  579. }
  580. else {
  581. // try [nonMetaClass resolveClassMethod:sel]
  582. // and [cls resolveInstanceMethod:sel]
  583. _class_resolveClassMethod(cls, sel, inst);
  584. if (!lookUpImpOrNil(cls, sel, inst,
  585. NO/*initialize*/, YES/*cache*/, NO/*resolver*/))
  586. {
  587. _class_resolveInstanceMethod(cls, sel, inst);
  588. }
  589. }
  590. }
  591. /***********************************************************************
  592. * class_getClassMethod. Return the class method for the specified
  593. * class and selector.
  594. **********************************************************************/
  595. Method class_getClassMethod(Class cls, SEL sel)
  596. {
  597. if (!cls || !sel) return nil;
  598. return class_getInstanceMethod(cls->getMeta(), sel);
  599. }
  600. /***********************************************************************
  601. * class_getInstanceVariable. Return the named instance variable.
  602. **********************************************************************/
  603. Ivar class_getInstanceVariable(Class cls, const char *name)
  604. {
  605. if (!cls || !name) return nil;
  606. return _class_getVariable(cls, name);
  607. }
  608. /***********************************************************************
  609. * class_getClassVariable. Return the named class variable.
  610. **********************************************************************/
  611. Ivar class_getClassVariable(Class cls, const char *name)
  612. {
  613. if (!cls) return nil;
  614. return class_getInstanceVariable(cls->ISA(), name);
  615. }
  616. /***********************************************************************
  617. * gdb_objc_class_changed
  618. * Tell gdb that a class changed. Currently used for OBJC2 ivar layouts only
  619. * Does nothing; gdb sets a breakpoint on it.
  620. **********************************************************************/
  621. BREAKPOINT_FUNCTION(
  622. void gdb_objc_class_changed(Class cls, unsigned long changes, const char *classname)
  623. );
  624. /***********************************************************************
  625. * class_respondsToSelector.
  626. **********************************************************************/
  627. BOOL class_respondsToMethod(Class cls, SEL sel)
  628. {
  629. OBJC_WARN_DEPRECATED;
  630. return class_respondsToSelector(cls, sel);
  631. }
  632. BOOL class_respondsToSelector(Class cls, SEL sel)
  633. {
  634. return class_respondsToSelector_inst(cls, sel, nil);
  635. }
  636. // inst is an instance of cls or a subclass thereof, or nil if none is known.
  637. // Non-nil inst is faster in some cases. See lookUpImpOrForward() for details.
  638. bool class_respondsToSelector_inst(Class cls, SEL sel, id inst)
  639. {
  640. IMP imp;
  641. if (!sel || !cls) return NO;
  642. // Avoids +initialize because it historically did so.
  643. // We're not returning a callable IMP anyway.
  644. imp = lookUpImpOrNil(cls, sel, inst,
  645. NO/*initialize*/, YES/*cache*/, YES/*resolver*/);
  646. return bool(imp);
  647. }
  648. /***********************************************************************
  649. * class_getMethodImplementation.
  650. * Returns the IMP that would be invoked if [obj sel] were sent,
  651. * where obj is an instance of class cls.
  652. **********************************************************************/
  653. IMP class_lookupMethod(Class cls, SEL sel)
  654. {
  655. OBJC_WARN_DEPRECATED;
  656. // No one responds to zero!
  657. if (!sel) {
  658. __objc_error(cls, "invalid selector (null)");
  659. }
  660. return class_getMethodImplementation(cls, sel);
  661. }
  662. IMP class_getMethodImplementation(Class cls, SEL sel)
  663. {
  664. IMP imp;
  665. if (!cls || !sel) return nil;
  666. imp = lookUpImpOrNil(cls, sel, nil,
  667. YES/*initialize*/, YES/*cache*/, YES/*resolver*/);
  668. // Translate forwarding function to C-callable external version
  669. if (!imp) {
  670. return _objc_msgForward;
  671. }
  672. return imp;
  673. }
  674. #if SUPPORT_STRET
  675. IMP class_getMethodImplementation_stret(Class cls, SEL sel)
  676. {
  677. IMP imp = class_getMethodImplementation(cls, sel);
  678. // Translate forwarding function to struct-returning version
  679. if (imp == (IMP)&_objc_msgForward /* not _internal! */) {
  680. return (IMP)&_objc_msgForward_stret;
  681. }
  682. return imp;
  683. }
  684. #endif
  685. /***********************************************************************
  686. * instrumentObjcMessageSends
  687. **********************************************************************/
  688. // Define this everywhere even if it isn't used to simplify fork() safety code.
  689. spinlock_t objcMsgLogLock;
  690. #if !SUPPORT_MESSAGE_LOGGING
  691. void instrumentObjcMessageSends(BOOL flag)
  692. {
  693. }
  694. #else
  695. bool objcMsgLogEnabled = false;
  696. static int objcMsgLogFD = -1;
  697. bool logMessageSend(bool isClassMethod,
  698. const char *objectsClass,
  699. const char *implementingClass,
  700. SEL selector)
  701. {
  702. char buf[ 1024 ];
  703. // Create/open the log file
  704. if (objcMsgLogFD == (-1))
  705. {
  706. snprintf (buf, sizeof(buf), "/tmp/msgSends-%d", (int) getpid ());
  707. objcMsgLogFD = secure_open (buf, O_WRONLY | O_CREAT, geteuid());
  708. if (objcMsgLogFD < 0) {
  709. // no log file - disable logging
  710. objcMsgLogEnabled = false;
  711. objcMsgLogFD = -1;
  712. return true;
  713. }
  714. }
  715. // Make the log entry
  716. snprintf(buf, sizeof(buf), "%c %s %s %s\n",
  717. isClassMethod ? '+' : '-',
  718. objectsClass,
  719. implementingClass,
  720. sel_getName(selector));
  721. objcMsgLogLock.lock();
  722. write (objcMsgLogFD, buf, strlen(buf));
  723. objcMsgLogLock.unlock();
  724. // Tell caller to not cache the method
  725. return false;
  726. }
  727. void instrumentObjcMessageSends(BOOL flag)
  728. {
  729. bool enable = flag;
  730. // Shortcut NOP
  731. if (objcMsgLogEnabled == enable)
  732. return;
  733. // If enabling, flush all method caches so we get some traces
  734. if (enable)
  735. _objc_flush_caches(Nil);
  736. // Sync our log file
  737. if (objcMsgLogFD != -1)
  738. fsync (objcMsgLogFD);
  739. objcMsgLogEnabled = enable;
  740. }
  741. // SUPPORT_MESSAGE_LOGGING
  742. #endif
  743. Class _calloc_class(size_t size)
  744. {
  745. return (Class) calloc(1, size);
  746. }
  747. Class class_getSuperclass(Class cls)
  748. {
  749. if (!cls) return nil;
  750. return cls->superclass;
  751. }
  752. BOOL class_isMetaClass(Class cls)
  753. {
  754. if (!cls) return NO;
  755. return cls->isMetaClass();
  756. }
  757. size_t class_getInstanceSize(Class cls)
  758. {
  759. if (!cls) return 0;
  760. return cls->alignedInstanceSize();
  761. }
  762. /***********************************************************************
  763. * method_getNumberOfArguments.
  764. **********************************************************************/
  765. unsigned int method_getNumberOfArguments(Method m)
  766. {
  767. if (!m) return 0;
  768. return encoding_getNumberOfArguments(method_getTypeEncoding(m));
  769. }
  770. void method_getReturnType(Method m, char *dst, size_t dst_len)
  771. {
  772. encoding_getReturnType(method_getTypeEncoding(m), dst, dst_len);
  773. }
  774. char * method_copyReturnType(Method m)
  775. {
  776. return encoding_copyReturnType(method_getTypeEncoding(m));
  777. }
  778. void method_getArgumentType(Method m, unsigned int index,
  779. char *dst, size_t dst_len)
  780. {
  781. encoding_getArgumentType(method_getTypeEncoding(m),
  782. index, dst, dst_len);
  783. }
  784. char * method_copyArgumentType(Method m, unsigned int index)
  785. {
  786. return encoding_copyArgumentType(method_getTypeEncoding(m), index);
  787. }
  788. /***********************************************************************
  789. * _objc_constructOrFree
  790. * Call C++ constructors, and free() if they fail.
  791. * bytes->isa must already be set.
  792. * cls must have cxx constructors.
  793. * Returns the object, or nil.
  794. **********************************************************************/
  795. id
  796. _objc_constructOrFree(id bytes, Class cls)
  797. {
  798. assert(cls->hasCxxCtor()); // for performance, not correctness
  799. id obj = object_cxxConstructFromClass(bytes, cls);
  800. if (!obj) free(bytes);
  801. return obj;
  802. }
  803. /***********************************************************************
  804. * _class_createInstancesFromZone
  805. * Batch-allocating version of _class_createInstanceFromZone.
  806. * Attempts to allocate num_requested objects, each with extraBytes.
  807. * Returns the number of allocated objects (possibly zero), with
  808. * the allocated pointers in *results.
  809. **********************************************************************/
  810. unsigned
  811. _class_createInstancesFromZone(Class cls, size_t extraBytes, void *zone,
  812. id *results, unsigned num_requested)
  813. {
  814. unsigned num_allocated;
  815. if (!cls) return 0;
  816. size_t size = cls->instanceSize(extraBytes);
  817. num_allocated =
  818. malloc_zone_batch_malloc((malloc_zone_t *)(zone ? zone : malloc_default_zone()),
  819. size, (void**)results, num_requested);
  820. for (unsigned i = 0; i < num_allocated; i++) {
  821. bzero(results[i], size);
  822. }
  823. // Construct each object, and delete any that fail construction.
  824. unsigned shift = 0;
  825. bool ctor = cls->hasCxxCtor();
  826. for (unsigned i = 0; i < num_allocated; i++) {
  827. id obj = results[i];
  828. obj->initIsa(cls); // fixme allow nonpointer
  829. if (ctor) obj = _objc_constructOrFree(obj, cls);
  830. if (obj) {
  831. results[i-shift] = obj;
  832. } else {
  833. shift++;
  834. }
  835. }
  836. return num_allocated - shift;
  837. }
  838. /***********************************************************************
  839. * inform_duplicate. Complain about duplicate class implementations.
  840. **********************************************************************/
  841. void
  842. inform_duplicate(const char *name, Class oldCls, Class newCls)
  843. {
  844. #if TARGET_OS_WIN32
  845. (DebugDuplicateClasses ? _objc_fatal : _objc_inform)
  846. ("Class %s is implemented in two different images.", name);
  847. #else
  848. const header_info *oldHeader = _headerForClass(oldCls);
  849. const header_info *newHeader = _headerForClass(newCls);
  850. const char *oldName = oldHeader ? oldHeader->fname() : "??";
  851. const char *newName = newHeader ? newHeader->fname() : "??";
  852. (DebugDuplicateClasses ? _objc_fatal : _objc_inform)
  853. ("Class %s is implemented in both %s (%p) and %s (%p). "
  854. "One of the two will be used. Which one is undefined.",
  855. name, oldName, oldCls, newName, newCls);
  856. #endif
  857. }
  858. const char *
  859. copyPropertyAttributeString(const objc_property_attribute_t *attrs,
  860. unsigned int count)
  861. {
  862. char *result;
  863. unsigned int i;
  864. if (count == 0) return strdup("");
  865. #if DEBUG
  866. // debug build: sanitize input
  867. for (i = 0; i < count; i++) {
  868. assert(attrs[i].name);
  869. assert(strlen(attrs[i].name) > 0);
  870. assert(! strchr(attrs[i].name, ','));
  871. assert(! strchr(attrs[i].name, '"'));
  872. if (attrs[i].value) assert(! strchr(attrs[i].value, ','));
  873. }
  874. #endif
  875. size_t len = 0;
  876. for (i = 0; i < count; i++) {
  877. if (attrs[i].value) {
  878. size_t namelen = strlen(attrs[i].name);
  879. if (namelen > 1) namelen += 2; // long names get quoted
  880. len += namelen + strlen(attrs[i].value) + 1;
  881. }
  882. }
  883. result = (char *)malloc(len + 1);
  884. char *s = result;
  885. for (i = 0; i < count; i++) {
  886. if (attrs[i].value) {
  887. size_t namelen = strlen(attrs[i].name);
  888. if (namelen > 1) {
  889. s += sprintf(s, "\"%s\"%s,", attrs[i].name, attrs[i].value);
  890. } else {
  891. s += sprintf(s, "%s%s,", attrs[i].name, attrs[i].value);
  892. }
  893. }
  894. }
  895. // remove trailing ',' if any
  896. if (s > result) s[-1] = '\0';
  897. return result;
  898. }
  899. /*
  900. Property attribute string format:
  901. - Comma-separated name-value pairs.
  902. - Name and value may not contain ,
  903. - Name may not contain "
  904. - Value may be empty
  905. - Name is single char, value follows
  906. - OR Name is double-quoted string of 2+ chars, value follows
  907. Grammar:
  908. attribute-string: \0
  909. attribute-string: name-value-pair (',' name-value-pair)*
  910. name-value-pair: unquoted-name optional-value
  911. name-value-pair: quoted-name optional-value
  912. unquoted-name: [^",]
  913. quoted-name: '"' [^",]{2,} '"'
  914. optional-value: [^,]*
  915. */
  916. static unsigned int
  917. iteratePropertyAttributes(const char *attrs,
  918. bool (*fn)(unsigned int index,
  919. void *ctx1, void *ctx2,
  920. const char *name, size_t nlen,
  921. const char *value, size_t vlen),
  922. void *ctx1, void *ctx2)
  923. {
  924. if (!attrs) return 0;
  925. #if DEBUG
  926. const char *attrsend = attrs + strlen(attrs);
  927. #endif
  928. unsigned int attrcount = 0;
  929. while (*attrs) {
  930. // Find the next comma-separated attribute
  931. const char *start = attrs;
  932. const char *end = start + strcspn(attrs, ",");
  933. // Move attrs past this attribute and the comma (if any)
  934. attrs = *end ? end+1 : end;
  935. assert(attrs <= attrsend);
  936. assert(start <= attrsend);
  937. assert(end <= attrsend);
  938. // Skip empty attribute
  939. if (start == end) continue;
  940. // Process one non-empty comma-free attribute [start,end)
  941. const char *nameStart;
  942. const char *nameEnd;
  943. assert(start < end);
  944. assert(*start);
  945. if (*start != '\"') {
  946. // single-char short name
  947. nameStart = start;
  948. nameEnd = start+1;
  949. start++;
  950. }
  951. else {
  952. // double-quoted long name
  953. nameStart = start+1;
  954. nameEnd = nameStart + strcspn(nameStart, "\",");
  955. start++; // leading quote
  956. start += nameEnd - nameStart; // name
  957. if (*start == '\"') start++; // trailing quote, if any
  958. }
  959. // Process one possibly-empty comma-free attribute value [start,end)
  960. const char *valueStart;
  961. const char *valueEnd;
  962. assert(start <= end);
  963. valueStart = start;
  964. valueEnd = end;
  965. bool more = (*fn)(attrcount, ctx1, ctx2,
  966. nameStart, nameEnd-nameStart,
  967. valueStart, valueEnd-valueStart);
  968. attrcount++;
  969. if (!more) break;
  970. }
  971. return attrcount;
  972. }
  973. static bool
  974. copyOneAttribute(unsigned int index, void *ctxa, void *ctxs,
  975. const char *name, size_t nlen, const char *value, size_t vlen)
  976. {
  977. objc_property_attribute_t **ap = (objc_property_attribute_t**)ctxa;
  978. char **sp = (char **)ctxs;
  979. objc_property_attribute_t *a = *ap;
  980. char *s = *sp;
  981. a->name = s;
  982. memcpy(s, name, nlen);
  983. s += nlen;
  984. *s++ = '\0';
  985. a->value = s;
  986. memcpy(s, value, vlen);
  987. s += vlen;
  988. *s++ = '\0';
  989. a++;
  990. *ap = a;
  991. *sp = s;
  992. return YES;
  993. }
  994. objc_property_attribute_t *
  995. copyPropertyAttributeList(const char *attrs, unsigned int *outCount)
  996. {
  997. if (!attrs) {
  998. if (outCount) *outCount = 0;
  999. return nil;
  1000. }
  1001. // Result size:
  1002. // number of commas plus 1 for the attributes (upper bound)
  1003. // plus another attribute for the attribute array terminator
  1004. // plus strlen(attrs) for name/value string data (upper bound)
  1005. // plus count*2 for the name/value string terminators (upper bound)
  1006. unsigned int attrcount = 1;
  1007. const char *s;
  1008. for (s = attrs; s && *s; s++) {
  1009. if (*s == ',') attrcount++;
  1010. }
  1011. size_t size =
  1012. attrcount * sizeof(objc_property_attribute_t) +
  1013. sizeof(objc_property_attribute_t) +
  1014. strlen(attrs) +
  1015. attrcount * 2;
  1016. objc_property_attribute_t *result = (objc_property_attribute_t *)
  1017. calloc(size, 1);
  1018. objc_property_attribute_t *ra = result;
  1019. char *rs = (char *)(ra+attrcount+1);
  1020. attrcount = iteratePropertyAttributes(attrs, copyOneAttribute, &ra, &rs);
  1021. assert((uint8_t *)(ra+1) <= (uint8_t *)result+size);
  1022. assert((uint8_t *)rs <= (uint8_t *)result+size);
  1023. if (attrcount == 0) {
  1024. free(result);
  1025. result = nil;
  1026. }
  1027. if (outCount) *outCount = attrcount;
  1028. return result;
  1029. }
  1030. static bool
  1031. findOneAttribute(unsigned int index, void *ctxa, void *ctxs,
  1032. const char *name, size_t nlen, const char *value, size_t vlen)
  1033. {
  1034. const char *query = (char *)ctxa;
  1035. char **resultp = (char **)ctxs;
  1036. if (strlen(query) == nlen && 0 == strncmp(name, query, nlen)) {
  1037. char *result = (char *)calloc(vlen+1, 1);
  1038. memcpy(result, value, vlen);
  1039. result[vlen] = '\0';
  1040. *resultp = result;
  1041. return NO;
  1042. }
  1043. return YES;
  1044. }
  1045. char *copyPropertyAttributeValue(const char *attrs, const char *name)
  1046. {
  1047. char *result = nil;
  1048. iteratePropertyAttributes(attrs, findOneAttribute, (void*)name, &result);
  1049. return result;
  1050. }