From 7cea2578637b823e93798e308ab0811c7fd7b7a4 Mon Sep 17 00:00:00 2001 From: Matthias Benkard Date: Mon, 28 Jan 2008 19:17:00 +0100 Subject: Directory layout: Put code imported from PyObjC into its own directory. darcs-hash:e3dd1138105e4eece0fbcbc13365eb3a25ffb808 --- Objective-C/GNUmakefile | 7 +- Objective-C/PyObjC/libffi_support.h | 21 ++ Objective-C/PyObjC/libffi_support.m | 401 +++++++++++++++++++++++++ Objective-C/PyObjC/objc-runtime-apple.h | 137 +++++++++ Objective-C/PyObjC/objc-runtime-apple.m | 159 ++++++++++ Objective-C/PyObjC/objc-runtime-gnu.h | 174 +++++++++++ Objective-C/PyObjC/objc-runtime-gnu.m | 217 ++++++++++++++ Objective-C/PyObjC/objc_support.h | 46 +++ Objective-C/PyObjC/objc_support.m | 505 ++++++++++++++++++++++++++++++++ Objective-C/PyObjC/pyobjc.h | 46 +++ Objective-C/libffi_support.h | 21 -- Objective-C/libffi_support.m | 401 ------------------------- Objective-C/libobjcl.m | 4 +- Objective-C/objc-runtime-apple.h | 137 --------- Objective-C/objc-runtime-apple.m | 159 ---------- Objective-C/objc-runtime-gnu.h | 174 ----------- Objective-C/objc-runtime-gnu.m | 217 -------------- Objective-C/objc_support.h | 46 --- Objective-C/objc_support.m | 505 -------------------------------- Objective-C/pyobjc.h | 46 --- 20 files changed, 1712 insertions(+), 1711 deletions(-) create mode 100644 Objective-C/PyObjC/libffi_support.h create mode 100644 Objective-C/PyObjC/libffi_support.m create mode 100644 Objective-C/PyObjC/objc-runtime-apple.h create mode 100644 Objective-C/PyObjC/objc-runtime-apple.m create mode 100644 Objective-C/PyObjC/objc-runtime-gnu.h create mode 100644 Objective-C/PyObjC/objc-runtime-gnu.m create mode 100644 Objective-C/PyObjC/objc_support.h create mode 100644 Objective-C/PyObjC/objc_support.m create mode 100644 Objective-C/PyObjC/pyobjc.h delete mode 100644 Objective-C/libffi_support.h delete mode 100644 Objective-C/libffi_support.m delete mode 100644 Objective-C/objc-runtime-apple.h delete mode 100644 Objective-C/objc-runtime-apple.m delete mode 100644 Objective-C/objc-runtime-gnu.h delete mode 100644 Objective-C/objc-runtime-gnu.m delete mode 100644 Objective-C/objc_support.h delete mode 100644 Objective-C/objc_support.m delete mode 100644 Objective-C/pyobjc.h (limited to 'Objective-C') diff --git a/Objective-C/GNUmakefile b/Objective-C/GNUmakefile index c69d1d7..7401667 100644 --- a/Objective-C/GNUmakefile +++ b/Objective-C/GNUmakefile @@ -33,7 +33,7 @@ LIBRARY_NAME = libobjcl RPM_DISABLE_RELOCATABLE = YES ADDITIONAL_OBJCFLAGS = -Wall -g -DVERSION=\"$(VERSION)\" -I/usr/local/include -libobjcl_OBJC_FILES = libobjcl.m objc_support.m objc-runtime-apple.m objc-runtime-gnu.m +libobjcl_OBJC_FILES = libobjcl.m PyObjC/objc_support.m PyObjC/objc-runtime-apple.m PyObjC/objc-runtime-gnu.m LIBRARIES_DEPEND_UPON = $(FND_LIBS) $(GUI_LIBS) $(OBJC_LIBS) $(SYSTEM_LIBS) $(CONFIG_SYSTEM_LIBS) ADDITIONAL_LDFLAGS = $(LIBS) @@ -49,13 +49,14 @@ ADDITIONAL_OBJCFLAGS += -I../libffi/include FFI_DEPS += ../libffi/.libs/libffi.a FFI_CLEAN += libffi_clean endif -libobjcl_OBJC_FILES += libffi_support.m +libobjcl_OBJC_FILES += PyObjC/libffi_support.m endif ifneq ($(COMMON_MAKE_LOADED),) -include $(GNUSTEP_MAKEFILES)/library.make before-all:: $(FFI_DEPS) + mkdir -p $(GNUSTEP_OBJ_DIR)/PyObjC after-clean:: $(FFI_CLEAN) @@ -77,7 +78,7 @@ obj/libobjcl.dylib.$(VERSION): $(libobjcl_OBJ_FILES) gcc -dynamiclib -current_version $(VERSION) -flat_namespace -undefined warning -install_name $(CURDIR)/obj/libobjcl.dylib.$(VERSION) -o $@ $(libobjcl_OBJ_FILES) -fnext-runtime -framework AppKit -framework Foundation -lm $(ADDITIONAL_LDFLAGS) $(ADDITIONAL_OBJCFLAGS) obj/%.o: %.m - mkdir -p obj + mkdir -p $(dir $@) gcc -o $@ -c $< -MMD -MP -DNeXT_Foundation_LIBRARY=1 -DNeXT_GUI_LIBRARY=1 -DNeXT_RUNTIME=1 -dynamic -fno-common -fno-omit-frame-pointer -Wno-import -fno-strict-aliasing -fnext-runtime -I. $(ADDITIONAL_OBJCFLAGS) endif diff --git a/Objective-C/PyObjC/libffi_support.h b/Objective-C/PyObjC/libffi_support.h new file mode 100644 index 0000000..ca04c6b --- /dev/null +++ b/Objective-C/PyObjC/libffi_support.h @@ -0,0 +1,21 @@ +#ifndef PyObjC_FFI_SUPPORT_H +#define PyObjC_FFI_SUPPORT_H + +#ifdef USE_LIBFFI +#ifdef HAVE_FFI_H +#include +#elif HAVE_FFI_FFI_H +#include +#else +/* We are using our own build of libffi. */ +#include +#endif +#endif + +ffi_type* +objcl_pyobjc_signature_to_ffi_return_type (const char* argtype); + +ffi_type* +objcl_pyobjc_arg_signature_to_ffi_type (const char* argtype); + +#endif /* PyObjC_FFI_SUPPORT_H */ diff --git a/Objective-C/PyObjC/libffi_support.m b/Objective-C/PyObjC/libffi_support.m new file mode 100644 index 0000000..4bc1137 --- /dev/null +++ b/Objective-C/PyObjC/libffi_support.m @@ -0,0 +1,401 @@ +/* + * Support for libffi (http://sources.redhat.com/libffi) + * + * libffi is a library that makes it possible to dynamicly create calls + * to C functions (without knowing the signature at compile-time). It also + * provides a way to create closures, that is dynamicly create functions with + * a runtime specified interface. + * + * This file contains functions to dynamicly call objc_msgSendSuper and to + * dynamicly create IMPs for use in Objective-C method dispatch tables. The + * file 'register.m' contains compile-time generated equivalents of these. + */ +#include "pyobjc.h" + +#import +#import +#import + +#ifdef MACOSX +/* + * Define SMALL_STRUCT_LIMIT as the largest struct that will be returned + * in registers instead of with a hidden pointer argument. + */ + +#if defined(__ppc__) + +# define SMALL_STRUCT_LIMIT 4 + +#elif defined(__i386__) + +# define SMALL_STRUCT_LIMIT 8 + +#else + +# error "Unsupported MACOSX platform" + +#endif + +#endif /* MACOSX */ + + + +#if 0 /* Usefull during debugging, only used in the debugger */ +static void describe_ffitype(ffi_type* type) +{ + switch (type->type) { + case FFI_TYPE_VOID: printf("%s", "void"); break; + case FFI_TYPE_INT: printf("%s", "int"); break; + case FFI_TYPE_FLOAT: printf("%s", "float"); break; + case FFI_TYPE_DOUBLE: printf("%s", "double"); break; + case FFI_TYPE_UINT8: printf("%s", "uint8"); break; + case FFI_TYPE_SINT8: printf("%s", "sint8"); break; + case FFI_TYPE_UINT16: printf("%s", "uint16"); break; + case FFI_TYPE_SINT16: printf("%s", "sint16"); break; + case FFI_TYPE_UINT32: printf("%s", "uint32"); break; + case FFI_TYPE_SINT32: printf("%s", "sint32"); break; + case FFI_TYPE_UINT64: printf("%s", "uint64"); break; + case FFI_TYPE_SINT64: printf("%s", "sint64"); break; + case FFI_TYPE_POINTER: printf("%s", "*"); break; + case FFI_TYPE_STRUCT: { + ffi_type** elems = type->elements; + + printf("%s", "struct { "); + if (elems) { + while (*elems) { + describe_ffitype(*(elems++)); + printf("%s", "; "); + } + } + printf("%s", "}"); + } + break; + + default: + // Don't abort, this is called from the debugger + printf("?(%d)", type->type); + } +} + +static void describe_cif(ffi_cif* cif) +{ + size_t i; + printf("abi, cif->nargs, cif->bytes, cif->flags); + for (i = 0; i < cif->nargs; i++) { + describe_ffitype(cif->arg_types[i]); + printf("%s", ", "); + } + printf("%s", "] rettype="); + describe_ffitype(cif->rtype); + printf("%s", ">\n"); +} + +#endif + + +static Py_ssize_t +num_struct_fields(const char* argtype) +{ + Py_ssize_t res = 0; + + if (*argtype != _C_STRUCT_B) return -1; + while (*argtype != _C_STRUCT_E && *argtype != '=') argtype++; + if (*argtype == _C_STRUCT_E) return 0; + + argtype++; + while (*argtype != _C_STRUCT_E) { + argtype = PyObjCRT_SkipTypeSpec(argtype); + if (argtype == NULL) return -1; + res ++; + } + return res; +} + + +static void +free_type(void *obj) +{ + PyMem_Free(((ffi_type*)obj)->elements); + PyMem_Free(obj); +} + +static ffi_type* signature_to_ffi_type(const char* argtype); + +static ffi_type* +array_to_ffi_type(const char* argtype) +{ + static NSMutableDictionary* array_types = nil; + NSValue *v; + ffi_type* type; + Py_ssize_t field_count; + Py_ssize_t i; + const NSString* key = [NSString stringWithUTF8String: argtype]; + + if (array_types == NULL || array_types == nil) { + array_types = [NSMutableDictionary dictionaryWithCapacity: 100]; + if (array_types == NULL || array_types == nil) return NULL; + } + + v = [array_types objectForKey: key]; + if (v != nil) { + return (ffi_type*)[v pointerValue]; + } + + /* We don't have a type description yet, dynamicly + * create it. + */ + field_count = atoi(argtype+1); + + type = PyMem_Malloc(sizeof(*type)); + if (type == NULL) { + PyErr_NoMemory(); + return NULL; + } + type->size = PyObjCRT_SizeOfType(argtype); + type->alignment = PyObjCRT_AlignOfType(argtype); + + /* Libffi doesn't really know about arrays as part of larger + * data-structres (e.g. struct foo { int field[3]; };). We fake it + * by treating the nested array as a struct. This seems to work + * fine on MacOS X. + */ + type->type = FFI_TYPE_STRUCT; + type->elements = PyMem_Malloc((1+field_count) * sizeof(ffi_type*)); + if (type->elements == NULL) { + PyMem_Free(type); + PyErr_NoMemory(); + return NULL; + } + + while (isdigit(*++argtype)); + type->elements[0] = signature_to_ffi_type(argtype); + for (i = 1; i < field_count; i++) { + type->elements[i] = type->elements[0]; + } + type->elements[field_count] = 0; + + v = [NSValue valueWithPointer: type]; + if (v == NULL || v == nil) { + free_type(type); + return NULL; + } + + NS_DURING + { + [array_types setObject: v forKey: key]; + } + NS_HANDLER + { + NS_VALUERETURN (NULL, ffi_type*); + } + NS_ENDHANDLER + + return type; +} + +static ffi_type* +struct_to_ffi_type(const char* argtype) +{ + static NSMutableDictionary* struct_types = nil; + NSValue* v; + ffi_type* type; + Py_ssize_t field_count; + const char* curtype; + const NSString* key = [NSString stringWithUTF8String: argtype]; + + if (struct_types == NULL || struct_types == nil) { + struct_types = [NSMutableDictionary dictionaryWithCapacity: 100]; + if (struct_types == NULL || struct_types == nil) return NULL; + } + + v = [struct_types objectForKey: key]; + if (v != nil) { + return (ffi_type*)[v pointerValue]; + } + + /* We don't have a type description yet, dynamicly + * create it. + */ + field_count = num_struct_fields(argtype); + if (field_count == -1) { +#ifdef STRICT_TYPE_PARSING + [[NSException exceptionWithName: @"PyObjCExc_InternalError" + reason: [NSString stringWithFormat: @"Cannot determine layout of %s", argtype] + userInfo: NULL] raise]; +#else + NSLog (@"PyObjCExc_InternalError: Cannot determine layout of %s", argtype); +#endif + return NULL; + } + + type = PyMem_Malloc(sizeof(*type)); + if (type == NULL) { + PyErr_NoMemory(); + return NULL; + } + type->size = PyObjCRT_SizeOfType(argtype); + type->alignment = PyObjCRT_AlignOfType(argtype); + type->type = FFI_TYPE_STRUCT; + type->elements = PyMem_Malloc((1+field_count) * sizeof(ffi_type*)); + if (type->elements == NULL) { + PyMem_Free(type); + PyErr_NoMemory(); + return NULL; + } + + field_count = 0; + curtype = argtype+1; + while (*curtype != _C_STRUCT_E && *curtype != '=') curtype++; + if (*curtype == '=') { + curtype ++; + while (*curtype != _C_STRUCT_E) { + type->elements[field_count] = + signature_to_ffi_type(curtype); + if (type->elements[field_count] == NULL) { + PyMem_Free(type->elements); + return NULL; + } + field_count++; + curtype = PyObjCRT_SkipTypeSpec(curtype); + if (curtype == NULL) { + PyMem_Free(type->elements); + return NULL; + } + } + } + type->elements[field_count] = NULL; + + v = [NSValue valueWithPointer: type]; + if (v == NULL || v == nil) { + free_type(type); + return NULL; + } + + NS_DURING + { + [struct_types setObject: v forKey: key]; + } + NS_HANDLER + { + NS_VALUERETURN (NULL, ffi_type*); + } + NS_ENDHANDLER + + return type; +} + +ffi_type* +objcl_pyobjc_signature_to_ffi_return_type(const char* argtype) +{ + switch (*argtype) { + case _C_CHR: case _C_SHT: + return &ffi_type_sint; + case _C_UCHR: case _C_USHT: + return &ffi_type_uint; +#ifdef _C_BOOL + case _C_BOOL: return &ffi_type_sint; +#endif + default: + return signature_to_ffi_type(argtype); + } +} + + +static ffi_type* +signature_to_ffi_type(const char* argtype) +{ + switch (*argtype) { + case _C_VOID: return &ffi_type_void; + case _C_ID: return &ffi_type_pointer; + case _C_CLASS: return &ffi_type_pointer; + case _C_SEL: return &ffi_type_pointer; + case _C_CHR: return &ffi_type_schar; +#ifdef _C_BOOL + case _C_BOOL: return &ffi_type_sint; +#endif + case _C_UCHR: return &ffi_type_uchar; + case _C_SHT: return &ffi_type_sshort; + case _C_USHT: return &ffi_type_ushort; + case _C_INT: return &ffi_type_sint; + case _C_UINT: return &ffi_type_uint; + + /* The next to defintions are incorrect, but the correct definitions + * don't work (e.g. give testsuite failures). We should be fine + * as long as sizeof(long) == sizeof(int) + */ + case _C_LNG: return &ffi_type_sint; /* ffi_type_slong */ + case _C_ULNG: return &ffi_type_uint; /* ffi_type_ulong */ + case _C_LNGLNG: return &ffi_type_sint64; + case _C_ULNGLNG: return &ffi_type_uint64; + case _C_FLT: return &ffi_type_float; + case _C_DBL: return &ffi_type_double; + case _C_CHARPTR: return &ffi_type_pointer; + case _C_PTR: return &ffi_type_pointer; + case _C_ARY_B: + return array_to_ffi_type(argtype); + case _C_IN: case _C_OUT: case _C_INOUT: case _C_CONST: + return signature_to_ffi_type(argtype+1); + case _C_STRUCT_B: + return struct_to_ffi_type(argtype); + default: +#ifdef STRICT_TYPE_PARSING + [[NSException exceptionWithName: @"PyExc_NotImplementedError" + reason: [NSString stringWithFormat: @"Type '%c' not supported", *argtype] + userInfo: NULL] raise]; +#else + NSLog (@"PyExc_NotImplementedError: Type '%#x' not supported", *argtype); +#endif + return NULL; + } +} + +/* + * arg_signature_to_ffi_type: Make the ffi_type for the call to the method IMP, + * on MacOS X this is the same as the normal signature_to_ffi_type, but on + * Linux/GNUstep we need a slightly different function. + */ +#ifdef MACOSX + +#ifdef __ppc__ +ffi_type* +objcl_pyobjc_arg_signature_to_ffi_type(const char* argtype) +{ + return signature_to_ffi_type (argtype); +} + +#else +ffi_type* +objcl_pyobjc_arg_signature_to_ffi_type(const char* argtype) +{ + /* NOTE: This is the minimal change to pass the unittests, it is not + * based on analysis of the calling conventions. + */ + switch (*argtype) { + case _C_CHR: return &ffi_type_sint; + case _C_UCHR: return &ffi_type_uint; + case _C_SHT: return &ffi_type_sint; + case _C_USHT: return &ffi_type_uint; + default: return signature_to_ffi_type(argtype); + } +} +#endif + +#else /* GNUstep */ + +ffi_type* +objcl_pyobjc_arg_signature_to_ffi_type(const char* argtype) +{ + /* NOTE: This is the minimal change to pass the unittests, it is not + * based on analysis of the calling conventions. + */ + switch (*argtype) { + case _C_CHR: return &ffi_type_sint; + case _C_UCHR: return &ffi_type_uint; + case _C_SHT: return &ffi_type_sint; + case _C_USHT: return &ffi_type_uint; + default: return signature_to_ffi_type(argtype); + } +} + +#endif /* GNUstep */ diff --git a/Objective-C/PyObjC/objc-runtime-apple.h b/Objective-C/PyObjC/objc-runtime-apple.h new file mode 100644 index 0000000..8d050a1 --- /dev/null +++ b/Objective-C/PyObjC/objc-runtime-apple.h @@ -0,0 +1,137 @@ +/* Copyright (c) 1996,97,98 by Lele Gaifax. All Rights Reserved + * Copyright (c) 2003 Ronald Oussoren + * + * This software may be used and distributed freely for any purpose + * provided that this notice is included unchanged on any and all + * copies. The author does not warrant or guarantee this software in + * any way. + * + * This file is part of the PyObjC package. + * + * RCSfile: objc_support.h,v + * Revision: 1.16 + * Date: 1998/08/18 15:35:57 + * + * Created Tue Sep 10 14:11:38 1996. + */ + +#ifndef PyObjC_RUNTIME_APPLE_H +#define PyObjC_RUNTIME_APPLE_H + +#import +#import + +#include +#include + +#include +#include +#include +#include + +static inline int +PyObjCRT_SameSEL(SEL a, SEL b) +{ + return a == b; +} + +static inline const char* +PyObjCRT_SELName(SEL sel) +{ + return sel_getName(sel); +} + +static inline SEL +PyObjCRT_SELUID(const char* str) +{ + return sel_getUid(str); +} + +static inline Class +PyObjCRT_LookUpClass(const char* name) +{ + return objc_lookUpClass(name); +} + +static inline struct objc_method_list * +PyObjCRT_NextMethodList(Class c, void ** p) +{ + return class_nextMethodList(c, p); +} + +static inline void +PyObjCRT_InitMethod(Method m, SEL name, const char* types, IMP imp) +{ + memset(m, 0, sizeof(*m)); + m->method_name = name; + m->method_types = strdup((char*)types); + m->method_imp = imp; +} + +static inline void +PyObjCRT_ClassAddMethodList(Class cls, struct objc_method_list* lst) +{ + class_addMethods(cls, lst); +} + + +extern struct objc_method_list* PyObjCRT_AllocMethodList(ssize_t); +extern struct objc_protocol_list* PyObjCRT_AllocProtocolList(ssize_t); + +typedef Method PyObjCRT_Method_t; +typedef Ivar PyObjCRT_Ivar_t; + +#define GETISA(c) ((c)->isa) + +#define RECEIVER(c) ((c).receiver) + +#define _C_CONST 'r' +#define _C_IN 'n' +#define _C_INOUT 'N' +#define _C_OUT 'o' +#define _C_BYCOPY 'O' +#define _C_ONEWAY 'V' +#define _C_LNGLNG 'q' +#define _C_ULNGLNG 'Q' +#define _C_BOOL 'B' /* (Objective-)C++ 'bool' */ + + +/* Return a number that is likely to change when the method list changes, + * and is cheap to compute. + */ +static inline int +objc_methodlist_magic(Class cls) +{ + int res = 0; + int cnt = 0; + + /* This is the documented way of enumerating the method list. It + * is slower than the obvious way, but does not explode under + * esoteric situations. + */ + void *iterator = NULL; + struct objc_method_list *mlist; + + if (cls == NULL) return -1; + + while ( (mlist = class_nextMethodList( cls, &iterator )) != NULL ) { + res += mlist->method_count; + cnt++; + } + + return (cnt << 16) | (res & 0xFFFF); +} + +static inline const char * +get_selector_encoding (id self, SEL sel) +{ + struct objc_method* m = class_getInstanceMethod(self->isa, sel); + + if (!m) { + return NULL; + } else { + return m->method_types; + } +} + +#endif /* PyObjC_RUNTIME_APPLE_H */ diff --git a/Objective-C/PyObjC/objc-runtime-apple.m b/Objective-C/PyObjC/objc-runtime-apple.m new file mode 100644 index 0000000..b2888ac --- /dev/null +++ b/Objective-C/PyObjC/objc-runtime-apple.m @@ -0,0 +1,159 @@ +/* This file is part of the PyObjC package. */ +/* + * Support code for the Apple runtime + */ +#include "pyobjc.h" + +#if defined(APPLE_RUNTIME) +#include "objc-runtime-apple.h" + +int PyObjCRT_SetupClass( + Class cls, + Class metaCls, + const char*name, + Class superCls, + Class rootCls, + ssize_t ivarSize, + struct objc_ivar_list* ivarList, + struct objc_protocol_list* protocolList +) + +{ + /* Initialize the structure */ + memset(cls, 0, sizeof(*cls)); + memset(metaCls, 0, sizeof(*cls)); + + cls->methodLists = NULL; + metaCls->methodLists = NULL; + cls->isa = metaCls; + + cls->info = CLS_CLASS; // |CLS_METHOD_ARRAY; + metaCls->info = CLS_META; // |CLS_METHOD_ARRAY; + + 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->methodLists = malloc(sizeof(struct objc_method_list*)); + if (cls->methodLists == NULL) { + PyErr_NoMemory(); + free((char*)(cls->name)); + cls->name = NULL; + free((char*)(metaCls->name)); + metaCls->name = NULL; + return -1; + } + memset(cls->methodLists, 0, sizeof(*(cls->methodLists))); + + metaCls->methodLists = malloc(sizeof(struct objc_method_list*)); + if (cls->methodLists == NULL) { + PyErr_NoMemory(); + free((char*)(cls->name)); + cls->name = NULL; + free((char*)(metaCls->name)); + metaCls->name = NULL; + free(cls->methodLists); + cls->methodLists = NULL; + return -1; + } + memset(metaCls->methodLists, 0, sizeof(*(metaCls->methodLists))); + + /* + * This is MacOS X specific, and an undocumented feature (long live + * Open Source!). + * + * The code in the objc runtime assumes that the method lists are + * terminated by '-1', and will happily overwite existing data if + * they aren't. + * + * Ronald filed a bugreport for this: Radar #3317376 + */ + cls->methodLists[0] = (struct objc_method_list*)-1; + metaCls->methodLists[0] = (struct objc_method_list*)-1; + + cls->super_class = superCls; + metaCls->super_class = superCls->isa; + metaCls->isa = rootCls->isa; + + cls->instance_size = ivarSize; + cls->ivars = ivarList; + + metaCls->instance_size = metaCls->super_class->instance_size; + metaCls->ivars = NULL; + + metaCls->protocols = cls->protocols = protocolList; + + return 0; +} + +void PyObjCRT_ClearClass(Class cls) +{ + if (cls->methodLists) { + if (cls->methodLists) { + struct objc_method_list** cur; + + cur = cls->methodLists; + while (*cur != (struct objc_method_list*)-1) { + if (*cur != NULL) { + free(*cur); + *cur = NULL; + } + cur++; + } + free(cls->methodLists); + cls->methodLists = NULL; + } + cls->methodLists = NULL; + } + + if (cls->name) { + free((char*)(cls->name)); + } +} + +struct objc_method_list *PyObjCRT_AllocMethodList(ssize_t numMethods) +{ + struct objc_method_list *mlist; + + mlist = malloc(sizeof(struct objc_method_list) + + ((numMethods+1) * sizeof(struct objc_method))); + + if (mlist == NULL) { + return NULL; + } + + mlist->method_count = 0; + mlist->obsolete = NULL; + + return mlist; +} + +struct objc_protocol_list* PyObjCRT_AllocProtocolList(ssize_t 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; +} + +#else /* !APPLE_RUNTIME */ + +static int dummy __attribute__((__unused__)); + +#endif /* !APPLE_RUNTIME */ diff --git a/Objective-C/PyObjC/objc-runtime-gnu.h b/Objective-C/PyObjC/objc-runtime-gnu.h new file mode 100644 index 0000000..5c87b6d --- /dev/null +++ b/Objective-C/PyObjC/objc-runtime-gnu.h @@ -0,0 +1,174 @@ +#ifndef PyObjC_RUNTIME_GNU_H +#define PyObjC_RUNTIME_GNU_H + +/* + * Specific support for the GNU Objective-C runtime + */ + +#include +#include + +#define objc_msgSendSuper(super, op, args...) \ + ((super)->self == NULL \ + ? 0 \ + : ( \ + class_get_instance_method( \ + (super)->class, (op) \ + )->method_imp)( \ + (super)->self, \ + (op) ,##args)) + + +/* + * XXX: AFAIK as I (Ronald) know, there should be an include named + * on systems with the GNU runtime. However, this file + * not present on my Linux playmachine (running Debian testing)... + * + * The alternative is to declare some prototypes ourselves... + */ +#if 0 +# include +#else + extern void class_add_method_list(Class, MethodList_t); + extern void __objc_add_class_to_hash(Class); +#endif + + +#ifndef nil +#define nil NULL +#endif + +/* What we call _C_LNGLNG is actually _C_LNG_LNG in the GNU runtime */ +#define _C_LNGLNG _C_LNG_LNG +#define _C_ULNGLNG _C_ULNG_LNG + +/* XXX: names don't conform to the coding-style! */ +extern Ivar_t class_getInstanceVariable(Class aClass, const char *name); +extern Ivar_t object_getInstanceVariable(id obj, const char *name, void **out); +extern Ivar_t object_setInstanceVariable(id obj, const char *name, void *value); +extern void objc_addClass(Class aClass); +//extern id objc_msgSendSuper(struct objc_super *super, SEL op, ...); +extern void objc_freeMethodList(struct objc_method_list *list); + +static inline int PyObjCRT_SameSEL(SEL a, SEL b) +{ + return sel_eq(a, b); +} + + +static inline const char* +PyObjCRT_SELName(SEL sel) +{ + return sel_get_name(sel); +} + +static inline SEL +PyObjCRT_SELUID(const char* str) +{ + return sel_get_uid(str); +} + +static inline void +PyObjCRT_ClassAddMethodList(Class cls, MethodList_t lst) +{ + int i; + + /* First convert the method_names to strings, class_add_method_list + * assumes the method_names are strings and converts these back + * to selectors. + */ + for (i = 0; i < lst->method_count; i++) { + lst->method_list[i].method_name = (SEL)PyObjCRT_SELName(lst->method_list[i].method_name); + } + + class_add_method_list(cls, lst); +} + +static inline Class +PyObjCRT_LookUpClass(const char* name) +{ + return objc_lookup_class(name); +} + +static inline struct objc_method_list * +PyObjCRT_NextMethodList(Class c, void ** p) +{ + if (*p == 0) { + *p = c->methods; + } else { + *p = (*((MethodList_t*)p))->method_next; + } + return *(MethodList_t*)p; +} + +static inline void +PyObjCRT_InitMethod(Method_t m, SEL name, const char* types, IMP imp) +{ + /* XXX: With some versions of the GNU runtime, the runtime assumes + * that method_name is initialy a string instead of a selector, other + * versions do not. The version on my development box currently + * doesn't. + * + * m->method_name = (SEL)PyObjCRT_SELName(name); + */ + m->method_name = name; + m->method_types = types; + m->method_imp = imp; +} + + +extern MethodList_t PyObjCRT_AllocMethodList(ssize_t); +extern struct objc_protocol_list* PyObjCRT_AllocProtocolList(ssize_t); + + +typedef Method_t PyObjCRT_Method_t; +typedef Ivar_t PyObjCRT_Ivar_t; + +static inline Class GETISA(id obj) +{ + return obj->class_pointer; +} + +//#define GETISA(c) (*((struct objc_object**)&(c))->class_pointer) +#define CLS_CLASS _CLS_CLASS +#define CLS_META _CLS_META +#define RECEIVER(c) (c).self + +static inline const char * +get_selector_encoding (id self, SEL sel) +{ + return sel->sel_types; +} + + + +extern void PyObjCRT_AddClass(Class cls); +#define objc_addClass PyObjCRT_AddClass + +/* Return a number that is likely to change when the method list changes, + * and is cheap to compute. + */ +static inline int +objc_methodlist_magic(Class cls) +{ + struct objc_method_list *mlist; + int res, cnt; + void *iterator = 0; + + res = cnt = 0; + + if (cls == NULL) + return -1; + + while ((mlist = PyObjCRT_NextMethodList(cls, &iterator))) + { + res += mlist->method_count; + cnt ++; + } + + return (cnt << 16) | (res & 0xFFFF); +} + + + +#endif /* PyObjC_RUNTIME_GNU_H */ diff --git a/Objective-C/PyObjC/objc-runtime-gnu.m b/Objective-C/PyObjC/objc-runtime-gnu.m new file mode 100644 index 0000000..df868e4 --- /dev/null +++ b/Objective-C/PyObjC/objc-runtime-gnu.m @@ -0,0 +1,217 @@ +/* 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) +#include "objc-runtime-gnu.h" + +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 */ diff --git a/Objective-C/PyObjC/objc_support.h b/Objective-C/PyObjC/objc_support.h new file mode 100644 index 0000000..a9b4b28 --- /dev/null +++ b/Objective-C/PyObjC/objc_support.h @@ -0,0 +1,46 @@ +/* Copyright (c) 1996,97,98 by Lele Gaifax. All Rights Reserved + * Copyright (2) 2003 Ronald Oussoren + * + * This software may be used and distributed freely for any purpose + * provided that this notice is included unchanged on any and all + * copies. The author does not warrant or guarantee this software in + * any way. + * + * This file is part of the PyObjC package. + * + * RCSfile: objc_support.h,v + * Revision: 1.16 + * Date: 1998/08/18 15:35:57 + * + * Created Tue Sep 10 14:11:38 1996. + * + * TODO: the functions exported by this file should be changed, the names + * should start with 'PyObjC' and should be the same as the names used in + * pyobjc-api.h (where appropriate). + */ + +#ifndef _objc_support_H +#define _objc_support_H + +#ifdef GNU_RUNTIME + +# include "objc-runtime-gnu.h" + +#else /* NeXTSTEP / Mac OS X */ + +# include "objc-runtime-apple.h" + +#endif + +extern ssize_t PyObjCRT_SizeOfReturnType(const char* type); +extern ssize_t PyObjCRT_SizeOfType(const char *type); +extern ssize_t PyObjCRT_AlignOfType(const char *type); +extern const char *PyObjCRT_SkipTypeSpec (const char *type); +extern const char* PyObjCRT_SkipTypeQualifiers (const char* type); + +extern int PyObjCRT_SetupClass( + Class, Class, const char*, Class, Class, ssize_t, struct objc_ivar_list*, + struct objc_protocol_list*); +extern void PyObjCRT_ClearClass(Class cls); + +#endif /* _objc_support_H */ diff --git a/Objective-C/PyObjC/objc_support.m b/Objective-C/PyObjC/objc_support.m new file mode 100644 index 0000000..862879c --- /dev/null +++ b/Objective-C/PyObjC/objc_support.m @@ -0,0 +1,505 @@ +/* Copyright (c) 1996,97,98 by Lele Gaifax. All Rights Reserved + * Copyright (c) 2002, 2003 Ronald Oussoren + * + * This software may be used and distributed freely for any purpose + * provided that this notice is included unchanged on any and all + * copies. The author does not warrant or guarantee this software in + * any way. + * + * This file is part of the PyObjC package. + * + * RCSfile: objc_support.m,v + * Revision: 1.24 + * Date: 1998/08/18 15:35:58 + * + * Created Tue Sep 10 14:16:02 1996. + */ + +#include "objc_support.h" +#include "pyobjc.h" + +#include + +#include + +#ifdef MACOSX +/* OSX 10.1 doesn't define LLONG_MIN, LLONG_MAX and ULLONG_MAX */ +#ifndef LLONG_MIN +#error "Mac OS X 10.1 not supported" +#endif +#endif + +#import +#import +#import +#import + +#ifdef MACOSX +#include +#endif /* MACOSX */ + + +/* Define in order to throw exceptions when a typespec cannot be parsed. */ +#undef STRICT_TYPE_PARSING + + +#ifndef MAX +static inline ssize_t +MAX(ssize_t x, ssize_t y) +{ + return x > y ? x : y; +} +#endif + +static inline ssize_t +ROUND(ssize_t v, ssize_t a) +{ + if (v % a == 0) { + return v; + } else { + return v + a - (v % a); + } +} + + +const char* +PyObjCRT_SkipTypeQualifiers (const char* type) +{ + while ( + *type == _C_CONST || + *type == _C_IN || + *type == _C_INOUT || + *type == _C_OUT || + *type == _C_BYCOPY || + *type == _C_ONEWAY) { + type++; + } + while (*type && isdigit(*type)) type++; + return type; +} + + +const char * +PyObjCRT_SkipTypeSpec (const char *type) +{ + type = PyObjCRT_SkipTypeQualifiers (type); + + switch (*type) { + /* The following are one character type codes */ + case _C_UNDEF: + case _C_CLASS: + case _C_SEL: + case _C_CHR: + case _C_UCHR: + case _C_CHARPTR: +#ifdef _C_ATOM + case _C_ATOM: +#endif +#ifdef _C_BOOL + case _C_BOOL: +#endif + case _C_SHT: + case _C_USHT: + case _C_INT: + case _C_UINT: + case _C_LNG: + case _C_ULNG: + case _C_FLT: + case _C_DBL: + case _C_VOID: + case _C_LNGLNG: + case _C_ULNGLNG: + case _C_BFLD: /* Not really 1 character, but close enough */ + ++type; + break; + + case _C_ID: + ++type; +#ifdef MACOSX + if (*type == '"') { + /* embedded field name in an ivar_type */ + type=strchr(type+1, '"'); + if (type != NULL) { + type++; + } + } +#endif + break; + + case _C_ARY_B: + /* skip digits, typespec and closing ']' */ + + while (isdigit (*++type)); + type = PyObjCRT_SkipTypeSpec (type); + assert (type == NULL || *type == _C_ARY_E); + if (type) type++; + break; + + case _C_STRUCT_B: + /* skip name, and elements until closing '}' */ + while (*type != _C_STRUCT_E && *type++ != '='); + while (type && *type != _C_STRUCT_E) { + if (*type == '"') { + /* embedded field names */ + type = strchr(type+1, '"'); + if (type != NULL) { + type++; + } else { + return NULL; + } + } + type = PyObjCRT_SkipTypeSpec (type); + } + if (type) type++; + break; + + case _C_UNION_B: + /* skip name, and elements until closing ')' */ + while (*type != _C_UNION_E && *type++ != '='); + while (type && *type != _C_UNION_E) { + type = PyObjCRT_SkipTypeSpec (type); + } + if (type) type++; + break; + + case _C_PTR: + case _C_CONST: + case _C_IN: + case _C_INOUT: + case _C_OUT: + case _C_BYCOPY: + case _C_ONEWAY: + + /* Just skip the following typespec */ + type = PyObjCRT_SkipTypeSpec (type+1); + break; + + + default: +#ifdef STRICT_TYPE_PARSING + [[NSException exceptionWithName: @"PyObjCRT_SkipTypeSpec" + reason: [NSString stringWithFormat: @"Unhandled type: '%c'", *type] + userInfo: NULL] raise]; +#else + NSLog (@"PyObjCRT_SkipTypeSpec: Unhandled type: '%c'", *type); +#endif + return NULL; + } + + /* The compiler inserts a number after the actual signature, + * this number may or may not be usefull depending on the compiler + * version. We never use it. + */ + while (type && *type && isdigit(*type)) type++; + return type; +} + +/* +Return the alignment of an object specified by type +*/ + +/* +* On MacOS X, the elements of a struct are aligned differently inside the +* struct than outside. That is, the maximum alignment of any struct field +* (except the first) is 4, doubles outside of a struct have an alignment of +* 8. +* +* Other platform don't seem to have this inconsistency. +* +* XXX: sizeof_struct, alignof_struct and {de,}pythonify_c_struct should +* probably be moved to platform dependend files. As long as this is the +* only platform dependent code this isn't worth the effort. +*/ +#ifdef MACOSX + +static inline ssize_t +PyObjC_EmbeddedAlignOfType (const char* type) +{ + ssize_t align = PyObjCRT_AlignOfType(type); + +#ifdef __i386__ + return align; + +#else + if (align < 4 || align == 16) { + return align; + } else { + return 4; + } +#endif +} + +#else + +static inline int +PyObjC_EmbeddedAlignOfType (const char* type) +{ + ssize_t align = PyObjCRT_AlignOfType(type); + + /* GNUstep/ix86 seems to behave like this: */ + if (align < 4) { + return align; + } else { + return 4; + } +} + +#endif + +ssize_t +PyObjCRT_AlignOfType (const char *type) +{ + switch (*type) { + case _C_ID: return __alignof__ (id); + case _C_CLASS: return __alignof__ (Class); + case _C_SEL: return __alignof__ (SEL); + case _C_CHR: return __alignof__ (char); + case _C_UCHR: return __alignof__ (unsigned char); + case _C_SHT: return __alignof__ (short); + case _C_USHT: return __alignof__ (unsigned short); +#ifdef _C_BOOL + case _C_BOOL: return __alignof__ (bool); +#endif + case _C_INT: return __alignof__ (int); + case _C_UINT: return __alignof__ (unsigned int); + case _C_LNG: return __alignof__ (long); + case _C_ULNG: return __alignof__ (unsigned long); + case _C_FLT: return __alignof__ (float); + case _C_DBL: +#if defined(__APPLE__) && defined(__i386__) + /* The ABI says natural alignment is 4 bytes, but + * GCC's __alignof__ says 8. The latter is wrong. + */ + return 4; +#else + return __alignof__ (double); +#endif + + case _C_CHARPTR: return __alignof__ (char *); +#ifdef _C_ATOM + case _C_ATOM: return __alignof__ (char *); +#endif + case _C_PTR: return __alignof__ (void *); +#if defined(__APPLE__) && defined(__i386__) + /* The ABI says natural alignment is 4 bytes, but + * GCC's __alignof__ says 8. The latter is wrong. + */ + case _C_LNGLNG: return 4; + case _C_ULNGLNG: return 4; +#else + case _C_LNGLNG: return __alignof__(long long); + case _C_ULNGLNG: return __alignof__(unsigned long long); +#endif + + case _C_ARY_B: + while (isdigit(*++type)) /* do nothing */; + return PyObjCRT_AlignOfType (type); + + case _C_STRUCT_B: + { + struct { int x; double y; } fooalign; + while(*type != _C_STRUCT_E && *type++ != '=') /* do nothing */; + if (*type != _C_STRUCT_E) { + int have_align = 0; + ssize_t align = 0; + + while (type != NULL && *type != _C_STRUCT_E) { + if (*type == '"') { + type = strchr(type+1, '"'); + if (type) type++; + } + if (have_align) { + align = MAX(align, + PyObjC_EmbeddedAlignOfType(type)); + } else { + align = PyObjCRT_AlignOfType(type); + have_align = 1; + } + type = PyObjCRT_SkipTypeSpec(type); + } + if (type == NULL) return -1; + return align; + } else { + return __alignof__ (fooalign); + } + } + + case _C_UNION_B: + { + int maxalign = 0; + type++; + while (*type != _C_UNION_E) + { + int item_align = PyObjCRT_AlignOfType(type); + if (item_align == -1) return -1; + maxalign = MAX (maxalign, item_align); + type = PyObjCRT_SkipTypeSpec (type); + } + return maxalign; + } + + case _C_CONST: + case _C_IN: + case _C_INOUT: + case _C_OUT: + case _C_BYCOPY: + case _C_ONEWAY: + return PyObjCRT_AlignOfType(type+1); + + default: +#ifdef STRICT_TYPE_PARSING + [[NSException exceptionWithName: @"PyObjCRT_SkipTypeSpec" + reason: [NSString stringWithFormat: @"Unhandled type: '%c'", *type] + userInfo: NULL] raise]; +#else + NSLog (@"PyObjCRT_SkipTypeSpec: Unhandled type: '%c'", *type); +#endif + return -1; + } +} + +/* +The aligned size if the size rounded up to the nearest alignment. +*/ + +static ssize_t +PyObjCRT_AlignedSize (const char *type) +{ + ssize_t size = PyObjCRT_SizeOfType (type); + ssize_t align = PyObjCRT_AlignOfType (type); + + if (size == -1 || align == -1) return -1; + return ROUND(size, align); +} + +/* +return the size of an object specified by type +*/ + +ssize_t +PyObjCRT_SizeOfType (const char *type) +{ + ssize_t itemSize; + switch (*type) { + case _C_VOID: return 0; + case _C_ID: return sizeof(id); + case _C_CLASS: return sizeof(Class); + case _C_SEL: return sizeof(SEL); + case _C_CHR: return sizeof(char); + case _C_UCHR: return sizeof(unsigned char); + case _C_SHT: return sizeof(short); + case _C_USHT: return sizeof(unsigned short); +#ifdef _C_BOOL + case _C_BOOL: return sizeof(bool); +#endif + case _C_INT: return sizeof(int); + case _C_UINT: return sizeof(unsigned int); + case _C_LNG: return sizeof(long); + case _C_ULNG: return sizeof(unsigned long); + case _C_FLT: return sizeof(float); + case _C_DBL: return sizeof(double); + case _C_LNGLNG: return sizeof(long long); + case _C_ULNGLNG: return sizeof(unsigned long long); + + case _C_PTR: + case _C_CHARPTR: +#ifdef _C_ATOM + case _C_ATOM: +#endif + return sizeof(char*); + + case _C_ARY_B: + { + ssize_t len = atoi(type+1); + ssize_t item_align; + while (isdigit(*++type)) + ; + item_align = PyObjCRT_AlignedSize(type); + if (item_align == -1) return -1; + return len*item_align; + } + break; + + case _C_STRUCT_B: + { + ssize_t acc_size = 0; + int have_align = 0; + ssize_t align; + ssize_t max_align = 0; + + while (*type != _C_STRUCT_E && *type++ != '=') + ; /* skip "=" */ + while (*type != _C_STRUCT_E) { + if (*type == '"') { + type = strchr(type+1, '"'); + if (type) type++; + } + if (have_align) { + align = PyObjC_EmbeddedAlignOfType(type); + if (align == -1) return -1; + } else { + align = PyObjCRT_AlignOfType(type); + if (align == -1) return -1; + have_align = 1; + } + max_align = MAX(align, max_align); + acc_size = ROUND (acc_size, align); + + itemSize = PyObjCRT_SizeOfType (type); + if (itemSize == -1) return -1; + acc_size += itemSize; + type = PyObjCRT_SkipTypeSpec (type); + } + if (max_align) { + acc_size = ROUND(acc_size, max_align); + } + return acc_size; + } + + case _C_UNION_B: + { + ssize_t max_size = 0; + type++; + while (*type != _C_UNION_E) { + itemSize = PyObjCRT_SizeOfType (type); + if (itemSize == -1) return -1; + max_size = MAX (max_size, itemSize); + type = PyObjCRT_SkipTypeSpec (type); + } + return max_size; + } + + case _C_CONST: + case _C_IN: + case _C_INOUT: + case _C_OUT: + case _C_BYCOPY: + case _C_ONEWAY: + return PyObjCRT_SizeOfType(type+1); + + default: +#ifdef STRICT_TYPE_PARSING + [[NSException exceptionWithName: @"PyObjCRT_SkipTypeSpec" + reason: [NSString stringWithFormat: @"Unhandled type: '%c'", *type] + userInfo: NULL] raise]; +#else + NSLog (@"PyObjCRT_SkipTypeSpec: Unhandled type: '%c'", *type); +#endif + return -1; + } +} + + +ssize_t +PyObjCRT_SizeOfReturnType(const char* type) +{ + switch(*type) { + case _C_CHR: + case _C_UCHR: + case _C_SHT: + case _C_USHT: + return sizeof(int); + default: + return PyObjCRT_SizeOfType(type); + } +} diff --git a/Objective-C/PyObjC/pyobjc.h b/Objective-C/PyObjC/pyobjc.h new file mode 100644 index 0000000..6a2d6b4 --- /dev/null +++ b/Objective-C/PyObjC/pyobjc.h @@ -0,0 +1,46 @@ +/* Copyright 2007, Matthias Andreas Benkard. */ + +#ifndef __pyobjc_H +#define __pyobjc_H + +#include +#include +#include "libobjcl.h" + + +#ifdef __NEXT_RUNTIME__ + +#ifndef APPLE_RUNTIME +#define APPLE_RUNTIME +#endif + +#import + +#else /* !__NEXT_RUNTIME__ */ + +#ifndef GNU_RUNTIME +#define GNU_RUNTIME +#endif + +#import +#ifndef __CXX__ +#define bool BOOL +#endif + +#endif /* __NEXT_RUNTIME__ */ + + +#define PyMem_Free free +#define PyMem_Malloc malloc +#define Py_ssize_t ssize_t + +#ifdef OOM_KILL +#define PyErr_NoMemory() [objcl_oom_exception raise] +#else +#define PyErr_NoMemory() NSLog (@"ERROR: Memory exhausted."); +#endif + +#include "objc_support.h" +#include "libffi_support.h" + +#endif /* __pyobjc_H */ diff --git a/Objective-C/libffi_support.h b/Objective-C/libffi_support.h deleted file mode 100644 index ca04c6b..0000000 --- a/Objective-C/libffi_support.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef PyObjC_FFI_SUPPORT_H -#define PyObjC_FFI_SUPPORT_H - -#ifdef USE_LIBFFI -#ifdef HAVE_FFI_H -#include -#elif HAVE_FFI_FFI_H -#include -#else -/* We are using our own build of libffi. */ -#include -#endif -#endif - -ffi_type* -objcl_pyobjc_signature_to_ffi_return_type (const char* argtype); - -ffi_type* -objcl_pyobjc_arg_signature_to_ffi_type (const char* argtype); - -#endif /* PyObjC_FFI_SUPPORT_H */ diff --git a/Objective-C/libffi_support.m b/Objective-C/libffi_support.m deleted file mode 100644 index 4bc1137..0000000 --- a/Objective-C/libffi_support.m +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Support for libffi (http://sources.redhat.com/libffi) - * - * libffi is a library that makes it possible to dynamicly create calls - * to C functions (without knowing the signature at compile-time). It also - * provides a way to create closures, that is dynamicly create functions with - * a runtime specified interface. - * - * This file contains functions to dynamicly call objc_msgSendSuper and to - * dynamicly create IMPs for use in Objective-C method dispatch tables. The - * file 'register.m' contains compile-time generated equivalents of these. - */ -#include "pyobjc.h" - -#import -#import -#import - -#ifdef MACOSX -/* - * Define SMALL_STRUCT_LIMIT as the largest struct that will be returned - * in registers instead of with a hidden pointer argument. - */ - -#if defined(__ppc__) - -# define SMALL_STRUCT_LIMIT 4 - -#elif defined(__i386__) - -# define SMALL_STRUCT_LIMIT 8 - -#else - -# error "Unsupported MACOSX platform" - -#endif - -#endif /* MACOSX */ - - - -#if 0 /* Usefull during debugging, only used in the debugger */ -static void describe_ffitype(ffi_type* type) -{ - switch (type->type) { - case FFI_TYPE_VOID: printf("%s", "void"); break; - case FFI_TYPE_INT: printf("%s", "int"); break; - case FFI_TYPE_FLOAT: printf("%s", "float"); break; - case FFI_TYPE_DOUBLE: printf("%s", "double"); break; - case FFI_TYPE_UINT8: printf("%s", "uint8"); break; - case FFI_TYPE_SINT8: printf("%s", "sint8"); break; - case FFI_TYPE_UINT16: printf("%s", "uint16"); break; - case FFI_TYPE_SINT16: printf("%s", "sint16"); break; - case FFI_TYPE_UINT32: printf("%s", "uint32"); break; - case FFI_TYPE_SINT32: printf("%s", "sint32"); break; - case FFI_TYPE_UINT64: printf("%s", "uint64"); break; - case FFI_TYPE_SINT64: printf("%s", "sint64"); break; - case FFI_TYPE_POINTER: printf("%s", "*"); break; - case FFI_TYPE_STRUCT: { - ffi_type** elems = type->elements; - - printf("%s", "struct { "); - if (elems) { - while (*elems) { - describe_ffitype(*(elems++)); - printf("%s", "; "); - } - } - printf("%s", "}"); - } - break; - - default: - // Don't abort, this is called from the debugger - printf("?(%d)", type->type); - } -} - -static void describe_cif(ffi_cif* cif) -{ - size_t i; - printf("abi, cif->nargs, cif->bytes, cif->flags); - for (i = 0; i < cif->nargs; i++) { - describe_ffitype(cif->arg_types[i]); - printf("%s", ", "); - } - printf("%s", "] rettype="); - describe_ffitype(cif->rtype); - printf("%s", ">\n"); -} - -#endif - - -static Py_ssize_t -num_struct_fields(const char* argtype) -{ - Py_ssize_t res = 0; - - if (*argtype != _C_STRUCT_B) return -1; - while (*argtype != _C_STRUCT_E && *argtype != '=') argtype++; - if (*argtype == _C_STRUCT_E) return 0; - - argtype++; - while (*argtype != _C_STRUCT_E) { - argtype = PyObjCRT_SkipTypeSpec(argtype); - if (argtype == NULL) return -1; - res ++; - } - return res; -} - - -static void -free_type(void *obj) -{ - PyMem_Free(((ffi_type*)obj)->elements); - PyMem_Free(obj); -} - -static ffi_type* signature_to_ffi_type(const char* argtype); - -static ffi_type* -array_to_ffi_type(const char* argtype) -{ - static NSMutableDictionary* array_types = nil; - NSValue *v; - ffi_type* type; - Py_ssize_t field_count; - Py_ssize_t i; - const NSString* key = [NSString stringWithUTF8String: argtype]; - - if (array_types == NULL || array_types == nil) { - array_types = [NSMutableDictionary dictionaryWithCapacity: 100]; - if (array_types == NULL || array_types == nil) return NULL; - } - - v = [array_types objectForKey: key]; - if (v != nil) { - return (ffi_type*)[v pointerValue]; - } - - /* We don't have a type description yet, dynamicly - * create it. - */ - field_count = atoi(argtype+1); - - type = PyMem_Malloc(sizeof(*type)); - if (type == NULL) { - PyErr_NoMemory(); - return NULL; - } - type->size = PyObjCRT_SizeOfType(argtype); - type->alignment = PyObjCRT_AlignOfType(argtype); - - /* Libffi doesn't really know about arrays as part of larger - * data-structres (e.g. struct foo { int field[3]; };). We fake it - * by treating the nested array as a struct. This seems to work - * fine on MacOS X. - */ - type->type = FFI_TYPE_STRUCT; - type->elements = PyMem_Malloc((1+field_count) * sizeof(ffi_type*)); - if (type->elements == NULL) { - PyMem_Free(type); - PyErr_NoMemory(); - return NULL; - } - - while (isdigit(*++argtype)); - type->elements[0] = signature_to_ffi_type(argtype); - for (i = 1; i < field_count; i++) { - type->elements[i] = type->elements[0]; - } - type->elements[field_count] = 0; - - v = [NSValue valueWithPointer: type]; - if (v == NULL || v == nil) { - free_type(type); - return NULL; - } - - NS_DURING - { - [array_types setObject: v forKey: key]; - } - NS_HANDLER - { - NS_VALUERETURN (NULL, ffi_type*); - } - NS_ENDHANDLER - - return type; -} - -static ffi_type* -struct_to_ffi_type(const char* argtype) -{ - static NSMutableDictionary* struct_types = nil; - NSValue* v; - ffi_type* type; - Py_ssize_t field_count; - const char* curtype; - const NSString* key = [NSString stringWithUTF8String: argtype]; - - if (struct_types == NULL || struct_types == nil) { - struct_types = [NSMutableDictionary dictionaryWithCapacity: 100]; - if (struct_types == NULL || struct_types == nil) return NULL; - } - - v = [struct_types objectForKey: key]; - if (v != nil) { - return (ffi_type*)[v pointerValue]; - } - - /* We don't have a type description yet, dynamicly - * create it. - */ - field_count = num_struct_fields(argtype); - if (field_count == -1) { -#ifdef STRICT_TYPE_PARSING - [[NSException exceptionWithName: @"PyObjCExc_InternalError" - reason: [NSString stringWithFormat: @"Cannot determine layout of %s", argtype] - userInfo: NULL] raise]; -#else - NSLog (@"PyObjCExc_InternalError: Cannot determine layout of %s", argtype); -#endif - return NULL; - } - - type = PyMem_Malloc(sizeof(*type)); - if (type == NULL) { - PyErr_NoMemory(); - return NULL; - } - type->size = PyObjCRT_SizeOfType(argtype); - type->alignment = PyObjCRT_AlignOfType(argtype); - type->type = FFI_TYPE_STRUCT; - type->elements = PyMem_Malloc((1+field_count) * sizeof(ffi_type*)); - if (type->elements == NULL) { - PyMem_Free(type); - PyErr_NoMemory(); - return NULL; - } - - field_count = 0; - curtype = argtype+1; - while (*curtype != _C_STRUCT_E && *curtype != '=') curtype++; - if (*curtype == '=') { - curtype ++; - while (*curtype != _C_STRUCT_E) { - type->elements[field_count] = - signature_to_ffi_type(curtype); - if (type->elements[field_count] == NULL) { - PyMem_Free(type->elements); - return NULL; - } - field_count++; - curtype = PyObjCRT_SkipTypeSpec(curtype); - if (curtype == NULL) { - PyMem_Free(type->elements); - return NULL; - } - } - } - type->elements[field_count] = NULL; - - v = [NSValue valueWithPointer: type]; - if (v == NULL || v == nil) { - free_type(type); - return NULL; - } - - NS_DURING - { - [struct_types setObject: v forKey: key]; - } - NS_HANDLER - { - NS_VALUERETURN (NULL, ffi_type*); - } - NS_ENDHANDLER - - return type; -} - -ffi_type* -objcl_pyobjc_signature_to_ffi_return_type(const char* argtype) -{ - switch (*argtype) { - case _C_CHR: case _C_SHT: - return &ffi_type_sint; - case _C_UCHR: case _C_USHT: - return &ffi_type_uint; -#ifdef _C_BOOL - case _C_BOOL: return &ffi_type_sint; -#endif - default: - return signature_to_ffi_type(argtype); - } -} - - -static ffi_type* -signature_to_ffi_type(const char* argtype) -{ - switch (*argtype) { - case _C_VOID: return &ffi_type_void; - case _C_ID: return &ffi_type_pointer; - case _C_CLASS: return &ffi_type_pointer; - case _C_SEL: return &ffi_type_pointer; - case _C_CHR: return &ffi_type_schar; -#ifdef _C_BOOL - case _C_BOOL: return &ffi_type_sint; -#endif - case _C_UCHR: return &ffi_type_uchar; - case _C_SHT: return &ffi_type_sshort; - case _C_USHT: return &ffi_type_ushort; - case _C_INT: return &ffi_type_sint; - case _C_UINT: return &ffi_type_uint; - - /* The next to defintions are incorrect, but the correct definitions - * don't work (e.g. give testsuite failures). We should be fine - * as long as sizeof(long) == sizeof(int) - */ - case _C_LNG: return &ffi_type_sint; /* ffi_type_slong */ - case _C_ULNG: return &ffi_type_uint; /* ffi_type_ulong */ - case _C_LNGLNG: return &ffi_type_sint64; - case _C_ULNGLNG: return &ffi_type_uint64; - case _C_FLT: return &ffi_type_float; - case _C_DBL: return &ffi_type_double; - case _C_CHARPTR: return &ffi_type_pointer; - case _C_PTR: return &ffi_type_pointer; - case _C_ARY_B: - return array_to_ffi_type(argtype); - case _C_IN: case _C_OUT: case _C_INOUT: case _C_CONST: - return signature_to_ffi_type(argtype+1); - case _C_STRUCT_B: - return struct_to_ffi_type(argtype); - default: -#ifdef STRICT_TYPE_PARSING - [[NSException exceptionWithName: @"PyExc_NotImplementedError" - reason: [NSString stringWithFormat: @"Type '%c' not supported", *argtype] - userInfo: NULL] raise]; -#else - NSLog (@"PyExc_NotImplementedError: Type '%#x' not supported", *argtype); -#endif - return NULL; - } -} - -/* - * arg_signature_to_ffi_type: Make the ffi_type for the call to the method IMP, - * on MacOS X this is the same as the normal signature_to_ffi_type, but on - * Linux/GNUstep we need a slightly different function. - */ -#ifdef MACOSX - -#ifdef __ppc__ -ffi_type* -objcl_pyobjc_arg_signature_to_ffi_type(const char* argtype) -{ - return signature_to_ffi_type (argtype); -} - -#else -ffi_type* -objcl_pyobjc_arg_signature_to_ffi_type(const char* argtype) -{ - /* NOTE: This is the minimal change to pass the unittests, it is not - * based on analysis of the calling conventions. - */ - switch (*argtype) { - case _C_CHR: return &ffi_type_sint; - case _C_UCHR: return &ffi_type_uint; - case _C_SHT: return &ffi_type_sint; - case _C_USHT: return &ffi_type_uint; - default: return signature_to_ffi_type(argtype); - } -} -#endif - -#else /* GNUstep */ - -ffi_type* -objcl_pyobjc_arg_signature_to_ffi_type(const char* argtype) -{ - /* NOTE: This is the minimal change to pass the unittests, it is not - * based on analysis of the calling conventions. - */ - switch (*argtype) { - case _C_CHR: return &ffi_type_sint; - case _C_UCHR: return &ffi_type_uint; - case _C_SHT: return &ffi_type_sint; - case _C_USHT: return &ffi_type_uint; - default: return signature_to_ffi_type(argtype); - } -} - -#endif /* GNUstep */ diff --git a/Objective-C/libobjcl.m b/Objective-C/libobjcl.m index a1a0a39..58baf67 100644 --- a/Objective-C/libobjcl.m +++ b/Objective-C/libobjcl.m @@ -18,8 +18,8 @@ */ #import "libobjcl.h" -#import "libffi_support.h" -#import "objc_support.h" +#import "PyObjC/libffi_support.h" +#import "PyObjC/objc_support.h" #import #include diff --git a/Objective-C/objc-runtime-apple.h b/Objective-C/objc-runtime-apple.h deleted file mode 100644 index 8d050a1..0000000 --- a/Objective-C/objc-runtime-apple.h +++ /dev/null @@ -1,137 +0,0 @@ -/* Copyright (c) 1996,97,98 by Lele Gaifax. All Rights Reserved - * Copyright (c) 2003 Ronald Oussoren - * - * This software may be used and distributed freely for any purpose - * provided that this notice is included unchanged on any and all - * copies. The author does not warrant or guarantee this software in - * any way. - * - * This file is part of the PyObjC package. - * - * RCSfile: objc_support.h,v - * Revision: 1.16 - * Date: 1998/08/18 15:35:57 - * - * Created Tue Sep 10 14:11:38 1996. - */ - -#ifndef PyObjC_RUNTIME_APPLE_H -#define PyObjC_RUNTIME_APPLE_H - -#import -#import - -#include -#include - -#include -#include -#include -#include - -static inline int -PyObjCRT_SameSEL(SEL a, SEL b) -{ - return a == b; -} - -static inline const char* -PyObjCRT_SELName(SEL sel) -{ - return sel_getName(sel); -} - -static inline SEL -PyObjCRT_SELUID(const char* str) -{ - return sel_getUid(str); -} - -static inline Class -PyObjCRT_LookUpClass(const char* name) -{ - return objc_lookUpClass(name); -} - -static inline struct objc_method_list * -PyObjCRT_NextMethodList(Class c, void ** p) -{ - return class_nextMethodList(c, p); -} - -static inline void -PyObjCRT_InitMethod(Method m, SEL name, const char* types, IMP imp) -{ - memset(m, 0, sizeof(*m)); - m->method_name = name; - m->method_types = strdup((char*)types); - m->method_imp = imp; -} - -static inline void -PyObjCRT_ClassAddMethodList(Class cls, struct objc_method_list* lst) -{ - class_addMethods(cls, lst); -} - - -extern struct objc_method_list* PyObjCRT_AllocMethodList(ssize_t); -extern struct objc_protocol_list* PyObjCRT_AllocProtocolList(ssize_t); - -typedef Method PyObjCRT_Method_t; -typedef Ivar PyObjCRT_Ivar_t; - -#define GETISA(c) ((c)->isa) - -#define RECEIVER(c) ((c).receiver) - -#define _C_CONST 'r' -#define _C_IN 'n' -#define _C_INOUT 'N' -#define _C_OUT 'o' -#define _C_BYCOPY 'O' -#define _C_ONEWAY 'V' -#define _C_LNGLNG 'q' -#define _C_ULNGLNG 'Q' -#define _C_BOOL 'B' /* (Objective-)C++ 'bool' */ - - -/* Return a number that is likely to change when the method list changes, - * and is cheap to compute. - */ -static inline int -objc_methodlist_magic(Class cls) -{ - int res = 0; - int cnt = 0; - - /* This is the documented way of enumerating the method list. It - * is slower than the obvious way, but does not explode under - * esoteric situations. - */ - void *iterator = NULL; - struct objc_method_list *mlist; - - if (cls == NULL) return -1; - - while ( (mlist = class_nextMethodList( cls, &iterator )) != NULL ) { - res += mlist->method_count; - cnt++; - } - - return (cnt << 16) | (res & 0xFFFF); -} - -static inline const char * -get_selector_encoding (id self, SEL sel) -{ - struct objc_method* m = class_getInstanceMethod(self->isa, sel); - - if (!m) { - return NULL; - } else { - return m->method_types; - } -} - -#endif /* PyObjC_RUNTIME_APPLE_H */ diff --git a/Objective-C/objc-runtime-apple.m b/Objective-C/objc-runtime-apple.m deleted file mode 100644 index b2888ac..0000000 --- a/Objective-C/objc-runtime-apple.m +++ /dev/null @@ -1,159 +0,0 @@ -/* This file is part of the PyObjC package. */ -/* - * Support code for the Apple runtime - */ -#include "pyobjc.h" - -#if defined(APPLE_RUNTIME) -#include "objc-runtime-apple.h" - -int PyObjCRT_SetupClass( - Class cls, - Class metaCls, - const char*name, - Class superCls, - Class rootCls, - ssize_t ivarSize, - struct objc_ivar_list* ivarList, - struct objc_protocol_list* protocolList -) - -{ - /* Initialize the structure */ - memset(cls, 0, sizeof(*cls)); - memset(metaCls, 0, sizeof(*cls)); - - cls->methodLists = NULL; - metaCls->methodLists = NULL; - cls->isa = metaCls; - - cls->info = CLS_CLASS; // |CLS_METHOD_ARRAY; - metaCls->info = CLS_META; // |CLS_METHOD_ARRAY; - - 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->methodLists = malloc(sizeof(struct objc_method_list*)); - if (cls->methodLists == NULL) { - PyErr_NoMemory(); - free((char*)(cls->name)); - cls->name = NULL; - free((char*)(metaCls->name)); - metaCls->name = NULL; - return -1; - } - memset(cls->methodLists, 0, sizeof(*(cls->methodLists))); - - metaCls->methodLists = malloc(sizeof(struct objc_method_list*)); - if (cls->methodLists == NULL) { - PyErr_NoMemory(); - free((char*)(cls->name)); - cls->name = NULL; - free((char*)(metaCls->name)); - metaCls->name = NULL; - free(cls->methodLists); - cls->methodLists = NULL; - return -1; - } - memset(metaCls->methodLists, 0, sizeof(*(metaCls->methodLists))); - - /* - * This is MacOS X specific, and an undocumented feature (long live - * Open Source!). - * - * The code in the objc runtime assumes that the method lists are - * terminated by '-1', and will happily overwite existing data if - * they aren't. - * - * Ronald filed a bugreport for this: Radar #3317376 - */ - cls->methodLists[0] = (struct objc_method_list*)-1; - metaCls->methodLists[0] = (struct objc_method_list*)-1; - - cls->super_class = superCls; - metaCls->super_class = superCls->isa; - metaCls->isa = rootCls->isa; - - cls->instance_size = ivarSize; - cls->ivars = ivarList; - - metaCls->instance_size = metaCls->super_class->instance_size; - metaCls->ivars = NULL; - - metaCls->protocols = cls->protocols = protocolList; - - return 0; -} - -void PyObjCRT_ClearClass(Class cls) -{ - if (cls->methodLists) { - if (cls->methodLists) { - struct objc_method_list** cur; - - cur = cls->methodLists; - while (*cur != (struct objc_method_list*)-1) { - if (*cur != NULL) { - free(*cur); - *cur = NULL; - } - cur++; - } - free(cls->methodLists); - cls->methodLists = NULL; - } - cls->methodLists = NULL; - } - - if (cls->name) { - free((char*)(cls->name)); - } -} - -struct objc_method_list *PyObjCRT_AllocMethodList(ssize_t numMethods) -{ - struct objc_method_list *mlist; - - mlist = malloc(sizeof(struct objc_method_list) - + ((numMethods+1) * sizeof(struct objc_method))); - - if (mlist == NULL) { - return NULL; - } - - mlist->method_count = 0; - mlist->obsolete = NULL; - - return mlist; -} - -struct objc_protocol_list* PyObjCRT_AllocProtocolList(ssize_t 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; -} - -#else /* !APPLE_RUNTIME */ - -static int dummy __attribute__((__unused__)); - -#endif /* !APPLE_RUNTIME */ diff --git a/Objective-C/objc-runtime-gnu.h b/Objective-C/objc-runtime-gnu.h deleted file mode 100644 index 5c87b6d..0000000 --- a/Objective-C/objc-runtime-gnu.h +++ /dev/null @@ -1,174 +0,0 @@ -#ifndef PyObjC_RUNTIME_GNU_H -#define PyObjC_RUNTIME_GNU_H - -/* - * Specific support for the GNU Objective-C runtime - */ - -#include -#include - -#define objc_msgSendSuper(super, op, args...) \ - ((super)->self == NULL \ - ? 0 \ - : ( \ - class_get_instance_method( \ - (super)->class, (op) \ - )->method_imp)( \ - (super)->self, \ - (op) ,##args)) - - -/* - * XXX: AFAIK as I (Ronald) know, there should be an include named - * on systems with the GNU runtime. However, this file - * not present on my Linux playmachine (running Debian testing)... - * - * The alternative is to declare some prototypes ourselves... - */ -#if 0 -# include -#else - extern void class_add_method_list(Class, MethodList_t); - extern void __objc_add_class_to_hash(Class); -#endif - - -#ifndef nil -#define nil NULL -#endif - -/* What we call _C_LNGLNG is actually _C_LNG_LNG in the GNU runtime */ -#define _C_LNGLNG _C_LNG_LNG -#define _C_ULNGLNG _C_ULNG_LNG - -/* XXX: names don't conform to the coding-style! */ -extern Ivar_t class_getInstanceVariable(Class aClass, const char *name); -extern Ivar_t object_getInstanceVariable(id obj, const char *name, void **out); -extern Ivar_t object_setInstanceVariable(id obj, const char *name, void *value); -extern void objc_addClass(Class aClass); -//extern id objc_msgSendSuper(struct objc_super *super, SEL op, ...); -extern void objc_freeMethodList(struct objc_method_list *list); - -static inline int PyObjCRT_SameSEL(SEL a, SEL b) -{ - return sel_eq(a, b); -} - - -static inline const char* -PyObjCRT_SELName(SEL sel) -{ - return sel_get_name(sel); -} - -static inline SEL -PyObjCRT_SELUID(const char* str) -{ - return sel_get_uid(str); -} - -static inline void -PyObjCRT_ClassAddMethodList(Class cls, MethodList_t lst) -{ - int i; - - /* First convert the method_names to strings, class_add_method_list - * assumes the method_names are strings and converts these back - * to selectors. - */ - for (i = 0; i < lst->method_count; i++) { - lst->method_list[i].method_name = (SEL)PyObjCRT_SELName(lst->method_list[i].method_name); - } - - class_add_method_list(cls, lst); -} - -static inline Class -PyObjCRT_LookUpClass(const char* name) -{ - return objc_lookup_class(name); -} - -static inline struct objc_method_list * -PyObjCRT_NextMethodList(Class c, void ** p) -{ - if (*p == 0) { - *p = c->methods; - } else { - *p = (*((MethodList_t*)p))->method_next; - } - return *(MethodList_t*)p; -} - -static inline void -PyObjCRT_InitMethod(Method_t m, SEL name, const char* types, IMP imp) -{ - /* XXX: With some versions of the GNU runtime, the runtime assumes - * that method_name is initialy a string instead of a selector, other - * versions do not. The version on my development box currently - * doesn't. - * - * m->method_name = (SEL)PyObjCRT_SELName(name); - */ - m->method_name = name; - m->method_types = types; - m->method_imp = imp; -} - - -extern MethodList_t PyObjCRT_AllocMethodList(ssize_t); -extern struct objc_protocol_list* PyObjCRT_AllocProtocolList(ssize_t); - - -typedef Method_t PyObjCRT_Method_t; -typedef Ivar_t PyObjCRT_Ivar_t; - -static inline Class GETISA(id obj) -{ - return obj->class_pointer; -} - -//#define GETISA(c) (*((struct objc_object**)&(c))->class_pointer) -#define CLS_CLASS _CLS_CLASS -#define CLS_META _CLS_META -#define RECEIVER(c) (c).self - -static inline const char * -get_selector_encoding (id self, SEL sel) -{ - return sel->sel_types; -} - - - -extern void PyObjCRT_AddClass(Class cls); -#define objc_addClass PyObjCRT_AddClass - -/* Return a number that is likely to change when the method list changes, - * and is cheap to compute. - */ -static inline int -objc_methodlist_magic(Class cls) -{ - struct objc_method_list *mlist; - int res, cnt; - void *iterator = 0; - - res = cnt = 0; - - if (cls == NULL) - return -1; - - while ((mlist = PyObjCRT_NextMethodList(cls, &iterator))) - { - res += mlist->method_count; - cnt ++; - } - - return (cnt << 16) | (res & 0xFFFF); -} - - - -#endif /* PyObjC_RUNTIME_GNU_H */ diff --git a/Objective-C/objc-runtime-gnu.m b/Objective-C/objc-runtime-gnu.m deleted file mode 100644 index df868e4..0000000 --- a/Objective-C/objc-runtime-gnu.m +++ /dev/null @@ -1,217 +0,0 @@ -/* 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) -#include "objc-runtime-gnu.h" - -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 */ diff --git a/Objective-C/objc_support.h b/Objective-C/objc_support.h deleted file mode 100644 index a9b4b28..0000000 --- a/Objective-C/objc_support.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright (c) 1996,97,98 by Lele Gaifax. All Rights Reserved - * Copyright (2) 2003 Ronald Oussoren - * - * This software may be used and distributed freely for any purpose - * provided that this notice is included unchanged on any and all - * copies. The author does not warrant or guarantee this software in - * any way. - * - * This file is part of the PyObjC package. - * - * RCSfile: objc_support.h,v - * Revision: 1.16 - * Date: 1998/08/18 15:35:57 - * - * Created Tue Sep 10 14:11:38 1996. - * - * TODO: the functions exported by this file should be changed, the names - * should start with 'PyObjC' and should be the same as the names used in - * pyobjc-api.h (where appropriate). - */ - -#ifndef _objc_support_H -#define _objc_support_H - -#ifdef GNU_RUNTIME - -# include "objc-runtime-gnu.h" - -#else /* NeXTSTEP / Mac OS X */ - -# include "objc-runtime-apple.h" - -#endif - -extern ssize_t PyObjCRT_SizeOfReturnType(const char* type); -extern ssize_t PyObjCRT_SizeOfType(const char *type); -extern ssize_t PyObjCRT_AlignOfType(const char *type); -extern const char *PyObjCRT_SkipTypeSpec (const char *type); -extern const char* PyObjCRT_SkipTypeQualifiers (const char* type); - -extern int PyObjCRT_SetupClass( - Class, Class, const char*, Class, Class, ssize_t, struct objc_ivar_list*, - struct objc_protocol_list*); -extern void PyObjCRT_ClearClass(Class cls); - -#endif /* _objc_support_H */ diff --git a/Objective-C/objc_support.m b/Objective-C/objc_support.m deleted file mode 100644 index 862879c..0000000 --- a/Objective-C/objc_support.m +++ /dev/null @@ -1,505 +0,0 @@ -/* Copyright (c) 1996,97,98 by Lele Gaifax. All Rights Reserved - * Copyright (c) 2002, 2003 Ronald Oussoren - * - * This software may be used and distributed freely for any purpose - * provided that this notice is included unchanged on any and all - * copies. The author does not warrant or guarantee this software in - * any way. - * - * This file is part of the PyObjC package. - * - * RCSfile: objc_support.m,v - * Revision: 1.24 - * Date: 1998/08/18 15:35:58 - * - * Created Tue Sep 10 14:16:02 1996. - */ - -#include "objc_support.h" -#include "pyobjc.h" - -#include - -#include - -#ifdef MACOSX -/* OSX 10.1 doesn't define LLONG_MIN, LLONG_MAX and ULLONG_MAX */ -#ifndef LLONG_MIN -#error "Mac OS X 10.1 not supported" -#endif -#endif - -#import -#import -#import -#import - -#ifdef MACOSX -#include -#endif /* MACOSX */ - - -/* Define in order to throw exceptions when a typespec cannot be parsed. */ -#undef STRICT_TYPE_PARSING - - -#ifndef MAX -static inline ssize_t -MAX(ssize_t x, ssize_t y) -{ - return x > y ? x : y; -} -#endif - -static inline ssize_t -ROUND(ssize_t v, ssize_t a) -{ - if (v % a == 0) { - return v; - } else { - return v + a - (v % a); - } -} - - -const char* -PyObjCRT_SkipTypeQualifiers (const char* type) -{ - while ( - *type == _C_CONST || - *type == _C_IN || - *type == _C_INOUT || - *type == _C_OUT || - *type == _C_BYCOPY || - *type == _C_ONEWAY) { - type++; - } - while (*type && isdigit(*type)) type++; - return type; -} - - -const char * -PyObjCRT_SkipTypeSpec (const char *type) -{ - type = PyObjCRT_SkipTypeQualifiers (type); - - switch (*type) { - /* The following are one character type codes */ - case _C_UNDEF: - case _C_CLASS: - case _C_SEL: - case _C_CHR: - case _C_UCHR: - case _C_CHARPTR: -#ifdef _C_ATOM - case _C_ATOM: -#endif -#ifdef _C_BOOL - case _C_BOOL: -#endif - case _C_SHT: - case _C_USHT: - case _C_INT: - case _C_UINT: - case _C_LNG: - case _C_ULNG: - case _C_FLT: - case _C_DBL: - case _C_VOID: - case _C_LNGLNG: - case _C_ULNGLNG: - case _C_BFLD: /* Not really 1 character, but close enough */ - ++type; - break; - - case _C_ID: - ++type; -#ifdef MACOSX - if (*type == '"') { - /* embedded field name in an ivar_type */ - type=strchr(type+1, '"'); - if (type != NULL) { - type++; - } - } -#endif - break; - - case _C_ARY_B: - /* skip digits, typespec and closing ']' */ - - while (isdigit (*++type)); - type = PyObjCRT_SkipTypeSpec (type); - assert (type == NULL || *type == _C_ARY_E); - if (type) type++; - break; - - case _C_STRUCT_B: - /* skip name, and elements until closing '}' */ - while (*type != _C_STRUCT_E && *type++ != '='); - while (type && *type != _C_STRUCT_E) { - if (*type == '"') { - /* embedded field names */ - type = strchr(type+1, '"'); - if (type != NULL) { - type++; - } else { - return NULL; - } - } - type = PyObjCRT_SkipTypeSpec (type); - } - if (type) type++; - break; - - case _C_UNION_B: - /* skip name, and elements until closing ')' */ - while (*type != _C_UNION_E && *type++ != '='); - while (type && *type != _C_UNION_E) { - type = PyObjCRT_SkipTypeSpec (type); - } - if (type) type++; - break; - - case _C_PTR: - case _C_CONST: - case _C_IN: - case _C_INOUT: - case _C_OUT: - case _C_BYCOPY: - case _C_ONEWAY: - - /* Just skip the following typespec */ - type = PyObjCRT_SkipTypeSpec (type+1); - break; - - - default: -#ifdef STRICT_TYPE_PARSING - [[NSException exceptionWithName: @"PyObjCRT_SkipTypeSpec" - reason: [NSString stringWithFormat: @"Unhandled type: '%c'", *type] - userInfo: NULL] raise]; -#else - NSLog (@"PyObjCRT_SkipTypeSpec: Unhandled type: '%c'", *type); -#endif - return NULL; - } - - /* The compiler inserts a number after the actual signature, - * this number may or may not be usefull depending on the compiler - * version. We never use it. - */ - while (type && *type && isdigit(*type)) type++; - return type; -} - -/* -Return the alignment of an object specified by type -*/ - -/* -* On MacOS X, the elements of a struct are aligned differently inside the -* struct than outside. That is, the maximum alignment of any struct field -* (except the first) is 4, doubles outside of a struct have an alignment of -* 8. -* -* Other platform don't seem to have this inconsistency. -* -* XXX: sizeof_struct, alignof_struct and {de,}pythonify_c_struct should -* probably be moved to platform dependend files. As long as this is the -* only platform dependent code this isn't worth the effort. -*/ -#ifdef MACOSX - -static inline ssize_t -PyObjC_EmbeddedAlignOfType (const char* type) -{ - ssize_t align = PyObjCRT_AlignOfType(type); - -#ifdef __i386__ - return align; - -#else - if (align < 4 || align == 16) { - return align; - } else { - return 4; - } -#endif -} - -#else - -static inline int -PyObjC_EmbeddedAlignOfType (const char* type) -{ - ssize_t align = PyObjCRT_AlignOfType(type); - - /* GNUstep/ix86 seems to behave like this: */ - if (align < 4) { - return align; - } else { - return 4; - } -} - -#endif - -ssize_t -PyObjCRT_AlignOfType (const char *type) -{ - switch (*type) { - case _C_ID: return __alignof__ (id); - case _C_CLASS: return __alignof__ (Class); - case _C_SEL: return __alignof__ (SEL); - case _C_CHR: return __alignof__ (char); - case _C_UCHR: return __alignof__ (unsigned char); - case _C_SHT: return __alignof__ (short); - case _C_USHT: return __alignof__ (unsigned short); -#ifdef _C_BOOL - case _C_BOOL: return __alignof__ (bool); -#endif - case _C_INT: return __alignof__ (int); - case _C_UINT: return __alignof__ (unsigned int); - case _C_LNG: return __alignof__ (long); - case _C_ULNG: return __alignof__ (unsigned long); - case _C_FLT: return __alignof__ (float); - case _C_DBL: -#if defined(__APPLE__) && defined(__i386__) - /* The ABI says natural alignment is 4 bytes, but - * GCC's __alignof__ says 8. The latter is wrong. - */ - return 4; -#else - return __alignof__ (double); -#endif - - case _C_CHARPTR: return __alignof__ (char *); -#ifdef _C_ATOM - case _C_ATOM: return __alignof__ (char *); -#endif - case _C_PTR: return __alignof__ (void *); -#if defined(__APPLE__) && defined(__i386__) - /* The ABI says natural alignment is 4 bytes, but - * GCC's __alignof__ says 8. The latter is wrong. - */ - case _C_LNGLNG: return 4; - case _C_ULNGLNG: return 4; -#else - case _C_LNGLNG: return __alignof__(long long); - case _C_ULNGLNG: return __alignof__(unsigned long long); -#endif - - case _C_ARY_B: - while (isdigit(*++type)) /* do nothing */; - return PyObjCRT_AlignOfType (type); - - case _C_STRUCT_B: - { - struct { int x; double y; } fooalign; - while(*type != _C_STRUCT_E && *type++ != '=') /* do nothing */; - if (*type != _C_STRUCT_E) { - int have_align = 0; - ssize_t align = 0; - - while (type != NULL && *type != _C_STRUCT_E) { - if (*type == '"') { - type = strchr(type+1, '"'); - if (type) type++; - } - if (have_align) { - align = MAX(align, - PyObjC_EmbeddedAlignOfType(type)); - } else { - align = PyObjCRT_AlignOfType(type); - have_align = 1; - } - type = PyObjCRT_SkipTypeSpec(type); - } - if (type == NULL) return -1; - return align; - } else { - return __alignof__ (fooalign); - } - } - - case _C_UNION_B: - { - int maxalign = 0; - type++; - while (*type != _C_UNION_E) - { - int item_align = PyObjCRT_AlignOfType(type); - if (item_align == -1) return -1; - maxalign = MAX (maxalign, item_align); - type = PyObjCRT_SkipTypeSpec (type); - } - return maxalign; - } - - case _C_CONST: - case _C_IN: - case _C_INOUT: - case _C_OUT: - case _C_BYCOPY: - case _C_ONEWAY: - return PyObjCRT_AlignOfType(type+1); - - default: -#ifdef STRICT_TYPE_PARSING - [[NSException exceptionWithName: @"PyObjCRT_SkipTypeSpec" - reason: [NSString stringWithFormat: @"Unhandled type: '%c'", *type] - userInfo: NULL] raise]; -#else - NSLog (@"PyObjCRT_SkipTypeSpec: Unhandled type: '%c'", *type); -#endif - return -1; - } -} - -/* -The aligned size if the size rounded up to the nearest alignment. -*/ - -static ssize_t -PyObjCRT_AlignedSize (const char *type) -{ - ssize_t size = PyObjCRT_SizeOfType (type); - ssize_t align = PyObjCRT_AlignOfType (type); - - if (size == -1 || align == -1) return -1; - return ROUND(size, align); -} - -/* -return the size of an object specified by type -*/ - -ssize_t -PyObjCRT_SizeOfType (const char *type) -{ - ssize_t itemSize; - switch (*type) { - case _C_VOID: return 0; - case _C_ID: return sizeof(id); - case _C_CLASS: return sizeof(Class); - case _C_SEL: return sizeof(SEL); - case _C_CHR: return sizeof(char); - case _C_UCHR: return sizeof(unsigned char); - case _C_SHT: return sizeof(short); - case _C_USHT: return sizeof(unsigned short); -#ifdef _C_BOOL - case _C_BOOL: return sizeof(bool); -#endif - case _C_INT: return sizeof(int); - case _C_UINT: return sizeof(unsigned int); - case _C_LNG: return sizeof(long); - case _C_ULNG: return sizeof(unsigned long); - case _C_FLT: return sizeof(float); - case _C_DBL: return sizeof(double); - case _C_LNGLNG: return sizeof(long long); - case _C_ULNGLNG: return sizeof(unsigned long long); - - case _C_PTR: - case _C_CHARPTR: -#ifdef _C_ATOM - case _C_ATOM: -#endif - return sizeof(char*); - - case _C_ARY_B: - { - ssize_t len = atoi(type+1); - ssize_t item_align; - while (isdigit(*++type)) - ; - item_align = PyObjCRT_AlignedSize(type); - if (item_align == -1) return -1; - return len*item_align; - } - break; - - case _C_STRUCT_B: - { - ssize_t acc_size = 0; - int have_align = 0; - ssize_t align; - ssize_t max_align = 0; - - while (*type != _C_STRUCT_E && *type++ != '=') - ; /* skip "=" */ - while (*type != _C_STRUCT_E) { - if (*type == '"') { - type = strchr(type+1, '"'); - if (type) type++; - } - if (have_align) { - align = PyObjC_EmbeddedAlignOfType(type); - if (align == -1) return -1; - } else { - align = PyObjCRT_AlignOfType(type); - if (align == -1) return -1; - have_align = 1; - } - max_align = MAX(align, max_align); - acc_size = ROUND (acc_size, align); - - itemSize = PyObjCRT_SizeOfType (type); - if (itemSize == -1) return -1; - acc_size += itemSize; - type = PyObjCRT_SkipTypeSpec (type); - } - if (max_align) { - acc_size = ROUND(acc_size, max_align); - } - return acc_size; - } - - case _C_UNION_B: - { - ssize_t max_size = 0; - type++; - while (*type != _C_UNION_E) { - itemSize = PyObjCRT_SizeOfType (type); - if (itemSize == -1) return -1; - max_size = MAX (max_size, itemSize); - type = PyObjCRT_SkipTypeSpec (type); - } - return max_size; - } - - case _C_CONST: - case _C_IN: - case _C_INOUT: - case _C_OUT: - case _C_BYCOPY: - case _C_ONEWAY: - return PyObjCRT_SizeOfType(type+1); - - default: -#ifdef STRICT_TYPE_PARSING - [[NSException exceptionWithName: @"PyObjCRT_SkipTypeSpec" - reason: [NSString stringWithFormat: @"Unhandled type: '%c'", *type] - userInfo: NULL] raise]; -#else - NSLog (@"PyObjCRT_SkipTypeSpec: Unhandled type: '%c'", *type); -#endif - return -1; - } -} - - -ssize_t -PyObjCRT_SizeOfReturnType(const char* type) -{ - switch(*type) { - case _C_CHR: - case _C_UCHR: - case _C_SHT: - case _C_USHT: - return sizeof(int); - default: - return PyObjCRT_SizeOfType(type); - } -} diff --git a/Objective-C/pyobjc.h b/Objective-C/pyobjc.h deleted file mode 100644 index 6a2d6b4..0000000 --- a/Objective-C/pyobjc.h +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright 2007, Matthias Andreas Benkard. */ - -#ifndef __pyobjc_H -#define __pyobjc_H - -#include -#include -#include "libobjcl.h" - - -#ifdef __NEXT_RUNTIME__ - -#ifndef APPLE_RUNTIME -#define APPLE_RUNTIME -#endif - -#import - -#else /* !__NEXT_RUNTIME__ */ - -#ifndef GNU_RUNTIME -#define GNU_RUNTIME -#endif - -#import -#ifndef __CXX__ -#define bool BOOL -#endif - -#endif /* __NEXT_RUNTIME__ */ - - -#define PyMem_Free free -#define PyMem_Malloc malloc -#define Py_ssize_t ssize_t - -#ifdef OOM_KILL -#define PyErr_NoMemory() [objcl_oom_exception raise] -#else -#define PyErr_NoMemory() NSLog (@"ERROR: Memory exhausted."); -#endif - -#include "objc_support.h" -#include "libffi_support.h" - -#endif /* __pyobjc_H */ -- cgit v1.2.3