Merge branch 'master' into json-signed-integers

This commit is contained in:
Graham Lee 2017-12-18 12:56:28 +00:00 committed by GitHub
commit 186d840ce6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 218 additions and 31 deletions

View file

@ -1,4 +1,4 @@
2017-11-25 Graham Lee <graham@iamleeg.com> 2017-12-18 Graham Lee <graham@iamleeg.com>
* Source/NSJSONSerialization.m: Fix for bug #12 on github. This * Source/NSJSONSerialization.m: Fix for bug #12 on github. This
makes sure that unsigned integer types are written as such, makes sure that unsigned integer types are written as such,
@ -6,6 +6,26 @@
* Tests/base/NSJSONSerialization/tests00.m: Test case for above. * Tests/base/NSJSONSerialization/tests00.m: Test case for above.
2017-12-17 David Chisnall <theraven@sucs.org>
* 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 <fredkiefer@gmx.de>
* Headers/Foundation/NSFileManager.h
* Source/NSFileManager.m: Correct setting the delegate.
Add new symbolic link method.
2017-11-16 Richard Frith-Macdonald <rfm@gnu.org> 2017-11-16 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSArray.m: Fix for bug reported on github by zneak. * Source/NSArray.m: Fix for bug reported on github by zneak.

View file

@ -302,6 +302,14 @@ typedef NSUInteger NSDirectoryEnumerationOptions;
*/ */
- (BOOL) removeItemAtURL: (NSURL*)url - (BOOL) removeItemAtURL: (NSURL*)url
error: (NSError**)error; error: (NSError**)error;
/**
* Creates a symbolic link at the path
* that point to the destination path.<br />
* Returns YES on success, otherwise NO.
*/
- (BOOL) createSymbolicLinkAtPath: (NSString*)path
withDestinationPath: (NSString*)destPath
error: (NSError**)error;
#endif #endif
/** /**

View file

@ -107,6 +107,10 @@ typedef retTy(^name)()
#endif /* __has_feature(blocks) */ #endif /* __has_feature(blocks) */
#if __has_include(<objc/blocks_runtime.h>)
# include <objc/blocks_runtime.h>
#else
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@ -136,5 +140,7 @@ void _Block_release(const void *) __attribute__((weak));
# define Block_release(x) _Block_release((const void *)(x)) # define Block_release(x) _Block_release((const void *)(x))
#endif #endif
#endif /* __has_include(<objc/blocks_runtime.h>) */
#endif /* __GSBlocks_h_GNUSTEP_BASE_INCLUDE */ #endif /* __GSBlocks_h_GNUSTEP_BASE_INCLUDE */

Binary file not shown.

View file

