// // DPObjCRuntime.h // HigherOrderMessaging // // Created by Ofri Wolfus on 03/11/06. // Copyright 2006 Ofri Wolfus. All rights reserved. // #ifndef _DP_OBJCRUNTIME_H #define _DP_OBJCRUNTIME_H #import #import // // Size and alignment of types // #if __OBJC2__ #define sizeOfType(t...) ({ NSUInteger __s; NSGetSizeAndAlignment(t, &__s, NULL); __s; }) #define alignOfType(t...) ({ NSUInteger __s; NSGetSizeAndAlignment(t, NULL, &__s); __s; }) #else #define sizeOfType(t...) ({ unsigned int __s; NSGetSizeAndAlignment(t, &__s, NULL); __s; }) #define alignOfType(t...) ({ unsigned int __s; NSGetSizeAndAlignment(t, NULL, &__s); __s; }) #endif // // Type descriptions // DP_EXTERN unsigned dp_getNumberOfArguments(const char *typedesc); DP_EXTERN unsigned dp_getArgumentInfo(const char *typedesc, int argIndex, const char** type, int* offset); DP_EXTERN unsigned dp_getSizeOfArguments(const char *typedesc); // // Classes and objects inspection // #define class_isClass(cls) class_isMetaClass(cls->isa) DP_EXTERN BOOL class_isSubclassOfClass(Class cls, Class superCls); #define object_isInstance(obj) class_isClass(obj->isa) #define object_getClass(obj) (obj->isa) #define object_isKindOfClass(obj, superCls) class_isSubclassOfClass(object_getClass(obj), superCls) DP_EXTERN_INLINE BOOL object_respondsToSelector(id object, SEL sel); // Handles both objects and classes DP_EXTERN_INLINE Method dp_getMethod(id obj, SEL sel); DP_STATIC_INLINE Class dp_getSuper(Class cls, const char *name) { while ((cls = class_getSuperclass(cls))) if (strcmp(class_getName(cls), name) == 0) return cls; return Nil; } #define Super(name, X...) \ method_getImplementation(class_getInstanceMethod(dp_getSuper(object_isInstance(self) ? \ object_getClass(self) : self, #name),\ _cmd), _cmd)(self, _cmd, X) // // Selectors // DP_EXTERN_INLINE unsigned int sel_getNumberOfArguments(SEL sel); // Always takes the self and _cmd arguments in count // // Method description // /* * If you need the method's implementation, you should use MethodDescription * instead of Method/objc_method and objc_method_description. */ struct dp_method_description { // Identical to objc_method_description SEL name; char *types; }; typedef struct dp_method_description *MethodDescription; DP_EXTERN_INLINE SEL description_getName(MethodDescription desc); DP_EXTERN_INLINE const char *description_getTypes(MethodDescription desc); DP_EXTERN_INLINE void description_setName(MethodDescription desc, SEL name); DP_EXTERN_INLINE void description_setTypes(MethodDescription desc, const char *types /* Not copied */); // Returns a MethodDescription from a given method #define dp_getMethodDescription(m) \ ({ \ struct dp_method_description __desc; \ description_setName(&__desc, method_getName(m)); \ description_setTypes(&__desc, method_getTypeEncoding(m)); \ &__desc; \ }) // Copies a MethodDescription from a given method DP_EXTERN_INLINE MethodDescription dp_copyMethodDescription(Method m); //DP_EXTERN_INLINE void description_free(MethodDescription d); DP_EXTERN_INLINE unsigned description_getNumberOfArguments(MethodDescription d); DP_EXTERN_INLINE unsigned description_getArgumentInfo(MethodDescription d, int argIndex, const char** type, int* offset); DP_EXTERN_INLINE unsigned description_getSizeOfArguments(MethodDescription d); DP_EXTERN_INLINE MethodDescription description_createDescription(SEL name, const char *types); // // Allocation/copying of marg_list // #define dp_marg_malloc(argsSize) malloc(dp_marg_prearg_size + (7 + argsSize & ~7) /* <- huh? */) #define dp_marg_alloc(method) dp_marg_malloc(method_getSizeOfArguments(method)) #define dp_marg_copy(margs, method) \ ({ marg_list __marg = dp_marg_alloc(method); memcpy(__marg, margs, malloc_size(__marg)); }) // // Getting arguments // //DP_EXTERN_INLINE void dp_getArgumentAtIndex(dp_marg_list args, unsigned index, void *buffer); // // Messaging // DP_EXTERN id dp_msgSendv(id target, SEL sel, unsigned args_size, marg_list args); #endif //_DP_OBJCRUNTIME_H