X-Git-Url: https://git.saurik.com/apple/objc4.git/blobdiff_plain/8070259c3936ee823b758fc1ad1645ae016ba500..refs/heads/master:/runtime/objc-runtime-old.h?ds=sidebyside diff --git a/runtime/objc-runtime-old.h b/runtime/objc-runtime-old.h index 31e1335..1467210 100644 --- a/runtime/objc-runtime-old.h +++ b/runtime/objc-runtime-old.h @@ -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 @@ -65,8 +65,12 @@ #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 @@ -77,6 +81,105 @@ #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,20 +223,30 @@ struct objc_class : objc_object { 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; } @@ -151,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; @@ -187,11 +292,21 @@ struct objc_class : objc_object { 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; @@ -203,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; @@ -210,7 +344,7 @@ 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()); } size_t instanceSize(size_t extraBytes) { @@ -222,92 +356,6 @@ struct objc_class : objc_object { }; -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" @@ -327,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);