Unregister classes when deleting them.

Coverage checking of the test suite showed that objc_disposeClassPair
wasn't tested at all, which then led to discovering that it didn't
unregister the class.
main
David Chisnall 8 years ago
parent 554c6623dc
commit a5a0f70a03

@ -31,6 +31,11 @@ int main()
e = objc_allocateClassPair(d, "E", 0); e = objc_allocateClassPair(d, "E", 0);
objc_registerClassPair(e); objc_registerClassPair(e);
assert(loaded == 0); assert(loaded == 0);
assert(objc_getClass("C") == c);
assert(objc_getClass("D") == d);
assert(objc_getClass("E") == e);
objc_disposeClassPair(e);
assert(objc_getClass("E") == nil);
return 0; return 0;
} }

@ -272,11 +272,18 @@ static inline BOOL objc_test_class_flag(struct objc_class *aClass,
return (aClass->info & (unsigned long)flag) == (unsigned long)flag; return (aClass->info & (unsigned long)flag) == (unsigned long)flag;
} }
/** /**
* Adds a class to the class table. * Adds a class to the class table.
*/ */
void class_table_insert(Class class); void class_table_insert(Class class);
/**
* Removes a class from the class table. Must be called with the runtime lock
* held!
*/
void class_table_remove(Class cls);
/** /**
* Array of classes used for small objects. Small objects are embedded in * Array of classes used for small objects. Small objects are embedded in
* their pointer. In 32-bit mode, we have one small object class (typically * their pointer. In 32-bit mode, we have one small object class (typically

@ -457,6 +457,12 @@ BOOL objc_registerSmallObjectClass_np(Class class, uintptr_t mask)
return YES; return YES;
} }
PRIVATE void class_table_remove(Class cls)
{
assert(objc_test_class_flag(cls, objc_class_flag_user_created));
class_table_internal_remove(class_table, (void*)cls->name);
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Public API // Public API

@ -719,6 +719,7 @@ void objc_disposeClassPair(Class cls)
LOCK_RUNTIME_FOR_SCOPE(); LOCK_RUNTIME_FOR_SCOPE();
safe_remove_from_subclass_list(meta); safe_remove_from_subclass_list(meta);
safe_remove_from_subclass_list(cls); safe_remove_from_subclass_list(cls);
class_table_remove(cls);
} }
// Free the method and ivar lists. // Free the method and ivar lists.

Loading…
Cancel
Save