Bug 880917 - Generalize JS_NewGlobalObject API to take CompartmentOptions. r=luke

This will be useful for versioning, as well as JIT options and all the other
stuff that eventually needs to move out of the JSContext.
This commit is contained in:
Bobby Holley 2013-06-13 10:09:25 -07:00
parent f0bb406fe1
commit 3b2745a4be
21 changed files with 81 additions and 45 deletions

View File

@ -1117,9 +1117,11 @@ nsFrameScriptExecutor::InitTabChildGlobalInternal(nsISupports* aScope,
JS_SetContextPrivate(cx, aScope);
JS::CompartmentOptions options;
options.setZone(JS::SystemZone);
nsresult rv =
xpc->InitClassesWithNewWrappedGlobal(cx, aScope, mPrincipal,
flags, JS::SystemZone, getter_AddRefs(mGlobal));
flags, options, getter_AddRefs(mGlobal));
NS_ENSURE_SUCCESS(rv, false);

View File

@ -284,9 +284,11 @@ nsXBLDocGlobalObject::EnsureScriptEnvironment()
// why - see bug 339647)
JS_SetErrorReporter(cx, XBL_ProtoErrorReporter);
JS::CompartmentOptions options;
options.setZone(JS::SystemZone);
mJSObject = JS_NewGlobalObject(cx, &gSharedGlobalClass,
nsJSPrincipals::get(GetPrincipal()),
JS::SystemZone);
options);
if (!mJSObject)
return NS_OK;

View File

@ -762,9 +762,11 @@ nsXULPDGlobalObject::EnsureScriptEnvironment()
// will re-fetch the global and set it up in our language globals array.
{
AutoPushJSContext cx(ctxNew->GetNativeContext());
JS::CompartmentOptions options;
options.setZone(JS::SystemZone);
JS::Rooted<JSObject*> newGlob(cx,
JS_NewGlobalObject(cx, &gSharedGlobalClass,
nsJSPrincipals::get(GetPrincipal()), JS::SystemZone));
nsJSPrincipals::get(GetPrincipal()), options));
if (!newGlob)
return NS_OK;

View File

@ -2120,10 +2120,10 @@ CreateNativeGlobalForInner(JSContext* aCx,
if (aNewInner->GetOuterWindow()) {
top = aNewInner->GetTop();
}
JS::ZoneSpecifier zoneSpec = JS::FreshZone;
JS::CompartmentOptions options;
if (top) {
if (top->GetGlobalJSObject()) {
zoneSpec = JS::SameZoneAs(top->GetGlobalJSObject());
options.zoneSpec = JS::SameZoneAs(top->GetGlobalJSObject());
}
}
@ -2139,7 +2139,7 @@ CreateNativeGlobalForInner(JSContext* aCx,
nsRefPtr<nsIXPConnectJSObjectHolder> jsholder;
nsresult rv = xpc->InitClassesWithNewWrappedGlobal(
aCx, ToSupports(aNewInner),
aPrincipal, flags, zoneSpec, getter_AddRefs(jsholder));
aPrincipal, flags, options, getter_AddRefs(jsholder));
NS_ENSURE_SUCCESS(rv, rv);
MOZ_ASSERT(jsholder);

View File

@ -783,11 +783,13 @@ XPCShellEnvironment::Init()
return false;
}
JS::CompartmentOptions options;
options.setZone(JS::SystemZone);
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = xpc->InitClassesWithNewWrappedGlobal(cx,
static_cast<nsIGlobalObject *>(backstagePass),
principal, 0,
JS::SystemZone,
options,
getter_AddRefs(holder));
if (NS_FAILED(rv)) {
NS_ERROR("InitClassesWithNewWrappedGlobal failed!");

View File

@ -941,7 +941,8 @@ JSRuntime::init(uint32_t maxbytes)
if (!atomsZone)
return false;
ScopedJSDeletePtr<JSCompartment> atomsCompartment(new_<JSCompartment>(atomsZone.get()));
JS::CompartmentOptions options;
ScopedJSDeletePtr<JSCompartment> atomsCompartment(new_<JSCompartment>(atomsZone.get(), options));
if (!atomsCompartment || !atomsCompartment->init(NULL))
return false;
@ -3427,7 +3428,8 @@ class AutoHoldZone
};
JS_PUBLIC_API(JSObject *)
JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals, JS::ZoneSpecifier zoneSpec)
JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals,
const JS::CompartmentOptions &options)
{
AssertHeapIsIdle(cx);
CHECK_REQUEST(cx);
@ -3436,18 +3438,18 @@ JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals, JS::
JSRuntime *rt = cx->runtime();
Zone *zone;
if (zoneSpec == JS::SystemZone)
if (options.zoneSpec == JS::SystemZone)
zone = rt->systemZone;
else if (zoneSpec == JS::FreshZone)
else if (options.zoneSpec == JS::FreshZone)
zone = NULL;
else
zone = ((JSObject *)zoneSpec)->zone();
zone = ((JSObject *)options.zoneSpec)->zone();
JSCompartment *compartment = NewCompartment(cx, zone, principals);
JSCompartment *compartment = NewCompartment(cx, zone, principals, options);
if (!compartment)
return NULL;
if (zoneSpec == JS::SystemZone) {
if (options.zoneSpec == JS::SystemZone) {
rt->systemZone = compartment->zone();
rt->systemZone->isSystem = true;
}

View File

@ -3144,11 +3144,20 @@ SameZoneAs(JSObject *obj)
return ZoneSpecifier(obj);
}
struct JS_PUBLIC_API(CompartmentOptions) {
ZoneSpecifier zoneSpec;
explicit CompartmentOptions() : zoneSpec(JS::FreshZone)
{}
CompartmentOptions &setZone(ZoneSpecifier spec) { zoneSpec = spec; return *this; }
};
} /* namespace JS */
extern JS_PUBLIC_API(JSObject *)
JS_NewGlobalObject(JSContext *cx, JSClass *clasp, JSPrincipals *principals,
JS::ZoneSpecifier zoneSpec = JS::FreshZone);
const JS::CompartmentOptions &options = JS::CompartmentOptions());
extern JS_PUBLIC_API(JSObject *)
JS_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent);

