Fix for 108389. r=jkeiser, sr=jst

This commit is contained in:
hyatt%netscape.com 2001-11-05 06:45:04 +00:00
parent 76a930d89c
commit 34f94450e0
5 changed files with 41 additions and 30 deletions

View File

@ -355,12 +355,19 @@ nsXBLContentSink::CreateElement(const nsIParserNode& aNode, PRInt32 aNameSpaceID
if (!prototype)
return NS_ERROR_OUT_OF_MEMORY;
prototype->mType = nsXULPrototypeNode::eType_RefCounted_Element;
prototype->mNodeInfo = aNodeInfo;
// Reset the refcnt to 0. Normally XUL prototype elements get a refcnt of 1
// to represent ownership by the XUL prototype document. In our case we have
// no prototype document, and our initial ref count of 1 will come from being
// wrapped by a real XUL element in the Create call below.
prototype->mRefCnt = 0;
AddAttributesToXULPrototype(aNode, prototype);
// Following this function call, the prototype's ref count will be 1.
nsresult rv = nsXULElement::Create(prototype, mDocument, PR_FALSE, aResult);
if (NS_FAILED(rv)) return rv;
return NS_OK;
}

View File

@ -515,11 +515,8 @@ nsXULElement::Init()
nsXULElement::~nsXULElement()
{
if (mPrototype && mPrototype->mType == nsXULPrototypeNode::eType_RefCounted_Element) {
mPrototype->mRefCnt--;
if (mPrototype->mRefCnt == 0)
delete mPrototype;
}
if (mPrototype)
mPrototype->Release();
delete mSlots;
@ -578,8 +575,7 @@ nsXULElement::Create(nsXULPrototypeElement* aPrototype,
element->mPrototype = aPrototype;
element->mDocument = aDocument;
if (aPrototype->mType == nsXULPrototypeNode::eType_RefCounted_Element)
aPrototype->mRefCnt++;
aPrototype->AddRef();
if (aIsScriptable) {
// Check each attribute on the prototype to see if we need to do
@ -4760,13 +4756,7 @@ nsresult nsXULElement::MakeHeavyweight()
}
}
if (proto->mType == nsXULPrototypeNode::eType_RefCounted_Element) {
proto->mRefCnt--;
if (proto->mRefCnt == 0)
delete proto;
}
proto->Release();
return NS_OK;
}

View File

@ -186,14 +186,12 @@ public:
class nsXULPrototypeNode
{
public:
enum Type { eType_Element, eType_RefCounted_Element, eType_Script, eType_Text };
enum Type { eType_Element, eType_Script, eType_Text };
Type mType;
union {
PRInt32 mLineNo;
PRInt32 mRefCnt;
};
virtual ~nsXULPrototypeNode() {}
virtual nsresult Serialize(nsIObjectOutputStream* aStream,
@ -201,9 +199,18 @@ public:
virtual nsresult Deserialize(nsIObjectInputStream* aStream,
nsIScriptContext* aContext);
void AddRef() { mRefCnt++; };
void Release()
{
mRefCnt--;
if (mRefCnt == 0)
delete this;
};
virtual void ReleaseSubtree() { Release(); };
protected:
nsXULPrototypeNode(Type aType, PRInt32 aLineNo)
: mType(aType), mLineNo(aLineNo) {}
: mType(aType), mLineNo(aLineNo), mRefCnt(1) {}
};
class nsXULPrototypeElement : public nsXULPrototypeNode
@ -226,13 +233,19 @@ public:
delete[] mAttributes;
delete mClassList;
for (PRInt32 i = mNumChildren - 1; i >= 0; --i)
delete mChildren[i];
delete[] mChildren;
}
virtual void ReleaseSubtree()
{
if (mChildren) {
for (PRInt32 i = mNumChildren-1; i >= 0; i--)
mChildren[i]->ReleaseSubtree();
}
nsXULPrototypeNode::ReleaseSubtree();
}
virtual nsresult Serialize(nsIObjectOutputStream* aStream,
nsIScriptContext* aContext);
virtual nsresult Deserialize(nsIObjectInputStream* aStream,

View File

@ -238,14 +238,15 @@ nsXULPrototypeDocument::Init()
return NS_OK;
}
nsXULPrototypeDocument::~nsXULPrototypeDocument()
{
if (mGlobalObject) {
mGlobalObject->SetContext(nsnull); // remove circular reference
mGlobalObject->SetGlobalObjectOwner(nsnull); // just in case
}
delete mRoot;
if (mRoot)
mRoot->ReleaseSubtree();
}
NS_IMPL_ISUPPORTS3(nsXULPrototypeDocument,