Bug 1461292 part 1 - Rename JSAutoCompartment to JSAutoRealm. r=bz,luke
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 16 May 2018 10:53:16 +0200
changeset 418508 6b6365bdb4c2dd18efdc5a4ee0f4f8b8550f5e8b
parent 418507 83bed828a0d6f8ef077ccb444159c86b9a4b3f38
child 418509 1096b51e73edb8dc98527e9bae274fe8690f1029
push id34004
push usershindli@mozilla.com
push dateWed, 16 May 2018 18:32:17 +0000
treeherdermozilla-central@d5b463283f39 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz, luke
bugs1461292
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1461292 part 1 - Rename JSAutoCompartment to JSAutoRealm. r=bz,luke
devtools/shared/heapsnapshot/tests/gtest/DevTools.h
devtools/shared/heapsnapshot/tests/gtest/DoesCrossCompartmentBoundaries.cpp
devtools/shared/heapsnapshot/tests/gtest/DoesntCrossCompartmentBoundaries.cpp
dom/base/ChromeUtils.cpp
dom/base/CustomElementRegistry.cpp
dom/base/Element.cpp
dom/base/IntlUtils.cpp
dom/base/PostMessageEvent.cpp
dom/base/StructuredCloneBlob.cpp
dom/base/nsContentPermissionHelper.cpp
dom/base/nsContentUtils.cpp
dom/base/nsDocument.cpp
dom/base/nsFrameLoader.cpp
dom/base/nsFrameMessageManager.cpp
dom/base/nsGlobalWindowInner.cpp
dom/base/nsGlobalWindowOuter.cpp
dom/base/nsINode.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsJSUtils.cpp
dom/base/nsJSUtils.h
dom/base/nsNodeUtils.cpp
dom/base/nsObjectLoadingContent.cpp
dom/bindings/BindingUtils.cpp
dom/bindings/BindingUtils.h
dom/bindings/CallbackObject.cpp
dom/bindings/CallbackObject.h
dom/bindings/Codegen.py
dom/bindings/SimpleGlobalObject.cpp
dom/bindings/StructuredClone.cpp
dom/bindings/TypedArray.h
dom/bindings/WebIDLGlobalNameHash.cpp
dom/browser-element/BrowserElementParent.cpp
dom/canvas/WebGLContextUtils.h
dom/clients/manager/ClientOpenWindowUtils.cpp
dom/console/Console.cpp
dom/console/ConsoleUtils.cpp
dom/encoding/TextEncoder.cpp
dom/events/EventListenerManager.cpp
dom/events/EventListenerService.cpp
dom/events/EventListenerService.h
dom/html/nsHTMLDocument.cpp
dom/indexedDB/IDBObjectStore.cpp
dom/indexedDB/IDBRequest.cpp
dom/ipc/ContentChild.cpp
dom/media/webaudio/AudioContext.cpp
dom/network/TCPSocket.cpp
dom/plugins/base/nsJSNPRuntime.cpp
dom/promise/Promise.cpp
dom/promise/PromiseDebugging.cpp
dom/script/ScriptSettings.cpp
dom/serviceworkers/ServiceWorkerPrivate.cpp
dom/workers/WorkerDebugger.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerRunnable.cpp
dom/workers/WorkerScope.cpp
dom/worklet/Worklet.cpp
dom/xbl/nsBindingManager.cpp
dom/xbl/nsXBLBinding.cpp
dom/xbl/nsXBLProtoImpl.cpp
dom/xbl/nsXBLProtoImplField.cpp
dom/xbl/nsXBLProtoImplMethod.cpp
dom/xbl/nsXBLProtoImplProperty.cpp
dom/xbl/nsXBLPrototypeHandler.cpp
dom/xul/XULDocument.cpp
ipc/testshell/XPCShellEnvironment.cpp
js/ductwork/debugger/JSDebugger.cpp
js/ipc/JavaScriptLogging.h
js/ipc/JavaScriptParent.cpp
js/ipc/JavaScriptShared.cpp
js/ipc/WrapperOwner.cpp
js/rust/build.rs
js/rust/src/ac.rs
js/rust/src/rust.rs
js/src/builtin/DataViewObject.cpp
js/src/builtin/MapObject.cpp
js/src/builtin/Promise.cpp
js/src/devtools/rootAnalysis/annotations.js
js/src/fuzz-tests/tests.cpp
js/src/gdb/gdb-tests.cpp
js/src/jsapi-tests/testBug604087.cpp
js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp
js/src/jsapi-tests/testChromeBuffer.cpp
js/src/jsapi-tests/testCloneScript.cpp
js/src/jsapi-tests/testDebugger.cpp
js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp
js/src/jsapi-tests/testGCGrayMarking.cpp
js/src/jsapi-tests/testGCMarking.cpp
js/src/jsapi-tests/testMutedErrors.cpp
js/src/jsapi-tests/testPreserveJitCode.cpp
js/src/jsapi-tests/testScriptObject.cpp
js/src/jsapi-tests/testStructuredClone.cpp
js/src/jsapi-tests/testUbiNode.cpp
js/src/jsapi-tests/testWeakMap.cpp
js/src/jsapi-tests/tests.cpp
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsfriendapi.cpp
js/src/shell/js.cpp
js/src/vm/Debugger.cpp
js/src/vm/JSObject.cpp
js/src/vm/JSScript.cpp
js/src/vm/SavedStacks.cpp
js/src/vm/SelfHosting.cpp
js/src/vm/StructuredClone.cpp
js/src/vm/TypedArrayObject.cpp
js/xpconnect/loader/ChromeScriptLoader.cpp
js/xpconnect/loader/ScriptPreloader.cpp
js/xpconnect/loader/mozJSComponentLoader.cpp
js/xpconnect/loader/mozJSComponentLoader.h
js/xpconnect/loader/mozJSSubScriptLoader.cpp
js/xpconnect/src/ExportHelpers.cpp
js/xpconnect/src/Sandbox.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCShellImpl.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/XPCWrappedNative.cpp
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
js/xpconnect/src/XPCWrappedNativeScope.cpp
js/xpconnect/src/XPCWrapper.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/xpcprivate.h
js/xpconnect/wrappers/WrapperFactory.cpp
js/xpconnect/wrappers/XrayWrapper.cpp
js/xpconnect/wrappers/XrayWrapper.h
netwerk/base/ProxyAutoConfig.cpp
toolkit/components/extensions/MatchPattern.cpp
toolkit/components/mozintl/MozIntlHelper.cpp
--- a/devtools/shared/heapsnapshot/tests/gtest/DevTools.h
+++ b/devtools/shared/heapsnapshot/tests/gtest/DevTools.h
@@ -89,17 +89,17 @@ struct DevTools : public ::testing::Test
     /* Create the global object. */
     JS::RootedObject newGlobal(cx);
     JS::CompartmentOptions options;
     newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), nullptr,
                                    JS::FireOnNewGlobalHook, options);
     if (!newGlobal)
       return nullptr;
 
-    JSAutoCompartment ac(cx, newGlobal);
+    JSAutoRealm ar(cx, newGlobal);
 
     /* Populate the global object with the standard globals, like Object and
        Array. */
     if (!JS_InitStandardClasses(cx, newGlobal))
       return nullptr;
 
     return newGlobal;
   }
--- a/devtools/shared/heapsnapshot/tests/gtest/DoesCrossCompartmentBoundaries.cpp
+++ b/devtools/shared/heapsnapshot/tests/gtest/DoesCrossCompartmentBoundaries.cpp
@@ -13,17 +13,17 @@ DEF_TEST(DoesCrossCompartmentBoundaries,
     JS::RootedObject newGlobal(cx, JS_NewGlobalObject(cx,
                                                       getGlobalClass(),
                                                       nullptr,
                                                       JS::FireOnNewGlobalHook,
                                                       options));
     ASSERT_TRUE(newGlobal);
     JSCompartment* newCompartment = nullptr;
     {
-      JSAutoCompartment ac(cx, newGlobal);
+      JSAutoRealm ar(cx, newGlobal);
       ASSERT_TRUE(JS_InitStandardClasses(cx, newGlobal));
       newCompartment = js::GetContextCompartment(cx);
     }
     ASSERT_TRUE(newCompartment);
     ASSERT_NE(newCompartment, compartment);
 
     // Our set of target compartments is both the old and new compartments.
     JS::CompartmentSet targetCompartments;
--- a/devtools/shared/heapsnapshot/tests/gtest/DoesntCrossCompartmentBoundaries.cpp
+++ b/devtools/shared/heapsnapshot/tests/gtest/DoesntCrossCompartmentBoundaries.cpp
@@ -13,17 +13,17 @@ DEF_TEST(DoesntCrossCompartmentBoundarie
     JS::RootedObject newGlobal(cx, JS_NewGlobalObject(cx,
                                                       getGlobalClass(),
                                                       nullptr,
                                                       JS::FireOnNewGlobalHook,
                                                       options));
     ASSERT_TRUE(newGlobal);
     JSCompartment* newCompartment = nullptr;
     {
-      JSAutoCompartment ac(cx, newGlobal);
+      JSAutoRealm ar(cx, newGlobal);
       ASSERT_TRUE(JS_InitStandardClasses(cx, newGlobal));
       newCompartment = js::GetContextCompartment(cx);
     }
     ASSERT_TRUE(newCompartment);
     ASSERT_NE(newCompartment, compartment);
 
     // Our set of target compartments is only the pre-existing compartment and
     // does not include the new compartment.
--- a/dom/base/ChromeUtils.cpp
+++ b/dom/base/ChromeUtils.cpp
@@ -210,17 +210,17 @@ ChromeUtils::ShallowClone(GlobalObject& 
       return;
     }
 
     if (js::IsScriptedProxy(obj)) {
       JS_ReportErrorASCII(cx, "Shallow cloning a proxy object is not allowed");
       return;
     }
 
-    JSAutoCompartment ac(cx, obj);
+    JSAutoRealm ar(cx, obj);
 
     if (!JS_Enumerate(cx, obj, &ids) ||
         !values.reserve(ids.length())) {
       return;
     }
 
     JS::Rooted<JS::PropertyDescriptor> desc(cx);
     JS::RootedId id(cx);
@@ -233,24 +233,24 @@ ChromeUtils::ShallowClone(GlobalObject& 
         continue;
       }
       values.infallibleAppend(desc.value());
     }
   }
 
   JS::RootedObject obj(cx);
   {
-    Maybe<JSAutoCompartment> ac;
+    Maybe<JSAutoRealm> ar;
     if (aTarget) {
       JS::RootedObject target(cx, js::CheckedUnwrap(aTarget));
       if (!target) {
         js::ReportAccessDenied(cx);
         return;
       }
-      ac.emplace(cx, target);
+      ar.emplace(cx, target);
     }
 
     obj = JS_NewPlainObject(cx);
     if (!obj) {
       return;
     }
 
     JS::RootedValue value(cx);
@@ -476,17 +476,17 @@ namespace module_getter {
     nsresult rv = moduleloader->Import(aCx, uri, &moduleGlobal, &moduleExports);
     if (NS_FAILED(rv)) {
       Throw(aCx, rv);
       return false;
     }
 
     JS::RootedValue value(aCx);
     {
-      JSAutoCompartment ac(aCx, moduleExports);
+      JSAutoRealm ar(aCx, moduleExports);
 
       if (!JS_GetPropertyById(aCx, moduleExports, id, &value)) {
         return false;
       }
     }
 
     if (!JS_WrapValue(aCx, &value) ||
         !JS_DefinePropertyById(aCx, thisObj, id, value,
@@ -723,21 +723,21 @@ ChromeUtils::CreateError(const GlobalObj
   });
 
   JS::RootedObject retVal(cx);
   {
     JS::RootedString fileName(cx, JS_GetEmptyString(cx));
     uint32_t line = 0;
     uint32_t column = 0;
 
-    Maybe<JSAutoCompartment> ac;
+    Maybe<JSAutoRealm> ar;
     JS::RootedObject stack(cx);
     if (aStack) {
       stack = UncheckedUnwrap(aStack);
-      ac.emplace(cx, stack);
+      ar.emplace(cx, stack);
 
       if (JS::GetSavedFrameLine(cx, stack, &line) != JS::SavedFrameResult::Ok ||
           JS::GetSavedFrameColumn(cx, stack, &column) != JS::SavedFrameResult::Ok ||
           JS::GetSavedFrameSource(cx, stack, &fileName) != JS::SavedFrameResult::Ok) {
         return;
       }
     }
 
--- a/dom/base/CustomElementRegistry.cpp
+++ b/dom/base/CustomElementRegistry.cpp
@@ -769,49 +769,49 @@ CustomElementRegistry::Define(const nsAS
   nsAutoPtr<LifecycleCallbacks> callbacksHolder(new LifecycleCallbacks());
   nsTArray<RefPtr<nsAtom>> observedAttributes;
   { // Set mIsCustomDefinitionRunning.
     /**
      * 9. Set this CustomElementRegistry's element definition is running flag.
      */
     AutoSetRunningFlag as(this);
 
-    { // Enter constructor's compartment.
+    { // Enter constructor's realm.
       /**
        * 10.1. Let prototype be Get(constructor, "prototype"). Rethrow any exceptions.
        */
-      JSAutoCompartment ac(cx, constructor);
+      JSAutoRealm ar(cx, constructor);
       // The .prototype on the constructor passed could be an "expando" of a
       // wrapper. So we should get it from wrapper instead of the underlying
       // object.
       if (!JS_GetProperty(cx, constructor, "prototype", &constructorPrototype)) {
         aRv.StealExceptionFromJSContext(cx);
         return;
       }
 
       /**
        * 10.2. If Type(prototype) is not Object, then throw a TypeError exception.
        */
       if (!constructorPrototype.isObject()) {
         aRv.ThrowTypeError<MSG_NOT_OBJECT>(NS_LITERAL_STRING("constructor.prototype"));
         return;
       }
-    } // Leave constructor's compartment.
+    } // Leave constructor's realm.
 
     JS::Rooted<JSObject*> constructorProtoUnwrapped(
       cx, js::CheckedUnwrap(&constructorPrototype.toObject()));
     if (!constructorProtoUnwrapped) {
       // If the caller's compartment does not have permission to access the
       // unwrapped prototype then throw.
       aRv.Throw(NS_ERROR_DOM_SECURITY_ERR);
       return;
     }
 
     { // Enter constructorProtoUnwrapped's compartment
-      JSAutoCompartment ac(cx, constructorProtoUnwrapped);
+      JSAutoRealm ar(cx, constructorProtoUnwrapped);
 
       /**
        * 10.3. Let lifecycleCallbacks be a map with the four keys
        *       "connectedCallback", "disconnectedCallback", "adoptedCallback", and
        *       "attributeChangedCallback", each of which belongs to an entry whose
        *       value is null.
        * 10.4. For each of the four keys callbackName in lifecycleCallbacks:
        *       1. Let callbackValue be Get(prototype, callbackName). Rethrow any
@@ -842,18 +842,18 @@ CustomElementRegistry::Define(const nsAS
        *       1. Let observedAttributesIterable be Get(constructor,
        *          "observedAttributes"). Rethrow any exceptions.
        *       2. If observedAttributesIterable is not undefined, then set
        *          observedAttributes to the result of converting
        *          observedAttributesIterable to a sequence<DOMString>. Rethrow
        *          any exceptions from the conversion.
        */
       if (callbacksHolder->mAttributeChangedCallback.WasPassed()) {
-        // Enter constructor's compartment.
-        JSAutoCompartment ac(cx, constructor);
+        // Enter constructor's realm.
+        JSAutoRealm ar(cx, constructor);
         JS::Rooted<JS::Value> observedAttributesIterable(cx);
 
         if (!JS_GetProperty(cx, constructor, "observedAttributes",
                             &observedAttributesIterable)) {
           aRv.StealExceptionFromJSContext(cx);
           return;
         }
 
@@ -892,17 +892,17 @@ CustomElementRegistry::Define(const nsAS
             }
 
             if (!observedAttributes.AppendElement(NS_Atomize(attrStr))) {
               aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
               return;
             }
           }
         }
-      } // Leave constructor's compartment.
+      } // Leave constructor's realm.
     } // Leave constructorProtoUnwrapped's compartment.
   } // Unset mIsCustomDefinitionRunning
 
   /**
    * 11. Let definition be a new custom element definition with name name,
    *     local name localName, constructor constructor, prototype prototype,
    *     observed attributes observedAttributes, and lifecycle callbacks
    *     lifecycleCallbacks.
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -3679,21 +3679,21 @@ Element::Animate(const Nullable<ElementO
   RefPtr<KeyframeEffect> effect =
     KeyframeEffect::Constructor(global, aTarget, aKeyframes, aOptions,
                                 aError);
   if (aError.Failed()) {
     return nullptr;
   }
 
   // Animation constructor follows the standard Xray calling convention and
-  // needs to be called in the target element's compartment.
-  Maybe<JSAutoCompartment> ac;
+  // needs to be called in the target element's realm.
+  Maybe<JSAutoRealm> ar;
   if (js::GetContextCompartment(aContext) !=
       js::GetObjectCompartment(ownerGlobal->GetGlobalJSObject())) {
-    ac.emplace(aContext, ownerGlobal->GetGlobalJSObject());
+    ar.emplace(aContext, ownerGlobal->GetGlobalJSObject());
   }
 
   AnimationTimeline* timeline = referenceElement->OwnerDoc()->Timeline();
   RefPtr<Animation> animation =
     Animation::Constructor(global, effect,
                            Optional<AnimationTimeline*>(timeline), aError);
   if (aError.Failed()) {
     return nullptr;
--- a/dom/base/IntlUtils.cpp
+++ b/dom/base/IntlUtils.cpp
@@ -83,17 +83,17 @@ IntlUtils::GetDisplayNames(const Sequenc
   }
 
   if (!retVal.isObject()) {
     aError.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   // Return the result as DisplayNameResult.
-  JSAutoCompartment ac(cx, &retVal.toObject());
+  JSAutoRealm ar(cx, &retVal.toObject());
   if (!aResult.Init(cx, retVal)) {
     aError.Throw(NS_ERROR_FAILURE);
   }
 }
 
 void
 IntlUtils::GetLocaleInfo(const Sequence<nsString>& aLocales,
                          LocaleInfo& aResult, ErrorResult& aError)
@@ -130,16 +130,16 @@ IntlUtils::GetLocaleInfo(const Sequence<
   }
 
   if (!retVal.isObject()) {
     aError.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   // Return the result as LocaleInfo.
-  JSAutoCompartment ac(cx, &retVal.toObject());
+  JSAutoRealm ar(cx, &retVal.toObject());
   if (!aResult.Init(cx, retVal)) {
     aError.Throw(NS_ERROR_FAILURE);
   }
 }
 
 } // dom namespace
 } // mozilla namespace
--- a/dom/base/PostMessageEvent.cpp
+++ b/dom/base/PostMessageEvent.cpp
@@ -72,17 +72,17 @@ PostMessageEvent::Run()
   // that's probably better than crashing.
 
   RefPtr<nsGlobalWindowInner> targetWindow;
   if (mTargetWindow->IsClosedOrClosing() ||
       !(targetWindow = mTargetWindow->GetCurrentInnerWindowInternal()) ||
       targetWindow->IsDying())
     return NS_OK;
 
-  JSAutoCompartment ac(cx, targetWindow->GetWrapper());
+  JSAutoRealm ar(cx, targetWindow->GetWrapper());
 
   // Ensure that any origin which might have been provided is the origin of this
   // window's document.  Note that we do this *now* instead of when postMessage
   // is called because the target window might have been navigated to a
   // different location between then and now.  If this check happened when
   // postMessage was called, it would be fairly easy for a malicious webpage to
   // intercept messages intended for another site by carefully timing navigation
   // of the target window so it changed location after postMessage but before
--- a/dom/base/StructuredCloneBlob.cpp
+++ b/dom/base/StructuredCloneBlob.cpp
@@ -33,42 +33,42 @@ StructuredCloneBlob::~StructuredCloneBlo
 StructuredCloneBlob::Constructor(GlobalObject& aGlobal, JS::HandleValue aValue,
                                  JS::HandleObject aTargetGlobal,
                                  ErrorResult& aRv)
 {
   JSContext* cx = aGlobal.Context();
 
   RefPtr<StructuredCloneBlob> holder = StructuredCloneBlob::Create();
 
-  Maybe<JSAutoCompartment> ac;
+  Maybe<JSAutoRealm> ar;
   JS::RootedValue value(cx, aValue);
 
   if (aTargetGlobal) {
     JS::RootedObject targetGlobal(cx, js::CheckedUnwrap(aTargetGlobal));
     if (!targetGlobal) {
       js::ReportAccessDenied(cx);
       aRv.NoteJSContextException(cx);
       return nullptr;
     }
 
-    ac.emplace(cx, targetGlobal);
+    ar.emplace(cx, targetGlobal);
 
     if (!JS_WrapValue(cx, &value)) {
       aRv.NoteJSContextException(cx);
       return nullptr;
     }
   } else if (value.isObject()) {
     JS::RootedObject obj(cx, js::CheckedUnwrap(&value.toObject()));
     if (!obj) {
       js::ReportAccessDenied(cx);
       aRv.NoteJSContextException(cx);
       return nullptr;
     }
 
-    ac.emplace(cx, obj);
+    ar.emplace(cx, obj);
     value = JS::ObjectValue(*obj);
   }
 
   holder->Write(cx, value, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
@@ -82,17 +82,17 @@ StructuredCloneBlob::Deserialize(JSConte
   JS::RootedObject scope(aCx, js::CheckedUnwrap(aTargetScope));
   if (!scope) {
     js::ReportAccessDenied(aCx);
     aRv.NoteJSContextException(aCx);
     return;
   }
 
   {
-    JSAutoCompartment ac(aCx, scope);
+    JSAutoRealm ar(aCx, scope);
 
     Read(xpc::NativeGlobal(scope), aCx, aResult, aRv);
     if (aRv.Failed()) {
       return;
     }
   }
 
   if (!JS_WrapValue(aCx, aResult)) {
--- a/dom/base/nsContentPermissionHelper.cpp
+++ b/dom/base/nsContentPermissionHelper.cpp
@@ -709,17 +709,17 @@ nsContentPermissionRequestProxy::Allow(J
     for (uint32_t i = 0; i < mPermissionRequests.Length(); ++i) {
       nsCString type = mPermissionRequests[i].type();
 
       AutoJSAPI jsapi;
       jsapi.Init();
 
       JSContext* cx = jsapi.cx();
       JS::Rooted<JSObject*> obj(cx, &aChoices.toObject());
-      JSAutoCompartment ac(cx, obj);
+      JSAutoRealm ar(cx, obj);
 
       JS::Rooted<JS::Value> val(cx);
 
       if (!JS_GetProperty(cx, obj, type.BeginReading(), &val) ||
           !val.isString()) {
         // no setting for the permission type, clear exception and skip it
         jsapi.ClearException();
       } else {
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -3118,17 +3118,17 @@ nsContentUtils::SubjectPrincipal()
   JSContext* cx = GetCurrentJSContext();
   if (!cx) {
     MOZ_CRASH("Accessing the Subject Principal without an AutoJSAPI on the stack is forbidden");
   }
 
   JSCompartment *compartment = js::GetContextCompartment(cx);
 
   // When an AutoJSAPI is instantiated, we are in a null compartment until the
-  // first JSAutoCompartment, which is kind of a purgatory as far as permissions
+  // first JSAutoRealm, which is kind of a purgatory as far as permissions
   // go. It would be nice to just hard-abort if somebody does a security check
   // in this purgatory zone, but that would be too fragile, since it could be
   // triggered by random IsCallerChrome() checks 20-levels deep.
   //
   // So we want to return _something_ here - and definitely not the System
   // Principal, since that would make an AutoJSAPI a very dangerous thing to
   // instantiate.
   //
@@ -7066,17 +7066,17 @@ nsContentUtils::IsPatternMatching(nsAStr
 {
   NS_ASSERTION(aDocument, "aDocument should be a valid pointer (not null)");
 
   AutoJSContext cx;
   AutoDisableJSInterruptCallback disabler(cx);
 
   // We can use the junk scope here, because we're just using it for
   // regexp evaluation, not actual script execution.
-  JSAutoCompartment ac(cx, xpc::UnprivilegedJunkScope());
+  JSAutoRealm ar(cx, xpc::UnprivilegedJunkScope());
 
   // The pattern has to match the entire value.
   aPattern.InsertLiteral(u"^(?:", 0);
   aPattern.AppendLiteral(")$");
 
   JS::Rooted<JSObject*> re(cx,
     JS_NewUCRegExpObject(cx,
                          static_cast<char16_t*>(aPattern.BeginWriting()),
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -2619,17 +2619,17 @@ nsIDocument::IsSynthesized() {
   return synthesized;
 }
 
 bool
 nsDocument::IsShadowDOMEnabled(JSContext* aCx, JSObject* aObject)
 {
   JS::Rooted<JSObject*> obj(aCx, aObject);
 
-  JSAutoCompartment ac(aCx, obj);
+  JSAutoRealm ar(aCx, obj);
   JS::Rooted<JSObject*> global(aCx, JS_GetGlobalForObject(aCx, obj));
   nsCOMPtr<nsPIDOMWindowInner> window =
     do_QueryInterface(nsJSUtils::GetStaticScriptGlobal(global));
 
   nsIDocument* doc = window ? window->GetExtantDoc() : nullptr;
   if (!doc) {
     return false;
   }
@@ -7087,17 +7087,17 @@ nsIDocument::AdoptNode(nsINode& aAdopted
   JS::Rooted<JSObject*> newScope(cx, nullptr);
   if (!sameDocument) {
     newScope = GetWrapper();
     if (!newScope && GetScopeObject() && GetScopeObject()->GetGlobalJSObject()) {
       // Make sure cx is in a semi-sane compartment before we call WrapNative.
       // It's kind of irrelevant, given that we're passing aAllowWrapping =
       // false, and documents should always insist on being wrapped in an
       // canonical scope. But we try to pass something sane anyway.
-      JSAutoCompartment ac(cx, GetScopeObject()->GetGlobalJSObject());
+      JSAutoRealm ar(cx, GetScopeObject()->GetGlobalJSObject());
       JS::Rooted<JS::Value> v(cx);
       rv = nsContentUtils::WrapNative(cx, this, this, &v,
                                       /* aAllowWrapping = */ false);
       if (rv.Failed())
         return nullptr;
       newScope = &v.toObject();
     }
   }
@@ -9642,17 +9642,17 @@ nsIDocument::GetStateObject(nsIVariant**
   // current state object.
 
   if (!mStateObjectCached && mStateObjectContainer) {
     AutoJSContext cx;
     nsIGlobalObject* sgo = GetScopeObject();
     NS_ENSURE_TRUE(sgo, NS_ERROR_UNEXPECTED);
     JS::Rooted<JSObject*> global(cx, sgo->GetGlobalJSObject());
     NS_ENSURE_TRUE(global, NS_ERROR_UNEXPECTED);
-    JSAutoCompartment ac(cx, global);
+    JSAutoRealm ar(cx, global);
 
     mStateObjectContainer->
       DeserializeToVariant(cx, getter_AddRefs(mStateObjectCached));
   }
 
   NS_IF_ADDREF(*aState = mStateObjectCached);
   return NS_OK;
 }
--- a/dom/base/nsFrameLoader.cpp
+++ b/dom/base/nsFrameLoader.cpp
@@ -1893,17 +1893,17 @@ nsFrameLoader::SetOwnerContent(Element* 
   }
   mOwnerContent = aContent;
 
   AutoJSAPI jsapi;
   jsapi.Init();
 
   JS::RootedObject wrapper(jsapi.cx(), GetWrapper());
   if (wrapper) {
-    JSAutoCompartment ac(jsapi.cx(), wrapper);
+    JSAutoRealm ar(jsapi.cx(), wrapper);
     IgnoredErrorResult rv;
     ReparentWrapper(jsapi.cx(), wrapper, rv);
     Unused << NS_WARN_IF(rv.Failed());
   }
 
   if (RenderFrameParent* rfp = GetCurrentRenderFrame()) {
     rfp->OwnerContentChanged(aContent);
   }
