OSDN Git Service

2007-04-09 Andrew Ruder <andy@aeruder.net>
authorpinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 9 Apr 2007 18:04:50 +0000 (18:04 +0000)
committerpinskia <pinskia@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 9 Apr 2007 18:04:50 +0000 (18:04 +0000)
        * sendmsg.c: Added __objc_msg_forward2, a hook that allows
        external libraries to provide a function that returns the real
        forwarding function based on both the selector and the receiver.
        * objc/objc-api.h: Define __objc_msg_forward2.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@123678 138bc75d-0d04-0410-961f-82ee72b054a4

libobjc/ChangeLog
libobjc/objc/objc-api.h
libobjc/sendmsg.c

index e05cac4..e55fa50 100644 (file)
@@ -1,3 +1,10 @@
+2007-04-09  Andrew Ruder  <andy@aeruder.net>
+
+       * sendmsg.c: Added __objc_msg_forward2, a hook that allows
+       external libraries to provide a function that returns the real
+       forwarding function based on both the selector and the receiver.
+       * objc/objc-api.h: Define __objc_msg_forward2.
+
 2007-03-01  Brooks Moses  <brooks.moses@codesourcery.com>
 
        * Makefile.in: Add dummy install-pdf target.
index e0e49e2..8100c6c 100644 (file)
@@ -41,11 +41,9 @@ extern "C" {
 /* For functions which return Method_t */
 #define METHOD_NULL    (Method_t)0
                                                 /* Boolean typedefs */
-/*
-** Method descriptor returned by introspective Object methods.
-** This is really just the first part of the more complete objc_method
-** structure defined below and used internally by the runtime.
-*/
+/* Method descriptor returned by introspective Object methods.
+   This is really just the first part of the more complete objc_method
+   structure defined below and used internally by the runtime.  */
 struct objc_method_description
 {
     SEL name;                  /* this is a selector, not a string */
@@ -85,36 +83,32 @@ struct objc_method_description
 #define _C_COMPLEX   'j'
 
 
-/*
-** Error handling
-**
-** Call objc_error() or objc_verror() to record an error; this error
-** routine will generally exit the program but not necessarily if the
-** user has installed his own error handler.
-**
-** Call objc_set_error_handler to assign your own function for
-** handling errors.  The function should return YES if it is ok
-** to continue execution, or return NO or just abort if the
-** program should be stopped.  The default error handler is just to
-** print a message on stderr.
-**
-** The error handler function should be of type objc_error_handler
-** The first parameter is an object instance of relevance.
-** The second parameter is an error code.
-** The third parameter is a format string in the printf style.
-** The fourth parameter is a variable list of arguments.
-*/
+/* Error handling
+  
+   Call objc_error() or objc_verror() to record an error; this error
+   routine will generally exit the program but not necessarily if the
+   user has installed his own error handler.
+  
+   Call objc_set_error_handler to assign your own function for
+   handling errors.  The function should return YES if it is ok
+   to continue execution, or return NO or just abort if the
+   program should be stopped.  The default error handler is just to
+   print a message on stderr.
+  
+   The error handler function should be of type objc_error_handler
+   The first parameter is an object instance of relevance.
+   The second parameter is an error code.
+   The third parameter is a format string in the printf style.
+   The fourth parameter is a variable list of arguments.  */
 extern void objc_error(id object, int code, const char* fmt, ...);
 extern void objc_verror(id object, int code, const char* fmt, va_list ap);
 typedef BOOL (*objc_error_handler)(id, int code, const char *fmt, va_list ap);
 extern objc_error_handler objc_set_error_handler(objc_error_handler func);
 
-/*
-** Error codes
-** These are used by the runtime library, and your
-** error handling may use them to determine if the error is
-** hard or soft thus whether execution can continue or abort.
-*/
+/* Error codes
+   These are used by the runtime library, and your
+   error handling may use them to determine if the error is
+   hard or soft thus whether execution can continue or abort.  */
 #define OBJC_ERR_UNKNOWN 0             /* Generic error */
 
 #define OBJC_ERR_OBJC_VERSION 1        /* Incorrect runtime version */
@@ -139,10 +133,8 @@ extern objc_error_handler objc_set_error_handler(objc_error_handler func);
 
 #define OBJC_ERR_BAD_STATE 40          /* Bad thread state */
 
-/*
-** Set this variable nonzero to print a line describing each
-** message that is sent.  (this is currently disabled)
-*/
+/* Set this variable nonzero to print a line describing each
+   message that is sent.  (this is currently disabled)  */
 extern BOOL objc_trace;
 
 
@@ -160,14 +152,12 @@ struct objc_static_instances
 #endif
 };
 
-/*
-** Whereas a Module (defined further down) is the root (typically) of a file,
-** a Symtab is the root of the class and category definitions within the
-** module.  
-** 
-** A Symtab contains a variable length array of pointers to classes and
-** categories  defined in the module. 
-*/
+/* Whereas a Module (defined further down) is the root (typically) of a file,
+   a Symtab is the root of the class and category definitions within the
+   module.  
+   
+   A Symtab contains a variable length array of pointers to classes and
+   categories  defined in the module.   */
 typedef struct objc_symtab {
   unsigned long sel_ref_cnt;                     /* Unknown. */
   SEL        refs;                              /* Unknown. */
@@ -431,11 +421,14 @@ objc_EXPORT void *(*_objc_calloc)(size_t, size_t);
 objc_EXPORT void (*_objc_free)(void *);
 
 /*
-**  Hook for method forwarding. This makes it easy to substitute a
+**  Hooks for method forwarding. This makes it easy to substitute a
 **  library, such as ffcall, that implements closures, thereby avoiding
-**  gcc's __builtin_apply problems.
+**  gcc's __builtin_apply problems.  __objc_msg_forward2's result will
+**  be preferred over that of __objc_msg_forward if both are set and
+**  return non-NULL.
 */
 objc_EXPORT IMP (*__objc_msg_forward)(SEL);
+objc_EXPORT IMP (*__objc_msg_forward2)(id, SEL);
 
 Method_t class_get_class_method(MetaClass _class, SEL aSel);
 
index 9453ef3..c1aed1c 100644 (file)
@@ -52,10 +52,15 @@ Boston, MA 02110-1301, 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);
@@ -69,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;
@@ -87,10 +91,11 @@ id nil_method (id, SEL);
 /* Given a selector, return the proper forwarding implementation. */
 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_forward)
     {
       IMP result;
@@ -99,7 +104,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;
 
@@ -168,7 +173,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);
            }
        }
     }
@@ -237,7 +242,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);
                }
            }
        }