void InitGlobalObjectOptions(JS::CompartmentOptions& aOptions, nsIPrincipal* aPrincipal) { bool shouldDiscardSystemSource = ShouldDiscardSystemSource(); bool extraWarningsForSystemJS = ExtraWarningsForSystemJS(); bool isSystem = nsContentUtils::IsSystemPrincipal(aPrincipal); if (isSystem) { // Make sure [SecureContext] APIs are visible: aOptions.creationOptions().setSecureContext(true); } short status = aPrincipal->GetAppStatus(); // Enable the ECMA-402 experimental formatToParts in certified apps. if (status == nsIPrincipal::APP_STATUS_CERTIFIED) { aOptions.creationOptions() .setExperimentalDateTimeFormatFormatToPartsEnabled(true); } if (shouldDiscardSystemSource) { bool discardSource = isSystem || (status == nsIPrincipal::APP_STATUS_PRIVILEGED || status == nsIPrincipal::APP_STATUS_CERTIFIED); aOptions.behaviors().setDiscardSource(discardSource); } if (extraWarningsForSystemJS) { if (isSystem) aOptions.behaviors().extraWarningsOverride().set(true); } }
void InitGlobalObjectOptions(JS::CompartmentOptions& aOptions, nsIPrincipal* aPrincipal) { bool shouldDiscardSystemSource = ShouldDiscardSystemSource(); bool extraWarningsForSystemJS = ExtraWarningsForSystemJS(); bool isSystem = nsContentUtils::IsSystemPrincipal(aPrincipal); if (isSystem) { // Make sure [SecureContext] APIs are visible: aOptions.creationOptions().setSecureContext(true); #if 0 // TODO: Reenable in Bug 1288653 // Enable the ECMA-402 experimental formatToParts in any chrome page aOptions.creationOptions() .setExperimentalDateTimeFormatFormatToPartsEnabled(true); #endif } if (shouldDiscardSystemSource) { bool discardSource = isSystem; aOptions.behaviors().setDiscardSource(discardSource); } if (extraWarningsForSystemJS) { if (isSystem) aOptions.behaviors().extraWarningsOverride().set(true); } }
bool DedicatedWorkerGlobalScope::WrapGlobalObject(JSContext* aCx, JS::MutableHandle<JSObject*> aReflector) { mWorkerPrivate->AssertIsOnWorkerThread(); MOZ_ASSERT(!mWorkerPrivate->IsSharedWorker()); JS::CompartmentOptions options; mWorkerPrivate->CopyJSCompartmentOptions(options); const bool usesSystemPrincipal = mWorkerPrivate->UsesSystemPrincipal(); // Note that xpc::ShouldDiscardSystemSource() and // xpc::ExtraWarningsForSystemJS() read prefs that are cached on the main // thread. This is benignly racey. const bool discardSource = usesSystemPrincipal && xpc::ShouldDiscardSystemSource(); const bool extraWarnings = usesSystemPrincipal && xpc::ExtraWarningsForSystemJS(); JS::CompartmentBehaviors& behaviors = options.behaviors(); behaviors.setDiscardSource(discardSource) .extraWarningsOverride().set(extraWarnings); const bool sharedMemoryEnabled = xpc::SharedMemoryEnabled(); JS::CompartmentCreationOptions& creationOptions = options.creationOptions(); creationOptions.setSharedMemoryAndAtomicsEnabled(sharedMemoryEnabled); return DedicatedWorkerGlobalScopeBinding::Wrap(aCx, this, this, options, GetWorkerPrincipal(), true, aReflector); }
JSObject* createTestGlobal(bool preserveJitCode) { JS::CompartmentOptions options; options.creationOptions().setPreserveJitCode(preserveJitCode); return JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook, options); }
JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options = JS::CompartmentOptions()) : creationOptions_(options.creationOptions()), behaviors_(options.behaviors()), zone_(zone), runtime_(zone->runtimeFromAnyThread()), principals_(nullptr), isSystem_(false), isAtomsCompartment_(false), isSelfHosting(false), marked(true), warnedAboutExprClosure(false), warnedAboutStringGenericsMethods(0), #ifdef DEBUG firedOnNewGlobalObject(false), #endif global_(nullptr), enterCompartmentDepth(0), globalHolds(0), performanceMonitoring(runtime_), data(nullptr), realmData(nullptr), allocationMetadataBuilder(nullptr), lastAnimationTime(0), regExps(), arraySpeciesLookup(), globalWriteBarriered(0), detachedTypedObjects(0), objectMetadataState(ImmediateMetadata()), selfHostingScriptSource(nullptr), objectMetadataTable(nullptr), innerViews(zone), lazyArrayBuffers(nullptr), wasm(zone), nonSyntacticLexicalEnvironments_(nullptr), gcIncomingGrayPointers(nullptr), debugModeBits(0), validAccessPtr(nullptr), randomKeyGenerator_(runtime_->forkRandomKeyGenerator()), scriptCountsMap(nullptr), scriptNameMap(nullptr), debugScriptMap(nullptr), debugEnvs(nullptr), enumerators(nullptr), compartmentStats_(nullptr), scheduledForDestruction(false), maybeAlive(true), jitCompartment_(nullptr), mappedArgumentsTemplate_(nullptr), unmappedArgumentsTemplate_(nullptr), iterResultTemplate_(nullptr), lcovOutput() { PodArrayZero(sawDeprecatedLanguageExtension); runtime_->numCompartments++; MOZ_ASSERT_IF(creationOptions_.mergeable(), creationOptions_.invisibleToDebugger()); }
JSCompartment::JSCompartment(Zone* zone, const JS::CompartmentOptions& options = JS::CompartmentOptions()) : creationOptions_(options.creationOptions()), behaviors_(options.behaviors()), zone_(zone), runtime_(zone->runtimeFromMainThread()), principals_(nullptr), isSystem_(false), isSelfHosting(false), marked(true), warnedAboutExprClosure(false), #ifdef DEBUG firedOnNewGlobalObject(false), #endif global_(nullptr), enterCompartmentDepth(0), performanceMonitoring(runtime_), data(nullptr), allocationMetadataBuilder(nullptr), lastAnimationTime(0), regExps(runtime_), globalWriteBarriered(0), detachedTypedObjects(0), objectMetadataState(ImmediateMetadata()), propertyTree(thisForCtor()), baseShapes(zone, BaseShapeSet()), initialShapes(zone, InitialShapeSet()), selfHostingScriptSource(nullptr), objectMetadataTable(nullptr), lazyArrayBuffers(nullptr), wasmInstances(zone, WasmInstanceObjectSet()), nonSyntacticLexicalScopes_(nullptr), gcIncomingGrayPointers(nullptr), debugModeBits(0), watchpointMap(nullptr), scriptCountsMap(nullptr), debugScriptMap(nullptr), debugScopes(nullptr), enumerators(nullptr), compartmentStats_(nullptr), scheduledForDestruction(false), maybeAlive(true), jitCompartment_(nullptr), mappedArgumentsTemplate_(nullptr), unmappedArgumentsTemplate_(nullptr), lcovOutput() { PodArrayZero(sawDeprecatedLanguageExtension); runtime_->numCompartments++; MOZ_ASSERT_IF(creationOptions_.mergeable(), creationOptions_.invisibleToDebugger()); }
bool XPCShellEnvironment::Init() { nsresult rv; // unbuffer stdout so that output is in the correct order; note that stderr // is unbuffered by default setbuf(stdout, 0); AutoSafeJSContext cx; mGlobalHolder.init(cx); nsCOMPtr<nsIXPConnect> xpc = do_GetService(nsIXPConnect::GetCID()); if (!xpc) { NS_ERROR("failed to get nsXPConnect service!"); return false; } nsCOMPtr<nsIPrincipal> principal; nsCOMPtr<nsIScriptSecurityManager> securityManager = do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv); if (NS_SUCCEEDED(rv) && securityManager) { rv = securityManager->GetSystemPrincipal(getter_AddRefs(principal)); if (NS_FAILED(rv)) { fprintf(stderr, "+++ Failed to obtain SystemPrincipal from ScriptSecurityManager service.\n"); } } else { fprintf(stderr, "+++ Failed to get ScriptSecurityManager service, running without principals"); } RefPtr<BackstagePass> backstagePass; rv = NS_NewBackstagePass(getter_AddRefs(backstagePass)); if (NS_FAILED(rv)) { NS_ERROR("Failed to create backstage pass!"); return false; } JS::CompartmentOptions options; options.creationOptions().setSystemZone(); options.behaviors().setVersion(JSVERSION_LATEST); if (xpc::SharedMemoryEnabled()) options.creationOptions().setSharedMemoryAndAtomicsEnabled(true); nsCOMPtr<nsIXPConnectJSObjectHolder> holder; rv = xpc->InitClassesWithNewWrappedGlobal(cx, static_cast<nsIGlobalObject *>(backstagePass), principal, 0, options, getter_AddRefs(holder)); if (NS_FAILED(rv)) { NS_ERROR("InitClassesWithNewWrappedGlobal failed!"); return false; } JS::Rooted<JSObject*> globalObj(cx, holder->GetJSObject()); if (!globalObj) { NS_ERROR("Failed to get global JSObject!"); return false; } JSAutoCompartment ac(cx, globalObj); backstagePass->SetGlobalObject(globalObj); JS::Rooted<Value> privateVal(cx, PrivateValue(this)); if (!JS_DefineProperty(cx, globalObj, "__XPCShellEnvironment", privateVal, JSPROP_READONLY | JSPROP_PERMANENT, JS_STUBGETTER, JS_STUBSETTER) || !JS_DefineFunctions(cx, globalObj, gGlobalFunctions) || !JS_DefineProfilingFunctions(cx, globalObj)) { NS_ERROR("JS_DefineFunctions failed!"); return false; } mGlobalHolder = globalObj; FILE* runtimeScriptFile = fopen(kDefaultRuntimeScriptFilename, "r"); if (runtimeScriptFile) { fprintf(stdout, "[loading '%s'...]\n", kDefaultRuntimeScriptFilename); ProcessFile(cx, kDefaultRuntimeScriptFilename, runtimeScriptFile, false); fclose(runtimeScriptFile); } return true; }
// static JSObject* SimpleGlobalObject::Create(GlobalType globalType, JS::Handle<JS::Value> proto) { // We can't root our return value with our AutoJSAPI because the rooting // analysis thinks ~AutoJSAPI can GC. So we need to root in a scope outside // the lifetime of the AutoJSAPI. JS::Rooted<JSObject*> global(RootingCx()); { // Scope to ensure the AutoJSAPI destructor runs before we end up returning AutoJSAPI jsapi; jsapi.Init(); JSContext* cx = jsapi.cx(); JS::CompartmentOptions options; options.creationOptions() .setInvisibleToDebugger(true) // Put our SimpleGlobalObjects in the system zone, so we won't create // lots of zones for what are probably very short-lived // compartments. This should help them be GCed quicker and take up // less memory before they're GCed. .setZone(JS::SystemZone); if (NS_IsMainThread()) { nsCOMPtr<nsIPrincipal> principal = nsNullPrincipal::Create(); options.creationOptions().setTrace(xpc::TraceXPCGlobal); global = xpc::CreateGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass), nsJSPrincipals::get(principal), options); } else { global = JS_NewGlobalObject(cx, js::Jsvalify(&SimpleGlobalClass), nullptr, JS::DontFireOnNewGlobalHook, options); } if (!global) { jsapi.ClearException(); return nullptr; } JSAutoCompartment ac(cx, global); // It's important to create the nsIGlobalObject for our new global before we // start trying to wrap things like the prototype into its compartment, // because the wrap operation relies on the global having its // nsIGlobalObject already. RefPtr<SimpleGlobalObject> globalObject = new SimpleGlobalObject(global, globalType); // Pass on ownership of globalObject to |global|. JS_SetPrivate(global, globalObject.forget().take()); if (proto.isObjectOrNull()) { JS::Rooted<JSObject*> protoObj(cx, proto.toObjectOrNull()); if (!JS_WrapObject(cx, &protoObj)) { jsapi.ClearException(); return nullptr; } if (!JS_SplicePrototype(cx, global, protoObj)) { jsapi.ClearException(); return nullptr; } } else if (!proto.isUndefined()) { // Bogus proto. return nullptr; } JS_FireOnNewGlobalObject(cx, global); } return global; }