View File

@ -30,8 +30,9 @@ using namespace js::gc;
using mozilla::DebugOnly;
JSCompartment::JSCompartment(Zone *zone)
JSCompartment::JSCompartment(Zone *zone, const JS::CompartmentOptions &options = JS::CompartmentOptions())
: zone_(zone),
options_(options),
rt(zone->rt),
principals(NULL),
isSystem(false),

View File

@ -123,6 +123,7 @@ class DebugScopes;
struct JSCompartment
{
JS::Zone *zone_;
JS::CompartmentOptions options_;
JSRuntime *rt;
JSPrincipals *principals;
@ -144,6 +145,8 @@ struct JSCompartment
JS::Zone *zone() { return zone_; }
const JS::Zone *zone() const { return zone_; }
JS::CompartmentOptions &options() { return options_; }
const JS::CompartmentOptions &options() const { return options_; }
/*
* Nb: global_ might be NULL, if (a) it's the atoms compartment, or (b) the
@ -259,7 +262,7 @@ struct JSCompartment
unsigned debugModeBits; // see debugMode() below
public:
JSCompartment(JS::Zone *zone);
JSCompartment(JS::Zone *zone, const JS::CompartmentOptions &options);
~JSCompartment();
bool init(JSContext *cx);

View File

@ -4699,7 +4699,8 @@ AutoPrepareForTracing::AutoPrepareForTracing(JSRuntime *rt)
}
JSCompartment *
js::NewCompartment(JSContext *cx, Zone *zone, JSPrincipals *principals)
js::NewCompartment(JSContext *cx, Zone *zone, JSPrincipals *principals,
const JS::CompartmentOptions &options)
{
JSRuntime *rt = cx->runtime();
JS_AbortIfWrongThread(rt);
@ -4721,7 +4722,7 @@ js::NewCompartment(JSContext *cx, Zone *zone, JSPrincipals *principals)
zone->isSystem = principals && principals == trusted;
}
ScopedJSDeletePtr<JSCompartment> compartment(cx->new_<JSCompartment>(zone));
ScopedJSDeletePtr<JSCompartment> compartment(cx->new_<JSCompartment>(zone, options));
if (!compartment || !compartment->init(cx))
return NULL;

View File

@ -1201,7 +1201,8 @@ js_FinalizeStringRT(JSRuntime *rt, JSString *str);
namespace js {
JSCompartment *
NewCompartment(JSContext *cx, JS::Zone *zone, JSPrincipals *principals);
NewCompartment(JSContext *cx, JS::Zone *zone, JSPrincipals *principals,
const JS::CompartmentOptions &options);
namespace gc {

View File

@ -4799,8 +4799,9 @@ DestroyContext(JSContext *cx, bool withGC)
static JSObject *
NewGlobalObject(JSContext *cx, JSObject *sameZoneAs)
{
JS::ZoneSpecifier spec = sameZoneAs ? JS::SameZoneAs(sameZoneAs) : JS::FreshZone;
RootedObject glob(cx, JS_NewGlobalObject(cx, &global_class, NULL, spec));
JS::CompartmentOptions options;
options.setZone(sameZoneAs ? JS::SameZoneAs(sameZoneAs) : JS::FreshZone);
RootedObject glob(cx, JS_NewGlobalObject(cx, &global_class, NULL, options));
if (!glob)
return NULL;

View File

@ -44,7 +44,7 @@ class nsWrapperCache;
[ref] native nsCCTraversalCallbackRef(nsCycleCollectionTraversalCallback);
[ptr] native nsAXPCNativeCallContextPtr(nsAXPCNativeCallContext);
[ptr] native nsWrapperCachePtr(nsWrapperCache);
native ZoneSpecifier(uintptr_t);
[ref] native JSCompartmentOptions(JS::CompartmentOptions);
[ref] native JSCallArgsRef(const JS::CallArgs);
native JSHandleId(JS::HandleId);
@ -291,7 +291,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports
{ 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } }
%}
[uuid(2950bc62-ba03-4465-9685-a0eec9e188c2)]
[uuid(bd61342d-8a88-4f23-8d2d-1782fff02d26)]
interface nsIXPConnect : nsISupports
{
%{ C++
@ -318,14 +318,15 @@ interface nsIXPConnect : nsISupports
* compartment. Can be null if not on the main thread.
* @param aFlags one of the flags below specifying what options this
* global object wants.
* @param aOptions JSAPI-specific options for the new compartment.
*/
nsIXPConnectJSObjectHolder
initClassesWithNewWrappedGlobal(
in JSContextPtr aJSContext,
in nsISupports aCOMObj,
in nsIPrincipal aPrincipal,
in uint32_t aFlags,
in ZoneSpecifier aZoneSpec);
in JSContextPtr aJSContext,
in nsISupports aCOMObj,
in nsIPrincipal aPrincipal,
in uint32_t aFlags,
in JSCompartmentOptions aOptions);
const uint32_t INIT_JS_STANDARD_CLASSES = 1 << 0;
// Free bit here!

