aboutsummaryrefslogtreecommitdiff
path: root/libobjc
diff options
context:
space:
mode:
authorpinskia <>2007-04-09 17:04:50 +0000
committerpinskia <>2007-04-09 17:04:50 +0000
commitf6f7d62180b81919941992ed3a8465b988683463 (patch)
treed4296a5892d33adec631c46ee86b937dcd79fb6f /libobjc
parent06b7e2bdaf036b60f67072dd71feba8efd678eba (diff)
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.
Diffstat (limited to 'libobjc')
-rw-r--r--libobjc/ChangeLog7
-rw-r--r--libobjc/objc/objc-api.h81
-rw-r--r--libobjc/sendmsg.c25
3 files changed, 59 insertions, 54 deletions
diff --git a/libobjc/ChangeLog b/libobjc/ChangeLog
index e05cac4456f..e55fa509beb 100644
--- a/libobjc/ChangeLog
+++ b/libobjc/ChangeLog
@@ -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.
diff --git a/libobjc/objc/objc-api.h b/libobjc/objc/objc-api.h
index e0e49e21fdf..8100c6cfa27 100644
--- a/libobjc/objc/objc-api.h
+++ b/libobjc/objc/objc-api.h
@@ -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);
diff --git a/libobjc/sendmsg.c b/libobjc/sendmsg.c
index 9453ef3dd46..c1aed1c0f9a 100644
--- a/libobjc/sendmsg.c
+++ b/libobjc/sendmsg.c
@@ -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);
}
}
}