sendmsg.c: Added __objc_msg_forward2...
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. From-SVN: r123678
This commit is contained in:
parent
ecc0fc15ec
commit
80ae8e8ad2
@ -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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user