--- a/dom/base/nsFrameMessageManager.cpp
+++ b/dom/base/nsFrameMessageManager.cpp
@@ -1018,19 +1018,19 @@ nsFrameMessageManager::GetInitialProcess
                                              ErrorResult& aError)
 {
   MOZ_ASSERT(mIsProcessManager);
   MOZ_ASSERT_IF(mChrome, IsBroadcaster());
 
   JS::RootedValue init(aCx, mInitialProcessData);
   if (mChrome && init.isUndefined()) {
     // We create the initial object in the junk scope. If we created it in a
-    // normal compartment, that compartment would leak until shutdown.
+    // normal realm, that realm would leak until shutdown.
     JS::RootedObject global(aCx, xpc::PrivilegedJunkScope());
-    JSAutoCompartment ac(aCx, global);
+    JSAutoRealm ar(aCx, global);
 
     JS::RootedObject obj(aCx, JS_NewPlainObject(aCx));
     if (!obj) {
       aError.NoteJSContextException(aCx);
       return;
     }
 
     mInitialProcessData.setObject(*obj);
--- a/dom/base/nsGlobalWindowInner.cpp
+++ b/dom/base/nsGlobalWindowInner.cpp
@@ -4125,17 +4125,17 @@ nsGlobalWindowInner::CallerInnerWindow()
 
   // When Jetpack runs content scripts inside a sandbox, it uses
   // sandboxPrototype to make them appear as though they're running in the
   // scope of the page. So when a content script invokes postMessage, it expects
   // the |source| of the received message to be the window set as the
   // sandboxPrototype. This used to work incidentally for unrelated reasons, but
   // now we need to do some special handling to support it.
   if (xpc::IsSandbox(scope)) {
-    JSAutoCompartment ac(cx, scope);
+    JSAutoRealm ar(cx, scope);
     JS::Rooted<JSObject*> scopeProto(cx);
     bool ok = JS_GetPrototype(cx, scope, &scopeProto);
     NS_ENSURE_TRUE(ok, nullptr);
     if (scopeProto && xpc::IsSandboxPrototypeProxy(scopeProto) &&
         (scopeProto = js::CheckedUnwrap(scopeProto, /* stopAtWindowProxy = */ false)))
     {
       global = xpc::NativeGlobal(scopeProto);
       NS_ENSURE_TRUE(global, nullptr);
--- a/dom/base/nsGlobalWindowOuter.cpp
+++ b/dom/base/nsGlobalWindowOuter.cpp
@@ -788,17 +788,17 @@ nsChromeOuterWindowProxy::className(JSCo
 }
 
 const nsChromeOuterWindowProxy
 nsChromeOuterWindowProxy::singleton;
 
 static JSObject*
 NewOuterWindowProxy(JSContext *cx, JS::Handle<JSObject*> global, bool isChrome)
 {
-  JSAutoCompartment ac(cx, global);
+  JSAutoRealm ar(cx, global);
   MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(global) == global);
 
   js::WrapperOptions options;
   options.setClass(&OuterWindowProxyClass);
   options.setSingleton(true);
   JSObject *obj = js::Wrapper::New(cx, global,
                                    isChrome ? &nsChromeOuterWindowProxy::singleton
                                             : &nsOuterWindowProxy::singleton,
@@ -1530,17 +1530,17 @@ EnablePrivilege(JSContext* cx, unsigned 
 static const JSFunctionSpec EnablePrivilegeSpec[] = {
   JS_FN("enablePrivilege", EnablePrivilege, 1, 0),
   JS_FS_END
 };
 
 static bool
 InitializeLegacyNetscapeObject(JSContext* aCx, JS::Handle<JSObject*> aGlobal)
 {
-  JSAutoCompartment ac(aCx, aGlobal);
+  JSAutoRealm ar(aCx, aGlobal);
 
   // Note: MathJax depends on window.netscape being exposed. See bug 791526.
   JS::Rooted<JSObject*> obj(aCx);
   obj = JS_DefineObject(aCx, aGlobal, "netscape", nullptr);
   NS_ENSURE_TRUE(obj, false);
 
   obj = JS_DefineObject(aCx, obj, "security", nullptr);
   NS_ENSURE_TRUE(obj, false);
@@ -1867,18 +1867,18 @@ nsGlobalWindowOuter::SetNewDocument(nsID
       SetWrapper(outerObject);
 
       MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(outerObject) == newInnerGlobal);
 
       // Inform the nsJSContext, which is the canonical holder of the outer.
       mContext->SetWindowProxy(outerObject);
     }
 
-    // Enter the new global's compartment.
-    JSAutoCompartment ac(cx, GetWrapperPreserveColor());
+    // Enter the new global's realm.
+    JSAutoRealm ar(cx, GetWrapperPreserveColor());
 
     {
       JS::Rooted<JSObject*> outer(cx, GetWrapperPreserveColor());
       js::SetWindowProxy(cx, newInnerGlobal, outer);
     }
 
     // Set scriptability based on the state of the docshell.
     bool allow = GetDocShell()->GetCanExecuteScripts();
@@ -1900,17 +1900,17 @@ nsGlobalWindowOuter::SetNewDocument(nsID
       // And same thing for the "self" property.
       if (!JS_GetProperty(cx, newInnerGlobal, "self", &unused)) {
         NS_ERROR("can't create the 'self' property");
         return NS_ERROR_FAILURE;
       }
     }
   }
 
-  JSAutoCompartment ac(cx, GetWrapperPreserveColor());
+  JSAutoRealm ar(cx, GetWrapperPreserveColor());
 
   if (!aState && !reUseInnerWindow) {
     // Loading a new page and creating a new inner window, *not*
     // restoring from session history.
 
     // Now that both the the inner and outer windows are initialized
     // let the script context do its magic to hook them together.
     MOZ_ASSERT(mContext->GetWindowProxy() == GetWrapperPreserveColor());
@@ -3803,17 +3803,17 @@ nsGlobalWindowOuter::DispatchResizeEvent
     return false;
   }
 
   // We don't init the AutoJSAPI with ourselves because we don't want it
   // reporting errors to our onerror handlers.
   AutoJSAPI jsapi;
   jsapi.Init();
   JSContext* cx = jsapi.cx();
-  JSAutoCompartment ac(cx, GetWrapperPreserveColor());
+  JSAutoRealm ar(cx, GetWrapperPreserveColor());
 
   DOMWindowResizeEventDetail detail;
   detail.mWidth = aSize.width;
   detail.mHeight = aSize.height;
   JS::Rooted<JS::Value> detailValue(cx);
   if (!ToJSValue(cx, detail, &detailValue)) {
     return false;
   }
@@ -5599,17 +5599,17 @@ nsGlobalWindowOuter::CallerInnerWindow()
 
   // When Jetpack runs content scripts inside a sandbox, it uses
   // sandboxPrototype to make them appear as though they're running in the
   // scope of the page. So when a content script invokes postMessage, it expects
   // the |source| of the received message to be the window set as the
   // sandboxPrototype. This used to work incidentally for unrelated reasons, but
   // now we need to do some special handling to support it.
   if (xpc::IsSandbox(scope)) {
-    JSAutoCompartment ac(cx, scope);
+    JSAutoRealm ar(cx, scope);
     JS::Rooted<JSObject*> scopeProto(cx);
     bool ok = JS_GetPrototype(cx, scope, &scopeProto);
     NS_ENSURE_TRUE(ok, nullptr);
     if (scopeProto && xpc::IsSandboxPrototypeProxy(scopeProto) &&
         (scopeProto = js::CheckedUnwrap(scopeProto, /* stopAtWindowProxy = */ false)))
     {
       global = xpc::NativeGlobal(scopeProto);
       NS_ENSURE_TRUE(global, nullptr);
@@ -7147,17 +7147,17 @@ nsresult
 nsGlobalWindowOuter::SecurityCheckURL(const char *aURL)
 {
   nsCOMPtr<nsPIDOMWindowInner> sourceWindow = do_QueryInterface(GetEntryGlobal());
   if (!sourceWindow) {
     sourceWindow = GetCurrentInnerWindow();
   }
   AutoJSContext cx;
   nsGlobalWindowInner* sourceWin = nsGlobalWindowInner::Cast(sourceWindow);
-  JSAutoCompartment ac(cx, sourceWin->GetGlobalJSObject());
+  JSAutoRealm ar(cx, sourceWin->GetGlobalJSObject());
 
   // Resolve the baseURI, which could be relative to the calling window.
   //
   // Note the algorithm to get the base URI should match the one
   // used to actually kick off the load in nsWindowWatcher.cpp.
   nsCOMPtr<nsIDocument> doc = sourceWindow->GetDoc();
   nsIURI* baseURI = nullptr;
   auto encoding = UTF_8_ENCODING; // default to utf-8
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -1271,17 +1271,17 @@ CheckForOutdatedParent(nsINode* aParent,
     JS::Rooted<JSObject*> existingObj(RootingCx(), existingObjUnrooted);
 
     AutoJSContext cx;
     nsIGlobalObject* global = aParent->OwnerDoc()->GetScopeObject();
     MOZ_ASSERT(global);
 
     if (js::GetGlobalForObjectCrossCompartment(existingObj) !=
         global->GetGlobalJSObject()) {
-      JSAutoCompartment ac(cx, existingObj);
+      JSAutoRealm ar(cx, existingObj);
       ReparentWrapper(cx, existingObj, aError);
     }
   }
 }
 
 nsresult
 nsINode::doInsertChildAt(nsIContent* aKid, uint32_t aIndex,
                          bool aNotify, nsAttrAndChildArray& aChildArray)
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -788,17 +788,17 @@ nsJSContext::ConvertSupportsTojsvals(nsI
           // just wrap it.
 #ifdef DEBUG
           // but first, check its not another nsISupportsPrimitive, as
           // these are now deprecated for use with script contexts.
           nsCOMPtr<nsISupportsPrimitive> prim(do_QueryInterface(arg));
           NS_ASSERTION(prim == nullptr,
                        "Don't pass nsISupportsPrimitives - use nsIVariant!");
 #endif
-          JSAutoCompartment ac(cx, aScope);
+          JSAutoRealm ar(cx, aScope);
           rv = nsContentUtils::WrapNative(cx, arg, thisVal);
         }
       }
     }
   } else {
     nsCOMPtr<nsIVariant> variant = do_QueryInterface(aArgs);
     if (variant) {
       rv = xpc->VariantToJS(cx, aScope, variant, aArgsOut[0]);
@@ -979,17 +979,17 @@ nsJSContext::AddSupportsPrimitiveTojsval
       p->GetData(getter_AddRefs(data));
       p->GetDataIID(&iid);
       NS_ENSURE_TRUE(iid, NS_ERROR_UNEXPECTED);
 
       AutoFree iidGuard(iid); // Free iid upon destruction.
 
       JS::Rooted<JSObject*> scope(cx, GetWindowProxy());
       JS::Rooted<JS::Value> v(cx);
-      JSAutoCompartment ac(cx, scope);
+      JSAutoRealm ar(cx, scope);
       nsresult rv = nsContentUtils::WrapNative(cx, data, iid, &v);
       NS_ENSURE_SUCCESS(rv, rv);
 
       *aArgv = v;
 
       break;
     }
     case nsISupportsPrimitive::TYPE_ID :
@@ -1114,17 +1114,17 @@ static const JSFunctionSpec JProfFunctio
 #endif /* defined(MOZ_JPROF) */
 
 nsresult
 nsJSContext::InitClasses(JS::Handle<JSObject*> aGlobalObj)
 {
   AutoJSAPI jsapi;
   jsapi.Init();
   JSContext* cx = jsapi.cx();
-  JSAutoCompartment ac(cx, aGlobalObj);
+  JSAutoRealm ar(cx, aGlobalObj);
 
   // Attempt to initialize profiling functions
   ::JS_DefineProfilingFunctions(cx, aGlobalObj);
 
 #ifdef MOZ_JPROF
   // Attempt to initialize JProf functions
   ::JS_DefineFunctions(cx, aGlobalObj, JProfFunctions);
 #endif
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -137,17 +137,17 @@ EvaluationExceptionToNSResult(JSContext*
 nsJSUtils::ExecutionContext::ExecutionContext(JSContext* aCx,
                                               JS::Handle<JSObject*> aGlobal)
   :
 #ifdef MOZ_GECKO_PROFILER
     mAutoProfilerLabel("nsJSUtils::ExecutionContext", /* dynamicStr */ nullptr,
                        __LINE__, js::ProfileEntry::Category::JS),
 #endif
     mCx(aCx)
-  , mCompartment(aCx, aGlobal)
+  , mRealm(aCx, aGlobal)
   , mRetValue(aCx)
   , mScopeChain(aCx)
   , mRv(NS_OK)
   , mSkip(false)
   , mCoerceToString(false)
   , mEncodeBytecode(false)
 #ifdef DEBUG
   , mWantsReturnValue(false)
--- a/dom/base/nsJSUtils.h
+++ b/dom/base/nsJSUtils.h
@@ -72,18 +72,18 @@ public:
   class MOZ_STACK_CLASS ExecutionContext {
 #ifdef MOZ_GECKO_PROFILER
     // Register stack annotations for the Gecko profiler.
     mozilla::AutoProfilerLabel mAutoProfilerLabel;
 #endif
 
     JSContext* mCx;
 
-    // Handles switching to our global's compartment.
-    JSAutoCompartment mCompartment;
+    // Handles switching to our global's realm.
+    JSAutoRealm mRealm;
 
     // Set to a valid handle if a return value is expected.
     JS::Rooted<JS::Value> mRetValue;
 
     // Scope chain in which the execution takes place.
     JS::AutoObjectVector mScopeChain;
 
     // returned value forwarded when we have to interupt the execution eagerly
--- a/dom/base/nsNodeUtils.cpp
+++ b/dom/base/nsNodeUtils.cpp
@@ -579,17 +579,17 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNod
       elem->RecompileScriptEventListeners();
     }
 
     if (aReparentScope) {
       AutoJSContext cx;
       JS::Rooted<JSObject*> wrapper(cx);
       if ((wrapper = aNode->GetWrapper())) {
         MOZ_ASSERT(IsDOMObject(wrapper));
-        JSAutoCompartment ac(cx, wrapper);
+        JSAutoRealm ar(cx, wrapper);
         ReparentWrapper(cx, wrapper, aError);
         if (aError.Failed()) {
           if (wasRegistered) {
             aNode->OwnerDoc()->UnregisterActivityObserver(aNode->AsElement());
           }
           aNode->mNodeInfo.swap(newNodeInfo);
           if (elem) {
             elem->NodeInfoChanged(newDoc);
--- a/dom/base/nsObjectLoadingContent.cpp
+++ b/dom/base/nsObjectLoadingContent.cpp
@@ -3558,22 +3558,22 @@ nsObjectLoadingContent::SetupProtoChain(
   }
 
   if (!nsContentUtils::IsSafeToRunScript()) {
     RefPtr<SetupProtoChainRunner> runner = new SetupProtoChainRunner(this);
     nsContentUtils::AddScriptRunner(runner);
     return;
   }
 
-  // We get called on random compartments here for some reason
-  // (perhaps because WrapObject can happen on a random compartment?)
-  // so make sure to enter the compartment of aObject.
+  // We get called on random realms here for some reason
+  // (perhaps because WrapObject can happen on a random realm?)
+  // so make sure to enter the realm of aObject.
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
 
-  JSAutoCompartment ac(aCx, aObject);
+  JSAutoRealm ar(aCx, aObject);
 
   RefPtr<nsNPAPIPluginInstance> pi;
   nsresult rv = ScriptRequestPluginInstance(aCx, getter_AddRefs(pi));
   if (NS_FAILED(rv)) {
     return;
   }
 
   if (!pi) {
@@ -3668,20 +3668,19 @@ nsObjectLoadingContent::SetupProtoChain(
 // static
 nsresult
 nsObjectLoadingContent::GetPluginJSObject(JSContext *cx,
                                           JS::Handle<JSObject*> obj,
                                           nsNPAPIPluginInstance *plugin_inst,
                                           JS::MutableHandle<JSObject*> plugin_obj,
                                           JS::MutableHandle<JSObject*> plugin_proto)
 {
-  // NB: We need an AutoEnterCompartment because we can be called from
-  // nsPluginFrame when the plugin loads after the JS object for our content
-  // node has been created.
-  JSAutoCompartment ac(cx, obj);
+  // NB: We need a JSAutoRealm because we can be called from nsPluginFrame when
+  // the plugin loads after the JS object for our content node has been created.
+  JSAutoRealm ar(cx, obj);
 
   if (plugin_inst) {
     plugin_inst->GetJSObject(cx, plugin_obj.address());
     if (plugin_obj) {
       if (!::JS_GetPrototype(cx, plugin_obj, plugin_proto)) {
         return NS_ERROR_UNEXPECTED;
       }
     }
@@ -3702,17 +3701,17 @@ nsObjectLoadingContent::TeardownProtoCha
   // reporting errors to our window's onerror listeners.
   AutoJSAPI jsapi;
   jsapi.Init();
   JSContext* cx = jsapi.cx();
   JS::Rooted<JSObject*> obj(cx, thisContent->GetWrapper());
   MOZ_ASSERT(obj);
 
   JS::Rooted<JSObject*> proto(cx);
-  JSAutoCompartment ac(cx, obj);
+  JSAutoRealm ar(cx, obj);
 
   // Loop over the DOM element's JS object prototype chain and remove
   // all JS objects of the class sNPObjectJSWrapperClass
   DebugOnly<bool> removed = false;
   while (obj) {
     if (!::JS_GetPrototype(cx, obj, &proto)) {
       return;
     }
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -1603,17 +1603,17 @@ static bool
 ResolvePrototypeOrConstructor(JSContext* cx, JS::Handle<JSObject*> wrapper,
                               JS::Handle<JSObject*> obj,
                               size_t protoAndIfaceCacheIndex, unsigned attrs,
                               JS::MutableHandle<JS::PropertyDescriptor> desc,
                               bool& cacheOnHolder)
 {
   JS::Rooted<JSObject*> global(cx, js::GetGlobalForObjectCrossCompartment(obj));
   {
-    JSAutoCompartment ac(cx, global);
+    JSAutoRealm ar(cx, global);
     ProtoAndIfaceCache& protoAndIfaceCache = *GetProtoAndIfaceCache(global);
     // This function is called when resolving the "constructor" and "prototype"
     // properties of Xrays for DOM prototypes and constructors respectively.
     // This means the relevant Xray exists, which means its _target_ exists.
     // And that means we managed to successfullly create the prototype or
     // constructor, respectively, and hence must have managed to create the
     // thing it's pointing to as well.  So our entry slot must exist.
     JSObject* protoOrIface =
@@ -2249,17 +2249,17 @@ ReparentWrapper(JSContext* aCx, JS::Hand
   JS::Rooted<JSObject*> oldParent(aCx,
                                   js::GetGlobalForObjectCrossCompartment(aObj));
   MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(oldParent) == oldParent);
 
   JS::Rooted<JSObject*> newParent(aCx,
                                   domClass->mGetAssociatedGlobal(aCx, aObj));
   MOZ_ASSERT(JS_IsGlobalObject(newParent));
 
-  JSAutoCompartment oldAc(aCx, oldParent);
+  JSAutoRealm oldAr(aCx, oldParent);
 
   JSCompartment* oldCompartment = js::GetObjectCompartment(oldParent);
   JSCompartment* newCompartment = js::GetObjectCompartment(newParent);
   if (oldCompartment == newCompartment) {
     MOZ_ASSERT(oldParent == newParent);
     return;
   }
 
@@ -2269,17 +2269,17 @@ ReparentWrapper(JSContext* aCx, JS::Hand
   }
 
   bool isProxy = js::IsProxy(aObj);
   JS::Rooted<JSObject*> expandoObject(aCx);
   if (isProxy) {
     expandoObject = DOMProxyHandler::GetAndClearExpandoObject(aObj);
   }
 
-  JSAutoCompartment newAc(aCx, newParent);
+  JSAutoRealm newAr(aCx, newParent);
 
   // First we clone the reflector. We get a copy of its properties and clone its
   // expando chain.
 
   JS::Handle<JSObject*> proto = (domClass->mGetProto)(aCx);
   if (!proto) {
     aError.StealExceptionFromJSContext(aCx);
     return;
@@ -3505,20 +3505,20 @@ GetMaplikeSetlikeBackingObject(JSContext
   reflector = IsDOMObject(aObj) ? aObj : js::UncheckedUnwrap(aObj,
                                                              /* stopAtWindowProxy = */ false);
 
   // Retrieve the backing object from the reserved slot on the maplike/setlike
   // object. If it doesn't exist yet, create it.
   JS::Rooted<JS::Value> slotValue(aCx);
   slotValue = js::GetReservedSlot(reflector, aSlotIndex);
   if (slotValue.isUndefined()) {
-    // Since backing object access can happen in non-originating compartments,
-    // make sure to create the backing object in reflector compartment.
+    // Since backing object access can happen in non-originating realms,
+    // make sure to create the backing object in reflector realm.
     {
-      JSAutoCompartment ac(aCx, reflector);
+      JSAutoRealm ar(aCx, reflector);
       JS::Rooted<JSObject*> newBackingObj(aCx);
       newBackingObj.set(Method(aCx));
       if (NS_WARN_IF(!newBackingObj)) {
         return false;
       }
       js::SetReservedSlot(reflector, aSlotIndex, JS::ObjectValue(*newBackingObj));
     }
     slotValue = js::GetReservedSlot(reflector, aSlotIndex);
@@ -3731,17 +3731,17 @@ HTMLConstructor(JSContext* aCx, unsigned
   // Enter the compartment of our underlying newTarget object, so we end
   // up comparing to the constructor object for our interface from that global.
   // XXXbz This is not what the spec says to do, and it's not super-clear to me
   // at this point why we're doing it.  Why not just compare |newTarget| and
   // |callee| if the intent is just to prevent registration of HTML interface
   // objects as constructors?  Of course it's not clear that the spec check
   // makes sense to start with: https://github.com/whatwg/html/issues/3575
   {
-    JSAutoCompartment ac(aCx, newTarget);
+    JSAutoRealm ar(aCx, newTarget);
     JS::Handle<JSObject*> constructor =
       GetPerInterfaceObjectHandle(aCx, aConstructorId, aCreator,
                                   true);
     if (!constructor) {
       return false;
     }
     if (newTarget == constructor) {
       return ThrowErrorMessage(aCx, MSG_ILLEGAL_CONSTRUCTOR);
@@ -3764,19 +3764,19 @@ HTMLConstructor(JSContext* aCx, unsigned
     ns = kNameSpaceID_XHTML;
   }
 
   int32_t tag = eHTMLTag_userdefined;
   if (!definition->IsCustomBuiltIn()) {
     // Step 4.
     // If the definition is for an autonomous custom element, the active
     // function should be HTMLElement or XULElement.  We want to get the actual
-    // functions to compare to from our global's compartment, not the caller
-    // compartment.
-    JSAutoCompartment ac(aCx, global.Get());
+    // functions to compare to from our global's realm, not the caller
+    // realm.
+    JSAutoRealm ar(aCx, global.Get());
 
     JS::Rooted<JSObject*> constructor(aCx);
     if (ns == kNameSpaceID_XUL) {
       constructor = XULElementBinding::GetConstructorObject(aCx);
     } else {
       constructor = HTMLElementBinding::GetConstructorObject(aCx);
     }
 
@@ -3806,19 +3806,19 @@ HTMLConstructor(JSContext* aCx, unsigned
 
     // If the definition is for a customized built-in element, the active
     // function should be the localname's element interface.
     constructorGetterCallback cb = sConstructorGetterCallback[tag];
     if (!cb) {
       return ThrowErrorMessage(aCx, MSG_ILLEGAL_CONSTRUCTOR);
     }
 
-    // We want to get the constructor from our global's compartment, not the
-    // caller compartment.
-    JSAutoCompartment ac(aCx, global.Get());
+    // We want to get the constructor from our global's realm, not the
+    // caller realm.
+    JSAutoRealm ar(aCx, global.Get());
     JS::Rooted<JSObject*> constructor(aCx, cb(aCx));
     if (!constructor) {
       return false;
     }
 
     if (constructor != js::CheckedUnwrap(callee)) {
       return ThrowErrorMessage(aCx, MSG_ILLEGAL_CONSTRUCTOR);
     }
@@ -3828,49 +3828,49 @@ HTMLConstructor(JSContext* aCx, unsigned
   JS::Rooted<JSObject*> desiredProto(aCx);
   if (!GetDesiredProto(aCx, args, &desiredProto)) {
     return false;
   }
 
   // Step 7.
   if (!desiredProto) {
     // This fallback behavior is designed to match analogous behavior for the
-    // JavaScript built-ins. So we enter the compartment of our underlying
-    // newTarget object and fall back to the prototype object from that global.
+    // JavaScript built-ins. So we enter the realm of our underlying newTarget
+    // object and fall back to the prototype object from that global.
     // XXX The spec says to use GetFunctionRealm(), which is not actually
     // the same thing as what we have here (e.g. in the case of scripted callable proxies
-    // whose target is not same-compartment with the proxy, or bound functions, etc).
+    // whose target is not same-realm with the proxy, or bound functions, etc).
     // https://bugzilla.mozilla.org/show_bug.cgi?id=1317658
     {
-      JSAutoCompartment ac(aCx, newTarget);
+      JSAutoRealm ar(aCx, newTarget);
       desiredProto = GetPerInterfaceObjectHandle(aCx, aProtoId, aCreator, true);
       if (!desiredProto) {
           return false;
       }
     }
 
-    // desiredProto is in the compartment of the underlying newTarget object.
-    // Wrap it into the context compartment.
+    // desiredProto is in the realm of the underlying newTarget object.
+    // Wrap it into the context realm.
     if (!JS_WrapObject(aCx, &desiredProto)) {
       return false;
     }
   }
 
   // We need to do some work to actually return an Element, so we do step 8 on
   // one branch and steps 9-12 on another branch, then common up the "return
   // element" work.
   RefPtr<Element> element;
   nsTArray<RefPtr<Element>>& constructionStack =
     definition->mConstructionStack;
   if (constructionStack.IsEmpty()) {
     // Step 8.
     // Now we go to construct an element.  We want to do this in global's
-    // compartment, not caller compartment (the normal constructor behavior),
+    // realm, not caller realm (the normal constructor behavior),
     // just in case those elements create JS things.
-    JSAutoCompartment ac(aCx, global.Get());
+    JSAutoRealm ar(aCx, global.Get());
 
     RefPtr<NodeInfo> nodeInfo =
       doc->NodeInfoManager()->GetNodeInfo(definition->mLocalName,
                                           nullptr,
                                           ns,
                                           nsINode::ELEMENT_NODE);
     MOZ_ASSERT(nodeInfo);
 
@@ -3902,33 +3902,33 @@ HTMLConstructor(JSContext* aCx, unsigned
 
     // Step 11.
     // Do prototype swizzling for upgrading a custom element here, for cases
     // when we have a reflector already.  If we don't have one yet, we will
     // create it with the right proto (by calling DoGetOrCreateDOMReflector with
     // that proto).
     JS::Rooted<JSObject*> reflector(aCx, element->GetWrapper());
     if (reflector) {
-      // reflector might be in different compartment.
-      JSAutoCompartment ac(aCx, reflector);
+      // reflector might be in different realm.
+      JSAutoRealm ar(aCx, reflector);
       JS::Rooted<JSObject*> givenProto(aCx, desiredProto);
       if (!JS_WrapObject(aCx, &givenProto) ||
           !JS_SetPrototype(aCx, reflector, givenProto)) {
         return false;
       }
     }
 
     // Step 12.
     constructionStack.LastElement() = ALREADY_CONSTRUCTED_MARKER;
   }
 
   // Tail end of step 8 and step 13: returning the element.  We want to do this
-  // part in the global's compartment, though in practice it won't matter much
-  // because Element always knows which compartment it should be created in.
-  JSAutoCompartment ac(aCx, global.Get());
+  // part in the global's realm, though in practice it won't matter much
+  // because Element always knows which realm it should be created in.
+  JSAutoRealm ar(aCx, global.Get());
   if (!js::IsObjectInContextCompartment(desiredProto, aCx) &&
       !JS_WrapObject(aCx, &desiredProto)) {
     return false;
   }
 
   return GetOrCreateDOMReflector(aCx, element, args.rval(), desiredProto);
 }
 } // namespace binding_detail
@@ -3940,21 +3940,21 @@ AssertReflectorHasGivenProto(JSContext* 
                              JS::Handle<JSObject*> aGivenProto)
 {
   if (!aGivenProto) {
     // Nothing to assert here
     return;
   }
 
   JS::Rooted<JSObject*> reflector(aCx, aReflector);
-  JSAutoCompartment ac(aCx, reflector);
+  JSAutoRealm ar(aCx, reflector);
   JS::Rooted<JSObject*> reflectorProto(aCx);
   bool ok = JS_GetPrototype(aCx, reflector, &reflectorProto);
   MOZ_ASSERT(ok);
-  // aGivenProto may not be in the right compartment here, so we
+  // aGivenProto may not be in the right realm here, so we
   // have to wrap it to compare.
   JS::Rooted<JSObject*> givenProto(aCx, aGivenProto);
   ok = JS_WrapObject(aCx, &givenProto);
   MOZ_ASSERT(ok);
   MOZ_ASSERT(givenProto == reflectorProto,
              "How are we supposed to change the proto now?");
 }
 } // namespace binding_detail
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -1123,17 +1123,17 @@ DoGetOrCreateDOMReflector(JSContext* cx,
   bool sameCompartment =
     js::GetObjectCompartment(obj) == js::GetContextCompartment(cx);
   if (sameCompartment && couldBeDOMBinding) {
     return TypeNeedsOuterization<T>::value ? TryToOuterize(rval) : true;
   }
 
   if (wrapBehavior == eDontWrapIntoContextCompartment) {
     if (TypeNeedsOuterization<T>::value) {
-      JSAutoCompartment ac(cx, obj);
+      JSAutoRealm ar(cx, obj);
       return TryToOuterize(rval);
     }
 
     return true;
   }
 
   return JS_WrapValue(cx, rval);
 }
@@ -1183,32 +1183,32 @@ inline bool
 WrapNewBindingNonWrapperCachedObject(JSContext* cx,
                                      JS::Handle<JSObject*> scopeArg,
                                      T* value,
                                      JS::MutableHandle<JS::Value> rval,
                                      JS::Handle<JSObject*> givenProto = nullptr)
 {
   static_assert(IsRefcounted<T>::value, "Don't pass owned classes in here.");
   MOZ_ASSERT(value);
-  // We try to wrap in the compartment of the underlying object of "scope"
+  // We try to wrap in the realm of the underlying object of "scope"
   JS::Rooted<JSObject*> obj(cx);
   {
-    // scope for the JSAutoCompartment so that we restore the compartment
+    // scope for the JSAutoRealm so that we restore the realm
     // before we call JS_WrapValue.
-    Maybe<JSAutoCompartment> ac;
+    Maybe<JSAutoRealm> ar;
     // Maybe<Handle> doesn't so much work, and in any case, adding
     // more Maybe (one for a Rooted and one for a Handle) adds more
     // code (and branches!) than just adding a single rooted.
     JS::Rooted<JSObject*> scope(cx, scopeArg);
     JS::Rooted<JSObject*> proto(cx, givenProto);
     if (js::IsWrapper(scope)) {
       scope = js::CheckedUnwrap(scope, /* stopAtWindowProxy = */ false);
       if (!scope)
         return false;
-      ac.emplace(cx, scope);
+      ar.emplace(cx, scope);
       if (!JS_WrapObject(cx, &proto)) {
         return false;
       }
     }
 
     MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
     if (!value->WrapObject(cx, proto, &obj)) {
       return false;
@@ -1234,32 +1234,32 @@ WrapNewBindingNonWrapperCachedObject(JSC
                                      JS::Handle<JSObject*> givenProto = nullptr)
 {
   static_assert(!IsRefcounted<T>::value, "Only pass owned classes in here.");
   // We do a runtime check on value, because otherwise we might in
   // fact end up wrapping a null and invoking methods on it later.
   if (!value) {
     MOZ_CRASH("Don't try to wrap null objects");
   }
-  // We try to wrap in the compartment of the underlying object of "scope"
+  // We try to wrap in the realm of the underlying object of "scope"
   JS::Rooted<JSObject*> obj(cx);
   {
-    // scope for the JSAutoCompartment so that we restore the compartment
+    // scope for the JSAutoRealm so that we restore the realm
     // before we call JS_WrapValue.
-    Maybe<JSAutoCompartment> ac;
+    Maybe<JSAutoRealm> ar;
     // Maybe<Handle> doesn't so much work, and in any case, adding
     // more Maybe (one for a Rooted and one for a Handle) adds more
     // code (and branches!) than just adding a single rooted.
     JS::Rooted<JSObject*> scope(cx, scopeArg);
     JS::Rooted<JSObject*> proto(cx, givenProto);
     if (js::IsWrapper(scope)) {
       scope = js::CheckedUnwrap(scope, /* stopAtWindowProxy = */ false);
       if (!scope)
         return false;
-      ac.emplace(cx, scope);
+      ar.emplace(cx, scope);
       if (!JS_WrapObject(cx, &proto)) {
         return false;
       }
     }
 
     MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
     if (!value->WrapObject(cx, proto, &obj)) {
       return false;
@@ -2505,17 +2505,17 @@ XrayOwnPropertyKeys(JSContext* cx, JS::H
  *     interface or interface prototype object.
  */
 inline bool
 XrayGetNativeProto(JSContext* cx, JS::Handle<JSObject*> obj,
                    JS::MutableHandle<JSObject*> protop)
 {
   JS::Rooted<JSObject*> global(cx, js::GetGlobalForObjectCrossCompartment(obj));
   {
-    JSAutoCompartment ac(cx, global);
+    JSAutoRealm ar(cx, global);
     const DOMJSClass* domClass = GetDOMClass(obj);
     if (domClass) {
       ProtoHandleGetter protoGetter = domClass->mGetProto;
       if (protoGetter) {
         protop.set(protoGetter(cx));
       } else {
         protop.set(JS::GetRealmObjectPrototype(cx));
       }
@@ -3146,17 +3146,17 @@ CreateGlobal(JSContext* aCx, T* aNative,
 
   aGlobal.set(JS_NewGlobalObject(aCx, aClass, aPrincipal,
                                  JS::DontFireOnNewGlobalHook, aOptions));
   if (!aGlobal) {
     NS_WARNING("Failed to create global");
     return false;
   }
 
-  JSAutoCompartment ac(aCx, aGlobal);
+  JSAutoRealm ar(aCx, aGlobal);
 
   {
     js::SetReservedSlot(aGlobal, DOM_OBJECT_SLOT, JS::PrivateValue(aNative));
     NS_ADDREF(aNative);
 
     aCache->SetWrapper(aGlobal);
 
     dom::AllocateProtoAndIfaceCache(aGlobal,
@@ -3335,17 +3335,17 @@ WrappedJSToDictionary(JSContext* aCx, ns
     return false;
   }
 
   JS::Rooted<JSObject*> obj(aCx, wrappedObj->GetJSObject());
   if (!obj) {
     return false;
   }
 
-  JSAutoCompartment ac(aCx, obj);
+  JSAutoRealm ar(aCx, obj);
   JS::Rooted<JS::Value> v(aCx, JS::ObjectValue(*obj));
   return aDictionary.Init(aCx, v);
 }
 
 template<class T>
 inline bool
 WrappedJSToDictionary(nsISupports* aObject, T& aDictionary)
 {
--- a/dom/bindings/CallbackObject.cpp
+++ b/dom/bindings/CallbackObject.cpp
@@ -241,22 +241,22 @@ CallbackObject::CallSetup::CallSetup(Cal
   // JSContext. (Rooted<> does not care about requests or compartments.)
   mRootedCallable.emplace(cx, aCallback->CallbackOrNull());
 
   mAsyncStack.emplace(cx, aCallback->GetCreationStack());
   if (*mAsyncStack) {
     mAsyncStackSetter.emplace(cx, *mAsyncStack, aExecutionReason);
   }
 
-  // Enter the compartment of our callback, so we can actually work with it.
+  // Enter the realm of our callback, so we can actually work with it.
   //
   // Note that if the callback is a wrapper, this will not be the same
-  // compartment that we ended up in with mAutoEntryScript above, because the
+  // realm that we ended up in with mAutoEntryScript above, because the
   // entry point is based off of the unwrapped callback (realCallback).
-  mAc.emplace(cx, *mRootedCallable);
+  mAr.emplace(cx, *mRootedCallable);
 
   // And now we're ready to go.
   mCx = cx;
 }
 
 bool
 CallbackObject::CallSetup::ShouldRethrowException(JS::Handle<JS::Value> aException)
 {
@@ -297,22 +297,22 @@ CallbackObject::CallSetup::ShouldRethrow
 
   JS::Rooted<JSObject*> obj(mCx, &aException.toObject());
   obj = js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false);
   return js::GetObjectCompartment(obj) == mCompartment;
 }
 
 CallbackObject::CallSetup::~CallSetup()
 {
-  // To get our nesting right we have to destroy our JSAutoCompartment first.
+  // To get our nesting right we have to destroy our JSAutoRealm first.
   // In particular, we want to do this before we try reporting any exceptions,
-  // so we end up reporting them while in the compartment of our entry point,
+  // so we end up reporting them while in the realm of our entry point,
   // not whatever cross-compartment wrappper mCallback might be.
-  // Be careful: the JSAutoCompartment might not have been constructed at all!
-  mAc.reset();
+  // Be careful: the JSAutoRealm might not have been constructed at all!
+  mAr.reset();
 
   // Now, if we have a JSContext, report any pending errors on it, unless we
   // were told to re-throw them.
   if (mCx) {
     bool needToDealWithException = mAutoEntryScript->HasException();
     if ((mCompartment && mExceptionHandling == eRethrowContentExceptions) ||
         mExceptionHandling == eRethrowExceptions) {
       mErrorResult.MightThrowJSException();
@@ -327,17 +327,17 @@ CallbackObject::CallSetup::~CallSetup()
         }
       }
     }
 
     if (needToDealWithException) {
       // Either we're supposed to report our exceptions, or we're supposed to
       // re-throw them but we failed to get the exception value.  Either way,
       // we'll just report the pending exception, if any, once ~mAutoEntryScript
-      // runs.  Note that we've already run ~mAc, effectively, so we don't have
+      // runs.  Note that we've already run ~mAr, effectively, so we don't have
       // to worry about ordering here.
       if (mErrorResult.IsJSContextException()) {
         // XXXkhuey bug 1117269.  When this is fixed, please consider fixing
         // ThrowExceptionValueIfSafe over in Exceptions.cpp in the same way.
 
         // IsJSContextException shouldn't be true anymore because we will report
         // the exception on the JSContext ... so throw something else.
         mErrorResult.ThrowWithCustomCleanup(NS_ERROR_UNEXPECTED);
@@ -371,17 +371,17 @@ CallbackObjectHolderBase::ToXPCOMCallbac
   jsapi.Init();
   JSContext* cx = jsapi.cx();
 
   JS::Rooted<JSObject*> callback(cx, aCallback->CallbackOrNull());
   if (!callback) {
     return nullptr;
   }
 
-  JSAutoCompartment ac(cx, callback);
+  JSAutoRealm ar(cx, callback);
   RefPtr<nsXPCWrappedJS> wrappedJS;
   nsresult rv =
     nsXPCWrappedJS::GetNewOrUsed(callback, aIID, getter_AddRefs(wrappedJS));
   if (NS_FAILED(rv) || !wrappedJS) {
     return nullptr;
   }
 
   nsCOMPtr<nsISupports> retval;
--- a/dom/bindings/CallbackObject.h
+++ b/dom/bindings/CallbackObject.h
@@ -332,21 +332,21 @@ protected:
     Maybe<AutoIncumbentScript> mAutoIncumbentScript;
 
     Maybe<JS::Rooted<JSObject*> > mRootedCallable;
 
     // Members which are used to set the async stack.
     Maybe<JS::Rooted<JSObject*>> mAsyncStack;
     Maybe<JS::AutoSetAsyncStackForNewCalls> mAsyncStackSetter;
 
-    // Can't construct a JSAutoCompartment without a JSContext either.  Also,
-    // Put mAc after mAutoEntryScript so that we exit the compartment before
-    // we pop the JSContext. Though in practice we'll often manually order
-    // those two things.
-    Maybe<JSAutoCompartment> mAc;
+    // Can't construct a JSAutoRealm without a JSContext either.  Also,
+    // Put mAr after mAutoEntryScript so that we exit the realm before we
+    // pop the script settings stack. Though in practice we'll often manually
+    // order those two things.
+    Maybe<JSAutoRealm> mAr;
 
     // An ErrorResult to possibly re-throw exceptions on and whether
     // we should re-throw them.
     ErrorResult& mErrorResult;
     const ExceptionHandling mExceptionHandling;
     const bool mIsMainThread;
   };
 };
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -3740,17 +3740,17 @@ class CGWrapWithCacheMethod(CGAbstractMe
             aReflector.set(aCache->GetWrapper());
             if (aReflector) {
             #ifdef DEBUG
               AssertReflectorHasGivenProto(aCx, aReflector, aGivenProto);
             #endif // DEBUG
               return true;
             }
 
-            JSAutoCompartment ac(aCx, global);
+            JSAutoRealm ar(aCx, global);
             $*{declareProto}
 
             $*{createObject}
 
             aCache->SetWrapper(aReflector);
             $*{unforgeable}
             $*{slots}
             $*{setImmutablePrototype}
@@ -3901,19 +3901,19 @@ class CGWrapGlobalMethod(CGAbstractMetho
                                              sClass.ToJSClass(),
                                              aOptions,
                                              aPrincipal,
                                              aInitStandardClasses,
                                              aReflector)) {
               $*{failureCode}
             }
 
-            // aReflector is a new global, so has a new compartment.  Enter it
+            // aReflector is a new global, so has a new realm.  Enter it
             // before doing anything with it.
-            JSAutoCompartment ac(aCx, aReflector);
+            JSAutoRealm ar(aCx, aReflector);
 
             if (!DefineProperties(aCx, aReflector, ${properties}, ${chromeProperties})) {
               $*{failureCode}
             }
             $*{unforgeable}
 
             $*{slots}
 
@@ -3988,17 +3988,17 @@ class CGClearCachedValueMethod(CGAbstrac
             noopRetval = " true"
             saveMember = (
                 "JS::Rooted<JS::Value> oldValue(aCx, js::GetReservedSlot(obj, %s));\n" %
                 slotIndex)
             regetMember = fill(
                 """
                 JS::Rooted<JS::Value> temp(aCx);
                 JSJitGetterCallArgs args(&temp);
-                JSAutoCompartment ac(aCx, obj);
+                JSAutoRealm ar(aCx, obj);
                 if (!get_${name}(aCx, obj, aObject, args)) {
                   js::SetReservedSlot(obj, ${slotIndex}, oldValue);
                   return false;
                 }
                 return true;
                 """,
                 name=self.member.identifier.name,
                 slotIndex=slotIndex)
@@ -5383,22 +5383,22 @@ def getJSToNativeConversionInfo(type, de
         else:
             getPromiseGlobal = dedent(
                 """
                 globalObj = JS::CurrentGlobalOrNull(cx);
                 """)
 
         templateBody = fill(
             """
-            { // Scope for our GlobalObject, FastErrorResult, JSAutoCompartment,
+            { // Scope for our GlobalObject, FastErrorResult, JSAutoRealm,
               // etc.
 
               JS::Rooted<JSObject*> globalObj(cx);
               $*{getPromiseGlobal}
-              JSAutoCompartment ac(cx, globalObj);
+              JSAutoRealm ar(cx, globalObj);
               GlobalObject promiseGlobal(cx, globalObj);
               if (promiseGlobal.Failed()) {
                 $*{exceptionCode}
               }
 
               JS::Rooted<JS::Value> valueToResolve(cx, $${val});
               if (!JS_WrapValue(cx, &valueToResolve)) {
                 $*{exceptionCode}
@@ -7631,18 +7631,18 @@ class CGPerSignatureCall(CGThing):
                 # object's compartment and then wrap up all of our arguments into
                 # that compartment as needed.  This is all happening after we've
                 # already done the conversions from JS values to WebIDL (C++)
                 # values, so we only need to worry about cases where there are 'any'
                 # or 'object' types, or other things that we represent as actual
                 # JSAPI types, present.  Effectively, we're emulating a
                 # CrossCompartmentWrapper, but working with the C++ types, not the
                 # original list of JS::Values.
-                cgThings.append(CGGeneric("Maybe<JSAutoCompartment> ac;\n"))
-                xraySteps.append(CGGeneric("ac.emplace(cx, obj);\n"))
+                cgThings.append(CGGeneric("Maybe<JSAutoRealm> ar;\n"))
+                xraySteps.append(CGGeneric("ar.emplace(cx, obj);\n"))
                 xraySteps.append(CGGeneric(dedent(
                     """
                     if (!JS_WrapObject(cx, &desiredProto)) {
                       return false;
                     }
                     """)))
                 xraySteps.extend(
                     wrapArgIntoCurrentCompartment(arg, argname, isMember=False)
@@ -7842,27 +7842,27 @@ class CGPerSignatureCall(CGThing):
                 conversionScope = "isXray ? obj : slotStorage"
             else:
                 conversionScope = "slotStorage"
 
             wrapCode = fill(
                 """
                 {
                   JS::Rooted<JSObject*> conversionScope(cx, ${conversionScope});
-                  JSAutoCompartment ac(cx, conversionScope);
+                  JSAutoRealm ar(cx, conversionScope);
                   do { // block we break out of when done wrapping
                     $*{wrapCode}
                   } while (false);
                   $*{postConversionSteps}
                 }
-                { // And now store things in the compartment of our slotStorage.
-                  JSAutoCompartment ac(cx, slotStorage);
+                { // And now store things in the realm of our slotStorage.
+                  JSAutoRealm ar(cx, slotStorage);
                   $*{slotStorageSteps}
                 }
-                // And now make sure args.rval() is in the caller compartment
+                // And now make sure args.rval() is in the caller realm.
                 return ${maybeWrap}(cx, args.rval());
                 """,
                 conversionScope=conversionScope,
                 wrapCode=wrapCode,
                 postConversionSteps=postConversionSteps,
                 slotStorageSteps=slotStorageSteps,
                 maybeWrap=getMaybeWrapValueFuncForType(self.idlNode.type))
         return wrapCode
@@ -10855,17 +10855,17 @@ class CGResolveOwnPropertyViaResolve(CGA
         return CGGeneric(dedent("""
             {
               // Since we're dealing with an Xray, do the resolve on the
               // underlying object first.  That gives it a chance to
               // define properties on the actual object as needed, and
               // then use the fact that it created the objects as a flag
               // to avoid re-resolving the properties if someone deletes
               // them.
-              JSAutoCompartment ac(cx, obj);
+              JSAutoRealm ar(cx, obj);
               JS_MarkCrossZoneId(cx, id);
               JS::Rooted<JS::PropertyDescriptor> objDesc(cx);
               if (!self->DoResolve(cx, obj, id, &objDesc)) {
                 return false;
               }
               // If desc.value() is undefined, then the DoResolve call
               // has already defined the property on the object.  Don't
               // try to also define it.
@@ -11550,17 +11550,17 @@ class CGDeleteNamedProperty(CGAbstractSt
                                         "bool", args)
 
     def definition_body(self):
         return fill(
             """
             MOZ_ASSERT(xpc::WrapperFactory::IsXrayWrapper(xray));
             MOZ_ASSERT(js::IsProxy(proxy));
             MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy));
-            JSAutoCompartment ac(cx, proxy);
+            JSAutoRealm ar(cx, proxy);
             bool deleteSucceeded = false;
             bool found = false;
             $*{namedBody}
             if (!found || deleteSucceeded) {
               return opresult.succeed();
             }
             return opresult.failCantDelete();
             """,
@@ -12749,17 +12749,17 @@ class CGDictionary(CGThing):
                 AutoJSAPI jsapi;
                 jsapi.Init();
                 JSContext *cx = jsapi.cx();
                 // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here
                 // because we'll only be creating objects, in ways that have no
                 // side-effects, followed by a call to JS::ToJSONMaybeSafely,
                 // which likewise guarantees no side-effects for the sorts of
                 // things we will pass it.
-                JSAutoCompartment ac(cx, UnprivilegedJunkScopeOrWorkerGlobal());
+                JSAutoRealm ar(cx, UnprivilegedJunkScopeOrWorkerGlobal());
                 JS::Rooted<JS::Value> val(cx);
                 if (!ToObjectInternal(cx, &val)) {
                   return false;
                 }
                 JS::Rooted<JSObject*> obj(cx, &val.toObject());
                 return StringifyToJSON(cx, obj, aJSON);
             """), const=True)
 
@@ -15301,17 +15301,17 @@ class CGJSImplClass(CGBindingImplClass):
         return fill(
             """
             JS::Rooted<JSObject*> obj(aCx, ${name}Binding::Wrap(aCx, this, aGivenProto));
             if (!obj) {
               return nullptr;
             }
 
             // Now define it on our chrome object
-            JSAutoCompartment ac(aCx, mImpl->CallbackOrNull());
+            JSAutoRealm ar(aCx, mImpl->CallbackOrNull());
             if (!JS_WrapObject(aCx, &obj)) {
               return nullptr;
             }
             if (!JS_DefineProperty(aCx, mImpl->CallbackOrNull(), "__DOM_IMPL__", obj, 0)) {
               return nullptr;
             }
             return obj;
             """,
@@ -16679,27 +16679,27 @@ class CGMaplikeOrSetlikeHelperFunctionGe
             """
             MOZ_ASSERT(self);
             AutoJSAPI jsapi;
             jsapi.Init();
             JSContext* cx = jsapi.cx();
             // It's safe to use UnprivilegedJunkScopeOrWorkerGlobal here because
             // all we want is to wrap into _some_ scope and then unwrap to find
             // the reflector, and wrapping has no side-effects.
-            JSAutoCompartment tempCompartment(cx, UnprivilegedJunkScopeOrWorkerGlobal());
+            JSAutoRealm tempRealm(cx, UnprivilegedJunkScopeOrWorkerGlobal());
             JS::Rooted<JS::Value> v(cx);
             if(!ToJSValue(cx, self, &v)) {
               aRv.Throw(NS_ERROR_UNEXPECTED);
               return%s;
             }
             // This is a reflector, but due to trying to name things
             // similarly across method generators, it's called obj here.
             JS::Rooted<JSObject*> obj(cx);
             obj = js::UncheckedUnwrap(&v.toObject(), /* stopAtWindowProxy = */ false);
-            JSAutoCompartment reflectorCompartment(cx, obj);
+            JSAutoRealm reflectorRealm(cx, obj);
             """ % self.getDefaultRetval())
 
     def getArgs(self, returnType, argList):
         # We don't need the context or the value. We'll generate those instead.
         args = CGNativeMember.getArgs(self, returnType, argList)
         # Prepend a pointer to the binding object onto the arguments
         return [Argument(self.descriptorProvider.nativeType + "*", "self")] + args
 
--- a/dom/bindings/SimpleGlobalObject.cpp
+++ b/dom/bindings/SimpleGlobalObject.cpp
@@ -129,17 +129,17 @@ SimpleGlobalObject::Create(GlobalType gl
                                   JS::DontFireOnNewGlobalHook, options);
     }
 
     if (!global) {
       jsapi.ClearException();
       return nullptr;
     }
 
-    JSAutoCompartment ac(cx, global);
+    JSAutoRealm ar(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);
 
--- a/dom/bindings/StructuredClone.cpp
+++ b/dom/bindings/StructuredClone.cpp
@@ -42,17 +42,17 @@ ReadStructuredCloneImageData(JSContext* 
 bool
 WriteStructuredCloneImageData(JSContext* aCx, JSStructuredCloneWriter* aWriter,
                               ImageData* aImageData)
 {
   uint32_t width = aImageData->Width();
   uint32_t height = aImageData->Height();
   JS::Rooted<JSObject*> dataArray(aCx, aImageData->GetDataObject());
 
-  JSAutoCompartment ac(aCx, dataArray);
+  JSAutoRealm ar(aCx, dataArray);
   JS::Rooted<JS::Value> arrayValue(aCx, JS::ObjectValue(*dataArray));
   return JS_WriteUint32Pair(aWriter, SCTAG_DOM_IMAGEDATA, 0) &&
          JS_WriteUint32Pair(aWriter, width, height) &&
          JS_WriteTypedArray(aWriter, arrayValue);
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/bindings/TypedArray.h
+++ b/dom/bindings/TypedArray.h
@@ -167,19 +167,19 @@ public:
     : Base(Move(aOther))
   {
   }
 
   static inline JSObject*
   Create(JSContext* cx, nsWrapperCache* creator, uint32_t length,
          const T* data = nullptr) {
     JS::Rooted<JSObject*> creatorWrapper(cx);
-    Maybe<JSAutoCompartment> ac;
+    Maybe<JSAutoRealm> ar;
     if (creator && (creatorWrapper = creator->GetWrapperPreserveColor())) {
-      ac.emplace(cx, creatorWrapper);
+      ar.emplace(cx, creatorWrapper);
     }
 
     return CreateCommon(cx, length, data);
   }
 
   static inline JSObject*
   Create(JSContext* cx, uint32_t length, const T* data = nullptr) {
     return CreateCommon(cx, length, data);
--- a/dom/bindings/WebIDLGlobalNameHash.cpp
+++ b/dom/bindings/WebIDLGlobalNameHash.cpp
@@ -303,17 +303,17 @@ WebIDLGlobalNameHash::DefineIfEnabled(JS
   //   slots are set up. In the Xray case, this means unwrapping and doing
   //   a non-Xray resolve before doing the Xray resolve.
   //
   // This all could use some grand refactoring, but for now we just limp
   // along.
   if (xpc::WrapperFactory::IsXrayWrapper(aObj)) {
     JS::Rooted<JSObject*> constructor(aCx);
     {
-      JSAutoCompartment ac(aCx, global);
+      JSAutoRealm ar(aCx, global);
       constructor = FindNamedConstructorForXray(aCx, aId, entry);
     }
     if (NS_WARN_IF(!constructor)) {
       return Throw(aCx, NS_ERROR_FAILURE);
     }
     if (!JS_WrapObject(aCx, &constructor)) {
       return Throw(aCx, NS_ERROR_FAILURE);
     }
--- a/dom/browser-element/BrowserElementParent.cpp
+++ b/dom/browser-element/BrowserElementParent.cpp
@@ -141,17 +141,17 @@ BrowserElementParent::DispatchOpenWindow
   JS::Rooted<JS::Value> val(cx);
 
   nsIGlobalObject* sgo = aPopupFrameElement->OwnerDoc()->GetScopeObject();
   if (!sgo) {
     return BrowserElementParent::OPEN_WINDOW_IGNORED;
   }
 
   JS::Rooted<JSObject*> global(cx, sgo->GetGlobalJSObject());
-  JSAutoCompartment ac(cx, global);
+  JSAutoRealm ar(cx, global);
   if (!ToJSValue(cx, detail, &val)) {
     MOZ_CRASH("Failed to convert dictionary to JS::Value due to OOM.");
     return BrowserElementParent::OPEN_WINDOW_IGNORED;
   }
 
   nsEventStatus status = nsEventStatus_eIgnore;
   bool dispatchSucceeded =
     DispatchCustomDOMEvent(aOpenerFrameElement,
--- a/dom/canvas/WebGLContextUtils.h
+++ b/dom/canvas/WebGLContextUtils.h
@@ -62,17 +62,17 @@ WebGLContext::WebGLObjectAsJSValue(JSCon
                                    ErrorResult& rv) const
 {
     if (!object)
         return JS::NullValue();
 
     MOZ_ASSERT(this == object->mContext);
     JS::Rooted<JS::Value> v(cx);
     JS::Rooted<JSObject*> wrapper(cx, GetWrapper());
-    JSAutoCompartment ac(cx, wrapper);
+    JSAutoRealm ar(cx, wrapper);
     if (!dom::GetOrCreateDOMReflector(cx, const_cast<WebGLObjectType*>(object), &v)) {
         rv.Throw(NS_ERROR_FAILURE);
         return JS::NullValue();
     }
     return v;
 }
 
 template <typename WebGLObjectType>
--- a/dom/clients/manager/ClientOpenWindowUtils.cpp
+++ b/dom/clients/manager/ClientOpenWindowUtils.cpp
@@ -193,17 +193,17 @@ OpenWindow(const ClientOpenWindowArgs& a
     MOZ_DIAGNOSTIC_ASSERT(xpc);
 
     JS::Rooted<JSObject*> sandbox(cx);
     rv = xpc->CreateSandbox(cx, principal, sandbox.address());
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return NS_ERROR_TYPE_ERR;
     }
 
-    JSAutoCompartment ac(cx, sandbox);
+    JSAutoRealm ar(cx, sandbox);
 
     // ContentProcess
     nsCOMPtr<nsIWindowWatcher> wwatch =
       do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
     nsCOMPtr<nsPIWindowWatcher> pwwatch(do_QueryInterface(wwatch));
--- a/dom/console/Console.cpp
+++ b/dom/console/Console.cpp
@@ -638,17 +638,17 @@ private:
     if (NS_WARN_IF(!global)) {
       return;
     }
 
     // The CreateSandbox call returns a proxy to the actual sandbox object. We
     // don't need a proxy here.
     global = js::UncheckedUnwrap(global);
 
-    JSAutoCompartment ac(cx, global);
+    JSAutoRealm ar(cx, global);
 
     // We don't need to set a parent object in mCallData bacause there are not
     // DOM objects exposed to worklet.
 
     ProcessCallData(cx, mConsole, mCallData);
   }
 
   virtual void
@@ -753,17 +753,17 @@ protected:
     if (NS_WARN_IF(!global)) {
       return;
     }
 
     // The GetOrCreateSandbox call returns a proxy to the actual sandbox object.
     // We don't need a proxy here.
     global = js::UncheckedUnwrap(global);
 
-    JSAutoCompartment ac(cx, global);
+    JSAutoRealm ar(cx, global);
 
     RunConsole(cx, nullptr, nullptr);
   }
 
   void
   RunBackOnWorkerThreadForCleanup() override
   {
     mWorkerPrivate->AssertIsOnWorkerThread();
@@ -916,17 +916,17 @@ private:
     if (NS_WARN_IF(!global)) {
       return;
     }
 
     // The CreateSandbox call returns a proxy to the actual sandbox object. We
     // don't need a proxy here.
     global = js::UncheckedUnwrap(global);
 
-    JSAutoCompartment ac(cx, global);
+    JSAutoRealm ar(cx, global);
 
     // We don't need to set a parent object in mCallData bacause there are not
     // DOM objects exposed to worklet.
 
     ProcessProfileData(cx, mConsole, mName, mAction);
   }
 
   virtual void
@@ -1899,17 +1899,17 @@ Console::PopulateConsoleNotificationInTh
                                             aData->mLogTimerStatus);
   }
 
   else if (aData->mMethodName == MethodCount) {
     event.mCounter = CreateCounterValue(aCx, aData->mCountLabel,
                                         aData->mCountValue);
   }
 
-  JSAutoCompartment ac2(aCx, targetScope);
+  JSAutoRealm ar2(aCx, targetScope);
 
   if (NS_WARN_IF(!ToJSValue(aCx, event, aEventValue))) {
     return false;
   }
 
   JS::Rooted<JSObject*> eventObj(aCx, &aEventValue.toObject());
   if (NS_WARN_IF(!JS_DefineProperty(aCx, eventObj, "wrappedJSObject", eventObj,
                                     JSPROP_ENUMERATE))) {
@@ -2665,17 +2665,17 @@ Console::RetrieveConsoleEvents(JSContext
   MOZ_ASSERT(!NS_IsMainThread());
 
   JS::Rooted<JSObject*> targetScope(aCx, JS::CurrentGlobalOrNull(aCx));
 
   for (uint32_t i = 0; i < mCallDataStorage.Length(); ++i) {
     JS::Rooted<JS::Value> value(aCx);
 
     JS::Rooted<JSObject*> sequenceScope(aCx, mCallDataStorage[i]->mGlobal);
-    JSAutoCompartment ac(aCx, sequenceScope);
+    JSAutoRealm ar(aCx, sequenceScope);
 
     Sequence<JS::Value> sequence;
     SequenceRooter<JS::Value> arguments(aCx, &sequence);
 
     if (!mCallDataStorage[i]->PopulateArgumentsSequence(sequence)) {
       aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
       return;
     }
--- a/dom/console/ConsoleUtils.cpp
+++ b/dom/console/ConsoleUtils.cpp
@@ -75,17 +75,17 @@ ConsoleUtils::ReportForServiceWorkerScop
   if (NS_WARN_IF(!global)) {
     return;
   }
 
   // The GetOrCreateSandbox call returns a proxy to the actual sandbox object.
   // We don't need a proxy here.
   global = js::UncheckedUnwrap(global);
 
-  JSAutoCompartment ac(cx, global);
+  JSAutoRealm ar(cx, global);
 
   RootedDictionary<ConsoleEvent> event(cx);
 
   event.mID.Construct();
   event.mID.Value().SetAsString() = aScope;
 
   event.mInnerID.Construct();
   event.mInnerID.Value().SetAsString() = NS_LITERAL_STRING("ServiceWorker");
--- a/dom/encoding/TextEncoder.cpp
+++ b/dom/encoding/TextEncoder.cpp
@@ -26,17 +26,17 @@ TextEncoder::Encode(JSContext* aCx,
   nsresult rv;
   const Encoding* ignored;
   Tie(rv, ignored) = UTF_8_ENCODING->Encode(aString, utf8);
   if (NS_FAILED(rv)) {
     aRv.Throw(rv);
     return;
   }
 
-  JSAutoCompartment ac(aCx, aObj);
+  JSAutoRealm ar(aCx, aObj);
   JSObject* outView = Uint8Array::Create(
     aCx, utf8.Length(), reinterpret_cast<const uint8_t*>(utf8.BeginReading()));
   if (!outView) {
     aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
     return;
   }
 
   aRetval.set(outView);
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -1020,32 +1020,32 @@ EventListenerManager::CompileEventHandle
                                    typeAtom, win,
                                    &argCount, &argNames);
 
   // Wrap the event target, so that we can use it as the scope for the event
   // handler. Note that mTarget is different from aElement in the <body> case,
   // where mTarget is a Window.
   //
   // The wrapScope doesn't really matter here, because the target will create
-  // its reflector in the proper scope, and then we'll enter that compartment.
+  // its reflector in the proper scope, and then we'll enter that realm.
   JS::Rooted<JSObject*> wrapScope(cx, global->GetGlobalJSObject());
   JS::Rooted<JS::Value> v(cx);
   {
-    JSAutoCompartment ac(cx, wrapScope);
+    JSAutoRealm ar(cx, wrapScope);
     nsresult rv = nsContentUtils::WrapNative(cx, mTarget, &v,
                                              /* aAllowWrapping = */ false);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   }
 
   JS::Rooted<JSObject*> target(cx, &v.toObject());
-  JSAutoCompartment ac(cx, target);
+  JSAutoRealm ar(cx, target);
 
-  // Now that we've entered the compartment we actually care about, create our
+  // Now that we've entered the realm we actually care about, create our
   // scope chain.  Note that we start with |element|, not aElement, because
   // mTarget is different from aElement in the <body> case, where mTarget is a
   // Window, and in that case we do not want the scope chain to include the body
   // or the document.
   JS::AutoObjectVector scopeChain(cx);
   if (!nsJSUtils::GetScopeChainForElement(cx, element, scopeChain)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
--- a/dom/events/EventListenerService.cpp
+++ b/dom/events/EventListenerService.cpp
@@ -147,51 +147,51 @@ EventListenerInfo::GetInSystemEventGroup
   *aInSystemEventGroup = mInSystemEventGroup;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 EventListenerInfo::GetListenerObject(JSContext* aCx,
                                      JS::MutableHandle<JS::Value> aObject)
 {
-  Maybe<JSAutoCompartment> ac;
-  GetJSVal(aCx, ac, aObject);
+  Maybe<JSAutoRealm> ar;
+  GetJSVal(aCx, ar, aObject);
   return NS_OK;
 }
 
 /******************************************************************************
  * mozilla::EventListenerService
  ******************************************************************************/
 
 NS_IMPL_ISUPPORTS(EventListenerService, nsIEventListenerService)
 
 bool
 EventListenerInfo::GetJSVal(JSContext* aCx,
-                            Maybe<JSAutoCompartment>& aAc,
+                            Maybe<JSAutoRealm>& aAr,
                             JS::MutableHandle<JS::Value> aJSVal)
 {
   if (mScriptedListener) {
     aJSVal.setObject(*mScriptedListener);
-    aAc.emplace(aCx, mScriptedListener);
+    aAr.emplace(aCx, mScriptedListener);
     return true;
   }
 
   aJSVal.setNull();
   return false;
 }
 
 NS_IMETHODIMP
 EventListenerInfo::ToSource(nsAString& aResult)
 {
   aResult.SetIsVoid(true);
 
   AutoSafeJSContext cx;
-  Maybe<JSAutoCompartment> ac;
+  Maybe<JSAutoRealm> ar;
   JS::Rooted<JS::Value> v(cx);
-  if (GetJSVal(cx, ac, &v)) {
+  if (GetJSVal(cx, ar, &v)) {
     JSString* str = JS_ValueToSource(cx, v);
     if (str) {
       nsAutoJSString autoStr;
       if (autoStr.init(cx, str)) {
         aResult.Assign(autoStr);
       }
     }
   }
--- a/dom/events/EventListenerService.h
+++ b/dom/events/EventListenerService.h
@@ -56,17 +56,17 @@ public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(EventListenerInfo)
   NS_DECL_NSIEVENTLISTENERINFO
 
 protected:
  virtual ~EventListenerInfo();
 
   bool GetJSVal(JSContext* aCx,
-                Maybe<JSAutoCompartment>& aAc,
+                Maybe<JSAutoRealm>& aAr,
                 JS::MutableHandle<JS::Value> aJSVal);
 
   nsString mType;
   JS::Heap<JSObject*> mScriptedListener;  // May be null.
   bool mCapturing;
   bool mAllowsUntrusted;
   bool mInSystemEventGroup;
 };
--- a/dom/html/nsHTMLDocument.cpp
+++ b/dom/html/nsHTMLDocument.cpp
@@ -1446,17 +1446,17 @@ nsHTMLDocument::Open(JSContext* cx,
     // Now make sure we're not flagged as the initial document anymore, now
     // that we've had stuff done to us.  From now on, if anyone tries to
     // document.open() us, they get a new inner window.
     SetIsInitialDocument(false);
 
     nsCOMPtr<nsIScriptGlobalObject> newScope(do_QueryReferent(mScopeObject));
     JS::Rooted<JSObject*> wrapper(cx, GetWrapper());
     if (oldScope && newScope != oldScope && wrapper) {
-      JSAutoCompartment ac(cx, wrapper);
+      JSAutoRealm ar(cx, wrapper);
       mozilla::dom::ReparentWrapper(cx, wrapper, aError);
       if (aError.Failed()) {
         return nullptr;
       }
 
       // Also reparent the template contents owner document
       // because its global is set to the same as this document.
       if (mTemplateContentsOwner) {
--- a/dom/indexedDB/IDBObjectStore.cpp
+++ b/dom/indexedDB/IDBObjectStore.cpp
@@ -1462,17 +1462,17 @@ public:
     JSContext* cx = jsapi.cx();
 
     JS::Rooted<JSObject*> global(cx, SandboxHolder::GetSandbox(cx));
     if (NS_WARN_IF(!global)) {
       OperationCompleted(NS_ERROR_FAILURE);
       return NS_OK;
     }
 
-    JSAutoCompartment ac(cx, global);
+    JSAutoRealm ar(cx, global);
 
     JS::Rooted<JS::Value> value(cx);
     nsresult rv = DeserializeIndexValue(cx, &value);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       OperationCompleted(rv);
       return NS_OK;
     }
 
@@ -1584,17 +1584,17 @@ public:
     JSContext* cx = jsapi.cx();
 
     JS::Rooted<JSObject*> global(cx, SandboxHolder::GetSandbox(cx));
     if (NS_WARN_IF(!global)) {
       OperationCompleted(NS_ERROR_FAILURE);
       return NS_OK;
     }
 
-    JSAutoCompartment ac(cx, global);
+    JSAutoRealm ar(cx, global);
 
     JS::Rooted<JS::Value> value(cx);
     nsresult rv = DeserializeUpgradeValue(cx, &value);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       OperationCompleted(rv);
       return NS_OK;
     }
 
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -311,23 +311,23 @@ IDBRequest::SetResultCallback(ResultCall
 
   // See if our window is still valid.
   if (NS_WARN_IF(NS_FAILED(CheckInnerWindowCorrectness()))) {
     SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
     return;
   }
 
   AutoJSAPI autoJS;
-  Maybe<JSAutoCompartment> ac;
+  Maybe<JSAutoRealm> ar;
 
   if (GetScriptOwner()) {
     // If we have a script owner we want the SafeJSContext and then to enter the
-    // script owner's compartment.
+    // script owner's realm.
     autoJS.Init();
-    ac.emplace(autoJS.cx(), GetScriptOwner());
+    ar.emplace(autoJS.cx(), GetScriptOwner());
   } else {
     // Otherwise our owner is a window and we use that to initialize.
     MOZ_ASSERT(GetOwner());
     if (!autoJS.Init(GetOwner())) {
       IDB_WARNING("Failed to initialize AutoJSAPI!");
       SetError(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
       return;
     }
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -467,17 +467,17 @@ ConsoleListener::Observe(nsIConsoleMessa
       jsapi.Init();
       JSContext* cx = jsapi.cx();
 
       JS::RootedValue stack(cx);
       rv = scriptError->GetStack(&stack);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (stack.isObject()) {
-        JSAutoCompartment ac(cx, &stack.toObject());
+        JSAutoRealm ar(cx, &stack.toObject());
 
         StructuredCloneData data;
         ErrorResult err;
         data.Write(cx, stack, err);
         if (err.Failed()) {
           return err.StealNSResult();
         }
 
--- a/dom/media/webaudio/AudioContext.cpp
+++ b/dom/media/webaudio/AudioContext.cpp
@@ -530,17 +530,17 @@ AudioContext::DecodeAudioData(const Arra
                               const Optional<OwningNonNull<DecodeErrorCallback> >& aFailureCallback,
                               ErrorResult& aRv)
 {
   nsCOMPtr<nsIGlobalObject> parentObject = do_QueryInterface(GetParentObject());
   RefPtr<Promise> promise;
   AutoJSAPI jsapi;
   jsapi.Init();
   JSContext* cx = jsapi.cx();
-  JSAutoCompartment ac(cx, aBuffer.Obj());
+  JSAutoRealm ar(cx, aBuffer.Obj());
 
   promise = Promise::Create(parentObject, aRv);
   if (aRv.Failed()) {
     return nullptr;
   }
 
   aBuffer.ComputeLengthAndData();
 
--- a/dom/network/TCPSocket.cpp
+++ b/dom/network/TCPSocket.cpp
@@ -854,17 +854,17 @@ TCPSocket::Send(JSContext* aCx,
   if (mSocketBridgeChild) {
     nsresult rv = mSocketBridgeChild->SendSend(aData, aByteOffset, byteLength, ++mTrackingNumber);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       aRv.Throw(rv);
       return false;
     }
   } else {
     JS::Rooted<JSObject*> obj(aCx, aData.Obj());
-    JSAutoCompartment ac(aCx, obj);
+    JSAutoRealm ar(aCx, obj);
     JS::Rooted<JS::Value> value(aCx, JS::ObjectValue(*obj));
 
     stream = do_CreateInstance("@mozilla.org/io/arraybuffer-input-stream;1");
     nsresult rv = stream->SetData(value, aByteOffset, byteLength, aCx);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       aRv.Throw(rv);
       return false;
     }
--- a/dom/plugins/base/nsJSNPRuntime.cpp
+++ b/dom/plugins/base/nsJSNPRuntime.cpp
@@ -733,17 +733,17 @@ nsJSObjWrapper::NP_HasMethod(NPObject *n
     ThrowJSExceptionASCII(cx,
                           "Null npobj in nsJSObjWrapper::NP_HasMethod!");
 
     return false;
   }
 
   nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
 
-  JSAutoCompartment ac(cx, npjsobj->mJSObj);
+  JSAutoRealm ar(cx, npjsobj->mJSObj);
   MarkCrossZoneNPIdentifier(cx, id);
 
   AutoJSExceptionSuppressor suppressor(aes, npjsobj);
 
   JS::Rooted<JS::Value> v(cx);
   bool ok = GetProperty(cx, npjsobj->mJSObj, id, &v);
 
   return ok && !v.isPrimitive() &&
@@ -773,17 +773,17 @@ doInvoke(NPObject *npobj, NPIdentifier m
   }
 
   // Initialize *result
   VOID_TO_NPVARIANT(*result);
 
   nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
 
   JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
-  JSAutoCompartment ac(cx, jsobj);
+  JSAutoRealm ar(cx, jsobj);
   MarkCrossZoneNPIdentifier(cx, method);
   JS::Rooted<JS::Value> fv(cx);
 
   AutoJSExceptionSuppressor suppressor(aes, npjsobj);
 
   if (method != NPIdentifier_VOID) {
     if (!GetProperty(cx, jsobj, method, &fv) ||
         ::JS_TypeOfValue(cx, fv) != JSTYPE_FUNCTION) {
@@ -866,17 +866,17 @@ nsJSObjWrapper::NP_HasProperty(NPObject 
     return false;
   }
 
   nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
   bool found, ok = false;
 
   AutoJSExceptionSuppressor suppressor(aes, npjsobj);
   JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
-  JSAutoCompartment ac(cx, jsobj);
+  JSAutoRealm ar(cx, jsobj);
   MarkCrossZoneNPIdentifier(cx, npid);
 
   NS_ASSERTION(NPIdentifierIsInt(npid) || NPIdentifierIsString(npid),
                "id must be either string or int!\n");
   JS::Rooted<jsid> id(cx, NPIdentifierToJSId(npid));
   ok = ::JS_HasPropertyById(cx, jsobj, id, &found);
   return ok && found;
 }
@@ -903,17 +903,17 @@ nsJSObjWrapper::NP_GetProperty(NPObject 
                           "Null npobj in nsJSObjWrapper::NP_GetProperty!");
 
     return false;
   }
 
   nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
 
   AutoJSExceptionSuppressor suppressor(aes, npjsobj);
-  JSAutoCompartment ac(cx, npjsobj->mJSObj);
+  JSAutoRealm ar(cx, npjsobj->mJSObj);
   MarkCrossZoneNPIdentifier(cx, id);
 
   JS::Rooted<JS::Value> v(cx);
   return (GetProperty(cx, npjsobj->mJSObj, id, &v) &&
           JSValToNPVariant(npp, cx, v, result));
 }
 
 // static
@@ -940,17 +940,17 @@ nsJSObjWrapper::NP_SetProperty(NPObject 
     return false;
   }
 
   nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
   bool ok = false;
 
   AutoJSExceptionSuppressor suppressor(aes, npjsobj);
   JS::Rooted<JSObject*> jsObj(cx, npjsobj->mJSObj);
-  JSAutoCompartment ac(cx, jsObj);
+  JSAutoRealm ar(cx, jsObj);
   MarkCrossZoneNPIdentifier(cx, npid);
 
   JS::Rooted<JS::Value> v(cx, NPVariantToJSVal(npp, cx, value));
 
   NS_ASSERTION(NPIdentifierIsInt(npid) || NPIdentifierIsString(npid),
                "id must be either string or int!\n");
   JS::Rooted<jsid> id(cx, NPIdentifierToJSId(npid));
   ok = ::JS_SetPropertyById(cx, jsObj, id, v);
@@ -978,17 +978,17 @@ nsJSObjWrapper::NP_RemoveProperty(NPObje
     return false;
   }
 
   nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
 
   AutoJSExceptionSuppressor suppressor(aes, npjsobj);
   JS::ObjectOpResult result;
   JS::Rooted<JSObject*> obj(cx, npjsobj->mJSObj);
-  JSAutoCompartment ac(cx, obj);
+  JSAutoRealm ar(cx, obj);
   MarkCrossZoneNPIdentifier(cx, npid);
 
   NS_ASSERTION(NPIdentifierIsInt(npid) || NPIdentifierIsString(npid),
                "id must be either string or int!\n");
   JS::Rooted<jsid> id(cx, NPIdentifierToJSId(npid));
   if (!::JS_DeletePropertyById(cx, obj, id, result))
     return false;
 
@@ -1032,17 +1032,17 @@ nsJSObjWrapper::NP_Enumerate(NPObject *n
 
     return false;
   }
 
   nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj;
 
   AutoJSExceptionSuppressor suppressor(aes, npjsobj);
   JS::Rooted<JSObject*> jsobj(cx, npjsobj->mJSObj);
-  JSAutoCompartment ac(cx, jsobj);
+  JSAutoRealm ar(cx, jsobj);
 
   JS::Rooted<JS::IdVector> ida(cx, JS::IdVector(cx));
   if (!JS_Enumerate(cx, jsobj, &ida)) {
     return false;
   }
 
   *count = ida.length();
   *idarray = (NPIdentifier*) malloc(*count * sizeof(NPIdentifier));
@@ -1174,17 +1174,17 @@ GetNPObjectWrapper(JSContext *cx, JS::Ha
   while (obj && (obj = js::CheckedUnwrap(obj))) {
     if (nsNPObjWrapper::IsWrapper(obj)) {
       if (wrapResult && !JS_WrapObject(cx, &obj)) {
         return nullptr;
       }
       return obj;
     }
 
-    JSAutoCompartment ac(cx, obj);
+    JSAutoRealm ar(cx, obj);
     if (!::JS_GetPrototype(cx, obj, &obj)) {
       return nullptr;
     }
   }
   return nullptr;
 }
 
 static NPObject *
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -96,33 +96,33 @@ Promise::Create(nsIGlobalObject* aGlobal
   return p.forget();
 }
 
 // static
 already_AddRefed<Promise>
 Promise::Resolve(nsIGlobalObject* aGlobal, JSContext* aCx,
                  JS::Handle<JS::Value> aValue, ErrorResult& aRv)
 {
-  JSAutoCompartment ac(aCx, aGlobal->GetGlobalJSObject());
+  JSAutoRealm ar(aCx, aGlobal->GetGlobalJSObject());
   JS::Rooted<JSObject*> p(aCx,
                           JS::CallOriginalPromiseResolve(aCx, aValue));
   if (!p) {
     aRv.NoteJSContextException(aCx);
     return nullptr;
   }
 
   return CreateFromExisting(aGlobal, p);
 }
 
 // static
 already_AddRefed<Promise>
 Promise::Reject(nsIGlobalObject* aGlobal, JSContext* aCx,
                 JS::Handle<JS::Value> aValue, ErrorResult& aRv)
 {
-  JSAutoCompartment ac(aCx, aGlobal->GetGlobalJSObject());
+  JSAutoRealm ar(aCx, aGlobal->GetGlobalJSObject());
   JS::Rooted<JSObject*> p(aCx,
                           JS::CallOriginalPromiseReject(aCx, aValue));
   if (!p) {
     aRv.NoteJSContextException(aCx);
     return nullptr;
   }
 
   return CreateFromExisting(aGlobal, p);
--- a/dom/promise/PromiseDebugging.cpp
+++ b/dom/promise/PromiseDebugging.cpp
@@ -274,17 +274,17 @@ PromiseDebugging::FlushUncaughtRejection
     }
 
     for (size_t j = 0; j < observers.Length(); ++j) {
       RefPtr<UncaughtRejectionObserver> obs =
         static_cast<UncaughtRejectionObserver*>(observers[j].get());
 
       obs->OnLeftUncaught(promise, IgnoreErrors());
     }
-    JSAutoCompartment ac(cx, promise);
+    JSAutoRealm ar(cx, promise);
     Promise::ReportRejectedPromise(cx, promise);
   }
   storage->mUncaughtRejections.clear();
 
   // Notify observers of consumed Promise.
 
   for (size_t i = 0; i < consumed.length(); i++) {
     JS::RootedObject promise(cx, consumed[i]);
--- a/dom/script/ScriptSettings.cpp
+++ b/dom/script/ScriptSettings.cpp
@@ -374,17 +374,17 @@ AutoJSAPI::InitInternal(nsIGlobalObject*
     if (exn.isObject()) {
       JS::Rooted<JSObject*> exnObj(aCx, &exn.toObject());
 
       // Make sure we can actually read things from it.  This UncheckedUwrap is
       // safe because we're only getting data for a debug printf.  In
       // particular, we do not expose this data to anyone, which is very
       // important; otherwise it could be a cross-origin information leak.
       exnObj = js::UncheckedUnwrap(exnObj);
-      JSAutoCompartment ac(aCx, exnObj);
+      JSAutoRealm ar(aCx, exnObj);
 
       nsAutoJSString stack, filename, name, message;
       int32_t line;
 
       JS::Rooted<JS::Value> tmp(aCx);
       if (!JS_GetProperty(aCx, exnObj, "filename", &tmp)) {
         JS_ClearPendingException(aCx);
       }
@@ -553,28 +553,28 @@ void
 AutoJSAPI::ReportException()
 {
   if (!HasException()) {
     return;
   }
 
   // AutoJSAPI uses a JSAutoNullableCompartment, and may be in a null
   // compartment when the destructor is called. However, the JS engine
-  // requires us to be in a compartment when we fetch the pending exception.
+  // requires us to be in a realm when we fetch the pending exception.
   // In this case, we enter the privileged junk scope and don't dispatch any
   // error events.
   JS::Rooted<JSObject*> errorGlobal(cx(), JS::CurrentGlobalOrNull(cx()));
   if (!errorGlobal) {
     if (mIsMainThread) {
       errorGlobal = xpc::PrivilegedJunkScope();
     } else {
       errorGlobal = GetCurrentThreadWorkerGlobal();
     }
   }
-  JSAutoCompartment ac(cx(), errorGlobal);
+  JSAutoRealm ar(cx(), errorGlobal);
   JS::Rooted<JS::Value> exn(cx());
   js::ErrorReport jsReport(cx());
   if (StealException(&exn) &&
       jsReport.init(cx(), exn, js::ErrorReport::WithSideEffects)) {
     if (mIsMainThread) {
       RefPtr<xpc::ErrorReport> xpcReport = new xpc::ErrorReport();
 
       RefPtr<nsGlobalWindowInner> win = xpc::WindowGlobalOrNull(errorGlobal);
@@ -815,15 +815,15 @@ AutoSlowOperation::AutoSlowOperation(MOZ
   Init();
 }
 
 void
 AutoSlowOperation::CheckForInterrupt()
 {
   // For now we support only main thread!
   if (mIsMainThread) {
-    // JS_CheckForInterrupt expects us to be in a compartment.
-    JSAutoCompartment ac(cx(), xpc::UnprivilegedJunkScope());
+    // JS_CheckForInterrupt expects us to be in a realm.
+    JSAutoRealm ar(cx(), xpc::UnprivilegedJunkScope());
     JS_CheckForInterrupt(cx());
   }
 }
 
 } // namespace mozilla
--- a/dom/serviceworkers/ServiceWorkerPrivate.cpp
+++ b/dom/serviceworkers/ServiceWorkerPrivate.cpp
@@ -604,17 +604,17 @@ ServiceWorkerPrivate::SendMessageEvent(i
 
   JS::Rooted<JSObject*> global(cx, sandbox);
   NS_ENSURE_TRUE(sandbox, NS_ERROR_FAILURE);
 
   // The CreateSandbox call returns a proxy to the actual sandbox object.  We
   // don't need a proxy here.
   global = js::UncheckedUnwrap(global);
 
-  JSAutoCompartment ac(cx, global);
+  JSAutoRealm ar(cx, global);
 
   JS::Rooted<JS::Value> messageData(cx);
   aData.Read(cx, &messageData, rv);
   if (rv.Failed()) {
     return rv.StealNSResult();
   }
 
   Sequence<OwningNonNull<MessagePort>> ports;
--- a/dom/workers/WorkerDebugger.cpp
+++ b/dom/workers/WorkerDebugger.cpp
@@ -98,17 +98,17 @@ private:
 
     if (NS_WARN_IF(!aWorkerPrivate->EnsureClientSource())) {
       return false;
     }
 
     JS::Rooted<JSObject*> global(aCx, globalScope->GetWrapper());
 
     ErrorResult rv;
-    JSAutoCompartment ac(aCx, global);
+    JSAutoRealm ar(aCx, global);
     workerinternals::LoadMainScript(aWorkerPrivate, mScriptURL,
                                     DebuggerScript, rv);
     rv.WouldReportJSException();
     // Explicitly ignore NS_BINDING_ABORTED on rv.  Or more precisely, still
     // return false and don't SetWorkerScriptExecutedSuccessfully() in that
     // case, but don't throw anything on aCx.  The idea is to not dispatch error
     // events if our load is canceled with that error code.
     if (rv.ErrorCodeIs(NS_BINDING_ABORTED)) {
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -460,22 +460,22 @@ private:
     // because all the other errors are handled when the script is loaded.
     // See: https://dom.spec.whatwg.org/#concept-event-fire
     if (rv.Failed() && !rv.IsJSException()) {
       ReportCompileErrorRunnable::CreateAndDispatch(aCx, aWorkerPrivate);
       rv.SuppressException();
       return false;
     }
 
-    // This is a little dumb, but aCx is in the null compartment here because we
+    // This is a little dumb, but aCx is in the null realm here because we
     // set it up that way in our Run(), since we had not created the global at
-    // that point yet.  So we need to enter the compartment of our global,
+    // that point yet.  So we need to enter the realm of our global,
     // because setting a pending exception on aCx involves wrapping into its
     // current compartment.  Luckily we have a global now.
-    JSAutoCompartment ac(aCx, globalScope->GetGlobalJSObject());
+    JSAutoRealm ar(aCx, globalScope->GetGlobalJSObject());
     if (rv.MaybeSetPendingException(aCx)) {
       return false;
     }
 
     aWorkerPrivate->SetWorkerScriptExecutedSuccessfully();
     return true;
   }
 
@@ -3213,17 +3213,17 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
   AutoJSAPI jsapi;
   jsapi.Init();
   MOZ_ASSERT(jsapi.cx() == aCx);
 
   EnableMemoryReporter();
 
   InitializeGCTimers();
 
-  Maybe<JSAutoCompartment> workerCompartment;
+  Maybe<JSAutoRealm> workerCompartment;
 
   for (;;) {
     WorkerStatus currentStatus, previousStatus;
     bool debuggerRunnablesPending = false;
     bool normalRunnablesPending = false;
 
     {
       MutexAutoLock lock(mMutex);
@@ -3327,27 +3327,27 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
       CycleCollectedJSContext* ccjs = CycleCollectedJSContext::Get();
       ccjs->PerformDebuggerMicroTaskCheckpoint();
 
       if (debuggerRunnablesPending) {
         WorkerDebuggerGlobalScope* globalScope = DebuggerGlobalScope();
         MOZ_ASSERT(globalScope);
 
         // Now *might* be a good time to GC. Let the JS engine make the decision.
-        JSAutoCompartment ac(aCx, globalScope->GetGlobalJSObject());
+        JSAutoRealm ar(aCx, globalScope->GetGlobalJSObject());
         JS_MaybeGC(aCx);
       }
     } else if (normalRunnablesPending) {
       // Process a single runnable from the main queue.
       NS_ProcessNextEvent(mThread, false);
 
       normalRunnablesPending = NS_HasPendingEvents(mThread);
       if (normalRunnablesPending && GlobalScope()) {
         // Now *might* be a good time to GC. Let the JS engine make the decision.
-        JSAutoCompartment ac(aCx, GlobalScope()->GetGlobalJSObject());
+        JSAutoRealm ar(aCx, GlobalScope()->GetGlobalJSObject());
         JS_MaybeGC(aCx);
       }
     }
 
     if (!debuggerRunnablesPending && !normalRunnablesPending) {
       // Both the debugger event queue and the normal event queue has been
       // exhausted, cancel the periodic GC timer and schedule the idle GC timer.
       SetGCTimerMode(IdleTimer);
@@ -5292,17 +5292,17 @@ WorkerPrivate::GetOrCreateGlobalScope(JS
                                      GetServiceWorkerRegistrationDescriptor());
     } else {
       globalScope = new DedicatedWorkerGlobalScope(this, WorkerName());
     }
 
     JS::Rooted<JSObject*> global(aCx);
     NS_ENSURE_TRUE(globalScope->WrapGlobalObject(aCx, &global), nullptr);
 
-    JSAutoCompartment ac(aCx, global);
+    JSAutoRealm ar(aCx, global);
 
     // RegisterBindings() can spin a nested event loop so we have to set mScope
     // before calling it, and we have to make sure to unset mScope if it fails.
     mScope = Move(globalScope);
 
     if (!RegisterBindings(aCx, global)) {
       mScope = nullptr;
       return nullptr;
@@ -5322,17 +5322,17 @@ WorkerPrivate::CreateDebuggerGlobalScope
   MOZ_ASSERT(!mDebuggerScope);
 
   RefPtr<WorkerDebuggerGlobalScope> globalScope =
     new WorkerDebuggerGlobalScope(this);
 
   JS::Rooted<JSObject*> global(aCx);
   NS_ENSURE_TRUE(globalScope->WrapGlobalObject(aCx, &global), nullptr);
 
-  JSAutoCompartment ac(aCx, global);
+  JSAutoRealm ar(aCx, global);
 
   // RegisterDebuggerBindings() can spin a nested event loop so we have to set
   // mDebuggerScope before calling it, and we have to make sure to unset
   // mDebuggerScope if it fails.
   mDebuggerScope = Move(globalScope);
 
   if (!RegisterDebuggerBindings(aCx, global)) {
     mDebuggerScope = nullptr;
--- a/dom/workers/WorkerRunnable.cpp
+++ b/dom/workers/WorkerRunnable.cpp
@@ -267,17 +267,17 @@ WorkerRunnable::Run()
 
   bool result = PreRun(mWorkerPrivate);
   if (!result) {
     MOZ_ASSERT(targetIsWorkerThread,
                "The only PreRun implementation that can fail is "
                "ScriptExecutorRunnable");
     mWorkerPrivate->AssertIsOnWorkerThread();
     MOZ_ASSERT(!JS_IsExceptionPending(mWorkerPrivate->GetJSContext()));
-    // We can't enter a useful compartment on the JSContext here; just pass it
+    // We can't enter a useful realm on the JSContext here; just pass it
     // in as-is.
     PostRun(mWorkerPrivate->GetJSContext(), mWorkerPrivate, false);
     return NS_ERROR_FAILURE;
   }
 
   // Track down the appropriate global, if any, to use for the AutoEntryScript.
   nsCOMPtr<nsIGlobalObject> globalObject;
   bool isMainThread = !targetIsWorkerThread && !mWorkerPrivate->GetParent();
@@ -339,46 +339,46 @@ WorkerRunnable::Run()
   // then we must be a dedicated worker (because there are no
   // Shared/ServiceWorkers whose parent is itself a worker) and then we
   // definitely have a globalObject.  If it _is_ the main thread, globalObject
   // can be null for workers started from JSMs or other non-window contexts,
   // sadly.
   MOZ_ASSERT_IF(!targetIsWorkerThread && !isMainThread,
                 mWorkerPrivate->IsDedicatedWorker() && globalObject);
 
-  // If we're on the parent thread we might be in a null compartment in the
+  // If we're on the parent thread we might be in a null realm in the
   // situation described above when globalObject is null.  Make sure to enter
-  // the compartment of the worker's reflector if there is one.  There might
+  // the realm of the worker's reflector if there is one.  There might
   // not be one if we're just starting to compile the script for this worker.
-  Maybe<JSAutoCompartment> ac;
+  Maybe<JSAutoRealm> ar;
   if (!targetIsWorkerThread &&
       mWorkerPrivate->IsDedicatedWorker() &&
       mWorkerPrivate->ParentEventTargetRef()->GetWrapper()) {
     JSObject* wrapper = mWorkerPrivate->ParentEventTargetRef()->GetWrapper();
 
     // If we're on the parent thread and have a reflector and a globalObject,
-    // then the compartments of cx, globalObject, and the worker's reflector
+    // then the realms of cx, globalObject, and the worker's reflector
     // should all match.
     MOZ_ASSERT_IF(globalObject,
                   js::GetObjectCompartment(wrapper) ==
                     js::GetContextCompartment(cx));
     MOZ_ASSERT_IF(globalObject,
                   js::GetObjectCompartment(wrapper) ==
                     js::GetObjectCompartment(globalObject->GetGlobalJSObject()));
 
     // If we're on the parent thread and have a reflector, then our
-    // JSContext had better be either in the null compartment (and hence
-    // have no globalObject) or in the compartment of our reflector.
+    // JSContext had better be either in the null realm (and hence
+    // have no globalObject) or in the realm of our reflector.
     MOZ_ASSERT(!js::GetContextCompartment(cx) ||
                js::GetObjectCompartment(wrapper) ==
                  js::GetContextCompartment(cx),
                "Must either be in the null compartment or in our reflector "
                "compartment");
 
-    ac.emplace(cx, wrapper);
+    ar.emplace(cx, wrapper);
   }
 
   MOZ_ASSERT(!jsapi->HasException());
   result = WorkerRun(cx, mWorkerPrivate);
   MOZ_ASSERT_IF(result, !jsapi->HasException());
   jsapi->ReportException();
 
   // We can't even assert that this didn't create our global, since in the case
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -1008,25 +1008,25 @@ WorkerDebuggerGlobalScope::CreateSandbox
 void
 WorkerDebuggerGlobalScope::LoadSubScript(JSContext* aCx,
                                          const nsAString& aURL,
                                          const Optional<JS::Handle<JSObject*>>& aSandbox,
                                          ErrorResult& aRv)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();
 
-  Maybe<JSAutoCompartment> ac;
+  Maybe<JSAutoRealm> ar;
   if (aSandbox.WasPassed()) {
     JS::Rooted<JSObject*> sandbox(aCx, js::CheckedUnwrap(aSandbox.Value()));
     if (!IsWorkerDebuggerSandbox(sandbox)) {
       aRv.Throw(NS_ERROR_INVALID_ARG);
       return;
     }
 
-    ac.emplace(aCx, sandbox);
+    ar.emplace(aCx, sandbox);
   }
 
   nsTArray<nsString> urls;
   urls.AppendElement(aURL);
   workerinternals::Load(mWorkerPrivate, urls, DebuggerScript, aRv);
 }
 
 void
--- a/dom/worklet/Worklet.cpp
+++ b/dom/worklet/Worklet.cpp
@@ -372,17 +372,17 @@ void
 ExecutionRunnable::RunOnWorkletThread()
 {
   WorkletThread::AssertIsOnWorkletThread();
 
   WorkletThread* workletThread = WorkletThread::Get();
   MOZ_ASSERT(workletThread);
 
   JSContext* cx = workletThread->GetJSContext();
-  JSAutoRequest ar(cx);
+  JSAutoRequest areq(cx);
 
   AutoJSAPI jsapi;
   jsapi.Init();
 
   RefPtr<WorkletGlobalScope> globalScope =
     Worklet::CreateGlobalScope(jsapi.cx(), mWorkletType);
   MOZ_ASSERT(globalScope);
 
@@ -394,17 +394,17 @@ ExecutionRunnable::RunOnWorkletThread()
   NS_ConvertUTF16toUTF8 url(mHandler->URL());
 
   JS::CompileOptions compileOptions(cx);
   compileOptions.setIntroductionType("Worklet");
   compileOptions.setFileAndLine(url.get(), 0);
   compileOptions.setIsRunOnce(true);
   compileOptions.setNoScriptRval(true);
 
-  JSAutoCompartment comp(cx, globalObj);
+  JSAutoRealm ar(cx, globalObj);
 
   JS::SourceBufferHolder buffer(mScriptBuffer.release(), mScriptLength,
                                 JS::SourceBufferHolder::GiveOwnership);
   JS::Rooted<JS::Value> unused(cx);
   if (!JS::Evaluate(cx, compileOptions, buffer, &unused)) {
     ErrorResult error;
     error.MightThrowJSException();
     error.StealExceptionFromJSContext(cx);
@@ -533,17 +533,17 @@ Worklet::CreateGlobalScope(JSContext* aC
     case ePaintWorklet:
       scope = new PaintWorkletGlobalScope();
       break;
   }
 
   JS::Rooted<JSObject*> global(aCx);
   NS_ENSURE_TRUE(scope->WrapGlobalObject(aCx, &global), nullptr);
 
-  JSAutoCompartment ac(aCx, global);
+  JSAutoRealm ar(aCx, global);
 
   // Init Web IDL bindings
   if (!RegisterWorkletBindings(aCx, global)) {
     return nullptr;
   }
 
   JS_FireOnNewGlobalObject(aCx, global);
 
--- a/dom/xbl/nsBindingManager.cpp
+++ b/dom/xbl/nsBindingManager.cpp
@@ -635,17 +635,17 @@ nsBindingManager::GetBindingImplementati
       // binding, some of which may not be exposed on the prototype of
       // untrusted content. We don't need to consider add-on scopes here
       // because they're chrome-only and no Xrays are involved.
       //
       // If there's no separate XBL scope, or if the reflector itself lives in
       // the XBL scope, we'll end up with the global of the reflector.
       JS::Rooted<JSObject*> xblScope(cx, xpc::GetXBLScopeOrGlobal(cx, jsobj));
       NS_ENSURE_TRUE(xblScope, NS_ERROR_UNEXPECTED);
-      JSAutoCompartment ac(cx, xblScope);
+      JSAutoRealm ar(cx, xblScope);
       bool ok = JS_WrapObject(cx, &jsobj);
       NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
       MOZ_ASSERT_IF(js::IsWrapper(jsobj), xpc::IsXrayWrapper(jsobj));
 
       nsresult rv = xpConnect->WrapJSAggregatedToNative(aContent, cx,
                                                         jsobj, aIID, aResult);
       if (NS_FAILED(rv))
         return rv;
--- a/dom/xbl/nsXBLBinding.cpp
+++ b/dom/xbl/nsXBLBinding.cpp
@@ -732,17 +732,17 @@ nsXBLBinding::ChangeDocument(nsIDocument
       if (scriptObject) {
         // XXX Stay in sync! What if a layered binding has an
         // <interface>?!
         // XXXbz what does that comment mean, really?  It seems to date
         // back to when there was such a thing as an <interface>, whever
         // that was...
 
         // Find the right prototype.
-        JSAutoCompartment ac(cx, scriptObject);
+        JSAutoRealm ar(cx, scriptObject);
 
         JS::Rooted<JSObject*> base(cx, scriptObject);
         JS::Rooted<JSObject*> proto(cx);
         for ( ; true; base = proto) { // Will break out on null proto
           if (!JS_GetPrototype(cx, base, &proto)) {
             return;
           }
           if (!proto) {
@@ -890,17 +890,17 @@ GetOrCreateMapEntryForPrototype(JSContex
   // Now, enter the XBL scope, since that's where we need to operate, and wrap
   // the proto accordingly. We hang the map off of the content XBL scope for
   // content, and the Window for chrome (whether add-ons are involved or not).
   JS::Rooted<JSObject*> scope(cx, xpc::GetXBLScopeOrGlobal(cx, proto));
   NS_ENSURE_TRUE(scope, nullptr);
   MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(scope) == scope);
 
   JS::Rooted<JSObject*> wrappedProto(cx, proto);
-  JSAutoCompartment ac(cx, scope);
+  JSAutoRealm ar(cx, scope);
   if (!JS_WrapObject(cx, &wrappedProto)) {
     return nullptr;
   }
 
   // Grab the appropriate WeakMap.
   JS::Rooted<JSObject*> map(cx, GetOrCreateClassObjectMap(cx, scope, name));
   if (!map) {
     return nullptr;
@@ -969,24 +969,24 @@ nsXBLBinding::DoInitJSClass(JSContext *c
 
   // Get the map entry for the parent prototype. In the one-off case that the
   // parent prototype is null, we somewhat hackily just use the WeakMap itself
   // as a property holder.
   JS::Rooted<JSObject*> holder(cx);
   if (parent_proto) {
     holder = GetOrCreateMapEntryForPrototype(cx, parent_proto);
   } else {
-    JSAutoCompartment innerAC(cx, xblScope);
+    JSAutoRealm innerAR(cx, xblScope);
     holder = GetOrCreateClassObjectMap(cx, xblScope, "__ContentClassObjectMap__");
   }
   if (NS_WARN_IF(!holder)) {
     return NS_ERROR_FAILURE;
   }
   js::AssertSameCompartment(holder, xblScope);
-  JSAutoCompartment ac(cx, holder);
+  JSAutoRealm ar(cx, holder);
 
   // Look up the class on the property holder. The only properties on the
   // holder should be class objects. If we don't find the class object, we need
   // to create and define it.
   JS::Rooted<JSObject*> proto(cx);
   JS::Rooted<JS::PropertyDescriptor> desc(cx);
   if (!JS_GetOwnUCPropertyDescriptor(cx, holder, aClassName.get(), &desc)) {
     return NS_ERROR_OUT_OF_MEMORY;
@@ -994,49 +994,49 @@ nsXBLBinding::DoInitJSClass(JSContext *c
   *aNew = !desc.object();
   if (desc.object()) {
     proto = &desc.value().toObject();
     DebugOnly<nsXBLPrototypeBinding*> cachedBinding =
       GetProtoBindingFromClassObject(js::UncheckedUnwrap(proto));
     MOZ_ASSERT(cachedBinding == aProtoBinding);
   } else {
 
-    // We need to create the prototype. First, enter the compartment where it's
+    // We need to create the prototype. First, enter the realm where it's
     // going to live, and create it.
-    JSAutoCompartment ac2(cx, global);
+    JSAutoRealm ar2(cx, global);
     proto = JS_NewObjectWithGivenProto(cx, &gPrototypeJSClass, parent_proto);
     if (!proto) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
     // Keep this proto binding alive while we're alive.  Do this first so that
     // we can guarantee that in XBLFinalize this will be non-null.
     // Note that we can't just store aProtoBinding in the private and
     // addref/release the nsXBLDocumentInfo through it, because cycle
     // collection doesn't seem to work right if the private is not an
     // nsISupports.
     nsXBLDocumentInfo* docInfo = aProtoBinding->XBLDocumentInfo();
     ::JS_SetPrivate(proto, docInfo);
     NS_ADDREF(docInfo);
     JS_SetReservedSlot(proto, 0, JS::PrivateValue(aProtoBinding));
 
-    // Next, enter the compartment of the property holder, wrap the proto, and
+    // Next, enter the realm of the property holder, wrap the proto, and
     // stick it on.
-    JSAutoCompartment ac3(cx, holder);
+    JSAutoRealm ar3(cx, holder);
     if (!JS_WrapObject(cx, &proto) ||
         !JS_DefineUCProperty(cx, holder, aClassName.get(), -1, proto,
                              JSPROP_READONLY | JSPROP_PERMANENT))
     {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
-  // Whew. We have the proto. Wrap it back into the compartment of |obj|,
+  // Whew. We have the proto. Wrap it back into the realm of |obj|,
   // splice it in, and return it.
-  JSAutoCompartment ac4(cx, obj);
+  JSAutoRealm ar4(cx, obj);
   if (!JS_WrapObject(cx, &proto) || !JS_SetPrototype(cx, obj, proto)) {
     return NS_ERROR_FAILURE;
   }
   aClassObject.set(proto);
   return NS_OK;
 }
 
 bool
@@ -1105,17 +1105,17 @@ nsXBLBinding::LookupMember(JSContext* aC
     js::GetGlobalForObjectCrossCompartment(mBoundElement->GetWrapper()));
   MOZ_RELEASE_ASSERT(!xpc::IsInContentXBLScope(boundScope));
   JS::Rooted<JSObject*> xblScope(aCx, xpc::GetXBLScope(aCx, boundScope));
   NS_ENSURE_TRUE(xblScope, false);
   MOZ_ASSERT(boundScope != xblScope);
 
   // Enter the xbl scope and invoke the internal version.
   {
-    JSAutoCompartment ac(aCx, xblScope);
+    JSAutoRealm ar(aCx, xblScope);
     JS::Rooted<jsid> id(aCx, aId);
     if (!LookupMemberInternal(aCx, name, id, aDesc, xblScope)) {
       return false;
     }
   }
 
   // Wrap into the caller's scope.
   return JS_WrapPropertyDescriptor(aCx, aDesc);
--- a/dom/xbl/nsXBLProtoImpl.cpp
+++ b/dom/xbl/nsXBLProtoImpl.cpp
@@ -75,24 +75,24 @@ nsXBLProtoImpl::InstallImplementation(ns
 
   // We want to define the canonical set of members in a safe place. If we're
   // using a separate XBL scope, we want to define them there first (so that
   // they'll be available for Xray lookups, among other things), and then copy
   // the properties to the content-side prototype as needed. We don't need to
   // bother about the field accessors here, since we don't use/support those
   // for in-content bindings.
 
-  // First, start by entering the compartment of the XBL scope. This may or may
-  // not be the same compartment as globalObject.
+  // First, start by entering the realm of the XBL scope. This may or may
+  // not be the same realm as globalObject.
   JS::Rooted<JSObject*> globalObject(cx,
     GetGlobalForObjectCrossCompartment(targetClassObject));
   JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScopeOrGlobal(cx, globalObject));
   NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
   MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(scopeObject) == scopeObject);
-  JSAutoCompartment ac(cx, scopeObject);
+  JSAutoRealm ar(cx, scopeObject);
 
   // Determine the appropriate property holder.
   //
   // Note: If |targetIsNew| is false, we'll early-return above. However, that only
   // tells us if the content-side object is new, which may be the case even if
   // we've already set up the binding on the XBL side. For example, if we apply
   // a binding #foo to a <span> when we've already applied it to a <div>, we'll
   // end up with a different content prototype, but we'll already have a property
@@ -159,17 +159,17 @@ nsXBLProtoImpl::InstallImplementation(ns
 
         ok = JS_CopyPropertyFrom(cx, id, targetClassObject, propertyHolder);
         NS_ENSURE_TRUE(ok, NS_ERROR_UNEXPECTED);
       }
     }
   }
 
   // From here on out, work in the scope of the bound element.
-  JSAutoCompartment ac2(cx, targetClassObject);
+  JSAutoRealm ar2(cx, targetClassObject);
 
   // Install all of our field accessors.
   for (nsXBLProtoImplField* curr = mFields;
        curr;
        curr = curr->GetNext())
     curr->InstallAccessors(cx, targetClassObject);
 
   return NS_OK;
@@ -201,28 +201,28 @@ nsXBLProtoImpl::InitTargetObjects(nsXBLP
   }
 
   // Because our prototype implementation has a class, we need to build up a corresponding
   // class for the concrete implementation in the bound document.
   AutoJSContext cx;
   JS::Rooted<JSObject*> global(cx, sgo->GetGlobalJSObject());
   JS::Rooted<JS::Value> v(cx);
 
-  JSAutoCompartment ac(cx, global);
+  JSAutoRealm ar(cx, global);
   // Make sure the interface object is created before the prototype object
   // so that XULElement is hidden from content. See bug 909340.
   bool defineOnGlobal = dom::XULElementBinding::ConstructorEnabled(cx, global);
   dom::XULElementBinding::GetConstructorObjectHandle(cx, defineOnGlobal);
 
   rv = nsContentUtils::WrapNative(cx, aBoundElement, &v,
                                   /* aAllowWrapping = */ false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   JS::Rooted<JSObject*> value(cx, &v.toObject());
-  JSAutoCompartment ac2(cx, value);
+  JSAutoRealm ar2(cx, value);
 
   // All of the above code was just obtaining the bound element's script object and its immediate
   // concrete base class.  We need to alter the object so that our concrete class is interposed
   // between the object and its base class.  We become the new base class of the object, and the
   // object's old base class becomes the new class' base class.
   rv = aBinding->InitClass(mClassName, cx, value, aTargetClassObject, aTargetIsNew);
   if (NS_FAILED(rv)) {
     return rv;
--- a/dom/xbl/nsXBLProtoImplField.cpp
+++ b/dom/xbl/nsXBLProtoImplField.cpp
@@ -170,40 +170,40 @@ InstallXBLField(JSContext* cx,
     xpc::Throw(cx, NS_ERROR_UNEXPECTED);
     return false;
   }
 
   // Now that |this| is okay, actually install the field.
 
   // Because of the possibility (due to XBL binding inheritance, because each
   // XBL binding lives in its own global object) that |this| might be in a
-  // different compartment from the callee (not to mention that this method can
+  // different realm from the callee (not to mention that this method can
   // be called with an arbitrary |this| regardless of how insane XBL is), and
-  // because in this method we've entered |this|'s compartment (see in
-  // Field[GS]etter where we attempt a cross-compartment call), we must enter
-  // the callee's compartment to access its reserved slots.
+  // because in this method we've entered |this|'s realm (see in
+  // Field[GS]etter where we attempt a cross-realm call), we must enter
+  // the callee's realm to access its reserved slots.
   nsXBLPrototypeBinding* protoBinding;
   nsAutoJSString fieldName;
   {
-    JSAutoCompartment ac(cx, callee);
+    JSAutoRealm ar(cx, callee);
 
     JS::Rooted<JSObject*> xblProto(cx);
     xblProto = &js::GetFunctionNativeReserved(callee, XBLPROTO_SLOT).toObject();
 
     JS::Rooted<JS::Value> name(cx, js::GetFunctionNativeReserved(callee, FIELD_SLOT));
     if (!fieldName.init(cx, name.toString())) {
       return false;
     }
 
     MOZ_ALWAYS_TRUE(JS_ValueToId(cx, name, idp));
 
-    // If a separate XBL scope is being used, the callee is not same-compartment
+    // If a separate XBL scope is being used, the callee is not same-realm
     // with the xbl prototype, and the object is a cross-compartment wrapper.
     xblProto = js::UncheckedUnwrap(xblProto);
-    JSAutoCompartment ac2(cx, xblProto);
+    JSAutoRealm ar2(cx, xblProto);
     JS::Value slotVal = ::JS_GetReservedSlot(xblProto, 0);
     protoBinding = static_cast<nsXBLPrototypeBinding*>(slotVal.toPrivate());
     MOZ_ASSERT(protoBinding);
   }
 
   nsXBLProtoImplField* field = protoBinding->FindField(fieldName);
   MOZ_ASSERT(field);
 
@@ -221,17 +221,17 @@ InstallXBLField(JSContext* cx,
 bool
 FieldGetterImpl(JSContext *cx, const JS::CallArgs& args)
 {
   JS::Handle<JS::Value> thisv = args.thisv();
   MOZ_ASSERT(ValueHasISupportsPrivate(thisv));
 
   JS::Rooted<JSObject*> thisObj(cx, &thisv.toObject());
 
-  // We should be in the compartment of |this|. If we got here via nativeCall,
+  // We should be in the realm of |this|. If we got here via nativeCall,
   // |this| is not same-compartment with |callee|, and it's possible via
   // asymmetric security semantics that |args.calleev()| is actually a security
   // wrapper. In this case, we know we want to do an unsafe unwrap, and
   // InstallXBLField knows how to handle cross-compartment pointers.
   bool installed = false;
   JS::Rooted<JSObject*> callee(cx, js::UncheckedUnwrap(&args.calleev().toObject()));
   JS::Rooted<jsid> id(cx);
   if (!InstallXBLField(cx, callee, thisObj, &id, &installed)) {
@@ -257,17 +257,17 @@ FieldGetter(JSContext *cx, unsigned argc
 bool
 FieldSetterImpl(JSContext *cx, const JS::CallArgs& args)
 {
   JS::Handle<JS::Value> thisv = args.thisv();
   MOZ_ASSERT(ValueHasISupportsPrivate(thisv));
 
   JS::Rooted<JSObject*> thisObj(cx, &thisv.toObject());
 
-  // We should be in the compartment of |this|. If we got here via nativeCall,
+  // We should be in the realm of |this|. If we got here via nativeCall,
   // |this| is not same-compartment with |callee|, and it's possible via
   // asymmetric security semantics that |args.calleev()| is actually a security
   // wrapper. In this case, we know we want to do an unsafe unwrap, and
   // InstallXBLField knows how to handle cross-compartment pointers.
   bool installed = false;
   JS::Rooted<JSObject*> callee(cx, js::UncheckedUnwrap(&args.calleev().toObject()));
   JS::Rooted<jsid> id(cx);
   if (!InstallXBLField(cx, callee, thisObj, &id, &installed)) {
@@ -323,17 +323,17 @@ nsXBLProtoImplField::InstallAccessors(JS
     return NS_ERROR_FAILURE;
   if (found)
     return NS_OK;
 
   // FieldGetter and FieldSetter need to run in the XBL scope so that they can
   // see through any SOWs on their targets.
 
   // First, enter the XBL scope, and compile the functions there.
-  JSAutoCompartment ac(aCx, scopeObject);
+  JSAutoRealm ar(aCx, scopeObject);
   JS::Rooted<JS::Value> wrappedClassObj(aCx, JS::ObjectValue(*aTargetClassObject));
   if (!JS_WrapValue(aCx, &wrappedClassObj))
     return NS_ERROR_OUT_OF_MEMORY;
 
   JS::Rooted<JSObject*> get(aCx,
     JS_GetFunctionObject(js::NewFunctionByIdWithReserved(aCx, FieldGetter,
                                                          0, 0, id)));
   if (!get) {
@@ -350,17 +350,17 @@ nsXBLProtoImplField::InstallAccessors(JS
     return NS_ERROR_OUT_OF_MEMORY;
   }
   js::SetFunctionNativeReserved(set, XBLPROTO_SLOT, wrappedClassObj);
   js::SetFunctionNativeReserved(set, FIELD_SLOT,
                                 JS::StringValue(JSID_TO_STRING(id)));
 
   // Now, re-enter the class object's scope, wrap the getters/setters, and define
   // them there.
-  JSAutoCompartment ac2(aCx, aTargetClassObject);
+  JSAutoRealm ar2(aCx, aTargetClassObject);
   if (!JS_WrapObject(aCx, &get) || !JS_WrapObject(aCx, &set)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   if (!::JS_DefinePropertyById(aCx, aTargetClassObject, id,
                                JS_DATA_TO_FUNC_PTR(JSNative, get.get()),
                                JS_DATA_TO_FUNC_PTR(JSNative, set.get()),
                                AccessorAttributes())) {
@@ -396,17 +396,17 @@ nsXBLProtoImplField::InstallField(JS::Ha
   nsIGlobalObject* globalObject = xpc::WindowGlobalOrNull(aBoundNode);
   if (!globalObject) {
     return NS_OK;
   }
 
   // We are going to run script via EvaluateString, so we need a script entry
   // point, but as this is XBL related it does not appear in the HTML spec.
   // We need an actual JSContext to do GetXBLScopeOrGlobal, and it needs to
-  // be in the compartment of globalObject.  But we want our XBL execution scope
+  // be in the realm of globalObject.  But we want our XBL execution scope
   // to be our entry global.
   AutoJSAPI jsapi;
   if (!jsapi.Init(globalObject)) {
     return NS_ERROR_UNEXPECTED;
   }
   MOZ_ASSERT(!::JS_IsExceptionPending(jsapi.cx()),
              "Shouldn't get here when an exception is pending!");
 
@@ -445,23 +445,23 @@ nsXBLProtoImplField::InstallField(JS::Ha
 
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   if (rv == NS_SUCCESS_DOM_SCRIPT_EVALUATION_THREW) {
     // Report the exception now, before we try using the JSContext for
     // the JS_DefineUCProperty call.  Note that this reports in our current
-    // compartment, which is the XBL scope.
+    // realm, which is the XBL scope.
     aes.ReportException();
   }
 
-  // Now, enter the node's compartment, wrap the eval result, and define it on
+  // Now, enter the node's realm, wrap the eval result, and define it on
   // the bound node.
-  JSAutoCompartment ac2(cx, aBoundNode);
+  JSAutoRealm ar2(cx, aBoundNode);
   nsDependentString name(mName);
   if (!JS_WrapValue(cx, &result) ||
       !::JS_DefineUCProperty(cx, aBoundNode,
                              reinterpret_cast<const char16_t*>(mName),
                              name.Length(), result, mJSAttributes)) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
--- a/dom/xbl/nsXBLProtoImplMethod.cpp
+++ b/dom/xbl/nsXBLProtoImplMethod.cpp
@@ -183,17 +183,17 @@ nsXBLProtoImplMethod::CompileMember(Auto
   NS_ConvertUTF16toUTF8 cname(mName);
   NS_ConvertUTF16toUTF8 functionUri(aClassStr);
   int32_t hash = functionUri.RFindChar('#');
   if (hash != kNotFound) {
     functionUri.Truncate(hash);
   }
 
   JSContext *cx = jsapi.cx();
-  JSAutoCompartment ac(cx, aClassObject);
+  JSAutoRealm ar(cx, aClassObject);
   JS::CompileOptions options(cx);
   options.setFileAndLine(functionUri.get(),
                          uncompiledMethod->mBodyText.GetLineNumber());
   JS::Rooted<JSObject*> methodObject(cx);
   JS::AutoObjectVector emptyVector(cx);
   nsresult rv = nsJSUtils::CompileFunction(jsapi, emptyVector, options, cname,
                                            paramCount,
                                            const_cast<const char**>(args),
--- a/dom/xbl/nsXBLProtoImplProperty.cpp
+++ b/dom/xbl/nsXBLProtoImplProperty.cpp
@@ -184,17 +184,17 @@ nsXBLProtoImplProperty::CompileMember(Au
     }
   }
 
   bool deletedGetter = false;
   nsXBLTextWithLineNumber *getterText = mGetter.GetUncompiled();
   if (getterText && getterText->GetText()) {
     nsDependentString getter(getterText->GetText());
     if (!getter.IsEmpty()) {
-      JSAutoCompartment ac(cx, aClassObject);
+      JSAutoRealm ar(cx, aClassObject);
       JS::CompileOptions options(cx);
       options.setFileAndLine(functionUri.get(), getterText->GetLineNumber());
       nsCString name = NS_LITERAL_CSTRING("get_") + NS_ConvertUTF16toUTF8(mName);
       JS::Rooted<JSObject*> getterObject(cx);
       JS::AutoObjectVector emptyVector(cx);
       rv = nsJSUtils::CompileFunction(jsapi, emptyVector, options, name, 0,
                                       nullptr, getter, getterObject.address());
 
@@ -229,17 +229,17 @@ nsXBLProtoImplProperty::CompileMember(Au
     return rv;
   }
 
   bool deletedSetter = false;
   nsXBLTextWithLineNumber *setterText = mSetter.GetUncompiled();
   if (setterText && setterText->GetText()) {
     nsDependentString setter(setterText->GetText());
     if (!setter.IsEmpty()) {
-      JSAutoCompartment ac(cx, aClassObject);
+      JSAutoRealm ar(cx, aClassObject);
       JS::CompileOptions options(cx);
       options.setFileAndLine(functionUri.get(), setterText->GetLineNumber());
       nsCString name = NS_LITERAL_CSTRING("set_") + NS_ConvertUTF16toUTF8(mName);
       JS::Rooted<JSObject*> setterObject(cx);
       JS::AutoObjectVector emptyVector(cx);
       rv = nsJSUtils::CompileFunction(jsapi, emptyVector, options, name, 1,
                                       gPropertyArgs, setter,
                                       setterObject.address());
--- a/dom/xbl/nsXBLPrototypeHandler.cpp
+++ b/dom/xbl/nsXBLPrototypeHandler.cpp
@@ -349,17 +349,17 @@ nsXBLPrototypeHandler::ExecuteHandler(Ev
   NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
 
   // Bind it to the bound element. Note that if we're using a separate XBL scope,
   // we'll actually be binding the event handler to a cross-compartment wrapper
   // to the bound element's reflector.
 
   // First, enter our XBL scope. This is where the generic handler should have
   // been compiled, above.
-  JSAutoCompartment ac(cx, scopeObject);
+  JSAutoRealm ar(cx, scopeObject);
   JS::Rooted<JSObject*> genericHandler(cx, handler.get());
   bool ok = JS_WrapObject(cx, &genericHandler);
   NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
   MOZ_ASSERT(!js::IsCrossCompartmentWrapper(genericHandler));
 
   // Build a scope chain in the XBL scope.
   RefPtr<Element> targetElement = do_QueryObject(scriptTarget);
   JS::AutoObjectVector scopeChain(cx);
@@ -420,32 +420,32 @@ nsXBLPrototypeHandler::EnsureEventHandle
   NS_ENSURE_SUCCESS(rv, rv);
 
   uint32_t argCount;
   const char **argNames;
   nsContentUtils::GetEventArgNames(kNameSpaceID_XBL, aName, false, &argCount,
                                    &argNames);
 
   // Compile the event handler in the xbl scope.
-  JSAutoCompartment ac(cx, scopeObject);
+  JSAutoRealm ar(cx, scopeObject);
   JS::CompileOptions options(cx);
   options.setFileAndLine(bindingURI.get(), mLineNumber);
 
   JS::Rooted<JSObject*> handlerFun(cx);
   JS::AutoObjectVector emptyVector(cx);
   rv = nsJSUtils::CompileFunction(jsapi, emptyVector, options,
                                   nsAtomCString(aName), argCount,
                                   argNames, handlerText,
                                   handlerFun.address());
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ENSURE_TRUE(handlerFun, NS_ERROR_FAILURE);
 
   // Wrap the handler into the content scope, since we're about to stash it
   // on the DOM window and such.
-  JSAutoCompartment ac2(cx, globalObject);
+  JSAutoRealm ar2(cx, globalObject);
   bool ok = JS_WrapObject(cx, &handlerFun);
   NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);
   aHandler.set(handlerFun);
   NS_ENSURE_TRUE(aHandler, NS_ERROR_FAILURE);
 
   if (pWindow) {
     pWindow->CacheXBLPrototypeHandler(this, aHandler);
   }
--- a/dom/xul/XULDocument.cpp
+++ b/dom/xul/XULDocument.cpp
@@ -3227,17 +3227,17 @@ XULDocument::ExecuteScript(nsXULPrototyp
 
     JS::Rooted<JSScript*> scriptObject(cx, aScript->GetScriptObject());
     NS_ENSURE_TRUE(scriptObject, NS_ERROR_UNEXPECTED);
 
     JS::Rooted<JSObject*> global(cx, JS::CurrentGlobalOrNull(cx));
     NS_ENSURE_TRUE(xpc::Scriptability::Get(global).Allowed(), NS_OK);
 
     JS::ExposeObjectToActiveJS(global);
-    JSAutoCompartment ac(cx, global);
+    JSAutoRealm ar(cx, global);
 
     // The script is in the compilation scope. Clone it into the target scope
     // and execute it. On failure, ~AutoScriptEntry will handle exceptions, so
     // there is no need to manually check the return value.
     JS::RootedValue rval(cx);
     JS::CloneAndExecuteScript(cx, scriptObject, &rval);
 
     return NS_OK;
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -382,17 +382,17 @@ XPCShellEnvironment::~XPCShellEnvironmen
         AutoJSAPI jsapi;
         if (!jsapi.Init(GetGlobalObject())) {
             return;
         }
         JSContext* cx = jsapi.cx();
         Rooted<JSObject*> global(cx, GetGlobalObject());
 
         {
-            JSAutoCompartment ac(cx, global);
+            JSAutoRealm ar(cx, global);
             JS_SetAllNonReservedSlotsToUndefined(cx, global);
         }
         mGlobalHolder.reset();
 
         JS_GC(cx);
     }
 }
 
@@ -443,17 +443,17 @@ XPCShellEnvironment::Init()
         NS_ERROR("InitClassesWithNewWrappedGlobal failed!");
         return false;
     }
 
     if (!globalObj) {
         NS_ERROR("Failed to get global JSObject!");
         return false;
     }
-    JSAutoCompartment ac(cx, globalObj);
+    JSAutoRealm ar(cx, globalObj);
 
     backstagePass->SetGlobalObject(globalObj);
 
     JS::Rooted<Value> privateVal(cx, PrivateValue(this));
     if (!JS_DefineProperty(cx, globalObj, "__XPCShellEnvironment",
                            privateVal,
                            JSPROP_READONLY | JSPROP_PERMANENT) ||
         !JS_DefineFunctions(cx, globalObj, gGlobalFunctions) ||
--- a/js/ductwork/debugger/JSDebugger.cpp
+++ b/js/ductwork/debugger/JSDebugger.cpp
@@ -45,17 +45,17 @@ JSDebugger::AddClass(JS::Handle<JS::Valu
   }
 
   JS::RootedObject obj(cx, &global.toObject());
   obj = js::UncheckedUnwrap(obj, /* stopAtWindowProxy = */ false);
   if (!obj) {
     return NS_ERROR_FAILURE;
   }
 
-  JSAutoCompartment ac(cx, obj);
+  JSAutoRealm ar(cx, obj);
   if (JS_GetGlobalForObject(cx, obj) != obj) {
     return NS_ERROR_INVALID_ARG;
   }
 
   if (!JS_DefineDebuggerObject(cx, obj)) {
     return NS_ERROR_FAILURE;
   }
 
--- a/js/ipc/JavaScriptLogging.h
+++ b/js/ipc/JavaScriptLogging.h
@@ -101,17 +101,17 @@ class Logging
         const char* side;
         const char* objDesc;
         void* ptr;
 
         if (local == incoming) {
             JS::RootedObject obj(cx);
             obj = shared->objects_.find(id);
             if (obj) {
-                JSAutoCompartment ac(cx, obj);
+                JSAutoRealm ar(cx, obj);
                 objDesc = js::ObjectClassName(cx, obj);
             } else {
                 objDesc = "<dead object>";
             }
 
             side = shared->isParent() ? "parent" : "child";
             ptr = js::UncheckedUnwrap(obj, true);
         } else {
--- a/js/ipc/JavaScriptParent.cpp
+++ b/js/ipc/JavaScriptParent.cpp
@@ -68,17 +68,17 @@ JavaScriptParent::allowMessage(JSContext
 
     MessageChannel* channel = GetIPCChannel();
     bool isSafe = channel->IsInTransaction();
 
     bool warn = !isSafe;
     nsIGlobalObject* global = dom::GetIncumbentGlobal();
     JS::Rooted<JSObject*> jsGlobal(cx, global ? global->GetGlobalJSObject() : nullptr);
     if (jsGlobal) {
-        JSAutoCompartment ac(cx, jsGlobal);
+        JSAutoRealm ar(cx, jsGlobal);
 
         if (!xpc::CompartmentPrivate::Get(jsGlobal)->allowCPOWs) {
             if (ForbidUnsafeBrowserCPOWs() && !isSafe) {
                 Telemetry::Accumulate(Telemetry::BROWSER_SHIM_USAGE_BLOCKED, 1);
                 JS_ReportErrorASCII(cx, "unsafe CPOW usage forbidden");
                 return false;
             }
         }
--- a/js/ipc/JavaScriptShared.cpp
+++ b/js/ipc/JavaScriptShared.cpp
@@ -531,20 +531,20 @@ JavaScriptShared::findObjectById(JSConte
         JS_ReportErrorASCII(cx, "operation not possible on dead CPOW");
         return nullptr;
     }
 
     // Each process has a dedicated compartment for CPOW targets. All CPOWs
     // from the other process point to objects in this scope. From there, they
     // can access objects in other compartments using cross-compartment
     // wrappers.
-    JSAutoCompartment ac(cx, scopeForTargetObjects());
+    JSAutoRealm ar(cx, scopeForTargetObjects());
     if (objId.hasXrayWaiver()) {
         {
-            JSAutoCompartment ac2(cx, obj);
+            JSAutoRealm ar2(cx, obj);
             obj = js::ToWindowProxyIfWindow(obj);
             MOZ_ASSERT(obj);
         }
         if (!xpc::WrapperFactory::WaiveXrayAndWrap(cx, &obj))
             return nullptr;
     } else {
         if (!JS_WrapObject(cx, &obj))
             return nullptr;
--- a/js/ipc/WrapperOwner.cpp
+++ b/js/ipc/WrapperOwner.cpp
@@ -1182,17 +1182,17 @@ JSObject*
 WrapperOwner::fromRemoteObjectVariant(JSContext* cx, const RemoteObject& objVar)
 {
     ObjectId objId = ObjectId::deserialize(objVar.serializedId());
     RootedObject obj(cx, findCPOWById(objId));
     if (!obj) {
 
         // All CPOWs live in the privileged junk scope.
         RootedObject junkScope(cx, xpc::PrivilegedJunkScope());
-        JSAutoCompartment ac(cx, junkScope);
+        JSAutoRealm ar(cx, junkScope);
         RootedValue v(cx, UndefinedValue());
         // We need to setLazyProto for the getPrototype/getPrototypeIfOrdinary
         // hooks.
         ProxyOptions options;
         options.setLazyProto(true);
         obj = NewProxyObject(cx,
                              &CPOWProxyHandler::singleton,
                              v,
--- a/js/rust/build.rs
+++ b/js/rust/build.rs
@@ -157,17 +157,17 @@ const WHITELIST_TYPES: &'static [&'stati
     "JS::Handle",
     "JS::HandleFunction",
     "JS::HandleId",
     "JS::HandleObject",
     "JS::HandleString",
     "JS::HandleValue",
     "JS::HandleValueArray",
     "JS::IsAcceptableThis",
-    "JSAutoCompartment",
+    "JSAutoRealm",
     "JSAutoStructuredCloneBuffer",
     "JSClass",
     "JSClassOps",
     "JSContext",
     "JSErrNum",
     "JSErrorCallback",
     "JSErrorFormatString",
     "JSErrorReport",
--- a/js/rust/src/ac.rs
+++ b/js/rust/src/ac.rs
@@ -1,56 +1,56 @@
 use jsapi::root::*;
 #[cfg(feature = "debugmozjs")]
 use std::ptr;
 
 #[derive(Debug)]
-pub struct AutoCompartment(JSAutoCompartment);
+pub struct AutoCompartment(JSAutoRealm);
 
 impl AutoCompartment {
     #[cfg(feature = "debugmozjs")]
     pub unsafe fn with_obj(cx: *mut JSContext,
                            target: *mut JSObject)
                            -> AutoCompartment
     {
         let mut notifier = mozilla::detail::GuardObjectNotifier {
             mStatementDone: ptr::null_mut(),
         };
 
         AutoCompartment(
-            JSAutoCompartment::new(
+            JSAutoRealm::new(
                 cx,
                 target,
                 &mut notifier as *mut _))
     }
 
     #[cfg(not(feature = "debugmozjs"))]
     pub unsafe fn with_obj(cx: *mut JSContext,
                            target: *mut JSObject)
                            -> AutoCompartment
     {
-        AutoCompartment(JSAutoCompartment::new(cx, target))
+        AutoCompartment(JSAutoRealm::new(cx, target))
     }
 
     #[cfg(feature = "debugmozjs")]
     pub unsafe fn with_script(cx: *mut JSContext,
                               target: *mut JSScript)
                               -> AutoCompartment
     {
         let mut notifier = mozilla::detail::GuardObjectNotifier {
             mStatementDone: ptr::null_mut(),
         };
 
         AutoCompartment(
-            JSAutoCompartment::new1(
+            JSAutoRealm::new1(
                 cx,
                 target,
                 &mut notifier as *mut _))
     }
 
     #[cfg(not(feature = "debugmozjs"))]
     pub unsafe fn with_script(cx: *mut JSContext,
                               target: *mut JSScript)
                               -> AutoCompartment
     {
-        AutoCompartment(JSAutoCompartment::new1(cx, target))
+        AutoCompartment(JSAutoRealm::new1(cx, target))
     }
 }
--- a/js/rust/src/rust.rs
+++ b/js/rust/src/rust.rs
@@ -604,17 +604,17 @@ impl GCMethods for JS::Value {
     unsafe fn post_barrier(v: *mut JS::Value, prev: JS::Value, next: JS::Value) {
         JS::HeapValuePostBarrier(v, &prev, &next);
     }
 }
 
 // ___________________________________________________________________________
 // Implementations for various things in jsapi.rs
 
-impl Drop for JSAutoCompartment {
+impl Drop for JSAutoRealm {
     fn drop(&mut self) {
         unsafe { JS_LeaveCompartment(self.cx_, self.oldCompartment_); }
     }
 }
 
 impl JSJitMethodCallArgs {
     #[inline]
     pub fn get(&self, i: u32) -> JS::HandleValue {
--- a/js/src/builtin/DataViewObject.cpp
+++ b/js/src/builtin/DataViewObject.cpp
@@ -229,17 +229,17 @@ DataViewObject::constructWrapped(JSConte
     if (!proto) {
         proto = GlobalObject::getOrCreateDataViewPrototype(cx, global);
         if (!proto)
             return false;
     }
 
     RootedObject dv(cx);
     {
-        JSAutoCompartment ac(cx, unwrapped);
+        JSAutoRealm ar(cx, unwrapped);
 
         Rooted<ArrayBufferObjectMaybeShared*> buffer(cx);
         buffer = &unwrapped->as<ArrayBufferObjectMaybeShared>();
 
         RootedObject wrappedProto(cx, proto);
         if (!cx->compartment()->wrap(cx, &wrappedProto))
             return false;
 
--- a/js/src/builtin/MapObject.cpp
+++ b/js/src/builtin/MapObject.cpp
@@ -1689,34 +1689,34 @@ CallObjFunc(RetT(*ObjFunc)(JSContext*, H
 {
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj);
 
     // Always unwrap, in case this is an xray or cross-compartment wrapper.
     RootedObject unwrappedObj(cx);
     unwrappedObj = UncheckedUnwrap(obj);
 
-    // Enter the compartment of the backing object before calling functions on
+    // Enter the realm of the backing object before calling functions on
     // it.
-    JSAutoCompartment ac(cx, unwrappedObj);
+    JSAutoRealm ar(cx, unwrappedObj);
     return ObjFunc(cx, unwrappedObj);
 }
 
 // Handles Has/Delete for public jsapi map/set access
 bool
 CallObjFunc(bool(*ObjFunc)(JSContext *cx, HandleObject obj, HandleValue key, bool *rval),
             JSContext *cx, HandleObject obj, HandleValue key, bool *rval)
 {
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, key);
 
     // Always unwrap, in case this is an xray or cross-compartment wrapper.
     RootedObject unwrappedObj(cx);
     unwrappedObj = UncheckedUnwrap(obj);
-    JSAutoCompartment ac(cx, unwrappedObj);
+    JSAutoRealm ar(cx, unwrappedObj);
 
     // If we're working with a wrapped map/set, rewrap the key into the
     // compartment of the unwrapped map/set.
     RootedValue wrappedKey(cx, key);
     if (obj != unwrappedObj) {
         if (!JS_WrapValue(cx, &wrappedKey))
             return false;
     }
@@ -1734,17 +1734,17 @@ CallObjFunc(bool(*ObjFunc)(JSContext* cx
     assertSameCompartment(cx, obj);
 
     // Always unwrap, in case this is an xray or cross-compartment wrapper.
     RootedObject unwrappedObj(cx);
     unwrappedObj = UncheckedUnwrap(obj);
     {
         // Retrieve the iterator while in the unwrapped map/set's compartment,
         // otherwise we'll crash on a compartment assert.
-        JSAutoCompartment ac(cx, unwrappedObj);
+        JSAutoRealm ar(cx, unwrappedObj);
         if (!ObjFunc(cx, iterType, unwrappedObj, rval))
             return false;
     }
 
     // If the caller is in a different compartment than the map/set, rewrap the
     // iterator object into the caller's compartment.
     if (obj != unwrappedObj) {
         if (!JS_WrapValue(cx, rval))
@@ -1768,22 +1768,22 @@ JS::MapSize(JSContext* cx, HandleObject 
 }
 
 JS_PUBLIC_API(bool)
 JS::MapGet(JSContext* cx, HandleObject obj, HandleValue key, MutableHandleValue rval)
 {
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, key, rval);
 
-    // Unwrap the object, and enter its compartment. If object isn't wrapped,
+    // Unwrap the object, and enter its realm. If object isn't wrapped,
     // this is essentially a noop.
     RootedObject unwrappedObj(cx);
     unwrappedObj = UncheckedUnwrap(obj);
     {
-        JSAutoCompartment ac(cx, unwrappedObj);
+        JSAutoRealm ar(cx, unwrappedObj);
         RootedValue wrappedKey(cx, key);
 
         // If we passed in a wrapper, wrap our key into its compartment now.
         if (obj != unwrappedObj) {
             if (!JS_WrapValue(cx, &wrappedKey))
                 return false;
         }
         if (!MapObject::get(cx, unwrappedObj, wrappedKey, rval))
@@ -1804,17 +1804,17 @@ JS::MapSet(JSContext *cx, HandleObject o
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, key, val);
 
     // Unwrap the object, and enter its compartment. If object isn't wrapped,
     // this is essentially a noop.
     RootedObject unwrappedObj(cx);
     unwrappedObj = UncheckedUnwrap(obj);
     {
-        JSAutoCompartment ac(cx, unwrappedObj);
+        JSAutoRealm ar(cx, unwrappedObj);
 
         // If we passed in a wrapper, wrap both key and value before adding to
         // the map
         RootedValue wrappedKey(cx, key);
         RootedValue wrappedValue(cx, val);
         if (obj != unwrappedObj) {
             if (!JS_WrapValue(cx, &wrappedKey) ||
                 !JS_WrapValue(cx, &wrappedValue)) {
@@ -1885,17 +1885,17 @@ JS::SetAdd(JSContext *cx, HandleObject o
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, key);
 
     // Unwrap the object, and enter its compartment. If object isn't wrapped,
     // this is essentially a noop.
     RootedObject unwrappedObj(cx);
     unwrappedObj = UncheckedUnwrap(obj);
     {
-        JSAutoCompartment ac(cx, unwrappedObj);
+        JSAutoRealm ar(cx, unwrappedObj);
 
         // If we passed in a wrapper, wrap key before adding to the set
         RootedValue wrappedKey(cx, key);
         if (obj != unwrappedObj) {
             if (!JS_WrapValue(cx, &wrappedKey))
                 return false;
         }
         return SetObject::add(cx, unwrappedObj, wrappedKey);
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -1966,17 +1966,17 @@ PerformPromiseAll(JSContext *cx, JS::For
     // should be OK because the only things we hand the
     // PromiseAllResolveElement function to are the "then" calls we do and in
     // the case when the Promise's compartment is not the current compartment
     // those are happening over Xrays anyway, which means they get the
     // canonical "then" function and content can't see our
     // PromiseAllResolveElement.
     RootedObject valuesArray(cx);
     if (unwrappedPromiseObj) {
-        JSAutoCompartment ac(cx, unwrappedPromiseObj);
+        JSAutoRealm ar(cx, unwrappedPromiseObj);
         valuesArray = NewDenseFullyAllocatedArray(cx, 0);
     } else {
         valuesArray = NewDenseFullyAllocatedArray(cx, 0);
     }
     if (!valuesArray)
         return false;
 
     RootedValue valuesArrayVal(cx, ObjectValue(*valuesArray));
@@ -2025,20 +2025,20 @@ PerformPromiseAll(JSContext *cx, JS::For
                                              promiseObj);
             }
 
             // We're all set for now!
             return true;
         }
 
         // Step h.
-        { // Scope for the JSAutoCompartment we need to work with valuesArray.  We
+        { // Scope for the JSAutoRealm we need to work with valuesArray.  We
             // mostly do this for performance; we could go ahead and do the define via
             // a cross-compartment proxy instead...
-            JSAutoCompartment ac(cx, valuesArray);
+            JSAutoRealm ar(cx, valuesArray);
             indexId = INT_TO_JSID(index);
             if (!DefineDataProperty(cx, valuesArray, indexId, UndefinedHandleValue))
                 return false;
         }
 
         // Step i.
         // Sadly, because someone could have overridden
         // "resolve" on the canonical Promise constructor.
--- a/js/src/devtools/rootAnalysis/annotations.js
+++ b/js/src/devtools/rootAnalysis/annotations.js
@@ -196,17 +196,17 @@ var ignoreFunctions = {
     "NS_LogCOMPtrRelease": true,
 
     // FIXME!
     "NS_DebugBreak": true,
 
     // These are a little overzealous -- these destructors *can* GC if they end
     // up wrapping a pending exception. See bug 898815 for the heavyweight fix.
     "void js::AutoCompartment::~AutoCompartment(int32)" : true,
-    "void JSAutoCompartment::~JSAutoCompartment(int32)" : true,
+    "void JSAutoRealm::~JSAutoRealm(int32)" : true,
 
     // Similar to heap snapshot mock classes, and GTests below. This posts a
     // synchronous runnable when a GTest fails, and we are pretty sure that the
     // particular runnable it posts can't even GC, but the analysis isn't
     // currently smart enough to determine that. In either case, this is (a)
     // only in GTests, and (b) only when the Gtest has already failed. We have
     // static and dynamic checks for no GC in the non-test code, and in the test
     // code we fall back to only the dynamic checks.
--- a/js/src/fuzz-tests/tests.cpp
+++ b/js/src/fuzz-tests/tests.cpp
@@ -48,17 +48,17 @@ jsfuzz_createGlobal(JSContext* cx, JSPri
 #ifdef ENABLE_STREAMS
     options.creationOptions().setStreamsEnabled(true);
 #endif
     newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), principals, JS::FireOnNewGlobalHook,
                                    options);
     if (!newGlobal)
         return nullptr;
 
-    JSAutoCompartment ac(cx, newGlobal);
+    JSAutoRealm ar(cx, newGlobal);
 
     // Populate the global object with the standard globals like Object and
     // Array.
     if (!JS_InitStandardClasses(cx, newGlobal))
         return nullptr;
 
     return newGlobal;
 }
--- a/js/src/gdb/gdb-tests.cpp
+++ b/js/src/gdb/gdb-tests.cpp
@@ -77,23 +77,23 @@ main(int argc, const char** argv)
     JSContext* cx = checkPtr(JS_NewContext(1024 * 1024));
 
     JS_SetGCParameter(cx, JSGC_MAX_BYTES, 0xffffffff);
     JS_SetNativeStackQuota(cx, 5000000);
 
     checkBool(JS::InitSelfHostedCode(cx));
     JS::SetWarningReporter(cx, reportWarning);
 
-    JSAutoRequest ar(cx);
+    JSAutoRequest areq(cx);
 
     /* Create the global object. */
     JS::CompartmentOptions options;
     RootedObject global(cx, checkPtr(JS_NewGlobalObject(cx, &global_class,
                         nullptr, JS::FireOnNewGlobalHook, options)));
-    JSAutoCompartment ac(cx, global);
+    JSAutoRealm ar(cx, global);
 
     /* Populate the global object with the standard globals,
        like Object and Array. */
     checkBool(JS_InitStandardClasses(cx, global));
 
     argv++;
     while (*argv) {
         const char* name = *argv++;
--- a/js/src/jsapi-tests/testBug604087.cpp
+++ b/js/src/jsapi-tests/testBug604087.cpp
@@ -14,17 +14,17 @@
 
 const js::Class OuterWrapperClass = PROXY_CLASS_DEF(
     "Proxy",
     JSCLASS_HAS_RESERVED_SLOTS(1) /* additional class flags */);
 
 static JSObject*
 wrap(JSContext* cx, JS::HandleObject toWrap, JS::HandleObject target)
 {
-    JSAutoCompartment ac(cx, target);
+    JSAutoRealm ar(cx, target);
     JS::RootedObject wrapper(cx, toWrap);
     if (!JS_WrapObject(cx, &wrapper))
         return nullptr;
     return wrapper;
 }
 
 static void
 PreWrap(JSContext* cx, JS::HandleObject scope, JS::HandleObject obj,
@@ -75,17 +75,17 @@ BEGIN_TEST(testBug604087)
 
     JS::RootedObject c4wrapper(cx, wrap(cx, outerObj, compartment4));
     CHECK(c4wrapper);
     c4wrapper->as<js::ProxyObject>().setReservedSlot(0, js::Int32Value(4));
     compartment4 = c4wrapper = nullptr;
 
     JS::RootedObject next(cx);
     {
-        JSAutoCompartment ac(cx, compartment2);
+        JSAutoRealm ar(cx, compartment2);
         next = js::Wrapper::New(cx, compartment2, &js::Wrapper::singleton, options);
         CHECK(next);
     }
 
     JS_SetWrapObjectCallbacks(cx, &WrapObjectCallbacks);
     CHECK(JS_TransplantObject(cx, outerObj, next));
     return true;
 }
--- a/js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp
+++ b/js/src/jsapi-tests/testCallNonGenericMethodOnProxy.cpp
@@ -58,17 +58,17 @@ BEGIN_TEST(test_CallNonGenericMethodOnPr
   // Now create the second global object and compartment...
   {
     JS::CompartmentOptions options;
     JS::RootedObject globalB(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr,
 						    JS::FireOnNewGlobalHook, options));
     CHECK(globalB);
 
     // ...and enter it.
-    JSAutoCompartment enter(cx, globalB);
+    JSAutoRealm enter(cx, globalB);
     JS::RootedObject customB(cx, JS_NewObject(cx, &CustomClass));
     CHECK(customB);
     JS_SetReservedSlot(customB, CUSTOM_SLOT, Int32Value(42));
 
     JS::RootedFunction customMethodB(cx, JS_NewFunction(cx, CustomMethod, 0, 0,
 							"customMethodB"));
     CHECK(customMethodB);
 
--- a/js/src/jsapi-tests/testChromeBuffer.cpp
+++ b/js/src/jsapi-tests/testChromeBuffer.cpp
@@ -33,17 +33,17 @@ static JS::PersistentRootedObject truste
 
 static bool
 CallTrusted(JSContext* cx, unsigned argc, JS::Value* vp)
 {
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
 
     bool ok = false;
     {
-        JSAutoCompartment ac(cx, trusted_glob);
+        JSAutoRealm ar(cx, trusted_glob);
         JS::RootedValue funVal(cx, JS::ObjectValue(*trusted_fun));
         ok = JS_CallFunctionValue(cx, nullptr, funVal, JS::HandleValueArray::empty(), args.rval());
     }
     return ok;
 }
 
 BEGIN_TEST(testChromeBuffer)
 {
@@ -61,17 +61,17 @@ BEGIN_TEST(testChromeBuffer)
      * compiled with "trusted principals" can run using reserved trusted-only
      * buffer space.
      */
     {
         // Disable the JIT because if we don't this test fails.  See bug 1160414.
         JS::ContextOptions oldOptions = JS::ContextOptionsRef(cx);
         JS::ContextOptionsRef(cx).setIon(false).setBaseline(false);
         {
-            JSAutoCompartment ac(cx, trusted_glob);
+            JSAutoRealm ar(cx, trusted_glob);
             const char* paramName = "x";
             const char* bytes = "return x ? 1 + trusted(x-1) : 0";
             JS::CompileOptions options(cx);
             options.setFileAndLine("", 0);
             JS::AutoObjectVector emptyScopeChain(cx);
             CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "trusted",
                                       1, &paramName, bytes, strlen(bytes), &fun));
             CHECK(JS_DefineProperty(cx, trusted_glob, "trusted", fun, JSPROP_ENUMERATE));
@@ -105,17 +105,17 @@ BEGIN_TEST(testChromeBuffer)
     }
 
     /*
      * Check that content called from chrome in the reserved-buffer space
      * immediately ooms.
      */
     {
         {
-            JSAutoCompartment ac(cx, trusted_glob);
+            JSAutoRealm ar(cx, trusted_glob);
             const char* paramName = "untrusted";
             const char* bytes = "try {                                  "
                                 "  untrusted();                         "
                                 "} catch (e) {                          "
                                 "  /*                                   "
                                 "   * Careful!  We must not reenter JS  "
                                 "   * that might try to push a frame.   "
                                 "   */                                  "
@@ -151,17 +151,17 @@ BEGIN_TEST(testChromeBuffer)
         CHECK(JS_CallFunction(cx, nullptr, fun, JS::HandleValueArray(v), &rval));
         bool match;
         CHECK(JS_StringEqualsAscii(cx, rval.toString(), "From trusted: InternalError: too much recursion", &match));
         CHECK(match);
     }
 
     {
         {
-            JSAutoCompartment ac(cx, trusted_glob);
+            JSAutoRealm ar(cx, trusted_glob);
             const char* bytes = "return 42";
             JS::CompileOptions options(cx);
             options.setFileAndLine("", 0);
             JS::AutoObjectVector emptyScopeChain(cx);
             CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "trusted",
                                       0, nullptr, bytes, strlen(bytes), &fun));
             CHECK(JS_DefineProperty(cx, trusted_glob, "trusted", fun, JSPROP_ENUMERATE));
             trusted_fun = JS_GetFunctionObject(fun);
--- a/js/src/jsapi-tests/testCloneScript.cpp
+++ b/js/src/jsapi-tests/testCloneScript.cpp
@@ -26,29 +26,29 @@ BEGIN_TEST(test_cloneScript)
         "    ++i;\n"
         "}\n"
         "(sum);\n";
 
     JS::RootedObject obj(cx);
 
     // compile for A
     {
-        JSAutoCompartment a(cx, A);
+        JSAutoRealm a(cx, A);
         JS::RootedFunction fun(cx);
         JS::CompileOptions options(cx);
         options.setFileAndLine(__FILE__, 1);
         JS::AutoObjectVector emptyScopeChain(cx);
         CHECK(JS::CompileFunction(cx, emptyScopeChain, options, "f", 0, nullptr,
                                   source, strlen(source), &fun));
         CHECK(obj = JS_GetFunctionObject(fun));
     }
 
     // clone into B
     {
-        JSAutoCompartment b(cx, B);
+        JSAutoRealm b(cx, B);
         CHECK(JS::CloneFunctionObject(cx, obj));
     }
 
     return true;
 }
 END_TEST(test_cloneScript)
 
 struct Principals final : public JSPrincipals
@@ -107,17 +107,17 @@ BEGIN_TEST(test_cloneScriptWithPrincipal
 
     const char* argnames[] = { "arg" };
     const char* source = "return function() { return arg; }";
 
     JS::RootedObject obj(cx);
 
     // Compile in A
     {
-        JSAutoCompartment a(cx, A);
+        JSAutoRealm a(cx, A);
         JS::CompileOptions options(cx);
         options.setFileAndLine(__FILE__, 1);
         JS::RootedFunction fun(cx);
         JS::AutoObjectVector emptyScopeChain(cx);
         JS::CompileFunction(cx, emptyScopeChain, options, "f",
                            mozilla::ArrayLength(argnames), argnames, source,
                            strlen(source), &fun);
         CHECK(fun);
@@ -126,17 +126,17 @@ BEGIN_TEST(test_cloneScriptWithPrincipal
         CHECK(script = JS_GetFunctionScript(cx, fun));
 
         CHECK(JS_GetScriptPrincipals(script) == principalsA);
         CHECK(obj = JS_GetFunctionObject(fun));
     }
 
     // Clone into B
     {
-        JSAutoCompartment b(cx, B);
+        JSAutoRealm b(cx, B);
         JS::RootedObject cloned(cx);
         CHECK(cloned = JS::CloneFunctionObject(cx, obj));
 
         JS::RootedFunction fun(cx);
         JS::RootedValue clonedValue(cx, JS::ObjectValue(*cloned));
         CHECK(fun = JS_ValueToFunction(cx, clonedValue));
 
         JSScript* script;
--- a/js/src/jsapi-tests/testDebugger.cpp
+++ b/js/src/jsapi-tests/testDebugger.cpp
@@ -14,17 +14,17 @@ BEGIN_TEST(testDebugger_newScriptHook)
 {
     // Test that top-level indirect eval fires the newScript hook.
     CHECK(JS_DefineDebuggerObject(cx, global));
     JS::CompartmentOptions options;
     JS::RootedObject g(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr,
                                               JS::FireOnNewGlobalHook, options));
     CHECK(g);
     {
-        JSAutoCompartment ae(cx, g);
+        JSAutoRealm ae(cx, g);
         CHECK(JS_InitStandardClasses(cx, g));
     }
 
     JS::RootedObject gWrapper(cx, g);
     CHECK(JS_WrapObject(cx, &gWrapper));
     JS::RootedValue v(cx, JS::ObjectValue(*gWrapper));
     CHECK(JS_SetProperty(cx, global, "g", v));
 
@@ -43,17 +43,17 @@ BEGIN_TEST(testDebugger_newScriptHook)
     return testIndirectEval(g, "Math.abs(0)");
 }
 
 bool testIndirectEval(JS::HandleObject scope, const char* code)
 {
     EXEC("hits = 0;");
 
     {
-        JSAutoCompartment ae(cx, scope);
+        JSAutoRealm ae(cx, scope);
         JSString* codestr = JS_NewStringCopyZ(cx, code);
         CHECK(codestr);
         JS::RootedValue arg(cx, JS::StringValue(codestr));
         JS::RootedValue v(cx);
         CHECK(JS_CallFunctionName(cx, scope, "eval", HandleValueArray(arg), &v));
     }
 
     JS::RootedValue hitsv(cx);
--- a/js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp
+++ b/js/src/jsapi-tests/testFreshGlobalEvalRedefinition.cpp
@@ -28,17 +28,17 @@ BEGIN_TEST(testRedefineGlobalEval)
     };
 
     /* Create the global object. */
     JS::CompartmentOptions options;
     JS::Rooted<JSObject*> g(cx, JS_NewGlobalObject(cx, &cls, nullptr, JS::FireOnNewGlobalHook, options));
     if (!g)
         return false;
 
-    JSAutoCompartment ac(cx, g);
+    JSAutoRealm ar(cx, g);
     JS::Rooted<JS::Value> v(cx);
     CHECK(JS_GetProperty(cx, g, "Object", &v));
 
     static const char data[] = "Object.defineProperty(this, 'eval', { configurable: false });";
     JS::CompileOptions opts(cx);
     CHECK(JS::Evaluate(cx, opts.setFileAndLine(__FILE__, __LINE__),
                        data, mozilla::ArrayLength(data) - 1, &v));
 
--- a/js/src/jsapi-tests/testGCGrayMarking.cpp
+++ b/js/src/jsapi-tests/testGCGrayMarking.cpp
@@ -40,17 +40,17 @@ BEGIN_TEST(testGCGrayMarking)
 {
     AutoNoAnalysisForTest disableAnalysis;
     AutoDisableCompactingGC disableCompactingGC(cx);
 #ifdef JS_GC_ZEAL
     AutoLeaveZeal nozeal(cx);
 #endif /* JS_GC_ZEAL */
 
     CHECK(InitGlobals());
-    JSAutoCompartment ac(cx, global1);
+    JSAutoRealm ar(cx, global1);
 
     InitGrayRootTracer();
 
     bool ok =
         TestMarking() &&
         TestWeakMaps() &&
         TestUnassociatedWeakMaps() &&
         TestCCWs() &&
@@ -652,17 +652,17 @@ AllocSameCompartmentSourceObject(JSObjec
     return source;
 }
 
 JSObject*
 GetCrossCompartmentWrapper(JSObject* target)
 {
     MOZ_ASSERT(target->compartment() == global1->compartment());
     JS::RootedObject obj(cx, target);
-    JSAutoCompartment ac(cx, global2);
+    JSAutoRealm ar(cx, global2);
     if (!JS_WrapObject(cx, &obj))
         return nullptr;
 
     EvictNursery();
 
     MOZ_ASSERT(obj->compartment() == global2->compartment());
     return obj;
 }
--- a/js/src/jsapi-tests/testGCMarking.cpp
+++ b/js/src/jsapi-tests/testGCMarking.cpp
@@ -40,17 +40,17 @@ ConstructCCW(JSContext* cx, const JSClas
     // This checks that the API obeys the implicit zone request.
     if (global1->zone() == global2->zone()) {
         fprintf(stderr, "global2 is in global1's zone");
         return false;
     }
 
     // Define an object in compartment 2, that is wrapped by a CCW into compartment 1.
     {
-        JSAutoCompartment ac(cx, global2);
+        JSAutoRealm ar(cx, global2);
         wrappee.set(JS_NewPlainObject(cx));
         if (wrappee->compartment() != global2->compartment()) {
             fprintf(stderr, "wrappee in wrong compartment");
             return false;
         }
     }
 
     wrapper.set(wrappee);
--- a/js/src/jsapi-tests/testMutedErrors.cpp
+++ b/js/src/jsapi-tests/testMutedErrors.cpp
@@ -41,17 +41,17 @@ eval(const char* asciiChars, bool mutedE
     for (size_t i = 0; i < len; ++i)
         chars[i] = asciiChars[i];
     chars[len] = 0;
 
     JS::CompartmentOptions globalOptions;
     JS::RootedObject global(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr,
 						   JS::FireOnNewGlobalHook, globalOptions));
     CHECK(global);
-    JSAutoCompartment ac(cx, global);
+    JSAutoRealm ar(cx, global);
     CHECK(JS_InitStandardClasses(cx, global));
 
 
     JS::CompileOptions options(cx);
     options.setMutedErrors(mutedErrors)
            .setFileAndLine("", 0);
 
     return JS::Evaluate(cx, options, chars.get(), len, rval);
--- a/js/src/jsapi-tests/testPreserveJitCode.cpp
+++ b/js/src/jsapi-tests/testPreserveJitCode.cpp
@@ -36,17 +36,17 @@ bool
 testPreserveJitCode(bool preserveJitCode, unsigned remainingIonScripts)
 {
     cx->options().setBaseline(true);
     cx->options().setIon(true);
     cx->runtime()->setOffthreadIonCompilationEnabled(false);
 
     RootedObject global(cx, createTestGlobal(preserveJitCode));
     CHECK(global);
-    JSAutoCompartment ac(cx, global);
+    JSAutoRealm ar(cx, global);
 
     // The Ion JIT may be unavailable due to --disable-ion or lack of support
     // for this platform.
     if (!js::jit::IsIonEnabled(cx))
         knownFail = true;
 
     CHECK_EQUAL(countIonScripts(global), 0u);
 
--- a/js/src/jsapi-tests/testScriptObject.cpp
+++ b/js/src/jsapi-tests/testScriptObject.cpp
@@ -180,17 +180,17 @@ BEGIN_FIXTURE_TEST(ScriptObjectFixture, 
     options.setFileAndLine(__FILE__, __LINE__);
     CHECK(JS_CompileScript(cx, "val", 3, options, &script));
     JS::RootedValue value(cx);
     CHECK(JS_ExecuteScript(cx, script, &value));
     CHECK(value.toInt32() == 42);
     {
         JS::RootedObject global2(cx, createGlobal());
         CHECK(global2);
-        JSAutoCompartment ac(cx, global2);
+        JSAutoRealm ar(cx, global2);
         CHECK(JS_WrapValue(cx, &fortyTwo));
         CHECK(JS_SetProperty(cx, global, "val", fortyTwo));
         JS::RootedValue value2(cx);
         CHECK(JS::CloneAndExecuteScript(cx, script, &value2));
         CHECK(value2.toInt32() == 42);
     }
     JS::RootedValue value3(cx);
     CHECK(JS_ExecuteScript(cx, script, &value3));
--- a/js/src/jsapi-tests/testStructuredClone.cpp
+++ b/js/src/jsapi-tests/testStructuredClone.cpp
@@ -14,27 +14,27 @@ BEGIN_TEST(testStructuredClone_object)
     JS::RootedObject g1(cx, createGlobal());
     JS::RootedObject g2(cx, createGlobal());
     CHECK(g1);
     CHECK(g2);
 
     JS::RootedValue v1(cx);
 
     {
-        JSAutoCompartment ac(cx, g1);
+        JSAutoRealm ar(cx, g1);
         JS::RootedValue prop(cx, JS::Int32Value(1337));
 
         JS::RootedObject obj(cx, JS_NewPlainObject(cx));
         v1 = JS::ObjectOrNullValue(obj);
         CHECK(v1.isObject());
         CHECK(JS_SetProperty(cx, obj, "prop", prop));
     }
 
     {
-        JSAutoCompartment ac(cx, g2);
+        JSAutoRealm ar(cx, g2);
         JS::RootedValue v2(cx);
 
         CHECK(JS_StructuredClone(cx, v1, &v2, nullptr, nullptr));
         CHECK(v2.isObject());
         JS::RootedObject obj(cx, &v2.toObject());
 
         JS::RootedValue prop(cx);
         CHECK(JS_GetProperty(cx, obj, "prop", &prop));
@@ -52,26 +52,26 @@ BEGIN_TEST(testStructuredClone_string)
     JS::RootedObject g1(cx, createGlobal());
     JS::RootedObject g2(cx, createGlobal());
     CHECK(g1);
     CHECK(g2);
 
     JS::RootedValue v1(cx);
 
     {
-        JSAutoCompartment ac(cx, g1);
+        JSAutoRealm ar(cx, g1);
         JS::RootedValue prop(cx, JS::Int32Value(1337));
 
         v1 = JS::StringValue(JS_NewStringCopyZ(cx, "Hello World!"));
         CHECK(v1.isString());
         CHECK(v1.toString());
     }
 
     {
-        JSAutoCompartment ac(cx, g2);
+        JSAutoRealm ar(cx, g2);
         JS::RootedValue v2(cx);
 
         CHECK(JS_StructuredClone(cx, v1, &v2, nullptr, nullptr));
         CHECK(v2.isString());
         CHECK(v2.toString());
 
         JS::RootedValue expected(cx, JS::StringValue(
             JS_NewStringCopyZ(cx, "Hello World!")));
@@ -88,28 +88,28 @@ BEGIN_TEST(testStructuredClone_externalA
     JS::RootedObject g1(cx, createGlobal());
     JS::RootedObject g2(cx, createGlobal());
     CHECK(g1);
     CHECK(g2);
 
     JS::RootedValue v1(cx);
 
     {
-        JSAutoCompartment ac(cx, g1);
+        JSAutoRealm ar(cx, g1);
 
         JS::RootedObject obj(cx, JS_NewExternalArrayBuffer(cx, data.len(), data.contents(),
             &ExternalData::freeCallback, &data));
         CHECK(!data.wasFreed());
 
         v1 = JS::ObjectOrNullValue(obj);
         CHECK(v1.isObject());
     }
 
     {
-        JSAutoCompartment ac(cx, g2);
+        JSAutoRealm ar(cx, g2);
         JS::RootedValue v2(cx);
 
         CHECK(JS_StructuredClone(cx, v1, &v2, nullptr, nullptr));
         CHECK(v2.isObject());
 
         JS::RootedObject obj(cx, &v2.toObject());
         CHECK(&v1.toObject() != obj);
 
@@ -264,17 +264,17 @@ BEGIN_TEST(testStructuredClone_SavedFram
 
     for (auto* pp = principalsToTest; pp->principals != DONE; pp++) {
         fprintf(stderr, "Testing with principals '%s'\n", pp->name);
 
 	JS::CompartmentOptions options;
         JS::RootedObject g(cx, JS_NewGlobalObject(cx, getGlobalClass(), pp->principals,
                                                   JS::FireOnNewGlobalHook, options));
         CHECK(g);
-        JSAutoCompartment ac(cx, g);
+        JSAutoRealm ar(cx, g);
 
         CHECK(js::DefineTestingFunctions(cx, g, false, false));
 
         JS::RootedValue srcVal(cx);
         CHECK(evaluate("(function one() {                      \n"  // 1
                        "  return (function two() {             \n"  // 2
                        "    return (function three() {         \n"  // 3
                        "      return saveStack();              \n"  // 4
--- a/js/src/jsapi-tests/testUbiNode.cpp
+++ b/js/src/jsapi-tests/testUbiNode.cpp
@@ -89,17 +89,17 @@ BEGIN_TEST(test_ubiNodeZone)
     RootedString string1(cx, JS_NewStringCopyZ(cx, "Simpson's Individual Stringettes!"));
     CHECK(string1);
     RootedScript script1(cx);
     CHECK(JS::Compile(cx, options, "", 0, &script1));
 
     {
         // ... and then enter global2's zone and create a string and script
         // there, too.
-        JSAutoCompartment ac(cx, global2);
+        JSAutoRealm ar(cx, global2);
 
         RootedString string2(cx, JS_NewStringCopyZ(cx, "A million household uses!"));
         CHECK(string2);
         RootedScript script2(cx);
         CHECK(JS::Compile(cx, options, "", 0, &script2));
 
         CHECK(JS::ubi::Node(string1).zone() == global1->zone());
         CHECK(JS::ubi::Node(script1).zone() == global1->zone());
@@ -124,24 +124,24 @@ BEGIN_TEST(test_ubiNodeCompartment)
                                                 JS::FireOnNewGlobalHook, globalOptions));
     CHECK(global2);
     CHECK(global1->compartment() != global2->compartment());
     CHECK(JS::ubi::Node(global2).compartment() == global2->compartment());
     CHECK(JS::ubi::Node(global2).compartment() != global1->compartment());
 
     JS::CompileOptions options(cx);
 
-    // Create a script in the original compartment...
+    // Create a script in the original realm...
     RootedScript script1(cx);
     CHECK(JS::Compile(cx, options, "", 0, &script1));
 
     {
-        // ... and then enter global2's compartment and create a script
+        // ... and then enter global2's realm and create a script
         // there, too.
-        JSAutoCompartment ac(cx, global2);
+        JSAutoRealm ar(cx, global2);
 
         RootedScript script2(cx);
         CHECK(JS::Compile(cx, options, "", 0, &script2));
 
         CHECK(JS::ubi::Node(script1).compartment() == global1->compartment());
         CHECK(JS::ubi::Node(script2).compartment() == global2->compartment());
     }
 
--- a/js/src/jsapi-tests/testWeakMap.cpp
+++ b/js/src/jsapi-tests/testWeakMap.cpp
@@ -81,17 +81,17 @@ BEGIN_TEST(testWeakMap_keyDelegates)
     CHECK(key);
 
     JS::RootedObject delegate(cx, newDelegate());
     CHECK(delegate);
     keyDelegate = delegate;
 
     JS::RootedObject delegateRoot(cx);
     {
-        JSAutoCompartment ac(cx, delegate);
+        JSAutoRealm ar(cx, delegate);
         delegateRoot = JS_NewPlainObject(cx);
         CHECK(delegateRoot);
         JS::RootedValue delegateValue(cx, JS::ObjectValue(*delegate));
         CHECK(JS_DefineProperty(cx, delegateRoot, "delegate", delegateValue, 0));
     }
     delegate = nullptr;
 
     /*
@@ -180,23 +180,23 @@ JSObject* newCCW(JS::HandleObject source
 {
     /*
      * Now ensure that this zone will be swept first by adding a cross
      * compartment wrapper to a new objct in the same zone as the
      * delegate obejct.
      */
     JS::RootedObject object(cx);
     {
-        JSAutoCompartment ac(cx, destZone);
+        JSAutoRealm ar(cx, destZone);
         object = JS_NewPlainObject(cx);
         if (!object)
             return nullptr;
     }
     {
-        JSAutoCompartment ac(cx, sourceZone);
+        JSAutoRealm ar(cx, sourceZone);
         if (!JS_WrapObject(cx, &object))
             return nullptr;
     }
 
     // In order to test the SCC algorithm, we need the wrapper/wrappee to be
     // tenured.
     cx->runtime()->gc.evictNursery();
 
--- a/js/src/jsapi-tests/tests.cpp
+++ b/js/src/jsapi-tests/tests.cpp
@@ -87,17 +87,17 @@ JSObject* JSAPITest::createGlobal(JSPrin
 #ifdef ENABLE_STREAMS
     options.creationOptions().setStreamsEnabled(true);
 #endif
     newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), principals, JS::FireOnNewGlobalHook,
                                    options);
     if (!newGlobal)
         return nullptr;
 
-    JSAutoCompartment ac(cx, newGlobal);
+    JSAutoRealm ar(cx, newGlobal);
 
     // Populate the global object with the standard globals like Object and
     // Array.
     if (!JS_InitStandardClasses(cx, newGlobal))
         return nullptr;
 
     global = newGlobal;
     return newGlobal;
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -688,37 +688,37 @@ JS_EnterCompartment(JSContext* cx, JSObj
 JS_PUBLIC_API(void)
 JS_LeaveCompartment(JSContext* cx, JSCompartment* oldCompartment)
 {
     AssertHeapIsIdle();
     CHECK_REQUEST(cx);
     cx->leaveCompartment(oldCompartment);
 }
 
-JSAutoCompartment::JSAutoCompartment(JSContext* cx, JSObject* target
-                                     MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
+JSAutoRealm::JSAutoRealm(JSContext* cx, JSObject* target
+                         MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
   : cx_(cx),
     oldCompartment_(cx->compartment())
 {
     AssertHeapIsIdleOrIterating();
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     cx_->enterCompartmentOf(target);
 }
 
-JSAutoCompartment::JSAutoCompartment(JSContext* cx, JSScript* target
-                                     MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
+JSAutoRealm::JSAutoRealm(JSContext* cx, JSScript* target
+                         MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
   : cx_(cx),
     oldCompartment_(cx->compartment())
 {
     AssertHeapIsIdleOrIterating();
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     cx_->enterCompartmentOf(target);
 }
 
-JSAutoCompartment::~JSAutoCompartment()
+JSAutoRealm::~JSAutoRealm()
 {
     cx_->leaveCompartment(oldCompartment_);
 }
 
 JSAutoNullableCompartment::JSAutoNullableCompartment(JSContext* cx,
                                                      JSObject* targetOrNull
                                                      MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
   : cx_(cx),
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1244,63 +1244,61 @@ JS_WrapValue(JSContext* cx, JS::MutableH
 
 extern JS_PUBLIC_API(JSObject*)
 JS_TransplantObject(JSContext* cx, JS::HandleObject origobj, JS::HandleObject target);
 
 extern JS_PUBLIC_API(bool)
 JS_RefreshCrossCompartmentWrappers(JSContext* cx, JS::Handle<JSObject*> obj);
 
 /*
- * At any time, a JSContext has a current (possibly-nullptr) compartment.
- * Compartments are described in:
+ * At any time, a JSContext has a current (possibly-nullptr) realm.
+ * Realms are described in:
  *
  *   developer.mozilla.org/en-US/docs/SpiderMonkey/SpiderMonkey_compartments
  *
- * The current compartment of a context may be changed. The preferred way to do
- * this is with JSAutoCompartment:
+ * The current realm of a context may be changed. The preferred way to do
+ * this is with JSAutoRealm:
  *
  *   void foo(JSContext* cx, JSObject* obj) {
- *     // in some compartment 'c'
+ *     // in some realm 'r'
  *     {
- *       JSAutoCompartment ac(cx, obj);  // constructor enters
- *       // in the compartment of 'obj'
+ *       JSAutoRealm ar(cx, obj);  // constructor enters
+ *       // in the realm of 'obj'
  *     }                                 // destructor leaves
- *     // back in compartment 'c'
+ *     // back in realm 'r'
  *   }
  *
  * For more complicated uses that don't neatly fit in a C++ stack frame, the
- * compartment can entered and left using separate function calls:
+ * realm can be entered and left using separate function calls:
  *
  *   void foo(JSContext* cx, JSObject* obj) {
  *     // in 'oldCompartment'
  *     JSCompartment* oldCompartment = JS_EnterCompartment(cx, obj);
  *     // in the compartment of 'obj'
  *     JS_LeaveCompartment(cx, oldCompartment);
  *     // back in 'oldCompartment'
  *   }
  *
  * Note: these calls must still execute in a LIFO manner w.r.t all other
  * enter/leave calls on the context. Furthermore, only the return value of a
  * JS_EnterCompartment call may be passed as the 'oldCompartment' argument of
  * the corresponding JS_LeaveCompartment call.
  *
- * Entering a compartment roots the compartment and its global object for the
- * lifetime of the JSAutoCompartment.
- */
-
-class MOZ_RAII JS_PUBLIC_API(JSAutoCompartment)
+ * Entering a realm roots the realm and its global object for the lifetime of
+ * the JSAutoRealm.
+ */
+
+class MOZ_RAII JS_PUBLIC_API(JSAutoRealm)
 {
     JSContext* cx_;
     JSCompartment* oldCompartment_;
   public:
-    JSAutoCompartment(JSContext* cx, JSObject* target
-                      MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
-    JSAutoCompartment(JSContext* cx, JSScript* target
-                      MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
-    ~JSAutoCompartment();
+    JSAutoRealm(JSContext* cx, JSObject* target MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
+    JSAutoRealm(JSContext* cx, JSScript* target MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
+    ~JSAutoRealm();
 
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 class MOZ_RAII JS_PUBLIC_API(JSAutoNullableCompartment)
 {
     JSContext* cx_;
     JSCompartment* oldCompartment_;
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -846,17 +846,17 @@ static JS::UniqueChars
 FormatFrame(JSContext* cx, const FrameIter& iter, JS::UniqueChars&& inBuf, int num,
             bool showArgs, bool showLocals, bool showThisProps)
 {
     MOZ_ASSERT(!cx->isExceptionPending());
     RootedScript script(cx, iter.script());
     jsbytecode* pc = iter.pc();
 
     RootedObject envChain(cx, iter.environmentChain(cx));
-    JSAutoCompartment ac(cx, envChain);
+    JSAutoRealm ar(cx, envChain);
 
     const char* filename = script->filename();
     unsigned lineno = PCToLineNumber(script, pc);
     RootedFunction fun(cx, iter.maybeCallee(cx));
     RootedString funname(cx);
     if (fun)
         funname = fun->displayAtom();
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -721,17 +721,17 @@ ShellInterruptCallback(JSContext* cx)
     // Do this first to prevent other interrupts that may occur while the
     // user-supplied callback is executing from re-entering the handler.
     sc->serviceInterrupt = false;
 
     bool result;
     if (sc->haveInterruptFunc) {
         bool wasAlreadyThrowing = cx->isExceptionPending();
         JS::AutoSaveExceptionState savedExc(cx);
-        JSAutoCompartment ac(cx, &sc->interruptFunc.toObject());
+        JSAutoRealm ar(cx, &sc->interruptFunc.toObject());
         RootedValue rval(cx);
 
         // Report any exceptions thrown by the JS interrupt callback, but do
         // *not* keep it on the cx. The interrupt handler is invoked at points
         // that are not expected to throw catchable exceptions, like at
         // JSOP_RETRVAL.
         //
         // If the interrupted JS code was already throwing, any exceptions
@@ -1939,17 +1939,17 @@ Evaluate(JSContext* cx, unsigned argc, V
             return false;
         if (!loadBuffer.append(loadData, loadLength)) {
             JS_ReportOutOfMemory(cx);
             return false;
         }
     }
 
     {
-        JSAutoCompartment ac(cx, global);
+        JSAutoRealm ar(cx, global);
         RootedScript script(cx);
 
         {
             if (saveBytecode) {
                 if (!JS::CompartmentCreationOptionsRef(cx).cloneSingletons()) {
                     JS_ReportErrorNumberASCII(cx, my_GetErrorMessage, nullptr,
                                               JSSMSG_CACHE_SINGLETON_FAILED);
                     return false;
@@ -2008,17 +2008,17 @@ Evaluate(JSContext* cx, unsigned argc, V
         // delazified should be encoded at the end of the delazification.
         if (saveIncrementalBytecode) {
             if (!StartIncrementalEncoding(cx, script))
                 return false;
         }
 
         if (!JS_ExecuteScript(cx, envChain, script, args.rval())) {
             if (catchTermination && !JS_IsExceptionPending(cx)) {
-                JSAutoCompartment ac1(cx, callerGlobal);
+                JSAutoRealm ar1(cx, callerGlobal);
                 JSString* str = JS_NewStringCopyZ(cx, "terminated");
                 if (!str)
                     return false;
                 args.rval().setString(str);
                 return true;
             }
             return false;
         }
@@ -3012,17 +3012,17 @@ DisassembleToSprinter(JSContext* cx, uns
     DisassembleOptionParser p(args.length(), args.array());
     if (!p.parse(cx))
         return false;
 
     if (p.argc == 0) {
         /* Without arguments, disassemble the current script. */
         RootedScript script(cx, GetTopScript(cx));
         if (script) {
-            JSAutoCompartment ac(cx, script);
+            JSAutoRealm ar(cx, script);
             if (!Disassemble(cx, script, p.lines, sprinter))
                 return false;
             if (!SrcNotes(cx, script, sprinter))
                 return false;
             if (!TryNotes(cx, script, sprinter))
                 return false;
             if (!ScopeNotes(cx, script, sprinter))
                 return false;
@@ -3275,22 +3275,22 @@ Clone(JSContext* cx, unsigned argc, Valu
 
     if (args.length() == 0) {
         JS_ReportErrorASCII(cx, "Invalid arguments to clone");
         return false;
     }
 
     RootedObject funobj(cx);
     {
-        Maybe<JSAutoCompartment> ac;
+        Maybe<JSAutoRealm> ar;
         RootedObject obj(cx, args[0].isPrimitive() ? nullptr : &args[0].toObject());
 
         if (obj && obj->is<CrossCompartmentWrapperObject>()) {
             obj = UncheckedUnwrap(obj);
-            ac.emplace(cx, obj);
+            ar.emplace(cx, obj);
             args[0].setObject(*obj);
         }
         if (obj && obj->is<JSFunction>()) {
             funobj = obj;
         } else {
             JSFunction* fun = JS_ValueToFunction(cx, args[0]);
             if (!fun)
                 return false;
@@ -3427,17 +3427,17 @@ NewSandbox(JSContext* cx, bool lazy)
     JS::CompartmentOptions options;
     SetStandardCompartmentOptions(options);
     RootedObject obj(cx, JS_NewGlobalObject(cx, &sandbox_class, nullptr,
                                             JS::DontFireOnNewGlobalHook, options));
     if (!obj)
         return nullptr;
 
     {
-        JSAutoCompartment ac(cx, obj);
+        JSAutoRealm ar(cx, obj);
         if (!lazy && !JS_InitStandardClasses(cx, obj))
             return nullptr;
 
         RootedValue value(cx, BooleanValue(lazy));
         if (!JS_DefineProperty(cx, obj, "lazy", value, JSPROP_PERMANENT | JSPROP_READONLY))
             return nullptr;
 
         JS_FireOnNewGlobalObject(cx, obj);
@@ -3493,22 +3493,22 @@ EvalInContext(JSContext* cx, unsigned ar
         return true;
     }
 
     JS::AutoFilename filename;
     unsigned lineno;
 
     DescribeScriptedCaller(cx, &filename, &lineno);
     {
-        Maybe<JSAutoCompartment> ac;
+        Maybe<JSAutoRealm> ar;
         unsigned flags;
         JSObject* unwrapped = UncheckedUnwrap(sobj, true, &flags);
         if (flags & Wrapper::CROSS_COMPARTMENT) {
             sobj = unwrapped;
-            ac.emplace(cx, sobj);
+            ar.emplace(cx, sobj);
         }
 
         sobj = ToWindowIfWindowProxy(sobj);
 
         if (!(sobj->getClass()->flags & JSCLASS_IS_GLOBAL)) {
             JS_ReportErrorASCII(cx, "Invalid scope argument to evalcx");
             return false;
         }
@@ -3596,26 +3596,26 @@ WorkerMain(void* arg)
     js::UseInternalJobQueues(cx);
 
     if (!JS::InitSelfHostedCode(cx))
         return;
 
     EnvironmentPreparer environmentPreparer(cx);
 
     do {
-        JSAutoRequest ar(cx);
+        JSAutoRequest areq(cx);
 
         JS::CompartmentOptions compartmentOptions;
         SetStandardCompartmentOptions(compartmentOptions);
 
         RootedObject global(cx, NewGlobalObject(cx, compartmentOptions, nullptr));
         if (!global)
             break;
 
-        JSAutoCompartment ac(cx, global);
+        JSAutoRealm ar(cx, global);
 
         JS::CompileOptions options(cx);
         options.setFileAndLine("<string>", 1)
                .setIsRunOnce(true);
 
         AutoReportException are(cx);
         RootedScript script(cx);
         if (!JS::Compile(cx, options, input->chars, input->length, &script))
@@ -5095,17 +5095,17 @@ DecompileThisScript(JSContext* cx, unsig
 
     NonBuiltinScriptFrameIter iter(cx);
     if (iter.done()) {
         args.rval().setString(cx->runtime()->emptyString);
         return true;
     }
 
     {
-        JSAutoCompartment ac(cx, iter.script());
+        JSAutoRealm ar(cx, iter.script());
 
         RootedScript script(cx, iter.script());
         JSString* result = JS_DecompileScript(cx, script);
         if (!result)
             return false;
 
         args.rval().setString(result);
     }
@@ -7575,21 +7575,21 @@ ErrorFilePointer()
 }
 
 static bool
 PrintStackTrace(JSContext* cx, HandleValue exn)
 {
     if (!exn.isObject())
         return false;
 
-    Maybe<JSAutoCompartment> ac;
+    Maybe<JSAutoRealm> ar;
     RootedObject exnObj(cx, &exn.toObject());
     if (IsCrossCompartmentWrapper(exnObj)) {
         exnObj = UncheckedUnwrap(exnObj);
-        ac.emplace(cx, exnObj);
+        ar.emplace(cx, exnObj);
     }
 
     // Ignore non-ErrorObject thrown by |throw| statement.
     if (!exnObj->is<ErrorObject>())
         return true;
 
     // Exceptions thrown while compiling top-level script have no stack.
     RootedObject stackObj(cx, exnObj->as<ErrorObject>().stack());
@@ -8205,17 +8205,17 @@ NewGlobalObject(JSContext* cx, JS::Compa
                 JSPrincipals* principals)
 {
     RootedObject glob(cx, JS_NewGlobalObject(cx, &global_class, principals,
                                              JS::DontFireOnNewGlobalHook, options));
     if (!glob)
         return nullptr;
 
     {
-        JSAutoCompartment ac(cx, glob);
+        JSAutoRealm ar(cx, glob);
 
 #ifndef LAZY_STANDARD_CLASSES
         if (!JS_InitStandardClasses(cx, glob))
             return nullptr;
 #endif
 
         bool succeeded;
         if (!JS_SetImmutablePrototype(cx, glob, &succeeded))
@@ -8798,33 +8798,33 @@ Shell(JSContext* cx, OptionParser* op, c
     Maybe<JS::AutoDisableGenerationalGC> noggc;
     if (op->getBoolOption("no-ggc"))
         noggc.emplace(cx);
 
     Maybe<AutoDisableCompactingGC> nocgc;
     if (op->getBoolOption("no-cgc"))
         nocgc.emplace(cx);
 
-    JSAutoRequest ar(cx);
+    JSAutoRequest areq(cx);
 
     if (op->getBoolOption("fuzzing-safe"))
         fuzzingSafe = true;
     else
         fuzzingSafe = (getenv("MOZ_FUZZING_SAFE") && getenv("MOZ_FUZZING_SAFE")[0] != '0');
 
     if (op->getBoolOption("disable-oom-functions"))
         disableOOMFunctions = true;
 
     JS::CompartmentOptions options;
     SetStandardCompartmentOptions(options);
     RootedObject glob(cx, NewGlobalObject(cx, options, nullptr));
     if (!glob)
         return 1;
 
-    JSAutoCompartment ac(cx, glob);
+    JSAutoRealm ar(cx, glob);
 
     ShellContext* sc = GetShellContext(cx);
     int result = EXIT_SUCCESS;
     {
         AutoReportException are(cx);
         if (!ProcessArgs(cx, op) && !sc->quitting)
             result = EXITCODE_RUNTIME_ERROR;
     }
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -9290,17 +9290,17 @@ DebuggerObject::promiseIDGetter(JSContex
 
 /* static */ bool
 DebuggerObject::promiseDependentPromisesGetter(JSContext* cx, unsigned argc, Value* vp)
 {
     THIS_DEBUGOBJECT_OWNER_PROMISE(cx, argc, vp, "get promiseDependentPromises", args, dbg, refobj);
 
     Rooted<GCVector<Value>> values(cx, GCVector<Value>(cx));
     {
-        JSAutoCompartment ac(cx, promise);
+        JSAutoRealm ar(cx, promise);
         if (!promise->dependentPromises(cx, &values))
             return false;
     }
     for (size_t i = 0; i < values.length(); i++) {
         if (!dbg->wrapDebuggeeValue(cx, values[i]))
             return false;
     }
     RootedArrayObject promises(cx);
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -1147,29 +1147,29 @@ JS_CopyPropertyFrom(JSContext* cx, Handl
     if (desc.setter() && !desc.hasSetterObject())
         return true;
 
     if (copyBehavior == MakeNonConfigurableIntoConfigurable) {
         // Mask off the JSPROP_PERMANENT bit.
         desc.attributesRef() &= ~JSPROP_PERMANENT;
     }
 
-    JSAutoCompartment ac(cx, target);
+    JSAutoRealm ar(cx, target);
     cx->markId(id);
     RootedId wrappedId(cx, id);
     if (!cx->compartment()->wrap(cx, &desc))
         return false;
 
     return DefineProperty(cx, target, wrappedId, desc);
 }
 
 JS_FRIEND_API(bool)
 JS_CopyPropertiesFrom(JSContext* cx, HandleObject target, HandleObject obj)
 {
-    JSAutoCompartment ac(cx, obj);
+    JSAutoRealm ar(cx, obj);
 
     AutoIdVector props(cx);
     if (!GetPropertyKeys(cx, obj, JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS, &props))
         return false;
 
     for (size_t i = 0; i < props.length(); ++i) {
         if (!JS_CopyPropertyFrom(cx, props[i], target, obj))
             return false;
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -4439,22 +4439,22 @@ JSScript::mayReadFrameArgsDirectly()
 }
 
 void
 JSScript::AutoDelazify::holdScript(JS::HandleFunction fun)
 {
     if (fun) {
         if (fun->compartment()->isSelfHosting) {
             // The self-hosting compartment is shared across runtimes, so we
-            // can't use JSAutoCompartment: it could cause races. Functions in
-            // the self-hosting compartment will never be lazy, so we can safely
+            // can't use JSAutoRealm: it could cause races. Functions in the
+            // self-hosting compartment will never be lazy, so we can safely
             // assume we don't have to delazify.
             script_ = fun->nonLazyScript();
         } else {
-            JSAutoCompartment ac(cx_, fun);
+            JSAutoRealm ar(cx_, fun);
             script_ = JSFunction::getOrCreateScript(cx_, fun);
             if (script_) {
                 oldDoNotRelazify_ = script_->doNotRelazify_;
                 script_->setDoNotRelazify(true);
             }
         }
     }
 }
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -790,23 +790,23 @@ public:
         // Note that obj might be null here, since we're doing this before
         // UnwrapSavedFrame.
         if (obj && cx->compartment() != obj->compartment())
         {
             JSSubsumesOp subsumes = cx->runtime()->securityCallbacks->subsumes;
             if (subsumes && subsumes(cx->compartment()->principals(),
                                      obj->compartment()->principals()))
             {
-                ac_.emplace(cx, obj);
+                ar_.emplace(cx, obj);
             }
         }
     }
 
  private:
-    Maybe<JSAutoCompartment> ac_;
+    Maybe<JSAutoRealm> ar_;
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
 } // namespace
 
 static inline js::SavedFrame*
 UnwrapSavedFrame(JSContext* cx, HandleObject obj, SavedFrameSelfHosted selfHosted,
                  bool& skippedAsync)
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -2932,17 +2932,17 @@ JSRuntime::initSelfHosting(JSContext* cx
      * parented to this one, so cannot include state in the nursery.
      */
     JS::AutoDisableGenerationalGC disable(cx);
 
     Rooted<GlobalObject*> shg(cx, JSRuntime::createSelfHostingGlobal(cx));
     if (!shg)
         return false;
 
-    JSAutoCompartment ac(cx, shg);
+    JSAutoRealm ar(cx, shg);
 
     /*
      * Set a temporary error reporter printing to stderr because it is too
      * early in the startup process for any other reporter to be registered
      * and we don't want errors in self-hosted code to be silently swallowed.
      *
      * This class also overrides the warning reporter to print warnings to
      * stderr. See selfHosting_WarningReporter.
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -1110,17 +1110,17 @@ JSStructuredCloneWriter::parseTransferab
             if (unwrappedObj->as<ArrayBufferObject>().isExternal())
                 return reportDataCloneError(JS_SCERR_TRANSFERABLE);
         }
 
         else  {
             if (!out.buf.callbacks_ || !out.buf.callbacks_->canTransfer)
                 return reportDataCloneError(JS_SCERR_TRANSFERABLE);
 
-            JSAutoCompartment ac(cx, unwrappedObj);
+            JSAutoRealm ar(cx, unwrappedObj);
             if (!out.buf.callbacks_->canTransfer(cx, unwrappedObj, out.buf.closure_))
                 return false;
         }
 
         // No duplicates allowed
         auto p = transferableObjects.lookupForAdd(tObj);
         if (p)
             return reportDataCloneError(JS_SCERR_DUP_TRANSFERABLE);
@@ -1194,17 +1194,17 @@ JSStructuredCloneWriter::checkStack()
  * Int16Array views of the same ArrayBuffer, should the data bytes be
  * byte-swapped when writing or not? The Int8Array requires them to not be
  * swapped; the Int16Array requires that they are.
  */
 bool
 JSStructuredCloneWriter::writeTypedArray(HandleObject obj)
 {
     Rooted<TypedArrayObject*> tarr(context(), &CheckedUnwrap(obj)->as<TypedArrayObject>());
-    JSAutoCompartment ac(context(), tarr);
+    JSAutoRealm ar(context(), tarr);
 
     if (!TypedArrayObject::ensureHasBuffer(context(), tarr))
         return false;
 
     if (!out.writePair(SCTAG_TYPED_ARRAY_OBJECT, tarr->length()))
         return false;
     uint64_t type = tarr->type();
     if (!out.write(type))
@@ -1217,34 +1217,34 @@ JSStructuredCloneWriter::writeTypedArray
 
     return out.write(tarr->byteOffset());
 }
 
 bool
 JSStructuredCloneWriter::writeDataView(HandleObject obj)
 {
     Rooted<DataViewObject*> view(context(), &CheckedUnwrap(obj)->as<DataViewObject>());
-    JSAutoCompartment ac(context(), view);
+    JSAutoRealm ar(context(), view);
 
     if (!out.writePair(SCTAG_DATA_VIEW_OBJECT, view->byteLength()))
         return false;
 
     // Write out the ArrayBuffer tag and contents
     RootedValue val(context(), DataViewObject::bufferValue(view));
     if (!startWrite(val))
         return false;
 
     return out.write(view->byteOffset());
 }
 
 bool
 JSStructuredCloneWriter::writeArrayBuffer(HandleObject obj)
 {
     Rooted<ArrayBufferObject*> buffer(context(), &CheckedUnwrap(obj)->as<ArrayBufferObject>());
-    JSAutoCompartment ac(context(), buffer);
+    JSAutoRealm ar(context(), buffer);
 
     return out.writePair(SCTAG_ARRAY_BUFFER_OBJECT, buffer->byteLength()) &&
            out.writeBytes(buffer->dataPointer(), buffer->byteLength());
 }
 
 bool
 JSStructuredCloneWriter::writeSharedArrayBuffer(HandleObject obj)
 {
@@ -1357,17 +1357,17 @@ JSStructuredCloneWriter::traverseObject(
 bool
 JSStructuredCloneWriter::traverseMap(HandleObject obj)
 {
     Rooted<GCVector<Value>> newEntries(context(), GCVector<Value>(context()));
     {
         // If there is no wrapper, the compartment munging is a no-op.
         RootedObject unwrapped(context(), CheckedUnwrap(obj));
         MOZ_ASSERT(unwrapped);
-        JSAutoCompartment ac(context(), unwrapped);
+        JSAutoRealm ar(context(), unwrapped);
         if (!MapObject::getKeysAndValuesInterleaved(unwrapped, &newEntries))
             return false;
     }
     if (!context()->compartment()->wrap(context(), &newEntries))
         return false;
 
     for (size_t i = newEntries.length(); i > 0; --i) {
         if (!entries.append(newEntries[i - 1]))
@@ -1387,17 +1387,17 @@ JSStructuredCloneWriter::traverseMap(Han
 bool
 JSStructuredCloneWriter::traverseSet(HandleObject obj)
 {
     Rooted<GCVector<Value>> keys(context(), GCVector<Value>(context()));
     {
         // If there is no wrapper, the compartment munging is a no-op.
         RootedObject unwrapped(context(), CheckedUnwrap(obj));
         MOZ_ASSERT(unwrapped);
-        JSAutoCompartment ac(context(), unwrapped);
+        JSAutoRealm ar(context(), unwrapped);
         if (!SetObject::keys(context(), unwrapped, &keys))
             return false;
     }
     if (!context()->compartment()->wrap(context(), &keys))
         return false;
 
     for (size_t i = keys.length(); i > 0; --i) {
         if (!entries.append(keys[i - 1]))
@@ -1682,17 +1682,17 @@ JSStructuredCloneWriter::transferOwnersh
             return false;
 
         if (cls == ESClass::ArrayBuffer) {
             tag = SCTAG_TRANSFER_MAP_ARRAY_BUFFER;
 
             // The current setup of the array buffer inheritance hierarchy doesn't
             // lend itself well to generic manipulation via proxies.
             Rooted<ArrayBufferObject*> arrayBuffer(cx, &CheckedUnwrap(obj)->as<ArrayBufferObject>());
-            JSAutoCompartment ac(cx, arrayBuffer);
+            JSAutoRealm ar(cx, arrayBuffer);
 
             if (arrayBuffer->isDetached()) {
                 JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_TYPED_ARRAY_DETACHED);
                 return false;
             }
 
             size_t nbytes = arrayBuffer->byteLength();
 
--- a/js/src/vm/TypedArrayObject.cpp
+++ b/js/src/vm/TypedArrayObject.cpp
@@ -891,17 +891,17 @@ class TypedArrayObjectTemplate : public 
             protoRoot =
                 GlobalObject::getOrCreatePrototype(cx, JSCLASS_CACHED_PROTO_KEY(instanceClass()));
             if (!protoRoot)
                 return nullptr;
         }
 
         RootedObject typedArray(cx);
         {
-            JSAutoCompartment ac(cx, unwrappedBuffer);
+            JSAutoRealm ar(cx, unwrappedBuffer);
 
             RootedObject wrappedProto(cx, protoRoot);
             if (!cx->compartment()->wrap(cx, &wrappedProto))
                 return nullptr;
 
             typedArray =
                 makeInstance(cx, unwrappedBuffer, CreateSingleton::No, uint32_t(byteOffset),
                              length, wrappedProto);
@@ -1172,17 +1172,17 @@ TypedArrayObjectTemplate<T>::fromTypedAr
         srcArray = &other->as<TypedArrayObject>();
     } else {
         RootedObject unwrapped(cx, CheckedUnwrap(other));
         if (!unwrapped) {
             ReportAccessDenied(cx);
             return nullptr;
         }
 
-        JSAutoCompartment ac(cx, unwrapped);
+        JSAutoRealm ar(cx, unwrapped);
 
         srcArray = &unwrapped->as<TypedArrayObject>();
 
         // To keep things simpler, we always reify the array buffer for
         // wrapped typed arrays.
         if (!TypedArrayObject::ensureHasBuffer(cx, srcArray))
             return nullptr;
     }
--- a/js/xpconnect/loader/ChromeScriptLoader.cpp
+++ b/js/xpconnect/loader/ChromeScriptLoader.cpp
@@ -303,17 +303,17 @@ PrecompiledScript::~PrecompiledScript()
 
 void
 PrecompiledScript::ExecuteInGlobal(JSContext* aCx, HandleObject aGlobal,
                                    MutableHandleValue aRval,
                                    ErrorResult& aRv)
 {
     {
         RootedObject targetObj(aCx, JS_FindCompilationScope(aCx, aGlobal));
-        JSAutoCompartment ac(aCx, targetObj);
+        JSAutoRealm ar(aCx, targetObj);
 
         Rooted<JSScript*> script(aCx, mScript);
         if (!JS::CloneAndExecuteScript(aCx, script, aRval)) {
             aRv.NoteJSContextException(aCx);
             return;
         }
     }
 
--- a/js/xpconnect/loader/ScriptPreloader.cpp
+++ b/js/xpconnect/loader/ScriptPreloader.cpp
@@ -962,17 +962,17 @@ ScriptPreloader::MaybeFinishOffThreadDec
         mParsingScripts.clear();
 
         DecodeNextBatch(OFF_THREAD_CHUNK_SIZE);
     });
 
     AutoSafeJSAPI jsapi;
     JSContext* cx = jsapi.cx();
 
-    JSAutoCompartment ac(cx, CompilationScope(cx));
+    JSAutoRealm ar(cx, CompilationScope(cx));
     JS::Rooted<JS::ScriptVector> jsScripts(cx, JS::ScriptVector(cx));
 
     // If this fails, we still need to mark the scripts as finished. Any that
     // weren't successfully compiled in this operation (which should never
     // happen under ordinary circumstances) will be re-decoded on the main
     // thread, and raise the appropriate errors when they're executed.
     //
     // The exception from the off-thread decode operation will be reported when
@@ -1032,17 +1032,17 @@ ScriptPreloader::DecodeNextBatch(size_t 
     }
 
     if (size == 0 && mPendingScripts.isEmpty()) {
         return;
     }
 
     AutoSafeJSAPI jsapi;
     JSContext* cx = jsapi.cx();
-    JSAutoCompartment ac(cx, scope ? scope : CompilationScope(cx));
+    JSAutoRealm ar(cx, scope ? scope : CompilationScope(cx));
 
     JS::CompileOptions options(cx);
     options.setNoScriptRval(true)
            .setSourceIsLazy(true);
 
     if (!JS::CanCompileOffThread(cx, options, size) ||
         !JS::DecodeMultiOffThreadScripts(cx, options, mParsingSources,
                                          OffThreadDecodeCallback,
@@ -1078,17 +1078,17 @@ ScriptPreloader::CachedScript::CachedScr
     // compare against last session's values later.
     mOriginalProcessTypes = mProcessTypes;
     mProcessTypes = {};
 }
 
 bool
 ScriptPreloader::CachedScript::XDREncode(JSContext* cx)
 {
-    JSAutoCompartment ac(cx, mScript);
+    JSAutoRealm ar(cx, mScript);
     JS::RootedScript jsscript(cx, mScript);
 
     mXDRData.construct<JS::TranscodeBuffer>();
 
     JS::TranscodeResult code = JS::EncodeScript(cx, Buffer(), jsscript);
     if (code == JS::TranscodeResult_Ok) {
         mXDRRange.emplace(Buffer().begin(), Buffer().length());
         mSize = Range().length();
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -441,17 +441,17 @@ mozJSComponentLoader::LoadModule(FileLoc
     RootedValue exn(cx);
     rv = ObjectForLocation(info, file, &entry->obj, &entry->thisObjectKey,
                            &entry->location, isCriticalModule, &exn);
     if (NS_FAILED(rv)) {
         // Temporary debugging assertion for bug 1403348:
         if (isCriticalModule && !exn.isUndefined()) {
             AnnotateCrashReport();
 
-            JSAutoCompartment ac(cx, xpc::PrivilegedJunkScope());
+            JSAutoRealm ar(cx, xpc::PrivilegedJunkScope());
             JS_WrapValue(cx, &exn);
 
             nsAutoCString file;
             uint32_t line;
             uint32_t column;
             nsAutoString msg;
             nsContentUtils::ExtractErrorValues(cx, exn, file, &line, &column, msg);
 
@@ -463,17 +463,17 @@ mozJSComponentLoader::LoadModule(FileLoc
         return nullptr;
     }
 
     nsCOMPtr<nsIComponentManager> cm;
     rv = NS_GetComponentManager(getter_AddRefs(cm));
     if (NS_FAILED(rv))
         return nullptr;
 
-    JSAutoCompartment ac(cx, entry->obj);
+    JSAutoRealm ar(cx, entry->obj);
     RootedObject entryObj(cx, entry->obj);
 
     RootedObject NSGetFactoryHolder(cx, ResolveModuleObjectProperty(cx, entryObj, "NSGetFactory"));
     RootedValue NSGetFactory_val(cx);
     if (!NSGetFactoryHolder ||
         !JS_GetProperty(cx, NSGetFactoryHolder, "NSGetFactory", &NSGetFactory_val) ||
         NSGetFactory_val.isUndefined())
     {
@@ -592,17 +592,17 @@ mozJSComponentLoader::CreateLoaderGlobal
                                               options,
                                               &global);
     NS_ENSURE_SUCCESS_VOID(rv);
 
     NS_ENSURE_TRUE_VOID(global);
 
     backstagePass->SetGlobalObject(global);
 
-    JSAutoCompartment ac(aCx, global);
+    JSAutoRealm ar(aCx, global);
     if (!JS_DefineFunctions(aCx, global, gGlobalFun) ||
         !JS_DefineProfilingFunctions(aCx, global)) {
         return;
     }
 
     // Set the location information for the new global, so that tools like
     // about:memory may use that information
     xpc::SetLocationForGlobal(global, aLocation);
@@ -687,17 +687,17 @@ mozJSComponentLoader::PrepareObjectForLo
         CreateLoaderGlobal(aCx, nativePath, &globalObj);
         createdNewGlobal = true;
     }
 
     // |thisObj| is the object we set properties on for a particular .jsm.
     RootedObject thisObj(aCx, globalObj);
     NS_ENSURE_TRUE(thisObj, nullptr);
 
-    JSAutoCompartment ac(aCx, thisObj);
+    JSAutoRealm ar(aCx, thisObj);
 
     if (reuseGlobal) {
         thisObj = js::NewJSMEnvironment(aCx);
         NS_ENSURE_TRUE(thisObj, nullptr);
     }
 
     *aRealFile = false;
 
@@ -796,17 +796,17 @@ mozJSComponentLoader::ObjectForLocation(
     nsresult rv = aInfo.EnsureURI();
     NS_ENSURE_SUCCESS(rv, rv);
     bool reuseGlobal = false;
     RootedObject obj(cx, PrepareObjectForLocation(cx, aComponentFile, aInfo.URI(),
                                                   &reuseGlobal, &realFile));
     NS_ENSURE_TRUE(obj, NS_ERROR_FAILURE);
     MOZ_ASSERT(JS_IsGlobalObject(obj) == !reuseGlobal);
 
-    JSAutoCompartment ac(cx, obj);
+    JSAutoRealm ar(cx, obj);
 
     RootedScript script(cx);
 
     nsAutoCString nativePath;
     rv = aInfo.URI()->GetSpec(nativePath);
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Before compiling the script, first check to see if we have it in
@@ -953,17 +953,17 @@ mozJSComponentLoader::UnloadModules()
 {
     mInitialized = false;
 
     if (mLoaderGlobal) {
         dom::AutoJSAPI jsapi;
         jsapi.Init();
         JSContext* cx = jsapi.cx();
         RootedObject global(cx, mLoaderGlobal);
-        JSAutoCompartment ac(cx, global);
+        JSAutoRealm ar(cx, global);
         MOZ_ASSERT(JS_HasExtensibleLexicalEnvironment(global));
         JS_SetAllNonReservedSlotsToUndefined(cx, JS_ExtensibleLexicalEnvironment(global));
         JS_SetAllNonReservedSlotsToUndefined(cx, global);
         mLoaderGlobal = nullptr;
     }
 
     mInProgressImports.Clear();
     mImports.Clear();
@@ -1006,19 +1006,19 @@ mozJSComponentLoader::ImportInto(const n
             // Not doing so breaks |make package|.
             return ReportOnCallerUTF8(cx, ERROR_SCOPE_OBJ,
                                       PromiseFlatCString(registryLocation).get());
         }
     } else {
         FindTargetObject(cx, &targetObject);
     }
 
-    Maybe<JSAutoCompartment> ac;
+    Maybe<JSAutoRealm> ar;
     if (targetObject) {
-        ac.emplace(cx, targetObject);
+        ar.emplace(cx, targetObject);
     }
 
     RootedObject global(cx);
     nsresult rv = ImportInto(registryLocation, targetObject, cx, &global);
 
     if (global) {
         if (!JS_WrapObject(cx, &global)) {
             NS_ERROR("can't wrap return value");
@@ -1183,17 +1183,17 @@ mozJSComponentLoader::ExtractExports(JSC
     JSCLContextHelper cxhelper(aCx);
 
     // Even though we are calling JS_SetPropertyById on targetObj, we want
     // to ensure that we never run script here, so we use an AutoJSAPI and
     // not an AutoEntryScript.
     dom::AutoJSAPI jsapi;
     jsapi.Init();
     JSContext* cx = jsapi.cx();
-    JSAutoCompartment ac(cx, aMod->obj);
+    JSAutoRealm ar(cx, aMod->obj);
 
     RootedValue symbols(cx);
     {
         RootedObject obj(cx, ResolveModuleObjectProperty(cx, aMod->obj,
                                                          "EXPORTED_SYMBOLS"));
         if (!obj || !JS_GetProperty(cx, obj, "EXPORTED_SYMBOLS", &symbols)) {
             return ReportOnCallerUTF8(cxhelper, ERROR_NOT_PRESENT, aInfo);
         }
--- a/js/xpconnect/loader/mozJSComponentLoader.h
+++ b/js/xpconnect/loader/mozJSComponentLoader.h
@@ -155,17 +155,17 @@ class mozJSComponentLoader final : publi
             Clear();
         }
 
         void Clear() {
             getfactoryobj = nullptr;
 
             if (obj) {
                 mozilla::AutoJSContext cx;
-                JSAutoCompartment ac(cx, obj);
+                JSAutoRealm ar(cx, obj);
 
                 if (JS_HasExtensibleLexicalEnvironment(obj)) {
                     JS_SetAllNonReservedSlotsToUndefined(cx, JS_ExtensibleLexicalEnvironment(obj));
                 }
                 JS_SetAllNonReservedSlotsToUndefined(cx, obj);
                 obj = nullptr;
                 thisObjectKey = nullptr;
             }
--- a/js/xpconnect/loader/mozJSSubScriptLoader.cpp
+++ b/js/xpconnect/loader/mozJSSubScriptLoader.cpp
@@ -224,17 +224,17 @@ EvalScript(JSContext* cx,
             MOZ_ASSERT(js::IsJSMEnvironment(loadScope));
             if (!js::ExecuteInJSMEnvironment(cx, script, loadScope, envChain)) {
                 return false;
             }
             retval.setUndefined();
         }
     }
 
-    JSAutoCompartment rac(cx, targetObj);
+    JSAutoRealm rar(cx, targetObj);
     if (!JS_WrapValue(cx, retval)) {
         return false;
     }
 
     if (script && (startupCache || preloadCache)) {
         nsAutoCString cachePath;
         SubscriptCachePath(cx, uri, targetObj, cachePath);
 
@@ -259,17 +259,17 @@ EvalScript(JSContext* cx,
             // disable and reenable an add-on without uninstalling it, leading
             // to cached scripts being held alive, and tied to nuked Sandbox
             // globals. Given the unusual circumstances required to trigger
             // this, it's not a major concern. But it should be kept in mind.
             ScriptPreloader::GetSingleton().NoteScript(uriStr, cachePath, script);
         }
 
         if (startupCache) {
-            JSAutoCompartment ac(cx, script);
+            JSAutoRealm ar(cx, script);
             WriteCachedScript(StartupCache::GetSingleton(), cachePath, cx, script);
         }
     }
 
     return true;
 }
 
 class AsyncScriptLoader : public nsIIncrementalStreamLoaderObserver
@@ -627,17 +627,17 @@ mozJSSubScriptLoader::DoLoadSubScriptWit
 
     // Figure out who's calling us
     JS::AutoFilename filename;
     if (!JS::DescribeScriptedCaller(cx, &filename)) {
         // No scripted frame means we don't know who's calling, bail.
         return NS_ERROR_FAILURE;
     }
 
-    JSAutoCompartment ac(cx, targetObj);
+    JSAutoRealm ar(cx, targetObj);
 
     nsCOMPtr<nsIIOService> serv = do_GetService(NS_IOSERVICE_CONTRACTID);
     if (!serv) {
         ReportError(cx, NS_LITERAL_CSTRING(LOAD_ERROR_NOSERVICE));
         return NS_OK;
     }
 
     NS_LossyConvertUTF16toASCII asciiUrl(url);
--- a/js/xpconnect/src/ExportHelpers.cpp
+++ b/js/xpconnect/src/ExportHelpers.cpp
@@ -206,30 +206,30 @@ public:
  * function returns, |val| is set to the result of the clone.
  */
 bool
 StackScopedClone(JSContext* cx, StackScopedCloneOptions& options,
                  MutableHandleValue val)
 {
     StackScopedCloneData data(cx, &options);
     {
-        // For parsing val we have to enter its compartment.
+        // For parsing val we have to enter its realm.
         // (unless it's a primitive)
-        Maybe<JSAutoCompartment> ac;
+        Maybe<JSAutoRealm> ar;
         if (val.isObject()) {
-            ac.emplace(cx, &val.toObject());
+            ar.emplace(cx, &val.toObject());
         } else if (val.isString() && !JS_WrapValue(cx, val)) {
             return false;
         }
 
         if (!data.Write(cx, val))
             return false;
     }
 
-    // Now recreate the clones in the target compartment.
+    // Now recreate the clones in the target realm.
     if (!data.Read(cx, val))
         return false;
 
     // Deep-freeze if requested.
     if (options.deepFreeze && val.isObject()) {
         RootedObject obj(cx, &val.toObject());
         if (!JS_DeepFreezeObject(cx, obj))
             return false;
@@ -295,17 +295,17 @@ FunctionForwarder(JSContext* cx, unsigne
             return false;
         thisVal.setObject(*thisObject);
     }
 
     {
         // We manually implement the contents of CrossCompartmentWrapper::call
         // here, because certain function wrappers (notably content->nsEP) are
         // not callable.
-        JSAutoCompartment ac(cx, unwrappedFun);
+        JSAutoRealm ar(cx, unwrappedFun);
         if (!CheckSameOriginArg(cx, options, thisVal) || !JS_WrapValue(cx, &thisVal))
             return false;
 
         for (size_t n = 0;  n < args.length(); ++n) {
             if (!CheckSameOriginArg(cx, options, args[n]) || !JS_WrapValue(cx, args[n]))
                 return false;
         }
 
@@ -394,18 +394,18 @@ ExportFunction(JSContext* cx, HandleValu
 
     if (js::IsScriptedProxy(targetScope)) {
         JS_ReportErrorASCII(cx, "Defining property on proxy object is not allowed");
         return false;
     }
 
     {
         // We need to operate in the target scope from here on, let's enter
-        // its compartment.
-        JSAutoCompartment ac(cx, targetScope);
+        // its realm.
+        JSAutoRealm ar(cx, targetScope);
 
         // Unwrapping to see if we have a callable.
         funObj = UncheckedUnwrap(funObj);
         if (!JS::IsCallable(funObj)) {
             JS_ReportErrorASCII(cx, "First argument must be a function");
             return false;
         }
 
@@ -478,17 +478,17 @@ CreateObjectIn(JSContext* cx, HandleValu
 
     if (define && js::IsScriptedProxy(scope)) {
         JS_ReportErrorASCII(cx, "Defining property on proxy object is not allowed");
         return false;
     }
 
     RootedObject obj(cx);
     {
-        JSAutoCompartment ac(cx, scope);
+        JSAutoRealm ar(cx, scope);
         JS_MarkCrossZoneId(cx, options.defineAs);
 
         obj = JS_NewPlainObject(cx);
         if (!obj)
             return false;
 
         if (define) {
             if (!JS_DefinePropertyById(cx, scope, options.defineAs, obj,
--- a/js/xpconnect/src/Sandbox.cpp
+++ b/js/xpconnect/src/Sandbox.cpp
@@ -190,17 +190,17 @@ SandboxImport(JSContext* cx, unsigned ar
             return false;
     } else {
         // NB: funobj must only be used to get the JSFunction out.
         RootedObject funobj(cx, &args[0].toObject());
         if (js::IsProxy(funobj)) {
             funobj = XPCWrapper::UnsafeUnwrapSecurityWrapper(funobj);
         }
 
-        JSAutoCompartment ac(cx, funobj);
+        JSAutoRealm ar(cx, funobj);
 
         RootedValue funval(cx, ObjectValue(*funobj));
         JSFunction* fun = JS_ValueToFunction(cx, funval);
         if (!fun) {
             XPCThrower::Throw(NS_ERROR_INVALID_ARG, cx);
             return false;
         }
 
@@ -1065,17 +1065,17 @@ xpc::CreateSandboxObject(JSContext* cx, 
     // same-origin Xrays for chrome->chrome access seems a bit superfluous.
     // Arguably we should just flip the default for chrome and still honor the
     // flag, but such a change would break code in subtle ways for minimal
     // benefit. So we just switch it off here.
     priv->wantXrays =
       AccessCheck::isChrome(sandbox) ? false : options.wantXrays;
 
     {
-        JSAutoCompartment ac(cx, sandbox);
+        JSAutoRealm ar(cx, sandbox);
 
         nsCOMPtr<nsIScriptObjectPrincipal> sbp =
             new SandboxPrivate(principal, sandbox);
 
         // Pass on ownership of sbp to |sandbox|.
         JS_SetPrivate(sandbox, sbp.forget().take());
 
         // Ensure |Object.prototype| is instantiated before prototype-
@@ -1151,17 +1151,17 @@ xpc::CreateSandboxObject(JSContext* cx, 
         return NS_ERROR_UNEXPECTED;
 
     // Set the location information for the new global, so that tools like
     // about:memory may use that information
     xpc::SetLocationForGlobal(sandbox, options.sandboxName);
 
     xpc::SetSandboxMetadata(cx, sandbox, options.metadata);
 
-    JSAutoCompartment ac(cx, sandbox);
+    JSAutoRealm ar(cx, sandbox);
     JS_FireOnNewGlobalObject(cx, sandbox);
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_utils_Sandbox::Call(nsIXPConnectWrappedNative* wrapper, JSContext* cx,
                                     JSObject* objArg, const CallArgs& args, bool* _retval)
@@ -1786,17 +1786,17 @@ xpc::EvalInSandbox(JSContext* cx, Handle
     RootedValue v(cx, UndefinedValue());
     RootedValue exn(cx, UndefinedValue());
     bool ok = true;
     {
         // We're about to evaluate script, so make an AutoEntryScript.
         // This is clearly Gecko-specific and not in any spec.
         mozilla::dom::AutoEntryScript aes(priv, "XPConnect sandbox evaluation");
         JSContext* sandcx = aes.cx();
-        JSAutoCompartment ac(sandcx, sandbox);
+        JSAutoRealm ar(sandcx, sandbox);
 
         JS::CompileOptions options(sandcx);
         options.setFileAndLine(filenameBuf.get(), lineNo);
         MOZ_ASSERT(JS_IsGlobalObject(sandbox));
         ok = JS::Evaluate(sandcx, options,
                           PromiseFlatString(source).get(), source.Length(), &v);
 
         // If the sandbox threw an exception, grab it off the context.
@@ -1839,17 +1839,17 @@ xpc::EvalInSandbox(JSContext* cx, Handle
 nsresult
 xpc::GetSandboxMetadata(JSContext* cx, HandleObject sandbox, MutableHandleValue rval)
 {
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_ASSERT(IsSandbox(sandbox));
 
     RootedValue metadata(cx);
     {
-      JSAutoCompartment ac(cx, sandbox);
+      JSAutoRealm ar(cx, sandbox);
       metadata = JS_GetReservedSlot(sandbox, XPCONNECT_SANDBOX_CLASS_METADATA_SLOT);
     }
 
     if (!JS_WrapValue(cx, &metadata))
         return NS_ERROR_UNEXPECTED;
 
     rval.set(metadata);
     return NS_OK;
@@ -1858,16 +1858,16 @@ xpc::GetSandboxMetadata(JSContext* cx, H
 nsresult
 xpc::SetSandboxMetadata(JSContext* cx, HandleObject sandbox, HandleValue metadataArg)
 {
     MOZ_ASSERT(NS_IsMainThread());
     MOZ_ASSERT(IsSandbox(sandbox));
 
     RootedValue metadata(cx);
 
-    JSAutoCompartment ac(cx, sandbox);
+    JSAutoRealm ar(cx, sandbox);
     if (!JS_StructuredClone(cx, metadataArg, &metadata, nullptr, nullptr))
         return NS_ERROR_UNEXPECTED;
 
     JS_SetReservedSlot(sandbox, XPCONNECT_SANDBOX_CLASS_METADATA_SLOT, metadata);
 
     return NS_OK;
 }
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -2450,17 +2450,17 @@ nsXPCComponents_Utils::GetGlobalForObjec
     // Wrappers are parented to their the global in their home compartment. But
     // when getting the global for a cross-compartment wrapper, we really want
     // a wrapper for the foreign global. So we need to unwrap before getting the
     // parent, enter the compartment for the duration of the call, and wrap the
     // result.
     Rooted<JSObject*> obj(cx, &object.toObject());
     obj = js::UncheckedUnwrap(obj);
     {
-        JSAutoCompartment ac(cx, obj);
+        JSAutoRealm ar(cx, obj);
         obj = JS_GetGlobalForObject(cx, obj);
     }
 
     if (!JS_WrapObject(cx, &obj))
         return NS_ERROR_FAILURE;
 
     // Get the WindowProxy if necessary.
     obj = js::ToWindowProxyIfWindow(obj);
@@ -2519,17 +2519,17 @@ nsXPCComponents_Utils::MakeObjectPropsNo
     if (!cx)
         return NS_ERROR_FAILURE;
 
     // first argument must be an object
     if (vobj.isPrimitive())
         return NS_ERROR_XPC_BAD_CONVERT_JS;
 
     RootedObject obj(cx, js::UncheckedUnwrap(&vobj.toObject()));
-    JSAutoCompartment ac(cx, obj);
+    JSAutoRealm ar(cx, obj);
     Rooted<IdVector> ida(cx, IdVector(cx));
     if (!JS_Enumerate(cx, obj, &ida))
         return NS_ERROR_FAILURE;
 
     RootedId id(cx);
     RootedValue v(cx);
     for (size_t i = 0; i < ida.length(); ++i) {
         id = ida[i];
@@ -2649,23 +2649,23 @@ nsXPCComponents_Utils::ForcePermissiveCO
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::Dispatch(HandleValue runnableArg, HandleValue scope,
                                 JSContext* cx)
 {
     RootedValue runnable(cx, runnableArg);
-    // Enter the given compartment, if any, and rewrap runnable.
-    Maybe<JSAutoCompartment> ac;
+    // Enter the given realm, if any, and rewrap runnable.
+    Maybe<JSAutoRealm> ar;
     if (scope.isObject()) {
         JSObject* scopeObj = js::UncheckedUnwrap(&scope.toObject());
         if (!scopeObj)
             return NS_ERROR_FAILURE;
-        ac.emplace(cx, scopeObj);
+        ar.emplace(cx, scopeObj);
         if (!JS_WrapValue(cx, &runnable))
             return NS_ERROR_FAILURE;
     }
 
     // Get an XPCWrappedJS for |runnable|.
     if (!runnable.isObject())
         return NS_ERROR_INVALID_ARG;
 
@@ -2891,17 +2891,17 @@ NS_IMETHODIMP
 nsXPCComponents_Utils::GenerateXPCWrappedJS(HandleValue aObj, HandleValue aScope,
                                             JSContext* aCx, nsISupports** aOut)
 {
     if (!aObj.isObject())
         return NS_ERROR_INVALID_ARG;
     RootedObject obj(aCx, &aObj.toObject());
     RootedObject scope(aCx, aScope.isObject() ? js::UncheckedUnwrap(&aScope.toObject())
                                               : CurrentGlobalOrNull(aCx));
-    JSAutoCompartment ac(aCx, scope);
+    JSAutoRealm ar(aCx, scope);
     if (!JS_WrapObject(aCx, &obj))
         return NS_ERROR_FAILURE;
 
     RefPtr<WrappedJSHolder> holder = new WrappedJSHolder();
     nsresult rv = nsXPCWrappedJS::GetNewOrUsed(obj, NS_GET_IID(nsISupports),
                                                getter_AddRefs(holder->mWrappedJS));
     holder.forget(aOut);
     return rv;
@@ -2959,17 +2959,17 @@ xpc::CloneInto(JSContext* aCx, HandleVal
 
     RootedObject optionsObject(aCx, aOptions.isObject() ? &aOptions.toObject()
                                                         : nullptr);
     StackScopedCloneOptions options(aCx, optionsObject);
     if (aOptions.isObject() && !options.Parse())
         return false;
 
     {
-        JSAutoCompartment ac(aCx, scope);
+        JSAutoRealm ar(aCx, scope);
         aCloned.set(aValue);
         if (!StackScopedClone(aCx, options, aCloned))
             return false;
     }
 
     return JS_WrapValue(aCx, aCloned);
 }
 
--- a/js/xpconnect/src/XPCConvert.cpp
+++ b/js/xpconnect/src/XPCConvert.cpp
@@ -952,17 +952,17 @@ XPCConvert::JSObject2NativeInterface(voi
                                      nsISupports* aOuter,
                                      nsresult* pErr)
 {
     MOZ_ASSERT(dest, "bad param");
     MOZ_ASSERT(src, "bad param");
     MOZ_ASSERT(iid, "bad param");
 
     AutoJSContext cx;
-    JSAutoCompartment ac(cx, src);
+    JSAutoRealm ar(cx, src);
 
     *dest = nullptr;
      if (pErr)
         *pErr = NS_ERROR_XPC_BAD_CONVERT_JS;
 
     nsISupports* iface;
 
     if (!aOuter) {
--- a/js/xpconnect/src/XPCShellImpl.cpp
+++ b/js/xpconnect/src/XPCShellImpl.cpp
@@ -537,17 +537,17 @@ XPCShellInterruptCallback(JSContext* cx)
 {
     MOZ_ASSERT(sScriptedInterruptCallback->initialized());
     RootedValue callback(cx, *sScriptedInterruptCallback);
 
     // If no interrupt callback was set by script, no-op.
     if (callback.isUndefined())
         return true;
 
-    JSAutoCompartment ac(cx, &callback.toObject());
+    JSAutoRealm ar(cx, &callback.toObject());
     RootedValue rv(cx);
     if (!JS_CallFunctionValue(cx, nullptr, callback, JS::HandleValueArray::empty(), &rv) ||
         !rv.isBoolean())
     {
         NS_WARNING("Scripted interrupt callback failed! Terminating script.");
         JS_ClearPendingException(cx);
         return false;
     }
@@ -1334,17 +1334,17 @@ XRE_XPCShellMain(int argc, char** argv, 
 
             // 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::CompartmentBehaviorsRef(glob).setDiscardSource(false);
 
             backstagePass->SetGlobalObject(glob);
 
-            JSAutoCompartment ac(cx, glob);
+            JSAutoRealm ar(cx, glob);
 
             if (!JS_InitReflectParse(cx, glob)) {
                 return 1;
             }
 
             if (!JS_DefineFunctions(cx, glob, glob_functions) ||
                 !JS_DefineProfilingFunctions(cx, glob)) {
                 return 1;
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -41,17 +41,17 @@ bool AutoScriptEvaluate::StartEvaluating
     MOZ_ASSERT(!mEvaluated, "AutoScriptEvaluate::Evaluate should only be called once");
 
     if (!mJSContext)
         return true;
 
     mEvaluated = true;
 
     JS_BeginRequest(mJSContext);
-    mAutoCompartment.emplace(mJSContext, scope);
+    mAutoRealm.emplace(mJSContext, scope);
 
     // Saving the exception state keeps us from interfering with another script
     // that may also be running on this context.  This occurred first with the
     // js debugger, as described in
     // http://bugzilla.mozilla.org/show_bug.cgi?id=88130 but presumably could
     // show up in any situation where a script calls into a wrapped js component
     // on the same context, while the context has a nonzero exception state.
     mState.emplace(mJSContext);
@@ -443,17 +443,17 @@ public:
 };
 
 NS_IMPL_ISUPPORTS(WrappedJSNamed, nsINamed)
 
 nsCString
 GetFunctionName(JSContext* cx, HandleObject obj)
 {
     RootedObject inner(cx, js::UncheckedUnwrap(obj));
-    JSAutoCompartment ac(cx, inner);
+    JSAutoRealm ar(cx, inner);
 
     RootedFunction fun(cx, JS_GetObjectFunction(inner));
     if (!fun) {
         // If the object isn't a function, it's likely that it has a single
         // function property (for things like nsITimerCallback). In this case,
         // return the name of that function property.
 
         Rooted<IdVector> idArray(cx, IdVector(cx));
@@ -963,17 +963,17 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
         NS_WARNING(str);
         return CheckForException(ccx, aes, name, GetInterfaceName());
     }
 
     RootedValue fval(cx);
     RootedObject obj(cx, wrapper->GetJSObject());
     RootedObject thisObj(cx, obj);
 
-    JSAutoCompartment ac(cx, obj);
+    JSAutoRealm ar(cx, obj);
 
     AutoValueVector args(cx);
     AutoScriptEvaluate scriptEval(cx);
 
     XPCJSContext* xpccx = ccx.GetContext();
     AutoSavePendingResult apr(xpccx);
 
     // XXX ASSUMES that retval is last arg. The xpidl compiler ensures this.
--- a/js/xpconnect/src/XPCWrappedNative.cpp
+++ b/js/xpconnect/src/XPCWrappedNative.cpp
@@ -181,19 +181,19 @@ XPCWrappedNative::WrapNewGlobal(xpcObjec
     aOptions.creationOptions().setTrace(XPCWrappedNative::Trace);
     if (xpc::SharedMemoryEnabled())
         aOptions.creationOptions().setSharedMemoryAndAtomicsEnabled(true);
     RootedObject global(cx, xpc::CreateGlobalObject(cx, clasp, principal, aOptions));
     if (!global)
         return NS_ERROR_FAILURE;
     XPCWrappedNativeScope* scope = RealmPrivate::Get(global)->scope;
 
-    // Immediately enter the global's compartment, so that everything else we
+    // Immediately enter the global's realm, so that everything else we
     // create ends up there.
-    JSAutoCompartment ac(cx, global);
+    JSAutoRealm ar(cx, global);
 
     // If requested, initialize the standard classes on the global.
     if (initStandardClasses && ! JS_InitStandardClasses(cx, global))
         return NS_ERROR_FAILURE;
 
     // Make a proto.
     XPCWrappedNativeProto* proto =
         XPCWrappedNativeProto::GetNewOrUsed(scope,
@@ -337,33 +337,33 @@ XPCWrappedNative::GetNewOrUsed(xpcObject
     // described by the nsIClassInfo, not for the class info object
     // itself.
     if (!isClassInfoSingleton)
         GatherScriptable(identity, info, getter_AddRefs(scrProto),
                          getter_AddRefs(scrWrapper));
 
     RootedObject parent(cx, Scope->GetGlobalJSObject());
 
-    mozilla::Maybe<JSAutoCompartment> ac;
+    mozilla::Maybe<JSAutoRealm> ar;
 
     if (scrWrapper && scrWrapper->WantPreCreate()) {
         RootedObject plannedParent(cx, parent);
         nsresult rv =
             scrWrapper->PreCreate(identity, cx, parent, parent.address());
         if (NS_FAILED(rv))
             return rv;
         rv = NS_OK;
 
         MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(parent),
                    "Xray wrapper being used to parent XPCWrappedNative?");
 
         MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(parent) == parent,
                    "Non-global being used to parent XPCWrappedNative?");
 
-        ac.emplace(static_cast<JSContext*>(cx), parent);
+        ar.emplace(static_cast<JSContext*>(cx), parent);
 
         if (parent != plannedParent) {
             XPCWrappedNativeScope* betterScope = ObjectScope(parent);
             MOZ_ASSERT(betterScope != Scope,
                        "How can we have the same scope for two different globals?");
             return GetNewOrUsed(helper, betterScope, Interface, resultWrapper);
         }
 
@@ -383,17 +383,17 @@ XPCWrappedNative::GetNewOrUsed(xpcObject
             if (wrapper->FindTearOff(Interface, false, &rv)) {
                 MOZ_ASSERT(NS_FAILED(rv), "returning NS_OK on failure");
                 return rv;
             }
             wrapper.forget(resultWrapper);
             return NS_OK;
         }
     } else {
-        ac.emplace(static_cast<JSContext*>(cx), parent);
+        ar.emplace(static_cast<JSContext*>(cx), parent);
     }
 
     AutoMarkingWrappedNativeProtoPtr proto(cx);
 
     // If there is ClassInfo (and we are not building a wrapper for the
     // nsIClassInfo interface) then we use a wrapper that needs a prototype.
 
     // Note that the security check happens inside FindTearOff - after the
--- a/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeJSOps.cpp
@@ -152,17 +152,17 @@ GetDoubleWrappedJSObject(XPCCallContext&
     nsCOMPtr<nsIXPConnectWrappedJS>
         underware = do_QueryInterface(wrapper->GetIdentityObject());
     if (underware) {
         RootedObject mainObj(ccx, underware->GetJSObject());
         if (mainObj) {
             RootedId id(ccx, ccx.GetContext()->
                             GetStringID(XPCJSContext::IDX_WRAPPED_JSOBJECT));
 
-            JSAutoCompartment ac(ccx, mainObj);
+            JSAutoRealm ar(ccx, mainObj);
 
             RootedValue val(ccx);
             if (JS_GetPropertyById(ccx, mainObj, id, &val) &&
                 !val.isPrimitive()) {
                 obj = val.toObjectOrNull();
             }
         }
     }
--- a/js/xpconnect/src/XPCWrappedNativeScope.cpp
+++ b/js/xpconnect/src/XPCWrappedNativeScope.cpp
@@ -286,17 +286,17 @@ XPCWrappedNativeScope::AllowContentXBLSc
     return mAllowContentXBLScope;
 }
 
 namespace xpc {
 JSObject*
 GetXBLScope(JSContext* cx, JSObject* contentScopeArg)
 {
     JS::RootedObject contentScope(cx, contentScopeArg);
-    JSAutoCompartment ac(cx, contentScope);
+    JSAutoRealm ar(cx, contentScope);
     XPCWrappedNativeScope* nativeScope = RealmPrivate::Get(contentScope)->scope;
 
     RootedObject scope(cx, nativeScope->EnsureContentXBLScope(cx));
     NS_ENSURE_TRUE(scope, nullptr); // See bug 858642.
 
     scope = js::UncheckedUnwrap(scope);
     JS::ExposeObjectToActiveJS(scope);
     return scope;
--- a/js/xpconnect/src/XPCWrapper.cpp
+++ b/js/xpconnect/src/XPCWrapper.cpp
@@ -62,17 +62,17 @@ XrayWrapperConstructor(JSContext* cx, un
   return JS_WrapValue(cx, args.rval());
 }
 // static
 bool
 AttachNewConstructorObject(JSContext* aCx, JS::HandleObject aGlobalObject)
 {
   // Pushing a JSContext calls ActivateDebugger which calls this function, so
   // we can't use an AutoJSContext here until JSD is gone.
-  JSAutoCompartment ac(aCx, aGlobalObject);
+  JSAutoRealm ar(aCx, aGlobalObject);
   JSFunction* xpcnativewrapper =
     JS_DefineFunction(aCx, aGlobalObject, "XPCNativeWrapper",
                       XrayWrapperConstructor, 1,
                       JSPROP_READONLY | JSPROP_PERMANENT | JSFUN_CONSTRUCTOR);
   if (!xpcnativewrapper) {
     return false;
   }
   JS::RootedObject obj(aCx, JS_GetFunctionObject(xpcnativewrapper));
--- a/js/xpconnect/src/nsXPConnect.cpp
+++ b/js/xpconnect/src/nsXPConnect.cpp
@@ -441,17 +441,17 @@ CreateGlobalObject(JSContext* cx, const 
     MOZ_RELEASE_ASSERT(principal != nsContentUtils::GetNullSubjectPrincipal(),
                        "The null subject principal is getting inherited - fix that!");
 
     RootedObject global(cx,
                         JS_NewGlobalObject(cx, clasp, nsJSPrincipals::get(principal),
                                            JS::DontFireOnNewGlobalHook, aOptions));
     if (!global)
         return nullptr;
-    JSAutoCompartment ac(cx, global);
+    JSAutoRealm ar(cx, global);
 
     // The constructor automatically attaches the scope to the compartment private
     // of |global|.
     (void) new XPCWrappedNativeScope(cx, global);
 
     if (clasp->flags & JSCLASS_DOM_GLOBAL) {
 #ifdef DEBUG
         // Verify that the right trace hook is called. Note that this doesn't
@@ -504,19 +504,19 @@ InitGlobalObjectOptions(JS::CompartmentO
         if (isSystem)
             aOptions.behaviors().extraWarningsOverride().set(true);
     }
 }
 
 bool
 InitGlobalObject(JSContext* aJSContext, JS::Handle<JSObject*> aGlobal, uint32_t aFlags)
 {
-    // Immediately enter the global's compartment so that everything we create
+    // Immediately enter the global's realm so that everything we create
     // ends up there.
-    JSAutoCompartment ac(aJSContext, aGlobal);
+    JSAutoRealm ar(aJSContext, aGlobal);
 
     // Stuff coming through this path always ends up as a DOM global.
     MOZ_ASSERT(js::GetObjectClass(aGlobal)->flags & JSCLASS_DOM_GLOBAL);
 
     if (!(aFlags & xpc::OMIT_COMPONENTS_OBJECT)) {
         // XPCCallContext gives us an active request needed to save/restore.
         if (!RealmPrivate::Get(aGlobal)->scope->AttachComponentsObject(aJSContext) ||
             !XPCNativeWrapper::AttachNewConstructorObject(aJSContext, aGlobal)) {
@@ -579,17 +579,17 @@ static nsresult
 NativeInterface2JSObject(HandleObject aScope,
                          nsISupports* aCOMObj,
                          nsWrapperCache* aCache,
                          const nsIID * aIID,
                          bool aAllowWrapping,
                          MutableHandleValue aVal)
 {
     AutoJSContext cx;
-    JSAutoCompartment ac(cx, aScope);
+    JSAutoRealm ar(cx, aScope);
 
     nsresult rv;
     xpcObjectHelper helper(aCOMObj, aCache);
     if (!XPCConvert::NativeInterface2JSObject(aVal, helper, aIID, aAllowWrapping, &rv))
         return rv;
 
     MOZ_ASSERT(aAllowWrapping || !xpc::WrapperFactory::IsXrayWrapper(&aVal.toObject()),
                "Shouldn't be returning a xray wrapper here");
@@ -648,17 +648,17 @@ nsXPConnect::WrapJS(JSContext * aJSConte
 {
     MOZ_ASSERT(aJSContext, "bad param");
     MOZ_ASSERT(aJSObjArg, "bad param");
     MOZ_ASSERT(result, "bad param");
 
     *result = nullptr;
 
     RootedObject aJSObj(aJSContext, aJSObjArg);
-    JSAutoCompartment ac(aJSContext, aJSObj);
+    JSAutoRealm ar(aJSContext, aJSObj);
 
     nsresult rv = NS_ERROR_UNEXPECTED;
     if (!XPCConvert::JSObject2NativeInterface(result, aJSObj,
                                               &aIID, nullptr, &rv))
         return rv;
     return NS_OK;
 }
 
@@ -783,17 +783,17 @@ nsXPConnect::EvalInSandboxObject(const n
 
 NS_IMETHODIMP
 nsXPConnect::GetWrappedNativePrototype(JSContext* aJSContext,
                                        JSObject* aScopeArg,
                                        nsIClassInfo* aClassInfo,
                                        JSObject** aRetVal)
 {
     RootedObject aScope(aJSContext, aScopeArg);
-    JSAutoCompartment ac(aJSContext, aScope);
+    JSAutoRealm ar(aJSContext, aScope);
 
     XPCWrappedNativeScope* scope = ObjectScope(aScope);
     if (!scope)
         return UnexpectedFailure(NS_ERROR_FAILURE);
 
     nsCOMPtr<nsIXPCScriptable> scrProto =
         XPCWrappedNative::GatherProtoScriptable(aClassInfo);
 
--- a/js/xpconnect/src/xpcprivate.h
+++ b/js/xpconnect/src/xpcprivate.h
@@ -2242,17 +2242,17 @@ public:
     /**
      * Does the post script evaluation.
      */
     ~AutoScriptEvaluate();
 private:
     JSContext* mJSContext;
     mozilla::Maybe<JS::AutoSaveExceptionState> mState;
     bool mEvaluated;
-    mozilla::Maybe<JSAutoCompartment> mAutoCompartment;
+    mozilla::Maybe<JSAutoRealm> mAutoRealm;
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 
     // No copying or assignment allowed
     AutoScriptEvaluate(const AutoScriptEvaluate&) = delete;
     AutoScriptEvaluate & operator =(const AutoScriptEvaluate&) = delete;
 };
 
 /***************************************************************************/
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -68,17 +68,17 @@ WrapperFactory::GetXrayWaiver(HandleObje
 JSObject*
 WrapperFactory::CreateXrayWaiver(JSContext* cx, HandleObject obj)
 {
     // The caller is required to have already done a lookup.
     // NB: This implictly performs the assertions of GetXrayWaiver.
     MOZ_ASSERT(!GetXrayWaiver(obj));
     XPCWrappedNativeScope* scope = ObjectScope(obj);
 
-    JSAutoCompartment ac(cx, obj);
+    JSAutoRealm ar(cx, obj);
     JSObject* waiver = Wrapper::New(cx, obj, &XrayWaiver);
     if (!waiver)
         return nullptr;
 
     // Add the new waiver to the map. It's important that we only ever have
     // one waiver for the lifetime of the target object.
     if (!scope->mWaiverWrapperMap) {
         scope->mWaiverWrapperMap =
@@ -223,17 +223,17 @@ WrapperFactory::PrepareForWrapping(JSCon
     // between scopes so for those we also want to return the wrapper. So...
     if (!IS_WN_REFLECTOR(obj) || JS_IsGlobalObject(obj)) {
         retObj.set(waive ? WaiveXray(cx, obj) : obj);
         return;
     }
 
     XPCWrappedNative* wn = XPCWrappedNative::Get(obj);
 
-    JSAutoCompartment ac(cx, obj);
+    JSAutoRealm ar(cx, obj);
     XPCCallContext ccx(cx, obj);
     RootedObject wrapScope(cx, scope);
 
     {
         if (ccx.GetScriptable() && ccx.GetScriptable()->WantPreCreate()) {
             // We have a precreate hook. This object might enforce that we only
             // ever create JS object for it.
 
--- a/js/xpconnect/wrappers/XrayWrapper.cpp
+++ b/js/xpconnect/wrappers/XrayWrapper.cpp
@@ -320,17 +320,17 @@ ReportWrapperDenial(JSContext* cx, Handl
 bool JSXrayTraits::getOwnPropertyFromWrapperIfSafe(JSContext* cx,
                                                    HandleObject wrapper,
                                                    HandleId id,
                                                    MutableHandle<PropertyDescriptor> outDesc)
 {
     MOZ_ASSERT(js::IsObjectInContextCompartment(wrapper, cx));
     RootedObject target(cx, getTargetObject(wrapper));
     {
-        JSAutoCompartment ac(cx, target);
+        JSAutoRealm ar(cx, target);
         JS_MarkCrossZoneId(cx, id);
         if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, id, outDesc))
             return false;
     }
     return JS_WrapPropertyDescriptor(cx, outDesc);
 }
 
 bool JSXrayTraits::getOwnPropertyFromTargetIfSafe(JSContext* cx,
@@ -351,52 +351,52 @@ bool JSXrayTraits::getOwnPropertyFromTar
         return false;
 
     // If the property doesn't exist at all, we're done.
     if (!desc.object())
         return true;
 
     // Disallow accessor properties.
     if (desc.hasGetterOrSetter()) {
-        JSAutoCompartment ac(cx, wrapper);
+        JSAutoRealm ar(cx, wrapper);
         JS_MarkCrossZoneId(cx, id);
         return ReportWrapperDenial(cx, id, WrapperDenialForXray, "property has accessor");
     }
 
     // Apply extra scrutiny to objects.
     if (desc.value().isObject()) {
         RootedObject propObj(cx, js::UncheckedUnwrap(&desc.value().toObject()));
-        JSAutoCompartment ac(cx, propObj);
+        JSAutoRealm ar(cx, propObj);
 
         // Disallow non-subsumed objects.
         if (!AccessCheck::subsumes(target, propObj)) {
-            JSAutoCompartment ac(cx, wrapper);
+            JSAutoRealm ar(cx, wrapper);
             JS_MarkCrossZoneId(cx, id);
             return ReportWrapperDenial(cx, id, WrapperDenialForXray, "value not same-origin with target");
         }
 
         // Disallow non-Xrayable objects.
         XrayType xrayType = GetXrayType(propObj);
         if (xrayType == NotXray || xrayType == XrayForOpaqueObject) {
-            JSAutoCompartment ac(cx, wrapper);
+            JSAutoRealm ar(cx, wrapper);
             JS_MarkCrossZoneId(cx, id);
             return ReportWrapperDenial(cx, id, WrapperDenialForXray, "value not Xrayable");
         }
 
         // Disallow callables.
         if (JS::IsCallable(propObj)) {
-            JSAutoCompartment ac(cx, wrapper);
+            JSAutoRealm ar(cx, wrapper);
             JS_MarkCrossZoneId(cx, id);
             return ReportWrapperDenial(cx, id, WrapperDenialForXray, "value is callable");
         }
     }
 
     // Disallow any property that shadows something on its (Xrayed)
     // prototype chain.
-    JSAutoCompartment ac2(cx, wrapper);
+    JSAutoRealm ar2(cx, wrapper);
     JS_MarkCrossZoneId(cx, id);
     RootedObject proto(cx);
     bool foundOnProto = false;
     if (!JS_GetPrototype(cx, wrapper, &proto) ||
         (proto && !JS_HasPropertyById(cx, proto, id, &foundOnProto)))
     {
         return false;
     }
@@ -564,17 +564,17 @@ JSXrayTraits::resolveOwnProperty(JSConte
         }
         if (IsTypedArrayKey(key)) {
             if (IsArrayIndex(GetArrayIndexFromId(cx, id))) {
                 // WebExtensions can't use cloneInto(), so we just let them do
                 // the slow thing to maximize compatibility.
                 if (CompartmentPrivate::Get(CurrentGlobalOrNull(cx))->isWebExtensionContentScript) {
                     Rooted<PropertyDescriptor> innerDesc(cx);
                     {
-                        JSAutoCompartment ac(cx, target);
+                        JSAutoRealm ar(cx, target);
                         JS_MarkCrossZoneId(cx, id);
                         if (!JS_GetOwnPropertyDescriptorById(cx, target, id, &innerDesc))
                             return false;
                     }
                     if (innerDesc.isDataDescriptor() && innerDesc.value().isNumber()) {
                         desc.setValue(innerDesc.value());
                         desc.object().set(wrapper);
                     }
@@ -602,17 +602,17 @@ JSXrayTraits::resolveOwnProperty(JSConte
                 // 'prototype' property.
                 JSProtoKey standardConstructor = constructorFor(holder);
                 if (standardConstructor != JSProto_Null) {
                     // Handle the 'prototype' property to make
                     // xrayedGlobal.StandardClass.prototype work.
                     if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_PROTOTYPE)) {
                         RootedObject standardProto(cx);
                         {
-                            JSAutoCompartment ac(cx, target);
+                            JSAutoRealm ar(cx, target);
                             if (!JS_GetClassPrototype(cx, standardConstructor, &standardProto))
                                 return false;
                             MOZ_ASSERT(standardProto);
                         }
 
                         if (!JS_WrapObject(cx, &standardProto))
                             return false;
                         FillPropertyDescriptor(desc, wrapper, JSPROP_PERMANENT | JSPROP_READONLY,
@@ -672,17 +672,17 @@ JSXrayTraits::resolveOwnProperty(JSConte
         // The rest of this function applies only to prototypes.
         return true;
     }
 
     // Handle the 'constructor' property.
     if (id == GetJSIDByIndex(cx, XPCJSContext::IDX_CONSTRUCTOR)) {
         RootedObject constructor(cx);
         {
-            JSAutoCompartment ac(cx, target);
+            JSAutoRealm ar(cx, target);
             if (!JS_GetClassObject(cx, key, &constructor))
                 return false;
         }
         if (!JS_WrapObject(cx, &constructor))
             return false;
         desc.object().set(wrapper);
         desc.setAttributes(0);
         desc.setGetter(nullptr);
@@ -721,17 +721,17 @@ JSXrayTraits::delete_(JSContext* cx, Han
     // If we're using Object Xrays, we allow callers to attempt to delete any
     // property from the underlying object that they are able to resolve. Note
     // that this deleting may fail if the property is non-configurable.
     JSProtoKey key = getProtoKey(holder);
     bool isObjectOrArrayInstance = (key == JSProto_Object || key == JSProto_Array) &&
                                    !isPrototype(holder);
     if (isObjectOrArrayInstance) {
         RootedObject target(cx, getTargetObject(wrapper));
-        JSAutoCompartment ac(cx, target);
+        JSAutoRealm ar(cx, target);
         JS_MarkCrossZoneId(cx, id);
         Rooted<PropertyDescriptor> desc(cx);
         if (!getOwnPropertyFromTargetIfSafe(cx, target, wrapper, id, &desc))
             return false;
         if (desc.object())
             return JS_DeletePropertyById(cx, target, id, result);
     }
     return result.succeed();
@@ -779,17 +779,17 @@ JSXrayTraits::defineProperty(JSContext* 
             return false;
         }
         if (existingDesc.object() && existingDesc.object() != wrapper) {
             JS_ReportErrorASCII(cx, "Not allowed to shadow non-own Xray-resolved property on [Object] or [Array] XrayWrapper");
             return false;
         }
 
         Rooted<PropertyDescriptor> wrappedDesc(cx, desc);
-        JSAutoCompartment ac(cx, target);
+        JSAutoRealm ar(cx, target);
         JS_MarkCrossZoneId(cx, id);
         if (!JS_WrapPropertyDescriptor(cx, &wrappedDesc) ||
             !JS_DefinePropertyById(cx, target, id, wrappedDesc, result))
         {
             return false;
         }
         *defined = true;
         return true;
@@ -798,17 +798,17 @@ JSXrayTraits::defineProperty(JSContext* 
     // For WebExtensions content scripts, we forward the definition of indexed properties. By
     // validating that the key and value are both numbers, we can avoid doing any wrapping.
     if (isInstance && IsTypedArrayKey(key) &&
         CompartmentPrivate::Get(JS::CurrentGlobalOrNull(cx))->isWebExtensionContentScript &&
         desc.isDataDescriptor() && (desc.value().isNumber() || desc.value().isUndefined()) &&
         IsArrayIndex(GetArrayIndexFromId(cx, id)))
     {
         RootedObject target(cx, getTargetObject(wrapper));
-        JSAutoCompartment ac(cx, target);
+        JSAutoRealm ar(cx, target);
         JS_MarkCrossZoneId(cx, id);
         if (!JS_DefinePropertyById(cx, target, id, desc, result))
             return false;
         *defined = true;
         return true;
     }
 
     return true;
@@ -861,17 +861,17 @@ JSXrayTraits::enumerateNames(JSContext* 
 
     JSProtoKey key = getProtoKey(holder);
     if (!isPrototype(holder)) {
         // For Object and Array instances, we expose some properties from the underlying
         // object, but only after filtering them carefully.
         if (key == JSProto_Object || key == JSProto_Array) {
             MOZ_ASSERT(props.empty());
             {
-                JSAutoCompartment ac(cx, target);
+                JSAutoRealm ar(cx, target);
                 AutoIdVector targetProps(cx);
                 if (!js::GetPropertyKeys(cx, target, flags | JSITER_OWNONLY, &targetProps))
                     return false;
                 // Loop over the properties, and only pass along the ones that
                 // we determine to be safe.
                 if (!props.reserve(targetProps.length()))
                     return false;
                 for (size_t i = 0; i < targetProps.length(); ++i) {
@@ -1163,17 +1163,17 @@ XrayTraits::getExpandoObjectInternal(JSC
         }
 #endif
         return true;
     }
 
     // The expando object lives in the compartment of the target, so all our
     // work needs to happen there.
     RootedObject head(cx, expandoChain);
-    JSAutoCompartment ac(cx, head);
+    JSAutoRealm ar(cx, head);
 
     // Iterate through the chain, looking for a same-origin object.
     while (head) {
         if (expandoObjectMatchesConsumer(cx, head, origin)) {
             expandoObject.set(head);
             return true;
         }
         head = JS_GetReservedSlot(head, JSSLOT_EXPANDO_NEXT).toObjectOrNull();
@@ -1248,31 +1248,31 @@ XrayTraits::attachExpandoObject(JSContex
 
     // AddRef and store the principal.
     NS_ADDREF(origin);
     JS_SetReservedSlot(expandoObject, JSSLOT_EXPANDO_ORIGIN, JS::PrivateValue(origin));
 
     // Note the exclusive wrapper, if there is one.
     RootedObject wrapperHolder(cx);
     if (exclusiveWrapper) {
-        JSAutoCompartment ac(cx, exclusiveWrapper);
+        JSAutoRealm ar(cx, exclusiveWrapper);
         wrapperHolder = JS_NewObjectWithGivenProto(cx, &gWrapperHolderClass, nullptr);
         if (!wrapperHolder)
             return nullptr;
         JS_SetReservedSlot(wrapperHolder, JSSLOT_WRAPPER_HOLDER_CONTENTS, ObjectValue(*exclusiveWrapper));
     }
     if (!JS_WrapObject(cx, &wrapperHolder))
         return nullptr;
     JS_SetReservedSlot(expandoObject, JSSLOT_EXPANDO_EXCLUSIVE_WRAPPER_HOLDER,
                        ObjectOrNullValue(wrapperHolder));
 
     // Store it on the exclusive wrapper, if there is one.
     if (exclusiveWrapper) {
         RootedObject cachedExpandoObject(cx, expandoObject);
-        JSAutoCompartment ac(cx, exclusiveWrapper);
+        JSAutoRealm ar(cx, exclusiveWrapper);
         if (!JS_WrapObject(cx, &cachedExpandoObject))
             return nullptr;
         JSObject* holder = ensureHolder(cx, exclusiveWrapper);
         if (!holder)
             return nullptr;
         SetCachedXrayExpando(holder, cachedExpandoObject);
     }
 
@@ -1290,17 +1290,17 @@ XrayTraits::attachExpandoObject(JSContex
     return expandoObject;
 }
 
 JSObject*
 XrayTraits::ensureExpandoObject(JSContext* cx, HandleObject wrapper,
                                 HandleObject target)
 {
     // Expando objects live in the target compartment.
-    JSAutoCompartment ac(cx, target);
+    JSAutoRealm ar(cx, target);
     RootedObject expandoObject(cx);
     if (!getExpandoObject(cx, target, wrapper, &expandoObject))
         return nullptr;
     if (!expandoObject) {
         JSObject* consumerGlobal = js::GetGlobalForObjectCrossCompartment(wrapper);
         bool isExclusive = GlobalHasExclusiveExpandos(consumerGlobal);
         expandoObject = attachExpandoObject(cx, target, isExclusive ? wrapper : nullptr,
                                             ObjectPrincipal(wrapper));
@@ -1319,17 +1319,17 @@ XrayTraits::cloneExpandoChain(JSContext*
         RootedObject exclusiveWrapper(cx);
         RootedObject wrapperHolder(cx, JS_GetReservedSlot(oldHead,
                                                           JSSLOT_EXPANDO_EXCLUSIVE_WRAPPER_HOLDER)
                                                          .toObjectOrNull());
         if (wrapperHolder) {
             // The global containing this wrapper holder has an xray for |src|
             // with expandos. Create an xray in the global for |dst| which
             // will be associated with a clone of |src|'s expando object.
-            JSAutoCompartment ac(cx, UncheckedUnwrap(wrapperHolder));
+            JSAutoRealm ar(cx, UncheckedUnwrap(wrapperHolder));
             exclusiveWrapper = dst;
             if (!JS_WrapObject(cx, &exclusiveWrapper))
                 return false;
         }
         RootedObject newHead(cx, attachExpandoObject(cx, dst, exclusiveWrapper,
                                                      GetExpandoObjectPrincipal(oldHead)));
         if (!JS_CopyPropertiesFrom(cx, newHead, oldHead))
             return false;
@@ -1577,27 +1577,27 @@ XrayTraits::resolveOwnProperty(JSContext
     RootedObject expando(cx);
     if (!getExpandoObject(cx, target, wrapper, &expando))
         return false;
 
     // Check for expando properties first. Note that the expando object lives
     // in the target compartment.
     bool found = false;
     if (expando) {
-        JSAutoCompartment ac(cx, expando);
+        JSAutoRealm ar(cx, expando);
         JS_MarkCrossZoneId(cx, id);
         if (!JS_GetOwnPropertyDescriptorById(cx, expando, id, desc))
             return false;
         found = !!desc.object();
     }
 
     // Next, check for ES builtins.
     if (!found && JS_IsGlobalObject(target)) {
         JSProtoKey key = JS_IdToProtoKey(cx, id);
-        JSAutoCompartment ac(cx, target);
+        JSAutoRealm ar(cx, target);
         if (key != JSProto_Null) {
             MOZ_ASSERT(key < JSProto_LIMIT);
             RootedObject constructor(cx);
             if (!JS_GetClassObject(cx, key, &constructor))
                 return false;
             MOZ_ASSERT(constructor);
             desc.value().set(ObjectValue(*constructor));
             found = true;
@@ -1660,17 +1660,17 @@ XPCWrappedNativeXrayTraits::resolveOwnPr
 bool
 XPCWrappedNativeXrayTraits::enumerateNames(JSContext* cx, HandleObject wrapper, unsigned flags,
                                            AutoIdVector& props)
 {
     // Force all native properties to be materialized onto the wrapped native.
     AutoIdVector wnProps(cx);
     {
         RootedObject target(cx, getTargetObject(wrapper));
-        JSAutoCompartment ac(cx, target);
+        JSAutoRealm ar(cx, target);
         if (!js::GetPropertyKeys(cx, target, flags, &wnProps))
             return false;
     }
 
     // Go through the properties we found on the underlying object and see if
     // they appear on the XrayWrapper. If it throws (which may happen if the
     // wrapper is a SecurityWrapper), just clear the exception and move on.
     MOZ_ASSERT(!JS_IsExceptionPending(cx));
@@ -2275,17 +2275,17 @@ XrayWrapper<Base, Traits>::definePropert
     if (!Traits::singleton.defineProperty(cx, wrapper, id, desc, existing_desc, result, &defined))
         return false;
     if (defined)
         return true;
 
     // We're placing an expando. The expando objects live in the target
     // compartment, so we need to enter it.
     RootedObject target(cx, Traits::getTargetObject(wrapper));
-    JSAutoCompartment ac(cx, target);
+    JSAutoRealm ar(cx, target);
     JS_MarkCrossZoneId(cx, id);
 
     // Grab the relevant expando object.
     RootedObject expandoObject(cx, Traits::singleton.ensureExpandoObject(cx, wrapper,
                                                                          target));
     if (!expandoObject)
         return false;
 
@@ -2319,17 +2319,17 @@ XrayWrapper<Base, Traits>::delete_(JSCon
 
     // Check the expando object.
     RootedObject target(cx, Traits::getTargetObject(wrapper));
     RootedObject expando(cx);
     if (!Traits::singleton.getExpandoObject(cx, target, wrapper, &expando))
         return false;
 
     if (expando) {
-        JSAutoCompartment ac(cx, expando);
+        JSAutoRealm ar(cx, expando);
         JS_MarkCrossZoneId(cx, id);
         bool hasProp;
         if (!JS_HasPropertyById(cx, expando, id, &hasProp)) {
             return false;
         }
         if (hasProp) {
             return JS_DeletePropertyById(cx, expando, id, result);
         }
@@ -2488,18 +2488,18 @@ XrayWrapper<Base, Traits>::getPrototype(
         return false;
 
     // We want to keep the Xray's prototype distinct from that of content, but
     // only if there's been a set. If there's not an expando, or the expando
     // slot is |undefined|, hand back the default proto, appropriately wrapped.
 
     if (expando) {
         RootedValue v(cx);
-        { // Scope for JSAutoCompartment
-            JSAutoCompartment ac(cx, expando);
+        { // Scope for JSAutoRealm
+            JSAutoRealm ar(cx, expando);
             v = JS_GetReservedSlot(expando, JSSLOT_EXPANDO_PROTOTYPE);
         }
         if (!v.isUndefined()) {
             protop.set(v.toObjectOrNull());
             return JS_WrapObject(cx, protop);
         }
     }
 
@@ -2532,18 +2532,18 @@ XrayWrapper<Base, Traits>::setPrototype(
     if (Base::hasSecurityPolicy())
         return Base::setPrototype(cx, wrapper, proto, result);
 
     RootedObject target(cx, Traits::getTargetObject(wrapper));
     RootedObject expando(cx, Traits::singleton.ensureExpandoObject(cx, wrapper, target));
     if (!expando)
         return false;
 
-    // The expando lives in the target's compartment, so do our installation there.
-    JSAutoCompartment ac(cx, target);
+    // The expando lives in the target's realm, so do our installation there.
+    JSAutoRealm ar(cx, target);
 
     RootedValue v(cx, ObjectOrNullValue(proto));
     if (!JS_WrapValue(cx, &v))
         return false;
     JS_SetReservedSlot(expando, JSSLOT_EXPANDO_PROTOTYPE, v);
     return result.succeed();
 }
 
@@ -2586,17 +2586,17 @@ XrayWrapper<Base, Traits>::getPropertyKe
     // Enumerate expando properties first. Note that the expando object lives
     // in the target compartment.
     RootedObject target(cx, Traits::getTargetObject(wrapper));
     RootedObject expando(cx);
     if (!Traits::singleton.getExpandoObject(cx, target, wrapper, &expando))
         return false;
 
     if (expando) {
-        JSAutoCompartment ac(cx, expando);
+        JSAutoRealm ar(cx, expando);
         if (!js::GetPropertyKeys(cx, expando, flags, &props))
             return false;
     }
     for (size_t i = 0; i < props.length(); ++i)
         JS_MarkCrossZoneId(cx, props[i]);
 
     return Traits::singleton.enumerateNames(cx, wrapper, flags, props);
 }
--- a/js/xpconnect/wrappers/XrayWrapper.h
+++ b/js/xpconnect/wrappers/XrayWrapper.h
@@ -300,17 +300,17 @@ public:
             if (protoKey == JSProto_Null) {
                 protop.set(nullptr);
                 return true;
             }
             key = protoKey;
         }
 
         {
-            JSAutoCompartment ac(cx, target);
+            JSAutoRealm ar(cx, target);
             if (!JS_GetClassPrototype(cx, key, protop))
                 return false;
         }
         return JS_WrapObject(cx, protop);
     }
 
     virtual void preserveWrapper(JSObject* target) override {
         // In the case of pure JS objects, there is no underlying object, and
@@ -414,17 +414,17 @@ public:
     bool getPrototype(JSContext* cx, JS::HandleObject wrapper,
                       JS::HandleObject target,
                       JS::MutableHandleObject protop)
     {
         // Opaque wrappers just get targetGlobal.Object.prototype as their
         // prototype. This is preferable to using a null prototype because it
         // lets things like |toString| and |__proto__| work.
         {
-            JSAutoCompartment ac(cx, target);
+            JSAutoRealm ar(cx, target);
             if (!JS_GetClassPrototype(cx, JSProto_Object, protop))
                 return false;
         }
         return JS_WrapObject(cx, protop);
     }
 
     static bool getBuiltinClass(JSContext* cx, JS::HandleObject wrapper, const js::Wrapper& baseInstance,
                                 js::ESClass* cls) {
--- a/netwerk/base/ProxyAutoConfig.cpp
+++ b/netwerk/base/ProxyAutoConfig.cpp
@@ -646,29 +646,29 @@ private:
     JS_SetNativeStackQuota(mContext, 128 * sizeof(size_t) * 1024);
 
     JS::SetWarningReporter(mContext, PACWarningReporter);
 
     if (!JS::InitSelfHostedCode(mContext)) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
-    JSAutoRequest ar(mContext);
+    JSAutoRequest areq(mContext);
 
     JS::CompartmentOptions options;
     options.creationOptions().setSystemZone();
     mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, nullptr,
                                  JS::DontFireOnNewGlobalHook, options);
     if (!mGlobal) {
       JS_ClearPendingException(mContext);
       return NS_ERROR_OUT_OF_MEMORY;
     }
     JS::Rooted<JSObject*> global(mContext, mGlobal);
 
-    JSAutoCompartment ac(mContext, global);
+    JSAutoRealm ar(mContext, global);
     AutoPACErrorReporter aper(mContext);
     if (!JS_InitStandardClasses(mContext, global)) {
       return NS_ERROR_FAILURE;
     }
     if (!JS_DefineFunctions(mContext, global, PACGlobalFunctions)) {
       return NS_ERROR_FAILURE;
     }
 
@@ -732,18 +732,18 @@ ProxyAutoConfig::SetupJS()
 
   NS_GetCurrentThread()->SetCanInvokeJS(true);
 
   mJSContext = JSContextWrapper::Create(mExtraHeapSize);
   if (!mJSContext)
     return NS_ERROR_FAILURE;
 
   JSContext* cx = mJSContext->Context();
-  JSAutoRequest ar(cx);
-  JSAutoCompartment ac(cx, mJSContext->Global());
+  JSAutoRequest areq(cx);
+  JSAutoRealm ar(cx, mJSContext->Global());
   AutoPACErrorReporter aper(cx);
 
   // check if this is a data: uri so that we don't spam the js console with
   // huge meaningless strings. this is not on the main thread, so it can't
   // use nsIURI scheme methods
   bool isDataURI = nsDependentCSubstring(mPACURI, 0, 5).LowerCaseEqualsASCII("data:", 5);
 
   SetRunning(this);
@@ -792,18 +792,18 @@ ProxyAutoConfig::GetProxyForURI(const ns
 {
   if (mJSNeedsSetup)
     SetupJS();
 
   if (!mJSContext || !mJSContext->IsOK())
     return NS_ERROR_NOT_AVAILABLE;
 
   JSContext *cx = mJSContext->Context();
-  JSAutoRequest ar(cx);
-  JSAutoCompartment ac(cx, mJSContext->Global());
+  JSAutoRequest areq(cx);
+  JSAutoRealm ar(cx, mJSContext->Global());
   AutoPACErrorReporter aper(cx);
 
   // the sRunning flag keeps a new PAC file from being installed
   // while the event loop is spinning on a DNS function. Don't early return.
   SetRunning(this);
   mRunningHost = aTestHost;
 
   nsresult rv = NS_ERROR_FAILURE;
@@ -860,17 +860,17 @@ ProxyAutoConfig::GetProxyForURI(const ns
 }
 
 void
 ProxyAutoConfig::GC()
 {
   if (!mJSContext || !mJSContext->IsOK())
     return;
 
-  JSAutoCompartment ac(mJSContext->Context(), mJSContext->Global());
+  JSAutoRealm ar(mJSContext->Context(), mJSContext->Global());
   JS_MaybeGC(mJSContext->Context());
 }
 
 ProxyAutoConfig::~ProxyAutoConfig()
 {
   MOZ_COUNT_DTOR(ProxyAutoConfig);
   MOZ_ASSERT(mShutdown, "Shutdown must be called before dtor.");
   NS_ASSERTION(!mJSContext,
--- a/toolkit/components/extensions/MatchPattern.cpp
+++ b/toolkit/components/extensions/MatchPattern.cpp
@@ -723,17 +723,17 @@ MatchGlob::Init(JSContext* aCx, const ns
 bool
 MatchGlob::Matches(const nsAString& aString) const
 {
   if (mRegExp) {
     AutoJSAPI jsapi;
     jsapi.Init();
     JSContext* cx = jsapi.cx();
 
-    JSAutoCompartment ac(cx, mRegExp);
+    JSAutoRealm ar(cx, mRegExp);
 
     JS::RootedObject regexp(cx, mRegExp);
     JS::RootedValue result(cx);
 
     nsString input(aString);
 
     size_t index = 0;
     if (!JS_ExecuteRegExpNoStatics(cx, regexp, input.BeginWriting(), aString.Length(),
--- a/toolkit/components/mozintl/MozIntlHelper.cpp
+++ b/toolkit/components/mozintl/MozIntlHelper.cpp
@@ -25,17 +25,17 @@ AddFunctions(JSContext* cx, JS::Handle<J
     return NS_ERROR_INVALID_ARG;
   }
 
   JS::Rooted<JSObject*> realIntlObj(cx, js::CheckedUnwrap(&val.toObject()));
   if (!realIntlObj) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  JSAutoCompartment ac(cx, realIntlObj);
+  JSAutoRealm ar(cx, realIntlObj);
 
   if (!JS_DefineFunctions(cx, realIntlObj, funcs)) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
@@ -68,17 +68,17 @@ MozIntlHelper::AddDateTimeFormatConstruc
     return NS_ERROR_INVALID_ARG;
   }
 
   JS::Rooted<JSObject*> realIntlObj(cx, js::CheckedUnwrap(&val.toObject()));
   if (!realIntlObj) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  JSAutoCompartment ac(cx, realIntlObj);
+  JSAutoRealm ar(cx, realIntlObj);
 
   if (!js::AddMozDateTimeFormatConstructor(cx, realIntlObj)) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }
 
@@ -89,17 +89,17 @@ MozIntlHelper::AddRelativeTimeFormatCons
     return NS_ERROR_INVALID_ARG;
   }
 
   JS::Rooted<JSObject*> realIntlObj(cx, js::CheckedUnwrap(&val.toObject()));
   if (!realIntlObj) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  JSAutoCompartment ac(cx, realIntlObj);
+  JSAutoRealm ar(cx, realIntlObj);
 
   if (!js::AddRelativeTimeFormatConstructor(cx, realIntlObj)) {
     return NS_ERROR_FAILURE;
   }
 
   return NS_OK;
 }