From 97f9a02308709ffa74c391c1d70f47c14ea48ff2 Mon Sep 17 00:00:00 2001 From: fredkiefer Date: Sun, 3 Dec 2017 21:55:33 +0100 Subject: [PATCH 1/9] Add new symbolic link method to NSFileManager. --- ChangeLog | 6 ++++++ Headers/Foundation/NSFileManager.h | 8 ++++++++ Source/NSFileManager.m | 22 +++++++++++++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 32438831c..9253c0226 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2017-12-03 Fred Kiefer + + * Headers/Foundation/NSFileManager.h + * Source/NSFileManager.m: Correct setting the delegate. + Add new symbolic link method. + 2017-11-16 Richard Frith-Macdonald * Source/NSArray.m: Fix for bug reported on github by zneak. diff --git a/Headers/Foundation/NSFileManager.h b/Headers/Foundation/NSFileManager.h index 4ccb21701..ce5cda07b 100644 --- a/Headers/Foundation/NSFileManager.h +++ b/Headers/Foundation/NSFileManager.h @@ -302,6 +302,14 @@ typedef NSUInteger NSDirectoryEnumerationOptions; */ - (BOOL) removeItemAtURL: (NSURL*)url error: (NSError**)error; +/** + * Creates a symbolic link at the path + * that point to the destination path.
+ * Returns YES on success, otherwise NO. + */ +- (BOOL) createSymbolicLinkAtPath: (NSString*)path + withDestinationPath: (NSString*)destPath + error: (NSError**)error; #endif /** diff --git a/Source/NSFileManager.m b/Source/NSFileManager.m index 37f8d8ecc..f57014c03 100644 --- a/Source/NSFileManager.m +++ b/Source/NSFileManager.m @@ -361,7 +361,7 @@ static NSStringEncoding defaultEncoding; return _delegate; } -- (void) setDelegate: (NSFileManager *)delegate { +- (void) setDelegate: (id)delegate { _delegate = delegate; } @@ -1586,6 +1586,26 @@ static NSStringEncoding defaultEncoding; return [self removeItemAtPath: [url path] error: error]; } +- (BOOL) createSymbolicLinkAtPath: (NSString*)path + withDestinationPath: (NSString*)destPath + error: (NSError**)error +{ + BOOL result; + + DESTROY(_lastError); + result = [self createSymbolicLinkAtPath: path pathContent: destPath]; + + if (error != NULL) + { + if (NO == result) + { + *error = [self _errorFrom: path to: destPath]; + } + } + + return result; +} + - (BOOL) fileExistsAtPath: (NSString*)path { return [self fileExistsAtPath: path isDirectory: 0]; From 6f206829f8b6dd8e8571ae4f3b907a2792edc23e Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Sat, 2 Dec 2017 11:16:30 +0000 Subject: [PATCH 2/9] Avoid conflicts with runtime header. Don't duplicate definitions from objc/blocks_runtime.h if it exists. --- Headers/GNUstepBase/GSBlocks.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Headers/GNUstepBase/GSBlocks.h b/Headers/GNUstepBase/GSBlocks.h index 6123e9e74..de0045d00 100644 --- a/Headers/GNUstepBase/GSBlocks.h +++ b/Headers/GNUstepBase/GSBlocks.h @@ -107,6 +107,10 @@ typedef retTy(^name)() #endif /* __has_feature(blocks) */ +#if __has_include() +# include +#else + #ifdef __cplusplus extern "C" { #endif @@ -136,5 +140,7 @@ void _Block_release(const void *) __attribute__((weak)); # define Block_release(x) _Block_release((const void *)(x)) #endif +#endif /* __has_include() */ + #endif /* __GSBlocks_h_GNUSTEP_BASE_INCLUDE */ From 98205ac26622d7752931ca74bf5c856efd7bbb84 Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Fri, 8 Dec 2017 17:32:36 +0000 Subject: [PATCH 3/9] Fix a bug in NSMapTable. In the simple constructors, we were using the pointer functions that use pointer equality and a hash derrived from the pointer, rather than -isEqual: and -hash. This led to some subtle and confusingly broken behavior. --- Source/NSMapTable.m | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/NSMapTable.m b/Source/NSMapTable.m index 26e3d93ec..7dd263474 100644 --- a/Source/NSMapTable.m +++ b/Source/NSMapTable.m @@ -100,29 +100,29 @@ static Class concreteClass = 0; + (id) strongToStrongObjectsMapTable { - return [self mapTableWithKeyOptions: NSMapTableObjectPointerPersonality - valueOptions: NSMapTableObjectPointerPersonality]; + return [self mapTableWithKeyOptions: NSPointerFunctionsObjectPersonality + valueOptions: NSPointerFunctionsObjectPersonality]; } + (id) strongToWeakObjectsMapTable { - return [self mapTableWithKeyOptions: NSMapTableObjectPointerPersonality - valueOptions: NSMapTableObjectPointerPersonality | + return [self mapTableWithKeyOptions: NSPointerFunctionsObjectPersonality + valueOptions: NSPointerFunctionsObjectPersonality | NSMapTableWeakMemory]; } + (id) weakToStrongObjectsMapTable { - return [self mapTableWithKeyOptions: NSMapTableObjectPointerPersonality | + return [self mapTableWithKeyOptions: NSPointerFunctionsObjectPersonality | NSMapTableWeakMemory - valueOptions: NSMapTableObjectPointerPersonality]; + valueOptions: NSPointerFunctionsObjectPersonality]; } + (id) weakToWeakObjectsMapTable { - return [self mapTableWithKeyOptions: NSMapTableObjectPointerPersonality | + return [self mapTableWithKeyOptions: NSPointerFunctionsObjectPersonality | NSMapTableWeakMemory - valueOptions: NSMapTableObjectPointerPersonality | + valueOptions: NSPointerFunctionsObjectPersonality | NSMapTableWeakMemory]; } From c3921ee1f7a43f997a2bc1f1d3e6583e2818fb49 Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Wed, 13 Dec 2017 17:14:18 +0000 Subject: [PATCH 4/9] Refactor refcount usage. This makes it easier for the runtime to change how reference counts are stored by removing any refcount manipulation from -base when the runtime provides accessors. This should have no functionality change with existing runtimes, but will let newer runtimes drop in alternative representations easily. --- Source/NSObject.m | 76 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 54 insertions(+), 22 deletions(-) diff --git a/Source/NSObject.m b/Source/NSObject.m index 701af3f4a..d2c3c778d 100644 --- a/Source/NSObject.m +++ b/Source/NSObject.m @@ -444,15 +444,8 @@ struct obj_layout { }; typedef struct obj_layout *obj; -/** - * Examines the extra reference count for the object and, if non-zero - * decrements it, otherwise leaves it unchanged.
- * Returns a flag to say whether the count was zero - * (and hence whether the extra reference count was decremented).
- * This function is used by the [NSObject-release] method. - */ -inline BOOL -NSDecrementExtraRefCountWasZero(id anObject) +__attribute__((weak)) +BOOL objc_release_fast_no_destroy_np(id anObject) { if (double_release_check_enabled) { @@ -483,6 +476,9 @@ NSDecrementExtraRefCountWasZero(id anObject) * have been greater than zero) */ (((obj)anObject)[-1].retained) = 0; +# ifdef OBJC_CAP_ARC + objc_delete_weak_refs(anObject); +# endif return YES; } #else /* GSATOMICREAD */ @@ -491,6 +487,9 @@ NSDecrementExtraRefCountWasZero(id anObject) [theLock lock]; if (((obj)anObject)[-1].retained == 0) { +# ifdef OBJC_CAP_ARC + objc_delete_weak_refs(anObject); +# endif [theLock unlock]; return YES; } @@ -505,6 +504,33 @@ NSDecrementExtraRefCountWasZero(id anObject) return NO; } +__attribute__((weak)) +void objc_release_fast_np(id anObject) +{ + if (objc_release_fast_no_destroy_np(anObject)) + { + [anObject dealloc]; + } +} + +/** + * Examines the extra reference count for the object and, if non-zero + * decrements it, otherwise leaves it unchanged.
+ * Returns a flag to say whether the count was zero + * (and hence whether the extra reference count was decremented).
+ */ +inline BOOL +NSDecrementExtraRefCountWasZero(id anObject) +{ + return objc_release_fast_no_destroy_np(anObject); +} + +__attribute__((weak)) +size_t object_getRetainCount_np(id anObject) +{ + return ((obj)anObject)[-1].retained + 1; +} + /** * Return the extra reference count of anObject (a value in the range * from 0 to the maximum unsigned integer value minus one).
@@ -513,7 +539,7 @@ NSDecrementExtraRefCountWasZero(id anObject) inline NSUInteger NSExtraRefCount(id anObject) { - return ((obj)anObject)[-1].retained; + return object_getRetainCount_np(anObject) - 1; } /** @@ -522,8 +548,8 @@ NSExtraRefCount(id anObject) * would be incremented to too large a value.
* This is used by the [NSObject-retain] method. */ -inline void -NSIncrementExtraRefCount(id anObject) +__attribute__((weak)) +id objc_retain_fast_np(id anObject) { BOOL tooFar = NO; @@ -586,6 +612,19 @@ NSIncrementExtraRefCount(id anObject) @" for %@ - %@", base, anObject]; } } + return anObject; +} + +/** + * Increments the extra reference count for anObject.
+ * The GNUstep version raises an exception if the reference count + * would be incremented to too large a value.
+ * This is used by the [NSObject-retain] method. + */ +inline void +NSIncrementExtraRefCount(id anObject) +{ + objc_retain_fast_np(anObject); } #ifndef NDEBUG @@ -1893,13 +1932,7 @@ static id gs_weak_load(id obj) */ - (oneway void) release { - if (NSDecrementExtraRefCountWasZero(self)) - { -# ifdef OBJC_CAP_ARC - objc_delete_weak_refs(self); -# endif - [self dealloc]; - } + objc_release_fast_np(self); } /** @@ -1958,8 +1991,7 @@ static id gs_weak_load(id obj) */ - (id) retain { - NSIncrementExtraRefCount(self); - return self; + return objc_retain_fast_np(self); } /** @@ -1983,7 +2015,7 @@ static id gs_weak_load(id obj) */ - (NSUInteger) retainCount { - return NSExtraRefCount(self) + 1; + return object_getRetainCount_np(self); } /** From e35eb61dbcbd5e9825da2bbad6ad1f0dd2d85d36 Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Wed, 13 Dec 2017 18:22:08 +0000 Subject: [PATCH 5/9] Make object allocation and deallocation use the runtime. All objects are now created and destroyed by the runtime, so we have clean layering between -base and libobjc. --- Source/NSObject.m | 35 +++++++++++++++++++++++++++++++++++ Tests/base/NSProxy/basic.m | 5 +++++ 2 files changed, 40 insertions(+) diff --git a/Source/NSObject.m b/Source/NSObject.m index d2c3c778d..143a4cc6b 100644 --- a/Source/NSObject.m +++ b/Source/NSObject.m @@ -125,6 +125,7 @@ BOOL NSDeallocateZombies = NO; static Class zombieClass = Nil; static NSMapTable *zombieMap = 0; +#ifndef OBJC_CAP_ARC static void GSMakeZombie(NSObject *o, Class c) { object_setClass(o, zombieClass); @@ -135,6 +136,7 @@ static void GSMakeZombie(NSObject *o, Class c) [allocationLock unlock]; } } +#endif static void GSLogZombie(id o, SEL sel) { @@ -635,6 +637,8 @@ NSIncrementExtraRefCount(id anObject) #define AREM(c, o) #endif + +#ifndef OBJC_CAP_ARC static SEL cxx_construct, cxx_destruct; /** @@ -668,6 +672,7 @@ callCXXConstructors(Class aClass, id anObject) } return constructor; } +#endif /* @@ -681,6 +686,9 @@ callCXXConstructors(Class aClass, id anObject) inline id NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone *zone) { +#ifdef OBJC_CAP_ARC + return class_createInstance(aClass, extraBytes); +#else id new; int size; @@ -713,17 +721,21 @@ NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone *zone) callCXXConstructors(aClass, new); return new; +#endif } inline void NSDeallocateObject(id anObject) { + Class aClass = object_getClass(anObject); if ((anObject != nil) && !class_isMetaClass(aClass)) { +#ifndef OBJC_CAP_ARC obj o = &((obj)anObject)[-1]; NSZone *z = NSZoneFromPointer(o); +#endif /* Call the default finalizer to handle C++ destructors. */ @@ -732,16 +744,37 @@ NSDeallocateObject(id anObject) AREM(aClass, (id)anObject); if (NSZombieEnabled == YES) { +#ifdef OBJC_CAP_ARC + if (0 != zombieMap) + { + [allocationLock lock]; + NSMapInsert(zombieMap, (void*)anObject, (void*)aClass); + [allocationLock unlock]; + } + if (NSDeallocateZombies == YES) + { + object_dispose(anObject); + } + else + { + object_setClass(anObject, zombieClass); + } +#else GSMakeZombie(anObject, aClass); if (NSDeallocateZombies == YES) { NSZoneFree(z, o); } +#endif } else { +#ifdef OBJC_CAP_ARC + object_dispose(anObject); +#else object_setClass((id)anObject, (Class)(void*)0xdeadface); NSZoneFree(z, o); +#endif } } return; @@ -1236,6 +1269,7 @@ static id gs_weak_load(id obj) - (void) finalize { +#ifndef OBJC_CAP_ARC Class destructorClass = Nil; IMP destructor = 0; /* @@ -1290,6 +1324,7 @@ static id gs_weak_load(id obj) } } return; +#endif } /** diff --git a/Tests/base/NSProxy/basic.m b/Tests/base/NSProxy/basic.m index bb21489cf..56aa29f65 100644 --- a/Tests/base/NSProxy/basic.m +++ b/Tests/base/NSProxy/basic.m @@ -1,6 +1,9 @@ #import "ObjectTesting.h" #import #import +#if __has_include( +#include +#endif int main() { @@ -24,8 +27,10 @@ int main() obj1 = [NSProxy allocWithZone:testZone]; PASS(obj1 != nil, "%s has working allocWithZone:",prefix); +#ifndef OBJC_CAP_ARC PASS(NSZoneFromPointer(obj1) == testZone, "%s uses zone for alloc",prefix); PASS([obj1 zone] == testZone, "%s -zone works",prefix); +#endif PASS([obj1 hash] != 0, "%s has working -hash",prefix); PASS([obj1 isEqual:obj1] == YES, "%s has working -isEqual:",prefix); From 7a7b18a0905ca77ffbebd249f9eba43a3b67677d Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Wed, 13 Dec 2017 18:56:32 +0000 Subject: [PATCH 6/9] Fix typo in test. --- Tests/base/NSProxy/basic.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/base/NSProxy/basic.m b/Tests/base/NSProxy/basic.m index 56aa29f65..5a977c73c 100644 --- a/Tests/base/NSProxy/basic.m +++ b/Tests/base/NSProxy/basic.m @@ -1,7 +1,7 @@ #import "ObjectTesting.h" #import #import -#if __has_include( +#if __has_include() #include #endif From d311dbe3d507182b7e3189286280f3f996e21fa9 Mon Sep 17 00:00:00 2001 From: Richard Frith-Macdonald Date: Fri, 15 Dec 2017 14:12:39 +0000 Subject: [PATCH 7/9] Update to latest timezone info --- NSTimeZones/NSTimeZones.tar | Bin 1290240 -> 1290240 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/NSTimeZones/NSTimeZones.tar b/NSTimeZones/NSTimeZones.tar index f711b1a75a76458cc2a13c394142fe5e52fa634e..21fdf638f1e6393e039df3e119e2e7482975e4f6 100644 GIT binary patch delta 33317 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�p!4tqQ&Rm8Dl1q4)T;g$; zp+UI)GIVx+74!we1~IiwO~AtR8TgsY&_fpX(k6TDm!qNi=hm7`0Po}`5%T`aQMy#1 zt+pAYx2SeWdWj*O;ww;ifqTYF1Q zeWs(kt)r!*JKYYm#I2)v?3JkCyy|emdJ7&fM$b)mb+>d*?b4>J4ySZrX*j9gcqLj! zZ6^0>G{6poVRE5N$Jtkd^nzET0zCU_R1*RV_11O+y6(27n%ec5&Xz8G<<%%(<4d|h z_{00IM#J&RtI-1v@+dxhX{ex>$iRfHPp@iOG^eGrxdrHs;#aRh)j0QBln+EiaOhez zvQPk@k#25j)ASO?bFM`r>I8~rcc(krTh?hJGiNXcXA>hdXg3ByOsH~>(Y zk4$M>4$cvY;f~@kg6b!MRi% z#?AWHba!idr7jlhD2T^I&tSv&r#GOX_&;ty2tRxSs`A>$Ep@WF=L@2-P1{8 z(0CJ>J`#bLAdL|f7=%!$YB&hRpk}2zGu@evW#F?BeRL!!fg28w?-v{h!qYaRSw+?1 zapnv&+q#<|V0D1V#zBO6d^7q9aKk8{mg(wDw*WIt-R4lt#4;tlBAr>90g4z{e`5`8 zJ>VN)4~!jSh>=`eqmA)Xp1U;NO^Ar%>R+OvBTUAL=dOaFTos9%v}gk`2XJ%yFVT>3 zU^$k1;s8HWL#AhC3qcsgum2KN%;ldxx1+hGb4gDpI3*_`ew1;~MtNz@NH6c{%n)hf zz!pdhbz4wqe3hX_;AUQWm0-Lyyunb)B-tEF;;n!~OTI_8pnUv?EvRq=&&$kA2Sg;o zi}~=y=@mo)VVrZL{%FIEXdvJSV|oGJrH{n%l{caRP5_RFwM#pBj*QLcF-}{XUY>4m zY3m?dne(twUQ}$9$IuA*XD!J^AU# zRS>kntHuexU@^n}CXtedg~Pq#Z#?8?^bH=f6@3R`I;oECMX>X`@D?=82Gn%kf_n2W zo(jRXt1Vq~L3&+!RgV_2$K&E#(a-{*1n|i>$Ki8sMT3V|!C5%{W?g4b2MGy~6gA+w zbZcjth%6k(i*ALeM&j!IfH9A7qk+r-m+Ik^y~T= z1hSQFD3uElTzjH1-A2MuJ)XA>4H=+)hKJsmoNj6&X+4Q=*oKPX4*XAM#5*bc`)z3R zC?anS)#SEz!h}wt_RA!U{K7ji8t%|O^s^tMpA7@tIt{IDE0^>@bz;y&e`{0X_-*L! z3Xp^``?U0uo^~P{`mFIYhL7Kdetw=w%&c_BvP`DKH_Je33~(&6AzknnrMuIe1UKGz zJ1WL~x1;HkO^mbCZOZ`ROp{D~z~or}ZM~nu^>?6opv5@eaR(}f%FN`Zu?193HU0V> zXfRZAG0@P5a9IQF>*6tBQuO!vnKh)O(&eoGO5)r*q4F!f6M1p;PLyxEU^bp`Cn~`` zcS6jrGo)|<*iC0Q(W|aBHlX8U1H@G{#Tr8wPpuONI2$%#OvLku0(ALf|90dDwqbol z5$HFGL?&!UgEa%sY)2#EVjR9>I~oBODg5j0utNA~JBq`v7%sdET~uYF=e<^^oF4+( z@hx|u3J@r`8GiaMkj>${&_nq0yGcT3luU#0($q@q*0gV9$W){;U}}U7=u^)~ceH7% z4PC0{Z(U_|AdD566+Ws5?B9WcLv;hL?OxZJCjP2BgZVp#$L~Nx@W>rdk}leT&eBA3 z*A5i5)lbH6>_84gNDJ)aog@e0~`>aYRLuuVJ9G} zy9Z5zTXB5tJz89e;XU`D`2-Vo+>5ruMGD_{FZxV~1g&5+gh0IWK2$uFlhkDWj?N|h zIn%H;NHE=P>5eqSX2aU}p>cS`E=Y2@yU++-OA~gXw+8ECxv&!!1g22*Uol*LKPtk5 z??>7Ay!+APBTU58dO(RC%ixJ|hShRIIJp}QnaEkIc@L7SX5#g&nYJbA_AbpAbtMX8 zidCMV^_ZP^`F;Mubz39q_IqS3@sBafd?^y{sh=_smC5;ldD1QKr z`k5dL;Xz%O(u0iMbjOmk9wr&T++YeXeE^oxyBI}7(_p@S2+H{ChY=b=m%TbnEi6_$;NQ-+ zH3nq;!?2j!^e`#}ONJn)-v2P#Z^Pbw=!i#KD%C@R{cIn4G7f}844kURe0tFc4x^7i z@TZp~_UK~?{QPgwg+oY9#8*fW?iW;1xbjhSXM_}4wLM+k;5<-~OwV*SFFHT7mK1qp zjnK~>eDG0JSFH9IWZd}}=-H72Ma6|oof@LrWi1JdtB@wx*L@CgvPz^4h&<^#y9 z0qOUmc-}LRO9>EM#PP~!^!xfSAbCcgiCo}Q&k!Wf=rif}qIkkVRHh*z7kKqy0Ge?S z1+|&zPlX?4MGi!=Hq40q7r>XgEMYxumzqAdLZ=b zzyoE#5N> z6V%7>>K8%UzkU%-(VqY2MF@y6ms;^V)Z~OF5|p~SY-W?@7DQ!2igi$HB3U65__0^f zD17==RN#c?z@d-5iUz3uKcJ87(7<9Iac&z~)xZLiOkVT`x|p=xqWGSpD5McaF7WE3 z8k=!#SbgOv`i(M?r{=t#b>NM}E=&UTA+0#m$zxCuq;|iF{-g-Ps)sO`ffgl?MIXZ( z-a`4K`5757lSzF~8) z*UEm=GW9V$=N&YxMw6wsmTGXtFE)Gunus{xj*I zXijwS&uAT}jqy?s8yJ~I=Ru*M^^0S8!UyM`c&Kl==drP9BmPK}=4ziNIG$4~tg%@Q;Glp{q{Nk_&wHX^5^Jr%^j3Y{pq_XL?x=G+C&fy?+{wQV0JNEw>Q_>ZbojV_i_9 zl1}8g(2`r#Qd7H!cRM%d2XtX-j9a3HD zq=W7*WveZq2C_qI0>$wE-GXzP;&vIFmN2&8we7N!(5L}`vApc;vT}VVOWV1@LrOvw z!+{*_j!aVdS-vv(r(D}ZD#u6aLq+%;c)$S!mE*aiLM7wj9ymOYSKlFH&%!=HKlkz6 zlF;Z7Xn@`$jV{`=z?YC2AflDyUzdgQ@ogocx`EJhVsK_N3Lhy6wT*(c2f1gi(oLda zfiB#@;lZI%4p_&PPf`v4j_#-OJ(w3a^hn<=5e_|nqQFb5GKCO-?y!43^M>48PdV0c?;sIrJiR8zlx zYZ}z@5cJxXufY3CfqHQJa=d*+Xb?V98fqwnw!8*z>)e*(k`xfw0QcZ+dl3_9vl}AS8s@@0|QE({eZP3pXbq1$YOo5n%}8oO-05B@5vzGVHBG_|Z;($cBU>;xe2 wSsdsNtt*5hZU#@}e=rX31INt+J{nJJLJb4d<(op=3dsMfp1AtGq0|2V1<7M)H~;_u delta 33170 zcmdsgd3+RA)@Z7$yOVU%S#CoJVG9Hi+0uJEj-W}{LqbEERRo$OkU&Uc76e=p9Y;hN zClKYj;O;2;`IH&dQioAoe~#m5blhbeR9wdA=b)d@abe`0Q@5(_ty`II-uvGB*jto^Xv* z4wmI^$g+WiLSaBs@8zKKlW|IaZ&CKaDMhQLjv~RZ)zMk*!km6Geyi9|D50ZkVDp`h z%>+9(p+q!d4y7pp6|tGL!E5g&9s;6GY>=d|+(`uaCPKtzh*;1h8YtSS+6RaPISwln z#9@YvLkt;jP{L?UI%wr1>=>ueTc&xk4o+UY#>TV|$R}n=P$^XU$x?eipetrSn$qJ# zuCB8~#6XuUTyFADQu-%1)Vr5Ff9#5bdm6sAYm`j_OxR5ud^YNVGA>4>p57961Lj>4 z=J8N4XfYWGJXp4ML!Patcraojc2L=|({H~Si<_DWH;4H9hu+>^91CWEMd;?iEFc~Z znS*G`d0s%Kc8Nc`f6ASunLkACYyaWXpB}8fv)|Q!2Fu|Tr;$P=>6SxWP&kMVKjxY<-mpl8wjw4W73~HNjW(AsqLzI_-NL_ z{m*`2*U)%4YSN}D{kb=})x+P7Ie6PELp|#I85#X2238&nym`J|GVx%-u5|R~&$58+ z@5pRVgn8c#)%Wb?8j1(wTxFX?x!}zy6HB!-hpLBM{m=X@tY&&M>DbFWrw;SDJy|~Zk^ZB%{Yf3Ic(F* zq7O%eq2Qn)CIKPa;v2)J z)`5*EN`_5J!UlNDP4h{e{mYe2#SjVX?lB?8?iI=;<%}V{p!2t`Y1!vafAfXnQcs@z zAICB>^j|mp?#al4`xzMp3u;msHSqt`U@#g5^_x>e55J{Or58_fXVGB^w|~yc?RV`% zbHvW@5$rJIf2+q7KBnC=Ng>MKRf?JS7>+#=;uJC+Tq`pn66Y$9o=z)Ur>ymrM1tUn zB|ZcNjYiP1=fcpL@c+nO__=iU%S|udzpM9;H@CG<@ZNoN>P?>=r88TVLp>`GkIgve zs(8Vwd#3lEyQ#Qf_0BQ9Yf{m^warRzI$G4XZtjP@^?`5u8YVv5+wdRn^sO)aAY=WX z4)tyL@|ldLLvI%}zj9Z`#(lpn*!1fwGFmRYsbKT&jTx=0dJ5XkTaeLyX1d_Kl})`J zBdZEJ&zRra3ogF&m5iR6j|+g|E;s$M%C(%v+LY2$MwTjpjEua3jAE4FWK1A4>MH6|8C4aj zjAeMRtRmI_<*cx0HFAJH+NS(O1#-3j(WY!udf*z8jDJWrwn#d*NItg60&I~D*di;i zMRs6|EWsApf-SN}Z-G77B8&7E*n};z3jdH@IDQ854F8aC*dp)n5BY~J@(}-!kJutF z@elclE%FpwX zEp>t7Q)tJFnPU}|9^I}KYjE#sg$}=1vd2VX@DS81hoA&xaFP?eOm>2asE{HtCwQei zUf9viF1ed{BF6nK^T~b62DdFxfv4dx*D7)piU{$8g|U4yA`u}NGLTy(ka!}*eHBhy zw6fcscm#RaWwBwugPvGehPh9MNyG)$$JZuLENg)RFgvVr%NQ5KP z=|-XsIfx1h6QL&^%;ibGEo*tsp)yfxPNykPDkUl%@uJdZ6JtCkgjPoOfQ)b~!Xq>z z`!xp$AkK3YXCobzK;kihB-YC@8AP1j=t>43>0oN{SpUpu8P z@dloE!+1e?yhIH9G71(t;MuQd0pOW3U@U443I(Y`g_5~0yJW%Fac(oz=ey)wIU%Rh zDH#OxgJZ<-0nqBe~EiTNhSPv~S4{daxn^l-Y$;A>q;JP_I@A@HNj(W(I zrA_X2t+CfLpm@TaJo-cWk3FtzZAzbOwXI$jf>_PM_e21P5@lL*_kmrJ1VP6G@9T%$BG;! z-$;T6m&8GsOZwLJpSvV9W5OI&_T}*~S9KJ#7Fi(6ITjJBf{ek7oebvMLe-%vEn2E}*#sGj2p;thZq$~Q zk|b?KUM8kh4sv2vnI1)eB(EI=h7-kD*Wh4XOh^(KOp^n~jxsW*#laj1V3wVHQZlsCSn+h_;V~FjvSh@wkxFFs<1& z2xCP3MSS`O!AG zUQjpW+O0DRi*csAe^cf%IAP8m=IP&)Z5P(qtPZ~Opm~4b01+HLBCM4ia}p)^8ccWS zKfXYszED@&C%my3CNyGP_*xnc3bUM~&6%iN->B8Dl2F1~PJqB_A&;XfF*^QxHQ2M_ zACC^Kte>7d=g&6|tg0H5Jok4O4XiFxl51{SGqBe6VKROBg~{{>&nD~FuTIuKb$7CH z_SwnCe|vgh!-R3k4OjhYpxNtAHgDQ7u<@ghlbfoW2U=cs4Q!rVJs7Xuf( zS(Ci*%z=T6wDRP|BY!i{Lkp8VC$1Ujfg&bUZQS&gKYD_6-S_HxB~E|;z1pCYfK?eJ z16w2oTO_|MB9HVI_=GL;N^gN**dovL7WjrO@=kC2k3)M-Mh5Z_ zFCZVWMP6cy{KOV{iY@XLTjVXa$X{%c$9fBV)?45;mdH4>t7y*;YBo7@aws}uN=+!l z%3Yyp5gK|?$2E_*#J z9*J}3uV?LLUiW&nzIrX)<#kV0|Lv8d^pMwmiaKP=T6zqxtU7U&4#{-?oVG0WjG>QY zx}VdbFUfMBt3$t^<*w18L)mZzp?7DyH6@|}MVi7$%5_U51+BFra9UV)$OCNcRLkoN zMix)pcG5$Mpq0fN*>I6tnqJ0Zan2oP;N#pml!z8#KXbP)8EteG`E-C`+ zXO-L!2#?1UHfvhzmS#=yh)}R)3n&flCluHk@KLY!aijZAd)R<^y~#~ot>}RkluXMY zlHokNLocDVJ4i?fvw=>xlv&#tC28JPhvtQau9%Q7l!Xi(a&8FKjb7ONnr~?+Q-)g|Fi|1F zxML7*n}}!%Lw3K6ELfZA3jkR}3+A5=%P_F#hil0k6{&nihJkGu9EKJ0pO@`QNI*5^4>G%96wYoo%78q| zAeg)+!$1yenxm!+bzyzrE%z#W$cX8iMvP1kHi*%{5qXDL%!(CkKb2PYp6o^;gXP&E zZUlkk(=F8^!EQLrDSEj5T*f#qsw(T}xNLy&sNit*V%vxx(aW50ua@`F2$fXTBl+z( z-)m+VSAnO_RT75o_)whS8TlD)7+fF7_Ae#as%{57j0P^XzxgXS3b0fBkI#uj7q-Klc>V z;*p*Xd-#D3e3o&udfaG_%=xHL9AI3X;92J_c2XJ@s*Wh4(WDo0vKQXH{J@Kz^NL@* zHoX7UE^-}aXKF^q;J( zJ<{MAnTHSSx!u2fx~$yu=iQ}&z2Ccs(P2SPr;TRVufZ*q(GzyioUpPbO%clIXLuZW zjxaZ4-f^}^N|$WAv39_&LoGPpBjsMUB(cUL$E%nyOJvHw*fB~%nBB6CK1-c2R#hB> zKN{Lfj~ukamM7K}e^#M~l64+?pW4B+Y7aa9La_F4tFj+GUs+ zBrH}x4CSq!b*@3QFDBUQ{}b9b&O00yu|4*3C+y&vTteny<&j-G?j*z1g8U;Mxp17!L1thYp8@O2iYMkfMd} z@+_A~6Za>fl*a2m; zpT6HSHdDA4)J8nuX_M9=gBHTL^SDT*!yc48K|C&~jKH9W9SjN!dA{z$|8NL7dB`JA z8iK+y{1YB&?II3qDRv${@8qH2crazA`$l85c+n#*@x*wt%vQFwvNt^P^hDgUArx$m zIOq!sH5PP6Gb)JO-2xK@n3(aOflL%|+Nb10*mi4Ks6ZT$>A+7t)jTvD1+?!7Ft zI417~j*IIz7z~sOZT#t8MajH6eYEzz^ViZvN4=wH?K;>1ocf7(G+lJ2x1RRh;w@7u z=;QzJ7HI`%ct26-$)9=`X>jiWWp`;F%K&D0?HK^@n8zkI2R_?@v1k%3?#%Sc_9YgS zcjzu=fjpF0=w#j0Iv6NMcZ8uWOT1uxi@j2@7^;S-%YY=d?S29zmqMD8d_iEup zW4-r3%Sw>n^w1x@P*vFIT_d^dh|T%!^w_c~VbacauG7)m5T~tPImkqX?fQBF>SCGa z;M2GbGKIX8lHf3>XGLVe1taqN}Hf~9-TB4%edI0O?EmUPR#$i|z!Yoww@ zSV+4V&UZR+4hoY|26MnMmbhGf&?_Z?unn1G%QB@$WU2*IHGR}!$0%YgLl^o#o<(Ur zBWnLph;(1(#f!vZ$Dp`&18yNgZ=KDeDsgL zOh;f4ss~KId6|+&hfLUX#ppwUJO1KK;7(DdWc^Tk<$!D^FgjDV{-6*#_3h^4GUZ4l z?m85bf+_NNpt;6Tm-%GdDlj_$aKbFh0Re6+r=`rQV|9hpqFPZlglH5Lt|sDa*UO*YH&t`UF(p%&R}sp zttnHQk%?gjU$fJK8)Y4XX)pI7n=@q(BW@XDF|otZL)cO*Bg5GugTVVzlCE!;K_GkK zu7#P*#j?6Uwa3KO80k{E8vrp!!Wf5(npenNffv9G!!tp4Ng#=YMUn~9CxJku-~+LR zo;?mB>aPmu62hHw@;))nTSLUxWlCWUY}-WD0J$?$+7}fUr%uew9+bO*q|e0F=;pAa z8@@Bh02#=X7Mv6CGK$4FoEJgOE>n6P4d$^NhPmM5ncw7iW~Dp3rqbajGH26N!KFoouL+@bGOYR|I!Lf8<&^@erR z;pirW-H51ev7;J-t!*YUhM8=Y^a7|682sxjOb;*1T4UeeVcY1yVESYjc(1{v$rx&% ztUTZ|O}o|<*3DgxZp3>1uVv;6FCiF%Jf3Bb(XbjM7?Yk8JSBkuR|MT;cswWJ0o_ujQNy%3N(6NJjE%gGi-YNqb z2!AUhoB*mUkEmu#iVH79n5J!XP>^lsEm9+)F~k7^d7Cu`V@h$hq)wofT(=oh#yk5F zQg_zRM7bY900zd%&a>t~(Z4{Vz?B?)y!ecSB% zY=?Wcc{1GI)ZrLQ-}fpebz3B=;=Jl;NMLKWtleQ@0`s;Hi}jZ}da+U|P5D{&&TRYi zJt9#2ZZ>wXN9te@=3e7qN<`Rc8BhxgDcLV|BSjG0S$A)?)0R&BgHgfGNvli!kwhg~3C zYu?S4G7Q)vVg?d?7hia9U)%ptw*AF@a799RTat^fAsx@QzlH>Xn7bmDoPCuoC1;Qt za~(Bir9Rmsi90XZ+JBZ$GEAsNN{r0)*%%py%`KevslI%dR*>)8ZYvSNJ4V8+Y^v`& zMf<+U*C)dWMMReDjrQ3mz_0~h&<-}%sq$Fx9xfN`RG)ng33C%+^AE!$?!ZKRTaP8S zGh|GlY{2!DVLMxf355h#&0uOBFk%LQF!ZG{KA6%k_1UNNz(T>nP4yjDv@cituD7!= z2(wlzey{=8I|hW^92N{?K&#Avp!oF$9jVW^B2rs?QcehS4bJNxpBxm$MMB2MT|PO0 zK$*!xhw15c63Vb6RM<+(`nlCt=28#8^o};~c3*|P90$8FOlvcI=6=VZV)d69(1X4U z;7b~>{9LzQmx`l!RO!-APGT{$N62?&Q#L@#<=GX4+<#}XeC%~ujp zU~z(o8O#Z3q;SwFk*pkbsa#pv)ts~yOOgp7t2AJ;or62g*zs0{5n_DBG815U}# zoNkx4r88%UE!zk~C4ei;&YV#$ZFEmgiv%O?%G#MDdlk-D!yNbKNahGZ%XBIR$i5tB zfx}c31LR(ZV8mBLnT0&;fDt$Evw-w;jy?Ec#4)o77^=`u$s0NLOp^;o0{c_HO zpL!|El{PQyuE=Nxx%uM;CW)NrPSX`THPmAzHPCnF7gH7=fsF=u>XuEW}`MBYH=N=X(W*s08=KIjLtw7^Zd z_Ah2ZOcw$H)5=?OG>$QAf3BQ~OQj~d-~p84eYsL$P}n-8(?QRA4B;NhwI_=Z zl!fe+@#L^fa6K(^W;+~P8Wfx{s^10mw zzzYS!+eiN{sW}8wp`ge3{FQ_VIuRay7|f3jK8FRPWO>1 zewoSQ+Azz=hxqLoIh4~J!FQzJt{_+v<(jA4@W}}{;CR11+Xg@(zA_4@`6X`~=WFb2 zuBlBv!@m_$+b{aHyQcexdX&xDp-TTt_MK9|UoOO1e!G(a7bHw8n72#%CHD*osig%B zwZ$@OgS~C+9--+_ST~auZzfe>9SvKyjyVt+m zzSaSoF*rI*!yoiJT(eLfWH66Of&dR<$=sm)aj6?HIKg8w%AfHshaJ$k#mSboKyQ|x z)O+*b=af9!#OM7{h5mY;Z&Lq(lVcS(ZGXW(nvQ)Les=w+mU(J)s3R}$mJ+?QMJCcqZ@VDAZTd<_Y<15q3R~>|kuixlFZ^WC({Wtvf2#RLP{ldF`DJuof z%L(JP+*_OxID?p3X^nm32;iD=?p5%SSD*OulE07oF$*xS#Z^Y?aZ=N)LbIz|Xm52(5 zqC(x_mw9$000kF30$WPmCzA}pgiDo?bFWN}=$V<=?#r_WO_*v5dpHn=vJ%yUdG?@* z8X}K(SQ-z!vz)3w~ql^0z#x zzylbYx@BPVjjY!YZ8_cluGf)W`BHMtvmv7wcfM?cVQUT4Rsk=_mtBN&O@BzfJ-FMg zhKar;-=@hBQv}z>L_bpQCXR2|m@iDS>Q<=(9Z|~|i^u2JLmKo(kGAvFe8v7n86mBP zeO39g7ZK|Kx?FFJ;`e5v`72z`&jmvw#Ie&A^Z)pB!FylGhBuTe?W}^FSXgjj+?*|g z*s5y!OU!d+PC;Y_d=0;#e{5+%zHN4n>)@ucY05{1#o2WD(tP_X4FJL|h=Ht?LB#K{ z1yoW<10DG`2LyShP@8A&qsyU?;>PEme0y~tP!)K>#C}D-?3ZD~hoL^khLOGbo%YWy zz*}UT9EQl9j&4MfnWp|GUygE7;Vlk^&LJm30@3XKtLO72X9pT@qHGpw2J$8E127zC z#^2*IfBCj6gYvJOlnb&xnJ<4ZTdd@=F-8~IWf+H7oh+z)pvQOa);a2P~kU0ly ztX4O$tA{pyPyl&Eyg=d%2%Kkl(=##cno%IXa3Z=Urku3}lKzH-O$}{@7>AQG+VQB6 z#P{R}6)m)?V1>L?V6BH39<@QH46*_fV_gUaWv%jX@H(-{0i1iIy<92tTHLwD)N5CP ztnE>u_W*x(r;k{9k$lI6PU3~=%2f60Lc1-4ftle- z#HCNh1$4t4&7^;yOn;nDe8j%)mEph*nHpji${ul!XRY%XTJ%iex-926@!{)DTy_|I z{(t@^{@!DSklGw6v}J*i2H4aW_cFg%D8C^o#>9^b?JIOpwy{<>MZp~}l;a04c{8|k ze!%wUPCS!F#@uASOl=jJg{5} zvp=4h_bbZDy&Fj-E!qg7t7RiOQ>~d-M|W=|AI_;-kjk!T?MiplcQx0i%aiGr&5a$t zss(j}U9MO>_*HmA{1=mcLVwFf%L zsqEU*9b^H!HnEe8)vswk=_I!+XTulmvn$qjAYnCatsQM!ngJoCLAo|)5IB9{QQhXi z<=tezyAIJh(oIfLDrvJ`(H}>G!+YR*TqU~gy&Vw!6Ng4(#y?_j(+3>>#%ejC&sPtfO z^XeO0(ya|Xq`*9e7xsl?;iL|Ls+yWx8q2HNTDzKC8$s?ZAnU=e!h=rWS@4l^<1%f! zi1V4hz!woT}0~OEtnoM%>~+(-$RC~^Xk|E{b>&=p9bF)$gb!Dd_mR9E4H_F zG|10S$lxv-8N>LG{Rb6{ZlLCOa|bt!G*rDTMvRM885P9{#7 z51lPuSnaC@FugU-QJi=_zsk6fT$ZBG{hZXTtep*4lIi;9^}x5Ef}r+3UbkYrK)-^5VYtD5>TtEje}*gQ*^@>WN~p) z08ch|)u)>~T7Ajd6#df`$ZyVSZD{OR*WIzrS2H(7pN9LugJB-uIA0@u4Z2~cw}pg>hseZ z(=Cn7t;mV&O}^C96dnHya^4I?yso)*L%JQT3;M+P$x5`Hx1^F1WdV?LisH=}7+fl=t7#`*kZ z5`Z`5awx8^(PGR1oKiJ&T ztWzzV>T%k-X`wU|LAgk((k=DfT_BVB*MLkeyM|PkRi;exnwmGS6F8G%=g5|?uOT;+ z3h>kh%hq+b_)s1XT}#eYA!DIK_mVLa_%MsptsC0fT74E8<^_Cc#a=SPHK&el*h^N- zv>@uz%^To}c_#73dD5cG1TdLtoWp(UreuW*YC+dhGGgew#U@Cq5flXaTnxARC>b^0 z>dd$^cOeF2ov68OTN-?Do}xceGTb%4jt;+$j4ai|D6+M#u?>i}I$)>stLUuj$o#p> z=2fy@=7Y+0bb-h*CgWq~1&dDWLItD*HW1|FiR%DM&c_wVM}dvTIg&cUD10 z8c2NB)HJs?Aq#2k^<<(t4>E*p*OOD}L)Vi62;~o7PpVXuz=`Y0qRG~?HoG?2!7qX% zpj&T%oKm;?TW=u4>5Dgz>k6y&%o=H|2Cr1#)J*GdB;z4{O3_CAm(g0G@$TSr<~RhrsI7O6<`{(U6u zs#!>n>?0!sH5eU@!Ri4Ll$`#skBrgL8*>wRnx1+yDW~7vM24ZLD{dxBR7|L@zZqbV zMZdinzF!SajTYZR_UZj=w~)_z1k-K;Q46N6pK{aIPq}I9r!y-|<(|nNwmc;}w-}Pd zR5#t4-sDS~dc-c#({Ce_>1nr-0Nr{Ud2Upk(YUY!a^lIsnC&b|&$*qH(4XB-9y+6D zg~5&LZV*)K25y+~fEYuG?dN|V$>E(BkBBs0u!Z7;#T`&_vjI^A)iK?jc z7N%&~eloVWYB@|qS{s1-_RQ!m9mbp;`xecK?1dYIqIiP6k{JqdU3HH+6}qYjXBM^selA-cP>3k(As)U57$ z@IP>MW=gyE0O@y4(tE0~02a)h$2ycRflF9_ko>s^CKuV29qH}OE#(#UkS(Dl+s^?T z@dEPipPbKZg!xcgYZJ`zAmuTD#EZNu^XgLYG+>_wEXrB88u7dmf}9ONKzUiC{Q>>F zqNYxBKSa6|6=zOYKTO6Ct${8opq8Q+A3&!-rJ?GvNCQ3m`eAY&Ocn9wj5; zi8^)waQXo~_fg2-A9$2x>%Hv*Al93Hr1yqL^i2f2sW0F&2OUCh?h9mFBO9mY@a&W> zc?=2@zv~NRnokX-kM{+<)>Fo*`4l@v0*mOb-x5Y(!EZ?^dq6(|*gCrK5I_w4mSnns z4C@3+BI20{IDx+TTT<+8fqa3%l<2I0M@!77N@&d?VC+qYgkJH)1O)Q&%o+pF=+l6R zFV$V&4PFv^KI?Y|ll23H#RCr_ouU{14(9nNA3R`^(vPg0^s^%*m;U)N;-kO(9mz5t zD|nm?*B`?J_LzR8KL$rJdfMZ_j-!to4Ey8bCd2e27(1oGQCgjlM58vfZUIb@e92kT z1#}Fdry!U;@)XIZ^-qyuDqecvDHx&uDH2wfL5}i1oVk}_Y6M4f>7u8}kYQ+GX4l;4 z>S*25WVt)J0$}fd8r*eqMM`_?X;SZDwG_hw>agge&!I5yc3y<1FZw+>%>`AI-M=SO zv^RcF-dCrg*_ptznsF)vGfqA58$AdYq0I8~AIUO>E`FI5g@7g2lT|Qp+6)Cw)C_?= z{Ibr#O)ryYlu77n%n|2wZv(sa&8dXhn|uw3-24i8SE22HB10-{qqTK3w5^lJGA`ms zR$o;nB(VSfKasLw;6;SH-OXv}rV4J3c?~iv&?;r?M@*W+}v8z=$4woeYEA_5IgLk*lf>+o9TDUMJmdbqNIh_IIF|xda6X zN0U8ER$x5^FRI`#>9KdnX>d?Szk7##q0X8+la?LGqn>>uzj;oI5EJR%2epUT-@>#xB*}t@%)8x(VDFFiPM>O=D|A+jius(7AEV#!?Ol zsK0%LoHEni(fsa>-P>&4uq(DsOdtyZI`(lWZ>IiC-d8F>9u|Fz+h9W63|W2U~B)I+V~m^e5pgTJIxPQ~l%YCk8$TvF z?9!E=kg>Xk-1rH(RIP$6u=G<%+o~{$o&6~k;lQ(4{m*G@fO_FNpYCKH_>|nF_uBYZ za$1Q^9cDwx5^6di{5nvV-G2oYt<`z=S5m2c{#P>Er9W8uxq(jjb8?XzK0$Z%IFR<2 zu`oP5_+UnCS zP^@b#ZEx#r-rCXK(%4x#J6+$^*0D`HZ9@Qr71i$E6!75#ziA0v0H@P72O^n1blFX% z*fXu@3>0Y(cLnAv{Rd931|n$gmcX`R*eqa@fSoD YD{$K|ofUTmzRuBL&vHBdORIhV6Cfh>KL7v# From 25e67bd1074e9be09bccc90359cbf10a1c304ddd Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Sun, 17 Dec 2017 10:53:33 +0000 Subject: [PATCH 8/9] Refactor weak symbol usage. The Linux run-time linker doesn't allow weak references in one library to be overridden by ones in another. To work around this, we now declare the runtime functions as weak and perform dynamic checks on whether the symbols have been resolved and call the fallbacks as local static functions if they are not present. --- Source/NSObject.m | 89 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/Source/NSObject.m b/Source/NSObject.m index 143a4cc6b..c68b06232 100644 --- a/Source/NSObject.m +++ b/Source/NSObject.m @@ -446,8 +446,24 @@ struct obj_layout { }; typedef struct obj_layout *obj; +/* + * These symbols are provided by newer versions of the GNUstep Objective-C + * runtime. When linked against an older version, we will use our internal + * versions. + */ __attribute__((weak)) -BOOL objc_release_fast_no_destroy_np(id anObject) +BOOL objc_release_fast_no_destroy_np(id anObject); + +__attribute__((weak)) +void objc_release_fast_np(id anObject); + +__attribute__((weak)) +size_t object_getRetainCount_np(id anObject); + +__attribute__((weak)) +id objc_retain_fast_np(id anObject); + +static BOOL objc_release_fast_no_destroy_internal(id anObject) { if (double_release_check_enabled) { @@ -506,15 +522,38 @@ BOOL objc_release_fast_no_destroy_np(id anObject) return NO; } -__attribute__((weak)) -void objc_release_fast_np(id anObject) +static BOOL release_fast_no_destroy(id anObject) { - if (objc_release_fast_no_destroy_np(anObject)) + if (objc_release_fast_no_destroy_np) + { + return objc_release_fast_no_destroy_np(anObject); + } + else + { + return objc_release_fast_no_destroy_internal(anObject); + } +} + +static void objc_release_fast_np_internal(id anObject) +{ + if (release_fast_no_destroy(anObject)) { [anObject dealloc]; } } +static void release_fast(id anObject) +{ + if (objc_release_fast_np) + { + objc_release_fast_np(anObject); + } + else + { + objc_release_fast_np_internal(anObject); + } +} + /** * Examines the extra reference count for the object and, if non-zero * decrements it, otherwise leaves it unchanged.
@@ -524,15 +563,26 @@ void objc_release_fast_np(id anObject) inline BOOL NSDecrementExtraRefCountWasZero(id anObject) { - return objc_release_fast_no_destroy_np(anObject); + return release_fast_no_destroy(anObject); } -__attribute__((weak)) -size_t object_getRetainCount_np(id anObject) +size_t object_getRetainCount_np_internal(id anObject) { return ((obj)anObject)[-1].retained + 1; } +size_t getRetainCount(id anObject) +{ + if (object_getRetainCount_np) + { + return object_getRetainCount_np(anObject); + } + else + { + return object_getRetainCount_np_internal(anObject); + } +} + /** * Return the extra reference count of anObject (a value in the range * from 0 to the maximum unsigned integer value minus one).
@@ -541,7 +591,7 @@ size_t object_getRetainCount_np(id anObject) inline NSUInteger NSExtraRefCount(id anObject) { - return object_getRetainCount_np(anObject) - 1; + return getRetainCount(anObject) - 1; } /** @@ -550,8 +600,7 @@ NSExtraRefCount(id anObject) * would be incremented to too large a value.
* This is used by the [NSObject-retain] method. */ -__attribute__((weak)) -id objc_retain_fast_np(id anObject) +static id objc_retain_fast_np_internal(id anObject) { BOOL tooFar = NO; @@ -617,6 +666,18 @@ id objc_retain_fast_np(id anObject) return anObject; } +static id retain_fast(id anObject) +{ + if (objc_retain_fast_np) + { + return objc_retain_fast_np(anObject); + } + else + { + return objc_retain_fast_np_internal(anObject); + } +} + /** * Increments the extra reference count for anObject.
* The GNUstep version raises an exception if the reference count @@ -626,7 +687,7 @@ id objc_retain_fast_np(id anObject) inline void NSIncrementExtraRefCount(id anObject) { - objc_retain_fast_np(anObject); + retain_fast(anObject); } #ifndef NDEBUG @@ -1967,7 +2028,7 @@ static id gs_weak_load(id obj) */ - (oneway void) release { - objc_release_fast_np(self); + release_fast(self); } /** @@ -2026,7 +2087,7 @@ static id gs_weak_load(id obj) */ - (id) retain { - return objc_retain_fast_np(self); + return retain_fast(self); } /** @@ -2050,7 +2111,7 @@ static id gs_weak_load(id obj) */ - (NSUInteger) retainCount { - return object_getRetainCount_np(self); + return getRetainCount(self); } /** From 8a89579e154b5e6dc5ad9ce7158ee665bc153397 Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Sun, 17 Dec 2017 10:56:09 +0000 Subject: [PATCH 9/9] Duplicate some data from an easy-to-find location to a less helpful one. --- ChangeLog | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/ChangeLog b/ChangeLog index 9253c0226..c510314b0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2017-12-17 David Chisnall + + * Source/NSObject.m: Refactor refcount usage. + + This makes it easier for the runtime to change how reference + counts are + stored by removing any refcount manipulation from -base when + the runtime + provides accessors. This should have no functionality + change with + existing runtimes, but will let newer runtimes drop in + alternative + representations easily. + 2017-12-03 Fred Kiefer * Headers/Foundation/NSFileManager.h