Part 1 of fix for bug 379718 (using trace API for reference counts) and bug 386912 (cycle collector faults after tracing "JS object but unknown to the JS GC"). r=igor/jst, sr=jst, a=blocking1.9+/M9 (for bug 386912).
git-svn-id: svn://10.0.0.236/trunk@238286 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -752,42 +752,6 @@ public:
|
||||
*/
|
||||
static nsIContentPolicy *GetContentPolicy();
|
||||
|
||||
/**
|
||||
* Make sure that whatever value *aPtr contains at any given moment is
|
||||
* protected from JS GC until we remove the GC root. A call to this that
|
||||
* succeeds MUST be matched by a call to RemoveJSGCRoot to avoid leaking.
|
||||
*/
|
||||
static nsresult AddJSGCRoot(jsval* aPtr, const char* aName) {
|
||||
return AddJSGCRoot((void*)aPtr, aName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that whatever object *aPtr is pointing to at any given moment is
|
||||
* protected from JS GC until we remove the GC root. A call to this that
|
||||
* succeeds MUST be matched by a call to RemoveJSGCRoot to avoid leaking.
|
||||
*/
|
||||
static nsresult AddJSGCRoot(JSObject** aPtr, const char* aName) {
|
||||
return AddJSGCRoot((void*)aPtr, aName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that whatever object *aPtr is pointing to at any given moment is
|
||||
* protected from JS GC until we remove the GC root. A call to this that
|
||||
* succeeds MUST be matched by a call to RemoveJSGCRoot to avoid leaking.
|
||||
*/
|
||||
static nsresult AddJSGCRoot(void* aPtr, const char* aName);
|
||||
|
||||
/**
|
||||
* Remove aPtr as a JS GC root
|
||||
*/
|
||||
static nsresult RemoveJSGCRoot(jsval* aPtr) {
|
||||
return RemoveJSGCRoot((void*)aPtr);
|
||||
}
|
||||
static nsresult RemoveJSGCRoot(JSObject** aPtr) {
|
||||
return RemoveJSGCRoot((void*)aPtr);
|
||||
}
|
||||
static nsresult RemoveJSGCRoot(void* aPtr);
|
||||
|
||||
/**
|
||||
* Quick helper to determine whether there are any mutation listeners
|
||||
* of a given type that apply to this content or any of its ancestors.
|
||||
@@ -1002,40 +966,73 @@ public:
|
||||
*/
|
||||
static void DestroyAnonymousContent(nsCOMPtr<nsIContent>* aContent);
|
||||
|
||||
static nsresult HoldScriptObject(PRUint32 aLangID, void *aObject);
|
||||
static nsresult DropScriptObject(PRUint32 aLangID, void *aObject);
|
||||
|
||||
class ScriptObjectHolder
|
||||
/**
|
||||
* Keep script object aNewObject, held by aScriptObjectHolder, alive.
|
||||
*
|
||||
* NOTE: This currently only supports objects that hold script objects of one
|
||||
* scripting language.
|
||||
*
|
||||
* @param aLangID script language ID of aNewObject
|
||||
* @param aScriptObjectHolder the object that holds aNewObject
|
||||
* @param aTracer the tracer for aScriptObject
|
||||
* @param aNewObject the script object to hold
|
||||
* @param aWasHoldingObjects whether aScriptObjectHolder was already holding
|
||||
* script objects (ie. HoldScriptObject was called
|
||||
* on it before, without a corresponding call to
|
||||
* DropScriptObjects)
|
||||
*/
|
||||
static nsresult HoldScriptObject(PRUint32 aLangID, void* aScriptObjectHolder,
|
||||
nsScriptObjectTracer* aTracer,
|
||||
void* aNewObject, PRBool aWasHoldingObjects)
|
||||
{
|
||||
public:
|
||||
ScriptObjectHolder(PRUint32 aLangID) : mLangID(aLangID),
|
||||
mObject(nsnull)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ScriptObjectHolder);
|
||||
if (aLangID == nsIProgrammingLanguage::JAVASCRIPT) {
|
||||
return aWasHoldingObjects ? NS_OK :
|
||||
HoldJSObjects(aScriptObjectHolder, aTracer);
|
||||
}
|
||||
~ScriptObjectHolder()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ScriptObjectHolder);
|
||||
if (mObject)
|
||||
DropScriptObject(mLangID, mObject);
|
||||
|
||||
return HoldScriptObject(aLangID, aNewObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Drop any script objects that aScriptObjectHolder is holding.
|
||||
*
|
||||
* NOTE: This currently only supports objects that hold script objects of one
|
||||
* scripting language.
|
||||
*
|
||||
* @param aLangID script language ID of the objects that
|
||||
* @param aScriptObjectHolder the object that holds script object that we want
|
||||
* to drop
|
||||
* @param aTracer the tracer for aScriptObject
|
||||
*/
|
||||
static nsresult DropScriptObjects(PRUint32 aLangID, void* aScriptObjectHolder,
|
||||
nsScriptObjectTracer* aTracer)
|
||||
{
|
||||
if (aLangID == nsIProgrammingLanguage::JAVASCRIPT) {
|
||||
return DropJSObjects(aScriptObjectHolder);
|
||||
}
|
||||
nsresult set(void *aObject)
|
||||
{
|
||||
NS_ASSERTION(aObject, "unexpected null object");
|
||||
NS_ASSERTION(!mObject, "already have an object");
|
||||
nsresult rv = HoldScriptObject(mLangID, aObject);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mObject = aObject;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
void traverse(nsCycleCollectionTraversalCallback &cb)
|
||||
{
|
||||
cb.NoteScriptChild(mLangID, mObject);
|
||||
}
|
||||
PRUint32 mLangID;
|
||||
void *mObject;
|
||||
};
|
||||
|
||||
aTracer->Trace(aScriptObjectHolder, DropScriptObject, nsnull);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep the JS objects held by aScriptObjectHolder alive.
|
||||
*
|
||||
* @param aScriptObjectHolder the object that holds JS objects that we want to
|
||||
* keep alive
|
||||
* @param aTracer the tracer for aScriptObject
|
||||
*/
|
||||
static nsresult HoldJSObjects(void* aScriptObjectHolder,
|
||||
nsScriptObjectTracer* aTracer);
|
||||
|
||||
/**
|
||||
* Drop the JS objects held by aScriptObjectHolder.
|
||||
*
|
||||
* @param aScriptObjectHolder the object that holds JS objects that we want to
|
||||
* drop
|
||||
*/
|
||||
static nsresult DropJSObjects(void* aScriptObjectHolder);
|
||||
|
||||
/**
|
||||
* Convert nsIContent::IME_STATUS_* to nsIKBStateControll::IME_STATUS_*
|
||||
@@ -1122,6 +1119,10 @@ private:
|
||||
|
||||
static nsIDOMScriptObjectFactory *GetDOMScriptObjectFactory();
|
||||
|
||||
static nsresult HoldScriptObject(PRUint32 aLangID, void* aObject);
|
||||
PR_STATIC_CALLBACK(void) DropScriptObject(PRUint32 aLangID, void *aObject,
|
||||
void *aClosure);
|
||||
|
||||
static nsIDOMScriptObjectFactory *sDOMScriptObjectFactory;
|
||||
|
||||
static nsIXPConnect *sXPConnect;
|
||||
@@ -1163,14 +1164,9 @@ private:
|
||||
// Holds pointers to nsISupports* that should be released at shutdown
|
||||
static nsVoidArray* sPtrsToPtrsToRelease;
|
||||
|
||||
// For now, we don't want to automatically clean this up in Shutdown(), since
|
||||
// consumers might unfortunately end up wanting to use it after that
|
||||
static nsIJSRuntimeService* sJSRuntimeService;
|
||||
static JSRuntime* sJSScriptRuntime;
|
||||
static PRInt32 sJSScriptRootCount;
|
||||
|
||||
static nsIScriptRuntime* sScriptRuntimes[NS_STID_ARRAY_UBOUND];
|
||||
static PRInt32 sScriptRootCount[NS_STID_ARRAY_UBOUND];
|
||||
static PRUint32 sJSGCThingRootCount;
|
||||
|
||||
#ifdef IBMBIDI
|
||||
static nsIBidiKeyboard* sBidiKeyboard;
|
||||
@@ -1180,6 +1176,14 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#define NS_HOLD_JS_OBJECTS(obj, clazz) \
|
||||
nsContentUtils::HoldJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz), \
|
||||
&NS_CYCLE_COLLECTION_NAME(clazz))
|
||||
|
||||
#define NS_DROP_JS_OBJECTS(obj, clazz) \
|
||||
nsContentUtils::DropJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz))
|
||||
|
||||
|
||||
class nsCxPusher
|
||||
{
|
||||
public:
|
||||
@@ -1202,33 +1206,38 @@ public:
|
||||
nsAutoGCRoot(jsval* aPtr, nsresult* aResult) :
|
||||
mPtr(aPtr)
|
||||
{
|
||||
mResult = *aResult =
|
||||
nsContentUtils::AddJSGCRoot(aPtr, "nsAutoGCRoot");
|
||||
mResult = *aResult = AddJSGCRoot(aPtr, "nsAutoGCRoot");
|
||||
}
|
||||
|
||||
// aPtr should be the pointer to the JSObject* we want to protect
|
||||
nsAutoGCRoot(JSObject** aPtr, nsresult* aResult) :
|
||||
mPtr(aPtr)
|
||||
{
|
||||
mResult = *aResult =
|
||||
nsContentUtils::AddJSGCRoot(aPtr, "nsAutoGCRoot");
|
||||
mResult = *aResult = AddJSGCRoot(aPtr, "nsAutoGCRoot");
|
||||
}
|
||||
|
||||
// aPtr should be the pointer to the thing we want to protect
|
||||
nsAutoGCRoot(void* aPtr, nsresult* aResult) :
|
||||
mPtr(aPtr)
|
||||
{
|
||||
mResult = *aResult =
|
||||
nsContentUtils::AddJSGCRoot(aPtr, "nsAutoGCRoot");
|
||||
mResult = *aResult = AddJSGCRoot(aPtr, "nsAutoGCRoot");
|
||||
}
|
||||
|
||||
~nsAutoGCRoot() {
|
||||
if (NS_SUCCEEDED(mResult)) {
|
||||
nsContentUtils::RemoveJSGCRoot(mPtr);
|
||||
RemoveJSGCRoot(mPtr);
|
||||
}
|
||||
}
|
||||
|
||||
static void Shutdown();
|
||||
|
||||
private:
|
||||
static nsresult AddJSGCRoot(void *aPtr, const char* aName);
|
||||
static nsresult RemoveJSGCRoot(void *aPtr);
|
||||
|
||||
static nsIJSRuntimeService* sJSRuntimeService;
|
||||
static JSRuntime* sJSScriptRuntime;
|
||||
|
||||
void* mPtr;
|
||||
nsresult mResult;
|
||||
};
|
||||
|
||||
@@ -180,15 +180,15 @@ nsILineBreaker *nsContentUtils::sLineBreaker;
|
||||
nsIWordBreaker *nsContentUtils::sWordBreaker;
|
||||
nsICaseConversion *nsContentUtils::sCaseConv;
|
||||
nsVoidArray *nsContentUtils::sPtrsToPtrsToRelease;
|
||||
nsIJSRuntimeService *nsContentUtils::sJSRuntimeService;
|
||||
JSRuntime *nsContentUtils::sJSScriptRuntime;
|
||||
PRInt32 nsContentUtils::sJSScriptRootCount = 0;
|
||||
nsIScriptRuntime *nsContentUtils::sScriptRuntimes[NS_STID_ARRAY_UBOUND];
|
||||
PRInt32 nsContentUtils::sScriptRootCount[NS_STID_ARRAY_UBOUND];
|
||||
PRUint32 nsContentUtils::sJSGCThingRootCount;
|
||||
#ifdef IBMBIDI
|
||||
nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nsnull;
|
||||
#endif
|
||||
|
||||
nsIJSRuntimeService *nsAutoGCRoot::sJSRuntimeService;
|
||||
JSRuntime *nsAutoGCRoot::sJSScriptRuntime;
|
||||
|
||||
PRBool nsContentUtils::sInitialized = PR_FALSE;
|
||||
|
||||
@@ -671,7 +671,8 @@ nsContentUtils::Shutdown()
|
||||
NS_IF_RELEASE(sStringBundleService);
|
||||
NS_IF_RELEASE(sConsoleService);
|
||||
NS_IF_RELEASE(sDOMScriptObjectFactory);
|
||||
NS_IF_RELEASE(sXPConnect);
|
||||
if (sJSGCThingRootCount == 0 && sXPConnect)
|
||||
NS_RELEASE(sXPConnect);
|
||||
NS_IF_RELEASE(sSecurityManager);
|
||||
NS_IF_RELEASE(sThreadJSContextStack);
|
||||
NS_IF_RELEASE(sNameSpaceManager);
|
||||
@@ -721,6 +722,8 @@ nsContentUtils::Shutdown()
|
||||
sEventListenerManagersHash.ops = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
nsAutoGCRoot::Shutdown();
|
||||
}
|
||||
|
||||
static PRBool IsCallerTrustedForCapability(const char* aCapability)
|
||||
@@ -2672,7 +2675,7 @@ nsContentUtils::GetContentPolicy()
|
||||
|
||||
// static
|
||||
nsresult
|
||||
nsContentUtils::AddJSGCRoot(void* aPtr, const char* aName)
|
||||
nsAutoGCRoot::AddJSGCRoot(void* aPtr, const char* aName)
|
||||
{
|
||||
if (!sJSScriptRuntime) {
|
||||
nsresult rv = CallGetService("@mozilla.org/js/xpc/RuntimeService;1",
|
||||
@@ -2690,25 +2693,16 @@ nsContentUtils::AddJSGCRoot(void* aPtr, const char* aName)
|
||||
PRBool ok;
|
||||
ok = ::JS_AddNamedRootRT(sJSScriptRuntime, aPtr, aName);
|
||||
if (!ok) {
|
||||
if (sJSScriptRootCount == 0) {
|
||||
// We just got the runtime... Just null things out, since no
|
||||
// one's expecting us to have a runtime yet
|
||||
NS_RELEASE(sJSRuntimeService);
|
||||
sJSScriptRuntime = nsnull;
|
||||
}
|
||||
NS_WARNING("JS_AddNamedRootRT failed");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// We now have one more root we added to the runtime
|
||||
++sJSScriptRootCount;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsContentUtils::RemoveJSGCRoot(void* aPtr)
|
||||
nsAutoGCRoot::RemoveJSGCRoot(void* aPtr)
|
||||
{
|
||||
if (!sJSScriptRuntime) {
|
||||
NS_NOTREACHED("Trying to remove a JS GC root when none were added");
|
||||
@@ -2717,11 +2711,6 @@ nsContentUtils::RemoveJSGCRoot(void* aPtr)
|
||||
|
||||
::JS_RemoveRootRT(sJSScriptRuntime, aPtr);
|
||||
|
||||
if (--sJSScriptRootCount == 0) {
|
||||
NS_RELEASE(sJSRuntimeService);
|
||||
sJSScriptRuntime = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -3525,6 +3514,8 @@ nsresult
|
||||
nsContentUtils::HoldScriptObject(PRUint32 aLangID, void *aObject)
|
||||
{
|
||||
NS_ASSERTION(aObject, "unexpected null object");
|
||||
NS_ASSERTION(aLangID != nsIProgrammingLanguage::JAVASCRIPT,
|
||||
"Should use HoldJSObjects.");
|
||||
nsresult rv;
|
||||
|
||||
PRUint32 langIndex = NS_STID_INDEX(aLangID);
|
||||
@@ -3551,17 +3542,47 @@ nsContentUtils::HoldScriptObject(PRUint32 aLangID, void *aObject)
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsContentUtils::DropScriptObject(PRUint32 aLangID, void *aObject)
|
||||
void
|
||||
nsContentUtils::DropScriptObject(PRUint32 aLangID, void *aObject,
|
||||
void *aClosure)
|
||||
{
|
||||
NS_ASSERTION(aObject, "unexpected null object");
|
||||
NS_ASSERTION(aLangID != nsIProgrammingLanguage::JAVASCRIPT,
|
||||
"Should use DropJSObjects.");
|
||||
PRUint32 langIndex = NS_STID_INDEX(aLangID);
|
||||
NS_LOG_RELEASE(sScriptRuntimes[langIndex], sScriptRootCount[langIndex] - 1,
|
||||
"HoldScriptObject");
|
||||
nsresult rv = sScriptRuntimes[langIndex]->DropScriptObject(aObject);
|
||||
sScriptRuntimes[langIndex]->DropScriptObject(aObject);
|
||||
if (--sScriptRootCount[langIndex] == 0) {
|
||||
NS_RELEASE(sScriptRuntimes[langIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsContentUtils::HoldJSObjects(void* aScriptObjectHolder,
|
||||
nsScriptObjectTracer* aTracer)
|
||||
{
|
||||
PRBool newHolder;
|
||||
nsresult rv = sXPConnect->AddJSHolder(aScriptObjectHolder, aTracer);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
++sJSGCThingRootCount;
|
||||
NS_LOG_ADDREF(sXPConnect, sJSGCThingRootCount, "HoldJSObjects",
|
||||
sizeof(void*));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsContentUtils::DropJSObjects(void* aScriptObjectHolder)
|
||||
{
|
||||
NS_LOG_RELEASE(sXPConnect, sJSGCThingRootCount - 1, "HoldJSObjects");
|
||||
nsresult rv = sXPConnect->RemoveJSHolder(aScriptObjectHolder);
|
||||
if (--sJSGCThingRootCount == 0 && !sInitialized) {
|
||||
NS_RELEASE(sXPConnect);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -3717,3 +3738,10 @@ nsContentUtils::IsNativeAnonymous(nsIContent* aContent)
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsAutoGCRoot::Shutdown()
|
||||
{
|
||||
NS_IF_RELEASE(sJSRuntimeService);
|
||||
}
|
||||
|
||||
@@ -306,7 +306,7 @@ TraverseKey(nsISupports* aKey, nsInsertionPointList* aData, void* aClosure)
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLBinding)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLBinding)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLBinding)
|
||||
// XXX Probably can't unlink mPrototypeBinding->XBLDocumentInfo(), because
|
||||
// mPrototypeBinding is weak.
|
||||
|
||||
@@ -452,6 +452,21 @@ UnlinkProtos(nsHashKey *aKey, void *aData, void* aClosure)
|
||||
return kHashEnumerateNext;
|
||||
}
|
||||
|
||||
struct ProtoTracer
|
||||
{
|
||||
TraceCallback mCallback;
|
||||
void *mClosure;
|
||||
};
|
||||
|
||||
static PRIntn PR_CALLBACK
|
||||
TraceProtos(nsHashKey *aKey, void *aData, void* aClosure)
|
||||
{
|
||||
ProtoTracer* closure = static_cast<ProtoTracer*>(aClosure);
|
||||
nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
|
||||
proto->Trace(closure->mCallback, closure->mClosure);
|
||||
return kHashEnumerateNext;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLDocumentInfo)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXBLDocumentInfo)
|
||||
if (tmp->mBindingTable) {
|
||||
@@ -466,7 +481,14 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXBLDocumentInfo)
|
||||
tmp->mBindingTable->Enumerate(TraverseProtos, &cb);
|
||||
}
|
||||
cb.NoteXPCOMChild(static_cast<nsIScriptGlobalObject*>(tmp->mGlobalObject));
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsXBLDocumentInfo)
|
||||
if (tmp->mBindingTable) {
|
||||
ProtoTracer closure = { aCallback, aClosure };
|
||||
tmp->mBindingTable->Enumerate(TraceProtos, &closure);
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXBLDocumentInfo)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIXBLDocumentInfo)
|
||||
@@ -507,7 +529,10 @@ nsXBLDocumentInfo::~nsXBLDocumentInfo()
|
||||
mGlobalObject->SetScriptContext(nsIProgrammingLanguage::JAVASCRIPT, nsnull);
|
||||
mGlobalObject->ClearGlobalObjectOwner(); // just in case
|
||||
}
|
||||
delete mBindingTable;
|
||||
if (mBindingTable) {
|
||||
NS_DROP_JS_OBJECTS(this, nsXBLDocumentInfo);
|
||||
delete mBindingTable;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@@ -541,8 +566,13 @@ DeletePrototypeBinding(nsHashKey* aKey, void* aData, void* aClosure)
|
||||
NS_IMETHODIMP
|
||||
nsXBLDocumentInfo::SetPrototypeBinding(const nsACString& aRef, nsXBLPrototypeBinding* aBinding)
|
||||
{
|
||||
if (!mBindingTable)
|
||||
if (!mBindingTable) {
|
||||
mBindingTable = new nsObjectHashtable(nsnull, nsnull, DeletePrototypeBinding, nsnull);
|
||||
if (!mBindingTable)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_HOLD_JS_OBJECTS(this, nsXBLDocumentInfo);
|
||||
}
|
||||
|
||||
const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
|
||||
nsCStringKey key(flat.get());
|
||||
|
||||
@@ -72,8 +72,8 @@ public:
|
||||
// nsIScriptGlobalObjectOwner methods
|
||||
virtual nsIScriptGlobalObject* GetScriptGlobalObject();
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXBLDocumentInfo,
|
||||
nsIXBLDocumentInfo)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsXBLDocumentInfo,
|
||||
nsIXBLDocumentInfo)
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIDocument> mDocument;
|
||||
|
||||
@@ -64,7 +64,7 @@ nsXBLInsertionPoint::Release()
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLInsertionPoint)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLInsertionPoint)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLInsertionPoint)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mElements)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDefaultContentTemplate)
|
||||
|
||||
@@ -200,7 +200,7 @@ nsXBLProtoImpl::CompilePrototypeMembers(nsXBLPrototypeBinding* aBinding)
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLProtoImpl::Traverse(nsCycleCollectionTraversalCallback &cb) const
|
||||
nsXBLProtoImpl::Trace(TraceCallback aCallback, void *aClosure) const
|
||||
{
|
||||
// If we don't have a class object then we either didn't compile members
|
||||
// or we only have fields, in both cases there are no cycles through our
|
||||
@@ -211,7 +211,7 @@ nsXBLProtoImpl::Traverse(nsCycleCollectionTraversalCallback &cb) const
|
||||
|
||||
nsXBLProtoImplMember *member;
|
||||
for (member = mMembers; member; member = member->GetNext()) {
|
||||
member->Traverse(cb);
|
||||
member->Trace(aCallback, aClosure);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ public:
|
||||
mFields = aFieldList;
|
||||
}
|
||||
|
||||
void Traverse(nsCycleCollectionTraversalCallback &cb) const;
|
||||
void Trace(TraceCallback aCallback, void *aClosure) const;
|
||||
void Unlink();
|
||||
|
||||
nsXBLProtoImplField* FindField(const nsString& aFieldName) const;
|
||||
|
||||
@@ -47,11 +47,11 @@
|
||||
#include "nsIJSRuntimeService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
class nsIScriptContext;
|
||||
struct JSRuntime;
|
||||
class nsIJSRuntimeService;
|
||||
class nsCycleCollectionTraversalCallback;
|
||||
|
||||
struct nsXBLTextWithLineNumber
|
||||
{
|
||||
@@ -114,7 +114,7 @@ public:
|
||||
const nsCString& aClassStr,
|
||||
void* aClassObject)=0;
|
||||
|
||||
virtual void Traverse(nsCycleCollectionTraversalCallback &cb) const = 0;
|
||||
virtual void Trace(TraceCallback aCallback, void *aClosure) const = 0;
|
||||
|
||||
protected:
|
||||
friend class nsAutoGCRoot;
|
||||
|
||||
@@ -72,8 +72,6 @@ nsXBLProtoImplMethod::Destroy(PRBool aIsCompiled)
|
||||
NS_PRECONDITION(aIsCompiled == mIsCompiled,
|
||||
"Incorrect aIsCompiled in nsXBLProtoImplMethod::Destroy");
|
||||
if (aIsCompiled) {
|
||||
if (mJSMethodObject)
|
||||
nsContentUtils::RemoveJSGCRoot(&mJSMethodObject);
|
||||
mJSMethodObject = nsnull;
|
||||
}
|
||||
else {
|
||||
@@ -263,8 +261,6 @@ nsXBLProtoImplMethod::CompileMember(nsIScriptContext* aContext, const nsCString&
|
||||
|
||||
if (methodObject) {
|
||||
// Root the compiled prototype script object.
|
||||
rv = nsContentUtils::AddJSGCRoot(&mJSMethodObject,
|
||||
"nsXBLProtoImplMethod::mJSMethodObject");
|
||||
if (NS_FAILED(rv)) {
|
||||
mJSMethodObject = nsnull;
|
||||
}
|
||||
@@ -277,11 +273,13 @@ nsXBLProtoImplMethod::CompileMember(nsIScriptContext* aContext, const nsCString&
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLProtoImplMethod::Traverse(nsCycleCollectionTraversalCallback &cb) const
|
||||
nsXBLProtoImplMethod::Trace(TraceCallback aCallback, void *aClosure) const
|
||||
{
|
||||
NS_ASSERTION(mIsCompiled, "Shouldn't traverse uncompiled method");
|
||||
|
||||
cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, mJSMethodObject);
|
||||
if (mJSMethodObject) {
|
||||
aCallback(nsIProgrammingLanguage::JAVASCRIPT, mJSMethodObject, aClosure);
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
||||
@@ -129,7 +129,7 @@ public:
|
||||
const nsCString& aClassStr,
|
||||
void* aClassObject);
|
||||
|
||||
virtual void Traverse(nsCycleCollectionTraversalCallback &cb) const;
|
||||
virtual void Trace(TraceCallback aCallback, void *aClosure) const;
|
||||
|
||||
protected:
|
||||
union {
|
||||
|
||||
@@ -87,14 +87,14 @@ nsXBLProtoImplProperty::Destroy(PRBool aIsCompiled)
|
||||
"Incorrect aIsCompiled in nsXBLProtoImplProperty::Destroy");
|
||||
|
||||
if ((mJSAttributes & JSPROP_GETTER) && mJSGetterObject) {
|
||||
nsContentUtils::RemoveJSGCRoot(&mJSGetterObject);
|
||||
mJSGetterObject = nsnull;
|
||||
}
|
||||
else {
|
||||
delete mGetterText;
|
||||
}
|
||||
|
||||
if ((mJSAttributes & JSPROP_SETTER) && mJSSetterObject) {
|
||||
nsContentUtils::RemoveJSGCRoot(&mJSSetterObject);
|
||||
mJSSetterObject = nsnull;
|
||||
}
|
||||
else {
|
||||
delete mSetterText;
|
||||
@@ -268,9 +268,6 @@ nsXBLProtoImplProperty::CompileMember(nsIScriptContext* aContext, const nsCStrin
|
||||
|
||||
if (mJSGetterObject && NS_SUCCEEDED(rv)) {
|
||||
mJSAttributes |= JSPROP_GETTER | JSPROP_SHARED;
|
||||
// Root the compiled prototype script object.
|
||||
rv = nsContentUtils::AddJSGCRoot(&mJSGetterObject,
|
||||
"nsXBLProtoImplProperty::mJSGetterObject");
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
mJSGetterObject = nsnull;
|
||||
@@ -320,9 +317,6 @@ nsXBLProtoImplProperty::CompileMember(nsIScriptContext* aContext, const nsCStrin
|
||||
|
||||
if (mJSSetterObject && NS_SUCCEEDED(rv)) {
|
||||
mJSAttributes |= JSPROP_SETTER | JSPROP_SHARED;
|
||||
// Root the compiled prototype script object.
|
||||
rv = nsContentUtils::AddJSGCRoot(&mJSSetterObject,
|
||||
"nsXBLProtoImplProperty::mJSSetterObject");
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
mJSSetterObject = nsnull;
|
||||
@@ -345,15 +339,15 @@ nsXBLProtoImplProperty::CompileMember(nsIScriptContext* aContext, const nsCStrin
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLProtoImplProperty::Traverse(nsCycleCollectionTraversalCallback &cb) const
|
||||
nsXBLProtoImplProperty::Trace(TraceCallback aCallback, void *aClosure) const
|
||||
{
|
||||
NS_ASSERTION(mIsCompiled, "Shouldn't traverse uncompiled method");
|
||||
|
||||
if (mJSAttributes & JSPROP_GETTER) {
|
||||
cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, mJSGetterObject);
|
||||
if ((mJSAttributes & JSPROP_GETTER) && mJSGetterObject) {
|
||||
aCallback(nsIProgrammingLanguage::JAVASCRIPT, mJSGetterObject, aClosure);
|
||||
}
|
||||
|
||||
if (mJSAttributes & JSPROP_SETTER) {
|
||||
cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, mJSSetterObject);
|
||||
if ((mJSAttributes & JSPROP_SETTER) && mJSSetterObject) {
|
||||
aCallback(nsIProgrammingLanguage::JAVASCRIPT, mJSSetterObject, aClosure);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
const nsCString& aClassStr,
|
||||
void* aClassObject);
|
||||
|
||||
virtual void Traverse(nsCycleCollectionTraversalCallback &cb) const;
|
||||
virtual void Trace(TraceCallback aCallback, void *aClosure) const;
|
||||
|
||||
protected:
|
||||
union {
|
||||
|
||||
@@ -244,7 +244,7 @@ private:
|
||||
PRUint32 nsXBLInsertionPointEntry::gRefCnt = 0;
|
||||
nsFixedSizeAllocator* nsXBLInsertionPointEntry::kPool;
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLInsertionPointEntry)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLInsertionPointEntry)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLInsertionPointEntry)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mInsertionParent)
|
||||
if (tmp->mDefaultContent) {
|
||||
@@ -355,8 +355,6 @@ void
|
||||
nsXBLPrototypeBinding::Traverse(nsCycleCollectionTraversalCallback &cb) const
|
||||
{
|
||||
cb.NoteXPCOMChild(mBinding);
|
||||
if (mImplementation)
|
||||
mImplementation->Traverse(cb);
|
||||
if (mResources)
|
||||
cb.NoteXPCOMChild(mResources->mLoader);
|
||||
if (mInsertionPointTable)
|
||||
@@ -372,6 +370,13 @@ nsXBLPrototypeBinding::Unlink()
|
||||
mImplementation->Unlink();
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLPrototypeBinding::Trace(TraceCallback aCallback, void *aClosure) const
|
||||
{
|
||||
if (mImplementation)
|
||||
mImplementation->Trace(aCallback, aClosure);
|
||||
}
|
||||
|
||||
void
|
||||
nsXBLPrototypeBinding::Initialize()
|
||||
{
|
||||
|
||||
@@ -198,6 +198,7 @@ public:
|
||||
|
||||
void Traverse(nsCycleCollectionTraversalCallback &cb) const;
|
||||
void Unlink();
|
||||
void Trace(TraceCallback aCallback, void *aClosure) const;
|
||||
|
||||
// Static members
|
||||
static PRUint32 gRefCnt;
|
||||
|
||||
@@ -55,7 +55,6 @@
|
||||
* use in OS2
|
||||
*/
|
||||
|
||||
#include "jsapi.h" // for JS_AddNamedRoot and JS_RemoveRootRT
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsDOMCID.h"
|
||||
#include "nsDOMError.h"
|
||||
@@ -702,7 +701,8 @@ nsScriptEventHandlerOwnerTearoff::CompileEventHandler(
|
||||
nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mElement->GetOwnerDoc());
|
||||
|
||||
nsIScriptContext *context;
|
||||
if (mElement->mPrototype && xuldoc) {
|
||||
nsXULPrototypeElement *elem = mElement->mPrototype;
|
||||
if (elem && xuldoc) {
|
||||
// It'll be shared among the instances of the prototype.
|
||||
|
||||
// Use the prototype document's special context. Because
|
||||
@@ -755,9 +755,16 @@ nsScriptEventHandlerOwnerTearoff::CompileEventHandler(
|
||||
XUL_PROTOTYPE_ATTRIBUTE_METER(gNumCacheFills);
|
||||
// take a copy of the event handler, and tell the language about it.
|
||||
if (aHandler) {
|
||||
NS_ASSERTION(!attr->mEventHandler, "Leaking handler.");
|
||||
|
||||
rv = nsContentUtils::HoldScriptObject(aContext->GetScriptTypeID(),
|
||||
aHandler);
|
||||
elem,
|
||||
&NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode),
|
||||
aHandler,
|
||||
elem->mHoldsScriptObject);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
elem->mHoldsScriptObject = PR_TRUE;
|
||||
}
|
||||
attr->mEventHandler = (void *)aHandler;
|
||||
}
|
||||
@@ -2351,26 +2358,40 @@ nsXULElement::RecompileScriptEventListeners()
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsXULPrototypeNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULPrototypeNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(nsXULPrototypeNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsXULPrototypeNode)
|
||||
if (tmp->mType == nsXULPrototypeNode::eType_Element) {
|
||||
nsXULPrototypeElement *elem =
|
||||
static_cast<nsXULPrototypeElement*>(tmp);
|
||||
PRUint32 i;
|
||||
for (i = 0; i < elem->mNumAttributes; ++i) {
|
||||
cb.NoteScriptChild(elem->mScriptTypeID,
|
||||
elem->mAttributes[i].mEventHandler);
|
||||
}
|
||||
for (i = 0; i < elem->mNumChildren; ++i) {
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(elem->mChildren[i],
|
||||
nsXULPrototypeNode)
|
||||
}
|
||||
}
|
||||
else if (tmp->mType == nsXULPrototypeNode::eType_Script) {
|
||||
static_cast<nsXULPrototypeScript*>(tmp)->mScriptObject.traverse(cb);
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(nsXULPrototypeNode)
|
||||
if (tmp->mType == nsXULPrototypeNode::eType_Element) {
|
||||
nsXULPrototypeElement *elem =
|
||||
static_cast<nsXULPrototypeElement*>(tmp);
|
||||
if (elem->mHoldsScriptObject) {
|
||||
PRUint32 i;
|
||||
for (i = 0; i < elem->mNumAttributes; ++i) {
|
||||
void *handler = elem->mAttributes[i].mEventHandler;
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(elem->mScriptTypeID,
|
||||
handler)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (tmp->mType == nsXULPrototypeNode::eType_Script) {
|
||||
nsXULPrototypeScript *script =
|
||||
static_cast<nsXULPrototypeScript*>(tmp);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(script->mScriptObject.mLangID,
|
||||
script->mScriptObject.mObject)
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_TRACE_END
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsXULPrototypeNode, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsXULPrototypeNode, Release)
|
||||
|
||||
@@ -2382,17 +2403,6 @@ NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsXULPrototypeNode, Release)
|
||||
nsXULPrototypeAttribute::~nsXULPrototypeAttribute()
|
||||
{
|
||||
MOZ_COUNT_DTOR(nsXULPrototypeAttribute);
|
||||
NS_ASSERTION(!mEventHandler, "Finalize not called - language object leak!");
|
||||
}
|
||||
|
||||
void
|
||||
nsXULPrototypeAttribute::Finalize(PRUint32 aLangID)
|
||||
{
|
||||
if (mEventHandler) {
|
||||
if (NS_FAILED(nsContentUtils::DropScriptObject(aLangID, mEventHandler)))
|
||||
NS_ERROR("Failed to drop script object");
|
||||
mEventHandler = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2679,6 +2689,19 @@ nsXULPrototypeElement::SetAttrAt(PRUint32 aPos, const nsAString& aValue,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsXULPrototypeElement::Unlink()
|
||||
{
|
||||
if (mHoldsScriptObject) {
|
||||
nsContentUtils::DropScriptObjects(mScriptTypeID, this,
|
||||
&NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode));
|
||||
mHoldsScriptObject = PR_FALSE;
|
||||
}
|
||||
mNumAttributes = 0;
|
||||
delete[] mAttributes;
|
||||
mAttributes = nsnull;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
// nsXULPrototypeScript
|
||||
@@ -2701,6 +2724,7 @@ nsXULPrototypeScript::nsXULPrototypeScript(PRUint32 aLangID, PRUint32 aLineNo, P
|
||||
|
||||
nsXULPrototypeScript::~nsXULPrototypeScript()
|
||||
{
|
||||
Unlink();
|
||||
}
|
||||
|
||||
nsresult
|
||||
@@ -2818,7 +2842,7 @@ nsXULPrototypeScript::Deserialize(nsIObjectInputStream* aStream,
|
||||
NS_WARNING("Language deseralization failed");
|
||||
return rv;
|
||||
}
|
||||
mScriptObject.set(newScriptObject);
|
||||
Set(newScriptObject);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -2871,7 +2895,7 @@ nsXULPrototypeScript::DeserializeOutOfLine(nsIObjectInputStream* aInput,
|
||||
NS_ERROR("XUL cache gave different language?");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
mScriptObject.set(newScriptObject);
|
||||
Set(newScriptObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2997,7 +3021,7 @@ nsXULPrototypeScript::Compile(const PRUnichar* aText,
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
mScriptObject.set(newScriptObject);
|
||||
Set(newScriptObject);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@@ -124,9 +124,6 @@ public:
|
||||
// nsScriptObjectHolder, but want to avoid the extra lang ID.
|
||||
void* mEventHandler;
|
||||
|
||||
// Containing element must tell us the langID so we can cleanup.
|
||||
void Finalize(PRUint32 aLangID);
|
||||
|
||||
#ifdef XUL_PROTOTYPE_ATTRIBUTE_METERING
|
||||
/**
|
||||
If enough attributes, on average, are event handlers, it pays to keep
|
||||
@@ -230,7 +227,7 @@ public:
|
||||
*/
|
||||
virtual void ReleaseSubtree() { Release(); }
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsXULPrototypeNode)
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(nsXULPrototypeNode)
|
||||
|
||||
protected:
|
||||
nsXULPrototypeNode(Type aType)
|
||||
@@ -249,6 +246,7 @@ public:
|
||||
mHasIdAttribute(PR_FALSE),
|
||||
mHasClassAttribute(PR_FALSE),
|
||||
mHasStyleAttribute(PR_FALSE),
|
||||
mHoldsScriptObject(PR_FALSE),
|
||||
mScriptTypeID(nsIProgrammingLanguage::UNKNOWN)
|
||||
{
|
||||
NS_LOG_ADDREF(this, 1, ClassName(), ClassSize());
|
||||
@@ -256,10 +254,7 @@ public:
|
||||
|
||||
virtual ~nsXULPrototypeElement()
|
||||
{
|
||||
PRUint32 i;
|
||||
for (i = 0; i < mNumAttributes; i++)
|
||||
mAttributes[i].Finalize(mScriptTypeID);
|
||||
delete[] mAttributes;
|
||||
Unlink();
|
||||
NS_ASSERTION(!mChildren && mNumChildren == 0,
|
||||
"ReleaseSubtree not called");
|
||||
}
|
||||
@@ -294,6 +289,8 @@ public:
|
||||
|
||||
nsresult SetAttrAt(PRUint32 aPos, const nsAString& aValue, nsIURI* aDocumentURI);
|
||||
|
||||
void Unlink();
|
||||
|
||||
PRUint32 mNumChildren;
|
||||
nsXULPrototypeNode** mChildren; // [OWNER]
|
||||
|
||||
@@ -305,6 +302,7 @@ public:
|
||||
PRPackedBool mHasIdAttribute:1;
|
||||
PRPackedBool mHasClassAttribute:1;
|
||||
PRPackedBool mHasStyleAttribute:1;
|
||||
PRPackedBool mHoldsScriptObject:1;
|
||||
|
||||
// The language ID can not be set on a per-node basis, but is tracked
|
||||
// so that the language ID from the originating root can be used
|
||||
@@ -361,13 +359,52 @@ public:
|
||||
nsIDocument* aDocument,
|
||||
nsIScriptGlobalObjectOwner* aGlobalOwner);
|
||||
|
||||
void Unlink()
|
||||
{
|
||||
if (mScriptObject.mObject) {
|
||||
nsContentUtils::DropScriptObjects(mScriptObject.mLangID, this,
|
||||
&NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode));
|
||||
mScriptObject.mObject = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
void Set(nsScriptObjectHolder &aHolder)
|
||||
{
|
||||
NS_ASSERTION(mScriptObject.mLangID == aHolder.getScriptTypeID(),
|
||||
"Wrong language, this will leak the previous object.");
|
||||
|
||||
mScriptObject.mLangID = aHolder.getScriptTypeID();
|
||||
Set((void*)aHolder);
|
||||
}
|
||||
void Set(void *aObject)
|
||||
{
|
||||
NS_ASSERTION(!mScriptObject.mObject, "Leaking script object.");
|
||||
|
||||
nsresult rv = nsContentUtils::HoldScriptObject(mScriptObject.mLangID,
|
||||
this,
|
||||
&NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode),
|
||||
aObject, PR_FALSE);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mScriptObject.mObject = aObject;
|
||||
}
|
||||
}
|
||||
|
||||
struct ScriptObjectHolder
|
||||
{
|
||||
ScriptObjectHolder(PRUint32 aLangID) : mLangID(aLangID),
|
||||
mObject(nsnull)
|
||||
{
|
||||
}
|
||||
PRUint32 mLangID;
|
||||
void* mObject;
|
||||
};
|
||||
nsCOMPtr<nsIURI> mSrcURI;
|
||||
PRUint32 mLineNo;
|
||||
PRPackedBool mSrcLoading;
|
||||
PRPackedBool mOutOfLine;
|
||||
nsXULDocument* mSrcLoadWaiters; // [OWNER] but not COMPtr
|
||||
PRUint32 mLangVersion;
|
||||
nsContentUtils::ScriptObjectHolder mScriptObject;
|
||||
ScriptObjectHolder mScriptObject;
|
||||
};
|
||||
|
||||
class nsXULPrototypeText : public nsXULPrototypeNode
|
||||
|
||||
@@ -3209,7 +3209,7 @@ nsXULDocument::LoadScript(nsXULPrototypeScript* aScriptProto, PRBool* aBlock)
|
||||
NS_ERROR("XUL cache gave me an incorrect script language");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
aScriptProto->mScriptObject.set(newScriptObject);
|
||||
aScriptProto->Set(newScriptObject);
|
||||
}
|
||||
|
||||
if (aScriptProto->mScriptObject.mObject) {
|
||||
|
||||
Reference in New Issue
Block a user