mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 00:30:53 +00:00
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:
parent
d605c6f7b5
commit
97e7df0ac3
11 changed files with 1246 additions and 863 deletions
15
ChangeLog
15
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
12
Source/ObjectiveC2/Availability.h
Normal file
12
Source/ObjectiveC2/Availability.h
Normal 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
|
|
@ -1,22 +1,41 @@
|
|||
#
|
||||
# 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
|
||||
|
||||
|
||||
ObjectiveC2_C_FILES = \
|
||||
runtime.c
|
||||
|
||||
|
@ -25,9 +44,6 @@ ObjectiveC2_HEADER_FILES = \
|
|||
blocks_runtime.h\
|
||||
runtime.h
|
||||
|
||||
ADDITIONAL_CFLAGS = -std=c99 -fexceptions
|
||||
ADDITIONAL_OBJCFLAGS = -fobjc-exceptions -fexceptions
|
||||
|
||||
ifeq ($(CC), clang)
|
||||
ADDITIONAL_OBJCFLAGS = -fblocks
|
||||
endif
|
||||
|
@ -35,7 +51,9 @@ ifeq ($(GNUSTEP_TARGET_CPU), ix86)
|
|||
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
|
||||
|
|
|
@ -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>
|
||||
|
@ -88,16 +88,17 @@ 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)
|
||||
if (flags & BLOCK_FIELD_IS_WEAK)
|
||||
{
|
||||
}
|
||||
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;
|
||||
|
@ -106,7 +107,7 @@ void _Block_object_assign(void *destAddr, void *object, const int flags)
|
|||
* represent the refcount but it still contains real flag, so this
|
||||
* is a little hack...
|
||||
*/
|
||||
if((src->flags & ~BLOCK_HAS_COPY_DISPOSE) == 0)
|
||||
if ((src->flags & ~BLOCK_HAS_COPY_DISPOSE) == 0)
|
||||
{
|
||||
*dst = malloc(src->size);
|
||||
memcpy(*dst, src, src->size);
|
||||
|
@ -114,26 +115,30 @@ void _Block_object_assign(void *destAddr, void *object, const int flags)
|
|||
{
|
||||
(*dst)->forwarding = *dst;
|
||||
}
|
||||
if(src->size >= sizeof(struct psy_block_byref_obj))
|
||||
if (src->size >= sizeof(struct psy_block_byref_obj))
|
||||
{
|
||||
src->byref_keep(*dst, src);
|
||||
}
|
||||
}
|
||||
else *dst = src;
|
||||
else
|
||||
{
|
||||
*dst = src;
|
||||
}
|
||||
|
||||
(*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;
|
||||
|
||||
*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];
|
||||
}
|
||||
}
|
||||
|
@ -145,33 +150,34 @@ 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)
|
||||
if (flags & BLOCK_FIELD_IS_WEAK)
|
||||
{
|
||||
}
|
||||
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)
|
||||
if ((src->flags & ~BLOCK_HAS_COPY_DISPOSE) == 0)
|
||||
{
|
||||
if(src->size >= sizeof(struct psy_block_byref_obj))
|
||||
if (src->size >= sizeof(struct psy_block_byref_obj))
|
||||
src->byref_dispose(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);
|
||||
}
|
||||
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];
|
||||
|
@ -195,8 +201,11 @@ struct StackBlockClass {
|
|||
};
|
||||
|
||||
|
||||
// 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;
|
||||
|
@ -204,13 +213,14 @@ void *_Block_copy(void *src)
|
|||
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 (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)
|
||||
if (self->flags & BLOCK_HAS_COPY_DISPOSE)
|
||||
self->descriptor->copy_helper(ret, self);
|
||||
memcpy(self, ret, self->descriptor->size);
|
||||
}
|
||||
|
@ -220,27 +230,32 @@ void *_Block_copy(void *src)
|
|||
}
|
||||
|
||||
// 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;
|
||||
|
||||
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)
|
||||
if (self->reserved == 0)
|
||||
{
|
||||
if(self->flags & BLOCK_HAS_COPY_DISPOSE)
|
||||
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;
|
||||
|
|
|
@ -8,25 +8,36 @@
|
|||
- (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)
|
||||
{
|
||||
char *addr;
|
||||
id ret;
|
||||
|
||||
if (isAtomic)
|
||||
{
|
||||
@synchronized(obj) {
|
||||
@synchronized(obj)
|
||||
{
|
||||
return objc_getProperty(obj, _cmd, offset, NO);
|
||||
}
|
||||
}
|
||||
char *addr = (char*)obj;
|
||||
addr = (char*)obj;
|
||||
addr += offset;
|
||||
id ret = *(id*)addr;
|
||||
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)
|
||||
{
|
||||
char *addr;
|
||||
id old;
|
||||
|
||||
if (isAtomic)
|
||||
{
|
||||
@synchronized(obj) {
|
||||
@synchronized(obj)
|
||||
{
|
||||
objc_setProperty(obj, _cmd, offset, arg, NO, isCopy);
|
||||
return;
|
||||
}
|
||||
|
@ -39,9 +50,9 @@ void objc_setProperty(id obj, SEL _cmd, ptrdiff_t offset, id arg, BOOL isAtomic,
|
|||
{
|
||||
arg = [arg retain];
|
||||
}
|
||||
char *addr = (char*)obj;
|
||||
addr = (char*)obj;
|
||||
addr += offset;
|
||||
id old = *(id*)addr;
|
||||
old = *(id*)addr;
|
||||
*(id*)addr = arg;
|
||||
[old release];
|
||||
}
|
||||
|
|
|
@ -82,21 +82,26 @@ extern objc_mutex_t __objc_runtime_mutex;
|
|||
* Looks up the instance method in a specific class, without recursing into
|
||||
* superclasses.
|
||||
*/
|
||||
static Method class_getInstanceMethodNonrecursive(Class aClass, SEL aSelector)
|
||||
static Method
|
||||
class_getInstanceMethodNonrecursive(Class aClass, SEL aSelector)
|
||||
{
|
||||
struct objc_method_list *methods;
|
||||
const char *name = sel_get_name(aSelector);
|
||||
const char *types = sel_get_type(aSelector);
|
||||
|
||||
for (struct objc_method_list *methods = aClass->methods;
|
||||
methods != NULL ; methods = methods->method_next)
|
||||
for (methods = aClass->methods;
|
||||
methods != NULL; methods = methods->method_next)
|
||||
{
|
||||
for (int i=0 ; i<methods->method_count ; i++)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < methods->method_count; i++)
|
||||
{
|
||||
Method_t method = &methods->method_list[i];
|
||||
|
||||
if (strcmp(sel_get_name(method->method_name), name) == 0)
|
||||
{
|
||||
if (NULL == types ||
|
||||
strcmp(types, method->method_types) == 0)
|
||||
if (NULL == types
|
||||
|| strcmp(types, method->method_types) == 0)
|
||||
{
|
||||
return method;
|
||||
}
|
||||
|
@ -109,11 +114,13 @@ static Method class_getInstanceMethodNonrecursive(Class aClass, SEL aSelector)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static void objc_updateDtableForClassContainingMethod(Method m)
|
||||
static void
|
||||
objc_updateDtableForClassContainingMethod(Method m)
|
||||
{
|
||||
Class nextClass = Nil;
|
||||
void *state;
|
||||
SEL sel = method_getName(m);
|
||||
|
||||
while (Nil != (nextClass = objc_next_class(&state)))
|
||||
{
|
||||
if (class_getInstanceMethodNonrecursive(nextClass, sel) == m)
|
||||
|
@ -125,20 +132,27 @@ static void objc_updateDtableForClassContainingMethod(Method m)
|
|||
}
|
||||
|
||||
|
||||
BOOL class_addIvar(Class cls,
|
||||
BOOL
|
||||
class_addIvar(Class cls,
|
||||
const char *name,
|
||||
size_t size,
|
||||
uint8_t alignment,
|
||||
const char *types)
|
||||
{
|
||||
struct objc_ivar_list *ivarlist;
|
||||
Ivar ivar;
|
||||
|
||||
if (CLS_ISRESOLV(cls) || CLS_ISMETA(cls))
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
struct objc_ivar_list *ivarlist = cls->ivars;
|
||||
if (class_getInstanceVariable(cls, name) != NULL)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (class_getInstanceVariable(cls, name) != NULL) { return NO; }
|
||||
ivarlist = cls->ivars;
|
||||
|
||||
if (NULL == ivarlist)
|
||||
{
|
||||
|
@ -153,7 +167,7 @@ BOOL class_addIvar(Class cls,
|
|||
+ (ivarlist->ivar_count - 1) * sizeof(struct objc_ivar));
|
||||
}
|
||||
|
||||
Ivar ivar = &cls->ivars->ivar_list[cls->ivars->ivar_count - 1];
|
||||
ivar = &cls->ivars->ivar_list[cls->ivars->ivar_count - 1];
|
||||
ivar->ivar_name = strdup(name);
|
||||
ivar->ivar_type = strdup(types);
|
||||
// Round up the offset of the ivar so it is correctly aligned.
|
||||
|
@ -163,15 +177,20 @@ BOOL class_addIvar(Class cls,
|
|||
return YES;
|
||||
}
|
||||
|
||||
BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
|
||||
BOOL
|
||||
class_addMethod(Class cls, SEL name, IMP imp, const char *types)
|
||||
{
|
||||
const char *methodName = sel_get_name(name);
|
||||
struct objc_method_list *methods;
|
||||
for (methods=cls->methods; methods!=NULL ; methods=methods->method_next)
|
||||
|
||||
for (methods = cls->methods; methods != NULL; methods = methods->method_next)
|
||||
{
|
||||
for (int i=0 ; i<methods->method_count ; i++)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < methods->method_count; i++)
|
||||
{
|
||||
Method_t method = &methods->method_list[i];
|
||||
|
||||
if (strcmp(sel_get_name(method->method_name), methodName) == 0)
|
||||
{
|
||||
return NO;
|
||||
|
@ -184,7 +203,8 @@ BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
|
|||
cls->methods = methods;
|
||||
|
||||
methods->method_count = 1;
|
||||
methods->method_list[0].method_name = sel_register_typed_name(methodName, types);
|
||||
methods->method_list[0].method_name
|
||||
= sel_register_typed_name(methodName, types);
|
||||
methods->method_list[0].method_types = strdup(types);
|
||||
methods->method_list[0].method_imp = (objc_imp_gnu)imp;
|
||||
|
||||
|
@ -196,12 +216,21 @@ BOOL class_addMethod(Class cls, SEL name, IMP imp, const char *types)
|
|||
return YES;
|
||||
}
|
||||
|
||||
BOOL class_addProtocol(Class cls, Protocol *protocol)
|
||||
BOOL
|
||||
class_addProtocol(Class cls, Protocol *protocol)
|
||||
{
|
||||
if (class_conformsToProtocol(cls, protocol)) { return NO; }
|
||||
struct objc_protocol_list *protocols = cls->protocols;
|
||||
struct objc_protocol_list *protocols;
|
||||
|
||||
if (class_conformsToProtocol(cls, protocol))
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
protocols = cls->protocols;
|
||||
protocols = objc_malloc(sizeof(struct objc_protocol_list));
|
||||
if (protocols == NULL) { return NO; }
|
||||
if (protocols == NULL)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
protocols->next = cls->protocols;
|
||||
protocols->count = 1;
|
||||
protocols->list[0] = protocol;
|
||||
|
@ -210,12 +239,17 @@ BOOL class_addProtocol(Class cls, Protocol *protocol)
|
|||
return YES;
|
||||
}
|
||||
|
||||
BOOL class_conformsToProtocol(Class cls, Protocol *protocol)
|
||||
BOOL
|
||||
class_conformsToProtocol(Class cls, Protocol *protocol)
|
||||
{
|
||||
for (struct objc_protocol_list *protocols = cls->protocols;
|
||||
protocols != NULL ; protocols = protocols->next)
|
||||
struct objc_protocol_list *protocols;
|
||||
|
||||
for (protocols = cls->protocols;
|
||||
protocols != NULL; protocols = protocols->next)
|
||||
{
|
||||
for (int i=0 ; i<protocols->count ; i++)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < protocols->count; i++)
|
||||
{
|
||||
if (strcmp(protocols->list[i]->protocol_name,
|
||||
protocol->protocol_name) == 0)
|
||||
|
@ -227,10 +261,14 @@ BOOL class_conformsToProtocol(Class cls, Protocol *protocol)
|
|||
return NO;
|
||||
}
|
||||
|
||||
Ivar * class_copyIvarList(Class cls, unsigned int *outCount)
|
||||
Ivar *
|
||||
class_copyIvarList(Class cls, unsigned int *outCount)
|
||||
{
|
||||
struct objc_ivar_list *ivarlist = cls->ivars;
|
||||
unsigned int count = 0;
|
||||
unsigned int i;
|
||||
Ivar *list;
|
||||
|
||||
if (ivarlist != NULL)
|
||||
{
|
||||
count = ivarlist->ivar_count;
|
||||
|
@ -244,19 +282,23 @@ Ivar * class_copyIvarList(Class cls, unsigned int *outCount)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
Ivar *list = malloc(count * sizeof(struct objc_ivar *));
|
||||
for (unsigned int i=0; i<ivarlist->ivar_count; i++)
|
||||
list = malloc(count * sizeof(struct objc_ivar *));
|
||||
for (i = 0; i < ivarlist->ivar_count; i++)
|
||||
{
|
||||
list[i] = &(ivarlist->ivar_list[i]);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
Method * class_copyMethodList(Class cls, unsigned int *outCount)
|
||||
Method *
|
||||
class_copyMethodList(Class cls, unsigned int *outCount)
|
||||
{
|
||||
unsigned int count = 0;
|
||||
for (struct objc_method_list *methods = cls->methods;
|
||||
methods != NULL ; methods = methods->method_next)
|
||||
Method *list;
|
||||
Method *copyDest;
|
||||
struct objc_method_list *methods;
|
||||
|
||||
for (methods = cls->methods; methods != NULL; methods = methods->method_next)
|
||||
{
|
||||
count += methods->method_count;
|
||||
}
|
||||
|
@ -269,13 +311,14 @@ Method * class_copyMethodList(Class cls, unsigned int *outCount)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
Method *list = malloc(count * sizeof(struct objc_method *));
|
||||
Method *copyDest = list;
|
||||
list = malloc(count * sizeof(struct objc_method *));
|
||||
copyDest = list;
|
||||
|
||||
for (struct objc_method_list *methods = cls->methods;
|
||||
methods != NULL ; methods = methods->method_next)
|
||||
for (methods = cls->methods; methods != NULL; methods = methods->method_next)
|
||||
{
|
||||
for (unsigned int i=0; i<methods->method_count; i++)
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < methods->method_count; i++)
|
||||
{
|
||||
copyDest[i] = &(methods->method_list[i]);
|
||||
}
|
||||
|
@ -285,13 +328,16 @@ Method * class_copyMethodList(Class cls, unsigned int *outCount)
|
|||
return list;
|
||||
}
|
||||
|
||||
Protocol ** class_copyProtocolList(Class cls, unsigned int *outCount)
|
||||
Protocol **
|
||||
class_copyProtocolList(Class cls, unsigned int *outCount)
|
||||
{
|
||||
struct objc_protocol_list *protocolList = cls->protocols;
|
||||
struct objc_protocol_list *list;
|
||||
int listSize = 0;
|
||||
for (struct objc_protocol_list *list = protocolList ;
|
||||
list != NULL ;
|
||||
list = list->next)
|
||||
Protocol **protocols;
|
||||
int index;
|
||||
|
||||
for (list = protocolList; list != NULL; list = list->next)
|
||||
{
|
||||
listSize += list->count;
|
||||
}
|
||||
|
@ -301,11 +347,9 @@ Protocol ** class_copyProtocolList(Class cls, unsigned int *outCount)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
Protocol **protocols = calloc(listSize, sizeof(Protocol*) + 1);
|
||||
int index = 0;
|
||||
for (struct objc_protocol_list *list = protocolList ;
|
||||
list != NULL ;
|
||||
list = list->next)
|
||||
protocols = calloc(listSize, sizeof(Protocol*) + 1);
|
||||
index = 0;
|
||||
for (list = protocolList; list != NULL; list = list->next)
|
||||
{
|
||||
memcpy(&protocols[index], list->list, list->count * sizeof(Protocol*));
|
||||
index += list->count;
|
||||
|
@ -315,20 +359,24 @@ Protocol ** class_copyProtocolList(Class cls, unsigned int *outCount)
|
|||
return protocols;
|
||||
}
|
||||
|
||||
id class_createInstance(Class cls, size_t extraBytes)
|
||||
id
|
||||
class_createInstance(Class cls, size_t extraBytes)
|
||||
{
|
||||
id obj = objc_malloc(cls->instance_size + extraBytes);
|
||||
obj->isa = cls;
|
||||
return obj;
|
||||
}
|
||||
|
||||
Method class_getInstanceMethod(Class aClass, SEL aSelector)
|
||||
Method
|
||||
class_getInstanceMethod(Class aClass, SEL aSelector)
|
||||
{
|
||||
Method method = class_getInstanceMethodNonrecursive(aClass, aSelector);
|
||||
|
||||
if (method == NULL)
|
||||
{
|
||||
// TODO: Check if this should be NULL or aClass
|
||||
Class superclass = class_getSuperclass(aClass);
|
||||
|
||||
if (superclass == NULL)
|
||||
{
|
||||
return NULL;
|
||||
|
@ -338,30 +386,40 @@ Method class_getInstanceMethod(Class aClass, SEL aSelector)
|
|||
return method;
|
||||
}
|
||||
|
||||
Method class_getClassMethod(Class aClass, SEL aSelector)
|
||||
Method
|
||||
class_getClassMethod(Class aClass, SEL aSelector)
|
||||
{
|
||||
return class_getInstanceMethod(aClass->class_pointer, aSelector);
|
||||
}
|
||||
|
||||
Ivar class_getClassVariable(Class cls, const char* name)
|
||||
Ivar
|
||||
class_getClassVariable(Class cls, const char* name)
|
||||
{
|
||||
assert(0 && "Class variables not implemented");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t class_getInstanceSize(Class cls)
|
||||
size_t
|
||||
class_getInstanceSize(Class cls)
|
||||
{
|
||||
return cls->instance_size;
|
||||
}
|
||||
|
||||
Ivar class_getInstanceVariable(Class cls, const char* name)
|
||||
Ivar
|
||||
class_getInstanceVariable(Class cls, const char* name)
|
||||
{
|
||||
struct objc_ivar_list *ivarlist = cls->ivars;
|
||||
if (NULL == ivarlist) { return NULL; }
|
||||
int i;
|
||||
|
||||
for (int i=0 ; i<ivarlist->ivar_count ; i++)
|
||||
if (NULL == ivarlist)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < ivarlist->ivar_count; i++)
|
||||
{
|
||||
Ivar ivar = &ivarlist->ivar_list[i];
|
||||
|
||||
if (strcmp(ivar->ivar_name, name) == 0)
|
||||
{
|
||||
return ivar;
|
||||
|
@ -372,30 +430,36 @@ Ivar class_getInstanceVariable(Class cls, const char* name)
|
|||
|
||||
// The format of the char* is undocumented. This function is only ever used in
|
||||
// conjunction with class_setIvarLayout().
|
||||
const char *class_getIvarLayout(Class cls)
|
||||
const char *
|
||||
class_getIvarLayout(Class cls)
|
||||
{
|
||||
return (char*)cls->ivars;
|
||||
}
|
||||
|
||||
IMP class_getMethodImplementation(Class cls, SEL name)
|
||||
IMP
|
||||
class_getMethodImplementation(Class cls, SEL name)
|
||||
{
|
||||
struct objc_object_gnu obj = { cls };
|
||||
return (IMP)objc_msg_lookup((id)&obj, name);
|
||||
}
|
||||
|
||||
IMP class_getMethodImplementation_stret(Class cls, SEL name)
|
||||
IMP
|
||||
class_getMethodImplementation_stret(Class cls, SEL name)
|
||||
{
|
||||
struct objc_object_gnu obj = { cls };
|
||||
return (IMP)objc_msg_lookup((id)&obj, name);
|
||||
}
|
||||
|
||||
const char * class_getName(Class cls)
|
||||
const char *
|
||||
class_getName(Class cls)
|
||||
{
|
||||
return class_get_class_name(cls);
|
||||
}
|
||||
|
||||
void __objc_resolve_class_links(void);
|
||||
Class class_getSuperclass(Class cls)
|
||||
|
||||
Class
|
||||
class_getSuperclass(Class cls)
|
||||
{
|
||||
if (!CLS_ISRESOLV(cls))
|
||||
{
|
||||
|
@ -404,42 +468,50 @@ Class class_getSuperclass(Class cls)
|
|||
return cls->super_class;
|
||||
}
|
||||
|
||||
int class_getVersion(Class theClass)
|
||||
int
|
||||
class_getVersion(Class theClass)
|
||||
{
|
||||
return class_get_version(theClass);
|
||||
}
|
||||
|
||||
const char *class_getWeakIvarLayout(Class cls)
|
||||
const char *
|
||||
class_getWeakIvarLayout(Class cls)
|
||||
{
|
||||
assert(0 && "Weak ivars not supported");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL class_isMetaClass(Class cls)
|
||||
BOOL
|
||||
class_isMetaClass(Class cls)
|
||||
{
|
||||
return CLS_ISMETA(cls);
|
||||
}
|
||||
|
||||
IMP class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)
|
||||
IMP
|
||||
class_replaceMethod(Class cls, SEL name, IMP imp, const char *types)
|
||||
{
|
||||
Method method = class_getInstanceMethodNonrecursive(cls, name);
|
||||
IMP old;
|
||||
|
||||
if (method == NULL)
|
||||
{
|
||||
class_addMethod(cls, name, imp, types);
|
||||
return NULL;
|
||||
}
|
||||
IMP old = (IMP)method->method_imp;
|
||||
old = (IMP)method->method_imp;
|
||||
method->method_imp = (objc_imp_gnu)imp;
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
BOOL class_respondsToSelector(Class cls, SEL sel)
|
||||
BOOL
|
||||
class_respondsToSelector(Class cls, SEL sel)
|
||||
{
|
||||
return __objc_responds_to(cls, sel);
|
||||
}
|
||||
|
||||
void class_setIvarLayout(Class cls, const char *layout)
|
||||
void
|
||||
class_setIvarLayout(Class cls, const char *layout)
|
||||
{
|
||||
struct objc_ivar_list *list = (struct objc_ivar_list*)layout;
|
||||
size_t listsize = sizeof(struct objc_ivar_list) +
|
||||
|
@ -449,57 +521,76 @@ void class_setIvarLayout(Class cls, const char *layout)
|
|||
}
|
||||
|
||||
__attribute__((deprecated))
|
||||
Class class_setSuperclass(Class cls, Class newSuper)
|
||||
Class
|
||||
class_setSuperclass(Class cls, Class newSuper)
|
||||
{
|
||||
Class oldSuper = cls->super_class;
|
||||
cls->super_class = newSuper;
|
||||
return oldSuper;
|
||||
}
|
||||
|
||||
void class_setVersion(Class theClass, int version)
|
||||
void
|
||||
class_setVersion(Class theClass, int version)
|
||||
{
|
||||
class_set_version(theClass, version);
|
||||
}
|
||||
|
||||
void class_setWeakIvarLayout(Class cls, const char *layout)
|
||||
void
|
||||
class_setWeakIvarLayout(Class cls, const char *layout)
|
||||
{
|
||||
assert(0 && "Not implemented");
|
||||
}
|
||||
|
||||
const char * ivar_getName(Ivar ivar)
|
||||
const char *
|
||||
ivar_getName(Ivar ivar)
|
||||
{
|
||||
return ivar->ivar_name;
|
||||
}
|
||||
|
||||
ptrdiff_t ivar_getOffset(Ivar ivar)
|
||||
ptrdiff_t
|
||||
ivar_getOffset(Ivar ivar)
|
||||
{
|
||||
return ivar->ivar_offset;
|
||||
}
|
||||
|
||||
const char * ivar_getTypeEncoding(Ivar ivar)
|
||||
const char *
|
||||
ivar_getTypeEncoding(Ivar ivar)
|
||||
{
|
||||
return ivar->ivar_type;
|
||||
}
|
||||
|
||||
static size_t lengthOfTypeEncoding(const char *types)
|
||||
static size_t
|
||||
lengthOfTypeEncoding(const char *types)
|
||||
{
|
||||
const char *end = objc_skip_argspec(types);
|
||||
size_t length;
|
||||
|
||||
end--;
|
||||
while (isdigit(*end)) { end--; }
|
||||
size_t length = end - types + 1;
|
||||
while (isdigit(*end))
|
||||
{
|
||||
end--;
|
||||
}
|
||||
length = end - types + 1;
|
||||
return length;
|
||||
}
|
||||
static char *copyTypeEncoding(const char *types)
|
||||
|
||||
static char *
|
||||
copyTypeEncoding(const char *types)
|
||||
{
|
||||
size_t length = lengthOfTypeEncoding(types);
|
||||
char *copy = malloc(length + 1);
|
||||
|
||||
memcpy(copy, types, length);
|
||||
copy[length] = '\0';
|
||||
return copy;
|
||||
}
|
||||
static const char * findParameterStart(const char *types, unsigned int index)
|
||||
|
||||
static const char *
|
||||
findParameterStart(const char *types, unsigned int index)
|
||||
{
|
||||
for (unsigned int i=0 ; i<index ; i++)
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < index; i++)
|
||||
{
|
||||
types = objc_skip_argspec(types);
|
||||
if ('\0' == *types)
|
||||
|
@ -510,9 +601,11 @@ static const char * findParameterStart(const char *types, unsigned int index)
|
|||
return types;
|
||||
}
|
||||
|
||||
char * method_copyArgumentType(Method method, unsigned int index)
|
||||
char *
|
||||
method_copyArgumentType(Method method, unsigned int index)
|
||||
{
|
||||
const char *types = findParameterStart(method->method_types, index);
|
||||
|
||||
if (NULL == types)
|
||||
{
|
||||
return NULL;
|
||||
|
@ -520,31 +613,39 @@ char * method_copyArgumentType(Method method, unsigned int index)
|
|||
return copyTypeEncoding(types);
|
||||
}
|
||||
|
||||
char * method_copyReturnType(Method method)
|
||||
char *
|
||||
method_copyReturnType(Method method)
|
||||
{
|
||||
return copyTypeEncoding(method->method_types);
|
||||
}
|
||||
|
||||
void method_exchangeImplementations(Method m1, Method m2)
|
||||
void
|
||||
method_exchangeImplementations(Method m1, Method m2)
|
||||
{
|
||||
IMP tmp = (IMP)m1->method_imp;
|
||||
|
||||
m1->method_imp = m2->method_imp;
|
||||
m2->method_imp = (objc_imp_gnu)tmp;
|
||||
objc_updateDtableForClassContainingMethod(m1);
|
||||
objc_updateDtableForClassContainingMethod(m2);
|
||||
}
|
||||
void method_getArgumentType(Method method,
|
||||
|
||||
void
|
||||
method_getArgumentType(Method method,
|
||||
unsigned int index,
|
||||
char *dst,
|
||||
size_t dst_len)
|
||||
{
|
||||
const char *types = findParameterStart(method->method_types, index);
|
||||
const char *types;
|
||||
size_t length;
|
||||
|
||||
types = findParameterStart(method->method_types, index);
|
||||
if (NULL == types)
|
||||
{
|
||||
strncpy(dst, "", dst_len);
|
||||
return;
|
||||
}
|
||||
size_t length = lengthOfTypeEncoding(types);
|
||||
length = lengthOfTypeEncoding(types);
|
||||
if (length < dst_len)
|
||||
{
|
||||
memcpy(dst, types, length);
|
||||
|
@ -556,20 +657,24 @@ void method_getArgumentType(Method method,
|
|||
}
|
||||
}
|
||||
|
||||
IMP method_getImplementation(Method method)
|
||||
IMP
|
||||
method_getImplementation(Method method)
|
||||
{
|
||||
return (IMP)method->method_imp;
|
||||
}
|
||||
|
||||
SEL method_getName(Method method)
|
||||
SEL
|
||||
method_getName(Method method)
|
||||
{
|
||||
return method->method_name;
|
||||
}
|
||||
|
||||
unsigned method_getNumberOfArguments(Method method)
|
||||
unsigned
|
||||
method_getNumberOfArguments(Method method)
|
||||
{
|
||||
const char *types = method->method_types;
|
||||
unsigned int count = 0;
|
||||
|
||||
while('\0' != *types)
|
||||
{
|
||||
types = objc_skip_argspec(types);
|
||||
|
@ -578,11 +683,13 @@ unsigned method_getNumberOfArguments(Method method)
|
|||
return count - 1;
|
||||
}
|
||||
|
||||
void method_getReturnType(Method method, char *dst, size_t dst_len)
|
||||
void
|
||||
method_getReturnType(Method method, char *dst, size_t dst_len)
|
||||
{
|
||||
//TODO: Coped and pasted code. Factor it out.
|
||||
const char *types = method->method_types;
|
||||
size_t length = lengthOfTypeEncoding(types);
|
||||
|
||||
if (length < dst_len)
|
||||
{
|
||||
memcpy(dst, types, length);
|
||||
|
@ -594,27 +701,33 @@ void method_getReturnType(Method method, char *dst, size_t dst_len)
|
|||
}
|
||||
}
|
||||
|
||||
const char * method_getTypeEncoding(Method method)
|
||||
const char *
|
||||
method_getTypeEncoding(Method method)
|
||||
{
|
||||
return method->method_types;
|
||||
}
|
||||
|
||||
IMP method_setImplementation(Method method, IMP imp)
|
||||
IMP
|
||||
method_setImplementation(Method method, IMP imp)
|
||||
{
|
||||
IMP old = (IMP)method->method_imp;
|
||||
|
||||
method->method_imp = (objc_imp_gnu)old;
|
||||
objc_updateDtableForClassContainingMethod(method);
|
||||
return old;
|
||||
}
|
||||
|
||||
id objc_getClass(const char *name)
|
||||
id
|
||||
objc_getClass(const char *name)
|
||||
{
|
||||
return (id)objc_get_class(name);
|
||||
}
|
||||
|
||||
int objc_getClassList(Class *buffer, int bufferLen)
|
||||
int
|
||||
objc_getClassList(Class *buffer, int bufferLen)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
if (buffer == NULL)
|
||||
{
|
||||
void *state = NULL;
|
||||
|
@ -627,6 +740,7 @@ int objc_getClassList(Class *buffer, int bufferLen)
|
|||
{
|
||||
Class nextClass;
|
||||
void *state = NULL;
|
||||
|
||||
while (Nil != (nextClass = objc_next_class(&state)) && bufferLen > 0)
|
||||
{
|
||||
count++;
|
||||
|
@ -637,15 +751,18 @@ int objc_getClassList(Class *buffer, int bufferLen)
|
|||
return count;
|
||||
}
|
||||
|
||||
id objc_getMetaClass(const char *name)
|
||||
id
|
||||
objc_getMetaClass(const char *name)
|
||||
{
|
||||
Class cls = (Class)objc_getClass(name);
|
||||
return cls == Nil ? nil : (id)cls->class_pointer;
|
||||
}
|
||||
|
||||
id objc_getRequiredClass(const char *name)
|
||||
id
|
||||
objc_getRequiredClass(const char *name)
|
||||
{
|
||||
id cls = objc_getClass(name);
|
||||
|
||||
if (nil == cls)
|
||||
{
|
||||
abort();
|
||||
|
@ -653,35 +770,48 @@ id objc_getRequiredClass(const char *name)
|
|||
return cls;
|
||||
}
|
||||
|
||||
id objc_lookUpClass(const char *name)
|
||||
id
|
||||
objc_lookUpClass(const char *name)
|
||||
{
|
||||
// TODO: Check these are the right way around.
|
||||
return (id)objc_lookup_class(name);
|
||||
}
|
||||
|
||||
static void freeMethodLists(Class aClass)
|
||||
static void
|
||||
freeMethodLists(Class aClass)
|
||||
{
|
||||
struct objc_method_list *methods = aClass->methods;
|
||||
while(methods != NULL)
|
||||
struct objc_method_list *current;
|
||||
|
||||
while (methods != NULL)
|
||||
{
|
||||
for (int i=0 ; i<methods->method_count ; i++)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < methods->method_count; i++)
|
||||
{
|
||||
free((void*)methods->method_list[i].method_types);
|
||||
}
|
||||
struct objc_method_list *current = methods;
|
||||
current = methods;
|
||||
methods = methods->method_next;
|
||||
free(current);
|
||||
}
|
||||
}
|
||||
|
||||
static void freeIvarLists(Class aClass)
|
||||
static void
|
||||
freeIvarLists(Class aClass)
|
||||
{
|
||||
struct objc_ivar_list *ivarlist = aClass->ivars;
|
||||
if (NULL == ivarlist) { return; }
|
||||
int i;
|
||||
|
||||
for (int i=0 ; i<ivarlist->ivar_count ; i++)
|
||||
if (NULL == ivarlist)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < ivarlist->ivar_count; i++)
|
||||
{
|
||||
Ivar ivar = &ivarlist->ivar_list[i];
|
||||
|
||||
free((void*)ivar->ivar_type);
|
||||
free((void*)ivar->ivar_name);
|
||||
}
|
||||
|
@ -692,9 +822,11 @@ static void freeIvarLists(Class aClass)
|
|||
* Removes a class from the subclass list found on its super class.
|
||||
* Must be called with the objc runtime mutex locked.
|
||||
*/
|
||||
static inline void safe_remove_from_subclass_list(Class cls)
|
||||
static inline void
|
||||
safe_remove_from_subclass_list(Class cls)
|
||||
{
|
||||
Class sub = cls->super_class->subclass_list;
|
||||
|
||||
if (sub == cls)
|
||||
{
|
||||
cls->super_class->subclass_list = cls->sibling_class;
|
||||
|
@ -713,9 +845,11 @@ static inline void safe_remove_from_subclass_list(Class cls)
|
|||
}
|
||||
}
|
||||
|
||||
void objc_disposeClassPair(Class cls)
|
||||
void
|
||||
objc_disposeClassPair(Class cls)
|
||||
{
|
||||
Class meta = ((id)cls)->isa;
|
||||
|
||||
// Remove from the runtime system so nothing tries updating the dtable
|
||||
// while we are freeing the class.
|
||||
objc_mutex_lock(__objc_runtime_mutex);
|
||||
|
@ -733,17 +867,27 @@ void objc_disposeClassPair(Class cls)
|
|||
free(cls);
|
||||
}
|
||||
|
||||
Class objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes)
|
||||
Class
|
||||
objc_allocateClassPair(Class superclass, const char *name, size_t extraBytes)
|
||||
{
|
||||
Class newClass;
|
||||
Class metaClass;
|
||||
|
||||
// Check the class doesn't already exist.
|
||||
if (nil != objc_lookUpClass(name)) { return Nil; }
|
||||
if (nil != objc_lookUpClass(name))
|
||||
{
|
||||
return Nil;
|
||||
}
|
||||
|
||||
Class newClass = calloc(1, sizeof(struct objc_class) + extraBytes);
|
||||
newClass = calloc(1, sizeof(struct objc_class) + extraBytes);
|
||||
|
||||
if (Nil == newClass) { return Nil; }
|
||||
if (Nil == newClass)
|
||||
{
|
||||
return Nil;
|
||||
}
|
||||
|
||||
// Create the metaclass
|
||||
Class metaClass = calloc(1, sizeof(struct objc_class));
|
||||
metaClass = calloc(1, sizeof(struct objc_class));
|
||||
|
||||
// Initialize the metaclass
|
||||
metaClass->class_pointer = superclass->class_pointer->class_pointer;
|
||||
|
@ -766,7 +910,8 @@ Class objc_allocateClassPair(Class superclass, const char *name, size_t extraByt
|
|||
return newClass;
|
||||
}
|
||||
|
||||
void *object_getIndexedIvars(id obj)
|
||||
void *
|
||||
object_getIndexedIvars(id obj)
|
||||
{
|
||||
if (class_isMetaClass(obj->isa))
|
||||
{
|
||||
|
@ -775,7 +920,8 @@ void *object_getIndexedIvars(id obj)
|
|||
return ((char*)obj) + obj->isa->instance_size;
|
||||
}
|
||||
|
||||
Class object_getClass(id obj)
|
||||
Class
|
||||
object_getClass(id obj)
|
||||
{
|
||||
if (nil != obj)
|
||||
{
|
||||
|
@ -784,18 +930,21 @@ Class object_getClass(id obj)
|
|||
return Nil;
|
||||
}
|
||||
|
||||
Class object_setClass(id obj, Class cls)
|
||||
Class
|
||||
object_setClass(id obj, Class cls)
|
||||
{
|
||||
if (nil != obj)
|
||||
{
|
||||
Class oldClass = obj->isa;
|
||||
|
||||
obj->isa = cls;
|
||||
return oldClass;
|
||||
}
|
||||
return Nil;
|
||||
}
|
||||
|
||||
const char *object_getClassName(id obj)
|
||||
const char *
|
||||
object_getClassName(id obj)
|
||||
{
|
||||
return class_getName(object_getClass(obj));
|
||||
}
|
||||
|
@ -803,7 +952,8 @@ const char *object_getClassName(id obj)
|
|||
void __objc_add_class_to_hash(Class cls);
|
||||
void __objc_resolve_class_links(void);
|
||||
|
||||
void objc_registerClassPair(Class cls)
|
||||
void
|
||||
objc_registerClassPair(Class cls)
|
||||
{
|
||||
Class metaClass = cls->class_pointer;
|
||||
|
||||
|
@ -815,44 +965,53 @@ void objc_registerClassPair(Class cls)
|
|||
__objc_resolve_class_links();
|
||||
}
|
||||
|
||||
static id objectNew(id cls)
|
||||
static id
|
||||
objectNew(id cls)
|
||||
{
|
||||
static SEL newSel = NULL;
|
||||
IMP newIMP;
|
||||
|
||||
if (NULL == newSel)
|
||||
{
|
||||
newSel = sel_get_uid("new");
|
||||
}
|
||||
IMP newIMP = (IMP)objc_msg_lookup((void*)cls, newSel);
|
||||
newIMP = (IMP)objc_msg_lookup((void*)cls, newSel);
|
||||
return newIMP((id)cls, newSel);
|
||||
}
|
||||
|
||||
Protocol *objc_getProtocol(const char *name)
|
||||
Protocol *
|
||||
objc_getProtocol(const char *name)
|
||||
{
|
||||
// Protocols are not centrally registered in the GNU runtime.
|
||||
Protocol *protocol = (Protocol*)(objectNew(objc_getClass("Protocol")));
|
||||
|
||||
protocol->protocol_name = (char*)name;
|
||||
return protocol;
|
||||
}
|
||||
|
||||
BOOL protocol_conformsToProtocol(Protocol *p, Protocol *other)
|
||||
BOOL
|
||||
protocol_conformsToProtocol(Protocol *p, Protocol *other)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
struct objc_method_description *protocol_copyMethodDescriptionList(Protocol *p,
|
||||
struct objc_method_description *
|
||||
protocol_copyMethodDescriptionList(Protocol *p,
|
||||
BOOL isRequiredMethod, BOOL isInstanceMethod, unsigned int *count)
|
||||
{
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Protocol **protocol_copyProtocolList(Protocol *p, unsigned int *count)
|
||||
Protocol **
|
||||
protocol_copyProtocolList(Protocol *p, unsigned int *count)
|
||||
{
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *protocol_getName(Protocol *p)
|
||||
const char *
|
||||
protocol_getName(Protocol *p)
|
||||
{
|
||||
if (NULL != p)
|
||||
{
|
||||
|
@ -861,37 +1020,41 @@ const char *protocol_getName(Protocol *p)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
BOOL protocol_isEqual(Protocol *p, Protocol *other)
|
||||
BOOL
|
||||
protocol_isEqual(Protocol *p, Protocol *other)
|
||||
{
|
||||
if (NULL == p || NULL == other)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
if (p == other ||
|
||||
0 == strcmp(p->protocol_name, other->protocol_name))
|
||||
if (p == other
|
||||
|| 0 == strcmp(p->protocol_name, other->protocol_name))
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
const char *sel_getName(SEL sel)
|
||||
const char *
|
||||
sel_getName(SEL sel)
|
||||
{
|
||||
return sel_get_name(sel);
|
||||
}
|
||||
|
||||
SEL sel_getUid(const char *selName)
|
||||
SEL
|
||||
sel_getUid(const char *selName)
|
||||
{
|
||||
return sel_get_uid(selName);
|
||||
}
|
||||
|
||||
BOOL sel_isEqual(SEL sel1, SEL sel2)
|
||||
BOOL
|
||||
sel_isEqual(SEL sel1, SEL sel2)
|
||||
{
|
||||
// FIXME: Is this correct?
|
||||
return (0 == strcmp(sel_get_name(sel1), sel_get_name(sel2)));
|
||||
return sel_eq(sel1, sel2) ? YES : NO;
|
||||
}
|
||||
|
||||
SEL sel_registerName(const char *selName)
|
||||
SEL
|
||||
sel_registerName(const char *selName)
|
||||
{
|
||||
return sel_register_name(selName);
|
||||
}
|
||||
|
|
|
@ -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,44 +20,53 @@ 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);
|
||||
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);
|
||||
} 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
|
||||
Class lastClass;
|
||||
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);
|
||||
} while (Nil != object.isa
|
||||
&& objc_msg_lookup((id)&object, dealloc) == (IMP)deallocLockClass);
|
||||
return lastClass;
|
||||
}
|
||||
|
||||
static inline Class initLockObject(id obj)
|
||||
static inline Class
|
||||
initLockObject(id obj)
|
||||
{
|
||||
char nameBuffer[40];
|
||||
Class lockClass;
|
||||
const char *types;
|
||||
pthread_mutex_t *lock;
|
||||
|
||||
snprintf(nameBuffer, 39, "hiddenlockClass%lld", lockClassId++);
|
||||
Class lockClass = objc_allocateClassPair(obj->isa, nameBuffer,
|
||||
lockClass = objc_allocateClassPair(obj->isa, nameBuffer,
|
||||
sizeof(pthread_mutex_t));
|
||||
const char *types =
|
||||
method_getTypeEncoding(class_getInstanceMethod(obj->isa,
|
||||
types = method_getTypeEncoding(class_getInstanceMethod(obj->isa,
|
||||
@selector(dealloc)));
|
||||
class_addMethod(lockClass, @selector(dealloc), (IMP)deallocLockClass,
|
||||
types);
|
||||
class_addMethod(lockClass, @selector(dealloc), (IMP)deallocLockClass, types);
|
||||
objc_registerClassPair(lockClass);
|
||||
|
||||
pthread_mutex_t *lock = object_getIndexedIvars(lockClass);
|
||||
lock = object_getIndexedIvars(lockClass);
|
||||
pthread_mutexattr_t attr;
|
||||
pthread_mutexattr_init(&attr);
|
||||
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
||||
|
@ -68,12 +77,14 @@ static inline Class initLockObject(id obj)
|
|||
return lockClass;
|
||||
}
|
||||
|
||||
static void deallocLockClass(id obj, SEL _cmd)
|
||||
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);
|
||||
|
@ -82,9 +93,12 @@ static void deallocLockClass(id obj, SEL _cmd)
|
|||
[obj dealloc];
|
||||
}
|
||||
|
||||
void objc_sync_enter(id obj)
|
||||
void
|
||||
objc_sync_enter(id obj)
|
||||
{
|
||||
Class lockClass = findLockClass(obj);
|
||||
pthread_mutex_t *lock;
|
||||
|
||||
if (Nil == lockClass)
|
||||
{
|
||||
pthread_mutex_lock(&at_sync_init_lock);
|
||||
|
@ -96,10 +110,12 @@ void objc_sync_enter(id obj)
|
|||
}
|
||||
pthread_mutex_unlock(&at_sync_init_lock);
|
||||
}
|
||||
pthread_mutex_t *lock = object_getIndexedIvars(lockClass);
|
||||
lock = object_getIndexedIvars(lockClass);
|
||||
pthread_mutex_lock(lock);
|
||||
}
|
||||
void objc_sync_exit(id obj)
|
||||
|
||||
void
|
||||
objc_sync_exit(id obj)
|
||||
{
|
||||
Class lockClass = findLockClass(obj);
|
||||
pthread_mutex_t *lock = object_getIndexedIvars(lockClass);
|
||||
|
|
|
@ -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
115
configure
vendored
|
@ -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
|
||||
|
|
11
configure.ac
11
configure.ac
|
@ -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
|
||||
|
||||
#--------------------------------------------------------------------
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue