Bug 1235615 - Split JS::CompartmentOptions into JS::CompartmentCreationOptions that are immutable characteristics of a compartment, and JS::CompartmentBehaviors that may be changed after the compartment's been created. r=terrence

This commit is contained in:
Jeff Walden 2015-12-28 16:15:52 -06:00
parent 7be5030d64
commit 0195fbed46
42 changed files with 362 additions and 237 deletions

View File

@ -113,7 +113,7 @@ struct DevTools : public ::testing::Test {
/* Create the global object. */
JS::RootedObject newGlobal(cx);
JS::CompartmentOptions options;
options.setVersion(JSVERSION_LATEST);
options.behaviors().setVersion(JSVERSION_LATEST);
newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), nullptr,
JS::FireOnNewGlobalHook, options);
if (!newGlobal)

View File

@ -1809,8 +1809,8 @@ nsMessageManagerScriptExecutor::InitChildGlobalInternal(
const uint32_t flags = nsIXPConnect::INIT_JS_STANDARD_CLASSES;
JS::CompartmentOptions options;
options.setZone(JS::SystemZone)
.setVersion(JSVERSION_LATEST);
options.creationOptions().setZone(JS::SystemZone);
options.behaviors().setVersion(JSVERSION_LATEST);
nsresult rv =
xpc->InitClassesWithNewWrappedGlobal(cx, aScope, mPrincipal,

View File

@ -2325,13 +2325,11 @@ CreateNativeGlobalForInner(JSContext* aCx,
// windows or inside a browser element. In such cases we want to tag the
// window's compartment with the add-on ID. See bug 1092156.
if (nsContentUtils::IsSystemPrincipal(aPrincipal)) {
options.setAddonId(MapURIToAddonID(aURI));
options.creationOptions().setAddonId(MapURIToAddonID(aURI));
}
if (top) {
if (top->GetGlobalJSObject()) {
options.setSameZoneAs(top->GetGlobalJSObject());
}
if (top && top->GetGlobalJSObject()) {
options.creationOptions().setSameZoneAs(top->GetGlobalJSObject());
}
// Determine if we need the Components object.

View File

@ -3048,7 +3048,7 @@ CreateGlobal(JSContext* aCx, T* aNative, nsWrapperCache* aCache,
JSPrincipals* aPrincipal, bool aInitStandardClasses,
JS::MutableHandle<JSObject*> aGlobal)
{
aOptions.setTrace(CreateGlobalOptions<T>::TraceGlobal);
aOptions.creationOptions().setTrace(CreateGlobalOptions<T>::TraceGlobal);
aGlobal.set(JS_NewGlobalObject(aCx, aClass, aPrincipal,
JS::DontFireOnNewGlobalHook, aOptions));

View File

@ -1845,7 +1845,7 @@ RuntimeService::Init()
if (!sDefaultJSSettings.gcSettings[0].IsSet()) {
sDefaultJSSettings.runtimeOptions = JS::RuntimeOptions();
sDefaultJSSettings.chrome.maxScriptRuntime = -1;
sDefaultJSSettings.chrome.compartmentOptions.setVersion(JSVERSION_LATEST);
sDefaultJSSettings.chrome.compartmentOptions.behaviors().setVersion(JSVERSION_LATEST);
sDefaultJSSettings.content.maxScriptRuntime = MAX_SCRIPT_RUN_TIME_SEC;
#ifdef JS_GC_ZEAL
sDefaultJSSettings.gcZealFrequency = JS_DEFAULT_ZEAL_FREQ;
@ -2622,7 +2622,7 @@ RuntimeService::JSVersionChanged(const char* /* aPrefName */, void* /* aClosure
bool useLatest = Preferences::GetBool("dom.workers.latestJSVersion", false);
JS::CompartmentOptions& options = sDefaultJSSettings.content.compartmentOptions;
options.setVersion(useLatest ? JSVERSION_LATEST : JSVERSION_DEFAULT);
options.behaviors().setVersion(useLatest ? JSVERSION_LATEST : JSVERSION_DEFAULT);
}
NS_IMPL_ISUPPORTS_INHERITED0(LogViolationDetailsRunnable, nsRunnable)

View File

@ -432,8 +432,9 @@ DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx,
const bool extraWarnings = usesSystemPrincipal &&
xpc::ExtraWarningsForSystemJS();
options.setDiscardSource(discardSource)
.extraWarningsOverride().set(extraWarnings);
JS::CompartmentBehaviors& behaviors = options.behaviors();
behaviors.setDiscardSource(discardSource)
.extraWarningsOverride().set(extraWarnings);
return DedicatedWorkerGlobalScopeBinding_workers::Wrap(aCx, this, this,
options,
@ -796,7 +797,7 @@ WorkerDebuggerGlobalScope::CreateSandbox(JSContext* aCx, const nsAString& aName,
mWorkerPrivate->AssertIsOnWorkerThread();
JS::CompartmentOptions options;
options.setInvisibleToDebugger(true);
options.creationOptions().setInvisibleToDebugger(true);
JS::Rooted<JSObject*> sandbox(aCx,
JS_NewGlobalObject(aCx, js::Jsvalify(&workerdebuggersandbox_class), nullptr,

View File

@ -514,8 +514,9 @@ XPCShellEnvironment::Init()
}
JS::CompartmentOptions options;
options.setZone(JS::SystemZone)
.setVersion(JSVERSION_LATEST);
options.creationOptions().setZone(JS::SystemZone);
options.behaviors().setVersion(JSVERSION_LATEST);
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = xpc->InitClassesWithNewWrappedGlobal(cx,
static_cast<nsIGlobalObject *>(backstagePass),

View File

@ -2753,7 +2753,7 @@ SetLazyParsingDisabled(JSContext* cx, unsigned argc, Value* vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool disable = !args.hasDefined(0) || ToBoolean(args[0]);
JS::CompartmentOptionsRef(cx->compartment()).setDisableLazyParsing(disable);
cx->compartment()->behaviors().setDisableLazyParsing(disable);
args.rval().setUndefined();
return true;
@ -2765,7 +2765,7 @@ SetDiscardSource(JSContext* cx, unsigned argc, Value* vp)
CallArgs args = CallArgsFromVp(argc, vp);
bool discard = !args.hasDefined(0) || ToBoolean(args[0]);
JS::CompartmentOptionsRef(cx->compartment()).setDiscardSource(discard);
cx->compartment()->behaviors().setDiscardSource(discard);
args.rval().setUndefined();
return true;

View File

@ -199,7 +199,7 @@ BytecodeCompiler::maybeCompressSource()
sourceCompressor = maybeSourceCompressor.ptr();
}
if (!cx->compartment()->options().discardSource()) {
if (!cx->compartment()->behaviors().discardSource()) {
if (options.sourceIsLazy) {
scriptSource->setSourceRetrievable();
} else if (!scriptSource->setSourceCopy(cx, sourceBuffer, sourceArgumentsNotIncluded,
@ -217,8 +217,8 @@ BytecodeCompiler::canLazilyParse()
{
return options.canLazilyParse &&
!HasNonSyntacticStaticScopeChain(enclosingStaticScope) &&
!cx->compartment()->options().disableLazyParsing() &&
!cx->compartment()->options().discardSource() &&
!cx->compartment()->behaviors().disableLazyParsing() &&
!cx->compartment()->behaviors().discardSource() &&
!options.sourceIsLazy &&
!cx->lcovEnabled();
}

View File

@ -60,7 +60,7 @@ void breakpoint() {
GDBFragment* GDBFragment::allFragments = nullptr;
int
main (int argc, const char** argv)
main(int argc, const char** argv)
{
if (!JS_Init()) return 1;
JSRuntime* runtime = checkPtr(JS_NewRuntime(1024 * 1024));
@ -74,7 +74,8 @@ main (int argc, const char** argv)
/* Create the global object. */
JS::CompartmentOptions options;
options.setVersion(JSVERSION_LATEST);
options.behaviors().setVersion(JSVERSION_LATEST);
RootedObject global(cx, checkPtr(JS_NewGlobalObject(cx, &global_class,
nullptr, JS::FireOnNewGlobalHook, options)));
JSAutoCompartment ac(cx, global);

View File

@ -1491,7 +1491,8 @@ static const VMFunction DeepCloneObjectLiteralInfo =
bool
BaselineCompiler::emit_JSOP_OBJECT()
{
if (JS::CompartmentOptionsRef(cx).cloneSingletons()) {
JSCompartment* comp = cx->compartment();
if (comp->creationOptions().cloneSingletons()) {
RootedObject obj(cx, script->getObject(GET_UINT32_INDEX(pc)));
if (!obj)
return false;
@ -1510,7 +1511,7 @@ BaselineCompiler::emit_JSOP_OBJECT()
return true;
}
JS::CompartmentOptionsRef(cx).setSingletonsAsValues();
comp->behaviors().setSingletonsAsValues();
frame.push(ObjectValue(*script->getObject(pc)));
return true;
}

View File

@ -284,7 +284,7 @@ CompileCompartment::hasObjectMetadataCallback()
void
CompileCompartment::setSingletonsAsValues()
{
return JS::CompartmentOptionsRef(compartment()).setSingletonsAsValues();
compartment()->behaviors().setSingletonsAsValues();
}
JitCompileOptions::JitCompileOptions()
@ -296,8 +296,7 @@ JitCompileOptions::JitCompileOptions()
JitCompileOptions::JitCompileOptions(JSContext* cx)
{
JS::CompartmentOptions& options = cx->compartment()->options();
cloneSingletons_ = options.cloneSingletons();
cloneSingletons_ = cx->compartment()->creationOptions().cloneSingletons();
spsSlowAssertionsEnabled_ = cx->runtime()->spsProfiler.enabled() &&
cx->runtime()->spsProfiler.slowAssertionsEnabled();
offThreadCompilationAvailable_ = OffThreadCompilationAvailable(cx);

View File

@ -31,7 +31,6 @@ BEGIN_TEST(testRedefineGlobalEval)
/* Create the global object. */
JS::CompartmentOptions options;
options.setVersion(JSVERSION_LATEST);
JS::Rooted<JSObject*> g(cx, JS_NewGlobalObject(cx, &cls, nullptr, JS::FireOnNewGlobalHook, options));
if (!g)
return false;

View File

@ -123,7 +123,6 @@ BEGIN_TEST(testGCFinalizeCallback)
JSObject* createTestGlobal()
{
JS::CompartmentOptions options;
options.setVersion(JSVERSION_LATEST);
return JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook, options);
}

View File

@ -90,8 +90,8 @@ JSObject*
createTestGlobal(bool preserveJitCode)
{
JS::CompartmentOptions options;
options.setVersion(JSVERSION_LATEST);
options.setPreserveJitCode(preserveJitCode);
options.creationOptions().setPreserveJitCode(preserveJitCode);
options.behaviors().setVersion(JSVERSION_LATEST);
return JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook, options);
}
END_TEST(test_PreserveJitCode)

View File

@ -9,24 +9,32 @@
BEGIN_TEST(testBug795104)
{
JS::CompileOptions opts(cx);
JS::CompartmentOptionsRef(cx->compartment()).setDiscardSource(true);
JS::CompartmentBehaviorsRef(cx->compartment()).setDiscardSource(true);
const size_t strLen = 60002;
char* s = static_cast<char*>(JS_malloc(cx, strLen));
CHECK(s);
s[0] = '"';
memset(s + 1, 'x', strLen - 2);
s[strLen - 1] = '"';
// We don't want an rval for our Evaluate call
opts.setNoScriptRval(true);
JS::RootedValue unused(cx);
CHECK(JS::Evaluate(cx, opts, s, strLen, &unused));
JS::RootedFunction fun(cx);
JS::AutoObjectVector emptyScopeChain(cx);
// But when compiling a function we don't want to use no-rval
// mode, since it's not supported for functions.
opts.setNoScriptRval(false);
CHECK(JS::CompileFunction(cx, emptyScopeChain, opts, "f", 0, nullptr, s, strLen, &fun));
CHECK(fun);
JS_free(cx, s);
return true;

View File

@ -230,12 +230,14 @@ JSObject* newDelegate()
/* Create the global object. */
JS::CompartmentOptions options;
options.setVersion(JSVERSION_LATEST);
JS::RootedObject global(cx);
global = JS_NewGlobalObject(cx, Jsvalify(&delegateClass), nullptr, JS::FireOnNewGlobalHook,
options);
JS_SetReservedSlot(global, 0, JS::Int32Value(42));
options.behaviors().setVersion(JSVERSION_LATEST);
JS::RootedObject global(cx, JS_NewGlobalObject(cx, Jsvalify(&delegateClass), nullptr,
JS::FireOnNewGlobalHook, options));
if (!global)
return nullptr;
JS_SetReservedSlot(global, 0, JS::Int32Value(42));
return global;
}

View File

@ -74,12 +74,12 @@ bool JSAPITest::definePrint()
return JS_DefineFunction(cx, global, "print", (JSNative) print, 0, 0);
}
JSObject * JSAPITest::createGlobal(JSPrincipals* principals)
JSObject* JSAPITest::createGlobal(JSPrincipals* principals)
{
/* Create the global object. */
JS::RootedObject newGlobal(cx);
JS::CompartmentOptions options;
options.setVersion(JSVERSION_LATEST);
options.behaviors().setVersion(JSVERSION_LATEST);
newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), principals, JS::FireOnNewGlobalHook,
options);
if (!newGlobal)
@ -87,8 +87,8 @@ JSObject * JSAPITest::createGlobal(JSPrincipals* principals)
JSAutoCompartment ac(cx, newGlobal);
/* Populate the global object with the standard globals, like Object and
Array. */
// Populate the global object with the standard globals like Object and
// Array.
if (!JS_InitStandardClasses(cx, newGlobal))
return nullptr;

View File

@ -637,7 +637,7 @@ JS_GetVersion(JSContext* cx)
JS_PUBLIC_API(void)
JS_SetVersionForCompartment(JSCompartment* compartment, JSVersion version)
{
compartment->options().setVersion(version);
compartment->behaviors().setVersion(version);
}
static const struct v2smap {
@ -827,7 +827,7 @@ JS::StringOfAddonId(JSAddonId* id)
JS_PUBLIC_API(JSAddonId*)
JS::AddonIdOfObject(JSObject* obj)
{
return obj->compartment()->addonId;
return obj->compartment()->creationOptions().addonIdOrNull();
}
JS_PUBLIC_API(void)
@ -1795,47 +1795,65 @@ JS_GetConstructor(JSContext* cx, HandleObject proto)
}
bool
JS::CompartmentOptions::extraWarnings(JSRuntime* rt) const
JS::CompartmentBehaviors::extraWarnings(JSRuntime* rt) const
{
return extraWarningsOverride_.get(rt->options().extraWarnings());
}
bool
JS::CompartmentOptions::extraWarnings(JSContext* cx) const
JS::CompartmentBehaviors::extraWarnings(JSContext* cx) const
{
return extraWarnings(cx->runtime());
}
JS::CompartmentOptions&
JS::CompartmentOptions::setZone(ZoneSpecifier spec)
JS::CompartmentCreationOptions&
JS::CompartmentCreationOptions::setZone(ZoneSpecifier spec)
{
zone_.spec = spec;
return *this;
}
JS::CompartmentOptions&
JS::CompartmentOptions::setSameZoneAs(JSObject* obj)
JS::CompartmentCreationOptions&
JS::CompartmentCreationOptions::setSameZoneAs(JSObject* obj)
{
zone_.pointer = static_cast<void*>(obj->zone());
return *this;
}
JS::CompartmentOptions&
JS::CompartmentOptionsRef(JSCompartment* compartment)
const JS::CompartmentCreationOptions&
JS::CompartmentCreationOptionsRef(JSCompartment* compartment)
{
return compartment->options();
return compartment->creationOptions();
}
JS::CompartmentOptions&
JS::CompartmentOptionsRef(JSObject* obj)
const JS::CompartmentCreationOptions&
JS::CompartmentCreationOptionsRef(JSObject* obj)
{
return obj->compartment()->options();
return obj->compartment()->creationOptions();
}
JS::CompartmentOptions&
JS::CompartmentOptionsRef(JSContext* cx)
const JS::CompartmentCreationOptions&
JS::CompartmentCreationOptionsRef(JSContext* cx)
{
return cx->compartment()->options();
return cx->compartment()->creationOptions();
}
JS::CompartmentBehaviors&
JS::CompartmentBehaviorsRef(JSCompartment* compartment)
{
return compartment->behaviors();
}
JS::CompartmentBehaviors&
JS::CompartmentBehaviorsRef(JSObject* obj)
{
return obj->compartment()->behaviors();
}
JS::CompartmentBehaviors&
JS::CompartmentBehaviorsRef(JSContext* cx)
{
return cx->compartment()->behaviors();
}
JS_PUBLIC_API(JSObject*)
@ -1865,8 +1883,7 @@ JS_GlobalObjectTraceHook(JSTracer* trc, JSObject* global)
// compartment is live.
global->compartment()->trace(trc);
JSTraceOp trace = global->compartment()->options().getTrace();
if (trace)
if (JSTraceOp trace = global->compartment()->creationOptions().getTrace())
trace(trc, global);
}
@ -3897,7 +3914,7 @@ JS::CompileOptions::CompileOptions(JSContext* cx, JSVersion version)
this->version = (version != JSVERSION_UNKNOWN) ? version : cx->findVersion();
strictOption = cx->runtime()->options().strictMode();
extraWarningsOption = cx->compartment()->options().extraWarnings(cx);
extraWarningsOption = cx->compartment()->behaviors().extraWarnings(cx);
werrorOption = cx->runtime()->options().werror();
if (!cx->runtime()->options().asmJS())
asmJSOption = AsmJSOption::Disabled;

View File

@ -2163,7 +2163,104 @@ enum ZoneSpecifier {
SystemZone = 1
};
class JS_PUBLIC_API(CompartmentOptions)
/**
* CompartmentCreationOptions specifies options relevant to creating a new
* compartment, that are either immutable characteristics of that compartment
* or that are discarded after the compartment has been created.
*
* Access to these options on an existing compartment is read-only: if you
* need particular selections, make them before you create the compartment.
*/
class JS_PUBLIC_API(CompartmentCreationOptions)
{
public:
CompartmentCreationOptions()
: addonId_(nullptr),
traceGlobal_(nullptr),
invisibleToDebugger_(false),
mergeable_(false),
preserveJitCode_(false),
cloneSingletons_(false)
{
zone_.spec = JS::FreshZone;
}
// A null add-on ID means that the compartment is not associated with an
// add-on.
JSAddonId* addonIdOrNull() const { return addonId_; }
CompartmentCreationOptions& setAddonId(JSAddonId* id) {
addonId_ = id;
return *this;
}
JSTraceOp getTrace() const {
return traceGlobal_;
}
CompartmentCreationOptions& setTrace(JSTraceOp op) {
traceGlobal_ = op;
return *this;
}
void* zonePointer() const {
MOZ_ASSERT(uintptr_t(zone_.pointer) > uintptr_t(JS::SystemZone));
return zone_.pointer;
}
ZoneSpecifier zoneSpecifier() const { return zone_.spec; }
CompartmentCreationOptions& setZone(ZoneSpecifier spec);
CompartmentCreationOptions& setSameZoneAs(JSObject* obj);
// Certain scopes (i.e. XBL compilation scopes) are implementation details
// of the embedding, and references to them should never leak out to script.
// This flag causes the this compartment to skip firing onNewGlobalObject
// and makes addDebuggee a no-op for this global.
bool invisibleToDebugger() const { return invisibleToDebugger_; }
CompartmentCreationOptions& setInvisibleToDebugger(bool flag) {
invisibleToDebugger_ = flag;
return *this;
}
// Compartments used for off-thread compilation have their contents merged
// into a target compartment when the compilation is finished. This is only
// allowed if this flag is set. The invisibleToDebugger flag must also be
// set for such compartments.
bool mergeable() const { return mergeable_; }
CompartmentCreationOptions& setMergeable(bool flag) {
mergeable_ = flag;
return *this;
}
// Determines whether this compartment should preserve JIT code on
// non-shrinking GCs.
bool preserveJitCode() const { return preserveJitCode_; }
CompartmentCreationOptions& setPreserveJitCode(bool flag) {
preserveJitCode_ = flag;
return *this;
}
bool cloneSingletons() const { return cloneSingletons_; }
CompartmentCreationOptions& setCloneSingletons(bool flag) {
cloneSingletons_ = flag;
return *this;
}
private:
JSAddonId* addonId_;
JSTraceOp traceGlobal_;
union {
ZoneSpecifier spec;
void* pointer; // js::Zone* is not exposed in the API.
} zone_;
bool invisibleToDebugger_;
bool mergeable_;
bool preserveJitCode_;
bool cloneSingletons_;
};
/**
* CompartmentBehaviors specifies behaviors of a compartment that can be
* changed after the compartment's been created.
*/
class JS_PUBLIC_API(CompartmentBehaviors)
{
public:
class Override {
@ -2194,140 +2291,120 @@ class JS_PUBLIC_API(CompartmentOptions)
Mode mode_;
};
explicit CompartmentOptions()
CompartmentBehaviors()
: version_(JSVERSION_UNKNOWN)
, invisibleToDebugger_(false)
, mergeable_(false)
, discardSource_(false)
, disableLazyParsing_(false)
, cloneSingletons_(false)
, traceGlobal_(nullptr)
, singletonsAsTemplates_(true)
, addonId_(nullptr)
, preserveJitCode_(false)
{
zone_.spec = JS::FreshZone;
}
JSVersion version() const { return version_; }
CompartmentOptions& setVersion(JSVersion aVersion) {
CompartmentBehaviors& setVersion(JSVersion aVersion) {
MOZ_ASSERT(aVersion != JSVERSION_UNKNOWN);
version_ = aVersion;
return *this;
}
// Certain scopes (i.e. XBL compilation scopes) are implementation details
// of the embedding, and references to them should never leak out to script.
// This flag causes the this compartment to skip firing onNewGlobalObject
// and makes addDebuggee a no-op for this global.
bool invisibleToDebugger() const { return invisibleToDebugger_; }
CompartmentOptions& setInvisibleToDebugger(bool flag) {
invisibleToDebugger_ = flag;
return *this;
}
// Compartments used for off-thread compilation have their contents merged
// into a target compartment when the compilation is finished. This is only
// allowed if this flag is set. The invisibleToDebugger flag must also be
// set for such compartments.
bool mergeable() const { return mergeable_; }
CompartmentOptions& setMergeable(bool flag) {
mergeable_ = flag;
return *this;
}
// For certain globals, we know enough about the code that will run in them
// that we can discard script source entirely.
bool discardSource() const { return discardSource_; }
CompartmentOptions& setDiscardSource(bool flag) {
CompartmentBehaviors& setDiscardSource(bool flag) {
discardSource_ = flag;
return *this;
}
bool disableLazyParsing() const { return disableLazyParsing_; }
CompartmentOptions& setDisableLazyParsing(bool flag) {
CompartmentBehaviors& setDisableLazyParsing(bool flag) {
disableLazyParsing_ = flag;
return *this;
}
bool cloneSingletons() const { return cloneSingletons_; }
CompartmentOptions& setCloneSingletons(bool flag) {
cloneSingletons_ = flag;
return *this;
}
bool extraWarnings(JSRuntime* rt) const;
bool extraWarnings(JSContext* cx) const;
Override& extraWarningsOverride() { return extraWarningsOverride_; }
void* zonePointer() const {
MOZ_ASSERT(uintptr_t(zone_.pointer) > uintptr_t(JS::SystemZone));
return zone_.pointer;
}
ZoneSpecifier zoneSpecifier() const { return zone_.spec; }
CompartmentOptions& setZone(ZoneSpecifier spec);
CompartmentOptions& setSameZoneAs(JSObject* obj);
void setSingletonsAsValues() {
singletonsAsTemplates_ = false;
}
bool getSingletonsAsTemplates() const {
return singletonsAsTemplates_;
}
// A null add-on ID means that the compartment is not associated with an
// add-on.
JSAddonId* addonIdOrNull() const { return addonId_; }
CompartmentOptions& setAddonId(JSAddonId* id) {
addonId_ = id;
return *this;
}
CompartmentOptions& setTrace(JSTraceOp op) {
traceGlobal_ = op;
return *this;
}
JSTraceOp getTrace() const {
return traceGlobal_;
}
bool preserveJitCode() const { return preserveJitCode_; }
CompartmentOptions& setPreserveJitCode(bool flag) {
preserveJitCode_ = flag;
CompartmentBehaviors& setSingletonsAsValues() {
singletonsAsTemplates_ = false;
return *this;
}
private:
JSVersion version_;
bool invisibleToDebugger_;
bool mergeable_;
bool discardSource_;
bool disableLazyParsing_;
bool cloneSingletons_;
Override extraWarningsOverride_;
union {
ZoneSpecifier spec;
void* pointer; // js::Zone* is not exposed in the API.
} zone_;
JSTraceOp traceGlobal_;
// To XDR singletons, we need to ensure that all singletons are all used as
// templates, by making JSOP_OBJECT return a clone of the JSScript
// singleton, instead of returning the value which is baked in the JSScript.
bool singletonsAsTemplates_;
JSAddonId* addonId_;
bool preserveJitCode_;
};
JS_PUBLIC_API(CompartmentOptions&)
CompartmentOptionsRef(JSCompartment* compartment);
/**
* CompartmentOptions specifies compartment characteristics: both those that
* can't be changed on a compartment once it's been created
* (CompartmentCreationOptions), and those that can be changed on an existing
* compartment (CompartmentBehaviors).
*/
class JS_PUBLIC_API(CompartmentOptions)
{
public:
explicit CompartmentOptions()
: creationOptions_(),
behaviors_()
{}
JS_PUBLIC_API(CompartmentOptions&)
CompartmentOptionsRef(JSObject* obj);
CompartmentOptions(const CompartmentCreationOptions& compartmentCreation,
const CompartmentBehaviors& compartmentBehaviors)
: creationOptions_(compartmentCreation),
behaviors_(compartmentBehaviors)
{}
JS_PUBLIC_API(CompartmentOptions&)
CompartmentOptionsRef(JSContext* cx);
// CompartmentCreationOptions specify fundamental compartment
// characteristics that must be specified when the compartment is created,
// that can't be changed after the compartment is created.
CompartmentCreationOptions& creationOptions() {
return creationOptions_;
}
const CompartmentCreationOptions& creationOptions() const {
return creationOptions_;
}
// CompartmentBehaviors specify compartment characteristics that can be
// changed after the compartment is created.
CompartmentBehaviors& behaviors() {
return behaviors_;
}
const CompartmentBehaviors& behaviors() const {
return behaviors_;
}
private:
CompartmentCreationOptions creationOptions_;
CompartmentBehaviors behaviors_;
};
JS_PUBLIC_API(const CompartmentCreationOptions&)
CompartmentCreationOptionsRef(JSCompartment* compartment);
JS_PUBLIC_API(const CompartmentCreationOptions&)
CompartmentCreationOptionsRef(JSObject* obj);
JS_PUBLIC_API(const CompartmentCreationOptions&)
CompartmentCreationOptionsRef(JSContext* cx);
JS_PUBLIC_API(CompartmentBehaviors&)
CompartmentBehaviorsRef(JSCompartment* compartment);
JS_PUBLIC_API(CompartmentBehaviors&)
CompartmentBehaviorsRef(JSObject* obj);
JS_PUBLIC_API(CompartmentBehaviors&)
CompartmentBehaviorsRef(JSContext* cx);
/**
* During global creation, we fire notifications to callbacks registered

View File

@ -398,13 +398,13 @@ checkReportFlags(JSContext* cx, unsigned* flags)
JSScript* script = cx->currentScript(&pc);
if (script && IsCheckStrictOp(JSOp(*pc)))
*flags &= ~JSREPORT_WARNING;
else if (cx->compartment()->options().extraWarnings(cx))
else if (cx->compartment()->behaviors().extraWarnings(cx))
*flags |= JSREPORT_WARNING;
else
return true;
} else if (JSREPORT_IS_STRICT(*flags)) {
/* Warning/error only when JSOPTION_STRICT is set. */
if (!cx->compartment()->options().extraWarnings(cx))
if (!cx->compartment()->behaviors().extraWarnings(cx))
return true;
}
@ -1160,8 +1160,8 @@ JSContext::findVersion() const
if (JSScript* script = currentScript(nullptr, ALLOW_CROSS_COMPARTMENT))
return script->getVersion();
if (compartment() && compartment()->options().version() != JSVERSION_UNKNOWN)
return compartment()->options().version();
if (compartment() && compartment()->behaviors().version() != JSVERSION_UNKNOWN)
return compartment()->behaviors().version();
return runtime()->defaultVersion();
}

View File

@ -41,7 +41,8 @@ using mozilla::DebugOnly;
using mozilla::PodArrayZero;
JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options = JS::CompartmentOptions())
: options_(options),
: creationOptions_(options.creationOptions()),
behaviors_(options.behaviors()),
zone_(zone),
runtime_(zone->runtimeFromMainThread()),
principals_(nullptr),
@ -51,7 +52,6 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options =
warnedAboutFlagsArgument(false),
warnedAboutExprClosure(false),
warnedAboutRegExpMultiline(false),
addonId(options.addonIdOrNull()),
#ifdef DEBUG
firedOnNewGlobalObject(false),
#endif
@ -71,7 +71,6 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options =
lazyArrayBuffers(nullptr),
nonSyntacticLexicalScopes_(nullptr),
gcIncomingGrayPointers(nullptr),
gcPreserveJitCode(options.preserveJitCode()),
debugModeBits(0),
watchpointMap(nullptr),
scriptCountsMap(nullptr),
@ -88,7 +87,8 @@ JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options =
{
PodArrayZero(sawDeprecatedLanguageExtension);
runtime_->numCompartments++;
MOZ_ASSERT_IF(options.mergeable(), options.invisibleToDebugger());
MOZ_ASSERT_IF(creationOptions_.mergeable(),
creationOptions_.invisibleToDebugger());
}
JSCompartment::~JSCompartment()
@ -1148,7 +1148,7 @@ JSCompartment::reportTelemetry()
// Hazard analysis can't tell that the telemetry callbacks don't GC.
JS::AutoSuppressGCAnalysis nogc;
int id = addonId
int id = creationOptions_.addonIdOrNull()
? JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_ADDONS
: JS_TELEMETRY_DEPRECATED_LANGUAGE_EXTENSIONS_IN_CONTENT;
@ -1163,7 +1163,9 @@ void
JSCompartment::addTelemetry(const char* filename, DeprecatedLanguageExtension e)
{
// Only report telemetry for web content and add-ons, not chrome JS.
if (isSystem_ || (!addonId && (!filename || strncmp(filename, "http", 4) != 0)))
if (isSystem_)
return;
if (!creationOptions_.addonIdOrNull() && (!filename || strncmp(filename, "http", 4) != 0))
return;
sawDeprecatedLanguageExtension[e] = true;

View File

@ -223,7 +223,8 @@ class WeakMapBase;
struct JSCompartment
{
JS::CompartmentOptions options_;
const JS::CompartmentCreationOptions creationOptions_;
JS::CompartmentBehaviors behaviors_;
private:
JS::Zone* zone_;
@ -280,10 +281,6 @@ struct JSCompartment
bool warnedAboutExprClosure;
bool warnedAboutRegExpMultiline;
// A null add-on ID means that the compartment is not associated with an
// add-on.
JSAddonId* const addonId;
#ifdef DEBUG
bool firedOnNewGlobalObject;
#endif
@ -312,8 +309,10 @@ 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_; }
const JS::CompartmentCreationOptions& creationOptions() const { return creationOptions_; }
JS::CompartmentBehaviors& behaviors() { return behaviors_; }
const JS::CompartmentBehaviors& behaviors() const { return behaviors_; }
JSRuntime* runtimeFromMainThread() {
MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime_));
@ -473,9 +472,6 @@ struct JSCompartment
JSObject* gcIncomingGrayPointers;
private:
/* Whether to preserve JIT code on non-shrinking GCs. */
bool gcPreserveJitCode;
enum {
IsDebuggee = 1 << 0,
DebuggerObservesAllExecution = 1 << 1,
@ -553,7 +549,8 @@ struct JSCompartment
void traceOutgoingCrossCompartmentWrappers(JSTracer* trc);
static void traceIncomingCrossCompartmentEdgesForZoneGC(JSTracer* trc);
bool preserveJitCode() { return gcPreserveJitCode; }
/* Whether to preserve JIT code on non-shrinking GCs. */
bool preserveJitCode() { return creationOptions_.preserveJitCode(); }
void sweepAfterMinorGC();

View File

@ -727,7 +727,7 @@ ErrorReport::ReportAddonExceptionToTelementry(JSContext* cx)
return;
JSCompartment* comp = stack->compartment();
JSAddonId* addonId = comp->addonId;
JSAddonId* addonId = comp->creationOptions().addonIdOrNull();
// We only want to send the report if the scope that just have thrown belongs to an add-on.
// Let's check the compartment of the youngest function on the stack, to determine that.

View File

@ -6784,9 +6784,11 @@ gc::MergeCompartments(JSCompartment* source, JSCompartment* target)
{
// The source compartment must be specifically flagged as mergable. This
// also implies that the compartment is not visible to the debugger.
MOZ_ASSERT(source->options_.mergeable());
MOZ_ASSERT(source->creationOptions_.mergeable());
MOZ_ASSERT(source->creationOptions_.invisibleToDebugger());
MOZ_ASSERT(source->addonId == target->addonId);
MOZ_ASSERT(source->creationOptions().addonIdOrNull() ==
target->creationOptions().addonIdOrNull());
JSRuntime* rt = source->runtimeFromMainThread();

View File

@ -1275,7 +1275,7 @@ js::DeepCloneObjectLiteral(JSContext* cx, HandleObject obj, NewObjectKind newKin
{
/* NB: Keep this in sync with XDRObjectLiteral. */
MOZ_ASSERT_IF(obj->isSingleton(),
JS::CompartmentOptionsRef(cx).getSingletonsAsTemplates());
cx->compartment()->behaviors().getSingletonsAsTemplates());
MOZ_ASSERT(obj->is<PlainObject>() || obj->is<UnboxedPlainObject>() ||
obj->is<ArrayObject>() || obj->is<UnboxedArrayObject>());
MOZ_ASSERT(newKind != SingletonObject);
@ -1389,7 +1389,7 @@ js::XDRObjectLiteral(XDRState<mode>* xdr, MutableHandleObject obj)
JSContext* cx = xdr->cx();
MOZ_ASSERT_IF(mode == XDR_ENCODE && obj->isSingleton(),
JS::CompartmentOptionsRef(cx).getSingletonsAsTemplates());
cx->compartment()->behaviors().getSingletonsAsTemplates());
// Distinguish between objects and array classes.
uint32_t isArray = 0;

View File

@ -658,8 +658,10 @@ js::XDRScript(XDRState<mode>* xdr, HandleObject enclosingScopeArg, HandleScript
// JSOP_OBJECT that then got modified. So throw if we're not
// cloning in JSOP_OBJECT or if we ever didn't clone in it in the
// past.
const JS::CompartmentOptions& opts = JS::CompartmentOptionsRef(cx);
if (!opts.cloneSingletons() || !opts.getSingletonsAsTemplates()) {
JSCompartment* comp = cx->compartment();
if (!comp->creationOptions().cloneSingletons() ||
!comp->behaviors().getSingletonsAsTemplates())
{
JS_ReportError(cx,
"Can't serialize a run-once non-function script "
"when we're not doing singleton cloning");

View File

@ -1349,14 +1349,14 @@ Evaluate(JSContext* cx, unsigned argc, Value* vp)
{
if (saveBytecode) {
if (!JS::CompartmentOptionsRef(cx).cloneSingletons()) {
if (!JS::CompartmentCreationOptionsRef(cx).cloneSingletons()) {
JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
JSSMSG_CACHE_SINGLETON_FAILED);
return false;
}
// cloneSingletons implies that singletons are used as template objects.
MOZ_ASSERT(JS::CompartmentOptionsRef(cx).getSingletonsAsTemplates());
MOZ_ASSERT(JS::CompartmentBehaviorsRef(cx).getSingletonsAsTemplates());
}
if (loadBytecode) {
@ -2760,7 +2760,7 @@ WorkerMain(void* arg)
JSAutoRequest ar(cx);
JS::CompartmentOptions compartmentOptions;
compartmentOptions.setVersion(JSVERSION_DEFAULT);
compartmentOptions.behaviors().setVersion(JSVERSION_DEFAULT);
RootedObject global(cx, NewGlobalObject(cx, compartmentOptions, nullptr));
if (!global)
break;
@ -3954,33 +3954,38 @@ static bool
NewGlobal(JSContext* cx, unsigned argc, Value* vp)
{
JSPrincipals* principals = nullptr;
JS::CompartmentOptions options;
options.setVersion(JSVERSION_DEFAULT);
JS::CompartmentCreationOptions& creationOptions = options.creationOptions();
JS::CompartmentBehaviors& behaviors = options.behaviors();
behaviors.setVersion(JSVERSION_DEFAULT);
CallArgs args = CallArgsFromVp(argc, vp);
if (args.length() == 1 && args[0].isObject()) {
RootedObject opts(cx, &args[0].toObject());
RootedValue v(cx);
if (!JS_GetProperty(cx, opts, "sameZoneAs", &v))
return false;
if (v.isObject())
options.setSameZoneAs(UncheckedUnwrap(&v.toObject()));
if (!JS_GetProperty(cx, opts, "invisibleToDebugger", &v))
return false;
if (v.isBoolean())
options.setInvisibleToDebugger(v.toBoolean());
creationOptions.setInvisibleToDebugger(v.toBoolean());
if (!JS_GetProperty(cx, opts, "cloneSingletons", &v))
return false;
if (v.isBoolean())
options.setCloneSingletons(v.toBoolean());
creationOptions.setCloneSingletons(v.toBoolean());
if (!JS_GetProperty(cx, opts, "sameZoneAs", &v))
return false;
if (v.isObject())
creationOptions.setSameZoneAs(UncheckedUnwrap(&v.toObject()));
if (!JS_GetProperty(cx, opts, "disableLazyParsing", &v))
return false;
if (v.isBoolean())
options.setDisableLazyParsing(v.toBoolean());
behaviors.setDisableLazyParsing(v.toBoolean());
if (!JS_GetProperty(cx, opts, "principal", &v))
return false;
@ -6508,10 +6513,9 @@ Shell(JSContext* cx, OptionParser* op, char** envp)
if (op->getBoolOption("disable-oom-functions"))
disableOOMFunctions = true;
RootedObject glob(cx);
JS::CompartmentOptions options;
options.setVersion(JSVERSION_DEFAULT);
glob = NewGlobalObject(cx, options, nullptr);
options.behaviors().setVersion(JSVERSION_DEFAULT);
RootedObject glob(cx, NewGlobalObject(cx, options, nullptr));
if (!glob)
return 1;

View File

@ -1661,7 +1661,7 @@ void
Debugger::slowPathOnNewGlobalObject(JSContext* cx, Handle<GlobalObject*> global)
{
MOZ_ASSERT(!JS_CLIST_IS_EMPTY(&cx->runtime()->onNewGlobalObjectWatchers));
if (global->compartment()->options().invisibleToDebugger())
if (global->compartment()->creationOptions().invisibleToDebugger())
return;
/*
@ -3144,7 +3144,7 @@ Debugger::addAllGlobalsAsDebuggees(JSContext* cx, unsigned argc, Value* vp)
THIS_DEBUGGER(cx, argc, vp, "addAllGlobalsAsDebuggees", args, dbg);
for (ZonesIter zone(cx->runtime(), SkipAtoms); !zone.done(); zone.next()) {
for (CompartmentsInZoneIter c(zone); !c.done(); c.next()) {
if (c == dbg->object->compartment() || c->options().invisibleToDebugger())
if (c == dbg->object->compartment() || c->creationOptions().invisibleToDebugger())
continue;
c->scheduledForDestruction = false;
GlobalObject* global = c->maybeGlobal();
@ -3365,7 +3365,7 @@ Debugger::addDebuggeeGlobal(JSContext* cx, Handle<GlobalObject*> global)
// with certain testing aides we expose in the shell, so just make addDebuggee
// throw in that case.
JSCompartment* debuggeeCompartment = global->compartment();
if (debuggeeCompartment->options().invisibleToDebugger()) {
if (debuggeeCompartment->creationOptions().invisibleToDebugger()) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
JSMSG_DEBUG_CANT_DEBUG_GLOBAL);
return false;
@ -4247,7 +4247,7 @@ Debugger::findAllGlobals(JSContext* cx, unsigned argc, Value* vp)
JS::AutoCheckCannotGC nogc;
for (CompartmentsIter c(cx->runtime(), SkipAtoms); !c.done(); c.next()) {
if (c->options().invisibleToDebugger())
if (c->creationOptions().invisibleToDebugger())
continue;
c->scheduledForDestruction = false;
@ -4301,7 +4301,7 @@ Debugger::makeGlobalObjectReference(JSContext* cx, unsigned argc, Value* vp)
// then from it we can reach function objects, scripts, environments, etc.,
// none of which we're ever supposed to see.
JSCompartment* globalCompartment = global->compartment();
if (globalCompartment->options().invisibleToDebugger()) {
if (globalCompartment->creationOptions().invisibleToDebugger()) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
JSMSG_DEBUG_INVISIBLE_COMPARTMENT);
return false;
@ -7802,7 +7802,7 @@ DebuggerObject_unwrap(JSContext* cx, unsigned argc, Value* vp)
// invisible-to-Debugger global. (If our referent is a *wrapper* to such,
// and the wrapper is in a visible compartment, that's fine.)
JSCompartment* unwrappedCompartment = unwrapped->compartment();
if (unwrappedCompartment->options().invisibleToDebugger()) {
if (unwrappedCompartment->creationOptions().invisibleToDebugger()) {
JS_ReportErrorNumber(cx, GetErrorMessage, nullptr,
JSMSG_DEBUG_INVISIBLE_COMPARTMENT);
return false;

View File

@ -117,8 +117,9 @@ class DebuggerWeakMap : private WeakMap<RelocatablePtr<UnbarrieredKey>, Relocata
template<typename KeyInput, typename ValueInput>
bool relookupOrAdd(AddPtr& p, const KeyInput& k, const ValueInput& v) {
MOZ_ASSERT(v->compartment() == this->compartment);
MOZ_ASSERT(!k->compartment()->options_.mergeable());
MOZ_ASSERT_IF(!InvisibleKeysOk, !k->compartment()->options_.invisibleToDebugger());
MOZ_ASSERT(!k->compartment()->creationOptions().mergeable());
MOZ_ASSERT_IF(!InvisibleKeysOk,
!k->compartment()->creationOptions().invisibleToDebugger());
MOZ_ASSERT(!Base::has(k));
if (!incZoneCount(k->zone()))
return false;
@ -1081,7 +1082,7 @@ Debugger::onNewScript(JSContext* cx, HandleScript script)
{
// We early return in slowPathOnNewScript for self-hosted scripts, so we can
// ignore those in our assertion here.
MOZ_ASSERT_IF(!script->compartment()->options().invisibleToDebugger() &&
MOZ_ASSERT_IF(!script->compartment()->creationOptions().invisibleToDebugger() &&
!script->selfHosted(),
script->compartment()->firedOnNewGlobalObject);
if (script->compartment()->isDebuggee())

View File

@ -280,20 +280,21 @@ GlobalObject::new_(JSContext* cx, const Class* clasp, JSPrincipals* principals,
JSRuntime* rt = cx->runtime();
auto zoneSpecifier = options.creationOptions().zoneSpecifier();
Zone* zone;
if (options.zoneSpecifier() == JS::SystemZone)
if (zoneSpecifier == JS::SystemZone)
zone = rt->gc.systemZone;
else if (options.zoneSpecifier() == JS::FreshZone)
else if (zoneSpecifier == JS::FreshZone)
zone = nullptr;
else
zone = static_cast<Zone*>(options.zonePointer());
zone = static_cast<Zone*>(options.creationOptions().zonePointer());
JSCompartment* compartment = NewCompartment(cx, zone, principals, options);
if (!compartment)
return nullptr;
// Lazily create the system zone.
if (!rt->gc.systemZone && options.zoneSpecifier() == JS::SystemZone) {
if (!rt->gc.systemZone && zoneSpecifier == JS::SystemZone) {
rt->gc.systemZone = compartment->zone();
rt->gc.systemZone->isSystem = true;
}

View File

@ -350,20 +350,26 @@ js::StartOffThreadParseScript(JSContext* cx, const ReadOnlyCompileOptions& optio
// which could require barriers on the atoms compartment.
gc::AutoSuppressGC suppress(cx);
JS::CompartmentOptions compartmentOptions(cx->compartment()->options());
compartmentOptions.setZone(JS::FreshZone);
compartmentOptions.setInvisibleToDebugger(true);
compartmentOptions.setMergeable(true);
JSCompartment* currentCompartment = cx->compartment();
JS::CompartmentOptions compartmentOptions(currentCompartment->creationOptions(),
currentCompartment->behaviors());
auto& creationOptions = compartmentOptions.creationOptions();
creationOptions.setInvisibleToDebugger(true)
.setMergeable(true)
.setZone(JS::FreshZone);
// Don't falsely inherit the host's global trace hook.
compartmentOptions.setTrace(nullptr);
creationOptions.setTrace(nullptr);
JSObject* global = JS_NewGlobalObject(cx, &parseTaskGlobalClass, nullptr,
JS::FireOnNewGlobalHook, compartmentOptions);
if (!global)
return false;
JS_SetCompartmentPrincipals(global->compartment(), cx->compartment()->principals());
JS_SetCompartmentPrincipals(global->compartment(), currentCompartment->principals());
// Initialize all classes required for parsing while still on the main
// thread, for both the target and the new global so that prototype

View File

@ -2988,13 +2988,13 @@ END_CASE(JSOP_SYMBOL)
CASE(JSOP_OBJECT)
{
ReservedRooted<JSObject*> ref(&rootObject0, script->getObject(REGS.pc));
if (JS::CompartmentOptionsRef(cx).cloneSingletons()) {
if (cx->compartment()->creationOptions().cloneSingletons()) {
JSObject* obj = DeepCloneObjectLiteral(cx, ref, TenuredObject);
if (!obj)
goto error;
PUSH_OBJECT(*obj);
} else {
JS::CompartmentOptionsRef(cx).setSingletonsAsValues();
cx->compartment()->behaviors().setSingletonsAsValues();
PUSH_OBJECT(*ref);
}
}

View File

@ -1822,7 +1822,7 @@ GetNonexistentProperty(JSContext* cx, HandleNativeObject obj, HandleId id,
//
// Don't warn if extra warnings not enabled or for random getprop
// operations.
if (!cx->compartment()->options().extraWarnings(cx))
if (!cx->compartment()->behaviors().extraWarnings(cx))
return true;
jsbytecode* pc;
@ -2001,7 +2001,7 @@ MaybeReportUndeclaredVarAssignment(JSContext* cx, JSString* propname)
// check is needed.
if (IsStrictSetPC(pc))
flags = JSREPORT_ERROR;
else if (cx->compartment()->options().extraWarnings(cx))
else if (cx->compartment()->behaviors().extraWarnings(cx))
flags = JSREPORT_WARNING | JSREPORT_STRICT;
else
return true;

View File

@ -1719,8 +1719,8 @@ JSRuntime::createSelfHostingGlobal(JSContext* cx)
MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
JS::CompartmentOptions options;
options.setDiscardSource(true);
options.setZone(JS::FreshZone);
options.creationOptions().setZone(JS::FreshZone);
options.behaviors().setDiscardSource(true);
JSCompartment* compartment = NewCompartment(cx, nullptr, nullptr, options);
if (!compartment)

View File

@ -542,10 +542,13 @@ mozJSComponentLoader::PrepareObjectForLocation(JSContext* aCx,
NS_ENSURE_SUCCESS(rv, nullptr);
CompartmentOptions options;
options.setZone(SystemZone)
.setVersion(JSVERSION_LATEST)
options.creationOptions()
.setZone(SystemZone)
.setAddonId(aReuseLoaderGlobal ? nullptr : MapURIToAddonID(aURI));
options.behaviors().setVersion(JSVERSION_LATEST);
// Defer firing OnNewGlobalObject until after the __URI__ property has
// been defined so the JS debugger can tell what module the global is
// for

View File

@ -988,16 +988,18 @@ xpc::CreateSandboxObject(JSContext* cx, MutableHandleValue vp, nsISupports* prin
MOZ_ASSERT(principal);
JS::CompartmentOptions compartmentOptions;
if (options.sameZoneAs)
compartmentOptions.setSameZoneAs(js::UncheckedUnwrap(options.sameZoneAs));
else if (options.freshZone)
compartmentOptions.setZone(JS::FreshZone);
else
compartmentOptions.setZone(JS::SystemZone);
compartmentOptions.setInvisibleToDebugger(options.invisibleToDebugger)
.setDiscardSource(options.discardSource)
.setTrace(TraceXPCGlobal);
auto& creationOptions = compartmentOptions.creationOptions();
if (options.sameZoneAs)
creationOptions.setSameZoneAs(js::UncheckedUnwrap(options.sameZoneAs));
else if (options.freshZone)
creationOptions.setZone(JS::FreshZone);
else
creationOptions.setZone(JS::SystemZone);
creationOptions.setInvisibleToDebugger(options.invisibleToDebugger)
.setTrace(TraceXPCGlobal);
// Try to figure out any addon this sandbox should be associated with.
// The addon could have been passed in directly, as part of the metadata,
@ -1011,7 +1013,9 @@ xpc::CreateSandboxObject(JSContext* cx, MutableHandleValue vp, nsISupports* prin
addonId = id;
}
compartmentOptions.setAddonId(addonId);
creationOptions.setAddonId(addonId);
compartmentOptions.behaviors().setDiscardSource(options.discardSource);
const Class* clasp = options.writeToGlobalPrototype
? &SandboxWriteToProtoClass

View File

@ -1478,8 +1478,8 @@ XRE_XPCShellMain(int argc, char** argv, char** envp)
// Make the default XPCShell global use a fresh zone (rather than the
// System Zone) to improve cross-zone test coverage.
JS::CompartmentOptions options;
options.setZone(JS::FreshZone)
.setVersion(JSVERSION_LATEST);
options.creationOptions().setZone(JS::FreshZone);
options.behaviors().setVersion(JSVERSION_LATEST);
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = xpc->InitClassesWithNewWrappedGlobal(cx,
static_cast<nsIGlobalObject*>(backstagePass),
@ -1504,7 +1504,7 @@ XRE_XPCShellMain(int argc, char** argv, char** envp)
// Even if we're building in a configuration where source is
// discarded, there's no reason to do that on XPCShell, and doing so
// might break various automation scripts.
JS::CompartmentOptionsRef(glob).setDiscardSource(false);
JS::CompartmentBehaviorsRef(glob).setDiscardSource(false);
backstagePass->SetGlobalObject(glob);

View File

@ -182,7 +182,7 @@ XPCWrappedNative::WrapNewGlobal(xpcObjectHelper& nativeHelper,
MOZ_ASSERT(clasp->flags & JSCLASS_IS_GLOBAL);
// Create the global.
aOptions.setTrace(XPCWrappedNative::Trace);
aOptions.creationOptions().setTrace(XPCWrappedNative::Trace);
RootedObject global(cx, xpc::CreateGlobalObject(cx, clasp, principal, aOptions));
if (!global)
return NS_ERROR_FAILURE;

View File

@ -411,14 +411,14 @@ InitGlobalObject(JSContext* aJSContext, JS::Handle<JSObject*> aGlobal, uint32_t
isSystem = status == nsIPrincipal::APP_STATUS_PRIVILEGED ||
status == nsIPrincipal::APP_STATUS_CERTIFIED;
}
JS::CompartmentOptionsRef(aGlobal).setDiscardSource(isSystem);
JS::CompartmentBehaviorsRef(aGlobal).setDiscardSource(isSystem);
}
if (ExtraWarningsForSystemJS()) {
nsIPrincipal* prin = GetObjectPrincipal(aGlobal);
bool isSystem = nsContentUtils::IsSystemPrincipal(prin);
if (isSystem)
JS::CompartmentOptionsRef(aGlobal).extraWarningsOverride().set(true);
JS::CompartmentBehaviorsRef(aGlobal).extraWarningsOverride().set(true);
}
// Stuff coming through this path always ends up as a DOM global.

View File

@ -646,8 +646,8 @@ private:
JSAutoRequest ar(mContext);
JS::CompartmentOptions options;
options.setZone(JS::SystemZone)
.setVersion(JSVERSION_LATEST);
options.creationOptions().setZone(JS::SystemZone);
options.behaviors().setVersion(JSVERSION_LATEST);
mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, nullptr,
JS::DontFireOnNewGlobalHook, options);
NS_ENSURE_TRUE(mGlobal, NS_ERROR_OUT_OF_MEMORY);

View File

@ -93,7 +93,7 @@ CreateGlobalAndRunTest(JSRuntime* rt, JSContext* cx)
};
JS::CompartmentOptions options;
options.setVersion(JSVERSION_LATEST);
options.behaviors().setVersion(JSVERSION_LATEST);
JS::PersistentRootedObject global(cx);
global = JS_NewGlobalObject(cx, &GlobalClass, nullptr, JS::FireOnNewGlobalHook, options);
ASSERT_TRUE(global != nullptr);