#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;
// 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 {
return hasCxxCtor(); // one bit for both ctor and dtor
}
- bool hasCustomRR() {
+ // 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;
}
- void setHasCustomRR(bool = false) { }
- void setHasDefaultRR() { }
- void printCustomRR(bool) { }
- bool hasCustomAWZ() {
+ bool hasCustomAWZ() {
return true;
}
- void setHasCustomAWZ(bool = false) { }
- void setHasDefaultAWZ() { }
- void printCustomAWZ(bool) { }
+ bool forbidsAssociatedObjects() {
+ // Old runtime doesn't support forbidding associated objects.
+ return false;
+ }
+
bool instancesHaveAssociatedObjects() {
return info & CLS_INSTANCES_HAVE_ASSOCIATED_OBJECTS;
}
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;
IMP getLoadMethod();
+ bool isFuture();
+
bool isConnected();
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;
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;
// Class's ivar size rounded up to a pointer-size boundary.
uint32_t alignedInstanceSize() {
- return (unalignedInstanceSize() + WORD_MASK) & ~WORD_MASK;
+ return word_align(unalignedInstanceSize());
}
size_t instanceSize(size_t extraBytes) {
};
-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;
-};
-
-struct old_property_list {
- uint32_t entsize;
- uint32_t count;
- struct old_property first;
-};
-
#include "hashtable2.h"
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);