@ -361,7 +361,7 @@ static NSStringEncoding defaultEncoding;
return _delegate; return _delegate;
} }
- (void) setDelegate: (NSFileManager *)delegate { - (void) setDelegate: (id<NSFileManagerDelegate>)delegate {
_delegate = delegate; _delegate = delegate;
} }
@ -1586,6 +1586,26 @@ static NSStringEncoding defaultEncoding;
return [self removeItemAtPath: [url path] error: error]; 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 - (BOOL) fileExistsAtPath: (NSString*)path
{ {
return [self fileExistsAtPath: path isDirectory: 0]; return [self fileExistsAtPath: path isDirectory: 0];

View file

@ -100,29 +100,29 @@ static Class concreteClass = 0;
+ (id) strongToStrongObjectsMapTable + (id) strongToStrongObjectsMapTable
{ {
return [self mapTableWithKeyOptions: NSMapTableObjectPointerPersonality return [self mapTableWithKeyOptions: NSPointerFunctionsObjectPersonality
valueOptions: NSMapTableObjectPointerPersonality]; valueOptions: NSPointerFunctionsObjectPersonality];
} }
+ (id) strongToWeakObjectsMapTable + (id) strongToWeakObjectsMapTable
{ {
return [self mapTableWithKeyOptions: NSMapTableObjectPointerPersonality return [self mapTableWithKeyOptions: NSPointerFunctionsObjectPersonality
valueOptions: NSMapTableObjectPointerPersonality | valueOptions: NSPointerFunctionsObjectPersonality |
NSMapTableWeakMemory]; NSMapTableWeakMemory];
} }
+ (id) weakToStrongObjectsMapTable + (id) weakToStrongObjectsMapTable
{ {
return [self mapTableWithKeyOptions: NSMapTableObjectPointerPersonality | return [self mapTableWithKeyOptions: NSPointerFunctionsObjectPersonality |
NSMapTableWeakMemory NSMapTableWeakMemory
valueOptions: NSMapTableObjectPointerPersonality]; valueOptions: NSPointerFunctionsObjectPersonality];
} }
+ (id) weakToWeakObjectsMapTable + (id) weakToWeakObjectsMapTable
{ {
return [self mapTableWithKeyOptions: NSMapTableObjectPointerPersonality | return [self mapTableWithKeyOptions: NSPointerFunctionsObjectPersonality |
NSMapTableWeakMemory NSMapTableWeakMemory
valueOptions: NSMapTableObjectPointerPersonality | valueOptions: NSPointerFunctionsObjectPersonality |
NSMapTableWeakMemory]; NSMapTableWeakMemory];
} }

View file

@ -125,6 +125,7 @@ BOOL NSDeallocateZombies = NO;
static Class zombieClass = Nil; static Class zombieClass = Nil;
static NSMapTable *zombieMap = 0; static NSMapTable *zombieMap = 0;
#ifndef OBJC_CAP_ARC
static void GSMakeZombie(NSObject *o, Class c) static void GSMakeZombie(NSObject *o, Class c)
{ {
object_setClass(o, zombieClass); object_setClass(o, zombieClass);
@ -135,6 +136,7 @@ static void GSMakeZombie(NSObject *o, Class c)
[allocationLock unlock]; [allocationLock unlock];
} }
} }
#endif
static void GSLogZombie(id o, SEL sel) static void GSLogZombie(id o, SEL sel)
{ {
@ -444,15 +446,24 @@ struct obj_layout {
}; };
typedef struct obj_layout *obj; typedef struct obj_layout *obj;
/** /*
* Examines the extra reference count for the object and, if non-zero * These symbols are provided by newer versions of the GNUstep Objective-C
* decrements it, otherwise leaves it unchanged.<br /> * runtime. When linked against an older version, we will use our internal
* Returns a flag to say whether the count was zero * versions.
* (and hence whether the extra reference count was decremented).<br />
* This function is used by the [NSObject-release] method.
*/ */
inline BOOL __attribute__((weak))
NSDecrementExtraRefCountWasZero(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) if (double_release_check_enabled)
{ {
@ -483,6 +494,9 @@ NSDecrementExtraRefCountWasZero(id anObject)
* have been greater than zero) * have been greater than zero)
*/ */
(((obj)anObject)[-1].retained) = 0; (((obj)anObject)[-1].retained) = 0;
# ifdef OBJC_CAP_ARC
objc_delete_weak_refs(anObject);
# endif
return YES; return YES;
} }
#else /* GSATOMICREAD */ #else /* GSATOMICREAD */
@ -491,6 +505,9 @@ NSDecrementExtraRefCountWasZero(id anObject)
[theLock lock]; [theLock lock];
if (((obj)anObject)[-1].retained == 0) if (((obj)anObject)[-1].retained == 0)
{ {
# ifdef OBJC_CAP_ARC
objc_delete_weak_refs(anObject);
# endif
[theLock unlock]; [theLock unlock];
return YES; return YES;
} }
@ -505,6 +522,67 @@ NSDecrementExtraRefCountWasZero(id anObject)
return NO; return NO;
} }
static BOOL release_fast_no_destroy(id 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.<br />
* Returns a flag to say whether the count was zero
* (and hence whether the extra reference count was decremented).<br />
*/
inline BOOL
NSDecrementExtraRefCountWasZero(id anObject)
{
return release_fast_no_destroy(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 * Return the extra reference count of anObject (a value in the range
* from 0 to the maximum unsigned integer value minus one).<br /> * from 0 to the maximum unsigned integer value minus one).<br />
@ -513,7 +591,7 @@ NSDecrementExtraRefCountWasZero(id anObject)
inline NSUInteger inline NSUInteger
NSExtraRefCount(id anObject) NSExtraRefCount(id anObject)
{ {
return ((obj)anObject)[-1].retained; return getRetainCount(anObject) - 1;
} }
/** /**
@ -522,8 +600,7 @@ NSExtraRefCount(id anObject)
* would be incremented to too large a value.<br /> * would be incremented to too large a value.<br />
* This is used by the [NSObject-retain] method. * This is used by the [NSObject-retain] method.
*/ */
inline void static id objc_retain_fast_np_internal(id anObject)
NSIncrementExtraRefCount(id anObject)
{ {
BOOL tooFar = NO; BOOL tooFar = NO;
@ -586,6 +663,31 @@ NSIncrementExtraRefCount(id anObject)
@" for %@ - %@", base, anObject]; @" for %@ - %@", base, 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.<br />
* The GNUstep version raises an exception if the reference count
* would be incremented to too large a value.<br />
* This is used by the [NSObject-retain] method.
*/
inline void
NSIncrementExtraRefCount(id anObject)
{
retain_fast(anObject);
} }
#ifndef NDEBUG #ifndef NDEBUG
@ -596,6 +698,8 @@ NSIncrementExtraRefCount(id anObject)
#define AREM(c, o) #define AREM(c, o)
#endif #endif
#ifndef OBJC_CAP_ARC
static SEL cxx_construct, cxx_destruct; static SEL cxx_construct, cxx_destruct;
/** /**
@ -629,6 +733,7 @@ callCXXConstructors(Class aClass, id anObject)
} }
return constructor; return constructor;
} }
#endif
/* /*
@ -642,6 +747,9 @@ callCXXConstructors(Class aClass, id anObject)
inline id inline id
NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone *zone) NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone *zone)
{ {
#ifdef OBJC_CAP_ARC
return class_createInstance(aClass, extraBytes);
#else
id new; id new;
int size; int size;
@ -674,17 +782,21 @@ NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone *zone)
callCXXConstructors(aClass, new); callCXXConstructors(aClass, new);
return new; return new;
#endif
} }
inline void inline void
NSDeallocateObject(id anObject) NSDeallocateObject(id anObject)
{ {
Class aClass = object_getClass(anObject); Class aClass = object_getClass(anObject);
if ((anObject != nil) && !class_isMetaClass(aClass)) if ((anObject != nil) && !class_isMetaClass(aClass))
{ {
#ifndef OBJC_CAP_ARC
obj o = &((obj)anObject)[-1]; obj o = &((obj)anObject)[-1];
NSZone *z = NSZoneFromPointer(o); NSZone *z = NSZoneFromPointer(o);
#endif
/* Call the default finalizer to handle C++ destructors. /* Call the default finalizer to handle C++ destructors.
*/ */
@ -693,16 +805,37 @@ NSDeallocateObject(id anObject)
AREM(aClass, (id)anObject); AREM(aClass, (id)anObject);
if (NSZombieEnabled == YES) 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); GSMakeZombie(anObject, aClass);
if (NSDeallocateZombies == YES) if (NSDeallocateZombies == YES)
{ {
NSZoneFree(z, o); NSZoneFree(z, o);
} }
#endif
} }
else else
{ {
#ifdef OBJC_CAP_ARC
object_dispose(anObject);
#else
object_setClass((id)anObject, (Class)(void*)0xdeadface); object_setClass((id)anObject, (Class)(void*)0xdeadface);
NSZoneFree(z, o); NSZoneFree(z, o);
#endif
} }
} }
return; return;
@ -1197,6 +1330,7 @@ static id gs_weak_load(id obj)
- (void) finalize - (void) finalize
{ {
#ifndef OBJC_CAP_ARC
Class destructorClass = Nil; Class destructorClass = Nil;
IMP destructor = 0; IMP destructor = 0;
/* /*
@ -1251,6 +1385,7 @@ static id gs_weak_load(id obj)
} }
} }
return; return;
#endif
} }
/** /**
@ -1893,13 +2028,7 @@ static id gs_weak_load(id obj)
*/ */
- (oneway void) release - (oneway void) release
{ {
if (NSDecrementExtraRefCountWasZero(self)) release_fast(self);
{
# ifdef OBJC_CAP_ARC
objc_delete_weak_refs(self);
# endif
[self dealloc];
}
} }
/** /**
@ -1958,8 +2087,7 @@ static id gs_weak_load(id obj)
*/ */
- (id) retain - (id) retain
{ {
NSIncrementExtraRefCount(self); return retain_fast(self);
return self;
} }
/** /**
@ -1983,7 +2111,7 @@ static id gs_weak_load(id obj)
*/ */
- (NSUInteger) retainCount - (NSUInteger) retainCount
{ {
return NSExtraRefCount(self) + 1; return getRetainCount(self);
} }
/** /**

View file

@ -1,6 +1,9 @@
#import "ObjectTesting.h" #import "ObjectTesting.h"
#import <Foundation/NSAutoreleasePool.h> #import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSProxy.h> #import <Foundation/NSProxy.h>
#if __has_include(<objc/capabilities.h>)
#include <objc/capabilities.h>
#endif
int main() int main()
{ {
@ -24,8 +27,10 @@ int main()
obj1 = [NSProxy allocWithZone:testZone]; obj1 = [NSProxy allocWithZone:testZone];
PASS(obj1 != nil, "%s has working allocWithZone:",prefix); PASS(obj1 != nil, "%s has working allocWithZone:",prefix);
#ifndef OBJC_CAP_ARC
PASS(NSZoneFromPointer(obj1) == testZone, "%s uses zone for alloc",prefix); PASS(NSZoneFromPointer(obj1) == testZone, "%s uses zone for alloc",prefix);
PASS([obj1 zone] == testZone, "%s -zone works",prefix); PASS([obj1 zone] == testZone, "%s -zone works",prefix);
#endif
PASS([obj1 hash] != 0, "%s has working -hash",prefix); PASS([obj1 hash] != 0, "%s has working -hash",prefix);
PASS([obj1 isEqual:obj1] == YES, "%s has working -isEqual:",prefix); PASS([obj1 isEqual:obj1] == YES, "%s has working -isEqual:",prefix);