ObjFW  Check-in [1ecef2d7f6]

Overview
Comment:ObjFW-RT: Call +[unload] on class unregister
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 1ecef2d7f6094eb96bc9b6e52de43ac30d2d7395528d6387b1d5d6e0862e4807
User & Date: js on 2014-03-30 00:30:35
Other Links: manifest | tags
Context
2014-04-06
14:40
runtime/hashtable.m: Add support for deletion check-in: c2d9134d88 user: js tags: trunk
2014-03-30
00:30
ObjFW-RT: Call +[unload] on class unregister check-in: 1ecef2d7f6 user: js tags: trunk
2014-03-23
00:17
Add -Wobjc-property-synthesis check-in: 372e6283c7 user: js tags: trunk
Changes

Modified src/OFObject.h from [9b4e14f514] to [2a79ae4f27].

429
430
431
432
433
434
435
436
437
438
439
440














441
442
443
444
445
446
447
	Class _isa;
}

/*!
 * @brief A method which is called once when the class is loaded into the
 *	  runtime.
 *
 * Derived classes can overide this to execute their own code when the class is
 * loaded.
 */
+ (void)load;















/*!
 * @brief A method which is called the moment before the first call to the class
 *	  is being made.
 *
 * Derived classes can override this to execute their own code on
 * initialization. They should make sure to not execute any code if self is not
 * the class itself, as it might happen that the method was called for a







|
|



>
>
>
>
>
>
>
>
>
>
>
>
>
>







429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
	Class _isa;
}

/*!
 * @brief A method which is called once when the class is loaded into the
 *	  runtime.
 *
 * Derived classes can override this to execute their own code when the class
 * is loaded.
 */
+ (void)load;

/*!
 * @brief A method which is called when the class is unloaded from the runtime.
 *
 * Derived classes can override this to execute their own code when the class
 * is unloaded.
 *
 * @warning This is not supported by the Apple runtime and currently only
 *	    called by the ObjFW runtime when objc_unregister_class() or
 *	    objc_exit() has been called!
 *	    In the future, this might also be called by the ObjFW runtime when
 *	    the class is part of a plugin that has been unloaded.
 */
+ (void)unload;

/*!
 * @brief A method which is called the moment before the first call to the class
 *	  is being made.
 *
 * Derived classes can override this to execute their own code on
 * initialization. They should make sure to not execute any code if self is not
 * the class itself, as it might happen that the method was called for a

Modified src/OFObject.m from [f4d9610474] to [f3bed53382].

239
240
241
242
243
244
245




246
247
248
249
250
251
252
#else
	struct timeval t;
	gettimeofday(&t, NULL);
	srand((unsigned)(t.tv_sec ^ t.tv_usec));
	of_hash_seed = (uint32_t)((rand() << 16) | (rand() & 0xFFFF));
#endif
}





+ (void)initialize
{
}

+ alloc
{







>
>
>
>







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
#else
	struct timeval t;
	gettimeofday(&t, NULL);
	srand((unsigned)(t.tv_sec ^ t.tv_usec));
	of_hash_seed = (uint32_t)((rand() << 16) | (rand() & 0xFFFF));
#endif
}

+ (void)unload
{
}

+ (void)initialize
{
}

+ alloc
{

Modified src/runtime/class.m from [91fb9724fc] to [6289471667].

241
242
243
244
245
246
247
248


249
250

251
252
253
254
255
256
257
				for (j = 0; j < ml->count; j++)
					objc_sparsearray_set(cls->dtable,
					    (uint32_t)ml->methods[j].sel.uid,
					    ml->methods[j].imp);
		}
	}

	if (cls->subclass_list != NULL)


		for (i = 0; cls->subclass_list[i] != NULL; i++)
			objc_update_dtable(cls->subclass_list[i]);

}

static void
add_subclass(Class cls)
{
	size_t i;








|
>
>
|
|
>







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
				for (j = 0; j < ml->count; j++)
					objc_sparsearray_set(cls->dtable,
					    (uint32_t)ml->methods[j].sel.uid,
					    ml->methods[j].imp);
		}
	}

	if (cls->subclass_list != NULL) {
		Class *iter;

		for (iter = cls->subclass_list; *iter != NULL; iter++)
			objc_update_dtable(*iter);
	}
}

static void
add_subclass(Class cls)
{
	size_t i;

806
807
808
809
810
811
812

























813
814
815
816
817
818
819
820
821
822
823
824
825


826
827
828
829
830






831
832
833
834
835
836
837
838
839
840
	return class_getName(object_getClass(obj));
}

static void
unregister_class(Class rcls)
{
	struct objc_abi_class *cls = (struct objc_abi_class*)rcls;


























	if (rcls->subclass_list != NULL) {
		free(rcls->subclass_list);
		rcls->subclass_list = NULL;
	}

	if (rcls->dtable != NULL && rcls->dtable != empty_dtable)
		objc_sparsearray_free(rcls->dtable);

	rcls->dtable = NULL;

	if (rcls->superclass != Nil)
		cls->superclass = rcls->superclass->name;


}

void
objc_unregister_class(Class cls)
{






	objc_hashtable_set(classes, cls->name, NULL);

	if (strcmp(cls->name, "Protocol"))
		classes_cnt--;

	unregister_class(cls);
	unregister_class(cls->isa);
}

static void







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>













>
>





>
>
>
>
>
>


|







809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
	return class_getName(object_getClass(obj));
}

static void
unregister_class(Class rcls)
{
	struct objc_abi_class *cls = (struct objc_abi_class*)rcls;

	if ((rcls->info & OBJC_CLASS_INFO_SETUP) &&
	    rcls->superclass != Nil &&
	    rcls->superclass->subclass_list != NULL) {
		size_t i = SIZE_MAX, count = 0;
		Class *tmp;

		for (tmp = rcls->superclass->subclass_list;
		    *tmp != Nil; tmp++) {
			if (*tmp == rcls)
				i = count;

			count++;
		}

		if (count > 0 && i < SIZE_MAX) {
			tmp = rcls->superclass->subclass_list;
			tmp[i] = tmp[count - 1];
			tmp[count - 1] = NULL;

			if ((tmp = realloc(rcls->superclass->subclass_list,
			    count * sizeof(Class))) != NULL)
				rcls->superclass->subclass_list = tmp;
		}
	}

	if (rcls->subclass_list != NULL) {
		free(rcls->subclass_list);
		rcls->subclass_list = NULL;
	}

	if (rcls->dtable != NULL && rcls->dtable != empty_dtable)
		objc_sparsearray_free(rcls->dtable);

	rcls->dtable = NULL;

	if (rcls->superclass != Nil)
		cls->superclass = rcls->superclass->name;

	rcls->info &= ~OBJC_CLASS_INFO_SETUP;
}

void
objc_unregister_class(Class cls)
{
	while (cls->subclass_list != NULL && cls->subclass_list[0] != Nil)
		objc_unregister_class(cls->subclass_list[0]);

	if (cls->info & OBJC_CLASS_INFO_LOADED)
		call_method(cls, "unload");

	objc_hashtable_set(classes, cls->name, NULL);

	if (strcmp(class_getName(cls), "Protocol"))
		classes_cnt--;

	unregister_class(cls);
	unregister_class(cls->isa);
}

static void