mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 00:30:53 +00:00
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:
parent
1037eba204
commit
d857153423
3 changed files with 44 additions and 236 deletions
|
@ -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>
|
2001-04-30 Richard Frith-Macdonald <rfm@gnu.org>
|
||||||
|
|
||||||
* Source/NSString.m: parseQuotedString() handle \U escape sequences
|
* Source/NSString.m: parseQuotedString() handle \U escape sequences
|
||||||
|
|
|
@ -38,33 +38,32 @@
|
||||||
#define class_pointer isa
|
#define class_pointer isa
|
||||||
|
|
||||||
#define class_create_instance(CLASS) class_createInstance(CLASS, 0)
|
#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 ? */
|
/* FIXME: Any equivalent for this ? */
|
||||||
#define sel_get_type(SELECTOR) \
|
#define sel_get_type(SELECTOR) \
|
||||||
(NULL)
|
(NULL)
|
||||||
|
|
||||||
#define class_get_instance_method(CLASSPOINTER, SEL) \
|
#define class_get_instance_method class_getInstanceMethod
|
||||||
class_getInstanceMethod(CLASSPOINTER, SEL)
|
#define class_get_class_method class_getClassMethod
|
||||||
#define class_get_class_method(CLASSPOINTER, SEL) \
|
#define class_add_method_list class_addMethods
|
||||||
class_getClassMethod(CLASSPOINTER, SEL)
|
#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) \
|
#define class_get_class_name(CLASSPOINTER) \
|
||||||
(((struct objc_class*)(CLASSPOINTER))->name)
|
(((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) \
|
#define object_get_class(OBJECT) \
|
||||||
(((struct objc_class*)(OBJECT))->isa)
|
(((struct objc_class*)(OBJECT))->isa)
|
||||||
#define class_get_super_class(CLASSPOINTER) \
|
#define class_get_super_class(CLASSPOINTER) \
|
||||||
(((struct objc_class*)(CLASSPOINTER))->super_class)
|
(((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) \
|
#define __objc_responds_to(OBJECT,SEL) \
|
||||||
class_getInstanceMethod(object_get_class(OBJECT), SEL)
|
class_getInstanceMethod(object_get_class(OBJECT), SEL)
|
||||||
#define CLS_ISCLASS(CLASSPOINTER) \
|
#define CLS_ISCLASS(CLASSPOINTER) \
|
||||||
|
@ -74,6 +73,7 @@
|
||||||
#define objc_msg_lookup(OBJ,SEL) \
|
#define objc_msg_lookup(OBJ,SEL) \
|
||||||
(class_getInstanceMethod(object_get_class(OBJ), SEL)->method_imp)
|
(class_getInstanceMethod(object_get_class(OBJ), SEL)->method_imp)
|
||||||
|
|
||||||
|
|
||||||
#define OBJC_READONLY 1
|
#define OBJC_READONLY 1
|
||||||
#define OBJC_WRITEONLY 2
|
#define OBJC_WRITEONLY 2
|
||||||
|
|
||||||
|
|
|
@ -49,35 +49,15 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <base/preface.h>
|
#include <base/preface.h>
|
||||||
#include <base/behavior.h>
|
#include <base/behavior.h>
|
||||||
#include <Foundation/NSException.h>
|
#include <Foundation/NSException.h>
|
||||||
|
|
||||||
static int behavior_debug = 0;
|
static struct objc_method *search_for_method_in_list (struct objc_method_list * list, SEL op);
|
||||||
|
|
||||||
#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 BOOL class_is_kind_of(Class self, Class class);
|
static BOOL class_is_kind_of(Class self, Class class);
|
||||||
|
|
||||||
/* xxx consider using sendmsg.c:__objc_update_dispatch_table_for_class,
|
static int behavior_debug = 0;
|
||||||
but, I think it will be slower than the current method. */
|
|
||||||
|
|
||||||
void
|
void
|
||||||
behavior_set_debug(int i)
|
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(class), NSInvalidArgumentException);
|
||||||
NSCAssert(CLS_ISCLASS(behavior), NSInvalidArgumentException);
|
NSCAssert(CLS_ISCLASS(behavior), NSInvalidArgumentException);
|
||||||
|
|
||||||
__objc_send_initialize(class);
|
|
||||||
__objc_send_initialize(behavior);
|
|
||||||
|
|
||||||
/* If necessary, increase instance_size of CLASS. */
|
/* If necessary, increase instance_size of CLASS. */
|
||||||
if (class->instance_size < behavior->instance_size)
|
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;
|
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)
|
if (behavior_debug)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Adding behavior to class %s\n",
|
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);
|
behavior_class_add_class (class, behavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Need objc_lookup_class_category (const char *class_name
|
|
||||||
const char *category_name)
|
|
||||||
*/
|
|
||||||
|
|
||||||
void
|
void
|
||||||
behavior_class_add_category (Class class, struct objc_category *category)
|
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)
|
struct objc_method_list *methods)
|
||||||
{
|
{
|
||||||
static SEL initialize_sel = 0;
|
static SEL initialize_sel = 0;
|
||||||
MethodList_t mlist;
|
struct objc_method_list *mlist;
|
||||||
|
|
||||||
if (!initialize_sel)
|
if (!initialize_sel)
|
||||||
initialize_sel = sel_register_name ("initialize");
|
initialize_sel = sel_register_name ("initialize");
|
||||||
|
@ -186,49 +149,32 @@ behavior_class_add_methods (Class class,
|
||||||
for (mlist = methods; mlist; mlist = mlist->method_next)
|
for (mlist = methods; mlist; mlist = mlist->method_next)
|
||||||
{
|
{
|
||||||
int counter;
|
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. */
|
all methods will go in here. */
|
||||||
new_list = (MethodList_t)
|
new_list = (struct objc_method_list *)
|
||||||
objc_malloc (sizeof(MethodList) +
|
objc_malloc (sizeof(struct objc_method_list) +
|
||||||
sizeof(struct objc_method[counter+1]));
|
sizeof(struct objc_method[counter+1]));
|
||||||
new_list->method_count = 0;
|
new_list->method_count = 0;
|
||||||
|
new_list->method_next = NULL;
|
||||||
|
|
||||||
while (counter >= 0)
|
while (counter >= 0)
|
||||||
{
|
{
|
||||||
Method_t method = &(mlist->method_list[counter]);
|
struct objc_method *method = &(mlist->method_list[counter]);
|
||||||
|
|
||||||
if (behavior_debug)
|
if (behavior_debug)
|
||||||
fprintf(stderr, " processing method [%s]\n",
|
fprintf(stderr, " processing method [%s]\n",
|
||||||
sel_get_name(method->method_name));
|
sel_get_name(method->method_name));
|
||||||
|
|
||||||
if (!search_for_method_in_list(class->methods, 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,
|
/* As long as the method isn't defined in the CLASS,
|
||||||
put the BEHAVIOR method in there. Thus, behavior
|
put the BEHAVIOR method in there. Thus, behavior
|
||||||
methods override the superclasses' methods. */
|
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_list[new_list->method_count] = *method;
|
||||||
(new_list->method_count)++;
|
(new_list->method_count)++;
|
||||||
}
|
}
|
||||||
|
@ -236,8 +182,14 @@ behavior_class_add_methods (Class class,
|
||||||
}
|
}
|
||||||
if (new_list->method_count)
|
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;
|
new_list->method_next = class->methods;
|
||||||
class->methods = new_list;
|
class->methods = new_list;
|
||||||
|
//__objc_update_dispatch_table_for_class (class);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
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
|
/* 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
|
method's method structure. Return a pointer to the method's method
|
||||||
structure if found. NULL otherwise. */
|
structure if found. NULL otherwise. */
|
||||||
static Method_t
|
static struct objc_method *
|
||||||
search_for_method_in_list (MethodList_t list, SEL op)
|
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))
|
if (! sel_is_mapped (op))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -318,10 +217,10 @@ search_for_method_in_list (MethodList_t list, SEL op)
|
||||||
/* Search the method list. */
|
/* Search the method list. */
|
||||||
for (i = 0; i < method_list->method_count; ++i)
|
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)
|
||||||
if (method->method_name->sel_id == op->sel_id)
|
if (sel_eq(method->method_name, op))
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,102 +232,6 @@ search_for_method_in_list (MethodList_t list, SEL op)
|
||||||
return NULL;
|
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)
|
static BOOL class_is_kind_of(Class self, Class aClassObject)
|
||||||
{
|
{
|
||||||
Class class;
|
Class class;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue