Rewrite for NeXT runtime

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@9748 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Adam Fedor 2001-04-30 15:02:59 +00:00
parent 7d85131c1e
commit da293e3aec
3 changed files with 44 additions and 236 deletions

View file

@ -1,3 +1,8 @@
2001-04-30 Adam Fedor <fedor@gnu.org>
* Source/behavior.m: Rewrite to work with NeXT runtime.
* Headers/gnustep/base/objc-gnu2next.h: Add some extra translations.
2001-04-30 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSString.m: parseQuotedString() handle \U escape sequences

View file

@ -38,33 +38,32 @@
#define class_pointer isa
#define class_create_instance(CLASS) class_createInstance(CLASS, 0)
#define sel_get_name(ASEL) sel_getName(ASEL)
#define sel_get_uid(METHODNAME) sel_getUid(METHODNAME)
#define sel_get_name sel_getName
#define sel_get_uid sel_getUid
#define sel_eq(s1, s2) (s1 == s2)
/* FIXME: Any equivalent for this ? */
#define sel_get_type(SELECTOR) \
(NULL)
#define class_get_instance_method(CLASSPOINTER, SEL) \
class_getInstanceMethod(CLASSPOINTER, SEL)
#define class_get_class_method(CLASSPOINTER, SEL) \
class_getClassMethod(CLASSPOINTER, SEL)
#define class_get_instance_method class_getInstanceMethod
#define class_get_class_method class_getClassMethod
#define class_add_method_list class_addMethods
#define method_get_sizeof_arguments method_getSizeOfArguments
#define objc_lookup_class objc_lookUpClass
#define sel_get_any_uid sel_getUid
#define objc_get_class objc_getClass
#define class_get_version class_getVersion
#define sel_is_mapped sel_isMapped
#define class_get_class_name(CLASSPOINTER) \
(((struct objc_class*)(CLASSPOINTER))->name)
#define method_get_sizeof_arguments(METHOD) \
method_getSizeOfArguments(METHOD)
#define objc_lookup_class(CLASSNAME) \
objc_lookUpClass(CLASSNAME)
#define sel_get_any_uid(SELNAME) \
sel_getUid(SELNAME)
#define object_get_class(OBJECT) \
(((struct objc_class*)(OBJECT))->isa)
#define class_get_super_class(CLASSPOINTER) \
(((struct objc_class*)(CLASSPOINTER))->super_class)
#define objc_get_class(CLASSNAME) \
objc_lookUpClass(CLASSNAME) /* not exactly right */
#define class_get_version(CLASSPOINTER) \
(((struct objc_class*)(CLASSPOINTER))->version)
#define __objc_responds_to(OBJECT,SEL) \
class_getInstanceMethod(object_get_class(OBJECT), SEL)
#define CLS_ISCLASS(CLASSPOINTER) \
@ -74,6 +73,7 @@
#define objc_msg_lookup(OBJ,SEL) \
(class_getInstanceMethod(object_get_class(OBJ), SEL)->method_imp)
#define OBJC_READONLY 1
#define OBJC_WRITEONLY 2

View file

