// // DPObjC-Compatibility.h // HigherOrderMessaging // // Created by Ofri Wolfus on 28/10/06. // Copyright 2006 Ofri Wolfus. All rights reserved. // #ifndef _DP_OBJC_COMPATIBILITY_H #define _DP_OBJC_COMPATIBILITY_H #import /************************************** * Objective-C v1 * **************************************/ #pragma mark - #pragma mark Objective-C I /* Stuff that exist in the Objective-C 2 runtime, but not in v1 */ #if !__OBJC2__ #include #include // Although this is defined in Object.h, looking at the runtime's source // shows it actually does nothing. #define object_dispose(o) free(o) // // Methods manipulation // #define method_getName(m) (m->method_name) #define method_getImplementation(m) (m->method_imp) #define method_getTypeEncoding(m) (m->method_types) #define method_setImplementation(m, imp) ({IMP __r = m->method_imp; m->method_imp = imp; __r;}) DP_EXTERN char *method_copyReturnType(Method m); DP_EXTERN char *method_copyArgumentType(Method m, unsigned int index); DP_EXTERN void method_getReturnType(Method m, char *dst, size_t dst_len); DP_EXTERN void method_getArgumentType(Method m, unsigned int index, char *dst, size_t dst_len); // // Class manipulation // #define class_getName(cls) (((Class)cls)->name) #define class_getSuperclass(cls) (((Class)cls)->super_class) #define class_getInstanceSize(cls) (((Class)cls)->instance_size) // // Selectors // /* Shouldn't this work with the new runtime as well? */ #define sel_isEqual(s1, s2) (s1 == s2) // // Classes and objects inspection // #define class_isMetaClass(cls) ((((Class)cls)->info & CLS_META) != 0) #define object_getClass(obj) (obj->isa) DP_EXTERN BOOL class_respondsToSelector(Class cls, SEL sel); #define class_getSuperclass(cls) (((Class)cls)->super_class) // #define _CLS_IS_CLASS(cls) ((((Class)cls)->info & CLS_CLASS) != 0) #define _CLS_IS_META(cls) ((((Class)cls)->info & CLS_META) != 0) #define _CLS_GET_META(cls) (_CLS_IS_META(cls) ? cls : cls->isa) // // Missing types // #define _C_CONST 'r' /************************************** * Objective-C v2 * **************************************/ #pragma mark - #pragma mark Objective-C II /* Compatibility with the older Objective-C runtime */ #else // ObjC 2 #include #include #include // For uintptr_t #include // For malloc_size #endif // !__OBJC2__ #pragma mark - // These are defined in the GNU runtime but not in Apple's runtime, // although the characters are the same. #ifndef _C_IN #define _C_IN 'n' #endif #ifndef _C_INOUT #define _C_INOUT 'N' #endif #ifndef _C_OUT #define _C_OUT 'o' #endif #ifndef _C_BYCOPY #define _C_BYCOPY 'O' #endif #ifndef _C_BYREF #define _C_BYREF 'R' #endif #ifndef _C_ONEWAY #define _C_ONEWAY 'V' #endif // // Working with marg_list // /* PPC and PPC64 */ #if defined(__ppc__) || defined(__ppc64__) #if __OBJC2__ typedef ppc_marg_list dp_ppc_marg_list; typedef ppc64_marg_list dp_ppc64_marg_list; #else typedef struct { double fpParams[13]; // F1..F13 uintptr_t linkage[6]; // ignored by objc_msgSendv; do not modify uintptr_t regParams[8]; // R3..R10; objc_msgSendv ignores R3 and R4 uintptr_t stackParams[0]; // variable-size } *dp_ppc_marg_list, *dp_ppc64_marg_list; #endif #define dp_marg_size (13 * sizeof(double) + (6 + 8) * sizeof(uintptr_t)) #define dp_marg_var_space (8 * sizeof(uintptr_t) /* regParams */) /* i386 */ #elif defined(__i386__) #if __OBJC2__ typedef x86_marg_list dp_x86_marg_list; typedef i386_marg_list dp_i386_marg_list; #else typedef struct { uintptr_t params[0]; // variable-size } *dp_x86_marg_list, *dp_i386_marg_list; #endif // i386 passes arguments on stack #define dp_marg_size 0 #define dp_marg_var_space 0 /* x86-64 */ #elif defined(__x86_64__) #if __OBJC2__ /*typedef struct { union { double double_val; // __float128 float128_val; char _size_pad[16]; } fpParams[8]; // xmm0..xmm7 uintptr_t r10; // static chain, if any uintptr_t rax; // number of xmm registers used uintptr_t linkage[2]; // ignored by objc_msgSendv; do not modify uintptr_t regParams[6]; // rdi, rsi, rdx, rcx, r8, r9 uintptr_t stackParams[0]; // variable-size } *dp_x86_64_marg_list;*/ typedef x86_64_marg_list dp_x86_64_marg_list; #define dp_marg_size ( (sizeof(double) + sizeof(char) * 16) * 8 /* fpParams */\ + sizeof(uintptr_t) * 10 /* r10 + rax + linkage + regParams */) #define dp_marg_var_space (6 * sizeof(uintptr_t) /* regParams */) #else // __ObjC2__ #error x86-64 is not supported for ObjC 1 #endif #else // PPC, PPC64, i386, x86-64 # error unknown architecture #endif // PPC, PPC64, i386, x86-64 //#define dp_marg_size sizeof(dp_marg_list) /* * This is the fixed size of the marg_list. * This size plus the size returned from method_getSizeOfArguments() * is the total size of the arguments list. * Use dp_marg_alloc() for marg_list allocation. */ #define dp_marg_prearg_size (dp_marg_size - dp_marg_var_space) /* * If you need to work with marg_list, use dp_marg_list which works on all architectures * and both on ObjC 1 and 2. * An abstraction layer for modifying the contents of the arguments list is not yet * supported, so you'll have to be very careful and read the function calling ABI * of your target architectures. */ #if defined(__ppc__) || defined(__ppc64__) typedef dp_ppc_marg_list dp_marg_list; #elif defined(__i386__) typedef dp_i386_marg_list dp_marg_list; #elif defined(__x86_64__) typedef dp_x86_64_marg_list dp_marg_list; #else # error unknown architecture #endif #endif // _DP_OBJC_COMPATIBILITY_H