View File

@ -726,11 +726,13 @@ mozJSComponentLoader::PrepareObjectForLocation(JSCLContextHelper& aCx,
rv = NS_NewBackstagePass(getter_AddRefs(backstagePass));
NS_ENSURE_SUCCESS(rv, nullptr);
JS::CompartmentOptions options;
options.setZone(JS::SystemZone);
rv = xpc->InitClassesWithNewWrappedGlobal(aCx,
static_cast<nsIGlobalObject *>(backstagePass),
mSystemPrincipal,
0,
JS::SystemZone,
options,
getter_AddRefs(holder));
NS_ENSURE_SUCCESS(rv, nullptr);

View File

@ -1634,12 +1634,14 @@ main(int argc, char **argv, char **envp)
return 1;
}
JS::CompartmentOptions options;
options.setZone(JS::SystemZone);
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = xpc->InitClassesWithNewWrappedGlobal(cx,
static_cast<nsIGlobalObject *>(backstagePass),
systemprincipal,
0,
JS::SystemZone,
options,
getter_AddRefs(holder));
if (NS_FAILED(rv))
return 1;

View File

@ -3279,10 +3279,12 @@ xpc_CreateSandboxObject(JSContext *cx, jsval *vp, nsISupports *prinOrSop, Sandbo
MOZ_ASSERT(principal);
}
JS::ZoneSpecifier zoneSpec = options.sameZoneAs
JS::CompartmentOptions compartmentOptions;
compartmentOptions.setZone(options.sameZoneAs
? JS::SameZoneAs(js::UncheckedUnwrap(options.sameZoneAs))
: JS::SystemZone;
RootedObject sandbox(cx, xpc::CreateGlobalObject(cx, &SandboxClass, principal, zoneSpec));
: JS::SystemZone);
RootedObject sandbox(cx, xpc::CreateGlobalObject(cx, &SandboxClass,
principal, compartmentOptions));
if (!sandbox)
return NS_ERROR_FAILURE;

View File

