Attempt to link in ObjC2 compatibility code if we have an older runtime.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@29670 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2010-02-19 12:51:02 +00:00
parent 7cc69dfaae
commit 073595b9e9
11 changed files with 1246 additions and 863 deletions

View file

@ -1,3 +1,18 @@
2010-02-19 Richard Frith-Macdonald <rfm@gnu.org>
* configure.ac: Add check for ObjC2 support in runtime.
* config.mak.in: define OBJC2RUNTIME to yes or no
* configure: regenerate
* Source/GNUmakefile: Build/link ObjectiveC2 compat code if needed
* Source/ObjectiveC2/Availability.h:
* Source/ObjectiveC2/runtime.c:
* Source/ObjectiveC2/GNUmakefile:
* Source/ObjectiveC2/properties.m:
* Source/ObjectiveC2/sync.m:
* Source/ObjectiveC2/blocks_runtime.m:
Attempt to build in ObjectiveC2 compatibility functions when we don't
have an ObjC2 runtime.
2010-02-19 Richard Frith-Macdonald <rfm@gnu.org>
Simplify header imports with common headers handled in the correct

View file

@ -65,8 +65,13 @@ ifneq ($(base),no)
LIBRARY_NAME += libgnustep-base
endif
libgnustep-base_SUBPROJECTS = Additions
libgnustep-baseadd_SUBPROJECTS = Additions
ifeq ($(OBJC2RUNTIME),no)
libgnustep-base_SUBPROJECTS = ObjectiveC2
libgnustep-baseadd_SUBPROJECTS += Additions
endif
libgnustep-base_SUBPROJECTS += Additions
libgnustep-baseadd_SUBPROJECTS += Additions
ifeq ($(GNUSTEP_TARGET_OS), mingw32)
libgnustep-base_SUBPROJECTS+=win32
@ -473,7 +478,10 @@ libgnustep-baseadd_NEEDS_GUI = NO
# build Additions as a subproject, causing concurrency issues). If it
# can be guaranteed that they'll never be built together, this could
# be removed.
SUBPROJECTS = Additions
ifeq ($(OBJC2RUNTIME),no)
SUBPROJECTS = ObjectiveC2
endif
SUBPROJECTS += Additions
-include Makefile.preamble

View file

@ -0,0 +1,12 @@
#ifdef STRICT_MACOS_X
# define OBJC_NONPORTABLE __attribute__((error("Function not supported by the Apple runtime")))
#else
# define OBJC_NONPORTABLE
#endif
#if !defined(__DEPRECATE_DIRECT_ACCESS) || defined(__OBJC_LEGACY_GNU_MODE__) || defined(__OBJC_RUNTIME_INTERNAL__)
# define OBJC_DEPRECATED
#else
# define OBJC_DEPRECATED __attribute__((deprecated))
#endif

View file

@ -1,41 +1,59 @@
#
# src makefile for the GNUstep Base Library
#
# Copyright (C) 2010 Free Software Foundation, Inc.
#
# Written by: Richard Frith-Macdonald <rfm@gnu.org>
#
# This file is part of the GNUstep Base Library.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Library General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02111 USA.
#
PACKAGE_NAME = gnustep-base
GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../../base.make
include $(GNUSTEP_MAKEFILES)/common.make
include ../../config.mak
#
# Application
#
VERSION = 0.1
FRAMEWORK_NAME = ObjectiveC2
#
# Resource files
#
ObjectiveC2_LANGUAGES = English
SUBPROJECT_NAME = ObjectiveC2
ObjectiveC2_OBJC_FILES = \
blocks_runtime.m\
properties.m\
sync.m
blocks_runtime.m\
properties.m\
sync.m
ObjectiveC2_C_FILES = \
runtime.c
runtime.c
ObjectiveC2_HEADER_FILES = \
Availability.h\
blocks_runtime.h\
runtime.h
ADDITIONAL_CFLAGS = -std=c99 -fexceptions
ADDITIONAL_OBJCFLAGS = -fobjc-exceptions -fexceptions
Availability.h\
blocks_runtime.h\
runtime.h
ifeq ($(CC), clang)
ADDITIONAL_OBJCFLAGS = -fblocks
ADDITIONAL_OBJCFLAGS = -fblocks
endif
ifeq ($(GNUSTEP_TARGET_CPU), ix86)
ADDITIONAL_OBJCFLAGS += -march=i686
ADDITIONAL_OBJCFLAGS += -march=i686
endif
ObjectiveC2_OBJCFLAGS += -std=c99
-include Makefile.preamble
include $(GNUSTEP_MAKEFILES)/subproject.make
-include Makefile.postamble
include $(GNUSTEP_MAKEFILES)/framework.make
-include ../../etoile.make

