OSDN Git Service

* gcc.dg/pr34351.c: Compile for x86 targets only. Use %ebx register.
[pf3gnuchains/gcc-fork.git] / libobjc / sendmsg.c
index 0214e77..a0b66ba 100644 (file)
@@ -1,6 +1,6 @@
 /* GNU Objective C Runtime message lookup 
    Copyright (C) 1993, 1995, 1996, 1997, 1998,
-   2001, 2002 Free Software Foundation, Inc.
+   2001, 2002, 2004 Free Software Foundation, Inc.
    Contributed by Kresten Krab Thorup
 
 This file is part of GCC.
@@ -16,8 +16,8 @@ details.
 
 You should have received a copy of the GNU General Public License along with
 GCC; see the file COPYING.  If not, write to the Free Software
-Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 /* As a special exception, if you link this library with files compiled with
    GCC to produce an executable, this does not cause the resulting executable
@@ -26,16 +26,18 @@ Boston, MA 02111-1307, USA.  */
    covered by the GNU General Public License.  */
 
 /* FIXME: This file has no business including tm.h.  */
+/* FIXME: This should be using libffi instead of __builtin_apply
+   and friends.  */
 
 #include "tconfig.h"
 #include "coretypes.h"
 #include "tm.h"
-#include "runtime.h"
-#include "sarray.h"
-#include "encoding.h"
+#include "objc/runtime.h"
+#include "objc/sarray.h"
+#include "objc/encoding.h"
 #include "runtime-info.h"
 
-/* this is how we hack STRUCT_VALUE to be 1 or 0 */
+/* This is how we hack STRUCT_VALUE to be 1 or 0.   */
 #define gen_rtx(args...) 1
 #define gen_rtx_MEM(args...) 1
 #define gen_rtx_REG(args...) 1
@@ -50,10 +52,15 @@ Boston, MA 02111-1307, USA.  */
 /* The uninstalled dispatch table */
 struct sarray *__objc_uninstalled_dtable = 0;   /* !T:MUTEX */
 
-/* Hook for method forwarding. If it is set, is invoked to return a
-   function that performs the real forwarding. Otherwise the libgcc
-   based functions (__builtin_apply and friends) are used. */
+/* Two hooks for method forwarding. If either is set, it is invoked
+ * to return a function that performs the real forwarding.  If both
+ * are set, the result of __objc_msg_forward2 will be preferred over
+ * that of __objc_msg_forward.  If both return NULL or are unset,
+ * the libgcc based functions (__builtin_apply and friends) are
+ * used.
+ */
 IMP (*__objc_msg_forward) (SEL) = NULL;
+IMP (*__objc_msg_forward2) (id, SEL) = NULL;
 
 /* Send +initialize to class */
 static void __objc_send_initialize (Class);
@@ -67,8 +74,7 @@ static void __objc_init_install_dtable (id, SEL);
    return type for the selector.
    __objc_block_forward for structures.
    __objc_double_forward for floats/doubles.
-   __objc_word_forward for pointers or types that fit in registers.
-   */
+   __objc_word_forward for pointers or types that fit in registers. */
 static double __objc_double_forward (id, SEL, ...);
 static id __objc_word_forward (id, SEL, ...);
 typedef struct { id many[8]; } __big;
@@ -83,12 +89,19 @@ Method_t search_for_method_in_list (MethodList_t list, SEL op);
 id nil_method (id, SEL);
 
 /* Given a selector, return the proper forwarding implementation. */
-__inline__
+inline
 IMP
-__objc_get_forward_imp (SEL sel)
+__objc_get_forward_imp (id rcv, SEL sel)
 {
   /* If a custom forwarding hook was registered, try getting a forwarding
-   * function from it.  */
+     function from it. There are two forward routine hooks, one that
+     takes the receiver as an argument and one that does not. */
+  if (__objc_msg_forward2)
+    {
+      IMP result;
+      if ((result = __objc_msg_forward2 (rcv, sel)) != NULL)
+       return result;
+    }
   if (__objc_msg_forward)
     {
       IMP result;
@@ -97,7 +110,7 @@ __objc_get_forward_imp (SEL sel)
     }
 
   /* In all other cases, use the default forwarding functions built using
-   * __builtin_apply and friends.  */
+     __builtin_apply and friends.  */
     {
       const char *t = sel->sel_types;
 
@@ -115,7 +128,7 @@ __objc_get_forward_imp (SEL sel)
 }
 
 /* Given a class and selector, return the selector's implementation.  */
-__inline__
+inline
 IMP
 get_imp (Class class, SEL sel)
 {
@@ -166,7 +179,7 @@ get_imp (Class class, SEL sel)
                 is not in the dispatch table.  So the method just
                 doesn't exist for the class.  Return the forwarding
                 implementation. */
-             res = __objc_get_forward_imp (sel);
+             res = __objc_get_forward_imp ((id)class, sel);
            }
        }
     }
@@ -176,7 +189,7 @@ get_imp (Class class, SEL sel)
 /* Query if an object can respond to a selector, returns YES if the
 object implements the selector otherwise NO.  Does not check if the
 method can be forwarded. */
-__inline__
+inline
 BOOL
 __objc_responds_to (id object, SEL sel)
 {
@@ -201,7 +214,7 @@ __objc_responds_to (id object, SEL sel)
 /* This is the lookup function.  All entries in the table are either a 
    valid method *or* zero.  If zero then either the dispatch table
    needs to be installed or it doesn't exist and forwarding is attempted. */
-__inline__
+inline
 IMP
 objc_msg_lookup (id receiver, SEL op)
 {
@@ -235,7 +248,7 @@ objc_msg_lookup (id receiver, SEL op)
                {
                  /* If the method still just doesn't exist for the
                     class, attempt to forward the method. */
-                 result = __objc_get_forward_imp (op);
+                 result = __objc_get_forward_imp (receiver, op);
                }
            }
        }
@@ -463,28 +476,14 @@ __objc_update_dispatch_table_for_class (Class class)
 
    This one is only called for categories. Class objects have their
    methods installed right away, and their selectors are made into
-   SEL's by the function __objc_register_selectors_from_class. */ 
+   SEL's by the function __objc_register_selectors_from_class. */
 void
 class_add_method_list (Class class, MethodList_t list)
 {
-  int i;
-
   /* Passing of a linked list is not allowed.  Do multiple calls.  */
   assert (! list->method_next);
 
-  /* Check for duplicates.  */
-  for (i = 0; i < list->method_count; ++i)
-    {
-      Method_t method = &list->method_list[i];
-
-      if (method->method_name)  /* Sometimes these are NULL */
-       {
-         /* This is where selector names are transmogrified to SEL's */
-         method->method_name = 
-           sel_register_typed_name ((const char *) method->method_name,
-                                    method->method_types);
-       }
-    }
+  __objc_register_selectors_from_list(list);
 
   /* Add the methods to the class's method list.  */
   list->method_next = class->methods;
@@ -705,7 +704,7 @@ __objc_print_dtable_stats ()
 /* Returns the uninstalled dispatch table indicator.
  If a class' dispatch table points to __objc_uninstalled_dtable
  then that means it needs its dispatch table to be installed. */
-__inline__
+inline
 struct sarray *
 objc_get_uninstalled_dtable ()
 {