From ee655320c5060ec9283a598170756570e03a2543 Mon Sep 17 00:00:00 2001 From: Matthias Benkard Date: Sat, 15 Sep 2007 12:45:05 +0200 Subject: Add some support files from PyObjC. darcs-hash:9abac9aee8a4843a399d1c6472b32ff3bc3aa0ee --- Objective-C/objc-runtime-gnu.m | 216 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 Objective-C/objc-runtime-gnu.m (limited to 'Objective-C/objc-runtime-gnu.m') diff --git a/Objective-C/objc-runtime-gnu.m b/Objective-C/objc-runtime-gnu.m new file mode 100644 index 0000000..0f585e1 --- /dev/null +++ b/Objective-C/objc-runtime-gnu.m @@ -0,0 +1,216 @@ +/* This file is part of the PyObjC package. */ +/* + * Support code for the GNU runtime + * + * NOTE: This file uses some private functions in the GNU runtime as that seems + * to be the only way to properly interface with that runtime. + */ +#include "pyobjc.h" + +#if defined(GNU_RUNTIME) + +struct objc_protocol_list* PyObjCRT_AllocProtocolList(int numProtocols) +{ + struct objc_protocol_list *plist; + + plist = malloc(sizeof(struct objc_protocol_list) + + ((numProtocols+1) * sizeof(Protocol *))); + + if (plist == NULL) { + return NULL; + } + + plist->count = 0; + plist->next = NULL; + + return plist; +} + +int PyObjCRT_SetupClass( + Class cls, + Class metaCls, + const char*name, + Class superCls, + Class rootCls, + int ivarSize, + struct objc_ivar_list* ivarList, + struct objc_protocol_list* protocolList +) + +{ + /* This is a private function, but seems to be the only way to + * really create the class. + */ + extern void __objc_install_premature_dtable (Class); + + /* Initialize the structure */ + memset(cls, 0, sizeof(*cls)); + memset(metaCls, 0, sizeof(*cls)); + + cls->version = 0; + metaCls->version = 0; + cls->subclass_list = NULL; + metaCls->subclass_list = NULL; + cls->sibling_class = NULL; + metaCls->sibling_class = NULL; + + cls->methods = NULL; + metaCls->methods = NULL; + cls->class_pointer = metaCls; + + cls->info = CLS_CLASS; + metaCls->info = CLS_META; + + cls->name = strdup(name); + if (cls->name == NULL) { + return -1; + } + metaCls->name = strdup(name); + if (metaCls->name == NULL) { + free((char*)(cls->name)); + cls->name = NULL; + return -1; + } + + cls->methods = NULL; + metaCls->methods = NULL; + + cls->super_class = superCls; + metaCls->super_class = superCls->class_pointer; + metaCls->class_pointer = rootCls->class_pointer; + CLS_SETRESOLV(cls); + CLS_SETRESOLV(metaCls); + + cls->instance_size = ivarSize; + cls->ivars = ivarList; + + metaCls->instance_size = metaCls->super_class->instance_size; + metaCls->ivars = NULL; + + metaCls->protocols = cls->protocols = protocolList; + + metaCls->dtable = objc_get_uninstalled_dtable(); + cls->dtable = objc_get_uninstalled_dtable(); + + return 0; +} + +void PyObjCRT_AddClass(Class cls) +{ + cls->sibling_class = cls->super_class->subclass_list; + cls->super_class->subclass_list = cls; + cls->class_pointer->sibling_class = cls->super_class->class_pointer->subclass_list; + cls->super_class->class_pointer->subclass_list = cls->class_pointer; + __objc_add_class_to_hash(cls); +} + + +void PyObjCRT_ClearClass(Class cls) +{ + if (cls->methods) { + MethodList_t next, cur; + + cur = cls->methods; + + while (cur != NULL) { + next = cur->method_next; + + objc_free(cur); + cur = next; + } + cls->methods = NULL; + } + + if (cls->name) { + free((char*)(cls->name)); + cls->name = NULL; + } +} + +struct objc_method_list *PyObjCRT_AllocMethodList(int numMethods) +{ + struct objc_method_list *mlist; + + mlist = objc_malloc(sizeof(struct objc_method_list) + + ((numMethods+1) * sizeof(struct objc_method))); + + if (mlist == NULL) { + return NULL; + } + + mlist->method_count = 0; + mlist->method_next = NULL; + + return mlist; +} + +/* + * XXX: This functions should be renamed to avoid name classes with + * the actual ObjC runtime + */ + +Ivar_t class_getInstanceVariable(Class aClass, const char *name) +{ + if (!aClass || !name) + return NULL; + + for (; aClass != Nil; aClass = aClass->super_class) + { + int i; + + if (!aClass->ivars) + continue; + + for (i = 0; i < aClass->ivars->ivar_count; i++) + { + if (!strcmp(aClass->ivars->ivar_list[i].ivar_name, name)) + return &aClass->ivars->ivar_list[i]; + } + } + + return NULL; +} + +Ivar_t object_getInstanceVariable(id obj, const char *name, void **out) +{ + Ivar_t var = NULL; + + if (obj && name) + { + void **varIndex = NULL; + + if ((var = class_getInstanceVariable(obj->class_pointer, name))) + varIndex = (void **)((char *)obj + var->ivar_offset); + + if (out) + *out = *varIndex; + } + + return var; +} + +Ivar_t object_setInstanceVariable(id obj, const char *name, void *value) +{ + Ivar_t var = NULL; + + if (obj && name) + { + void **varIndex; + + if ((var = class_getInstanceVariable(obj->class_pointer, name))) + { + varIndex = (void **)((char *)obj + var->ivar_offset); + + *varIndex = value; + } + } + + return var; +} + + +#else /* !GNU_RUNTIME */ + +static int dummy __attribute__((__unused__)); + +#endif /* !GNU_RUNTIME */ -- cgit v1.2.3