mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
7be5030d64
commit
0195fbed46
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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));
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
249
js/src/jsapi.h
249
js/src/jsapi.h
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user