summaryrefslogtreecommitdiff
path: root/libobjcl.m
diff options
context:
space:
mode:
authorMatthias Benkard <code@mail.matthias.benkard.de>2007-08-03 15:03:08 +0200
committerMatthias Benkard <code@mail.matthias.benkard.de>2007-08-03 15:03:08 +0200
commit4b6286e29cf106584566c6d77009f3a4b3e3ed39 (patch)
tree68dc74ec1a9f5485eed4163be8a8658e98251a51 /libobjcl.m
parent714a595eb34406d75ce250477e7042c85c3ad95e (diff)
Use tagged data on both the Lisp and C sides.
darcs-hash:d32babb07560cbb4f8db5467b31a7e92534eeb0d
Diffstat (limited to 'libobjcl.m')
-rw-r--r--libobjcl.m157
1 files changed, 97 insertions, 60 deletions
diff --git a/libobjcl.m b/libobjcl.m
index 7aac299..bd59810 100644
--- a/libobjcl.m
+++ b/libobjcl.m
@@ -6,7 +6,7 @@
#include <objc/objc-api.h>
-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;
+}