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
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 overide this to execute their own code when the class is
 * loaded.
 * 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
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
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)
		for (i = 0; cls->subclass_list[i] != NULL; i++)
			objc_update_dtable(cls->subclass_list[i]);
	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
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(cls->name, "Protocol"))
	if (strcmp(class_getName(cls), "Protocol"))
		classes_cnt--;

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

static void