Patchwork libobjc/50002: Applied fix to 4.6 branch as well

login
register
mail settings
Submitter Nicola Pero
Date Oct. 14, 2011, 5:10 p.m.
Message ID <C2941E2D-8DDA-4E3D-882E-C9DF9FCB4A8E@meta-innovation.com>
Download mbox | patch
Permalink /patch/119859/
State New
Headers show

Comments

Nicola Pero - Oct. 14, 2011, 5:10 p.m.
I applied the following patch to the 4.6 branch to backport the fix for libobjc/50002.
It makes sense to backport it to 4.6.x so that it appears in 4.6.2.  It really is quite a bug,
and the fix is simple/safe (and, the ObjFW guys were particularly keen on it).

Thanks

Patch

Index: class.c
===================================================================
--- class.c     (revision 179967)
+++ class.c     (working copy)
@@ -850,35 +850,57 @@  __objc_update_classes_with_methods (struct objc_me
       
       while (node != NULL)
        {
-         /* Iterate over all methods in the class.  */
-         Class class = node->pointer;
-         struct objc_method_list * method_list = class->methods;
+         /* We execute this loop twice: the first time, we iterate
+            over all methods in the class (instance methods), while
+            the second time we iterate over all methods in the meta
+            class (class methods).  */
+         Class class = Nil;
+         BOOL done = NO;
 
-         while (method_list)
+         while (done == NO)
            {
-             int i;
+             struct objc_method_list * method_list;
 
-             for (i = 0; i < method_list->method_count; ++i)
+             if (class == Nil)
                {
-                 struct objc_method *method = &method_list->method_list[i];
+                 /* The first time, we work on the class.  */
+                 class = node->pointer;
+               }
+             else
+               {
+                 /* The second time, we work on the meta class.  */
+                 class = class->class_pointer;
+                 done = YES;
+               }
 
-                 /* If the method is one of the ones we are looking
-                    for, update the implementation.  */
-                 if (method == method_a)
-                   sarray_at_put_safe (class->dtable,
-                                       (sidx) method_a->method_name->sel_id,
-                                       method_a->method_imp);
+             method_list = class->methods;
 
-                 if (method == method_b)
+             while (method_list)
+               {
+                 int i;
+                 
+                 for (i = 0; i < method_list->method_count; ++i)
                    {
-                     if (method_b != NULL)
+                     struct objc_method *method = &method_list->method_list[i];
+                     
+                     /* If the method is one of the ones we are
+                        looking for, update the implementation.  */
+                     if (method == method_a)
                        sarray_at_put_safe (class->dtable,
-                                           (sidx) method_b->method_name->sel_id,
-                                           method_b->method_imp);
+                                           (sidx) method_a->method_name->sel_id,
+                                           method_a->method_imp);
+                     
+                     if (method == method_b)
+                       {
+                         if (method_b != NULL)
+                           sarray_at_put_safe (class->dtable,
+                                               (sidx) method_b->method_name->sel_id,
+                                               method_b->method_imp);
+                       }
                    }
+                 
+                 method_list = method_list->method_next;
                }
-         
-             method_list = method_list->method_next;
            }
          node = node->next;
        }
Index: ChangeLog
===================================================================
--- ChangeLog   (revision 179967)
+++ ChangeLog   (working copy)
@@ -1,3 +1,13 @@ 
+2011-10-14  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       Backport from mainline
+       2011-08-06  Nicola Pero  <nicola.pero@meta-innovation.com>
+
+       PR libobjc/50002
+       * class.c (__objc_update_classes_with_methods): Iterate over meta
+       classes as well as normal classes when refreshing the method
+       implementations.  This fixes replacing class methods.
+
 2011-06-27  Release Manager
 
        * GCC 4.6.1 released.