@ -49,35 +49,15 @@
*/
#include <config.h>
#include <stdio.h>
#include <base/preface.h>
#include <base/behavior.h>
#include <Foundation/NSException.h>
static int behavior_debug = 0;
#ifndef HAVE_OBJC_GET_UNINSTALLED_DTABLE
#ifndef objc_EXPORT
#define objc_EXPORT export
#endif
objc_EXPORT void *__objc_uninstalled_dtable;
static void *
objc_get_uninstalled_dtable()
{
return __objc_uninstalled_dtable;
}
#endif
static Method_t search_for_method_in_list (MethodList_t list, SEL op);
static void __objc_send_initialize(Class class);
#if 0
static void __objc_init_protocols (struct objc_protocol_list* protos);
static void __objc_class_add_protocols (Class class,
struct objc_protocol_list* protos);
#endif
static struct objc_method *search_for_method_in_list (struct objc_method_list * list, SEL op);
static BOOL class_is_kind_of(Class self, Class class);
/* xxx consider using sendmsg.c:__objc_update_dispatch_table_for_class,
but, I think it will be slower than the current method. */
static int behavior_debug = 0;
void
behavior_set_debug(int i)
@ -93,9 +73,6 @@ behavior_class_add_class (Class class, Class behavior)
NSCAssert(CLS_ISCLASS(class), NSInvalidArgumentException);
NSCAssert(CLS_ISCLASS(behavior), NSInvalidArgumentException);
__objc_send_initialize(class);
__objc_send_initialize(behavior);
/* If necessary, increase instance_size of CLASS. */
if (class->instance_size < behavior->instance_size)
{
@ -109,16 +86,6 @@ behavior_class_add_class (Class class, Class behavior)
class->instance_size = behavior->instance_size;
}
#if 0
/* xxx Do protocols */
if (behavior->protocols)
{
/* xxx Make sure they are not already there before adding. */
__objc_init_protocols (behavior->protocols);
__objc_class_add_protocols (class, behavior->protocols);
}
#endif
if (behavior_debug)
{
fprintf(stderr, "Adding behavior to class %s\n",
@ -158,10 +125,6 @@ class_add_behavior (Class class, Class behavior)
behavior_class_add_class (class, behavior);
}
/* Need objc_lookup_class_category (const char *class_name
const char *category_name)
*/
void
behavior_class_add_category (Class class, struct objc_category *category)
{
@ -177,7 +140,7 @@ behavior_class_add_methods (Class class,
struct objc_method_list *methods)
{
static SEL initialize_sel = 0;
MethodList_t mlist;
struct objc_method_list *mlist;
if (!initialize_sel)
initialize_sel = sel_register_name ("initialize");
@ -186,49 +149,32 @@ behavior_class_add_methods (Class class,
for (mlist = methods; mlist; mlist = mlist->method_next)
{
int counter;
MethodList_t new_list;
struct objc_method_list *new_list;
counter = mlist->method_count - 1;
counter = mlist->method_count ? mlist->method_count - 1 : 1;
/* xxx This is a little wasteful of memory, since not necessarily
/* This is a little wasteful of memory, since not necessarily
all methods will go in here. */
new_list = (MethodList_t)
objc_malloc (sizeof(MethodList) +
new_list = (struct objc_method_list *)
objc_malloc (sizeof(struct objc_method_list) +
sizeof(struct objc_method[counter+1]));
new_list->method_count = 0;
new_list->method_next = NULL;
while (counter >= 0)
{
Method_t method = &(mlist->method_list[counter]);
struct objc_method *method = &(mlist->method_list[counter]);
if (behavior_debug)
fprintf(stderr, " processing method [%s]\n",
sel_get_name(method->method_name));
if (!search_for_method_in_list(class->methods, method->method_name)
&& method->method_name->sel_id != initialize_sel->sel_id)
&& !sel_eq(method->method_name, initialize_sel))
{
/* As long as the method isn't defined in the CLASS,
put the BEHAVIOR method in there. Thus, behavior
methods override the superclasses' methods. */
/* If dtable is already installed, go ahead and put it in
the dtable sarray, but if it isn't, let
__objc_install_dispatch_table_for_class do it. */
if (class->dtable != objc_get_uninstalled_dtable())
{
sarray_at_put_safe (class->dtable,
(sidx) method->method_name->sel_id,
method->method_imp);
if (behavior_debug)
fprintf(stderr, "\tinstalled method\n");
}
else
{
if (behavior_debug)
fprintf(stderr, "\tappended method\n");
}
new_list->method_list[new_list->method_count] = *method;
(new_list->method_count)++;
}
@ -236,8 +182,14 @@ behavior_class_add_methods (Class class,
}
if (new_list->method_count)
{
#if NeXT_RUNTIME
/* Not sure why this doesn't work for GNU runtime */
class_add_method_list(class, new_list);
#else
new_list->method_next = class->methods;
class->methods = new_list;
//__objc_update_dispatch_table_for_class (class);
#endif
}
else
{
@ -246,66 +198,13 @@ behavior_class_add_methods (Class class,
}
}
/* Should implement this too:
class_add_behavior_category(),
and perhaps something like:
class_add_methods_if_not_there_or_inherited() */
#if 0
/* This is like class_add_method_list(), except is doesn't balk at
duplicates; it simply ignores them. Thus, a method implemented
in CLASS overrides a method implemented in BEHAVIOR. */
void
class_add_behavior_method_list (Class class, MethodList_t list)
{
int i;
static SEL initialize_sel = 0;
if (!initialize_sel)
initialize_sel = sel_register_name ("initialize");
/* Passing of a linked list is not allowed. Do multiple calls. */
NSCAssert(!list->method_next, NSInvalidArgumentException);
/* 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 */
{
if (search_for_method_in_list (class->methods, method->method_name)
&& method->method_name->sel_id != initialize_sel->sel_id)
{
/* Duplication. Print a error message an change the method name
to NULL. */
fprintf (stderr, "attempt to add a existing method: %s\n",
sel_get_name(method->method_name));
method->method_name = 0;
}
else
{
/* Behavior method not implemented in class. Add it. */
sarray_at_put_safe (class->dtable,
(sidx) method->method_name->sel_id,
method->method_imp);
}
}
}
/* Add the methods to the class's method list. */
list->method_next = class->methods;
class->methods = list;
}
#endif
/* Given a linked list of method and a method's name. Search for the named
method's method structure. Return a pointer to the method's method
structure if found. NULL otherwise. */
static Method_t
search_for_method_in_list (MethodList_t list, SEL op)
static struct objc_method *
search_for_method_in_list (struct objc_method_list *list, SEL op)
{
MethodList_t method_list = list;
struct objc_method_list *method_list = list;
if (! sel_is_mapped (op))
return NULL;
@ -318,10 +217,10 @@ search_for_method_in_list (MethodList_t list, SEL op)
/* Search the method list. */
for (i = 0; i < method_list->method_count; ++i)
{
Method_t method = &method_list->method_list[i];
struct objc_method *method = &method_list->method_list[i];
if (method->method_name)
if (method->method_name->sel_id == op->sel_id)
if (sel_eq(method->method_name, op))
return method;
}
@ -333,102 +232,6 @@ search_for_method_in_list (MethodList_t list, SEL op)
return NULL;
}
/* Send +initialize to class if not already done */
static void __objc_send_initialize(Class class)
{
/* This *must* be a class object */
NSCAssert(CLS_ISCLASS(class), NSInvalidArgumentException);
NSCAssert(!CLS_ISMETA(class), NSInvalidArgumentException);
if (!CLS_ISINITIALIZED(class))
{
CLS_SETINITIALIZED(class);
CLS_SETINITIALIZED(class->class_pointer);
if(class->super_class)
__objc_send_initialize(class->super_class);
{
MethodList_t method_list = class->class_pointer->methods;
SEL op = sel_register_name ("initialize");
/* If not found then we'll search the list. */
while (method_list)
{
int i;
/* Search the method list. */
for (i = 0; i < method_list->method_count; ++i)
{
Method_t method = &method_list->method_list[i];
if (method->method_name->sel_id == op->sel_id)
(*method->method_imp)((id) class, op);
}
/* The method wasn't found. Follow the link to the next list of
methods. */
method_list = method_list->method_next;
}
}
}
}
#if 0
static void
__objc_init_protocols (struct objc_protocol_list* protos)
{
int i;
static Class proto_class = 0;
if (! protos)
return;
if (!proto_class)
proto_class = objc_lookup_class("Protocol");
if (!proto_class)
{
unclaimed_proto_list = list_cons (protos, unclaimed_proto_list);
return;
}
for(i = 0; i < protos->count; i++)
{
struct objc_protocol* aProto = protos->list[i];
if (((size_t)aProto->class_pointer) == PROTOCOL_VERSION)
{
/* assign class pointer */
aProto->class_pointer = proto_class;
/* init super protocols */
__objc_init_protocols (aProto->protocol_list);
}
else if (protos->list[i]->class_pointer != proto_class)
{
fprintf (stderr,
"Version %d doesn't match runtime protocol version %d\n",
(int)((char*)protos->list[i]->class_pointer-(char*)0),
PROTOCOL_VERSION);
abort ();
}
}
}
static void __objc_class_add_protocols (Class class,
struct objc_protocol_list* protos)
{
/* Well... */
if (! protos)
return;
/* Add it... */
protos->next = class->protocols;
class->protocols = protos;
}
#endif /* 0 */
static BOOL class_is_kind_of(Class self, Class aClassObject)
{
Class class;