Skip to content

Commit 6a4d99a

Browse files
committed
Attempt to cleanup fast enumeration handling and improve support for gcc on mingw
1 parent bb1908a commit 6a4d99a

6 files changed

Lines changed: 1662 additions & 2115 deletions

File tree

Headers/GNUstepBase/GNUstep.h

Lines changed: 27 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,8 @@
2424
#ifndef __GNUSTEP_GNUSTEP_H_INCLUDED_
2525
#define __GNUSTEP_GNUSTEP_H_INCLUDED_
2626

27-
/* Check to see if this is a MINGW build
28-
*/
29-
#if defined(__MINGW32__) || defined(__MINGW64__)
30-
# if !defined(__MINGW__)
31-
# define __MINGW__
32-
# endif
33-
#endif
34-
35-
#if !defined(GS_GCC_MINREQ)
36-
#if defined(__GNUC__) && defined(__GNUC_MINOR__) && !defined(__clang__)
37-
# define GS_GCC_MINREQ(maj, min) \
38-
((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
39-
#else
40-
# define GS_GCC_MINREQ(maj, min) 0
41-
#endif
42-
43-
#if defined(__clang__)
44-
# define GS_CLANG_MINREQ(maj, min) \
45-
((__clang_major__ << 16) + __clang_minor__ >= ((maj) << 16) + (min))
46-
#else
47-
# define GS_CLANG_MINREQ(maj, min) 0
48-
#endif
49-
#endif /* GS_GCC_MINREQ */
27+
#import "GNUstepBase/GSConfig.h"
28+
#import "GNUstepBase/GSVersionMacros.h"
5029

5130
/* The contents of this file are designed to be usable with either
5231
* GNUstep-base or MacOS-X Foundation.
@@ -465,9 +444,14 @@ void *__object = (void*)(object);\
465444
#define GSLocalizedStaticString(key, comment) key
466445

467446
/**
447+
* <p>
448+
* This function (macro) is a GNUstep extension.
449+
* </p>
450+
* <p>
468451
* To be used inside a method for making sure that a range does not specify
469452
* anything outside the size of an array/string. Raises exception if range
470453
* extends beyond [0,size]. Size must be an unsigned integer (NSUInteger).
454+
* </p>
471455
*/
472456
#define GS_RANGE_CHECK(RANGE, SIZE) \
473457
if (RANGE.location > (NSUInteger)SIZE \
@@ -486,37 +470,40 @@ if ((NSUInteger)INDEX >= (NSUInteger)OVER) \
486470
GSNameFromSelector(_cmd), (NSUInteger)INDEX]
487471

488472

489-
#if defined(__clang__) || (GS_GCC_MINREQ(6,1) && !defined(__MINGW__))
490-
/** Macro to support fast enumeration on older compilers. The argument are
473+
#if defined(__clang__) \
474+
|| (GS_HAVE_FAST_ENUMERATION \
475+
&& (GS_HAVE_FAST_ENUMERATION_SETTER || !defined(__MINGW__)))
476+
/** <p>This function (macro) is a GNUstep extension.</p>
477+
* <p>
478+
* Macro to support fast enumeration on platforms where the compiler or
479+
* runtime do not support fast enumeration directly. The argument are
491480
* a type specification for the value returned by the iteration, the name of
492481
* a variable to hold that value, and the collection to be iterated over
493-
* (may also be an instance of [NSEnumerator] rather than a collection).
482+
* (may also be an instance of [NSEnumerator] rather than a collection).<br />
483+
* On a compiler/runtime with fast enumeration support, this macro starts
484+
* the fast enumeration block.
485+
* </p>
494486
*/
495487
#define GS_FOR_IN(type, var, collection) \
496488
for (type var in collection)\
497489
{
498-
/** Macro to end a fast enumeration block on older compilers. Its argument
499-
* must be identical to that of the corresponding GS_FOR_IN macro.
500-
* On a more modern compiler this just ends the fast enumeration block.
490+
/** <p>This function (macro) is a GNUstep extension.</p>
491+
* <p>
492+
* Macro to end a fast enumeration block on older compilers. Its argument
493+
* must be identical to that of the corresponding GS_FOR_IN macro.<br />
494+
* On a compiler/runtime with fast enumeration support, this just ends
495+
* the fast enumeration block.
496+
* </p>
501497
*/
502498
#define GS_END_FOR(collection) }
503499
#else
504500

505-
/* This is the code for the older compilers (and for systems where we can't
506-
* override the mutation handling function safely).
507-
* We declare the function to be called when a mutation of a collection is
508-
* detected during fast enumeration. If possible we use the standard one
509-
* provided by the runtime, otherwise we use one provided by GNUstep-base.
501+
/* We declare the function to be called when a mutation of a collection is
502+
* detected during fast enumeration; provided by GNUstep-base.
510503
*/
511504
#pragma GCC diagnostic push
512505
#pragma GCC diagnostic ignored "-Wattributes"
513-
#if defined(__MINGW__)
514-
#define USE_GSEnumerationMutation 1 /* Tells NSObject.m */
515506
void GSEnumerationMutation(id);
516-
#else
517-
void objc_enumerationMutation(id);
518-
#define GSEnumerationMutation(X) objc_enumerationMutation(X)
519-
#endif
520507
#pragma GCC diagnostic pop
521508

522509
#define GS_FOR_IN(type, var, c) \

Headers/GNUstepBase/GSConfig.h.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,8 @@ typedef struct {
272272
#define GS_USE_LIBCURL @HAVE_LIBCURL@
273273
#define GS_USE_LIBDISPATCH @HAVE_LIBDISPATCH@
274274
#define GS_USE_LIBDISPATCH_RUNLOOP @HAVE_LIBDISPATCH_RUNLOOP@
275+
#define GS_HAVE_FAST_ENUMERATION @OBJCFASTENUMERATION@
276+
#define GS_HAVE_FAST_ENUMERATION_SETTER @OBJCSETFASTENUMERATION@
275277
#define GS_HAVE_NSURLSESSION @GS_HAVE_NSURLSESSION@
276278
#define GS_HAVE_OBJC_ROOT_CLASS_ATTR @GS_HAVE_OBJC_ROOT_CLASS_ATTR@
277279
#define GS_USE_WIN32_THREADS_AND_LOCKS @HAVE_WIN32_THREADS_AND_LOCKS@

Headers/GNUstepBase/GSVersionMacros.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#ifndef __GNUSTEP_GSVERSIONMACROS_H_INCLUDED_
2525
#define __GNUSTEP_GSVERSIONMACROS_H_INCLUDED_
2626

27+
#import "GNUstepBase/GSConfig.h"
28+
2729
/* By default we defined NO_GNUSTEP to 0 so that we will include extensions.
2830
*/
2931
#if !defined(NO_GNUSTEP)

Source/NSObject.m

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -84,30 +84,37 @@
8484
#endif
8585
#endif
8686

87-
#if defined(USE_GSEnumerationMutation)
8887
/* GSEnumerationMutation() is called whenever a collection mutates in the
89-
* middle of fast enumeration which was not supported by the compiler and
90-
* where we need to use our own function name because the runtime library
91-
* contains a symbol which would conflict with the normal name (platforms
92-
* where weak symbols don't work reliably).
88+
* middle of fast enumeration.
9389
*/
9490
void GSEnumerationMutation(id obj)
9591
{
9692
[NSException raise: NSGenericException
9793
format: @"Collection %@ was mutated while being enumerated", obj];
9894
}
99-
#else
100-
/* objc_enumerationMutation() is called whenever a collection mutates in the
101-
* middle of fast enumeration. We need to have this defined and linked into
102-
* any code that uses fast enumeration, so we define it in NSObject.h
103-
* This symbol is exported to take precedence over the weak symbol provided
104-
* by the runtime library.
105-
*/
106-
GS_EXPORT void objc_enumerationMutation(id obj)
107-
{
108-
[NSException raise: NSGenericException
109-
format: @"Collection %@ was mutated while being enumerated", obj];
110-
}
95+
96+
#if GS_HAVE_FAST_ENUMERATION
97+
/* If possible we will ask the runtime to call our handler.
98+
*/
99+
# if GS_HAVE_FAST_ENUMERATION_SETTER
100+
extern void objc_setEnumerationMutationHandler(void (*handler)(id));
101+
# else
102+
/* Otherwise, we can override a weak symbol in the runtime on platforms
103+
* which support it (not reliable with DLLs in mingw).
104+
*/
105+
# if !defined(__MINGW__)
106+
/* objc_enumerationMutation() is called whenever a collection mutates
107+
* in the middle of fast enumeration. We need to have this defined
108+
* and linked into any code that uses fast enumeration.
109+
* This symbol is exported to take precedence over the weak symbol
110+
* provided by the runtime library.
111+
*/
112+
GS_EXPORT void objc_enumerationMutation(id obj)
113+
{
114+
GSEnumerationMutation(obj);
115+
}
116+
# endif
117+
# endif
111118
#endif
112119

113120
/* platforms which do not support weak */
@@ -1021,6 +1028,12 @@ + (void) initialize
10211028
{
10221029
if (self == [NSObject class])
10231030
{
1031+
#if GS_HAVE_FAST_ENUMERATION_SETTER
1032+
/* Tell runtime to pass enumeration mutation detection handling to us.
1033+
*/
1034+
objc_setEnumerationMutationHandler(GSEnumerationMutation);
1035+
#endif
1036+
10241037
#ifdef _WIN32
10251038
/* Start of sockets so we can get host name and other info */
10261039
WORD wVersionRequested = MAKEWORD(2, 2);

0 commit comments

Comments
 (0)