]> git.saurik.com Git - apple/objc4.git/blobdiff - runtime/objc-runtime-old.h
objc4-818.2.tar.gz
[apple/objc4.git] / runtime / objc-runtime-old.h
index ad5e99ecc7e898b9f295a31eed9779e0646747ed..14672106da8ca9ef8ba8c9b76689c0bcfa1d571f 100644 (file)
@@ -52,8 +52,8 @@
 #define CLS_CONSTRUCTING        0x10000
 // visibility=hidden
 #define CLS_HIDDEN              0x20000
-// GC:  class has unsafe finalize method
-#define CLS_FINALIZE_ON_MAIN_THREAD 0x40000
+// available for use; was CLS_FINALIZE_ON_MAIN_THREAD
+#define CLS_40000               0x40000
 // Lazy property list arrays
 #define CLS_NO_PROPERTY_ARRAY  0x80000
 // +load implementation
 #define CLS_LEAF                0x800000
 // class instances may have associative references
 #define CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS 0x1000000
-// class has instance-specific GC layout
-#define CLS_HAS_INSTANCE_SPECIFIC_LAYOUT 0x2000000
+// available for use; was CLS_HAS_INSTANCE_SPECIFIC_LAYOUT
+#define CLS_2000000 0x2000000
+// class compiled with ARC
+#define CLS_IS_ARC              0x4000000
+// class is not ARC but has ARC-style weak ivar layout
+#define CLS_HAS_WEAK_WITHOUT_ARC 0x8000000
 
 
 // Terminator for array of method lists
 #define GETMETA(cls)           (ISMETA(cls) ? (cls) : (cls)->ISA())
 
 
