mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 00:41:02 +00:00
Correctly call C++ constructors / destructors for C++ 'objects' in ObjC++ ivars.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@32632 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
58e3acf804
commit
644bda0ad8
1 changed files with 66 additions and 1 deletions
|
@ -648,6 +648,39 @@ GSObjCZone(NSObject *object)
|
|||
return ((obj)object)[-1].zone;
|
||||
}
|
||||
|
||||
static SEL cxx_construct, cxx_destruct;
|
||||
|
||||
/**
|
||||
* Calls the C++ constructors for this object, starting with the ones declared
|
||||
* in aClass. The compiler generates two methods on Objective-C++ classes that
|
||||
* static instances of C++ classes as ivars. These are -.cxx_construct and
|
||||
* -.cxx_destruct. The -.cxx_construct methods must be called in order from
|
||||
* the root class to all subclasses, to ensure that subclass ivars are
|
||||
* initialised after superclass ones. This must be done in reverse for
|
||||
* destruction.
|
||||
*
|
||||
* This function first calls itself recursively on the superclass, to get the
|
||||
* IMP for the constructor function in the superclass. It then compares the
|
||||
* construct method for this class with the one that's already been called,
|
||||
* and calls it if it's new.
|
||||
*/
|
||||
static IMP callCXXConstructors(Class aClass, id anObject)
|
||||
{
|
||||
IMP constructor = 0;
|
||||
|
||||
if (class_respondsToSelector(aClass, cxx_construct))
|
||||
{
|
||||
IMP calledConstructor =
|
||||
callCXXConstructors(class_getSuperclass(aClass), anObject);
|
||||
constructor = class_getMethodImplementation(aClass, cxx_construct);
|
||||
if (calledConstructor != constructor)
|
||||
{
|
||||
constructor(anObject, cxx_construct);
|
||||
}
|
||||
}
|
||||
return constructor;
|
||||
}
|
||||
|
||||
inline id
|
||||
NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone *zone)
|
||||
{
|
||||
|
@ -669,16 +702,48 @@ NSAllocateObject (Class aClass, NSUInteger extraBytes, NSZone *zone)
|
|||
object_setClass(new, aClass);
|
||||
AADD(aClass, new);
|
||||
}
|
||||
// Don't bother doing this in a thread-safe way, because the cost of locking
|
||||
// will be a lot more than the cost of doing the same call in two threads.
|
||||
// The returned selector will persist and the runtime will ensure that both
|
||||
// calls return the same selector, so we don't need to bother doing it
|
||||
// ourselves.
|
||||
if (0 == cxx_construct)
|
||||
{
|
||||
cxx_construct = sel_registerName(".cxx_construct");
|
||||
cxx_destruct = sel_registerName(".cxx_destruct");
|
||||
}
|
||||
callCXXConstructors(aClass, new);
|
||||
return new;
|
||||
}
|
||||
|
||||
inline void
|
||||
NSDeallocateObject(id anObject)
|
||||
{
|
||||
if ((anObject!=nil) && !class_isMetaClass(object_getClass((id)anObject)))
|
||||
Class aClass = object_getClass(anObject);
|
||||
if ((anObject!=nil) && !class_isMetaClass(aClass))
|
||||
{
|
||||
obj o = &((obj)anObject)[-1];
|
||||
NSZone *z = o->zone;
|
||||
Class destructorClass = aClass;
|
||||
IMP destructor = 0;
|
||||
|
||||
// C++ destructors must be called in the opposite order to their
|
||||
// creators, so start at the leaf class and then go up the tree until we
|
||||
// get to the root class. As a small optimisation, we don't bother
|
||||
// visiting any classes that don't have an implementation of this method
|
||||
// (including one inherited from a superclass).
|
||||
//
|
||||
// Care must be taken not to call inherited .cxx_destruct methods.
|
||||
while (class_respondsToSelector(destructorClass, cxx_destruct))
|
||||
{
|
||||
IMP newDestructor = class_getMethodImplementation(destructorClass, cxx_destruct);
|
||||
if (newDestructor != destructor)
|
||||
{
|
||||
newDestructor(anObject, cxx_destruct);
|
||||
destructor = newDestructor;
|
||||
}
|
||||
destructorClass = class_getSuperclass(destructorClass);
|
||||
}
|
||||
|
||||
AREM(object_getClass((id)anObject), (id)anObject);
|
||||
if (NSZombieEnabled == YES)
|
||||
|
|
Loading…
Reference in a new issue