]> err.no Git - sope/commitdiff
cleaned up NGObjCRuntime
authorhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Mon, 14 Feb 2005 21:16:51 +0000 (21:16 +0000)
committerhelge <helge@e4a50df8-12e2-0310-a44c-efbce7f8a7e3>
Mon, 14 Feb 2005 21:16:51 +0000 (21:16 +0000)
git-svn-id: http://svn.opengroupware.org/SOPE/trunk@560 e4a50df8-12e2-0310-a44c-efbce7f8a7e3

sope-core/NGExtensions/ChangeLog
sope-core/NGExtensions/NGObjCRuntime.m
sope-core/NGExtensions/Version

index e4d699a65db4e9aa2c9aa1eac8f077d9340e60f2..3dc6a840fbee149b5857343c6eb66595655dcd43 100644 (file)
@@ -1,3 +1,7 @@
+2005-02-14  Helge Hess  <helge.hess@opengroupware.org>
+
+       * NGObjCRuntime.m: decoupled some varargs processing (v4.5.148)
+
 2005-02-14  Helge Hess  <helge.hess@opengroupware.org>
 
        * NGExtensions/NGCalendarDateRange.h: fixed header file for MacOSX
index 4f7f1ee2de4ad9d278ccbd3acd90338468d64d60..80b461755d016357b9474f0a8b3590021a19740a 100644 (file)
@@ -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 */
index 25eb59ed9cd832e4e01c0f9f5ab2f14143dd4485..ec9dec8fd8a60cb614e9bf67bfa0b1f628f14483 100644 (file)
@@ -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