+struct old_class_ext {
+    uint32_t size;
+    const uint8_t *weak_ivar_layout;
+    struct old_property_list **propertyLists;
+};
+
+struct old_category {
+    char *category_name;
+    char *class_name;
+    struct old_method_list *instance_methods;
+    struct old_method_list *class_methods;
+    struct old_protocol_list *protocols;
+    // Fields below this point are in version 7 or later only.
+    uint32_t size;
+    struct old_property_list *instance_properties;
+    // Check size for fields below this point.
+    struct old_property_list *class_properties;
+
+    bool hasClassPropertiesField() const { 
+        return size >= offsetof(old_category, class_properties) + sizeof(class_properties);
+    }
+};
+
+struct old_ivar {
+    char *ivar_name;
+    char *ivar_type;
+    int ivar_offset;
+#ifdef __LP64__
+    int space;
+#endif
+};
+
+struct old_ivar_list {
+    int ivar_count;
+#ifdef __LP64__
+    int space;
+#endif
+    /* variable length structure */
+    struct old_ivar ivar_list[1];
+};
+
+
+struct old_method {
+    SEL method_name;
+    char *method_types;
+    IMP method_imp;
+};
+
+struct old_method_list {
+    void *obsolete;
+
+    int method_count;
+#ifdef __LP64__
+    int space;
+#endif
+    /* variable length structure */
+    struct old_method method_list[1];
+};
+
+struct old_protocol {
+    Class isa;
+    const char *protocol_name;
+    struct old_protocol_list *protocol_list;
+    struct objc_method_description_list *instance_methods;
+    struct objc_method_description_list *class_methods;
+};
+
+struct old_protocol_list {
+    struct old_protocol_list *next;
+    long count;
+    struct old_protocol *list[1];
+};
+
+struct old_protocol_ext {
+    uint32_t size;
+    struct objc_method_description_list *optional_instance_methods;
+    struct objc_method_description_list *optional_class_methods;
+    struct old_property_list *instance_properties;
+    const char **extendedMethodTypes;
+    struct old_property_list *class_properties;
+
+    bool hasClassPropertiesField() const { 
+        return size >= offsetof(old_protocol_ext, class_properties) + sizeof(class_properties);
+    }
+};
+
+
+struct old_property {
+    const char *name;
+    const char *attributes;
+};
+
+struct old_property_list {
+    uint32_t entsize;
+    uint32_t count;
+    struct old_property first;
+};
+
+
 struct objc_class : objc_object {
     Class superclass;
     const char *name;
@@ -102,7 +205,7 @@ struct objc_class : objc_object {
 
     // set and clear must not overlap
     void changeInfo(uint32_t set, uint32_t clear) {
-        assert((set & clear) == 0);
+        ASSERT((set & clear) == 0);
 
         uint32_t oldf, newf;
         do {
@@ -120,6 +223,30 @@ struct objc_class : objc_object {
         return hasCxxCtor();  // one bit for both ctor and dtor
     }
 
+    // Return YES if the class's ivars are managed by ARC, 
+    // or the class is MRC but has ARC-style weak ivars.
+    bool hasAutomaticIvars() {
+        return info & (CLS_IS_ARC | CLS_HAS_WEAK_WITHOUT_ARC);
+    }
+
+    // Return YES if the class's ivars are managed by ARC.
+    bool isARC() {
+        return info & CLS_IS_ARC;
+    }
+
+    bool hasCustomRR() {
+        return true;
+    }
+
+    bool hasCustomAWZ() {
+        return true;
+    }
+
+    bool forbidsAssociatedObjects() {
+        // Old runtime doesn't support forbidding associated objects.
+        return false;
+    }
+    
     bool instancesHaveAssociatedObjects() {
         return info & CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS;
     }
@@ -137,14 +264,6 @@ struct objc_class : objc_object {
         else clearInfo(CLS_GROW_CACHE);
     }
 
-    bool shouldFinalizeOnMainThread() {
-        return info & CLS_FINALIZE_ON_MAIN_THREAD;
-    }
-
-    void setShouldFinalizeOnMainThread() {
-        setInfo(CLS_FINALIZE_ON_MAIN_THREAD);
-    }
-
     // +initialize bits are stored on the metaclass only
     bool isInitializing() {
         return getMeta()->info & CLS_INITIALIZING;
@@ -173,9 +292,21 @@ struct objc_class : objc_object {
 
     IMP getLoadMethod();
 
+    bool isFuture();
+
     bool isConnected();
 
-    const char *getName() { return name; }
+    const char *mangledName() { return name; }
+    const char *demangledName() { return name; }
+    const char *nameForLogging() { return name; }
+    
+    bool isRootClass() {
+        return superclass == nil;
+    }
+
+    bool isRootMetaclass() {
+        return ISA() == (Class)this;
+    }
 
     bool isMetaClass() {
         return info & CLS_META;
@@ -187,6 +318,25 @@ struct objc_class : objc_object {
         else return this->ISA();
     }
 
+    // May be unaligned depending on class's ivars.
+    uint32_t unalignedInstanceStart() {
+        // This is not simply superclass->instance_size.
+        // superclass->instance_size is padded to its sizeof() boundary, 
+        // which may envelop one of this class's ivars. 
+        // That in turn would break ARC-style ivar layouts.
+        // Instead, we use the address of this class's first ivar when possible.
+        if (!superclass) return 0;
+        if (!ivars || ivars->ivar_count == 0) return superclass->instance_size;
+        return ivars->ivar_list[0].ivar_offset;
+    }
+
+    // Class's instance start rounded up to a pointer-size boundary.
+    // This is used for ARC layout bitmaps.
+    uint32_t alignedInstanceStart() {
+        return word_align(unalignedInstanceStart());
+    }
+
+
     // May be unaligned depending on class's ivars.
     uint32_t unalignedInstanceSize() {
         return instance_size;
@@ -194,95 +344,16 @@ struct objc_class : objc_object {
 
     // Class's ivar size rounded up to a pointer-size boundary.
     uint32_t alignedInstanceSize() {
-        return (unalignedInstanceSize() + WORD_MASK) & ~WORD_MASK;
+        return word_align(unalignedInstanceSize());
     }
 
-};
-
-struct old_class_ext {
-    uint32_t size;
-    const uint8_t *weak_ivar_layout;
-    struct old_property_list **propertyLists;
-};
-
-struct old_category {
-    char *category_name;
-    char *class_name;
-    struct old_method_list *instance_methods;
-    struct old_method_list *class_methods;
-    struct old_protocol_list *protocols;
-    uint32_t size;
-    struct old_property_list *instance_properties;
-};
-
-struct old_ivar {
-    char *ivar_name;
-    char *ivar_type;
-    int ivar_offset;
-#ifdef __LP64__
-    int space;
-#endif
-};
-
-struct old_ivar_list {
-    int ivar_count;
-#ifdef __LP64__
-    int space;
-#endif
-    /* variable length structure */
-    struct old_ivar ivar_list[1];
-};
-
-
-struct old_method {
-    SEL method_name;
-    char *method_types;
-    IMP method_imp;
-};
-
-struct old_method_list {
-    void *obsolete;
-
-    int method_count;
-#ifdef __LP64__
-    int space;
-#endif
-    /* variable length structure */
-    struct old_method method_list[1];
-};
-
-struct old_protocol {
-    Class isa;
-    const char *protocol_name;
-    struct old_protocol_list *protocol_list;
-    struct objc_method_description_list *instance_methods;
-    struct objc_method_description_list *class_methods;
-};
-
-struct old_protocol_list {
-    struct old_protocol_list *next;
-    long count;
-    struct old_protocol *list[1];
-};
-
-struct old_protocol_ext {
-    uint32_t size;
-    struct objc_method_description_list *optional_instance_methods;
-    struct objc_method_description_list *optional_class_methods;
-    struct old_property_list *instance_properties;
-    const char **extendedMethodTypes;
-};
-
-
-struct old_property {
-    const char *name;
-    const char *attributes;
-};
+    size_t instanceSize(size_t extraBytes) {
+        size_t size = alignedInstanceSize() + extraBytes;
+        // CF requires all objects be at least 16 bytes.
+        if (size < 16) size = 16;
+        return size;
+    }
 
-struct old_property_list {
-    uint32_t entsize;
-    uint32_t count;
-    struct old_property first;
 };
 
 
@@ -304,17 +375,17 @@ extern IMP lookupNamedMethodInMethodList(struct old_method_list *mlist, const ch
 extern void _objc_insertMethods(Class cls, struct old_method_list *mlist, struct old_category *cat);
 extern void _objc_removeMethods(Class cls, struct old_method_list *mlist);
 extern void _objc_flush_caches (Class cls);
-extern BOOL _class_addProperties(Class cls, struct old_property_list *additions);
-extern BOOL _class_hasLoadMethod(Class cls);
-extern void change_class_references(Class imposter, Class original, Class copy, BOOL changeSuperRefs);
+extern bool _class_addProperties(Class cls, struct old_property_list *additions);
+extern bool _class_hasLoadMethod(Class cls);
+extern void change_class_references(Class imposter, Class original, Class copy, bool changeSuperRefs);
 extern void flush_marked_caches(void);
-extern void set_superclass(Class cls, Class supercls, BOOL cls_is_new);
+extern void set_superclass(Class cls, Class supercls, bool cls_is_new);
 extern void try_free(const void *p);
 
 extern struct old_property *property_list_nth(const struct old_property_list *plist, uint32_t i);
 extern struct old_property **copyPropertyList(struct old_property_list *plist, unsigned int *outCount);
 
-extern struct objc_method_description * lookup_protocol_method(struct old_protocol *proto, SEL aSel, BOOL isRequiredMethod, BOOL isInstanceMethod, BOOL recursive);
+extern struct objc_method_description * lookup_protocol_method(struct old_protocol *proto, SEL aSel, bool isRequiredMethod, bool isInstanceMethod, bool recursive);
 
 // used by flush_caches outside objc-cache.m
 extern void _cache_flush(Class cls);