Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -263,10 +263,14 @@ ], [ AC_MSG_ERROR([libobjc not found!]) ]) ;; esac + +AC_CHECK_FUNC(objc_constructInstance, [], [ + AC_SUBST(INSTANCE_M, "instance.m") +]) AC_CHECK_FUNC(objc_autoreleasePoolPush, [], [ AC_SUBST(AUTORELEASE_M, "autorelease.m") ]) Index: extra.mk.in ================================================================== --- extra.mk.in +++ extra.mk.in @@ -11,10 +11,11 @@ EXCEPTIONS_A = @EXCEPTIONS_A@ EXCEPTIONS_EXCEPTIONS_A = @EXCEPTIONS_EXCEPTIONS_A@ EXCEPTIONS_EXCEPTIONS_LIB_A = @EXCEPTIONS_EXCEPTIONS_LIB_A@ EXCEPTIONS_LIB_A = @EXCEPTIONS_LIB_A@ FOUNDATION_COMPAT_M = @FOUNDATION_COMPAT_M@ +INSTANCE_M = @INSTANCE_M@ LOOKUP_S = @LOOKUP_S@ MACH_ALIAS_LIST = @MACH_ALIAS_LIST@ OFBLOCKTESTS_M = @OFBLOCKTESTS_M@ OBJC_PROPERTIES_M = @OBJC_PROPERTIES_M@ OBJC_SYNC_M = @OBJC_SYNC_M@ Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -77,17 +77,19 @@ OFTLSSocket.h \ ObjFW.h \ asprintf.h \ autorelease.h \ ${ATOMIC_H} \ + instance.h \ macros.h \ objfw-defs.h \ ${THREADING_H} SRCS += OFArray_adjacent.m \ OFArray_adjacentSubarray.m \ ${AUTORELEASE_M} \ + ${INSTANCE_M} \ OFCountedSet_hashtable.m \ OFDictionary_hashtable.m \ OFMutableArray_adjacent.m \ OFMutableDictionary_hashtable.m \ OFMutableSet_hashtable.m \ Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -58,10 +58,11 @@ # include #endif #import "OFString.h" +#import "instance.h" #if defined(OF_ATOMIC_OPS) # import "atomic.h" #elif defined(OF_THREADS) # import "threading.h" #endif ADDED src/instance.h Index: src/instance.h ================================================================== --- src/instance.h +++ src/instance.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#ifdef __cplusplus +extern "C" { +#endif +extern id objc_constructInstance(Class, void*); +extern void* objc_destructInstance(id); +#ifdef __cplusplus +} +#endif ADDED src/instance.m Index: src/instance.m ================================================================== --- src/instance.m +++ src/instance.m @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFObject.h" + +static SEL cxx_construct = NULL; +static SEL cxx_destruct = NULL; + +static void __attribute__((constructor)) +init(void) +{ + if (cxx_construct == NULL) + cxx_construct = sel_registerName(".cxx_construct"); + if (cxx_destruct == NULL) + cxx_destruct = sel_registerName(".cxx_destruct"); +} + +id +objc_constructInstance(Class cls, void *bytes) +{ + id obj = (id)bytes; + BOOL (*last)(id, SEL) = NULL; + + if (cls == Nil || bytes == NULL) + return nil; + + object_setClass(obj, cls); + + /* FIXME: Constructors of superclasses should be called first */ + for (; cls != Nil; cls = class_getSuperclass(cls)) { + BOOL (*ctor)(id, SEL); + + if (class_respondsToSelector(cls, cxx_construct)) { + if ((ctor = (BOOL(*)(id, SEL)) + class_getMethodImplementation(cls, + cxx_construct)) != last) + if (!ctor(obj, cxx_construct)) + return nil; + + last = ctor; + } else + break; + } + + return obj; +} + +void* +objc_destructInstance(id obj) +{ + Class cls; + void (*last)(id, SEL) = NULL; + + for (cls = object_getClass(obj); cls != Nil; + cls = class_getSuperclass(cls)) { + void (*dtor)(id, SEL); + + if (class_respondsToSelector(cls, cxx_destruct)) { + if ((dtor = (void(*)(id, SEL)) + class_getMethodImplementation(cls, + cxx_destruct)) != last) + dtor(obj, cxx_destruct); + + last = dtor; + } else + break; + } + + return obj; +} Index: src/runtime/class.m ================================================================== --- src/runtime/class.m +++ src/runtime/class.m @@ -28,13 +28,10 @@ static struct objc_hashtable *classes = NULL; static Class *load_queue = NULL; static size_t load_queue_cnt = 0; static struct objc_sparsearray *empty_dtable = NULL; -static SEL cxx_construct = NULL; -static SEL cxx_destruct = NULL; - static void register_class(struct objc_abi_class *cls) { if (classes == NULL) classes = objc_hashtable_new(2); @@ -294,15 +291,10 @@ void objc_register_all_classes(struct objc_abi_symtab *symtab) { uint_fast32_t i; - if (cxx_construct == NULL) - cxx_construct = sel_registerName(".cxx_construct"); - if (cxx_destruct == NULL) - cxx_destruct = sel_registerName(".cxx_destruct"); - for (i = 0; i < symtab->cls_def_cnt; i++) { struct objc_abi_class *cls = (struct objc_abi_class*)symtab->defs[i]; register_class(cls); @@ -540,64 +532,10 @@ objc_global_mutex_unlock(); return (IMP)nil; } -id -objc_constructInstance(Class cls, void *bytes) -{ - id obj = (id)bytes; - BOOL (*last)(id, SEL) = NULL; - - if (cls == Nil || bytes == NULL) - return nil; - - object_setClass(obj, cls); - - /* FIXME: Constructors of superclasses should be called first */ - for (; cls != Nil; cls = class_getSuperclass(cls)) { - BOOL (*ctor)(id, SEL); - - if (class_respondsToSelector(cls, cxx_construct)) { - if ((ctor = (BOOL(*)(id, SEL)) - class_getMethodImplementation(cls, - cxx_construct)) != last) - if (!ctor(obj, cxx_construct)) - return nil; - - last = ctor; - } else - break; - } - - return obj; -} - -void* -objc_destructInstance(id obj) -{ - Class cls; - void (*last)(id, SEL) = NULL; - - for (cls = object_getClass(obj); cls != Nil; - cls = class_getSuperclass(cls)) { - void (*dtor)(id, SEL); - - if (class_respondsToSelector(cls, cxx_destruct)) { - if ((dtor = (void(*)(id, SEL)) - class_getMethodImplementation(cls, - cxx_destruct)) != last) - dtor(obj, cxx_destruct); - - last = dtor; - } else - break; - } - - return obj; -} - static void free_class(Class rcls) { struct objc_abi_class *cls = (struct objc_abi_class*)rcls;