View file

@ -23,8 +23,8 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#import "objc/blocks_runtime.h"
#import "objc/runtime.h"
#import "blocks_runtime.h"
#import "runtime.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -38,47 +38,47 @@
// Descriptor attributes
enum {
BLOCK_HAS_COPY_DISPOSE = (1 << 25),
BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code
BLOCK_IS_GLOBAL = (1 << 28),
BLOCK_HAS_DESCRIPTOR = (1 << 29), // interim until complete world build is accomplished
BLOCK_HAS_COPY_DISPOSE = (1 << 25),
BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code
BLOCK_IS_GLOBAL = (1 << 28),
BLOCK_HAS_DESCRIPTOR = (1 << 29), // interim until complete world build is accomplished
};
// _Block_object_assign() and _Block_object_dispose() flag helpers.
enum {
BLOCK_FIELD_IS_OBJECT = 3, // id, NSObject, __attribute__((NSObject)), block, ...
BLOCK_FIELD_IS_BLOCK = 7, // a block variable
BLOCK_FIELD_IS_BYREF = 8, // the on stack structure holding the __block variable
BLOCK_FIELD_IS_WEAK = 16, // declared __weak
BLOCK_BYREF_CALLER = 128, // called from byref copy/dispose helpers
BLOCK_FIELD_IS_OBJECT = 3, // id, NSObject, __attribute__((NSObject)), block, ...
BLOCK_FIELD_IS_BLOCK = 7, // a block variable
BLOCK_FIELD_IS_BYREF = 8, // the on stack structure holding the __block variable
BLOCK_FIELD_IS_WEAK = 16, // declared __weak
BLOCK_BYREF_CALLER = 128, // called from byref copy/dispose helpers
};
// Helper structure
struct psy_block_literal {
void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
int flags;
int reserved;
void (*invoke)(void *, ...);
struct {
unsigned long int reserved; // NULL
unsigned long int size; // sizeof(struct Block_literal_1)
// optional helper functions
void (*copy_helper)(void *dst, void *src);
void (*dispose_helper)(void *src);
} *descriptor;
const char *types;
void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
int flags;
int reserved;
void (*invoke)(void *, ...);
struct {
unsigned long int reserved; // NULL
unsigned long int size; // sizeof(struct Block_literal_1)
// optional helper functions
void (*copy_helper)(void *dst, void *src);
void (*dispose_helper)(void *src);
} *descriptor;
const char *types;
};
// Helper structure
struct psy_block_byref_obj {
void *isa; // uninitialized
struct psy_block_byref_obj *forwarding;
int flags; //refcount;
int size;
void (*byref_keep)(struct psy_block_byref_obj *dst, struct psy_block_byref_obj *src);
void (*byref_dispose)(struct psy_block_byref_obj *);
void *isa; // uninitialized
struct psy_block_byref_obj *forwarding;
int flags; //refcount;
int size;
void (*byref_keep)(struct psy_block_byref_obj *dst, struct psy_block_byref_obj *src);
void (*byref_dispose)(struct psy_block_byref_obj *);
};
/* Certain field types require runtime assistance when being copied to the
@ -88,53 +88,58 @@ struct psy_block_byref_obj {
* the other choices which are mutually exclusive. Only in a Block copy helper
* will one see BLOCK_FIELD_IS_BYREF.
*/
void _Block_object_assign(void *destAddr, void *object, const int flags)
void
_Block_object_assign(void *destAddr, void *object, const int flags)
{
//printf("Copying %x to %x with flags %x\n", object, destAddr, flags);
// FIXME: Needs to be implemented
if(flags & BLOCK_FIELD_IS_WEAK)
//printf("Copying %x to %x with flags %x\n", object, destAddr, flags);
// FIXME: Needs to be implemented
if (flags & BLOCK_FIELD_IS_WEAK)
{
}
else
else
{
if(flags & BLOCK_FIELD_IS_BYREF)
if (flags & BLOCK_FIELD_IS_BYREF)
{
struct psy_block_byref_obj *src = object;
struct psy_block_byref_obj **dst = destAddr;
struct psy_block_byref_obj *src = object;
struct psy_block_byref_obj **dst = destAddr;
/* I followed Apple's specs saying byref's "flags" field should
* represent the refcount but it still contains real flag, so this
* is a little hack...
*/
if((src->flags & ~BLOCK_HAS_COPY_DISPOSE) == 0)
/* I followed Apple's specs saying byref's "flags" field should
* represent the refcount but it still contains real flag, so this
* is a little hack...
*/
if ((src->flags & ~BLOCK_HAS_COPY_DISPOSE) == 0)
{
*dst = malloc(src->size);
memcpy(*dst, src, src->size);
if (src->forwarding == src)
{
(*dst)->forwarding = *dst;
}
if(src->size >= sizeof(struct psy_block_byref_obj))
{
src->byref_keep(*dst, src);
}
*dst = malloc(src->size);
memcpy(*dst, src, src->size);
if (src->forwarding == src)
{
(*dst)->forwarding = *dst;
}
if (src->size >= sizeof(struct psy_block_byref_obj))
{
src->byref_keep(*dst, src);
}
}
else *dst = src;
else
{
*dst = src;
}
(*dst)->flags++;
(*dst)->flags++;
}
else if((flags & BLOCK_FIELD_IS_BLOCK) == BLOCK_FIELD_IS_BLOCK)
else if ((flags & BLOCK_FIELD_IS_BLOCK) == BLOCK_FIELD_IS_BLOCK)
{
struct psy_block_literal *src = object;
struct psy_block_literal **dst = destAddr;
struct psy_block_literal *src = object;
struct psy_block_literal **dst = destAddr;
*dst = Block_copy(src);
*dst = Block_copy(src);
}
else if((flags & BLOCK_FIELD_IS_OBJECT) == BLOCK_FIELD_IS_OBJECT)
else if ((flags & BLOCK_FIELD_IS_OBJECT) == BLOCK_FIELD_IS_OBJECT)
{
id src = object;
id *dst = destAddr;
*dst = [src retain];
id src = object;
id *dst = destAddr;
*dst = [src retain];
}
}
}
@ -145,103 +150,113 @@ void _Block_object_assign(void *destAddr, void *object, const int flags)
* The same flags used in the copy helper should be used for each call
* generated to this function:
*/
void _Block_object_dispose(void *object, const int flags)
void
_Block_object_dispose(void *object, const int flags)
{
// FIXME: Needs to be implemented
if(flags & BLOCK_FIELD_IS_WEAK)
// FIXME: Needs to be implemented
if (flags & BLOCK_FIELD_IS_WEAK)
{
}
else
else
{
if(flags & BLOCK_FIELD_IS_BYREF)
if (flags & BLOCK_FIELD_IS_BYREF)
{
struct psy_block_byref_obj *src = object;
src->flags--;
if((src->flags & ~BLOCK_HAS_COPY_DISPOSE) == 0)
struct psy_block_byref_obj *src = object;
src->flags--;
if ((src->flags & ~BLOCK_HAS_COPY_DISPOSE) == 0)
{
if(src->size >= sizeof(struct psy_block_byref_obj))
src->byref_dispose(src);
if (src->size >= sizeof(struct psy_block_byref_obj))
src->byref_dispose(src);
free(src);
free(src);
}
}
else if((flags & ~BLOCK_BYREF_CALLER) == BLOCK_FIELD_IS_BLOCK)
else if ((flags & ~BLOCK_BYREF_CALLER) == BLOCK_FIELD_IS_BLOCK)
{
struct psy_block_literal *src = object;
Block_release(src);
struct psy_block_literal *src = object;
Block_release(src);
}
else if((flags & ~BLOCK_BYREF_CALLER) == BLOCK_FIELD_IS_OBJECT)
else if ((flags & ~BLOCK_BYREF_CALLER) == BLOCK_FIELD_IS_OBJECT)
{
id src = object;
[src release];
id src = object;
[src release];
}
}
}
struct StackBlockClass {
void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
int flags;
int reserved;
void (*invoke)(void *, ...);
struct {
unsigned long int reserved; // NULL
unsigned long int size; // sizeof(struct Block_literal_1)
// optional helper functions
void (*copy_helper)(void *dst, void *src);
void (*dispose_helper)(void *src);
} *descriptor;
const char *types;
void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
int flags;
int reserved;
void (*invoke)(void *, ...);
struct {
unsigned long int reserved; // NULL
unsigned long int size; // sizeof(struct Block_literal_1)
// optional helper functions
void (*copy_helper)(void *dst, void *src);
void (*dispose_helper)(void *src);
} *descriptor;
const char *types;
};
// Copy a block to the heap if it's still on the stack or increments its retain count.
void *_Block_copy(void *src)
/* Copy a block to the heap if it's still on the stack or
* increments its retain count.
*/
void *
_Block_copy(void *src)
{
struct StackBlockClass *self = src;
struct StackBlockClass *ret = self;
struct StackBlockClass *self = src;
struct StackBlockClass *ret = self;
extern void _NSConcreteStackBlock __attribute__((weak));
extern void _NSConcreteStackBlock __attribute__((weak));
// If the block is Global, there's no need to copy it on the heap.
if(self->isa == &_NSConcreteStackBlock && self->flags & BLOCK_HAS_DESCRIPTOR)
// If the block is Global, there's no need to copy it on the heap.
if (self->isa == &_NSConcreteStackBlock
&& self->flags & BLOCK_HAS_DESCRIPTOR)
{
if(self->reserved == 0)
if (self->reserved == 0)
{
ret = malloc(self->descriptor->size);
memcpy(ret, self, self->descriptor->size);
if(self->flags & BLOCK_HAS_COPY_DISPOSE)
self->descriptor->copy_helper(ret, self);
memcpy(self, ret, self->descriptor->size);
ret = malloc(self->descriptor->size);
memcpy(ret, self, self->descriptor->size);
if (self->flags & BLOCK_HAS_COPY_DISPOSE)
self->descriptor->copy_helper(ret, self);
memcpy(self, ret, self->descriptor->size);
}
ret->reserved++;
ret->reserved++;
}
return ret;
return ret;
}
// Release a block and frees the memory when the retain count hits zero.
void _Block_release(void *src)
void
_Block_release(void *src)
{
struct StackBlockClass *self = src;
struct StackBlockClass *self = src;
extern void _NSConcreteStackBlock __attribute__((weak));
extern void _NSConcreteStackBlock __attribute__((weak));
if(self->isa == &_NSConcreteStackBlock && // A Global block doesn't need to be released
self->flags & BLOCK_HAS_DESCRIPTOR && // Should always be true...
self->reserved > 0) // If false, then it's not allocated on the heap, we won't release auto memory !
if (self->isa == &_NSConcreteStackBlock
// A Global block doesn't need to be released
&& self->flags & BLOCK_HAS_DESCRIPTOR
// Should always be true...
&& self->reserved > 0)
// If false, then it's not allocated on the heap, we won't release auto memory !
{
self->reserved--;
if(self->reserved == 0)
self->reserved--;
if (self->reserved == 0)
{
if(self->flags & BLOCK_HAS_COPY_DISPOSE)
self->descriptor->dispose_helper(self);
free(self);
if (self->flags & BLOCK_HAS_COPY_DISPOSE)
self->descriptor->dispose_helper(self);
free(self);
}
}
}
const char *_Block_get_types(void *blk)
const char *
_Block_get_types(void *blk)
{
struct psy_block_literal *block = blk;
return block->types;
struct psy_block_literal *block = blk;
return block->types;
}

View file

@ -8,40 +8,51 @@
- (void)release;
@end
id objc_getProperty(id obj, SEL _cmd, ptrdiff_t offset, BOOL isAtomic)
id
objc_getProperty(id obj, SEL _cmd, ptrdiff_t offset, BOOL isAtomic)
{
if (isAtomic)
char *addr;
id ret;
if (isAtomic)
{
@synchronized(obj)
{
@synchronized(obj) {
return objc_getProperty(obj, _cmd, offset, NO);
}
return objc_getProperty(obj, _cmd, offset, NO);
}
char *addr = (char*)obj;
addr += offset;
id ret = *(id*)addr;
return [[ret retain] autorelease];
}
addr = (char*)obj;
addr += offset;
ret = *(id*)addr;
return [[ret retain] autorelease];
}
void objc_setProperty(id obj, SEL _cmd, ptrdiff_t offset, id arg, BOOL isAtomic, BOOL isCopy)
void
objc_setProperty(id obj, SEL _cmd, ptrdiff_t offset, id arg, BOOL isAtomic,
BOOL isCopy)
{
if (isAtomic)
char *addr;
id old;
if (isAtomic)
{
@synchronized(obj)
{
@synchronized(obj) {
objc_setProperty(obj, _cmd, offset, arg, NO, isCopy);
return;
}
objc_setProperty(obj, _cmd, offset, arg, NO, isCopy);
return;
}
if (isCopy)
{
arg = [arg copy];
}
else
{
arg = [arg retain];
}
char *addr = (char*)obj;
addr += offset;
id old = *(id*)addr;
*(id*)addr = arg;
[old release];
}
if (isCopy)
{
arg = [arg copy];
}
else
{
arg = [arg retain];
}
addr = (char*)obj;
addr += offset;
old = *(id*)addr;
*(id*)addr = arg;
[old release];
}

