Bug 564991. Part 1: Create a new kind of frame property that can receive a frame pointer when its destructor is called. r=mats

This commit is contained in:
Robert O'Callahan 2010-07-16 09:07:45 +12:00
parent 29ce16568f
commit 270cfe600a
3 changed files with 41 additions and 19 deletions

View File

@ -62,7 +62,7 @@ FramePropertyTable::Set(nsIFrame* aFrame, const FramePropertyDescriptor* aProper
}
if (entry->mProp.mProperty == aProperty) {
// Just overwrite the current value
entry->mProp.DestroyValue();
entry->mProp.DestroyValueFor(aFrame);
entry->mProp.mValue = aValue;
return;
}
@ -80,7 +80,7 @@ FramePropertyTable::Set(nsIFrame* aFrame, const FramePropertyDescriptor* aProper
array->IndexOf(aProperty, 0, PropertyComparator());
if (index != nsTArray<PropertyValue>::NoIndex) {
PropertyValue* pv = &array->ElementAt(index);
pv->DestroyValue();
pv->DestroyValueFor(aFrame);
pv->mValue = aValue;
return;
}
@ -201,8 +201,9 @@ FramePropertyTable::Delete(nsIFrame* aFrame, const FramePropertyDescriptor* aPro
PRBool found;
void* v = Remove(aFrame, aProperty, &found);
if (found && aProperty->mDestructor) {
aProperty->mDestructor(v);
if (found) {
PropertyValue pv(aProperty, v);
pv.DestroyValueFor(aFrame);
}
}
@ -210,13 +211,13 @@ FramePropertyTable::Delete(nsIFrame* aFrame, const FramePropertyDescriptor* aPro
FramePropertyTable::DeleteAllForEntry(Entry* aEntry)
{
if (!aEntry->mProp.IsArray()) {
aEntry->mProp.DestroyValue();
aEntry->mProp.DestroyValueFor(aEntry->GetKey());
return;
}
nsTArray<PropertyValue>* array = aEntry->mProp.ToArray();
for (PRUint32 i = 0; i < array->Length(); ++i) {
array->ElementAt(i).DestroyValue();
array->ElementAt(i).DestroyValueFor(aEntry->GetKey());
}
array->nsTArray<PropertyValue>::~nsTArray<PropertyValue>();
}

View File

@ -48,6 +48,8 @@ namespace mozilla {
struct FramePropertyDescriptor;
typedef void (*FramePropertyDestructor)(void* aPropertyValue);
typedef void (*FramePropertyDestructorWithFrame)(nsIFrame* aFrame,
void* aPropertyValue);
/**
* A pointer to a FramePropertyDescriptor serves as a unique property ID.
@ -62,9 +64,22 @@ typedef void (*FramePropertyDestructor)(void* aPropertyValue);
*/
struct FramePropertyDescriptor {
/**
* mDestructor may be null, in which case no value destruction is a no-op.
* mDestructor will be called if it's non-null.
*/
FramePropertyDestructor mDestructor;
/**
* mDestructorWithFrame will be called if it's non-null and mDestructor
* is null. WARNING: The frame passed to mDestructorWithFrame may
* be a dangling frame pointer, if this is being called during
* presshell teardown. Do not use it except to compare against
* other frame pointers. No frame will have been allocated with
* the same address yet.
*/
FramePropertyDestructorWithFrame mDestructorWithFrame;
/**
* mDestructor and mDestructorWithFrame may both be null, in which case
* no value destruction is a no-op.
*/
FramePropertyDestructor mDestructor;
};
/**
@ -156,9 +171,11 @@ protected:
return reinterpret_cast<nsTArray<PropertyValue>*>(&mValue);
}
void DestroyValue() {
void DestroyValueFor(nsIFrame* aFrame) {
if (mProperty->mDestructor) {
mProperty->mDestructor(mValue);
} else if (mProperty->mDestructorWithFrame) {
mProperty->mDestructorWithFrame(aFrame, mValue);
}
}

View File

@ -828,19 +828,23 @@ public:
#ifdef _MSC_VER
// XXX Workaround MSVC issue by making the static FramePropertyDescriptor
// non-const. See bug 555727.
#define NS_DECLARE_FRAME_PROPERTY(prop, dtor) \
static const FramePropertyDescriptor* prop() { \
static FramePropertyDescriptor descriptor = { dtor }; \
return &descriptor; \
}
#define NS_PROPERTY_DESCRIPTOR_CONST
#else
#define NS_DECLARE_FRAME_PROPERTY(prop, dtor) \
static const FramePropertyDescriptor* prop() { \
static const FramePropertyDescriptor descriptor = { dtor }; \
return &descriptor; \
}
#define NS_PROPERTY_DESCRIPTOR_CONST const
#endif
#define NS_DECLARE_FRAME_PROPERTY(prop, dtor) \
static const FramePropertyDescriptor* prop() { \
static NS_PROPERTY_DESCRIPTOR_CONST FramePropertyDescriptor descriptor = { dtor, nsnull }; \
return &descriptor; \
}
// Don't use this unless you really know what you're doing!
#define NS_DECLARE_FRAME_PROPERTY_WITH_FRAME_IN_DTOR(prop, dtor) \
static const FramePropertyDescriptor* prop() { \
static NS_PROPERTY_DESCRIPTOR_CONST FramePropertyDescriptor descriptor = { nsnull, dtor }; \
return &descriptor; \
}
NS_DECLARE_FRAME_PROPERTY(IBSplitSpecialSibling, nsnull)
NS_DECLARE_FRAME_PROPERTY(IBSplitSpecialPrevSibling, nsnull)