From 714a595eb34406d75ce250477e7042c85c3ad95e Mon Sep 17 00:00:00 2001 From: Matthias Benkard Date: Thu, 2 Aug 2007 21:04:10 +0200 Subject: Beginnings of an Objective C bridge. darcs-hash:907cb9b5f058df6c6697bc71a309edeb976998ff --- libobjcl.m | 199 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 libobjcl.m (limited to 'libobjcl.m') diff --git a/libobjcl.m b/libobjcl.m new file mode 100644 index 0000000..7aac299 --- /dev/null +++ b/libobjcl.m @@ -0,0 +1,199 @@ +/* -*- mode: objc; coding: utf-8 -*- */ + +#import "libobjcl.h" +#import "Foundation/Foundation.h" +#include +#include + + +NSAutoreleasePool *objcl_autorelease_pool = NULL; + + +void +objcl_initialise_runtime () +{ + objcl_autorelease_pool = [[NSAutoreleasePool alloc] init]; +} + + +void +objcl_shutdown_runtime () +{ + [objcl_autorelease_pool release]; +} + + +#define _OBJCL_ARG_DECL(typespec, c_type) \ + c_type __##typespec##_tmp + + +#define _OBJCL_ARG_CASE(typespec, c_type) \ + case typespec: \ + __##typespec##_tmp = va_arg (arglist, c_type); \ + memmove (buffer, &__##typespec##_tmp, objc_sizeof_type (type)); \ + break; + + +void +_objcl_get_arg_pointer (void *buffer, const char *type, va_list arglist) +{ + _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]) + { + _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_INT, int); + _OBJCL_ARG_CASE(_C_UINT, unsigned 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_DBL, double); + _OBJCL_ARG_CASE(_C_BOOL, int); + _OBJCL_ARG_CASE(_C_PTR, void *); + _OBJCL_ARG_CASE(_C_CHARPTR, char *); +/* + _OBJCL_ARG_CASE(_C_VOID, void); + _OBJCL_ARG_CASE(_C_BFLD, bitfield); + _OBJCL_ARG_CASE(_C_ATOM, atom); + _OBJCL_ARG_CASE(_C_ARY_B, ); + _OBJCL_ARG_CASE(_C_UNION_B, ); + _OBJCL_ARG_CASE(_C_STRUCT_B, ); + _OBJCL_ARG_CASE(_C_VECTOR, ); + _OBJCL_ARG_CASE(_C_COMPLEX, ); +*/ + case _C_UNDEF: + default: + NSLog (@"Dammit. What the heck is `%s' supposed to mean?", type); + break; + } +} + + +void * +_objcl_invoke_method (id self_, + NSMethodSignature *signature, + SEL selector, + int argc, + va_list arglist) +{ + int i; + NSInvocation *invocation; + id result = NULL; + + if (signature == NULL) + { + return NULL; + } + + invocation = [NSInvocation invocationWithMethodSignature: signature]; + [invocation setTarget: self_]; + [invocation setSelector: selector]; + + 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); + + [invocation setArgument: buffer + atIndex: (i + 2)]; + + free (buffer); + } + + [invocation retainArguments]; + NSLog (@"Invoking %@ on %@.", invocation, self_); + [invocation invoke]; + NSLog (@"Fetching return value."); + [invocation getReturnValue: &result]; + NSLog (@"Returning: %@", result); + + return result; +} + + +void * +objcl_invoke_instance_method (void *receiver, + char *const method_name, + int argc, + ...) +{ + va_list arglist; + id self_; + SEL selector; + NSMethodSignature *signature; + void *result; + + self_ = (id) receiver; + selector = NSSelectorFromString ([NSString + stringWithUTF8String: method_name]); + + signature = [self_ instanceMethodSignatureForSelector: selector]; + + va_start (arglist, argc); + result = _objcl_invoke_method (self_, signature, selector, argc, arglist); + va_end (arglist); + + return result; +} + + +void * +objcl_invoke_class_method (void *class, + char *const method_name, + int argc, + ...) +{ + va_list arglist; + id self_; + SEL selector; + NSMethodSignature *signature; + void *result; + + self_ = (id) class; + selector = NSSelectorFromString ([NSString + stringWithUTF8String: method_name]); + + signature = [self_ methodSignatureForSelector: selector]; + + va_start (arglist, argc); + result = _objcl_invoke_method (self_, signature, selector, argc, arglist); + va_end (arglist); + + return result; +} + + +void * +objcl_find_class (char *const class_name) +{ + return NSClassFromString ([NSString stringWithUTF8String: class_name]); +} + -- cgit v1.2.3