]> git.saurik.com Git - apple/objc4.git/blobdiff - runtime/objc-runtime-new.h
objc4-493.9.tar.gz
[apple/objc4.git] / runtime / objc-runtime-new.h
index 1f84e36dfc79a07287b401620483d3fee13e1725..64e8736f6a27c1bf728c58b46806c789f17b8414 100644 (file)
  * @APPLE_LICENSE_HEADER_END@
  */
 
+#ifndef _OBJC_RUNTIME_NEW_H
+#define _OBJC_RUNTIME_NEW_H
+
+__BEGIN_DECLS
+
 // Values for class_ro_t->flags
 // These are emitted by the compiler and are part of the ABI. 
 // class is a metaclass
 #define RO_HIDDEN             (1<<4)
 // class has attribute(objc_exception): OBJC_EHTYPE_$_ThisClass is non-weak
 #define RO_EXCEPTION          (1<<5)
+// this bit is available for reassignment
+// #define RO_REUSE_ME           (1<<6) 
+// class compiled with -fobjc-arr (automatic retain/release)
+#define RO_IS_ARR             (1<<7)
+
 // class is in an unloadable bundle - must never be set by compiler
 #define RO_FROM_BUNDLE        (1<<29)
 // class is unrealized future class - must never be set by compiler
 #define RW_SPECIALIZED_VTABLE (1<<22)
 // class instances may have associative references
 #define RW_INSTANCES_HAVE_ASSOCIATED_OBJECTS (1<<21)
+// class or superclass has .cxx_construct/destruct implementations
+#define RW_HAS_CXX_STRUCTORS  (1<<20)
+// class has instance-specific GC layout
+#define RW_HAS_INSTANCE_SPECIFIC_LAYOUT (1 << 19)
+// class or superclass has non-trivial .release_ivars implementation
+#define RW_HAS_IVAR_RELEASER  (1<<18)
+// class or superclass has custom retain/release/autorelease/retainCount impl
+#define RW_HAS_CUSTOM_RR      (1<<17)
 
