mirror of git://gcc.gnu.org/git/gcc.git
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>
|
2007-03-01 Brooks Moses <brooks.moses@codesourcery.com>
|
||||||
|
|
||||||
* Makefile.in: Add dummy install-pdf target.
|
* Makefile.in: Add dummy install-pdf target.
|
||||||
|
|
|
@ -41,11 +41,9 @@ extern "C" {
|
||||||
/* For functions which return Method_t */
|
/* For functions which return Method_t */
|
||||||
#define METHOD_NULL (Method_t)0
|
#define METHOD_NULL (Method_t)0
|
||||||
/* Boolean typedefs */
|
/* Boolean typedefs */
|
||||||
/*
|
/* Method descriptor returned by introspective Object methods.
|
||||||
** Method descriptor returned by introspective Object methods.
|
This is really just the first part of the more complete objc_method
|
||||||
** This is really just the first part of the more complete objc_method
|
structure defined below and used internally by the runtime. */
|
||||||
** structure defined below and used internally by the runtime.
|
|
||||||
*/
|
|
||||||
struct objc_method_description
|
struct objc_method_description
|
||||||
{
|
{
|
||||||
SEL name; /* this is a selector, not a string */
|
SEL name; /* this is a selector, not a string */
|
||||||
|
@ -85,36 +83,32 @@ struct objc_method_description
|
||||||
#define _C_COMPLEX 'j'
|
#define _C_COMPLEX 'j'
|
||||||
|
|
||||||
|
|
||||||
/*
|
/* Error handling
|
||||||
** Error handling
|
|
||||||
**
|
Call objc_error() or objc_verror() to record an error; this error
|
||||||
** Call objc_error() or objc_verror() to record an error; this error
|
routine will generally exit the program but not necessarily if the
|
||||||
** routine will generally exit the program but not necessarily if the
|
user has installed his own error handler.
|
||||||
** user has installed his own error handler.
|
|
||||||
**
|
Call objc_set_error_handler to assign your own function for
|
||||||
** Call objc_set_error_handler to assign your own function for
|
handling errors. The function should return YES if it is ok
|
||||||
** handling errors. The function should return YES if it is ok
|
to continue execution, or return NO or just abort if the
|
||||||
** to continue execution, or return NO or just abort if the
|
program should be stopped. The default error handler is just to
|
||||||
** program should be stopped. The default error handler is just to
|
print a message on stderr.
|
||||||
** print a message on stderr.
|
|
||||||
**
|
The error handler function should be of type objc_error_handler
|
||||||
** The error handler function should be of type objc_error_handler
|
The first parameter is an object instance of relevance.
|
||||||
** The first parameter is an object instance of relevance.
|
The second parameter is an error code.
|
||||||
** The second parameter is an error code.
|
The third parameter is a format string in the printf style.
|
||||||
** The third parameter is a format string in the printf style.
|
The fourth parameter is a variable list of arguments. */
|
||||||
** The fourth parameter is a variable list of arguments.
|
|
||||||
*/
|
|
||||||
extern void objc_error(id object, int code, const char* fmt, ...);
|
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);
|
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);
|
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);
|
extern objc_error_handler objc_set_error_handler(objc_error_handler func);
|
||||||
|
|
||||||
/*
|
/* Error codes
|
||||||
** Error codes
|
These are used by the runtime library, and your
|
||||||
** These are used by the runtime library, and your
|
error handling may use them to determine if the error is
|
||||||
** error handling may use them to determine if the error is
|
hard or soft thus whether execution can continue or abort. */
|
||||||
** hard or soft thus whether execution can continue or abort.
|
|
||||||
*/
|
|
||||||
#define OBJC_ERR_UNKNOWN 0 /* Generic error */
|
#define OBJC_ERR_UNKNOWN 0 /* Generic error */
|
||||||
|
|
||||||
#define OBJC_ERR_OBJC_VERSION 1 /* Incorrect runtime version */
|
#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 */
|
#define OBJC_ERR_BAD_STATE 40 /* Bad thread state */
|
||||||
|
|
||||||
/*
|
/* Set this variable nonzero to print a line describing each
|
||||||
** Set this variable nonzero to print a line describing each
|
message that is sent. (this is currently disabled) */
|
||||||
** message that is sent. (this is currently disabled)
|
|
||||||
*/
|
|
||||||
extern BOOL objc_trace;
|
extern BOOL objc_trace;
|
||||||
|
|
||||||
|
|
||||||
|
@ -160,14 +152,12 @@ struct objc_static_instances
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/* Whereas a Module (defined further down) is the root (typically) of a file,
|
||||||
** 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
|
||||||
** a Symtab is the root of the class and category definitions within the
|
module.
|
||||||
** module.
|
|
||||||
**
|
A Symtab contains a variable length array of pointers to classes and
|
||||||
** A Symtab contains a variable length array of pointers to classes and
|
categories defined in the module. */
|
||||||
** categories defined in the module.
|
|
||||||
*/
|
|
||||||
typedef struct objc_symtab {
|
typedef struct objc_symtab {
|
||||||
unsigned long sel_ref_cnt; /* Unknown. */
|
unsigned long sel_ref_cnt; /* Unknown. */
|
||||||
SEL refs; /* Unknown. */
|
SEL refs; /* Unknown. */
|
||||||
|
@ -431,11 +421,14 @@ objc_EXPORT void *(*_objc_calloc)(size_t, size_t);
|
||||||
objc_EXPORT void (*_objc_free)(void *);
|
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
|
** 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_forward)(SEL);
|
||||||
|
objc_EXPORT IMP (*__objc_msg_forward2)(id, SEL);
|
||||||
|
|
||||||
Method_t class_get_class_method(MetaClass _class, SEL aSel);
|
Method_t class_get_class_method(MetaClass _class, SEL aSel);
|
||||||
|
|
||||||
|
|
|
@ -52,10 +52,15 @@ Boston, MA 02110-1301, USA. */
|
||||||
/* The uninstalled dispatch table */
|
/* The uninstalled dispatch table */
|
||||||
struct sarray *__objc_uninstalled_dtable = 0; /* !T:MUTEX */
|
struct sarray *__objc_uninstalled_dtable = 0; /* !T:MUTEX */
|
||||||
|
|
||||||
/* Hook for method forwarding. If it is set, is invoked to return a
|
/* Two hooks for method forwarding. If either is set, it is invoked
|
||||||
function that performs the real forwarding. Otherwise the libgcc
|
* to return a function that performs the real forwarding. If both
|
||||||
based functions (__builtin_apply and friends) are used. */
|
* 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_forward) (SEL) = NULL;
|
||||||
|
IMP (*__objc_msg_forward2) (id, SEL) = NULL;
|
||||||
|
|
||||||
/* Send +initialize to class */
|
/* Send +initialize to class */
|
||||||
static void __objc_send_initialize (Class);
|
static void __objc_send_initialize (Class);
|
||||||
|
@ -69,8 +74,7 @@ static void __objc_init_install_dtable (id, SEL);
|
||||||
return type for the selector.
|
return type for the selector.
|
||||||
__objc_block_forward for structures.
|
__objc_block_forward for structures.
|
||||||
__objc_double_forward for floats/doubles.
|
__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 double __objc_double_forward (id, SEL, ...);
|
||||||
static id __objc_word_forward (id, SEL, ...);
|
static id __objc_word_forward (id, SEL, ...);
|
||||||
typedef struct { id many[8]; } __big;
|
typedef struct { id many[8]; } __big;
|
||||||
|
@ -87,10 +91,11 @@ id nil_method (id, SEL);
|
||||||
/* Given a selector, return the proper forwarding implementation. */
|
/* Given a selector, return the proper forwarding implementation. */
|
||||||
inline
|
inline
|
||||||
IMP
|
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
|
/* 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)
|
if (__objc_msg_forward)
|
||||||
{
|
{
|
||||||
IMP result;
|
IMP result;
|
||||||
|
@ -99,7 +104,7 @@ __objc_get_forward_imp (SEL sel)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* In all other cases, use the default forwarding functions built using
|
/* 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;
|
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
|
is not in the dispatch table. So the method just
|
||||||
doesn't exist for the class. Return the forwarding
|
doesn't exist for the class. Return the forwarding
|
||||||
implementation. */
|
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
|
/* If the method still just doesn't exist for the
|
||||||
class, attempt to forward the method. */
|
class, attempt to forward the method. */
|
||||||
result = __objc_get_forward_imp (op);
|
result = __objc_get_forward_imp (receiver, op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue