fix bug 103259. Avoid crasher by correctly marking sharedscriptable object so that JSClasses don't get collected prematurely even when wrapper is 'stillborn' and not reflected into JS. r=dbradley sr=vidur.

This commit is contained in:
jband%netscape.com 2001-10-08 19:56:25 +00:00
parent 281ca9b8c3
commit 5992cc2572
2 changed files with 20 additions and 3 deletions

View File

@ -1533,7 +1533,10 @@ public:
void MarkBeforeJSFinalize(JSContext* cx) void MarkBeforeJSFinalize(JSContext* cx)
{if(mJSProtoObject) {if(mJSProtoObject)
JS_MarkGCThing(cx, mJSProtoObject, JS_MarkGCThing(cx, mJSProtoObject,
"XPCWrappedNativeProto::mJSProtoObject", nsnull);} "XPCWrappedNativeProto::mJSProtoObject", nsnull);
if(mScriptableInfo) mScriptableInfo->Mark();}
// Yes, we *do* need to mark the mScriptableInfo in both cases.
void Mark() const void Mark() const
{mSet->Mark(); {mSet->Mark();
if(mScriptableInfo) mScriptableInfo->Mark();} if(mScriptableInfo) mScriptableInfo->Mark();}
@ -1802,8 +1805,10 @@ public:
if(mScriptableInfo) mScriptableInfo->Mark(); if(mScriptableInfo) mScriptableInfo->Mark();
if(HasProto()) mMaybeProto->Mark();} if(HasProto()) mMaybeProto->Mark();}
// NOP. This is just here to make the AutoMarkingPtr code compile. // Yes, we *do* need to mark the mScriptableInfo in both cases.
inline void MarkBeforeJSFinalize(JSContext*) {}; inline void MarkBeforeJSFinalize(JSContext* cx)
{if(mScriptableInfo) mScriptableInfo->Mark();
if(HasProto()) mMaybeProto->MarkBeforeJSFinalize(cx);}
#ifdef DEBUG #ifdef DEBUG
void ASSERT_SetsNotMarked() const void ASSERT_SetsNotMarked() const

View File

@ -643,6 +643,18 @@ MarkForValidWrapper(JSContext *cx, XPCWrappedNative* wrapper, void *arg)
// are used in the DealWithDyingGCThings calls that are part of this JS GC // are used in the DealWithDyingGCThings calls that are part of this JS GC
// marking phase. By doing these calls later during our GC callback we // marking phase. By doing these calls later during our GC callback we
// avoid that problem. Arguably this could be changed. But it ain't broke. // avoid that problem. Arguably this could be changed. But it ain't broke.
// However, we do need to call the wrapper's MarkBeforeJSFinalize so that
// it can be sure that its (potentially shared) JSClass gets marked. The
// danger is that a live wrapper might not be in a wrapper map and thus
// won't be fully marked in the GC callback. This can happen if there is
// a security exception during wrapper creation or if during wrapper
// creation it is determined that the wrapper is not needed. In those cases
// the wrapper can never actually be used from JS code - so resources like
// the interface set will never be accessed. But the JS engine will still
// need to use the JSClass. So, some marking is required for protection.
wrapper->MarkBeforeJSFinalize(cx);
if(wrapper->HasProto()) if(wrapper->HasProto())
{ {