mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-07 04:05:49 +00:00
Bug 869740 - Non-LIFO use of Rooted in XPCConvert::NativeInterface2JSObject(). r=bholley
This commit is contained in:
parent
720319bcd4
commit
06feff854a
@ -37,34 +37,43 @@ XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
|
||||
mName(cx)
|
||||
{
|
||||
MOZ_ASSERT(cx);
|
||||
Init(callerLanguage, callerLanguage == NATIVE_CALLER, obj, funobj,
|
||||
Init(callerLanguage == NATIVE_CALLER, obj, funobj,
|
||||
INIT_SHOULD_LOOKUP_WRAPPER, name, argc, argv, rval);
|
||||
}
|
||||
|
||||
XPCCallContext::XPCCallContext(XPCContext::LangType callerLanguage,
|
||||
JSContext* cx,
|
||||
JSBool callBeginRequest,
|
||||
HandleObject obj,
|
||||
HandleObject flattenedJSObject,
|
||||
XPCWrappedNative* wrapper,
|
||||
XPCWrappedNativeTearOff* tearOff)
|
||||
XPCCallContext::XPCCallContext(JSContext *cx)
|
||||
: mState(INIT_FAILED),
|
||||
mXPC(nsXPConnect::GetXPConnect()),
|
||||
mXPCContext(nullptr),
|
||||
mJSContext(cx),
|
||||
mContextPopRequired(false),
|
||||
mDestroyJSContextInDestructor(false),
|
||||
mCallerLanguage(callerLanguage),
|
||||
mCallerLanguage(XPCContext::LANG_UNKNOWN),
|
||||
mScopeForNewJSObjects(cx),
|
||||
mFlattenedJSObject(cx, flattenedJSObject),
|
||||
mWrapper(wrapper),
|
||||
mTearOff(tearOff),
|
||||
mFlattenedJSObject(cx),
|
||||
mName(cx)
|
||||
{
|
||||
MOZ_ASSERT(cx);
|
||||
Init(callerLanguage, callBeginRequest, obj, NullPtr(),
|
||||
WRAPPER_PASSED_TO_CONSTRUCTOR, JSID_VOIDHANDLE, NO_ARGS,
|
||||
nullptr, nullptr);
|
||||
// Called from XPCLazyCallContext only.
|
||||
MOZ_ASSERT(mJSContext);
|
||||
}
|
||||
|
||||
void
|
||||
XPCCallContext::LazyInit(XPCContext::LangType callerLanguage,
|
||||
JSBool callBeginRequest,
|
||||
HandleObject obj,
|
||||
HandleObject flattenedJSObject,
|
||||
XPCWrappedNative* wrapper,
|
||||
XPCWrappedNativeTearOff* tearOff)
|
||||
{
|
||||
// Called from XPCLazyCallContext only.
|
||||
MOZ_ASSERT(mState == INIT_FAILED);
|
||||
MOZ_ASSERT(mJSContext);
|
||||
mCallerLanguage = callerLanguage;
|
||||
mFlattenedJSObject = flattenedJSObject;
|
||||
mWrapper = wrapper;
|
||||
mTearOff = tearOff;
|
||||
Init(callBeginRequest, obj, NullPtr(), WRAPPER_PASSED_TO_CONSTRUCTOR,
|
||||
JSID_VOIDHANDLE, NO_ARGS, nullptr, nullptr);
|
||||
}
|
||||
|
||||
#define IS_TEAROFF_CLASS(clazz) ((clazz) == &XPC_WN_Tearoff_JSClass)
|
||||
@ -89,8 +98,7 @@ XPCCallContext::GetDefaultJSContext()
|
||||
}
|
||||
|
||||
void
|
||||
XPCCallContext::Init(XPCContext::LangType callerLanguage,
|
||||
JSBool callBeginRequest,
|
||||
XPCCallContext::Init(JSBool callBeginRequest,
|
||||
HandleObject obj,
|
||||
HandleObject funobj,
|
||||
WrapperInitOptions wrapperInitOptions,
|
||||
|
@ -1214,22 +1214,29 @@ private:
|
||||
XPCCallContext(const XPCCallContext& r); // not implemented
|
||||
XPCCallContext& operator= (const XPCCallContext& r); // not implemented
|
||||
|
||||
// The following are for construction from XPCLazyCallContext. Delay doing
|
||||
// the initialization work until we know that the XPCCallContext will
|
||||
// actually be needed, but still eagerly construct the overall
|
||||
// XPCCallContext because it contains Rooted<T> fields that must be
|
||||
// destroyed in LIFO order. An XPCCallContext will always push its
|
||||
// Rooted<T>'s onto the stack upon construction, and then pop them off in
|
||||
// LIFO order during its destruction, regardless of whether LazyInit ever
|
||||
// gets called.
|
||||
friend class XPCLazyCallContext;
|
||||
XPCCallContext(XPCContext::LangType callerLanguage,
|
||||
JSContext* cx,
|
||||
JSBool callBeginRequest,
|
||||
JS::HandleObject obj,
|
||||
JS::HandleObject flattenedJSObject,
|
||||
XPCWrappedNative* wn,
|
||||
XPCWrappedNativeTearOff* tearoff);
|
||||
XPCCallContext(JSContext *cx);
|
||||
void LazyInit(XPCContext::LangType callerLanguage,
|
||||
JSBool callBeginRequest,
|
||||
JS::HandleObject obj,
|
||||
JS::HandleObject flattenedJSObject,
|
||||
XPCWrappedNative* wn,
|
||||
XPCWrappedNativeTearOff* tearoff);
|
||||
|
||||
enum WrapperInitOptions {
|
||||
WRAPPER_PASSED_TO_CONSTRUCTOR,
|
||||
INIT_SHOULD_LOOKUP_WRAPPER
|
||||
};
|
||||
|
||||
void Init(XPCContext::LangType callerLanguage,
|
||||
JSBool callBeginRequest,
|
||||
void Init(JSBool callBeginRequest,
|
||||
JS::HandleObject obj,
|
||||
JS::HandleObject funobj,
|
||||
WrapperInitOptions wrapperInitOptions,
|
||||
@ -1323,7 +1330,6 @@ public:
|
||||
: mCallBeginRequest(callerLanguage == NATIVE_CALLER ?
|
||||
CALL_BEGINREQUEST : DONT_CALL_BEGINREQUEST),
|
||||
mCcx(nullptr),
|
||||
mCcxToDestroy(nullptr),
|
||||
mCx(cx),
|
||||
mCallerLanguage(callerLanguage),
|
||||
mObj(cx, obj),
|
||||
@ -1335,6 +1341,16 @@ public:
|
||||
NS_ASSERTION(callerLanguage == NATIVE_CALLER ||
|
||||
callerLanguage == JS_CALLER,
|
||||
"Can't deal with unknown caller language!");
|
||||
// Construct with placement new to allow for the other constructor,
|
||||
// which accepts an existing XPCCallContext to use. This constructed
|
||||
// XPCCallContext may never be needed, in which case its LazyInit will
|
||||
// not be invoked, but it must be eagerly constructed here in order to
|
||||
// maintain LIFO order of its Rooted<T> fields and the ones contained
|
||||
// in XPCLazyCallContext. (If its construction were delayed, then any
|
||||
// Rooted<T> created in between the construction of XPCLazyCallContext
|
||||
// and the LazyInit call would not get destroyed during
|
||||
// ~XPCLazyCallContext and therefore would not follow LIFO ordering.)
|
||||
mCcxToDestroy = new (mData.addr()) XPCCallContext(mCx);
|
||||
#ifdef DEBUG
|
||||
AssertContextIsTopOfStack(cx);
|
||||
#endif
|
||||
@ -1388,16 +1404,15 @@ public:
|
||||
XPCCallContext &GetXPCCallContext()
|
||||
{
|
||||
if (!mCcx) {
|
||||
XPCCallContext *data = mData.addr();
|
||||
xpc_UnmarkGrayObject(mObj);
|
||||
xpc_UnmarkGrayObject(mFlattenedJSObject);
|
||||
mCcxToDestroy = mCcx =
|
||||
new (data) XPCCallContext(mCallerLanguage, mCx,
|
||||
mCallBeginRequest == CALL_BEGINREQUEST,
|
||||
mObj,
|
||||
mFlattenedJSObject,
|
||||
mWrapper,
|
||||
mTearOff);
|
||||
mCcxToDestroy = mCcx = mData.addr();
|
||||
mCcx->LazyInit(mCallerLanguage,
|
||||
mCallBeginRequest == CALL_BEGINREQUEST,
|
||||
mObj,
|
||||
mFlattenedJSObject,
|
||||
mWrapper,
|
||||
mTearOff);
|
||||
if (!mCcx->IsValid()) {
|
||||
NS_ERROR("This is not supposed to fail!");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user