зеркало из https://github.com/mozilla/gecko-dev.git
Bug 993413 - Remove use of JS_Add/Remove*Root in favour of JS::PersistentRooted where possible r=terrence r=bz r=bholley
This commit is contained in:
Родитель
f3f1e4c964
Коммит
173bd25321
|
@ -1363,17 +1363,10 @@ nsFrameScriptExecutor::DidCreateGlobal()
|
|||
}
|
||||
|
||||
static PLDHashOperator
|
||||
CachedScriptUnrooter(const nsAString& aKey,
|
||||
nsFrameScriptObjectExecutorHolder*& aData,
|
||||
void* aUserArg)
|
||||
RemoveCachedScriptEntry(const nsAString& aKey,
|
||||
nsFrameScriptObjectExecutorHolder*& aData,
|
||||
void* aUserArg)
|
||||
{
|
||||
JSContext* cx = static_cast<JSContext*>(aUserArg);
|
||||
if (aData->mScript) {
|
||||
JS_RemoveScriptRoot(cx, &aData->mScript);
|
||||
}
|
||||
if (aData->mFunction) {
|
||||
JS_RemoveObjectRoot(cx, &aData->mFunction);
|
||||
}
|
||||
delete aData;
|
||||
return PL_DHASH_REMOVE;
|
||||
}
|
||||
|
@ -1385,7 +1378,7 @@ nsFrameScriptExecutor::Shutdown()
|
|||
if (sCachedScripts) {
|
||||
AutoSafeJSContext cx;
|
||||
NS_ASSERTION(sCachedScripts != nullptr, "Need cached scripts");
|
||||
sCachedScripts->Enumerate(CachedScriptUnrooter, cx);
|
||||
sCachedScripts->Enumerate(RemoveCachedScriptEntry, nullptr);
|
||||
|
||||
delete sCachedScripts;
|
||||
sCachedScripts = nullptr;
|
||||
|
@ -1528,13 +1521,9 @@ nsFrameScriptExecutor::TryCacheLoadAndCompileScript(const nsAString& aURL,
|
|||
|
||||
// Root the object also for caching.
|
||||
if (script) {
|
||||
holder = new nsFrameScriptObjectExecutorHolder(script);
|
||||
JS_AddNamedScriptRoot(cx, &holder->mScript,
|
||||
"Cached message manager script");
|
||||
holder = new nsFrameScriptObjectExecutorHolder(cx, script);
|
||||
} else {
|
||||
holder = new nsFrameScriptObjectExecutorHolder(funobj);
|
||||
JS_AddNamedObjectRoot(cx, &holder->mFunction,
|
||||
"Cached message manager function");
|
||||
holder = new nsFrameScriptObjectExecutorHolder(cx, funobj);
|
||||
}
|
||||
sCachedScripts->Put(aURL, holder);
|
||||
}
|
||||
|
@ -1922,25 +1911,15 @@ nsSameProcessAsyncMessageBase::nsSameProcessAsyncMessageBase(JSContext* aCx,
|
|||
nsIPrincipal* aPrincipal)
|
||||
: mRuntime(js::GetRuntime(aCx)),
|
||||
mMessage(aMessage),
|
||||
mCpows(aCpows),
|
||||
mCpows(aCx, aCpows),
|
||||
mPrincipal(aPrincipal)
|
||||
{
|
||||
if (aData.mDataLength && !mData.copy(aData.mData, aData.mDataLength)) {
|
||||
NS_RUNTIMEABORT("OOM");
|
||||
}
|
||||
if (mCpows && !js_AddObjectRoot(mRuntime, &mCpows)) {
|
||||
NS_RUNTIMEABORT("OOM");
|
||||
}
|
||||
mClosure = aData.mClosure;
|
||||
}
|
||||
|
||||
nsSameProcessAsyncMessageBase::~nsSameProcessAsyncMessageBase()
|
||||
{
|
||||
if (mCpows) {
|
||||
JS_RemoveObjectRootRT(mRuntime, &mCpows);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSameProcessAsyncMessageBase::ReceiveMessage(nsISupports* aTarget,
|
||||
nsFrameMessageManager* aManager)
|
||||
|
@ -1951,7 +1930,7 @@ nsSameProcessAsyncMessageBase::ReceiveMessage(nsISupports* aTarget,
|
|||
data.mDataLength = mData.nbytes();
|
||||
data.mClosure = mClosure;
|
||||
|
||||
SameProcessCpowHolder cpows(mRuntime, JS::Handle<JSObject*>::fromMarkedLocation(&mCpows));
|
||||
SameProcessCpowHolder cpows(mRuntime, mCpows);
|
||||
|
||||
nsRefPtr<nsFrameMessageManager> mm = aManager;
|
||||
mm->ReceiveMessage(aTarget, mMessage, false, &data, &cpows,
|
||||
|
|
|
@ -337,7 +337,6 @@ public:
|
|||
const StructuredCloneData& aData,
|
||||
JS::Handle<JSObject*> aCpows,
|
||||
nsIPrincipal* aPrincipal);
|
||||
~nsSameProcessAsyncMessageBase();
|
||||
|
||||
void ReceiveMessage(nsISupports* aTarget, nsFrameMessageManager* aManager);
|
||||
|
||||
|
@ -348,7 +347,7 @@ private:
|
|||
nsString mMessage;
|
||||
JSAutoStructuredCloneBuffer mData;
|
||||
StructuredCloneClosure mClosure;
|
||||
JSObject* mCpows;
|
||||
JS::PersistentRooted<JSObject*> mCpows;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
};
|
||||
|
||||
|
@ -356,19 +355,21 @@ class nsScriptCacheCleaner;
|
|||
|
||||
struct nsFrameScriptObjectExecutorHolder
|
||||
{
|
||||
nsFrameScriptObjectExecutorHolder(JSScript* aScript) : mScript(aScript), mFunction(nullptr)
|
||||
nsFrameScriptObjectExecutorHolder(JSContext* aCx, JSScript* aScript)
|
||||
: mScript(aCx, aScript), mFunction(aCx, nullptr)
|
||||
{ MOZ_COUNT_CTOR(nsFrameScriptObjectExecutorHolder); }
|
||||
nsFrameScriptObjectExecutorHolder(JSObject* aFunction) : mScript(nullptr), mFunction(aFunction)
|
||||
|
||||
nsFrameScriptObjectExecutorHolder(JSContext* aCx, JSObject* aFunction)
|
||||
: mScript(aCx, nullptr), mFunction(aCx, aFunction)
|
||||
{ MOZ_COUNT_CTOR(nsFrameScriptObjectExecutorHolder); }
|
||||
|
||||
~nsFrameScriptObjectExecutorHolder()
|
||||
{ MOZ_COUNT_DTOR(nsFrameScriptObjectExecutorHolder); }
|
||||
|
||||
bool WillRunInGlobalScope() { return mScript; }
|
||||
|
||||
// We use JS_AddNamed{Script,Object}Root to root these fields explicitly, so
|
||||
// no need for Heap<T>.
|
||||
JSScript* mScript;
|
||||
JSObject* mFunction;
|
||||
JS::PersistentRooted<JSScript*> mScript;
|
||||
JS::PersistentRooted<JSObject*> mFunction;
|
||||
};
|
||||
|
||||
class nsFrameScriptObjectExecutorStackHolder;
|
||||
|
|
|
@ -233,24 +233,16 @@ DOMRequestService::FireDetailedError(nsIDOMDOMRequest* aRequest,
|
|||
class FireSuccessAsyncTask : public nsRunnable
|
||||
{
|
||||
|
||||
FireSuccessAsyncTask(DOMRequest* aRequest,
|
||||
FireSuccessAsyncTask(JSContext* aCx,
|
||||
DOMRequest* aRequest,
|
||||
const JS::Value& aResult) :
|
||||
mReq(aRequest),
|
||||
mResult(aResult),
|
||||
mIsSetup(false)
|
||||
mResult(aCx, aResult)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void
|
||||
Setup()
|
||||
{
|
||||
AutoSafeJSContext cx;
|
||||
JS_AddValueRoot(cx, &mResult);
|
||||
mIsSetup = true;
|
||||
}
|
||||
|
||||
// Due to the fact that initialization can fail during shutdown (since we
|
||||
// can't fetch a js context), set up an initiatization function to make sure
|
||||
// we can return the failure appropriately
|
||||
|
@ -259,8 +251,8 @@ public:
|
|||
const JS::Value& aResult)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
nsRefPtr<FireSuccessAsyncTask> asyncTask = new FireSuccessAsyncTask(aRequest, aResult);
|
||||
asyncTask->Setup();
|
||||
AutoSafeJSContext cx;
|
||||
nsRefPtr<FireSuccessAsyncTask> asyncTask = new FireSuccessAsyncTask(cx, aRequest, aResult);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(asyncTask))) {
|
||||
NS_WARNING("Failed to dispatch to main thread!");
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -271,25 +263,18 @@ public:
|
|||
NS_IMETHODIMP
|
||||
Run()
|
||||
{
|
||||
mReq->FireSuccess(JS::Handle<JS::Value>::fromMarkedLocation(&mResult));
|
||||
mReq->FireSuccess(JS::Handle<JS::Value>::fromMarkedLocation(mResult.address()));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
~FireSuccessAsyncTask()
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
if(!mIsSetup) {
|
||||
// If we never set up, no reason to unroot
|
||||
return;
|
||||
}
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
JS_RemoveValueRoot(cx, &mResult);
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<DOMRequest> mReq;
|
||||
JS::Value mResult;
|
||||
bool mIsSetup;
|
||||
JS::PersistentRooted<JS::Value> mResult;
|
||||
};
|
||||
|
||||
class FireErrorAsyncTask : public nsRunnable
|
||||
|
|
|
@ -161,8 +161,9 @@ static bool
|
|||
NPObjWrapper_Construct(JSContext *cx, unsigned argc, JS::Value *vp);
|
||||
|
||||
static bool
|
||||
CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject *npobj,
|
||||
JS::Handle<jsid> id, NPVariant* getPropertyResult, JS::Value *vp);
|
||||
CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
|
||||
JS::Handle<jsid> id, NPVariant* getPropertyResult,
|
||||
JS::MutableHandle<JS::Value> vp);
|
||||
|
||||
const JSClass sNPObjectJSWrapperClass =
|
||||
{
|
||||
|
@ -496,7 +497,7 @@ ReportExceptionIfPending(JSContext *cx)
|
|||
}
|
||||
|
||||
nsJSObjWrapper::nsJSObjWrapper(NPP npp)
|
||||
: mNpp(npp)
|
||||
: mJSObj(GetJSContext(npp), nullptr), mNpp(npp)
|
||||
{
|
||||
MOZ_COUNT_CTOR(nsJSObjWrapper);
|
||||
OnWrapperCreated();
|
||||
|
@ -514,9 +515,6 @@ nsJSObjWrapper::~nsJSObjWrapper()
|
|||
|
||||
void
|
||||
nsJSObjWrapper::ClearJSObject() {
|
||||
// Unroot the object's JSObject
|
||||
JS_RemoveObjectRootRT(sJSRuntime, &mJSObj);
|
||||
|
||||
// Forget our reference to the JSObject.
|
||||
mJSObj = nullptr;
|
||||
}
|
||||
|
@ -1022,6 +1020,8 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JS::Handle<JSObject*> obj)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
// Assign mJSObj, rooting the JSObject. Its lifetime is now tied to that of
|
||||
// the NPObject.
|
||||
wrapper->mJSObj = obj;
|
||||
|
||||
nsJSObjWrapperKey key(obj, npp);
|
||||
|
@ -1031,19 +1031,6 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JS::Handle<JSObject*> obj)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
NS_ASSERTION(wrapper->mNpp == npp, "nsJSObjWrapper::mNpp not initialized!");
|
||||
|
||||
// Root the JSObject, its lifetime is now tied to that of the
|
||||
// NPObject.
|
||||
if (!::JS_AddNamedObjectRoot(cx, &wrapper->mJSObj, "nsJSObjWrapper::mJSObject")) {
|
||||
NS_ERROR("Failed to root JSObject!");
|
||||
|
||||
sJSObjWrappers.remove(key);
|
||||
_releaseobject(wrapper);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Add postbarrier for the hashtable key
|
||||
JS_StoreObjectPostBarrierCallback(cx, JSObjWrapperKeyMarkCallback, obj, wrapper->mNpp);
|
||||
|
||||
|
@ -1271,7 +1258,7 @@ NPObjWrapper_GetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
|
|||
if (success) {
|
||||
// We return NPObject Member class here to support ambiguous members.
|
||||
if (hasProperty && hasMethod)
|
||||
return CreateNPObjectMember(npp, cx, obj, npobj, id, &npv, vp.address());
|
||||
return CreateNPObjectMember(npp, cx, obj, npobj, id, &npv, vp);
|
||||
|
||||
if (hasProperty) {
|
||||
vp.set(NPVariantToJSVal(npp, cx, &npv));
|
||||
|
@ -1294,7 +1281,7 @@ NPObjWrapper_GetProperty(JSContext *cx, JS::Handle<JSObject*> obj, JS::Handle<js
|
|||
|
||||
// We return NPObject Member class here to support ambiguous members.
|
||||
if (hasProperty && hasMethod)
|
||||
return CreateNPObjectMember(npp, cx, obj, npobj, id, nullptr, vp.address());
|
||||
return CreateNPObjectMember(npp, cx, obj, npobj, id, nullptr, vp);
|
||||
|
||||
if (hasProperty) {
|
||||
if (npobj->_class->getProperty(npobj, identifier, &npv))
|
||||
|
@ -1906,12 +1893,11 @@ LookupNPP(NPObject *npobj)
|
|||
return entry->mNpp;
|
||||
}
|
||||
|
||||
bool
|
||||
static bool
|
||||
CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
|
||||
JS::Handle<jsid> id, NPVariant* getPropertyResult, JS::Value *vp)
|
||||
JS::Handle<jsid> id, NPVariant* getPropertyResult,
|
||||
JS::MutableHandle<JS::Value> vp)
|
||||
{
|
||||
NS_ENSURE_TRUE(vp, false);
|
||||
|
||||
if (!npobj || !npobj->_class || !npobj->_class->getProperty ||
|
||||
!npobj->_class->invoke) {
|
||||
ThrowJSException(cx, "Bad NPObject");
|
||||
|
@ -1934,8 +1920,7 @@ CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
|
|||
return false;
|
||||
}
|
||||
|
||||
*vp = OBJECT_TO_JSVAL(memobj);
|
||||
::JS_AddValueRoot(cx, vp);
|
||||
vp.setObject(*memobj);
|
||||
|
||||
::JS_SetPrivate(memobj, (void *)memberPrivate);
|
||||
|
||||
|
@ -1953,13 +1938,7 @@ CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
|
|||
|
||||
NPBool hasProperty = npobj->_class->getProperty(npobj, identifier,
|
||||
&npv);
|
||||
if (!ReportExceptionIfPending(cx)) {
|
||||
::JS_RemoveValueRoot(cx, vp);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!hasProperty) {
|
||||
::JS_RemoveValueRoot(cx, vp);
|
||||
if (!ReportExceptionIfPending(cx) || !hasProperty) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1977,8 +1956,6 @@ CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
|
|||
memberPrivate->methodName = id;
|
||||
memberPrivate->npp = npp;
|
||||
|
||||
::JS_RemoveValueRoot(cx, vp);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ extern const JSClass sNPObjectJSWrapperClass;
|
|||
class nsJSObjWrapper : public NPObject
|
||||
{
|
||||
public:
|
||||
JSObject *mJSObj; /* Added as a GC root. */
|
||||
JS::PersistentRooted<JSObject *> mJSObj;
|
||||
const NPP mNpp;
|
||||
|
||||
static NPObject *GetNewOrUsed(NPP npp, JSContext *cx,
|
||||
|
|
|
@ -92,31 +92,18 @@ public:
|
|||
JS::Handle<JS::Value> aValue,
|
||||
Promise::PromiseState aState)
|
||||
: mPromise(aPromise)
|
||||
, mValue(aValue)
|
||||
, mValue(CycleCollectedJSRuntime::Get()->Runtime(), aValue)
|
||||
, mState(aState)
|
||||
{
|
||||
MOZ_ASSERT(aPromise);
|
||||
MOZ_ASSERT(mState != Promise::Pending);
|
||||
MOZ_COUNT_CTOR(PromiseResolverMixin);
|
||||
|
||||
/* It's safe to use unsafeGet() here: the unsafeness comes from the
|
||||
* possibility of updating the value of mJSObject without triggering the
|
||||
* barriers. However if the value will always be marked, post barriers
|
||||
* unnecessary. */
|
||||
JS_AddNamedValueRootRT(CycleCollectedJSRuntime::Get()->Runtime(), mValue.unsafeGet(),
|
||||
"PromiseResolverMixin.mValue");
|
||||
}
|
||||
|
||||
virtual ~PromiseResolverMixin()
|
||||
{
|
||||
NS_ASSERT_OWNINGTHREAD(PromiseResolverMixin);
|
||||
MOZ_COUNT_DTOR(PromiseResolverMixin);
|
||||
|
||||
/* It's safe to use unsafeGet() here: the unsafeness comes from the
|
||||
* possibility of updating the value of mJSObject without triggering the
|
||||
* barriers. However if the value will always be marked, post barriers
|
||||
* unnecessary. */
|
||||
JS_RemoveValueRootRT(CycleCollectedJSRuntime::Get()->Runtime(), mValue.unsafeGet());
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -131,7 +118,7 @@ protected:
|
|||
|
||||
private:
|
||||
nsRefPtr<Promise> mPromise;
|
||||
JS::Heap<JS::Value> mValue;
|
||||
JS::PersistentRooted<JS::Value> mValue;
|
||||
Promise::PromiseState mState;
|
||||
NS_DECL_OWNINGTHREAD;
|
||||
};
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "nsIPrefService.h"
|
||||
#include "nspr.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCxPusher.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
|
@ -29,14 +30,14 @@ using mozilla::AutoSafeJSContext;
|
|||
|
||||
//*****************************************************************************
|
||||
|
||||
static JSObject *autoconfigSb = nullptr;
|
||||
static mozilla::Maybe<JS::PersistentRooted<JSObject *> > autoconfigSb;
|
||||
|
||||
nsresult CentralizedAdminPrefManagerInit()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// If the sandbox is already created, no need to create it again.
|
||||
if (autoconfigSb)
|
||||
if (!autoconfigSb.empty())
|
||||
return NS_OK;
|
||||
|
||||
// Grab XPConnect.
|
||||
|
@ -57,37 +58,32 @@ nsresult CentralizedAdminPrefManagerInit()
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Unwrap, store and root the sandbox.
|
||||
autoconfigSb = sandbox->GetJSObject();
|
||||
NS_ENSURE_STATE(autoconfigSb);
|
||||
autoconfigSb = js::UncheckedUnwrap(autoconfigSb);
|
||||
JSAutoCompartment ac(cx, autoconfigSb);
|
||||
if (!JS_AddNamedObjectRoot(cx, &autoconfigSb, "AutoConfig Sandbox"))
|
||||
return NS_ERROR_FAILURE;
|
||||
NS_ENSURE_STATE(sandbox->GetJSObject());
|
||||
autoconfigSb.construct(cx, js::UncheckedUnwrap(sandbox->GetJSObject()));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult CentralizedAdminPrefManagerFinish()
|
||||
{
|
||||
if (autoconfigSb) {
|
||||
if (!autoconfigSb.empty()) {
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoCompartment(cx, autoconfigSb);
|
||||
JS_RemoveObjectRoot(cx, &autoconfigSb);
|
||||
autoconfigSb.destroy();
|
||||
JS_MaybeGC(cx);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult EvaluateAdminConfigScript(const char *js_buffer, size_t length,
|
||||
const char *filename, bool bGlobalContext,
|
||||
const char *filename, bool bGlobalContext,
|
||||
bool bCallbacks, bool skipFirstLine)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (skipFirstLine) {
|
||||
/* In order to protect the privacy of the JavaScript preferences file
|
||||
/* In order to protect the privacy of the JavaScript preferences file
|
||||
* from loading by the browser, we make the first line unparseable
|
||||
* by JavaScript. We must skip that line here before executing
|
||||
* by JavaScript. We must skip that line here before executing
|
||||
* the JavaScript code.
|
||||
*/
|
||||
unsigned int i = 0;
|
||||
|
@ -113,11 +109,11 @@ nsresult EvaluateAdminConfigScript(const char *js_buffer, size_t length,
|
|||
}
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
JSAutoCompartment ac(cx, autoconfigSb);
|
||||
JSAutoCompartment ac(cx, autoconfigSb.ref());
|
||||
|
||||
nsAutoCString script(js_buffer, length);
|
||||
JS::RootedValue v(cx);
|
||||
rv = xpc->EvalInSandboxObject(NS_ConvertASCIItoUTF16(script), filename, cx, autoconfigSb,
|
||||
rv = xpc->EvalInSandboxObject(NS_ConvertASCIItoUTF16(script), filename, cx, autoconfigSb.ref(),
|
||||
/* returnStringOnly = */ false, &v);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ static size_t gMaxStackSize = 128 * sizeof(size_t) * 1024;
|
|||
static double MAX_TIMEOUT_INTERVAL = 1800.0;
|
||||
static double gTimeoutInterval = -1.0;
|
||||
static volatile bool gTimedOut = false;
|
||||
static JS::Value gTimeoutFunc;
|
||||
static Maybe<JS::PersistentRootedValue> gTimeoutFunc;
|
||||
|
||||
static bool enableDisassemblyDumps = false;
|
||||
|
||||
|
@ -362,11 +362,11 @@ ShellInterruptCallback(JSContext *cx)
|
|||
return true;
|
||||
|
||||
bool result;
|
||||
if (!gTimeoutFunc.isNull()) {
|
||||
RootedValue timeoutFunc(cx, gTimeoutFunc.ref());
|
||||
if (!timeoutFunc.isNull()) {
|
||||
JS::AutoSaveExceptionState savedExc(cx);
|
||||
JSAutoCompartment ac(cx, &gTimeoutFunc.toObject());
|
||||
JSAutoCompartment ac(cx, &timeoutFunc.toObject());
|
||||
RootedValue rval(cx);
|
||||
HandleValue timeoutFunc = HandleValue::fromMarkedLocation(&gTimeoutFunc);
|
||||
if (!JS_CallFunctionValue(cx, JS::NullPtr(), timeoutFunc,
|
||||
JS::HandleValueArray::empty(), &rval))
|
||||
{
|
||||
|
@ -3303,7 +3303,7 @@ CancelExecution(JSRuntime *rt)
|
|||
gTimedOut = true;
|
||||
JS_RequestInterruptCallback(rt);
|
||||
|
||||
if (!gTimeoutFunc.isNull()) {
|
||||
if (!gTimeoutFunc.ref().get().isNull()) {
|
||||
static const char msg[] = "Script runs for too long, terminating.\n";
|
||||
#if defined(XP_UNIX) && !defined(JS_THREADSAFE)
|
||||
/* It is not safe to call fputs from signals. */
|
||||
|
@ -3357,7 +3357,7 @@ Timeout(JSContext *cx, unsigned argc, Value *vp)
|
|||
JS_ReportError(cx, "Second argument must be a timeout function");
|
||||
return false;
|
||||
}
|
||||
gTimeoutFunc = value;
|
||||
gTimeoutFunc.ref() = value;
|
||||
}
|
||||
|
||||
args.rval().setUndefined();
|
||||
|
@ -3538,11 +3538,8 @@ class OffThreadState {
|
|||
return false;
|
||||
|
||||
JS_ASSERT(!token);
|
||||
JS_ASSERT(!source);
|
||||
|
||||
source = newSource;
|
||||
if (!JS_AddStringRoot(cx, &source))
|
||||
return false;
|
||||
source.construct(cx, newSource);
|
||||
|
||||
state = COMPILING;
|
||||
return true;
|
||||
|
@ -3552,10 +3549,9 @@ class OffThreadState {
|
|||
AutoLockMonitor alm(monitor);
|
||||
JS_ASSERT(state == COMPILING);
|
||||
JS_ASSERT(!token);
|
||||
JS_ASSERT(source);
|
||||
JS_ASSERT(source.ref());
|
||||
|
||||
JS_RemoveStringRoot(cx, &source);
|
||||
source = nullptr;
|
||||
source.destroy();
|
||||
|
||||
state = IDLE;
|
||||
}
|
||||
|
@ -3564,7 +3560,7 @@ class OffThreadState {
|
|||
AutoLockMonitor alm(monitor);
|
||||
JS_ASSERT(state == COMPILING);
|
||||
JS_ASSERT(!token);
|
||||
JS_ASSERT(source);
|
||||
JS_ASSERT(source.ref());
|
||||
JS_ASSERT(newToken);
|
||||
|
||||
token = newToken;
|
||||
|
@ -3582,9 +3578,8 @@ class OffThreadState {
|
|||
alm.wait();
|
||||
}
|
||||
|
||||
JS_ASSERT(source);
|
||||
JS_RemoveStringRoot(cx, &source);
|
||||
source = nullptr;
|
||||
JS_ASSERT(source.ref());
|
||||
source.destroy();
|
||||
|
||||
JS_ASSERT(token);
|
||||
void *holdToken = token;
|
||||
|
@ -3597,7 +3592,7 @@ class OffThreadState {
|
|||
Monitor monitor;
|
||||
State state;
|
||||
void *token;
|
||||
JSString *source;
|
||||
Maybe<PersistentRootedString> source;
|
||||
};
|
||||
|
||||
static OffThreadState offThreadState;
|
||||
|
@ -6162,9 +6157,7 @@ main(int argc, char **argv, char **envp)
|
|||
if (!SetRuntimeOptions(rt, op))
|
||||
return 1;
|
||||
|
||||
gTimeoutFunc = NullValue();
|
||||
if (!JS_AddNamedValueRootRT(rt, &gTimeoutFunc, "gTimeoutFunc"))
|
||||
return 1;
|
||||
gTimeoutFunc.construct(rt, NullValue());
|
||||
|
||||
JS_SetGCParameter(rt, JSGC_MAX_BYTES, 0xffffffff);
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
|
@ -6210,13 +6203,12 @@ main(int argc, char **argv, char **envp)
|
|||
printf("OOM max count: %u\n", OOM_counter);
|
||||
#endif
|
||||
|
||||
gTimeoutFunc = NullValue();
|
||||
JS_RemoveValueRootRT(rt, &gTimeoutFunc);
|
||||
|
||||
DestroyContext(cx, true);
|
||||
|
||||
KillWatchdog();
|
||||
|
||||
gTimeoutFunc.destroy();
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
for (size_t i = 0; i < workerThreads.length(); i++)
|
||||
PR_JoinThread(workerThreads[i]);
|
||||
|
|
|
@ -415,7 +415,7 @@ mozJSComponentLoader::LoadModule(FileLocation &aFile)
|
|||
if (mModules.Get(spec, &mod))
|
||||
return mod;
|
||||
|
||||
nsAutoPtr<ModuleEntry> entry(new ModuleEntry);
|
||||
nsAutoPtr<ModuleEntry> entry(new ModuleEntry(mContext));
|
||||
|
||||
JSAutoRequest ar(mContext);
|
||||
RootedValue dummy(mContext);
|
||||
|
@ -752,8 +752,8 @@ mozJSComponentLoader::PrepareObjectForLocation(JSCLContextHelper& aCx,
|
|||
nsresult
|
||||
mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
|
||||
nsIURI *aURI,
|
||||
JSObject **aObject,
|
||||
JSScript **aTableScript,
|
||||
MutableHandleObject aObject,
|
||||
MutableHandleScript aTableScript,
|
||||
char **aLocation,
|
||||
bool aPropagateExceptions,
|
||||
MutableHandleValue aException)
|
||||
|
@ -1004,7 +1004,7 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
|
|||
|
||||
// Assign aObject here so that it's available to recursive imports.
|
||||
// See bug 384168.
|
||||
*aObject = obj;
|
||||
aObject.set(obj);
|
||||
|
||||
RootedScript tableScript(cx, script);
|
||||
if (!tableScript) {
|
||||
|
@ -1012,13 +1012,16 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
|
|||
MOZ_ASSERT(tableScript);
|
||||
}
|
||||
|
||||
*aTableScript = tableScript;
|
||||
aTableScript.set(tableScript);
|
||||
|
||||
if (js::GetObjectJSClass(obj) == &kFakeBackstagePassJSClass) {
|
||||
MOZ_ASSERT(mReuseLoaderGlobal);
|
||||
// tableScript stays in the table until shutdown. To avoid it being
|
||||
// collected and another script getting the same address, we root
|
||||
// tableScript lower down in this function.
|
||||
// tableScript stays in the table until shutdown. It is rooted by
|
||||
// virtue of the fact that aTableScript is a handle to
|
||||
// ModuleEntry::thisObjectKey, which is a PersistentRootedScript. Since
|
||||
// ModuleEntries are never dynamically unloaded when mReuseLoaderGlobal
|
||||
// is true, this prevents it from being collected and another script
|
||||
// getting the same address.
|
||||
mThisObjects.Put(tableScript, obj);
|
||||
}
|
||||
bool ok = false;
|
||||
|
@ -1040,8 +1043,8 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
|
|||
JS_GetPendingException(cx, aException);
|
||||
JS_ClearPendingException(cx);
|
||||
}
|
||||
*aObject = nullptr;
|
||||
*aTableScript = nullptr;
|
||||
aObject.set(nullptr);
|
||||
aTableScript.set(nullptr);
|
||||
mThisObjects.Remove(tableScript);
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -1049,14 +1052,12 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
|
|||
/* Freed when we remove from the table. */
|
||||
*aLocation = ToNewCString(nativePath);
|
||||
if (!*aLocation) {
|
||||
*aObject = nullptr;
|
||||
*aTableScript = nullptr;
|
||||
aObject.set(nullptr);
|
||||
aTableScript.set(nullptr);
|
||||
mThisObjects.Remove(tableScript);
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
JS_AddNamedObjectRoot(cx, aObject, *aLocation);
|
||||
JS_AddNamedScriptRoot(cx, aTableScript, *aLocation);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1238,7 +1239,7 @@ mozJSComponentLoader::ImportInto(const nsACString &aLocation,
|
|||
ModuleEntry* mod;
|
||||
nsAutoPtr<ModuleEntry> newEntry;
|
||||
if (!mImports.Get(key, &mod) && !mInProgressImports.Get(key, &mod)) {
|
||||
newEntry = new ModuleEntry;
|
||||
newEntry = new ModuleEntry(callercx);
|
||||
if (!newEntry)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
mInProgressImports.Put(key, newEntry);
|
||||
|
|
|
@ -73,8 +73,8 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
|
|||
|
||||
nsresult ObjectForLocation(nsIFile* aComponentFile,
|
||||
nsIURI *aComponent,
|
||||
JSObject **aObject,
|
||||
JSScript **aTableScript,
|
||||
JS::MutableHandleObject aObject,
|
||||
JS::MutableHandleScript aTableScript,
|
||||
char **location,
|
||||
bool aCatchException,
|
||||
JS::MutableHandleValue aException);
|
||||
|
@ -94,7 +94,9 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
|
|||
class ModuleEntry : public mozilla::Module
|
||||
{
|
||||
public:
|
||||
ModuleEntry() : mozilla::Module() {
|
||||
ModuleEntry(JSContext* aCx)
|
||||
: mozilla::Module(), obj(aCx, nullptr), thisObjectKey(aCx, nullptr)
|
||||
{
|
||||
mVersion = mozilla::Module::kVersion;
|
||||
mCIDs = nullptr;
|
||||
mContractIDs = nullptr;
|
||||
|
@ -103,8 +105,6 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
|
|||
loadProc = nullptr;
|
||||
unloadProc = nullptr;
|
||||
|
||||
obj = nullptr;
|
||||
thisObjectKey = nullptr;
|
||||
location = nullptr;
|
||||
}
|
||||
|
||||
|
@ -120,9 +120,8 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
|
|||
JSAutoCompartment ac(cx, obj);
|
||||
|
||||
JS_SetAllNonReservedSlotsToUndefined(cx, obj);
|
||||
JS_RemoveObjectRoot(cx, &obj);
|
||||
if (thisObjectKey)
|
||||
JS_RemoveScriptRoot(cx, &thisObjectKey);
|
||||
obj = nullptr;
|
||||
thisObjectKey = nullptr;
|
||||
}
|
||||
|
||||
if (location)
|
||||
|
@ -139,8 +138,8 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
|
|||
const mozilla::Module::CIDEntry& entry);
|
||||
|
||||
nsCOMPtr<xpcIJSGetFactory> getfactoryobj;
|
||||
JSObject *obj;
|
||||
JSScript *thisObjectKey;
|
||||
JS::PersistentRootedObject obj;
|
||||
JS::PersistentRootedScript thisObjectKey;
|
||||
char *location;
|
||||
};
|
||||
|
||||
|
|
|
@ -23,10 +23,6 @@ using mozilla::dom::DestroyProtoAndIfaceCache;
|
|||
XPCJSContextStack::~XPCJSContextStack()
|
||||
{
|
||||
if (mSafeJSContext) {
|
||||
{
|
||||
JSAutoRequest ar(mSafeJSContext);
|
||||
JS_RemoveObjectRoot(mSafeJSContext, &mSafeJSContextGlobal);
|
||||
}
|
||||
mSafeJSContextGlobal = nullptr;
|
||||
JS_DestroyContextNoGC(mSafeJSContext);
|
||||
mSafeJSContext = nullptr;
|
||||
|
@ -187,7 +183,6 @@ XPCJSContextStack::InitSafeJSContext()
|
|||
principal, options);
|
||||
if (!mSafeJSContextGlobal)
|
||||
MOZ_CRASH();
|
||||
JS_AddNamedObjectRoot(mSafeJSContext, &mSafeJSContextGlobal, "SafeJSContext global");
|
||||
|
||||
// Note: make sure to set the private before calling
|
||||
// InitClasses
|
||||
|
|
|
@ -3038,7 +3038,7 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect)
|
|||
mWrappedJSRoots(nullptr),
|
||||
mObjectHolderRoots(nullptr),
|
||||
mWatchdogManager(new WatchdogManager(MOZ_THIS_IN_INITIALIZER_LIST())),
|
||||
mJunkScope(nullptr),
|
||||
mJunkScope(MOZ_THIS_IN_INITIALIZER_LIST()->Runtime(), nullptr),
|
||||
mAsyncSnowWhiteFreer(new AsyncFreeSnowWhite())
|
||||
{
|
||||
DOM_InitInterfaces();
|
||||
|
@ -3476,7 +3476,6 @@ XPCJSRuntime::GetJunkScope()
|
|||
NS_ENSURE_SUCCESS(rv, nullptr);
|
||||
|
||||
mJunkScope = js::UncheckedUnwrap(&v.toObject());
|
||||
JS_AddNamedObjectRoot(cx, &mJunkScope, "XPConnect Junk Compartment");
|
||||
}
|
||||
return mJunkScope;
|
||||
}
|
||||
|
@ -3484,10 +3483,5 @@ XPCJSRuntime::GetJunkScope()
|
|||
void
|
||||
XPCJSRuntime::DeleteJunkScope()
|
||||
{
|
||||
if(!mJunkScope)
|
||||
return;
|
||||
|
||||
AutoSafeJSContext cx;
|
||||
JS_RemoveObjectRoot(cx, &mJunkScope);
|
||||
mJunkScope = nullptr;
|
||||
}
|
||||
|
|
|
@ -650,18 +650,20 @@ File(JSContext *cx, unsigned argc, Value *vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
static Value sScriptedInterruptCallback = UndefinedValue();
|
||||
static Maybe<PersistentRootedValue> sScriptedInterruptCallback;
|
||||
|
||||
static bool
|
||||
XPCShellInterruptCallback(JSContext *cx)
|
||||
{
|
||||
MOZ_ASSERT(!sScriptedInterruptCallback.empty());
|
||||
RootedValue callback(cx, sScriptedInterruptCallback.ref());
|
||||
|
||||
// If no interrupt callback was set by script, no-op.
|
||||
if (sScriptedInterruptCallback.isUndefined())
|
||||
if (callback.isUndefined())
|
||||
return true;
|
||||
|
||||
JSAutoCompartment ac(cx, &sScriptedInterruptCallback.toObject());
|
||||
JSAutoCompartment ac(cx, &callback.toObject());
|
||||
RootedValue rv(cx);
|
||||
RootedValue callback(cx, sScriptedInterruptCallback);
|
||||
if (!JS_CallFunctionValue(cx, JS::NullPtr(), callback, JS::HandleValueArray::empty(), &rv) ||
|
||||
!rv.isBoolean())
|
||||
{
|
||||
|
@ -676,6 +678,8 @@ XPCShellInterruptCallback(JSContext *cx)
|
|||
static bool
|
||||
SetInterruptCallback(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
MOZ_ASSERT(!sScriptedInterruptCallback.empty());
|
||||
|
||||
// Sanity-check args.
|
||||
JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
|
||||
if (args.length() != 1) {
|
||||
|
@ -685,7 +689,7 @@ SetInterruptCallback(JSContext *cx, unsigned argc, jsval *vp)
|
|||
|
||||
// Allow callers to remove the interrupt callback by passing undefined.
|
||||
if (args[0].isUndefined()) {
|
||||
sScriptedInterruptCallback = UndefinedValue();
|
||||
sScriptedInterruptCallback.ref() = UndefinedValue();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -695,7 +699,7 @@ SetInterruptCallback(JSContext *cx, unsigned argc, jsval *vp)
|
|||
return false;
|
||||
}
|
||||
|
||||
sScriptedInterruptCallback = args[0];
|
||||
sScriptedInterruptCallback.ref() = args[0];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -1471,6 +1475,7 @@ XRE_XPCShellMain(int argc, char **argv, char **envp)
|
|||
// Override the default XPConnect interrupt callback. We could store the
|
||||
// old one and restore it before shutting down, but there's not really a
|
||||
// reason to bother.
|
||||
sScriptedInterruptCallback.construct(rt, UndefinedValue());
|
||||
JS_SetInterruptCallback(rt, XPCShellInterruptCallback);
|
||||
|
||||
cx = JS_NewContext(rt, 8192);
|
||||
|
@ -1583,9 +1588,7 @@ XRE_XPCShellMain(int argc, char **argv, char **envp)
|
|||
JS_DefineProperty(cx, glob, "__LOCATION__", JSVAL_VOID,
|
||||
GetLocationProperty, nullptr, 0);
|
||||
|
||||
JS_AddValueRoot(cx, &sScriptedInterruptCallback);
|
||||
result = ProcessArgs(cx, glob, argv, argc, &dirprovider);
|
||||
JS_RemoveValueRoot(cx, &sScriptedInterruptCallback);
|
||||
|
||||
JS_DropPrincipals(rt, gJSPrincipals);
|
||||
JS_SetAllNonReservedSlotsToUndefined(cx, glob);
|
||||
|
@ -1603,6 +1606,8 @@ XRE_XPCShellMain(int argc, char **argv, char **envp)
|
|||
rv = NS_ShutdownXPCOM( nullptr );
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "NS_ShutdownXPCOM failed");
|
||||
|
||||
sScriptedInterruptCallback.destroyIfConstructed();
|
||||
|
||||
#ifdef TEST_CALL_ON_WRAPPED_JS_AFTER_SHUTDOWN
|
||||
// test of late call and release (see above)
|
||||
JSContext* bogusCX;
|
||||
|
|
|
@ -597,7 +597,7 @@ private:
|
|||
nsTArray<xpcContextCallback> extraContextCallbacks;
|
||||
nsRefPtr<WatchdogManager> mWatchdogManager;
|
||||
JS::GCSliceCallback mPrevGCSliceCallback;
|
||||
JSObject* mJunkScope;
|
||||
JS::PersistentRootedObject mJunkScope;
|
||||
nsRefPtr<AsyncFreeSnowWhite> mAsyncSnowWhiteFreer;
|
||||
|
||||
mozilla::TimeStamp mSlowScriptCheckpoint;
|
||||
|
@ -2768,7 +2768,7 @@ public:
|
|||
XPCJSContextStack(XPCJSRuntime *aRuntime)
|
||||
: mRuntime(aRuntime)
|
||||
, mSafeJSContext(nullptr)
|
||||
, mSafeJSContextGlobal(nullptr)
|
||||
, mSafeJSContextGlobal(aRuntime->Runtime(), nullptr)
|
||||
{ }
|
||||
|
||||
virtual ~XPCJSContextStack();
|
||||
|
@ -2804,7 +2804,7 @@ private:
|
|||
AutoInfallibleTArray<XPCJSContextInfo, 16> mStack;
|
||||
XPCJSRuntime* mRuntime;
|
||||
JSContext* mSafeJSContext;
|
||||
JSObject* mSafeJSContextGlobal;
|
||||
JS::PersistentRootedObject mSafeJSContextGlobal;
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
|
|
|
@ -12,9 +12,7 @@
|
|||
NS_IMPL_ISUPPORTS2(ArrayBufferInputStream, nsIArrayBufferInputStream, nsIInputStream);
|
||||
|
||||
ArrayBufferInputStream::ArrayBufferInputStream()
|
||||
: mRt(nullptr)
|
||||
, mArrayBuffer(JSVAL_VOID)
|
||||
, mBuffer(nullptr)
|
||||
: mBuffer(nullptr)
|
||||
, mBufferLength(0)
|
||||
, mOffset(0)
|
||||
, mPos(0)
|
||||
|
@ -22,13 +20,6 @@ ArrayBufferInputStream::ArrayBufferInputStream()
|
|||
{
|
||||
}
|
||||
|
||||
ArrayBufferInputStream::~ArrayBufferInputStream()
|
||||
{
|
||||
if (mRt) {
|
||||
JS_RemoveValueRootRT(mRt, &mArrayBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ArrayBufferInputStream::SetData(JS::Handle<JS::Value> aBuffer,
|
||||
uint32_t aByteOffset,
|
||||
|
@ -43,9 +34,7 @@ ArrayBufferInputStream::SetData(JS::Handle<JS::Value> aBuffer,
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mRt = JS_GetRuntime(aCx);
|
||||
mArrayBuffer = aBuffer;
|
||||
JS_AddNamedValueRootRT(mRt, &mArrayBuffer, "mArrayBuffer");
|
||||
mArrayBuffer.construct(aCx, aBuffer);
|
||||
|
||||
uint32_t buflen = JS_GetArrayBufferByteLength(arrayBuffer);
|
||||
mOffset = std::min(buflen, aByteOffset);
|
||||
|
|
|
@ -8,10 +8,11 @@
|
|||
|
||||
#include "nsIArrayBufferInputStream.h"
|
||||
#include "js/Value.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
|
||||
#define NS_ARRAYBUFFERINPUTSTREAM_CONTRACTID "@mozilla.org/io/arraybuffer-input-stream;1"
|
||||
#define NS_ARRAYBUFFERINPUTSTREAM_CID \
|
||||
{ /* 3014dde6-aa1c-41db-87d0-48764a3710f6 */ \
|
||||
{ /* 3014dde6-aa1c-41db-87d0-48764a3710f6 */ \
|
||||
0x3014dde6, \
|
||||
0xaa1c, \
|
||||
0x41db, \
|
||||
|
@ -21,14 +22,13 @@
|
|||
class ArrayBufferInputStream : public nsIArrayBufferInputStream {
|
||||
public:
|
||||
ArrayBufferInputStream();
|
||||
virtual ~ArrayBufferInputStream();
|
||||
virtual ~ArrayBufferInputStream() {}
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIARRAYBUFFERINPUTSTREAM
|
||||
NS_DECL_NSIINPUTSTREAM
|
||||
|
||||
private:
|
||||
JSRuntime* mRt;
|
||||
jsval mArrayBuffer;
|
||||
mozilla::Maybe<JS::PersistentRooted<JS::Value> > mArrayBuffer;
|
||||
uint8_t* mBuffer; // start of actual buffer
|
||||
uint32_t mBufferLength; // length of slice
|
||||
uint32_t mOffset; // permanent offset from start of actual buffer
|
||||
|
|
Загрузка…
Ссылка в новой задаче