From ddd5e22c74431c8dc0573e8bbcdac1557b11b636 Mon Sep 17 00:00:00 2001 From: helge Date: Mon, 14 Feb 2005 21:16:51 +0000 Subject: [PATCH] cleaned up NGObjCRuntime git-svn-id: http://svn.opengroupware.org/SOPE/trunk@560 e4a50df8-12e2-0310-a44c-efbce7f8a7e3 --- sope-core/NGExtensions/ChangeLog | 4 + sope-core/NGExtensions/NGObjCRuntime.m | 227 +++++++++++++++++-------- sope-core/NGExtensions/Version | 2 +- 3 files changed, 158 insertions(+), 75 deletions(-) diff --git a/sope-core/NGExtensions/ChangeLog b/sope-core/NGExtensions/ChangeLog index e4d699a6..3dc6a840 100644 --- a/sope-core/NGExtensions/ChangeLog +++ b/sope-core/NGExtensions/ChangeLog @@ -1,3 +1,7 @@ +2005-02-14 Helge Hess + + * NGObjCRuntime.m: decoupled some varargs processing (v4.5.148) + 2005-02-14 Helge Hess * NGExtensions/NGCalendarDateRange.h: fixed header file for MacOSX diff --git a/sope-core/NGExtensions/NGObjCRuntime.m b/sope-core/NGExtensions/NGObjCRuntime.m index 4f7f1ee2..80b46175 100644 --- a/sope-core/NGExtensions/NGObjCRuntime.m +++ b/sope-core/NGExtensions/NGObjCRuntime.m @@ -74,6 +74,26 @@ void class_add_behavior(Class class, Class behavior) { @end +#if NeXT_RUNTIME || APPLE_RUNTIME + +static __inline__ unsigned NGGetSizeOfType(char *ivarType) { + // TODO: add more types ... + switch (*ivarType) { + /* the Apple runtime has no func to calc a type size ?! */ + case '@': return sizeof(id); + case ':': return sizeof(SEL); + case 'c': return sizeof(signed char); + case 's': return sizeof(signed short); + case 'i': return sizeof(signed int); + case 'C': return sizeof(unsigned char); + case 'S': return sizeof(unsigned short); + case 'I': return sizeof(unsigned int); + default: return 0xDEAFBEAF; + } +} + +#endif + @implementation NSObject(NGObjCRuntime) static NSArray *emptyArray = nil; @@ -384,8 +404,36 @@ fillMethodListWithSpecs(MethodList_t methods, SEL _selector, va_list *va) void __objc_resolve_class_links(); #endif - //printf("execute class\n"); + /* + This is the main entry function in the GNU runtime. It does a LOT of + work, including the setup of global hashes if missing. Some things (like + the global hashes) are not relevant for us, since the runtime itself is + already up. + This function uses the internal lock for runtime modifications. + + The method does with the runtime lock applied (2.95.3): + - setup globals + - registers typed selectors for symtab->refs + - walks over all classes + - adds the class to the hash + - registers the selectors of the class + - registers the selectors of the metaclass + - install dtable's (just assigns NULL?) + - registers instance methods as class methods for root classes + - inits protocols + - add superclasses to unresolved-classes + - walks over all categories + - register uninitialized statics + - walk over unclaimed categories + - walk over unclaimed protocols + - send the +load message + + Actually this function just calls __objc_exec_module(), don't know why + we call this one instead. + */ + // printf("execute class\n"); __objc_exec_class(module); + //printf("resolve links\n"); __objc_resolve_class_links(); } @@ -395,21 +443,14 @@ fillMethodListWithSpecs(MethodList_t methods, SEL _selector, va_list *va) } + (Class)subclass:(NSString *)_className - ivars:(NSString *)_name1,... + ivarNames:(NSString **)_ivarNames + ivarTypes:(NSString **)_ivarTypes + ivarCount:(unsigned)ivarCount { - va_list va; - unsigned ivarCount, currentSize; - NSString *n, *t; + unsigned currentSize; currentSize = ((Class)self)->instance_size; - va_start(va, _name1); - for (n = _name1, t = va_arg(va, NSString *), ivarCount = 0; - (n != nil && t != nil); - n = va_arg(va, NSString *), t = va_arg(va, NSString *)) - ivarCount++; - va_end(va); - #if NeXT_RUNTIME || APPLE_RUNTIME { /* some tricks for Apple inspired by PyObjC, long live OpenSource ;-) */ @@ -422,17 +463,20 @@ fillMethodListWithSpecs(MethodList_t methods, SEL _selector, va_list *va) ivars = NULL; if (ivarCount > 0) { + unsigned i; + ivars = calloc(sizeof(struct objc_ivar_list) + (ivarCount) * sizeof(struct objc_ivar), sizeof(char)); - va_start(va, _name1); - for (n = _name1, t = va_arg(va, NSString *), ivarCount = 0; - (n != nil && t != nil); - n = va_arg(va, NSString *), t=va_arg(va, NSString *), ivarCount++) { + for (i = 0; i < ivarCount; i++) { + NSString *n, *t; Ivar var; char *ivarName, *ivarType; int ivarOffset; unsigned len, typeAlign, typeLen; + + n = _ivarNames[i]; + t = _ivarTypes[i]; len = [n cStringLength]; ivarName = malloc(len + 2); @@ -446,24 +490,13 @@ fillMethodListWithSpecs(MethodList_t methods, SEL _selector, va_list *va) /* calc ivarOffset */ typeAlign = 0; // TODO: alignment?! - // TODO: add more types ... - switch (*ivarType) { - /* the Apple runtime has no func to calc a type size ?! */ - case '@': typeLen = sizeof(id); break; - case ':': typeLen = sizeof(SEL); break; - case 'c': typeLen = sizeof(signed char); break; - case 's': typeLen = sizeof(signed short); break; - case 'i': typeLen = sizeof(signed int); break; - case 'C': typeLen = sizeof(unsigned char); break; - case 'S': typeLen = sizeof(unsigned short); break; - case 'I': typeLen = sizeof(unsigned int); break; - default: - NSAssert1(NO, @"does not support ivars of type '%s'", ivarType); - break; - } + + typeLen = NGGetSizeOfType(ivarType); + NSAssert1(typeLen != 0xDEAFBEAF, + @"does not support ivars of type '%s'", ivarType); ivarOffset = currentSize; - - var = ivars->ivar_list + ivars->ivar_count; + + var = ivars->ivar_list + ivars->ivar_count; ivars->ivar_count++; var->ivar_name = ivarName; @@ -473,9 +506,8 @@ fillMethodListWithSpecs(MethodList_t methods, SEL _selector, va_list *va) /* adjust current size */ currentSize = ivarOffset + typeLen; } - va_end(va); } - + // TODO: move the following to a subclass method /* determine root class */ @@ -525,53 +557,100 @@ fillMethodListWithSpecs(MethodList_t methods, SEL _selector, va_list *va) } #else { - IvarList_t ivars; - - ivars = malloc(sizeof(IvarList) + (sizeof(struct objc_ivar) * ivarCount)); - ivars->ivar_count = ivarCount; + unsigned i; + IvarList_t ivars; - va_start(va, _name1); - for (n = _name1, t = va_arg(va, NSString *), ivarCount = 0; - (n != nil && t != nil); - n = va_arg(va, NSString *), t = va_arg(va, NSString *), ivarCount++) { - char *ivarName, *ivarType; - int ivarOffset; - unsigned len, typeAlign, typeLen; - - len = [n cStringLength]; - ivarName = malloc(len + 2); - [n getCString:ivarName]; - ivarName[len] = '\0'; - - len = [t cStringLength]; - ivarType = malloc(len + 2); - [t getCString:ivarType]; - ivarType[len] = '\0'; - - /* calc ivarOffset */ - typeAlign = objc_alignof_type(ivarType); - typeLen = objc_sizeof_type(ivarType); - ivarOffset = currentSize; + ivars = malloc(sizeof(IvarList) + (sizeof(struct objc_ivar) * ivarCount)); + ivars->ivar_count = ivarCount; - /* check if offset is aligned */ - if ((ivarOffset % typeAlign) != 0) { - /* align offset */ - len = (typeAlign - (ivarOffset % typeAlign)); - ivarOffset += len; - } + for (i = 0; i < ivarCount; i++) { + NSString *n, *t; + char *ivarName, *ivarType; + int ivarOffset; + unsigned len, typeAlign, typeLen; + + n = _ivarNames[i]; + t = _ivarTypes[i]; + + len = [n cStringLength]; + ivarName = malloc(len + 2); + [n getCString:ivarName]; + ivarName[len] = '\0'; + + len = [t cStringLength]; + ivarType = malloc(len + 2); + [t getCString:ivarType]; + ivarType[len] = '\0'; + + /* calc ivarOffset */ + typeAlign = objc_alignof_type(ivarType); + typeLen = objc_sizeof_type(ivarType); + ivarOffset = currentSize; + + /* check if offset is aligned */ + if ((ivarOffset % typeAlign) != 0) { + /* align offset */ + len = (typeAlign - (ivarOffset % typeAlign)); + ivarOffset += len; + } - /* adjust current size */ - currentSize = ivarOffset + typeLen; + /* adjust current size */ + currentSize = ivarOffset + typeLen; - ivars->ivar_list[ivarCount].ivar_name = ivarName; - ivars->ivar_list[ivarCount].ivar_type = ivarType; - ivars->ivar_list[ivarCount].ivar_offset = ivarOffset; + ivars->ivar_list[ivarCount].ivar_name = ivarName; + ivars->ivar_list[ivarCount].ivar_type = ivarType; + ivars->ivar_list[ivarCount].ivar_offset = ivarOffset; + } + va_end(va); + + return [self subclass:_className ivarsList:ivars]; } +#endif +} + ++ (Class)subclass:(NSString *)_className + ivars:(NSString *)_name1,... +{ + va_list va; /* contains: name1, type1, name2, type2, ... */ + unsigned ivarCount; + NSString *n, *t; + NSString **ivarNames = NULL; + NSString **ivarTypes = NULL; + Class clazz; + + /* determine number of args */ + + va_start(va, _name1); + for (n = _name1, t = va_arg(va, NSString *), ivarCount = 0; + (n != nil && t != nil); + n = va_arg(va, NSString *), t = va_arg(va, NSString *)) + ivarCount++; va_end(va); - return [self subclass:_className ivarsList:ivars]; + /* collect args */ + + if (ivarCount > 0) { + ivarNames = calloc(ivarCount, sizeof(NSString *)); + ivarTypes = calloc(ivarCount, sizeof(NSString *)); + va_start(va, _name1); + for (n = _name1, t = va_arg(va, NSString *), ivarCount = 0; + (n != nil && t != nil); + n = va_arg(va, NSString *), t = va_arg(va, NSString *)) { + ivarNames[ivarCount] = n; + ivarTypes[ivarCount] = t; + ivarCount++; + } + va_end(va); } -#endif + + /* call primary method */ + + clazz = [self subclass:_className + ivarNames:ivarNames ivarTypes:ivarTypes ivarCount:ivarCount]; + + if (ivarNames != NULL) free(ivarNames); + if (ivarTypes != NULL) free(ivarTypes); + return clazz; } /* instance variables */ diff --git a/sope-core/NGExtensions/Version b/sope-core/NGExtensions/Version index 25eb59ed..ec9dec8f 100644 --- a/sope-core/NGExtensions/Version +++ b/sope-core/NGExtensions/Version @@ -1,6 +1,6 @@ # version -SUBMINOR_VERSION:=147 +SUBMINOR_VERSION:=148 # v4.3.115 requires libFoundation v1.0.59 # v4.2.72 requires libEOControl v4.2.39 -- 2.39.5