diff --git a/ChangeLog b/ChangeLog index 18f98b981..0eeb52c3c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2001-08-28 Adam Fedor + + * Headers/gnustep/base/objc-gnu2next.h: More defs. + * Source/NSObject.m (-methodSignatureForSelector:): Use sel_get_type. + + * Source/mframe.m (method_types_get_first_argument): New function. + (method_types_get_sizeof_arguments): Likewise. + * Source/objc-gnu2next.m (next_objc_msg_sendv): Use them. + 2001-08-21 Willem Rein Oudshoorn * Source/GSFFCallInvocation.m: Clearified comments diff --git a/Headers/gnustep/base/NSThread.h b/Headers/gnustep/base/NSThread.h index 47b66f954..0ec7773c9 100644 --- a/Headers/gnustep/base/NSThread.h +++ b/Headers/gnustep/base/NSThread.h @@ -25,7 +25,7 @@ #ifndef __NSThread_h_GNUSTEP_BASE_INCLUDE #define __NSThread_h_GNUSTEP_BASE_INCLUDE -#ifdef NeXT_RUNTIMME +#ifdef NeXT_RUNTIME #include #endif #include diff --git a/Headers/gnustep/base/objc-gnu2next.h b/Headers/gnustep/base/objc-gnu2next.h index 7bcdc3d38..ec9ee009d 100644 --- a/Headers/gnustep/base/objc-gnu2next.h +++ b/Headers/gnustep/base/objc-gnu2next.h @@ -47,7 +47,9 @@ typedef struct objc_super Super; #define class_get_instance_method class_getInstanceMethod #define class_get_class_method class_getClassMethod #define class_add_method_list class_addMethods +#define class_set_version class_setVersion #define class_get_version class_getVersion +#define class_pose_as class_poseAs #define method_get_sizeof_arguments method_getSizeOfArguments #define objc_lookup_class objc_lookUpClass #define objc_get_class objc_getClass @@ -71,13 +73,13 @@ typedef struct objc_super Super; (((struct objc_class*)(OBJECT))->isa) #define class_get_super_class(CLASSPOINTER) \ (((struct objc_class*)(CLASSPOINTER))->super_class) -#define object_get_super_class(OBJ) \ +#define object_get_super_class(OBJECT) \ (((struct objc_class*)(object_get_class(OBJECT)))->super_class) #define object_get_class_name(OBJECT) \ (((struct objc_class*)(object_get_class(OBJECT)))->name) #define __objc_responds_to(OBJECT,SEL) \ - class_getInstanceMethod(object_get_class(OBJECT), SEL) + (class_getInstanceMethod(object_get_class(OBJECT), SEL) != METHOD_NULL) #define CLS_ISCLASS(CLASSPOINTER) \ ((((struct objc_class*)(CLASSPOINTER))->info) & CLS_CLASS) #define CLS_ISMETA(CLASSPOINTER) \ @@ -87,6 +89,9 @@ typedef struct objc_super Super; #define objc_msg_lookup_super(OBJ,SEL) \ (class_getInstanceMethod(object_get_class(OBJ), SEL)->method_imp) +#define objc_msg_sendv next_objc_msg_sendv + +extern id next_objc_msg_sendv(id self, SEL op, void* arg_frame); #define OBJC_READONLY 1 #define OBJC_WRITEONLY 2 @@ -121,6 +126,18 @@ class_is_class(Class class) return CLS_ISCLASS(class); } +static inline BOOL +object_is_class(id object) +{ + return CLS_ISCLASS((Class)object); +} + +static inline long +class_get_instance_size(Class class) +{ + return CLS_ISCLASS(class)?class->instance_size:0; +} + static inline IMP method_get_imp(Method method) { diff --git a/Source/NSObject.m b/Source/NSObject.m index d5e142809..826b5da4f 100644 --- a/Source/NSObject.m +++ b/Source/NSObject.m @@ -780,7 +780,7 @@ static BOOL deallocNotifications = NO; } if (types == 0) { - types = aSelector->sel_types; + types = sel_get_type(aSelector); } if (types == 0) { @@ -2332,9 +2332,11 @@ GSSetValue(NSObject *self, NSString *key, id val, SEL sel, + (int) streamVersion: (TypedStream*)aStream { +#ifndef NeXT_RUNTIME if (aStream->mode == OBJC_READONLY) return objc_get_stream_class_version (aStream, self); else +#endif return class_get_version (self); } diff --git a/Source/mframe.m b/Source/mframe.m index d6b2720a7..3f10137db 100644 --- a/Source/mframe.m +++ b/Source/mframe.m @@ -577,6 +577,22 @@ method_types_get_next_argument (arglist_t argf, const char **type) } } +char* +method_types_get_first_argument (struct objc_method* m, + arglist_t argframe, + const char** type) +{ + *type = m->method_types; + return method_get_next_argument (argframe, type); +} + +int +method_types_get_sizeof_arguments (struct objc_method* mth) +{ + const char* type = objc_skip_typespec (mth->method_types); + return atoi (type); +} + /* mframe_dissect_call() diff --git a/Source/mframe/mframe.head b/Source/mframe/mframe.head index 3052ee448..7db2a15c4 100644 --- a/Source/mframe/mframe.head +++ b/Source/mframe/mframe.head @@ -125,3 +125,11 @@ mframe_destroy_argframe(const char *types, arglist_t argframe); ({ typeof(V) __v=(V); typeof(A) __a=(A); \ __a*((__v+__a-1)/__a); }) + +int method_types_get_sizeof_arguments (struct objc_method* mth); +char* method_types_get_next_argument (arglist_t argf, const char **type); +char* method_types_get_first_argument (struct objc_method* m, + arglist_t argframe, + const char** type); + + diff --git a/Source/objc-gnu2next.m b/Source/objc-gnu2next.m index da31d0d61..9c61c5909 100644 --- a/Source/objc-gnu2next.m +++ b/Source/objc-gnu2next.m @@ -25,6 +25,7 @@ #include "config.h" #include #include +#include "mframe.h" #ifndef ROUND #define ROUND(V, A) \ @@ -445,7 +446,33 @@ sel_types_match (const char* t1, const char* t2) return NO; } +id next_objc_msg_sendv(id object, SEL op, void* frame) +{ + arglist_t argFrame = __builtin_apply_args(); + Method *m = class_get_instance_method(object->class_pointer, op); + const char *type; + void *result; + argFrame->arg_ptr = frame; + *((id*)method_types_get_first_argument (m, argFrame, &type)) = object; + *((SEL*)method_types_get_next_argument (argFrame, &type)) = op; + result = __builtin_apply((apply_t)m->method_imp, + argFrame, + method_get_sizeof_arguments (m)); + +#if !defined(BROKEN_BUILTIN_APPLY) && defined(i386) + /* Special hack to avoid pushing the poped float value back to the fp + stack on i386 machines. This happens with NeXT runtime and 2.7.2 + compiler. If the result value is floating point don't call + __builtin_return anymore. */ + if(*m->method_types == _C_FLT || *m->method_types == _C_DBL) { + long double value = *(long double*)(((char*)result) + 8); + asm("fld %0" : : "f" (value)); + } + else +#endif + __builtin_return(result); +} /* ** Hook functions for memory allocation and disposal.