From e0d786d901a88c3b270be3f242279b0490fb091c Mon Sep 17 00:00:00 2001 From: Bobby Holley Date: Wed, 4 Sep 2013 14:06:55 -0700 Subject: [PATCH] Bug 899367 - Add an API to opt out of default compartment objects. r=luke We need this explicit API because otherwise the default compartment object will get set implicitly during the first call to InitClasses. --- js/src/jsapi.h | 6 +++++- js/src/jscntxt.h | 5 ++++- js/src/jscntxtinlines.h | 6 +++++- js/src/vm/SelfHosting.cpp | 12 +++++++++--- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/js/src/jsapi.h b/js/src/jsapi.h index d3229ed00f4..ba2bdf71cb7 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -1526,7 +1526,11 @@ JS_StringToVersion(const char *string); /* JS_BIT(10) is currently unused. */ -/* JS_BIT(11) is currently unused. */ +#define JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT JS_BIT(11) /* This JSContext does not use a + default compartment object. Such + an object will not be set implicitly, + and attempts to get or set it will + assert. */ #define JSOPTION_NO_SCRIPT_RVAL JS_BIT(12) /* A promise to the compiler that a null rval out-param diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 9344245a6d7..9ef434396d9 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -449,7 +449,10 @@ struct JSContext : public js::ExclusiveContext, public: inline void setDefaultCompartmentObject(JSObject *obj); inline void setDefaultCompartmentObjectIfUnset(JSObject *obj); - JSObject *maybeDefaultCompartmentObject() const { return defaultCompartmentObject_; } + JSObject *maybeDefaultCompartmentObject() const { + JS_ASSERT(!hasOption(JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT)); + return defaultCompartmentObject_; + } /* Wrap cx->exception for the current compartment. */ void wrapPendingException(); diff --git a/js/src/jscntxtinlines.h b/js/src/jscntxtinlines.h index c1c6cc3c97e..466cb1b4cfc 100644 --- a/js/src/jscntxtinlines.h +++ b/js/src/jscntxtinlines.h @@ -438,14 +438,18 @@ JSContext::setPendingException(js::Value v) { inline void JSContext::setDefaultCompartmentObject(JSObject *obj) { + JS_ASSERT(!hasOption(JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT)); defaultCompartmentObject_ = obj; } inline void JSContext::setDefaultCompartmentObjectIfUnset(JSObject *obj) { - if (!defaultCompartmentObject_) + if (!hasOption(JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT) && + !defaultCompartmentObject_) + { setDefaultCompartmentObject(obj); + } } inline void diff --git a/js/src/vm/SelfHosting.cpp b/js/src/vm/SelfHosting.cpp index a8590b2c9ad..2a6471fb1cd 100644 --- a/js/src/vm/SelfHosting.cpp +++ b/js/src/vm/SelfHosting.cpp @@ -682,12 +682,17 @@ bool JSRuntime::initSelfHosting(JSContext *cx) { JS_ASSERT(!selfHostingGlobal_); - RootedObject savedGlobal(cx, js::DefaultObjectForContextOrNull(cx)); + + bool receivesDefaultObject = !cx->hasOption(JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT); + RootedObject savedGlobal(cx, receivesDefaultObject + ? js::DefaultObjectForContextOrNull(cx) + : NULL); if (!(selfHostingGlobal_ = JS_NewGlobalObject(cx, &self_hosting_global_class, NULL, JS::DontFireOnNewGlobalHook))) return false; JSAutoCompartment ac(cx, selfHostingGlobal_); - js::SetDefaultObjectForContext(cx, selfHostingGlobal_); + if (receivesDefaultObject) + js::SetDefaultObjectForContext(cx, selfHostingGlobal_); Rooted shg(cx, &selfHostingGlobal_->as()); /* * During initialization of standard classes for the self-hosting global, @@ -756,7 +761,8 @@ JSRuntime::initSelfHosting(JSContext *cx) ok = Evaluate(cx, shg, options, src, srcLen, &rv); } JS_SetErrorReporter(cx, oldReporter); - js::SetDefaultObjectForContext(cx, savedGlobal); + if (receivesDefaultObject) + js::SetDefaultObjectForContext(cx, savedGlobal); return ok; }