@ -167,7 +167,9 @@ XPCJSContextStack::GetSafeJSContext()
JS_SetErrorReporter(mSafeJSContext, mozJSLoaderErrorReporter);
glob = xpc::CreateGlobalObject(mSafeJSContext, &global_class, principal, JS::SystemZone);
JS::CompartmentOptions options;
options.setZone(JS::SystemZone);
glob = xpc::CreateGlobalObject(mSafeJSContext, &global_class, principal, options);
if (glob) {
// Make sure the context is associated with a proper compartment

View File

@ -285,7 +285,7 @@ FinishCreate(XPCWrappedNativeScope* Scope,
nsresult
XPCWrappedNative::WrapNewGlobal(xpcObjectHelper &nativeHelper,
nsIPrincipal *principal, bool initStandardClasses,
ZoneSpecifier zoneSpec,
JS::CompartmentOptions& aOptions,
XPCWrappedNative **wrappedGlobal)
{
AutoJSContext cx;
@ -315,7 +315,7 @@ XPCWrappedNative::WrapNewGlobal(xpcObjectHelper &nativeHelper,
MOZ_ASSERT(clasp->flags & JSCLASS_IS_GLOBAL);
// Create the global.
RootedObject global(cx, xpc::CreateGlobalObject(cx, clasp, principal, zoneSpec));
RootedObject global(cx, xpc::CreateGlobalObject(cx, clasp, principal, aOptions));
if (!global)
return NS_ERROR_FAILURE;
XPCWrappedNativeScope *scope = GetCompartmentPrivate(global)->scope;

View File

@ -981,7 +981,7 @@ namespace xpc {
JSObject*
CreateGlobalObject(JSContext *cx, JSClass *clasp, nsIPrincipal *principal,
JS::ZoneSpecifier zoneSpec)
JS::CompartmentOptions& aOptions)
{
// Make sure that Type Inference is enabled for everything non-chrome.
// Sandboxes and compilation scopes are exceptions. See bug 744034.
@ -991,7 +991,7 @@ CreateGlobalObject(JSContext *cx, JSClass *clasp, nsIPrincipal *principal,
MOZ_ASSERT(principal);
RootedObject global(cx,
JS_NewGlobalObject(cx, clasp, nsJSPrincipals::get(principal), zoneSpec));
JS_NewGlobalObject(cx, clasp, nsJSPrincipals::get(principal), aOptions));
if (!global)
return nullptr;
JSAutoCompartment ac(cx, global);
@ -1027,7 +1027,7 @@ nsXPConnect::InitClassesWithNewWrappedGlobal(JSContext * aJSContext,
nsISupports *aCOMObj,
nsIPrincipal * aPrincipal,
uint32_t aFlags,
JS::ZoneSpecifier zoneSpec,
JS::CompartmentOptions& aOptions,
nsIXPConnectJSObjectHolder **_retval)
{
NS_ASSERTION(aJSContext, "bad param");
@ -1046,8 +1046,7 @@ nsXPConnect::InitClassesWithNewWrappedGlobal(JSContext * aJSContext,
nsresult rv =
XPCWrappedNative::WrapNewGlobal(helper, aPrincipal,
aFlags & nsIXPConnect::INIT_JS_STANDARD_CLASSES,
zoneSpec,
getter_AddRefs(wrappedGlobal));
aOptions, getter_AddRefs(wrappedGlobal));
NS_ENSURE_SUCCESS(rv, rv);
// Grab a copy of the global and enter its compartment.

View File

@ -2471,7 +2471,7 @@ public:
static nsresult
WrapNewGlobal(xpcObjectHelper &nativeHelper,
nsIPrincipal *principal, bool initStandardClasses,
JS::ZoneSpecifier zoneSpec,
JS::CompartmentOptions& aOptions,
XPCWrappedNative **wrappedGlobal);
static nsresult
@ -3796,7 +3796,7 @@ struct SandboxOptions {
JSObject *
CreateGlobalObject(JSContext *cx, JSClass *clasp, nsIPrincipal *principal,
JS::ZoneSpecifier zoneSpec);
JS::CompartmentOptions& aOptions);
}
// Helper for creating a sandbox object to use for evaluating

View File

@ -536,7 +536,9 @@ private:
JSAutoRequest ar(mContext);
mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, nullptr, JS::SystemZone);
JS::CompartmentOptions options;
options.setZone(JS::SystemZone);
mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, nullptr, options);
NS_ENSURE_TRUE(mGlobal, NS_ERROR_OUT_OF_MEMORY);
JS_SetGlobalObject(mContext, mGlobal);