File diff suppressed because it is too large Load diff

View file

@ -2,7 +2,7 @@
/* Ensure Unix98 compatible pthreads for glibc */
#if defined __GLIBC__
#define __USE_UNIX98 1
# define __USE_UNIX98 1
#endif
#include <pthread.h>
@ -20,88 +20,104 @@ IMP objc_msg_lookup(id, SEL);
static void deallocLockClass(id obj, SEL _cmd);
static inline Class findLockClass(id obj)
static inline Class
findLockClass(id obj)
{
struct objc_object object = { obj->isa };
SEL dealloc = @selector(dealloc);
// Find the first class where this lookup is correct
if (objc_msg_lookup((id)&object, dealloc) != (IMP)deallocLockClass)
struct objc_object object = { obj->isa };
SEL dealloc = @selector(dealloc);
Class lastClass;
// Find the first class where this lookup is correct
if (objc_msg_lookup((id)&object, dealloc) != (IMP)deallocLockClass)
{
do {
object.isa = class_getSuperclass(object.isa);
} while (Nil != object.isa
&& objc_msg_lookup((id)&object, dealloc) != (IMP)deallocLockClass);
}
if (Nil == object.isa)
{
return Nil;
}
/* object->isa is now either the lock class, or a class which inherits from
* the lock class
*/
do {
lastClass = object.isa;
object.isa = class_getSuperclass(object.isa);
} while (Nil != object.isa
&& objc_msg_lookup((id)&object, dealloc) == (IMP)deallocLockClass);
return lastClass;
}
static inline Class
initLockObject(id obj)
{
char nameBuffer[40];
Class lockClass;
const char *types;
pthread_mutex_t *lock;
snprintf(nameBuffer, 39, "hiddenlockClass%lld", lockClassId++);
lockClass = objc_allocateClassPair(obj->isa, nameBuffer,
sizeof(pthread_mutex_t));
types = method_getTypeEncoding(class_getInstanceMethod(obj->isa,
@selector(dealloc)));
class_addMethod(lockClass, @selector(dealloc), (IMP)deallocLockClass, types);
objc_registerClassPair(lockClass);
lock = object_getIndexedIvars(lockClass);
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(lock, &attr);
pthread_mutexattr_destroy(&attr);
obj->isa = lockClass;
return lockClass;
}
static void
deallocLockClass(id obj, SEL _cmd)
{
Class lockClass = findLockClass(obj);
Class realClass = class_getSuperclass(lockClass);
// Free the lock
pthread_mutex_t *lock = object_getIndexedIvars(lockClass);
pthread_mutex_destroy(lock);
// Free the class
objc_disposeClassPair(lockClass);
// Reset the class then call the real -dealloc
obj->isa = realClass;
[obj dealloc];
}
void
objc_sync_enter(id obj)
{
Class lockClass = findLockClass(obj);
pthread_mutex_t *lock;
if (Nil == lockClass)
{
pthread_mutex_lock(&at_sync_init_lock);
// Test again in case two threads call objc_sync_enter at once
lockClass = findLockClass(obj);
if (Nil == lockClass)
{
do {
object.isa = class_getSuperclass(object.isa);
} while (Nil != object.isa &&
objc_msg_lookup((id)&object, dealloc) != (IMP)deallocLockClass);
lockClass = initLockObject(obj);
}
if (Nil == object.isa) { return Nil; }
// object->isa is now either the lock class, or a class which inherits from
// the lock class
Class lastClass;
do {
lastClass = object.isa;
object.isa = class_getSuperclass(object.isa);
} while (Nil != object.isa &&
objc_msg_lookup((id)&object, dealloc) == (IMP)deallocLockClass);
return lastClass;
pthread_mutex_unlock(&at_sync_init_lock);
}
lock = object_getIndexedIvars(lockClass);
pthread_mutex_lock(lock);
}
static inline Class initLockObject(id obj)
void
objc_sync_exit(id obj)
{
char nameBuffer[40];
snprintf(nameBuffer, 39, "hiddenlockClass%lld", lockClassId++);
Class lockClass = objc_allocateClassPair(obj->isa, nameBuffer,
sizeof(pthread_mutex_t));
const char *types =
method_getTypeEncoding(class_getInstanceMethod(obj->isa,
@selector(dealloc)));
class_addMethod(lockClass, @selector(dealloc), (IMP)deallocLockClass,
types);
objc_registerClassPair(lockClass);
pthread_mutex_t *lock = object_getIndexedIvars(lockClass);
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(lock, &attr);
pthread_mutexattr_destroy(&attr);
obj->isa = lockClass;
return lockClass;
}
static void deallocLockClass(id obj, SEL _cmd)
{
Class lockClass = findLockClass(obj);
Class realClass = class_getSuperclass(lockClass);
// Free the lock
pthread_mutex_t *lock = object_getIndexedIvars(lockClass);
pthread_mutex_destroy(lock);
// Free the class
objc_disposeClassPair(lockClass);
// Reset the class then call the real -dealloc
obj->isa = realClass;
[obj dealloc];
}
void objc_sync_enter(id obj)
{
Class lockClass = findLockClass(obj);
if (Nil == lockClass)
{
pthread_mutex_lock(&at_sync_init_lock);
// Test again in case two threads call objc_sync_enter at once
lockClass = findLockClass(obj);
if (Nil == lockClass)
{
lockClass = initLockObject(obj);
}
pthread_mutex_unlock(&at_sync_init_lock);
}
pthread_mutex_t *lock = object_getIndexedIvars(lockClass);
pthread_mutex_lock(lock);
}
void objc_sync_exit(id obj)
{
Class lockClass = findLockClass(obj);
pthread_mutex_t *lock = object_getIndexedIvars(lockClass);
pthread_mutex_unlock(lock);
Class lockClass = findLockClass(obj);
pthread_mutex_t *lock = object_getIndexedIvars(lockClass);
pthread_mutex_unlock(lock);
}

