From 4b6286e29cf106584566c6d77009f3a4b3e3ed39 Mon Sep 17 00:00:00 2001 From: Matthias Benkard Date: Fri, 3 Aug 2007 15:03:08 +0200 Subject: Use tagged data on both the Lisp and C sides. darcs-hash:d32babb07560cbb4f8db5467b31a7e92534eeb0d --- libobjcl.m | 157 ++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 97 insertions(+), 60 deletions(-) (limited to 'libobjcl.m') diff --git a/libobjcl.m b/libobjcl.m index 7aac299..bd59810 100644 --- a/libobjcl.m +++ b/libobjcl.m @@ -6,7 +6,7 @@ #include -NSAutoreleasePool *objcl_autorelease_pool = NULL; +static NSAutoreleasePool *objcl_autorelease_pool = NULL; void @@ -23,59 +23,36 @@ objcl_shutdown_runtime () } -#define _OBJCL_ARG_DECL(typespec, c_type) \ - c_type __##typespec##_tmp - - -#define _OBJCL_ARG_CASE(typespec, c_type) \ +#define _OBJCL_ARG_CASE(typespec, field_name) \ case typespec: \ - __##typespec##_tmp = va_arg (arglist, c_type); \ - memmove (buffer, &__##typespec##_tmp, objc_sizeof_type (type)); \ + memmove (buffer, &argdata->data.field_name##_val, \ + objc_sizeof_type (argdata->type)); \ break; -void -_objcl_get_arg_pointer (void *buffer, const char *type, va_list arglist) +static void +_objcl_get_arg_pointer (void *buffer, OBJCL_OBJ_DATA argdata) { - _OBJCL_ARG_DECL(_C_ID, id); - _OBJCL_ARG_DECL(_C_CLASS, id); - _OBJCL_ARG_DECL(_C_SEL, SEL); - _OBJCL_ARG_DECL(_C_CHR, char); - _OBJCL_ARG_DECL(_C_UCHR, unsigned char); - _OBJCL_ARG_DECL(_C_SHT, short); - _OBJCL_ARG_DECL(_C_USHT, unsigned short); - _OBJCL_ARG_DECL(_C_INT, int); - _OBJCL_ARG_DECL(_C_UINT, unsigned int); - _OBJCL_ARG_DECL(_C_LNG, long); - _OBJCL_ARG_DECL(_C_ULNG, unsigned long); - _OBJCL_ARG_DECL(_C_LNG_LNG, long long); - _OBJCL_ARG_DECL(_C_ULNG_LNG, unsigned long long); - _OBJCL_ARG_DECL(_C_FLT, float); - _OBJCL_ARG_DECL(_C_DBL, double); - _OBJCL_ARG_DECL(_C_BOOL, BOOL); - _OBJCL_ARG_DECL(_C_PTR, void *); - _OBJCL_ARG_DECL(_C_CHARPTR, char *); - - switch (type[0]) + switch (argdata->type[0]) { _OBJCL_ARG_CASE(_C_ID, id); _OBJCL_ARG_CASE(_C_CLASS, id); - _OBJCL_ARG_CASE(_C_SEL, SEL); - _OBJCL_ARG_CASE(_C_CHR, int); - _OBJCL_ARG_CASE(_C_UCHR, int); - _OBJCL_ARG_CASE(_C_SHT, int); - _OBJCL_ARG_CASE(_C_USHT, int); + _OBJCL_ARG_CASE(_C_SEL, sel); + _OBJCL_ARG_CASE(_C_CHR, char); + _OBJCL_ARG_CASE(_C_UCHR, char); + _OBJCL_ARG_CASE(_C_SHT, short); + _OBJCL_ARG_CASE(_C_USHT, short); _OBJCL_ARG_CASE(_C_INT, int); - _OBJCL_ARG_CASE(_C_UINT, unsigned int); + _OBJCL_ARG_CASE(_C_UINT, int); _OBJCL_ARG_CASE(_C_LNG, long); - _OBJCL_ARG_CASE(_C_ULNG, unsigned long); - _OBJCL_ARG_CASE(_C_LNG_LNG, long long); - _OBJCL_ARG_CASE(_C_ULNG_LNG, unsigned long long); - _OBJCL_ARG_CASE(_C_FLT, double); + _OBJCL_ARG_CASE(_C_ULNG, long); + _OBJCL_ARG_CASE(_C_LNG_LNG, long_long); + _OBJCL_ARG_CASE(_C_ULNG_LNG, long_long); + _OBJCL_ARG_CASE(_C_FLT, float); _OBJCL_ARG_CASE(_C_DBL, double); - _OBJCL_ARG_CASE(_C_BOOL, int); - _OBJCL_ARG_CASE(_C_PTR, void *); - _OBJCL_ARG_CASE(_C_CHARPTR, char *); + _OBJCL_ARG_CASE(_C_BOOL, bool); + _OBJCL_ARG_CASE(_C_PTR, ptr); + _OBJCL_ARG_CASE(_C_CHARPTR, charptr); /* _OBJCL_ARG_CASE(_C_VOID, void); _OBJCL_ARG_CASE(_C_BFLD, bitfield); @@ -88,13 +65,14 @@ _objcl_get_arg_pointer (void *buffer, const char *type, va_list arglist) */ case _C_UNDEF: default: - NSLog (@"Dammit. What the heck is `%s' supposed to mean?", type); + NSLog (@"Dammit. What the heck is `%s' supposed to mean?", + argdata->type); break; } } -void * +static void * _objcl_invoke_method (id self_, NSMethodSignature *signature, SEL selector, @@ -103,13 +81,55 @@ _objcl_invoke_method (id self_, { int i; NSInvocation *invocation; - id result = NULL; + void *result_ptr = NULL; + OBJCL_OBJ_DATA result = malloc (sizeof (struct objcl_object)); + const char *type = [signature methodReturnType]; + + result->type = malloc (strlen (type) + 1); + strcpy (result->type, type); if (signature == NULL) { return NULL; } + + switch (type[0]) + { + case _C_ID: result_ptr = &(result->data.id_val); break; + case _C_CLASS: result_ptr = &result->data.id_val; break; + case _C_SEL: result_ptr = &result->data.sel_val; break; + case _C_CHR: result_ptr = &result->data.char_val; break; + case _C_UCHR: result_ptr = &result->data.char_val; break; + case _C_SHT: result_ptr = &result->data.short_val; break; + case _C_USHT: result_ptr = &result->data.short_val; break; + case _C_INT: result_ptr = &result->data.int_val; break; + case _C_UINT: result_ptr = &result->data.int_val; break; + case _C_LNG: result_ptr = &result->data.long_val; break; + case _C_ULNG: result_ptr = &result->data.long_val; break; + case _C_LNG_LNG: result_ptr = &result->data.long_long_val; break; + case _C_ULNG_LNG: result_ptr = &result->data.long_long_val; break; + case _C_FLT: result_ptr = &result->data.float_val; break; + case _C_DBL: result_ptr = &result->data.double_val; break; + case _C_BOOL: result_ptr = &result->data.bool_val; break; + case _C_PTR: result_ptr = &result->data.ptr_val; break; + case _C_CHARPTR: result_ptr = &result->data.charptr_val; break; + /* + case _C_BFLD: result_ptr = &result->data._val; break; + case _C_VOID: result_ptr = &result->data._val; break; + case _C_UNDEF: result_ptr = &result->data._val; break; + case _C_ATOM: result_ptr = &result->data._val; break; + case _C_ARY_B: result_ptr = &result->data._val; break; + case _C_ARY_E: result_ptr = &result->data._val; break; + case _C_UNION_B: result_ptr = &result->data._val; break; + case _C_UNION_E: result_ptr = &result->data._val; break; + case _C_STRUCT_B: result_ptr = &result->data._val; break; + case _C_STRUCT_E: result_ptr = &result->data._val; break; + case _C_VECTOR: result_ptr = &result->data._val; break; + case _C_COMPLEX: result_ptr = &result->data._val; break; + */ + } + invocation = [NSInvocation invocationWithMethodSignature: signature]; [invocation setTarget: self_]; [invocation setSelector: selector]; @@ -117,10 +137,14 @@ _objcl_invoke_method (id self_, for (i = 0; i < argc; i++) { const char* type = [signature getArgumentTypeAtIndex: (i + 2)]; - NSLog (@"Argument %d: type %s.", i, type); - void *buffer = malloc (objc_sizeof_type (type)); - _objcl_get_arg_pointer (buffer, type, arglist); + OBJCL_OBJ_DATA arg = va_arg (arglist, OBJCL_OBJ_DATA); + _objcl_get_arg_pointer (buffer, arg); + + if (type[0] == '#') + NSLog (@"Argument %d: %@ (type %s)", i, buffer, type); + else + NSLog (@"Argument %d: type %s.", i, type); [invocation setArgument: buffer atIndex: (i + 2)]; @@ -132,16 +156,17 @@ _objcl_invoke_method (id self_, NSLog (@"Invoking %@ on %@.", invocation, self_); [invocation invoke]; NSLog (@"Fetching return value."); - [invocation getReturnValue: &result]; - NSLog (@"Returning: %@", result); + [invocation getReturnValue: result_ptr]; + if (result->type[0] == '#') + NSLog (@"Returning: %@", result->data.id_val); return result; } void * -objcl_invoke_instance_method (void *receiver, - char *const method_name, +objcl_invoke_instance_method (OBJCL_OBJ_DATA receiver, + const char *method_name, int argc, ...) { @@ -151,7 +176,9 @@ objcl_invoke_instance_method (void *receiver, NSMethodSignature *signature; void *result; - self_ = (id) receiver; + assert (receiver->type[0] == '#' + || receiver->type[0] == '@'); + self_ = receiver->data.id_val; selector = NSSelectorFromString ([NSString stringWithUTF8String: method_name]); @@ -166,8 +193,8 @@ objcl_invoke_instance_method (void *receiver, void * -objcl_invoke_class_method (void *class, - char *const method_name, +objcl_invoke_class_method (OBJCL_OBJ_DATA class, + const char *method_name, int argc, ...) { @@ -177,7 +204,9 @@ objcl_invoke_class_method (void *class, NSMethodSignature *signature; void *result; - self_ = (id) class; + assert (class->type[0] == '#' + || class->type[0] == '@'); + self_ = class->data.id_val; selector = NSSelectorFromString ([NSString stringWithUTF8String: method_name]); @@ -192,8 +221,16 @@ objcl_invoke_class_method (void *class, void * -objcl_find_class (char *const class_name) +objcl_find_class (const char *class_name) { - return NSClassFromString ([NSString stringWithUTF8String: class_name]); -} + id class = + NSClassFromString ([NSString stringWithUTF8String: class_name]); + OBJCL_OBJ_DATA result = malloc (sizeof (struct objcl_object)); + const char *const typespec = "#8@0:4"; + + result->type = malloc (strlen (typespec) + 1); + strcpy (result->type, typespec); + result->data.id_val = class; + return result; +} -- cgit v1.2.3