|
|
|
@ -630,21 +630,9 @@ namespace {
|
|
|
|
struct WeakRef
|
|
|
|
struct WeakRef
|
|
|
|
{
|
|
|
|
{
|
|
|
|
void *isa = &weakref_class;
|
|
|
|
void *isa = &weakref_class;
|
|
|
|
id object;
|
|
|
|
id obj = nullptr;
|
|
|
|
struct
|
|
|
|
size_t weak_count = 1;
|
|
|
|
{
|
|
|
|
WeakRef(id o) : obj(o) {}
|
|
|
|
size_t weak_count:((sizeof(size_t) * 8) - 1);
|
|
|
|
|
|
|
|
bool isDeleted:1;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
id obj()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (isDeleted)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return nil;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return object;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
WeakRef(id o) : object(o), weak_count(1), isDeleted(false) {}
|
|
|
|
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
template<typename T>
|
|
|
|
template<typename T>
|
|
|
|
@ -722,7 +710,7 @@ static BOOL loadWeakPointer(id *addr, id *obj, WeakRef **ref)
|
|
|
|
if (classForObject(oldObj) == (Class)&weakref_class)
|
|
|
|
if (classForObject(oldObj) == (Class)&weakref_class)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
*ref = (WeakRef*)oldObj;
|
|
|
|
*ref = (WeakRef*)oldObj;
|
|
|
|
*obj = (*ref)->obj();
|
|
|
|
*obj = (*ref)->obj;
|
|
|
|
return YES;
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*ref = NULL;
|
|
|
|
*ref = NULL;
|
|
|
|
@ -736,7 +724,7 @@ static inline BOOL weakRefRelease(WeakRef *ref)
|
|
|
|
ref->weak_count--;
|
|
|
|
ref->weak_count--;
|
|
|
|
if (ref->weak_count == 0)
|
|
|
|
if (ref->weak_count == 0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
weakRefs().erase(ref->object);
|
|
|
|
weakRefs().erase(ref->obj);
|
|
|
|
delete ref;
|
|
|
|
delete ref;
|
|
|
|
return YES;
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@ -799,7 +787,7 @@ WeakRef *incrementWeakRefCount(id obj)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
else
|
|
|
|
{
|
|
|
|
{
|
|
|
|
assert(ref->obj() == obj);
|
|
|
|
assert(ref->obj == obj);
|
|
|
|
ref->weak_count++;
|
|
|
|
ref->weak_count++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ref;
|
|
|
|
return ref;
|
|
|
|
@ -875,7 +863,7 @@ extern "C" OBJC_PUBLIC BOOL objc_delete_weak_refs(id obj)
|
|
|
|
// accesses from loading from this. This must be done after
|
|
|
|
// accesses from loading from this. This must be done after
|
|
|
|
// removing the ref from the table, because the compare operation
|
|
|
|
// removing the ref from the table, because the compare operation
|
|
|
|
// tests the obj field.
|
|
|
|
// tests the obj field.
|
|
|
|
oldRef->isDeleted = true;
|
|
|
|
oldRef->obj = nil;
|
|
|
|
// If the weak reference count is zero, then we should have
|
|
|
|
// If the weak reference count is zero, then we should have
|
|
|
|
// already removed this.
|
|
|
|
// already removed this.
|
|
|
|
assert(oldRef->weak_count > 0);
|
|
|
|
assert(oldRef->weak_count > 0);
|
|
|
|
|