ObjFW  Diff

Differences From Artifact [8bf9db28f4]:

To Artifact [c8cb26401f]:


663
664
665
666
667
668
669

















































670
671
672
673

674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690

691
692
693
694
695
696
697
698

699
700
701


702
703
704
705
706
707
708
709
710
711
712
713
714


















715
716
717
718
719

720
721
722
723
724
725

726
727
728

729
730
731


732
733
734
735
736
737
738
739
740
741
742
743
744

745
746
747
748
749
750
751
752


753
754
755

756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781

782
783
784
785
786
787
788
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721

722

723
724
725
726
727
728










729








730



731
732




733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763

764

765
766
767
768

769



770



771
772













773








774
775



776

777





















778
779

780
781
782
783
784
785
786
787







+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+



-
+
-






-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
-
-
-
+
+
-
-
-
-









+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+




-
+
-




-
+
-
-
-
+
-
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-
+
+
-
-
-
+
-

-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-


-
+







	if (cls == Nil)
		return NULL;

	dummy.isa = cls;
	return objc_msg_lookup_stret((id)&dummy, sel);
}

static struct objc_method*
get_method(Class cls, SEL sel)
{
	struct objc_method_list *ml;
	struct objc_category **cats;

	for (ml = cls->methodlist; ml != NULL; ml = ml->next)
		for (unsigned int i = 0; i < ml->count; i++)
			if (sel_isEqual((SEL)&ml->methods[i].sel, sel))
				return &ml->methods[i];

	if ((cats = objc_categories_for_class(cls)) != NULL) {
		for (; *cats != NULL; cats++) {
			if (cls->info & OBJC_CLASS_INFO_METACLASS)
				ml = (*cats)->class_methods;
			else
				ml = (*cats)->instance_methods;

			for (; ml != NULL; ml = ml->next)
				for (unsigned int i = 0; i < ml->count; i++)
					if (sel_isEqual(
					    (SEL)&ml->methods[i].sel, sel))
						return &ml->methods[i];
		}
	}

	return NULL;
}

static void
add_method(Class cls, SEL sel, IMP imp, const char *types)
{
	struct objc_method_list *ml;

	/* FIXME: We need a way to free this at objc_exit() */
	if ((ml = malloc(sizeof(struct objc_method_list))) == NULL)
		OBJC_ERROR("Not enough memory to replace method!");

	ml->next = cls->methodlist;
	ml->count = 1;
	ml->methods[0].sel.uid = sel->uid;
	ml->methods[0].sel.types = types;
	ml->methods[0].imp = imp;

	cls->methodlist = ml;

	objc_update_dtable(cls);
}

const char*
class_getMethodTypeEncoding(Class cls, SEL sel)
{
	struct objc_method_list *ml;
	struct objc_method *method;
	struct objc_category **cats;

	if (cls == Nil)
		return NULL;

	objc_global_mutex_lock();

	for (ml = cls->methodlist; ml != NULL; ml = ml->next) {
		for (unsigned int i = 0; i < ml->count; i++) {
			if (sel_isEqual((SEL)&ml->methods[i].sel, sel)) {
				const char *ret = ml->methods[i].sel.types;
				objc_global_mutex_unlock();
				return ret;
			}
		}
	}

	if ((method = get_method(cls, sel)) != NULL) {
	if ((cats = objc_categories_for_class(cls)) != NULL) {
		for (; *cats != NULL; cats++) {
			for (ml = (*cats)->instance_methods; ml != NULL;
			    ml = ml->next) {
				for (unsigned int i = 0; i < ml->count; i++) {
					if (ml->methods[i].sel.uid ==
					    sel->uid) {
						const char *ret =
		const char *ret = method->sel.types;
						    ml->methods[i].sel.types;
						objc_global_mutex_unlock();
						return ret;
		objc_global_mutex_unlock();
		return ret;
					}
				}
			}
		}
	}

	objc_global_mutex_unlock();

	if (cls->superclass != Nil)
		return class_getMethodTypeEncoding(cls->superclass, sel);

	return NULL;
}

bool
class_addMethod(Class cls, SEL sel, IMP imp, const char *types)
{
	bool ret;

	objc_global_mutex_lock();

	if (get_method(cls, sel) == NULL) {
		add_method(cls, sel, imp, types);
		ret = true;
	} else
		ret = false;

	objc_global_mutex_unlock();

	return ret;
}

IMP
class_replaceMethod(Class cls, SEL sel, IMP newimp, const char *types)
{
	struct objc_method_list *ml;
	struct objc_method *method;
	struct objc_category **cats;
	IMP oldimp;

	objc_global_mutex_lock();

	for (ml = cls->methodlist; ml != NULL; ml = ml->next) {
	if ((method = get_method(cls, sel)) != NULL) {
		for (unsigned int i = 0; i < ml->count; i++) {
			if (ml->methods[i].sel.uid == sel->uid) {
				oldimp = ml->methods[i].imp;
		oldimp = method->imp;

				ml->methods[i].imp = newimp;
				objc_update_dtable(cls);
		method->imp = newimp;
		objc_update_dtable(cls);

				objc_global_mutex_unlock();

				return oldimp;
			}
		}
	}

	if ((cats = objc_categories_for_class(cls)) != NULL) {
		for (; *cats != NULL; cats++) {
			if (cls->info & OBJC_CLASS_INFO_METACLASS)
				ml = (*cats)->class_methods;
			else
	} else {
				ml = (*cats)->instance_methods;

			for (; ml != NULL; ml = ml->next) {
				for (unsigned int i = 0; i < ml->count; i++) {
					if (ml->methods[i].sel.uid ==
					    sel->uid) {
						oldimp = ml->methods[i].imp;

		oldimp = NULL;
		add_method(cls, sel, newimp, types);
						ml->methods[i].imp = newimp;
						objc_update_dtable(cls);

	}
						objc_global_mutex_unlock();

						return oldimp;
					}
				}
			}
		}
	}

	/* FIXME: We need a way to free this at objc_exit() */
	if ((ml = malloc(sizeof(struct objc_method_list))) == NULL)
		OBJC_ERROR("Not enough memory to replace method!");

	ml->next = cls->methodlist;
	ml->count = 1;
	ml->methods[0].sel.uid = sel->uid;
	ml->methods[0].sel.types = types;
	ml->methods[0].imp = newimp;

	cls->methodlist = ml;

	objc_update_dtable(cls);

	objc_global_mutex_unlock();

	return NULL;
	return oldimp;
}

Class
object_getClass(id obj_)
{
	struct objc_object *obj;