Bug 865308: GC: More rooting work in XPConnect r=bholley

This commit is contained in:
Jon Coppeard
2013-04-26 18:50:18 +01:00
parent 0560bbf909
commit a726d15847
7 changed files with 46 additions and 50 deletions

View File

@@ -680,7 +680,7 @@ mozJSComponentLoader::FindTargetObject(JSContext* aCx,
} }
void void
mozJSComponentLoader::NoteSubScript(JSScript* aScript, JSObject* aThisObject) mozJSComponentLoader::NoteSubScript(HandleScript aScript, HandleObject aThisObject)
{ {
if (!mInitialized && NS_FAILED(ReallyInit())) { if (!mInitialized && NS_FAILED(ReallyInit())) {
MOZ_NOT_REACHED(); MOZ_NOT_REACHED();
@@ -847,8 +847,8 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
JSAutoCompartment ac(cx, obj); JSAutoCompartment ac(cx, obj);
JSScript *script = nullptr; RootedScript script(cx);
JSFunction *function = nullptr; RootedFunction function(cx);
nsAutoCString nativePath; nsAutoCString nativePath;
nsresult rv = aURI->GetSpec(nativePath); nsresult rv = aURI->GetSpec(nativePath);
@@ -868,10 +868,10 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
if (cache) { if (cache) {
if (!mReuseLoaderGlobal) { if (!mReuseLoaderGlobal) {
rv = ReadCachedScript(cache, cachePath, cx, mSystemPrincipal, rv = ReadCachedScript(cache, cachePath, cx, mSystemPrincipal,
&script); script.address());
} else { } else {
rv = ReadCachedFunction(cache, cachePath, cx, mSystemPrincipal, rv = ReadCachedFunction(cache, cachePath, cx, mSystemPrincipal,
&function); function.address());
} }
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {

View File

@@ -55,7 +55,7 @@ class mozJSComponentLoader : public mozilla::ModuleLoader,
static mozJSComponentLoader* Get() { return sSelf; } static mozJSComponentLoader* Get() { return sSelf; }
void NoteSubScript(JSScript* aScript, JSObject* aThisObject); void NoteSubScript(JS::HandleScript aScript, JS::HandleObject aThisObject);
protected: protected:
static mozJSComponentLoader* sSelf; static mozJSComponentLoader* sSelf;

View File

@@ -34,6 +34,7 @@
#include "mozilla/Preferences.h" #include "mozilla/Preferences.h"
using namespace mozilla::scache; using namespace mozilla::scache;
using namespace JS;
/* load() error msgs, XXX localize? */ /* load() error msgs, XXX localize? */
#define LOAD_ERROR_NOSERVICE "Error creating IO Service." #define LOAD_ERROR_NOSERVICE "Error creating IO Service."
@@ -75,12 +76,14 @@ ReportError(JSContext *cx, const char *msg)
} }
nsresult nsresult
mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_obj, mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *targetObjArg,
const nsAString& charset, const char *uriStr, const nsAString& charset, const char *uriStr,
nsIIOService *serv, nsIPrincipal *principal, nsIIOService *serv, nsIPrincipal *principal,
bool reuseGlobal, JSScript **scriptp, bool reuseGlobal, JSScript **scriptp,
JSFunction **functionp) JSFunction **functionp)
{ {
RootedObject target_obj(cx, targetObjArg);
nsCOMPtr<nsIChannel> chan; nsCOMPtr<nsIChannel> chan;
nsCOMPtr<nsIInputStream> instream; nsCOMPtr<nsIInputStream> instream;
JSErrorReporter er; JSErrorReporter er;
@@ -125,7 +128,6 @@ mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_ob
JS::CompileOptions options(cx); JS::CompileOptions options(cx);
options.setPrincipals(nsJSPrincipals::get(principal)) options.setPrincipals(nsJSPrincipals::get(principal))
.setFileAndLine(uriStr, 1); .setFileAndLine(uriStr, 1);
JS::RootedObject target_obj_root(cx, target_obj);
if (!charset.IsVoid()) { if (!charset.IsVoid()) {
nsString script; nsString script;
rv = nsScriptLoader::ConvertToUTF16(nullptr, reinterpret_cast<const uint8_t*>(buf.get()), len, rv = nsScriptLoader::ConvertToUTF16(nullptr, reinterpret_cast<const uint8_t*>(buf.get()), len,
@@ -136,11 +138,11 @@ mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_ob
} }
if (!reuseGlobal) { if (!reuseGlobal) {
*scriptp = JS::Compile(cx, target_obj_root, options, *scriptp = JS::Compile(cx, target_obj, options,
reinterpret_cast<const jschar*>(script.get()), reinterpret_cast<const jschar*>(script.get()),
script.Length()); script.Length());
} else { } else {
*functionp = JS::CompileFunction(cx, target_obj_root, options, *functionp = JS::CompileFunction(cx, target_obj, options,
nullptr, 0, nullptr, nullptr, 0, nullptr,
reinterpret_cast<const jschar*>(script.get()), reinterpret_cast<const jschar*>(script.get()),
script.Length()); script.Length());
@@ -150,9 +152,9 @@ mozJSSubScriptLoader::ReadScript(nsIURI *uri, JSContext *cx, JSObject *target_ob
// the lazy source loader doesn't know the encoding. // the lazy source loader doesn't know the encoding.
if (!reuseGlobal) { if (!reuseGlobal) {
options.setSourcePolicy(JS::CompileOptions::LAZY_SOURCE); options.setSourcePolicy(JS::CompileOptions::LAZY_SOURCE);
*scriptp = JS::Compile(cx, target_obj_root, options, buf.get(), len); *scriptp = JS::Compile(cx, target_obj, options, buf.get(), len);
} else { } else {
*functionp = JS::CompileFunction(cx, target_obj_root, options, *functionp = JS::CompileFunction(cx, target_obj, options,
nullptr, 0, nullptr, buf.get(), nullptr, 0, nullptr, buf.get(),
len); len);
} }
@@ -198,7 +200,7 @@ mozJSSubScriptLoader::LoadSubScript(const nsAString& url,
JSAutoRequest ar(cx); JSAutoRequest ar(cx);
JS::RootedObject targetObj(cx); RootedObject targetObj(cx);
mozJSComponentLoader* loader = mozJSComponentLoader::Get(); mozJSComponentLoader* loader = mozJSComponentLoader::Get();
rv = loader->FindTargetObject(cx, &targetObj); rv = loader->FindTargetObject(cx, &targetObj);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
@@ -207,8 +209,8 @@ mozJSSubScriptLoader::LoadSubScript(const nsAString& url,
// We base reusingGlobal off of what the loader told us, but we may not // We base reusingGlobal off of what the loader told us, but we may not
// actually be using that object. // actually be using that object.
JSObject* passedObj; RootedObject passedObj(cx);
if (!JS_ValueToObject(cx, target, &passedObj)) if (!JS_ValueToObject(cx, target, passedObj.address()))
return NS_ERROR_ILLEGAL_VALUE; return NS_ERROR_ILLEGAL_VALUE;
if (passedObj) if (passedObj)
@@ -217,7 +219,7 @@ mozJSSubScriptLoader::LoadSubScript(const nsAString& url,
// Remember an object out of the calling compartment so that we // Remember an object out of the calling compartment so that we
// can properly wrap the result later. // can properly wrap the result later.
nsCOMPtr<nsIPrincipal> principal = mSystemPrincipal; nsCOMPtr<nsIPrincipal> principal = mSystemPrincipal;
JSObject *result_obj = targetObj; RootedObject result_obj(cx, targetObj);
targetObj = JS_FindCompilationScope(cx, targetObj); targetObj = JS_FindCompilationScope(cx, targetObj);
if (!targetObj) if (!targetObj)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
@@ -240,10 +242,10 @@ mozJSSubScriptLoader::LoadSubScript(const nsAString& url,
nsAutoCString uriStr; nsAutoCString uriStr;
nsAutoCString scheme; nsAutoCString scheme;
JSScript* script = nullptr; RootedScript script(cx);
// Figure out who's calling us // Figure out who's calling us
if (!JS_DescribeScriptedCaller(cx, &script, nullptr)) { if (!JS_DescribeScriptedCaller(cx, script.address(), nullptr)) {
// No scripted frame means we don't know who's calling, bail. // No scripted frame means we don't know who's calling, bail.
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
@@ -297,14 +299,14 @@ mozJSSubScriptLoader::LoadSubScript(const nsAString& url,
cachePath.AppendPrintf("jssubloader/%d", version); cachePath.AppendPrintf("jssubloader/%d", version);
PathifyURI(uri, cachePath); PathifyURI(uri, cachePath);
JSFunction* function = nullptr; RootedFunction function(cx);
script = nullptr; script = nullptr;
if (cache) if (cache)
rv = ReadCachedScript(cache, cachePath, cx, mSystemPrincipal, &script); rv = ReadCachedScript(cache, cachePath, cx, mSystemPrincipal, script.address());
if (!script) { if (!script) {
rv = ReadScript(uri, cx, targetObj, charset, rv = ReadScript(uri, cx, targetObj, charset,
static_cast<const char*>(uriStr.get()), serv, static_cast<const char*>(uriStr.get()), serv,
principal, reusingGlobal, &script, &function); principal, reusingGlobal, script.address(), function.address());
writeScript = !!script; writeScript = !!script;
} }

View File

@@ -3387,8 +3387,6 @@ xpc_CreateSandboxObject(JSContext *cx, jsval *vp, nsISupports *prinOrSop, Sandbo
xpc::GetCompartmentPrivate(sandbox)->wantXrays = xpc::GetCompartmentPrivate(sandbox)->wantXrays =
AccessCheck::isChrome(sandbox) ? false : options.wantXrays; AccessCheck::isChrome(sandbox) ? false : options.wantXrays;
JS::AutoObjectRooter tvr(cx, sandbox);
{ {
JSAutoCompartment ac(cx, sandbox); JSAutoCompartment ac(cx, sandbox);
@@ -3829,7 +3827,7 @@ class ContextHolder : public nsIScriptObjectPrincipal
, public nsIScriptContextPrincipal , public nsIScriptContextPrincipal
{ {
public: public:
ContextHolder(JSContext *aOuterCx, JSObject *aSandbox, nsIPrincipal *aPrincipal); ContextHolder(JSContext *aOuterCx, HandleObject aSandbox, nsIPrincipal *aPrincipal);
virtual ~ContextHolder(); virtual ~ContextHolder();
JSContext * GetJSContext() JSContext * GetJSContext()
@@ -3853,7 +3851,7 @@ private:
NS_IMPL_ISUPPORTS2(ContextHolder, nsIScriptObjectPrincipal, nsIScriptContextPrincipal) NS_IMPL_ISUPPORTS2(ContextHolder, nsIScriptObjectPrincipal, nsIScriptContextPrincipal)
ContextHolder::ContextHolder(JSContext *aOuterCx, ContextHolder::ContextHolder(JSContext *aOuterCx,
JSObject *aSandbox, HandleObject aSandbox,
nsIPrincipal *aPrincipal) nsIPrincipal *aPrincipal)
: mJSContext(JS_NewContext(JS_GetRuntime(aOuterCx), 1024)), : mJSContext(JS_NewContext(JS_GetRuntime(aOuterCx), 1024)),
mOrigCx(aOuterCx), mOrigCx(aOuterCx),
@@ -4199,8 +4197,8 @@ nsXPCComponents_Utils::NondeterministicGetWeakMapKeys(const JS::Value &aMap,
aKeys->setUndefined(); aKeys->setUndefined();
return NS_OK; return NS_OK;
} }
JSObject *objRet; RootedObject objRet(aCx);
if (!JS_NondeterministicGetWeakMapKeys(aCx, &aMap.toObject(), &objRet)) if (!JS_NondeterministicGetWeakMapKeys(aCx, &aMap.toObject(), objRet.address()))
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
*aKeys = objRet ? ObjectValue(*objRet) : UndefinedValue(); *aKeys = objRet ? ObjectValue(*objRet) : UndefinedValue();
return NS_OK; return NS_OK;

View File

@@ -494,22 +494,22 @@ nsXPCWrappedJSClass::IsWrappedJS(nsISupports* aPtr)
result == WrappedJSIdentity::GetSingleton(); result == WrappedJSIdentity::GetSingleton();
} }
// NB: This returns null unless there's nothing on the JSContext stack. // NB: This will return the top JSContext on the JSContext stack if there is one,
// before attempting to get the context from the wrapped JS object.
static JSContext * static JSContext *
GetContextFromObject(JSObject *objArg) GetContextFromObjectOrDefault(nsXPCWrappedJS* wrapper)
{ {
// Don't stomp over a running context. // Don't stomp over a running context.
XPCJSContextStack* stack = XPCJSRuntime::Get()->GetJSContextStack(); XPCJSContextStack* stack = XPCJSRuntime::Get()->GetJSContextStack();
if (stack && stack->Peek()) if (stack && stack->Peek())
return nullptr; return stack->Peek();
// In order to get a context, we need a context. // In order to get a context, we need a context.
XPCCallContext ccx(NATIVE_CALLER); XPCCallContext ccx(NATIVE_CALLER);
if (!ccx.IsValid()) if (!ccx.IsValid())
return nullptr; return nullptr;
RootedObject obj(ccx, objArg); RootedObject obj(ccx, wrapper->GetJSObject());
JSAutoCompartment ac(ccx, obj); JSAutoCompartment ac(ccx, obj);
XPCWrappedNativeScope* scope = GetObjectScope(obj); XPCWrappedNativeScope* scope = GetObjectScope(obj);
XPCContext *xpcc = scope->GetContext(); XPCContext *xpcc = scope->GetContext();
@@ -520,7 +520,7 @@ GetContextFromObject(JSObject *objArg)
return cx; return cx;
} }
return nullptr; return XPCCallContext::GetDefaultJSContext();
} }
class SameOriginCheckedComponent MOZ_FINAL : public nsISecurityCheckedComponent class SameOriginCheckedComponent MOZ_FINAL : public nsISecurityCheckedComponent
@@ -620,9 +620,7 @@ nsXPCWrappedJSClass::DelegatedQueryInterface(nsXPCWrappedJS* self,
return NS_NOINTERFACE; return NS_NOINTERFACE;
} }
JSContext *context = GetContextFromObject(self->GetJSObject()); JSContext *context = GetContextFromObjectOrDefault(self);
if (!context)
context = XPCCallContext::GetDefaultJSContext();
XPCCallContext ccx(NATIVE_CALLER, context); XPCCallContext ccx(NATIVE_CALLER, context);
if (!ccx.IsValid()) { if (!ccx.IsValid()) {
*aInstancePtr = nullptr; *aInstancePtr = nullptr;
@@ -1136,9 +1134,7 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
// the whole nsIXPCFunctionThisTranslator bit. That code uses ccx to // the whole nsIXPCFunctionThisTranslator bit. That code uses ccx to
// convert natives to JSObjects, but we do NOT plan to pass those JSObjects // convert natives to JSObjects, but we do NOT plan to pass those JSObjects
// to our real callee. // to our real callee.
JSContext *context = GetContextFromObject(wrapper->GetJSObject()); JSContext *context = GetContextFromObjectOrDefault(wrapper);
if (!context)
context = XPCCallContext::GetDefaultJSContext();
XPCCallContext ccx(NATIVE_CALLER, context); XPCCallContext ccx(NATIVE_CALLER, context);
if (!ccx.IsValid()) if (!ccx.IsValid())
return retval; return retval;

View File

@@ -346,7 +346,7 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapperArg, jsid idArg, Wr
return false; return false;
} }
JSObject *hallpass = &exposedProps.toObject(); RootedObject hallpass(cx, &exposedProps.toObject());
if (!AccessCheck::subsumes(js::UncheckedUnwrap(hallpass), wrappedObject)) { if (!AccessCheck::subsumes(js::UncheckedUnwrap(hallpass), wrappedObject)) {
EnterAndThrow(cx, wrapper, "Invalid __exposedProps__"); EnterAndThrow(cx, wrapper, "Invalid __exposedProps__");
@@ -355,19 +355,19 @@ ExposedPropertiesOnly::check(JSContext *cx, JSObject *wrapperArg, jsid idArg, Wr
Access access = NO_ACCESS; Access access = NO_ACCESS;
JSPropertyDescriptor desc; Rooted<JSPropertyDescriptor> desc(cx);
if (!JS_GetPropertyDescriptorById(cx, hallpass, id, 0, &desc)) { if (!JS_GetPropertyDescriptorById(cx, hallpass, id, 0, desc.address())) {
return false; // Error return false; // Error
} }
if (!desc.obj || !(desc.attrs & JSPROP_ENUMERATE)) if (!desc.object() || !desc.isEnumerable())
return false; return false;
if (!JSVAL_IS_STRING(desc.value)) { if (!desc.value().isString()) {
EnterAndThrow(cx, wrapper, "property must be a string"); EnterAndThrow(cx, wrapper, "property must be a string");
return false; return false;
} }
JSString *str = JSVAL_TO_STRING(desc.value); JSString *str = desc.value().toString();
size_t length; size_t length;
const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length); const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);
if (!chars) if (!chars)

View File

@@ -1378,16 +1378,16 @@ HasNativeProperty(JSContext *cx, HandleObject wrapper, HandleId id, bool *hasPro
RootedObject holder(cx, traits->ensureHolder(cx, wrapper)); RootedObject holder(cx, traits->ensureHolder(cx, wrapper));
NS_ENSURE_TRUE(holder, false); NS_ENSURE_TRUE(holder, false);
*hasProp = false; *hasProp = false;
JSPropertyDescriptor desc; Rooted<PropertyDescriptor> desc(cx);
Wrapper *handler = Wrapper::wrapperHandler(wrapper); Wrapper *handler = Wrapper::wrapperHandler(wrapper);
// Try resolveOwnProperty. // Try resolveOwnProperty.
Maybe<ResolvingId> resolvingId; Maybe<ResolvingId> resolvingId;
if (traits == &XPCWrappedNativeXrayTraits::singleton) if (traits == &XPCWrappedNativeXrayTraits::singleton)
resolvingId.construct(cx, wrapper, id); resolvingId.construct(cx, wrapper, id);
if (!traits->resolveOwnProperty(cx, *handler, wrapper, holder, id, &desc, 0)) if (!traits->resolveOwnProperty(cx, *handler, wrapper, holder, id, desc.address(), 0))
return false; return false;
if (desc.obj) { if (desc.object()) {
*hasProp = true; *hasProp = true;
return true; return true;
} }
@@ -1402,9 +1402,9 @@ HasNativeProperty(JSContext *cx, HandleObject wrapper, HandleId id, bool *hasPro
} }
// Try resolveNativeProperty. // Try resolveNativeProperty.
if (!traits->resolveNativeProperty(cx, wrapper, holder, id, &desc, 0)) if (!traits->resolveNativeProperty(cx, wrapper, holder, id, desc.address(), 0))
return false; return false;
*hasProp = !!desc.obj; *hasProp = !!desc.object();
return true; return true;
} }