-typedef struct method_t {
+struct method_t {
     SEL name;
     const char *types;
     IMP imp;
-} method_t;
+
+    struct SortBySELAddress :
+        public std::binary_function<const method_t&,
+                                    const method_t&, bool>
+    {
+        bool operator() (const method_t& lhs,
+                         const method_t& rhs)
+        { return lhs.name < rhs.name; }
+    };
+};
 
 typedef struct method_list_t {
-    uint32_t entsize_NEVER_USE;  // low 2 bits used for fixup markers
+    uint32_t entsize_NEVER_USE;  // high bits used for fixup markers
     uint32_t count;
-    struct method_t first;
+    method_t first;
+
+    uint32_t getEntsize() const { 
+        return entsize_NEVER_USE & ~(uint32_t)3; 
+    }
+    uint32_t getCount() const { 
+        return count; 
+    }
+    method_t& get(uint32_t i) const { 
+        return *(method_t *)((uint8_t *)&first + i*getEntsize()); 
+    }
+
+    // iterate methods, taking entsize into account
+    // fixme need a proper const_iterator
+    struct method_iterator {
+        uint32_t entsize;
+        uint32_t index;  // keeping track of this saves a divide in operator-
+        method_t* method;
+
+        typedef std::random_access_iterator_tag iterator_category;
+        typedef method_t value_type;
+        typedef ptrdiff_t difference_type;
+        typedef method_t* pointer;
+        typedef method_t& reference;
+
+        method_iterator() { }
+
+        method_iterator(const method_list_t& mlist, uint32_t start = 0)
+            : entsize(mlist.getEntsize())
+            , index(start)
+            , method(&mlist.get(start))
+        { }
+
+        const method_iterator& operator += (ptrdiff_t count) {
+            method = (method_t*)((uint8_t *)method + count*entsize);
+            index += (int32_t)count;
+            return *this;
+        }
+        const method_iterator& operator -= (ptrdiff_t count) {
+            method = (method_t*)((uint8_t *)method - count*entsize);
+            index -= (int32_t)count;
+            return *this;
+        }
+        const method_iterator operator + (ptrdiff_t count) const {
+            return method_iterator(*this) += count;
+        }
+        const method_iterator operator - (ptrdiff_t count) const {
+            return method_iterator(*this) -= count;
+        }
+
+        method_iterator& operator ++ () { *this += 1; return *this; }
+        method_iterator& operator -- () { *this -= 1; return *this; }
+        method_iterator operator ++ (int) {
+            method_iterator result(*this); *this += 1; return result;
+        }
+        method_iterator operator -- (int) {
+            method_iterator result(*this); *this -= 1; return result;
+        }
+
+        ptrdiff_t operator - (const method_iterator& rhs) const {
+            return (ptrdiff_t)this->index - (ptrdiff_t)rhs.index;
+        }
+
+        method_t& operator * () const { return *method; }
+        method_t* operator -> () const { return method; }
+
+        operator method_t& () const { return *method; }
+
+        bool operator == (const method_iterator& rhs) {
+            return this->method == rhs.method;
+        }
+        bool operator != (const method_iterator& rhs) {
+            return this->method != rhs.method;
+        }
+
+        bool operator < (const method_iterator& rhs) {
+            return this->method < rhs.method;
+        }
+        bool operator > (const method_iterator& rhs) {
+            return this->method > rhs.method;
+        }
+    };
+
+    method_iterator begin() const { return method_iterator(*this, 0); }
+    method_iterator end() const { return method_iterator(*this, getCount()); }
+
 } method_list_t;
 
 typedef struct ivar_t {
@@ -94,9 +206,20 @@ typedef struct ivar_t {
 typedef struct ivar_list_t {
     uint32_t entsize;
     uint32_t count;
-    struct ivar_t first;
+    ivar_t first;
 } ivar_list_t;
 
+typedef struct objc_property {
+    const char *name;
+    const char *attributes;
+} property_t;
+
+typedef struct property_list_t {
+    uint32_t entsize;
+    uint32_t count;
+    property_t first;
+} property_list_t;
+
 typedef uintptr_t protocol_ref_t;  // protocol_t *, but unremapped
 
 typedef struct protocol_t {
@@ -107,7 +230,7 @@ typedef struct protocol_t {
     method_list_t *classMethods;
     method_list_t *optionalInstanceMethods;
     method_list_t *optionalClassMethods;
-    struct objc_property_list *instanceProperties;
+    property_list_t *instanceProperties;
 } protocol_t;
 
 typedef struct protocol_list_t {
@@ -132,7 +255,7 @@ typedef struct class_ro_t {
     const ivar_list_t * ivars;
 
     const uint8_t * weakIvarLayout;
-    const struct objc_property_list *baseProperties;
+    const property_list_t *baseProperties;
 } class_ro_t;
 
 typedef struct class_rw_t {
@@ -141,20 +264,63 @@ typedef struct class_rw_t {
 
     const class_ro_t *ro;
     
-    struct method_list_t **methods;
+    method_list_t **methods;
     struct chained_property_list *properties;
-    struct protocol_list_t ** protocols;
+    const protocol_list_t ** protocols;
 
     struct class_t *firstSubclass;
     struct class_t *nextSiblingClass;
 } class_rw_t;
 
+// We cannot store flags in the low bits of the 'data' field until we work with
+// the 'leaks' team to not think that objc is leaking memory. See radar 8955342
+// for more info.
+#define CLASS_FAST_FLAGS_VIA_RW_DATA 0
+
 typedef struct class_t {
     struct class_t *isa;
     struct class_t *superclass;
     Cache cache;
     IMP *vtable;
-    class_rw_t *data;
+    uintptr_t data_NEVER_USE;  // class_rw_t * plus flags
+
+    class_rw_t *data() const { 
+#if CLASS_FAST_FLAGS_VIA_RW_DATA
+        return (class_rw_t *)(data_NEVER_USE & ~3UL); 
+#else
+        return (class_rw_t *)data_NEVER_USE;
+#endif
+    }
+    void setData(class_rw_t *newData) {
+#if CLASS_FAST_FLAGS_VIA_RW_DATA
+        uintptr_t flags = (uintptr_t)data_NEVER_USE & 3UL;
+        data_NEVER_USE = (uintptr_t)newData | flags;
+#else
+        data_NEVER_USE = (uintptr_t)newData;
+#endif
+    }
+
+    bool hasCustomRR() const {
+#if CLASS_FAST_FLAGS_VIA_RW_DATA
+       return data_NEVER_USE & 1UL;
+#else
+        return (data()->flags & RW_HAS_CUSTOM_RR);
+#endif
+    }
+    void setHasCustomRR();
+    void unsetHasCustomRR();
+
+    bool hasIvarReleaser() const {
+        return (data()->flags & RW_HAS_IVAR_RELEASER);
+    }
+    void setHasIvarReleaser();
+
+    bool isRootClass() const {
+        return superclass == NULL;
+    }
+    bool isRootMetaclass() const {
+        return isa == this;
+    }
 } class_t;
 
 typedef struct category_t {
@@ -163,10 +329,20 @@ typedef struct category_t {
     struct method_list_t *instanceMethods;
     struct method_list_t *classMethods;
     struct protocol_list_t *protocols;
-    struct objc_property_list *instanceProperties;
+    struct property_list_t *instanceProperties;
 } category_t;
 
 struct objc_super2 {
     id receiver;
     Class current_class;
 };
+
+typedef struct {
+    IMP imp;
+    SEL sel;
+} message_ref_t;
+
+
+__END_DECLS
+
+#endif