From 3e9cccc84db3c9d9229154793fce3b0b4e848285 Mon Sep 17 00:00:00 2001 From: Matthias Benkard Date: Sat, 15 Sep 2007 17:57:23 +0200 Subject: Objective-C layer: Implement objcl_invoke_with_types. darcs-hash:48fc78847f6466537cec456aa2819dd1dcf0733b --- Objective-C/libobjcl.h | 7 ++++--- Objective-C/libobjcl.m | 53 +++++++++++++++++++++++++++++++++++++------------- 2 files changed, 43 insertions(+), 17 deletions(-) (limited to 'Objective-C') diff --git a/Objective-C/libobjcl.h b/Objective-C/libobjcl.h index 5e1af6d..236cd3a 100644 --- a/Objective-C/libobjcl.h +++ b/Objective-C/libobjcl.h @@ -53,11 +53,12 @@ objcl_invoke_method (OBJCL_OBJ_DATA receiver, void objcl_invoke_with_types (void *receiver, SEL method_selector, - char *(types[]), id *exception, - void *return_value, int argc, - ...); + char *return_typespec, + char *arg_typespecs[], + void *return_value, + void **argv); OBJCL_OBJ_DATA objcl_find_class (const char *class_name); diff --git a/Objective-C/libobjcl.m b/Objective-C/libobjcl.m index 9d04347..18b76ad 100644 --- a/Objective-C/libobjcl.m +++ b/Objective-C/libobjcl.m @@ -1,7 +1,10 @@ /* -*- mode: objc; coding: utf-8 -*- */ #import "libobjcl.h" -#import "Foundation/Foundation.h" +#import "libffi_support.h" +#import "objc_support.h" + +#import #include #include @@ -263,38 +266,59 @@ objcl_invoke_method (OBJCL_OBJ_DATA receiver, } +#ifdef USE_LIBFFI void objcl_invoke_with_types (void *receiver, SEL method_selector, - char *types[], id *exception, - void *return_value, int argc, - ...) + char *return_typespec, + char *arg_typespecs[], + void *return_value, + void **argv) { va_list arglist; IMP method; int i; + void *tmp_arg; + ffi_cif cif; + ffi_type *return_type; + ffi_type *arg_types[argc + 2]; + ffi_status status; - char *return_type = types[0]; - char **arg_types = types + 1; + static ffi_type *id_type = NULL; + static ffi_type *sel_type = NULL; - *exception = NULL; + if (!id_type) + id_type = objcl_pyobjc_arg_signature_to_ffi_type ("@"); + if (!sel_type) + sel_type = objcl_pyobjc_arg_signature_to_ffi_type (":"); + NS_DURING + { #ifdef __NEXT_RUNTIME__ - method = class_getInstanceMethod ([((id) receiver) class], method_selector)->method_imp; + method = class_getInstanceMethod ([((id) receiver) class], method_selector)->method_imp; #else - method = objc_msg_lookup (receiver, method_selector); + method = objc_msg_lookup (receiver, method_selector); #endif - NS_DURING - { - va_start (arglist, argc); + *exception = NULL; + return_type = objcl_pyobjc_signature_to_ffi_return_type (return_typespec); + arg_types[0] = id_type; + arg_types[1] = sel_type; + for (i = 0; i < argc; i++) + arg_types[i + 2] = objcl_pyobjc_arg_signature_to_ffi_type (arg_typespecs[i]); + + status = ffi_prep_cif (&cif, FFI_DEFAULT_ABI, argc + 2, return_type, arg_types); + if (status != FFI_OK) { - va_arg_with_type (arglist, arg_types[i]); + [[NSException exceptionWithName: @"MLKInvalidFFITypeException" + reason: @"FFI type is invalid (this is probably a bug)." + userInfo: nil] raise]; } - va_end (arglist); + + ffi_call (&cif, (void *) method, return_value, argv); } NS_HANDLER { @@ -303,6 +327,7 @@ objcl_invoke_with_types (void *receiver, } NS_ENDHANDLER } +#endif OBJCL_OBJ_DATA -- cgit v1.2.3