View file

@ -18,6 +18,7 @@ WITH_FFI=@WITH_FFI@
NX_CONST_STRING_CLASS=@NX_CONST_STRING_CLASS@
OBJCFLAGS=@OBJCFLAGS@
OBJC2RUNTIME=@OBJC2RUNTIME@
HAVE_INET_PTON=@HAVE_INET_PTON@
HAVE_INET_NTOP=@HAVE_INET_NTOP@

115
configure vendored
View file

@ -310,7 +310,7 @@ ac_includes_default="\
#endif"
ac_subdirs_all="$ac_subdirs_all Source/pathconfig Source/mframe SSL"
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP WHOAMI EGREP OBJC_WITH_GC GS_WORDS_BIGENDIAN GS_SINT8 GS_UINT8 ac_cv_sizeof_short ac_cv_sizeof_int ac_cv_sizeof_long ac_cv_sizeof_long_long ac_cv_sizeof_float ac_cv_sizeof_double ac_cv_sizeof_voidp GS_SADDR GS_UADDR GS_SINT16 GS_UINT16 GS_SINT32 GS_UINT32 GS_SINT64 GS_UINT64 GS_HAVE_I64 GS_SINT128 GS_UINT128 GS_HAVE_I128 GS_FLT32 GS_FLT64 _GSC_S_SHT _GSC_S_INT _GSC_S_LNG _GSC_S_LNG_LNG DYNAMIC_LINKER NX_CONST_STRING_OBJCFLAGS NX_CONST_STRING_CLASS HAVE_OBJC_SYNC_ENTER GS_SIZEOF_MUTEX_T GS_SIZEOF_COND_T HAVE_PTS_STREAM_MODULES INCLUDE_STDINT DEFINE_INT8_T DEFINE_UINT8_T DEFINE_INT16_T DEFINE_UINT16_T DEFINE_INT32_T DEFINE_UINT32_T DEFINE_INT64_T DEFINE_UINT64_T DEFINE_INTPTR_T DEFINE_UINTPTR_T USE_ZLIB HAVE_INET_PTON HAVE_INET_NTOP GS_PASS_ARGUMENTS GS_FAKE_MAIN OBJCFLAGS WITH_FFI XML2_CONFIG XML_CONFIG XML_CFLAGS XML_LIBS HAVE_LIBXSLT HAVE_LIBXML TLS_CONFIG TLS_CFLAGS TLS_LIBS HAVE_GNUTLS HAVE_MDNS USE_GMP INCLUDE_FLAGS LDIR_FLAGS subdirs VERSION MAJOR_VERSION MINOR_VERSION SUBMINOR_VERSION GCC_VERSION LIBOBJS LTLIBOBJS'
ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP WHOAMI EGREP OBJC_WITH_GC GS_WORDS_BIGENDIAN GS_SINT8 GS_UINT8 ac_cv_sizeof_short ac_cv_sizeof_int ac_cv_sizeof_long ac_cv_sizeof_long_long ac_cv_sizeof_float ac_cv_sizeof_double ac_cv_sizeof_voidp GS_SADDR GS_UADDR GS_SINT16 GS_UINT16 GS_SINT32 GS_UINT32 GS_SINT64 GS_UINT64 GS_HAVE_I64 GS_SINT128 GS_UINT128 GS_HAVE_I128 GS_FLT32 GS_FLT64 _GSC_S_SHT _GSC_S_INT _GSC_S_LNG _GSC_S_LNG_LNG DYNAMIC_LINKER NX_CONST_STRING_OBJCFLAGS NX_CONST_STRING_CLASS OBJC2RUNTIME HAVE_OBJC_SYNC_ENTER GS_SIZEOF_MUTEX_T GS_SIZEOF_COND_T HAVE_PTS_STREAM_MODULES INCLUDE_STDINT DEFINE_INT8_T DEFINE_UINT8_T DEFINE_INT16_T DEFINE_UINT16_T DEFINE_INT32_T DEFINE_UINT32_T DEFINE_INT64_T DEFINE_UINT64_T DEFINE_INTPTR_T DEFINE_UINTPTR_T USE_ZLIB HAVE_INET_PTON HAVE_INET_NTOP GS_PASS_ARGUMENTS GS_FAKE_MAIN OBJCFLAGS WITH_FFI XML2_CONFIG XML_CONFIG XML_CFLAGS XML_LIBS HAVE_LIBXSLT HAVE_LIBXML TLS_CONFIG TLS_CFLAGS TLS_LIBS HAVE_GNUTLS HAVE_MDNS USE_GMP INCLUDE_FLAGS LDIR_FLAGS subdirs VERSION MAJOR_VERSION MINOR_VERSION SUBMINOR_VERSION GCC_VERSION LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@ -8647,6 +8647,118 @@ fi
done
#--------------------------------------------------------------------
# Check for ObjC2 support in runtime
#--------------------------------------------------------------------
for ac_func in objc_setProperty
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
if eval "test \"\${$as_ac_var+set}\" = set"; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define $ac_func innocuous_$ac_func
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
#undef $ac_func
/* Override any gcc2 internal prototype to avoid an error. */
#ifdef __cplusplus
extern "C"
{
#endif
/* We use char because int might match the return type of a gcc2
builtin and then its argument prototype would still apply. */
char $ac_func ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
choke me
#else
char (*f) () = $ac_func;
#endif
#ifdef __cplusplus
}
#endif
int
main ()
{
return f != $ac_func;
;
return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
(eval $ac_link) 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
{ ac_try='test -z "$ac_c_werror_flag"
|| test ! -s conftest.err'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
{ ac_try='test -s conftest$ac_exeext'
{ (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
(eval $ac_try) 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
eval "$as_ac_var=yes"
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
eval "$as_ac_var=no"
fi
rm -f conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
if test `eval echo '${'$as_ac_var'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
if test $ac_cv_func_objc_setProperty = yes ; then
OBJC2RUNTIME=yes
else
OBJC2RUNTIME=no
fi
# Don't revert any Objective-C flags as they are used in the next test
#--------------------------------------------------------------------
@ -21401,6 +21513,7 @@ s,@_GSC_S_LNG_LNG@,$_GSC_S_LNG_LNG,;t t
s,@DYNAMIC_LINKER@,$DYNAMIC_LINKER,;t t
s,@NX_CONST_STRING_OBJCFLAGS@,$NX_CONST_STRING_OBJCFLAGS,;t t
s,@NX_CONST_STRING_CLASS@,$NX_CONST_STRING_CLASS,;t t
s,@OBJC2RUNTIME@,$OBJC2RUNTIME,;t t
s,@HAVE_OBJC_SYNC_ENTER@,$HAVE_OBJC_SYNC_ENTER,;t t
s,@GS_SIZEOF_MUTEX_T@,$GS_SIZEOF_MUTEX_T,;t t
s,@GS_SIZEOF_COND_T@,$GS_SIZEOF_COND_T,;t t

View file

@ -658,6 +658,17 @@ fi
#--------------------------------------------------------------------
AC_CHECK_FUNCS(objc_thread_add)
#--------------------------------------------------------------------
# Check for ObjC2 support in runtime
#--------------------------------------------------------------------
AC_CHECK_FUNCS(objc_setProperty)
if test $ac_cv_func_objc_setProperty = yes ; then
OBJC2RUNTIME=yes
else
OBJC2RUNTIME=no
fi
AC_SUBST(OBJC2RUNTIME)
# Don't revert any Objective-C flags as they are used in the next test
#--------------------------------------------------------------------