Bug 1461292 part 3 - Rename AutoCompartment to AutoRealm. r=luke
authorJan de Mooij <jdemooij@mozilla.com>
Wed, 16 May 2018 21:03:18 +0200
changeset 418601 cf1b00c73d578d354661763722f27468bace2e05
parent 418600 11857580f5e11b0cd8429ce7522782ddcc2ecccd
child 418602 f050b09ee268eda98757cceb75b9e06a357a68d4
push id34007
push usercsabou@mozilla.com
push dateThu, 17 May 2018 09:47:02 +0000
treeherdermozilla-central@8fb36531f7d0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
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 3 - Rename AutoCompartment to AutoRealm. r=luke
js/src/builtin/Promise.cpp
js/src/builtin/TestingFunctions.cpp
js/src/devtools/rootAnalysis/annotations.js
js/src/devtools/rootAnalysis/computeGCFunctions.js
js/src/gc/Nursery.cpp
js/src/jit/BaselineDebugModeOSR.cpp
js/src/jit/CacheIR.cpp
js/src/jit/Ion.cpp
js/src/jit/JitFrames.cpp
js/src/jsapi-tests/testArrayBufferView.cpp
js/src/jsapi.cpp
js/src/jsfriendapi.cpp
js/src/proxy/CrossCompartmentWrapper.cpp
js/src/proxy/Wrapper.cpp
js/src/shell/js.cpp
js/src/vm/ArrayBufferObject.cpp
js/src/vm/BytecodeUtil.cpp
js/src/vm/Debugger.cpp
js/src/vm/Debugger.h
js/src/vm/GlobalObject.cpp
js/src/vm/HelperThreads.cpp
js/src/vm/Iteration.cpp
js/src/vm/JSAtom.cpp
js/src/vm/JSCompartment-inl.h
js/src/vm/JSCompartment.cpp
js/src/vm/JSCompartment.h
js/src/vm/JSContext.cpp
js/src/vm/JSContext.h
js/src/vm/JSObject.cpp
js/src/vm/JSScript.cpp
js/src/vm/SavedStacks.cpp
js/src/vm/SelfHosting.cpp
js/src/vm/Stack.cpp
js/src/vm/StringType.cpp
js/src/vm/StructuredClone.cpp
js/src/vm/SymbolType.cpp
--- a/js/src/builtin/Promise.cpp
+++ b/js/src/builtin/Promise.cpp
@@ -663,28 +663,28 @@ EnqueuePromiseReactionJob(JSContext* cx,
                           HandleValue handlerArg_, JS::PromiseState targetState)
 {
     // The reaction might have been stored on a Promise from another
     // compartment, which means it would've been wrapped in a CCW.
     // To properly handle that case here, unwrap it and enter its
     // compartment, where the job creation should take place anyway.
     Rooted<PromiseReactionRecord*> reaction(cx);
     RootedValue handlerArg(cx, handlerArg_);
-    mozilla::Maybe<AutoCompartment> ac;
+    mozilla::Maybe<AutoRealm> ar;
     if (!IsProxy(reactionObj)) {
         MOZ_RELEASE_ASSERT(reactionObj->is<PromiseReactionRecord>());
         reaction = &reactionObj->as<PromiseReactionRecord>();
     } else {
         if (JS_IsDeadWrapper(UncheckedUnwrap(reactionObj))) {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
             return false;
         }
         reaction = &UncheckedUnwrap(reactionObj)->as<PromiseReactionRecord>();
         MOZ_RELEASE_ASSERT(reaction->is<PromiseReactionRecord>());
-        ac.emplace(cx, reaction);
+        ar.emplace(cx, reaction);
         if (!reaction->compartment()->wrap(cx, &handlerArg))
             return false;
     }
 
     // Must not enqueue a reaction job more than once.
     MOZ_ASSERT(reaction->targetState() == JS::PromiseState::Pending);
 
     assertSameCompartment(cx, handlerArg);
@@ -695,27 +695,27 @@ EnqueuePromiseReactionJob(JSContext* cx,
     reaction->setTargetState(targetState);
     RootedValue handler(cx, reaction->handler());
 
     // If we have a handler callback, we enter that handler's compartment so
     // that the promise reaction job function is created in that compartment.
     // That guarantees that the embedding ends up with the right entry global.
     // This is relevant for some html APIs like fetch that derive information
     // from said global.
-    mozilla::Maybe<AutoCompartment> ac2;
+    mozilla::Maybe<AutoRealm> ar2;
     if (handler.isObject()) {
         RootedObject handlerObj(cx, &handler.toObject());
 
         // The unwrapping has to be unchecked because we specifically want to
         // be able to use handlers with wrappers that would only allow calls.
         // E.g., it's ok to have a handler from a chrome compartment in a
         // reaction to a content compartment's Promise instance.
         handlerObj = UncheckedUnwrap(handlerObj);
         MOZ_ASSERT(handlerObj);
-        ac2.emplace(cx, handlerObj);
+        ar2.emplace(cx, handlerObj);
 
         // We need to wrap the reaction to store it on the job function.
         if (!cx->compartment()->wrap(cx, &reactionVal))
             return false;
     }
 
     // Create the JS function to call when the job is triggered.
     RootedAtom funName(cx, cx->names().empty);
@@ -813,26 +813,26 @@ ResolvePromise(JSContext* cx, Handle<Pro
 
 // ES2016, 25.4.1.4.
 static MOZ_MUST_USE bool
 FulfillMaybeWrappedPromise(JSContext *cx, HandleObject promiseObj, HandleValue value_)
 {
     Rooted<PromiseObject*> promise(cx);
     RootedValue value(cx, value_);
 
-    mozilla::Maybe<AutoCompartment> ac;
+    mozilla::Maybe<AutoRealm> ar;
     if (!IsProxy(promiseObj)) {
         promise = &promiseObj->as<PromiseObject>();
     } else {
         if (JS_IsDeadWrapper(UncheckedUnwrap(promiseObj))) {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
             return false;
         }
         promise = &UncheckedUnwrap(promiseObj)->as<PromiseObject>();
-        ac.emplace(cx, promise);
+        ar.emplace(cx, promise);
         if (!promise->compartment()->wrap(cx, &value))
             return false;
     }
 
     MOZ_ASSERT(promise->state() == JS::PromiseState::Pending);
 
     return ResolvePromise(cx, promise, value, JS::PromiseState::Fulfilled);
 }
@@ -996,26 +996,26 @@ GetCapabilitiesExecutor(JSContext* cx, u
 
 // ES2016, 25.4.1.7.
 static MOZ_MUST_USE bool
 RejectMaybeWrappedPromise(JSContext *cx, HandleObject promiseObj, HandleValue reason_)
 {
     Rooted<PromiseObject*> promise(cx);
     RootedValue reason(cx, reason_);
 
-    mozilla::Maybe<AutoCompartment> ac;
+    mozilla::Maybe<AutoRealm> ar;
     if (!IsProxy(promiseObj)) {
         promise = &promiseObj->as<PromiseObject>();
     } else {
         if (JS_IsDeadWrapper(UncheckedUnwrap(promiseObj))) {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
             return false;
         }
         promise = &UncheckedUnwrap(promiseObj)->as<PromiseObject>();
-        ac.emplace(cx, promise);
+        ar.emplace(cx, promise);
 
         // The rejection reason might've been created in a compartment with higher
         // privileges than the Promise's. In that case, object-type rejection
         // values might be wrapped into a wrapper that throws whenever the
         // Promise's reaction handler wants to do anything useful with it. To
         // avoid that situation, we synthesize a generic error that doesn't
         // expose any privileged information but can safely be used in the
         // rejection handler.
@@ -1174,27 +1174,27 @@ PromiseReactionJob(JSContext* cx, unsign
 
     // To ensure that the embedding ends up with the right entry global, we're
     // guaranteeing that the reaction job function gets created in the same
     // compartment as the handler function. That's not necessarily the global
     // that the job was triggered from, though.
     // We can find the triggering global via the job's reaction record. To go
     // back, we check if the reaction is a wrapper and if so, unwrap it and
     // enter its compartment.
-    mozilla::Maybe<AutoCompartment> ac;
+    mozilla::Maybe<AutoRealm> ar;
     if (!IsProxy(reactionObj)) {
         MOZ_RELEASE_ASSERT(reactionObj->is<PromiseReactionRecord>());
     } else {
         reactionObj = UncheckedUnwrap(reactionObj);
         if (JS_IsDeadWrapper(reactionObj)) {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
             return false;
         }
         MOZ_RELEASE_ASSERT(reactionObj->is<PromiseReactionRecord>());
-        ac.emplace(cx, reactionObj);
+        ar.emplace(cx, reactionObj);
     }
 
     // Steps 1-2.
     Rooted<PromiseReactionRecord*> reaction(cx, &reactionObj->as<PromiseReactionRecord>());
     if (reaction->isAsyncFunction())
         return AsyncFunctionPromiseReactionJob(cx, reaction, args.rval());
     if (reaction->isAsyncGenerator())
         return AsyncGeneratorPromiseReactionJob(cx, reaction, args.rval());
@@ -1339,17 +1339,17 @@ EnqueuePromiseResolveThenableJob(JSConte
     RootedValue thenable(cx, thenable_);
 
     // We enter the `then` callable's compartment so that the job function is
     // created in that compartment.
     // That guarantees that the embedding ends up with the right entry global.
     // This is relevant for some html APIs like fetch that derive information
     // from said global.
     RootedObject then(cx, CheckedUnwrap(&thenVal.toObject()));
-    AutoCompartment ac(cx, then);
+    AutoRealm ar(cx, then);
 
     RootedAtom funName(cx, cx->names().empty);
     RootedFunction job(cx, NewNativeFunction(cx, PromiseResolveThenableJob, 0, funName,
                                              gc::AllocKind::FUNCTION_EXTENDED, GenericObject));
     if (!job)
         return false;
 
     // Store the `then` function on the callback.
@@ -1469,19 +1469,19 @@ CreatePromiseObjectInternal(JSContext* c
                             bool protoIsWrapped /* = false */, bool informDebugger /* = true */)
 {
     // Step 3.
     // Enter the unwrapped proto's compartment, if that's different from
     // the current one.
     // All state stored in a Promise's fixed slots must be created in the
     // same compartment, so we get all of that out of the way here.
     // (Except for the resolution functions, which are created below.)
-    mozilla::Maybe<AutoCompartment> ac;
+    mozilla::Maybe<AutoRealm> ar;
     if (protoIsWrapped)
-        ac.emplace(cx, proto);
+        ar.emplace(cx, proto);
 
     PromiseObject* promise = NewObjectWithClassProto<PromiseObject>(cx, proto);
     if (!promise)
         return nullptr;
 
     // Step 4.
     promise->initFixedSlot(PromiseSlot_Flags, Int32Value(0));
 
@@ -1562,17 +1562,17 @@ PromiseConstructor(JSContext* cx, unsign
     RootedObject proto(cx);
     if (IsWrapper(newTarget)) {
         JSObject* unwrappedNewTarget = CheckedUnwrap(newTarget);
         MOZ_ASSERT(unwrappedNewTarget);
         MOZ_ASSERT(unwrappedNewTarget != newTarget);
 
         newTarget = unwrappedNewTarget;
         {
-            AutoCompartment ac(cx, newTarget);
+            AutoRealm ar(cx, newTarget);
             Handle<GlobalObject*> global = cx->global();
             RootedObject promiseCtor(cx, GlobalObject::getOrCreatePromiseConstructor(cx, global));
             if (!promiseCtor)
                 return false;
 
             // Promise subclasses don't get the special Xray treatment, so
             // we only need to do the complex wrapping and unwrapping scheme
             // described above for instances of Promise itself.
@@ -1641,17 +1641,17 @@ PromiseObject::create(JSContext* cx, Han
     RootedObject rejectFn(cx);
     if (!CreateResolvingFunctions(cx, promiseObj, &resolveFn, &rejectFn))
         return nullptr;
 
     // Need to wrap the resolution functions before storing them on the Promise.
     MOZ_ASSERT(promise->getFixedSlot(PromiseSlot_RejectFunction).isUndefined(),
                "Slot must be undefined so initFixedSlot can be used");
     if (needsWrapping) {
-        AutoCompartment ac(cx, promise);
+        AutoRealm ar(cx, promise);
         RootedObject wrappedRejectFn(cx, rejectFn);
         if (!cx->compartment()->wrap(cx, &wrappedRejectFn))
             return nullptr;
         promise->initFixedSlot(PromiseSlot_RejectFunction, ObjectValue(*wrappedRejectFn));
     } else {
         promise->initFixedSlot(PromiseSlot_RejectFunction, ObjectValue(*rejectFn));
     }
 
@@ -2127,17 +2127,17 @@ PromiseAllResolveElementFunction(JSConte
     RootedNativeObject values(cx, &valuesObj->as<NativeObject>());
 
     // Step 6 (moved under step 10).
     // Step 7 (moved to step 9).
 
     // Step 8.
     // The index is guaranteed to be initialized to `undefined`.
     if (valuesListIsWrapped) {
-        AutoCompartment ac(cx, values);
+        AutoRealm ar(cx, values);
         if (!cx->compartment()->wrap(cx, &xVal))
             return false;
     }
     values->setDenseElement(index, xVal);
 
     // Steps 7,9.
     uint32_t remainingCount = data->decreaseRemainingCount();
 
@@ -3320,28 +3320,28 @@ BlockOnPromise(JSContext* cx, HandleValu
     // overridden by content and could leak it, or because a constructor
     // other than the original value of |Promise| was used to create it).
     // To have both that object and |blockedPromise| show up as dependent
     // promises in the debugger, add a dummy reaction to the list of reject
     // reactions that contains |blockedPromise|, but otherwise does nothing.
     RootedObject unwrappedPromiseObj(cx, promiseObj);
     RootedObject blockedPromise(cx, blockedPromise_);
 
-    mozilla::Maybe<AutoCompartment> ac;
+    mozilla::Maybe<AutoRealm> ar;
     if (IsProxy(promiseObj)) {
         unwrappedPromiseObj = CheckedUnwrap(promiseObj);
         if (!unwrappedPromiseObj) {
             ReportAccessDenied(cx);
             return false;
         }
         if (JS_IsDeadWrapper(unwrappedPromiseObj)) {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DEAD_OBJECT);
             return false;
         }
-        ac.emplace(cx, unwrappedPromiseObj);
+        ar.emplace(cx, unwrappedPromiseObj);
         if (!cx->compartment()->wrap(cx, &blockedPromise))
             return false;
     }
 
     // If either the object to depend on or the object that gets blocked isn't
     // a, maybe-wrapped, Promise instance, we ignore it. All this does is lose
     // some small amount of debug information in scenarios that are highly
     // unlikely to occur in useful code.
@@ -3362,19 +3362,19 @@ AddPromiseReaction(JSContext* cx, Handle
     MOZ_RELEASE_ASSERT(reaction->is<PromiseReactionRecord>());
     RootedValue reactionVal(cx, ObjectValue(*reaction));
 
     // The code that creates Promise reactions can handle wrapped Promises,
     // unwrapping them as needed. That means that the `promise` and `reaction`
     // objects we have here aren't necessarily from the same compartment. In
     // order to store the reaction on the promise, we have to ensure that it
     // is properly wrapped.
-    mozilla::Maybe<AutoCompartment> ac;
+    mozilla::Maybe<AutoRealm> ar;
     if (promise->compartment() != cx->compartment()) {
-        ac.emplace(cx, promise);
+        ar.emplace(cx, promise);
         if (!cx->compartment()->wrap(cx, &reactionVal))
             return false;
     }
 
     // 25.4.5.3.1 steps 7.a,b.
     RootedValue reactionsVal(cx, promise->getFixedSlot(PromiseSlot_ReactionsOrResult));
     RootedNativeObject reactions(cx);
 
@@ -3620,17 +3620,17 @@ OffThreadPromiseTask::run(JSContext* cx,
     MOZ_ASSERT(CurrentThreadCanAccessRuntime(runtime_));
     MOZ_ASSERT(registered_);
     MOZ_ASSERT(runtime_->offThreadPromiseState.ref().initialized());
 
     if (maybeShuttingDown == JS::Dispatchable::NotShuttingDown) {
         // We can't leave a pending exception when returning to the caller so do
         // the same thing as Gecko, which is to ignore the error. This should
         // only happen due to OOM or interruption.
-        AutoCompartment ac(cx, promise_);
+        AutoRealm ar(cx, promise_);
         if (!resolve(cx, promise_))
             cx->clearPendingException();
     }
 
     js_delete(this);
 }
 
 void
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -1326,19 +1326,19 @@ SaveStack(JSContext* cx, unsigned argc, 
         }
         compartmentObject = UncheckedUnwrap(&args[1].toObject());
         if (!compartmentObject)
             return false;
     }
 
     RootedObject stack(cx);
     {
-        Maybe<AutoCompartment> ac;
+        Maybe<AutoRealm> ar;
         if (compartmentObject)
-            ac.emplace(cx, compartmentObject);
+            ar.emplace(cx, compartmentObject);
         if (!JS::CaptureCurrentStack(cx, &stack, mozilla::Move(capture)))
             return false;
     }
 
     if (stack && !cx->compartment()->wrap(cx, &stack))
         return false;
 
     args.rval().setObjectOrNull(stack);
@@ -2178,20 +2178,20 @@ ResolvePromise(JSContext* cx, unsigned a
         return false;
     if (!args[0].isObject() || !UncheckedUnwrap(&args[0].toObject())->is<PromiseObject>()) {
         JS_ReportErrorASCII(cx, "first argument must be a maybe-wrapped Promise object");
         return false;
     }
 
     RootedObject promise(cx, &args[0].toObject());
     RootedValue resolution(cx, args[1]);
-    mozilla::Maybe<AutoCompartment> ac;
+    mozilla::Maybe<AutoRealm> ar;
     if (IsWrapper(promise)) {
         promise = UncheckedUnwrap(promise);
-        ac.emplace(cx, promise);
+        ar.emplace(cx, promise);
         if (!cx->compartment()->wrap(cx, &resolution))
             return false;
     }
 
     if (IsPromiseForAsync(promise)) {
         JS_ReportErrorASCII(cx, "async function's promise shouldn't be manually resolved");
         return false;
     }
@@ -2210,20 +2210,20 @@ RejectPromise(JSContext* cx, unsigned ar
         return false;
     if (!args[0].isObject() || !UncheckedUnwrap(&args[0].toObject())->is<PromiseObject>()) {
         JS_ReportErrorASCII(cx, "first argument must be a maybe-wrapped Promise object");
         return false;
     }
 
     RootedObject promise(cx, &args[0].toObject());
     RootedValue reason(cx, args[1]);
-    mozilla::Maybe<AutoCompartment> ac;
+    mozilla::Maybe<AutoRealm> ar;
     if (IsWrapper(promise)) {
         promise = UncheckedUnwrap(promise);
-        ac.emplace(cx, promise);
+        ar.emplace(cx, promise);
         if (!cx->compartment()->wrap(cx, &reason))
             return false;
     }
 
     if (IsPromiseForAsync(promise)) {
         JS_ReportErrorASCII(cx, "async function's promise shouldn't be manually rejected");
         return false;
     }
@@ -3922,17 +3922,17 @@ EvalReturningScope(JSContext* cx, unsign
 
     RootedObject varObj(cx);
     RootedObject lexicalScope(cx);
 
     {
         // If we're switching globals here, ExecuteInGlobalAndReturnScope will
         // take care of cloning the script into that compartment before
         // executing it.
-        AutoCompartment ac(cx, global);
+        AutoRealm ar(cx, global);
 
         if (!js::ExecuteInGlobalAndReturnScope(cx, global, script, &lexicalScope))
             return false;
 
         varObj = lexicalScope->enclosingEnvironment();
     }
 
     RootedObject rv(cx, JS_NewPlainObject(cx));
@@ -3997,17 +3997,17 @@ ShellCloneAndExecuteScript(JSContext* cx
         JS_ReportErrorASCII(cx, "Permission denied to access global");
         return false;
     }
     if (!global->is<GlobalObject>()) {
         JS_ReportErrorASCII(cx, "Argument must be a global object");
         return false;
     }
 
-    AutoCompartment ac(cx, global);
+    AutoRealm ar(cx, global);
 
     JS::RootedValue rval(cx);
     if (!JS::CloneAndExecuteScript(cx, script, &rval))
         return false;
 
     args.rval().setUndefined();
     return true;
 }
@@ -4382,17 +4382,17 @@ GetLcovInfo(JSContext* cx, unsigned argc
         }
     } else {
         global = JS::CurrentGlobalOrNull(cx);
     }
 
     size_t length = 0;
     char* content = nullptr;
     {
-        AutoCompartment ac(cx, global);
+        AutoRealm ar(cx, global);
         content = js::GetCodeCoverageSummary(cx, &length);
     }
 
     if (!content)
         return false;
 
     JSString* str = JS_NewStringCopyN(cx, content, length);
     free(content);
@@ -5186,17 +5186,17 @@ BaselineCompile(JSContext* cx, unsigned 
             ReportUsageErrorASCII(cx, callee, "forceDebugInstrumentation argument should be boolean");
             return false;
         }
         forceDebug = ToBoolean(args[1]);
     }
 
     const char* returnedStr = nullptr;
     do {
-        AutoCompartment ac(cx, script);
+        AutoRealm ar(cx, script);
         if (script->hasBaselineScript()) {
             if (forceDebug && !script->baselineScript()->hasDebugInstrumentation()) {
                 // There isn't an easy way to do this for a script that might be on
                 // stack right now. See js::jit::RecompileOnStackBaselineScriptsForDebugMode.
                 ReportUsageErrorASCII(cx, callee,
                                       "unsupported case: recompiling script for debug mode");
                 return false;
             }
--- a/js/src/devtools/rootAnalysis/annotations.js
+++ b/js/src/devtools/rootAnalysis/annotations.js
@@ -195,17 +195,17 @@ var ignoreFunctions = {
     "NS_LogCOMPtrAddRef": true,
     "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 js::AutoRealm::~AutoRealm(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
--- a/js/src/devtools/rootAnalysis/computeGCFunctions.js
+++ b/js/src/devtools/rootAnalysis/computeGCFunctions.js
@@ -42,17 +42,17 @@ redirect(gcFunctionsList_filename);
 for (var name in gcFunctions) {
     for (var readable of readableNames[name])
         print(name + "$" + readable);
 }
 
 // gcEdges is a list of edges that can GC for more specific reasons than just
 // calling a function that is in gcFunctions.txt.
 //
-// Right now, it is unused. It was meant for ~AutoCompartment when it might
+// Right now, it is unused. It was meant for ~AutoRealm when it might
 // wrap an exception, but anything held live across ~AC will have to be held
 // live across the corresponding constructor (and hence the whole scope of the
 // AC), and in that case it'll be held live across whatever could create an
 // exception within the AC scope. So ~AC edges are redundant. I will leave the
 // stub machinery here for now.
 printErr("Writing " + gcEdges_filename);
 redirect(gcEdges_filename);
 for (var block in gcEdges) {
--- a/js/src/gc/Nursery.cpp
+++ b/js/src/gc/Nursery.cpp
@@ -757,17 +757,17 @@ js::Nursery::collect(JS::gcreason::Reaso
     bool shouldPretenure = (validPromotionRate && promotionRate > 0.6) ||
         IsFullStoreBufferReason(reason);
 
     if (shouldPretenure) {
         JSContext* cx = rt->mainContextFromOwnThread();
         for (auto& entry : tenureCounts.entries) {
             if (entry.count >= 3000) {
                 ObjectGroup* group = entry.group;
-                AutoCompartment ac(cx, group);
+                AutoRealm ar(cx, group);
                 AutoSweepObjectGroup sweep(group);
                 if (group->canPreTenure(sweep)) {
                     group->setShouldPreTenure(sweep, cx);
                     pretenureCount++;
                 }
             }
         }
     }
--- a/js/src/jit/BaselineDebugModeOSR.cpp
+++ b/js/src/jit/BaselineDebugModeOSR.cpp
@@ -879,17 +879,17 @@ jit::RecompileOnStackBaselineScriptsForD
         }
     }
 
     // Try to recompile all the scripts. If we encounter an error, we need to
     // roll back as if none of the compilations happened, so that we don't
     // crash.
     for (size_t i = 0; i < entries.length(); i++) {
         JSScript* script = entries[i].script;
-        AutoCompartment ac(cx, script);
+        AutoRealm ar(cx, script);
         if (!RecompileBaselineScriptForDebugMode(cx, script, observing) ||
             !CloneOldBaselineStub(cx, entries, i))
         {
             UndoRecompileBaselineScriptsForDebugMode(cx, entries);
             return false;
         }
     }
 
@@ -1038,17 +1038,17 @@ BaselineFrame::deleteDebugModeOSRInfo()
     flags_ &= ~HAS_DEBUG_MODE_OSR_INFO;
 }
 
 JitCode*
 JitRuntime::getBaselineDebugModeOSRHandler(JSContext* cx)
 {
     if (!baselineDebugModeOSRHandler_) {
         AutoLockForExclusiveAccess lock(cx);
-        AutoAtomsCompartment ac(cx, lock);
+        AutoAtomsRealm ar(cx, lock);
         uint32_t offset;
         if (JitCode* code = generateBaselineDebugModeOSRHandler(cx, &offset)) {
             baselineDebugModeOSRHandler_ = code;
             baselineDebugModeOSRHandlerNoFrameRegPopAddr_ = code->raw() + offset;
         }
     }
 
     return baselineDebugModeOSRHandler_;
--- a/js/src/jit/CacheIR.cpp
+++ b/js/src/jit/CacheIR.cpp
@@ -1043,17 +1043,17 @@ GetPropIRGenerator::tryAttachCrossCompar
     // If we allowed different zones we would have to wrap strings.
     if (unwrapped->compartment()->zone() != cx_->compartment()->zone())
         return false;
 
     RootedObject wrappedGlobal(cx_, &obj->global());
     if (!cx_->compartment()->wrap(cx_, &wrappedGlobal))
         return false;
 
-    AutoCompartment ac(cx_, unwrapped);
+    AutoRealm ar(cx_, unwrapped);
 
     // The first CCW for iframes is almost always wrapping another WindowProxy
     // so we optimize for that case as well.
     bool isWindowProxy = IsWindowProxy(unwrapped);
     if (isWindowProxy) {
         MOZ_ASSERT(ToWindowIfWindowProxy(unwrapped) == unwrapped->compartment()->maybeGlobal());
         unwrapped = cx_->global();
         MOZ_ASSERT(unwrapped);
@@ -4596,17 +4596,17 @@ static const size_t SHAPE_CONTAINER_SLOT
 
 JSObject*
 jit::NewWrapperWithObjectShape(JSContext* cx, HandleNativeObject obj)
 {
     MOZ_ASSERT(cx->compartment() != obj->compartment());
 
     RootedObject wrapper(cx);
     {
-        AutoCompartment ac(cx, obj);
+        AutoRealm ar(cx, obj);
         wrapper = NewObjectWithClassProto(cx, &shapeContainerClass, nullptr);
         if (!obj)
             return nullptr;
         wrapper->as<NativeObject>().setSlot(SHAPE_CONTAINER_SLOT, PrivateGCThingValue(obj->lastProperty()));
     }
     if (!JS_WrapObject(cx, &wrapper))
         return nullptr;
     MOZ_ASSERT(IsWrapper(wrapper));
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -206,17 +206,17 @@ JitRuntime::startTrampolineCode(MacroAss
     masm.haltingAlign(CodeAlignment);
     masm.setFramePushed(0);
     return masm.currentOffset();
 }
 
 bool
 JitRuntime::initialize(JSContext* cx, AutoLockForExclusiveAccess& lock)
 {
-    AutoAtomsCompartment ac(cx, lock);
+    AutoAtomsRealm ar(cx, lock);
 
     JitContext jctx(cx, nullptr);
 
     if (!cx->compartment()->ensureJitCompartmentExists(cx))
         return false;
 
     functionWrappers_ = cx->new_<VMWrapperMap>(cx);
     if (!functionWrappers_ || !functionWrappers_->init())
@@ -334,17 +334,17 @@ JitRuntime::initialize(JSContext* cx, Au
 
 JitCode*
 JitRuntime::debugTrapHandler(JSContext* cx)
 {
     if (!debugTrapHandler_) {
         // JitRuntime code stubs are shared across compartments and have to
         // be allocated in the atoms compartment.
         AutoLockForExclusiveAccess lock(cx);
-        AutoAtomsCompartment ac(cx, lock);
+        AutoAtomsRealm ar(cx, lock);
         debugTrapHandler_ = generateDebugTrapHandler(cx);
     }
     return debugTrapHandler_;
 }
 
 JitRuntime::IonBuilderList&
 JitRuntime::ionLazyLinkList(JSRuntime* rt)
 {
@@ -1937,17 +1937,17 @@ AttachFinishedCompilations(JSContext* cx
 
         // Don't keep more than 100 lazy link builders in a runtime.
         // Link the oldest ones immediately.
         while (rt->jitRuntime()->ionLazyLinkListSize() > 100) {
             jit::IonBuilder* builder = rt->jitRuntime()->ionLazyLinkList(rt).getLast();
             RootedScript script(cx, builder->script());
 
             AutoUnlockHelperThreadState unlock(lock);
-            AutoCompartment ac(cx, script);
+            AutoRealm ar(cx, script);
             jit::LinkIonScript(cx, script);
         }
     }
 
     MOZ_ASSERT(!rt->jitRuntime()->numFinishedBuilders());
 }
 
 static void
--- a/js/src/jit/JitFrames.cpp
+++ b/js/src/jit/JitFrames.cpp
@@ -1881,17 +1881,17 @@ SnapshotIterator::initInstructionResults
     // If there is only one resume point in the list of instructions, then there
     // is no instruction to recover, and thus no need to register any results.
     if (recover_.numInstructions() == 1)
         return true;
 
     JitFrameLayout* fp = fallback.frame->jsFrame();
     RInstructionResults* results = fallback.activation->maybeIonFrameRecovery(fp);
     if (!results) {
-        AutoCompartment ac(cx, fallback.frame->script());
+        AutoRealm ar(cx, fallback.frame->script());
 
         // We do not have the result yet, which means that an observable stack
         // slot is requested.  As we do not want to bailout every time for the
         // same reason, we need to recompile without optimizing away the
         // observable stack slots.  The script would later be recompiled to have
         // support for Argument objects.
         if (fallback.consequence == MaybeReadFallback::Fallback_Invalidate) {
             ionScript_->invalidate(cx, fallback.frame->script(), /* resetUses = */ false,
--- a/js/src/jsapi-tests/testArrayBufferView.cpp
+++ b/js/src/jsapi-tests/testArrayBufferView.cpp
@@ -139,17 +139,17 @@ bool TestViewType(JSContext* cx)
 
     JS::CompartmentOptions options;
     JS::RootedObject otherGlobal(cx, JS_NewGlobalObject(cx, basicGlobalClass(), nullptr,
                                                         JS::DontFireOnNewGlobalHook, options));
     CHECK(otherGlobal);
 
     JS::Rooted<JSObject*> buffer(cx);
     {
-        AutoCompartment ac(cx, otherGlobal);
+        AutoRealm ar(cx, otherGlobal);
         buffer = JS_NewArrayBuffer(cx, 8);
         CHECK(buffer);
         CHECK(buffer->as<ArrayBufferObject>().byteLength() == 8);
     }
     CHECK(buffer->compartment() == otherGlobal->compartment());
     CHECK(JS_WrapObject(cx, &buffer));
     CHECK(buffer->compartment() == global->compartment());
 
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -885,32 +885,32 @@ JS_TransplantObject(JSContext* cx, Handl
 
     JSCompartment* destination = target->compartment();
 
     if (origobj->compartment() == destination) {
         // If the original object is in the same compartment as the
         // destination, then we know that we won't find a wrapper in the
         // destination's cross compartment map and that the same
         // object will continue to work.
-        AutoCompartmentUnchecked ac(cx, origobj->compartment());
+        AutoRealmUnchecked ar(cx, origobj->compartment());
         if (!JSObject::swap(cx, origobj, target))
             MOZ_CRASH();
         newIdentity = origobj;
     } else if (WrapperMap::Ptr p = destination->lookupWrapper(origv)) {
         // There might already be a wrapper for the original object in
         // the new compartment. If there is, we use its identity and swap
         // in the contents of |target|.
         newIdentity = &p->value().get().toObject();
 
         // When we remove origv from the wrapper map, its wrapper, newIdentity,
         // must immediately cease to be a cross-compartment wrapper. Nuke it.
         destination->removeWrapper(p);
         NukeCrossCompartmentWrapper(cx, newIdentity);
 
-        AutoCompartment ac(cx, newIdentity);
+        AutoRealm ar(cx, newIdentity);
         if (!JSObject::swap(cx, newIdentity, target))
             MOZ_CRASH();
     } else {
         // Otherwise, we use |target| for the new identity object.
         newIdentity = target;
     }
 
     // Now, iterate through other scopes looking for references to the old
@@ -919,17 +919,17 @@ JS_TransplantObject(JSContext* cx, Handl
     // `newIdentity == origobj`, because this process also clears out any
     // cached wrapper state.
     if (!RemapAllWrappersForObject(cx, origobj, newIdentity))
         MOZ_CRASH();
 
     // Lastly, update the original object to point to the new one.
     if (origobj->compartment() != destination) {
         RootedObject newIdentityWrapper(cx, newIdentity);
-        AutoCompartmentUnchecked ac(cx, origobj->compartment());
+        AutoRealmUnchecked ar(cx, origobj->compartment());
         if (!JS_WrapObject(cx, &newIdentityWrapper))
             MOZ_CRASH();
         MOZ_ASSERT(Wrapper::wrappedObject(newIdentityWrapper) == newIdentity);
         if (!JSObject::swap(cx, origobj, newIdentityWrapper))
             MOZ_CRASH();
         if (!origobj->compartment()->putWrapper(cx, CrossCompartmentKey(newIdentity), origv))
             MOZ_CRASH();
     }
@@ -3670,25 +3670,25 @@ CloneFunctionObject(JSContext* cx, Handl
 {
     AssertHeapIsIdle();
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, env);
     MOZ_ASSERT(env);
     // Note that funobj can be in a different compartment.
 
     if (!funobj->is<JSFunction>()) {
-        AutoCompartment ac(cx, funobj);
+        AutoRealm ar(cx, funobj);
         RootedValue v(cx, ObjectValue(*funobj));
         ReportIsNotFunction(cx, v);
         return nullptr;
     }
 
     RootedFunction fun(cx, &funobj->as<JSFunction>());
     if (fun->isInterpretedLazy()) {
-        AutoCompartment ac(cx, funobj);
+        AutoRealm ar(cx, funobj);
         if (!JSFunction::getOrCreateScript(cx, fun))
             return nullptr;
     }
 
     // Only allow cloning normal, interpreted functions.
     if (fun->isNative() ||
         fun->isBoundFunction() ||
         fun->kind() != JSFunction::NormalFunction ||
@@ -4527,17 +4527,17 @@ JS_GetScriptBaseLineNumber(JSContext* cx
 }
 
 JS_PUBLIC_API(JSScript*)
 JS_GetFunctionScript(JSContext* cx, HandleFunction fun)
 {
     if (fun->isNative())
         return nullptr;
     if (fun->isInterpretedLazy()) {
-        AutoCompartment funCompartment(cx, fun);
+        AutoRealm ar(cx, fun);
         JSScript* script = JSFunction::getOrCreateScript(cx, fun);
         if (!script)
             MOZ_CRASH();
         return script;
     }
     return fun->nonLazyScript();
 }
 
@@ -5247,27 +5247,27 @@ JS::CallOriginalPromiseReject(JSContext*
 static bool
 ResolveOrRejectPromise(JSContext* cx, JS::HandleObject promiseObj, JS::HandleValue resultOrReason_,
                        bool reject)
 {
     AssertHeapIsIdle();
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, promiseObj, resultOrReason_);
 
-    mozilla::Maybe<AutoCompartment> ac;
+    mozilla::Maybe<AutoRealm> ar;
     Rooted<PromiseObject*> promise(cx);
     RootedValue resultOrReason(cx, resultOrReason_);
     if (IsWrapper(promiseObj)) {
         JSObject* unwrappedPromiseObj = CheckedUnwrap(promiseObj);
         if (!unwrappedPromiseObj) {
             ReportAccessDenied(cx);
             return false;
         }
         promise = &unwrappedPromiseObj->as<PromiseObject>();
-        ac.emplace(cx, promise);
+        ar.emplace(cx, promise);
         if (!cx->compartment()->wrap(cx, &resultOrReason))
             return false;
     } else {
         promise = promiseObj.as<PromiseObject>();
     }
 
     return reject
            ? PromiseObject::reject(cx, promise, resultOrReason)
@@ -5295,28 +5295,28 @@ CallOriginalPromiseThenImpl(JSContext* c
     AssertHeapIsIdle();
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, promiseObj, onResolvedObj_, onRejectedObj_);
 
     MOZ_ASSERT_IF(onResolvedObj_, IsCallable(onResolvedObj_));
     MOZ_ASSERT_IF(onRejectedObj_, IsCallable(onRejectedObj_));
 
     {
-        mozilla::Maybe<AutoCompartment> ac;
+        mozilla::Maybe<AutoRealm> ar;
         Rooted<PromiseObject*> promise(cx);
         RootedObject onResolvedObj(cx, onResolvedObj_);
         RootedObject onRejectedObj(cx, onRejectedObj_);
         if (IsWrapper(promiseObj)) {
             JSObject* unwrappedPromiseObj = CheckedUnwrap(promiseObj);
             if (!unwrappedPromiseObj) {
                 ReportAccessDenied(cx);
                 return false;
             }
             promise = &unwrappedPromiseObj->as<PromiseObject>();
-            ac.emplace(cx, promise);
+            ar.emplace(cx, promise);
             if (!cx->compartment()->wrap(cx, &onResolvedObj) ||
                 !cx->compartment()->wrap(cx, &onRejectedObj))
             {
                 return false;
             }
         } else {
             promise = promiseObj.as<PromiseObject>();
         }
--- a/js/src/jsfriendapi.cpp
+++ b/js/src/jsfriendapi.cpp
@@ -794,23 +794,23 @@ static const char*
 FormatValue(JSContext* cx, const Value& vArg, JSAutoByteString& bytes)
 {
     RootedValue v(cx, vArg);
 
     if (v.isMagic(JS_OPTIMIZED_OUT))
         return "[unavailable]";
 
     /*
-     * We could use Maybe<AutoCompartment> here, but G++ can't quite follow
+     * We could use Maybe<AutoRealm> here, but G++ can't quite follow
      * that, and warns about uninitialized members being used in the
      * destructor.
      */
     RootedString str(cx);
     if (v.isObject()) {
-        AutoCompartment ac(cx, &v.toObject());
+        AutoRealm ar(cx, &v.toObject());
         str = ToString<CanGC>(cx, v);
     } else {
         str = ToString<CanGC>(cx, v);
     }
 
     if (!str)
         return nullptr;
     const char* buf = bytes.encodeLatin1(cx, str);
--- a/js/src/proxy/CrossCompartmentWrapper.cpp
+++ b/js/src/proxy/CrossCompartmentWrapper.cpp
@@ -15,17 +15,17 @@
 #include "vm/JSObject-inl.h"
 
 using namespace js;
 
 #define PIERCE(cx, wrapper, pre, op, post)                      \
     JS_BEGIN_MACRO                                              \
         bool ok;                                                \
         {                                                       \
-            AutoCompartment call(cx, wrappedObject(wrapper));   \
+            AutoRealm call(cx, wrappedObject(wrapper));         \
             ok = (pre) && (op);                                 \
         }                                                       \
         return ok && (post);                                    \
     JS_END_MACRO
 
 #define NOTHING (true)
 
 static bool
@@ -96,17 +96,17 @@ CrossCompartmentWrapper::delete_(JSConte
 }
 
 bool
 CrossCompartmentWrapper::getPrototype(JSContext* cx, HandleObject wrapper,
                                       MutableHandleObject protop) const
 {
     {
         RootedObject wrapped(cx, wrappedObject(wrapper));
-        AutoCompartment call(cx, wrapped);
+        AutoRealm call(cx, wrapped);
         if (!GetPrototype(cx, wrapped, protop))
             return false;
         if (protop) {
             if (!JSObject::setDelegate(cx, protop))
                 return false;
         }
     }
 
@@ -125,17 +125,17 @@ CrossCompartmentWrapper::setPrototype(JS
 }
 
 bool
 CrossCompartmentWrapper::getPrototypeIfOrdinary(JSContext* cx, HandleObject wrapper,
                                                 bool* isOrdinary, MutableHandleObject protop) const
 {
     {
         RootedObject wrapped(cx, wrappedObject(wrapper));
-        AutoCompartment call(cx, wrapped);
+        AutoRealm call(cx, wrapped);
         if (!GetPrototypeIfOrdinary(cx, wrapped, isOrdinary, protop))
             return false;
 
         if (!*isOrdinary)
             return true;
 
         if (protop) {
             if (!JSObject::setDelegate(cx, protop))
@@ -213,17 +213,17 @@ WrapReceiver(JSContext* cx, HandleObject
 }
 
 bool
 CrossCompartmentWrapper::get(JSContext* cx, HandleObject wrapper, HandleValue receiver,
                              HandleId id, MutableHandleValue vp) const
 {
     RootedValue receiverCopy(cx, receiver);
     {
-        AutoCompartment call(cx, wrappedObject(wrapper));
+        AutoRealm call(cx, wrappedObject(wrapper));
         if (!MarkAtoms(cx, id) || !WrapReceiver(cx, wrapper, &receiverCopy))
             return false;
 
         if (!Wrapper::get(cx, wrapper, receiverCopy, id, vp))
             return false;
     }
     return cx->compartment()->wrap(cx, vp);
 }
@@ -320,17 +320,17 @@ Reify(JSContext* cx, JSCompartment* orig
     return obj;
 }
 
 JSObject*
 CrossCompartmentWrapper::enumerate(JSContext* cx, HandleObject wrapper) const
 {
     RootedObject res(cx);
     {
-        AutoCompartment call(cx, wrappedObject(wrapper));
+        AutoRealm call(cx, wrappedObject(wrapper));
         res = Wrapper::enumerate(cx, wrapper);
         if (!res)
             return nullptr;
     }
 
     if (CanReify(res))
         return Reify(cx, cx->compartment(), res);
     if (!cx->compartment()->wrap(cx, &res))
@@ -339,17 +339,17 @@ CrossCompartmentWrapper::enumerate(JSCon
 }
 
 bool
 CrossCompartmentWrapper::call(JSContext* cx, HandleObject wrapper, const CallArgs& args) const
 {
     RootedObject wrapped(cx, wrappedObject(wrapper));
 
     {
-        AutoCompartment call(cx, wrapped);
+        AutoRealm call(cx, wrapped);
 
         args.setCallee(ObjectValue(*wrapped));
         if (!cx->compartment()->wrap(cx, args.mutableThisv()))
             return false;
 
         for (size_t n = 0; n < args.length(); ++n) {
             if (!cx->compartment()->wrap(cx, args[n]))
                 return false;
@@ -362,17 +362,17 @@ CrossCompartmentWrapper::call(JSContext*
     return cx->compartment()->wrap(cx, args.rval());
 }
 
 bool
 CrossCompartmentWrapper::construct(JSContext* cx, HandleObject wrapper, const CallArgs& args) const
 {
     RootedObject wrapped(cx, wrappedObject(wrapper));
     {
-        AutoCompartment call(cx, wrapped);
+        AutoRealm call(cx, wrapped);
 
         for (size_t n = 0; n < args.length(); ++n) {
             if (!cx->compartment()->wrap(cx, args[n]))
                 return false;
         }
         if (!cx->compartment()->wrap(cx, args.newTarget()))
             return false;
         if (!Wrapper::construct(cx, wrapper, args))
@@ -386,17 +386,17 @@ CrossCompartmentWrapper::nativeCall(JSCo
                                     const CallArgs& srcArgs) const
 {
     RootedObject wrapper(cx, &srcArgs.thisv().toObject());
     MOZ_ASSERT(srcArgs.thisv().isMagic(JS_IS_CONSTRUCTING) ||
                !UncheckedUnwrap(wrapper)->is<CrossCompartmentWrapperObject>());
 
     RootedObject wrapped(cx, wrappedObject(wrapper));
     {
-        AutoCompartment call(cx, wrapped);
+        AutoRealm call(cx, wrapped);
         InvokeArgs dstArgs(cx);
         if (!dstArgs.init(cx, srcArgs.length()))
             return false;
 
         Value* src = srcArgs.base();
         Value* srcend = srcArgs.array() + srcArgs.length();
         Value* dst = dstArgs.base();
 
@@ -429,50 +429,50 @@ CrossCompartmentWrapper::nativeCall(JSCo
     }
     return cx->compartment()->wrap(cx, srcArgs.rval());
 }
 
 bool
 CrossCompartmentWrapper::hasInstance(JSContext* cx, HandleObject wrapper, MutableHandleValue v,
                                      bool* bp) const
 {
-    AutoCompartment call(cx, wrappedObject(wrapper));
+    AutoRealm call(cx, wrappedObject(wrapper));
     if (!cx->compartment()->wrap(cx, v))
         return false;
     return Wrapper::hasInstance(cx, wrapper, v, bp);
 }
 
 const char*
 CrossCompartmentWrapper::className(JSContext* cx, HandleObject wrapper) const
 {
-    AutoCompartment call(cx, wrappedObject(wrapper));
+    AutoRealm call(cx, wrappedObject(wrapper));
     return Wrapper::className(cx, wrapper);
 }
 
 JSString*
 CrossCompartmentWrapper::fun_toString(JSContext* cx, HandleObject wrapper, bool isToSource) const
 {
     RootedString str(cx);
     {
-        AutoCompartment call(cx, wrappedObject(wrapper));
+        AutoRealm call(cx, wrappedObject(wrapper));
         str = Wrapper::fun_toString(cx, wrapper, isToSource);
         if (!str)
             return nullptr;
     }
     if (!cx->compartment()->wrap(cx, &str))
         return nullptr;
     return str;
 }
 
 RegExpShared*
 CrossCompartmentWrapper::regexp_toShared(JSContext* cx, HandleObject wrapper) const
 {
     RootedRegExpShared re(cx);
     {
-        AutoCompartment call(cx, wrappedObject(wrapper));
+        AutoRealm call(cx, wrappedObject(wrapper));
         re = Wrapper::regexp_toShared(cx, wrapper);
         if (!re)
             return nullptr;
     }
 
     // Get an equivalent RegExpShared associated with the current compartment.
     RootedAtom source(cx, re->getSource());
     cx->markAtom(source);
@@ -632,17 +632,17 @@ js::RemapWrapper(JSContext* cx, JSObject
     // When we remove origv from the wrapper map, its wrapper, wobj, must
     // immediately cease to be a cross-compartment wrapper. Nuke it.
     NukeCrossCompartmentWrapper(cx, wobj);
 
     // First, we wrap it in the new compartment. We try to use the existing
     // wrapper, |wobj|, since it's been nuked anyway. The wrap() function has
     // the choice to reuse |wobj| or not.
     RootedObject tobj(cx, newTarget);
-    AutoCompartmentUnchecked ac(cx, wcompartment);
+    AutoRealmUnchecked ar(cx, wcompartment);
     if (!wcompartment->rewrap(cx, &tobj, wobj))
         MOZ_CRASH();
 
     // If wrap() reused |wobj|, it will have overwritten it and returned with
     // |tobj == wobj|. Otherwise, |tobj| will point to a new wrapper and |wobj|
     // will still be nuked. In the latter case, we replace |wobj| with the
     // contents of the new wrapper in |tobj|.
     if (tobj != wobj) {
--- a/js/src/proxy/Wrapper.cpp
+++ b/js/src/proxy/Wrapper.cpp
@@ -438,27 +438,27 @@ js::TransparentObjectWrapper(JSContext* 
 {
     // Allow wrapping outer window proxies.
     MOZ_ASSERT(!obj->is<WrapperObject>() || IsWindowProxy(obj));
     return Wrapper::New(cx, obj, &CrossCompartmentWrapper::singleton);
 }
 
 ErrorCopier::~ErrorCopier()
 {
-    JSContext* cx = ac->context();
+    JSContext* cx = ar->context();
 
     // The provenance of Debugger.DebuggeeWouldRun is the topmost locking
     // debugger compartment; it should not be copied around.
-    if (ac->origin() != cx->compartment() &&
+    if (ar->origin() != cx->compartment() &&
         cx->isExceptionPending() &&
         !cx->isThrowingDebuggeeWouldRun())
     {
         RootedValue exc(cx);
         if (cx->getPendingException(&exc) && exc.isObject() && exc.toObject().is<ErrorObject>()) {
             cx->clearPendingException();
-            ac.reset();
+            ar.reset();
             Rooted<ErrorObject*> errObj(cx, &exc.toObject().as<ErrorObject>());
             JSObject* copyobj = CopyErrorObject(cx, errObj);
             if (copyobj)
                 cx->setPendingException(ObjectValue(*copyobj));
         }
     }
 }
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -786,17 +786,17 @@ SkipUTF8BOM(FILE* file)
 }
 
 void
 EnvironmentPreparer::invoke(HandleObject scope, Closure& closure)
 {
     JSContext* cx = TlsContext.get();
     MOZ_ASSERT(!JS_IsExceptionPending(cx));
 
-    AutoCompartment ac(cx, scope);
+    AutoRealm ar(cx, scope);
     AutoReportException are(cx);
     if (!closure(cx))
         return;
 }
 
 static MOZ_MUST_USE bool
 RunFile(JSContext* cx, const char* filename, FILE* file, bool compileOnly)
 {
@@ -1002,17 +1002,17 @@ ForwardingPromiseRejectionTrackerCallbac
                                           JS::PromiseRejectionHandlingState state,
                                           void* data)
 {
     RootedValue callback(cx, GetShellContext(cx)->promiseRejectionTrackerCallback);
     if (callback.isNull()) {
         return;
     }
 
-    AutoCompartment ac(cx, &callback.toObject());
+    AutoRealm ar(cx, &callback.toObject());
 
     FixedInvokeArgs<2> args(cx);
     args[0].setObject(*promise);
     args[1].setInt32(static_cast<int32_t>(state));
 
     if (!JS_WrapValue(cx, args[0]))
         return;
 
--- a/js/src/vm/ArrayBufferObject.cpp
+++ b/js/src/vm/ArrayBufferObject.cpp
@@ -1979,17 +1979,17 @@ JS_StealArrayBufferContents(JSContext* c
     }
 
     // The caller assumes that a plain malloc'd buffer is returned.
     // hasStealableContents is true for mapped buffers, so we must additionally
     // require that the buffer is plain. In the future, we could consider
     // returning something that handles releasing the memory.
     bool hasStealableContents = buffer->hasStealableContents() && buffer->isPlain();
 
-    AutoCompartment ac(cx, buffer);
+    AutoRealm ar(cx, buffer);
     return ArrayBufferObject::stealContents(cx, buffer, hasStealableContents).data();
 }
 
 JS_PUBLIC_API(JSObject*)
 JS_NewMappedArrayBufferWithContents(JSContext* cx, size_t nbytes, void* data)
 {
     AssertHeapIsIdle();
     CHECK_REQUEST(cx);
--- a/js/src/vm/BytecodeUtil.cpp
+++ b/js/src/vm/BytecodeUtil.cpp
@@ -2874,17 +2874,17 @@ js::GetPCCountScriptContents(JSContext* 
     }
 
     const ScriptAndCounts& sac = (*rt->scriptAndCountsVector)[index];
     JSScript* script = sac.script;
 
     StringBuffer buf(cx);
 
     {
-        AutoCompartment ac(cx, &script->global());
+        AutoRealm ar(cx, &script->global());
         if (!GetPCCountJSON(cx, sac, buf))
             return nullptr;
     }
 
     return buf.finishString();
 }
 
 static bool
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -243,17 +243,17 @@ RemoveAsyncWrapper(JSFunction *fun)
 
     return fun;
 }
 
 static inline bool
 EnsureFunctionHasScript(JSContext* cx, HandleFunction fun)
 {
     if (fun->isInterpretedLazy()) {
-        AutoCompartment ac(cx, fun);
+        AutoRealm ar(cx, fun);
         return !!JSFunction::getOrCreateScript(cx, fun);
     }
     return true;
 }
 
 static inline JSScript*
 GetOrCreateFunctionScript(JSContext* cx, HandleFunction fun)
 {
@@ -362,17 +362,17 @@ class MOZ_RAII js::EnterDebuggeeNoExecut
     }
 
     // Given a JSContext entered into a debuggee compartment, report a
     // warning or an error if there is a lock that locks it.
     static bool reportIfFoundInStack(JSContext* cx, HandleScript script) {
         if (EnterDebuggeeNoExecute* nx = findInStack(cx)) {
             bool warning = !cx->options().throwOnDebuggeeWouldRun();
             if (!warning || !nx->reported_) {
-                AutoCompartment ac(cx, nx->debugger().toJSObject());
+                AutoRealm ar(cx, nx->debugger().toJSObject());
                 nx->reported_ = true;
                 if (cx->options().dumpStackOnDebuggeeWouldRun()) {
                     fprintf(stdout, "Dumping stack for DebuggeeWouldRun:\n");
                     DumpBacktrace(cx);
                 }
                 const char* filename = script->filename() ? script->filename() : "(none)";
                 char linenoStr[15];
                 SprintfLiteral(linenoStr, "%zu", script->lineno());
@@ -955,32 +955,32 @@ Debugger::slowPathOnLeaveFrame(JSContext
             HandleDebuggerFrame frameobj = frames[i];
             Debugger* dbg = Debugger::fromChildJSObject(frameobj);
             EnterDebuggeeNoExecute nx(cx, *dbg);
 
             if (dbg->enabled && frameobj->onPopHandler())
             {
                 OnPopHandler* handler = frameobj->onPopHandler();
 
-                Maybe<AutoCompartment> ac;
-                ac.emplace(cx, dbg->object);
+                Maybe<AutoRealm> ar;
+                ar.emplace(cx, dbg->object);
 
                 RootedValue wrappedValue(cx, value);
                 RootedValue completion(cx);
                 if (!dbg->wrapDebuggeeValue(cx, &wrappedValue))
                 {
-                    resumeMode = dbg->reportUncaughtException(ac);
+                    resumeMode = dbg->reportUncaughtException(ar);
                     break;
                 }
 
                 /* Call the onPop handler. */
                 ResumeMode nextResumeMode = resumeMode;
                 RootedValue nextValue(cx, wrappedValue);
                 bool success = handler->onPop(cx, frameobj, nextResumeMode, &nextValue);
-                nextResumeMode = dbg->processParsedHandlerResult(ac, frame, pc, success,
+                nextResumeMode = dbg->processParsedHandlerResult(ar, frame, pc, success,
                                                                  nextResumeMode, &nextValue);
 
                 /*
                  * At this point, we are back in the debuggee compartment, and any error has
                  * been wrapped up as a completion value.
                  */
                 MOZ_ASSERT(cx->compartment() == debuggeeGlobal->compartment());
                 MOZ_ASSERT(!cx->isExceptionPending());
@@ -1347,19 +1347,19 @@ Debugger::unwrapPropertyDescriptor(JSCon
         }
         desc.setSetterObject(set);
     }
 
     return true;
 }
 
 ResumeMode
-Debugger::reportUncaughtException(Maybe<AutoCompartment>& ac)
-{
-    JSContext* cx = ac->context();
+Debugger::reportUncaughtException(Maybe<AutoRealm>& ar)
+{
+    JSContext* cx = ar->context();
 
     // Uncaught exceptions arise from Debugger code, and so we must already be
     // in an NX section.
     MOZ_ASSERT(EnterDebuggeeNoExecute::isLockedInStack(cx, *this));
 
     if (cx->isExceptionPending()) {
         /*
          * We want to report the pending exception, but we want to let the
@@ -1382,26 +1382,26 @@ Debugger::reportUncaughtException(Maybe<
         /*
          * And if not, or if PrepareScriptEnvironmentAndInvoke somehow left
          * an exception on cx (which it totally shouldn't do), just give
          * up.
          */
         cx->clearPendingException();
     }
 
-    ac.reset();
+    ar.reset();
     return ResumeMode::Terminate;
 }
 
 ResumeMode
-Debugger::handleUncaughtExceptionHelper(Maybe<AutoCompartment>& ac, MutableHandleValue* vp,
+Debugger::handleUncaughtExceptionHelper(Maybe<AutoRealm>& ar, MutableHandleValue* vp,
                                         const Maybe<HandleValue>& thisVForCheck,
                                         AbstractFramePtr frame)
 {
-    JSContext* cx = ac->context();
+    JSContext* cx = ar->context();
 
     // Uncaught exceptions arise from Debugger code, and so we must already be
     // in an NX section.
     MOZ_ASSERT(EnterDebuggeeNoExecute::isLockedInStack(cx, *this));
 
     if (cx->isExceptionPending()) {
         if (uncaughtExceptionHook) {
             RootedValue exc(cx);
@@ -1409,42 +1409,42 @@ Debugger::handleUncaughtExceptionHelper(
                 return ResumeMode::Terminate;
             cx->clearPendingException();
 
             RootedValue fval(cx, ObjectValue(*uncaughtExceptionHook));
             RootedValue rv(cx);
             if (js::Call(cx, fval, object, exc, &rv)) {
                 if (vp) {
                     ResumeMode resumeMode = ResumeMode::Continue;
-                    if (processResumptionValue(ac, frame, thisVForCheck, rv, resumeMode, *vp))
+                    if (processResumptionValue(ar, frame, thisVForCheck, rv, resumeMode, *vp))
                         return resumeMode;
                 } else {
                     return ResumeMode::Continue;
                 }
             }
         }
 
-        return reportUncaughtException(ac);
-    }
-
-    ac.reset();
+        return reportUncaughtException(ar);
+    }
+
+    ar.reset();
     return ResumeMode::Terminate;
 }
 
 ResumeMode
-Debugger::handleUncaughtException(Maybe<AutoCompartment>& ac, MutableHandleValue vp,
+Debugger::handleUncaughtException(Maybe<AutoRealm>& ar, MutableHandleValue vp,
                                   const Maybe<HandleValue>& thisVForCheck, AbstractFramePtr frame)
 {
-    return handleUncaughtExceptionHelper(ac, &vp, thisVForCheck, frame);
+    return handleUncaughtExceptionHelper(ar, &vp, thisVForCheck, frame);
 }
 
 ResumeMode
-Debugger::handleUncaughtException(Maybe<AutoCompartment>& ac)
-{
-    return handleUncaughtExceptionHelper(ac, nullptr, mozilla::Nothing(), NullFramePtr());
+Debugger::handleUncaughtException(Maybe<AutoRealm>& ar)
+{
+    return handleUncaughtExceptionHelper(ar, nullptr, mozilla::Nothing(), NullFramePtr());
 }
 
 /* static */ void
 Debugger::resultToCompletion(JSContext* cx, bool ok, const Value& rv,
                              ResumeMode* resumeMode, MutableHandleValue value)
 {
     MOZ_ASSERT_IF(ok, !cx->isExceptionPending());
 
@@ -1501,26 +1501,26 @@ Debugger::newCompletionValue(JSContext* 
         return false;
     }
 
     result.setObject(*obj);
     return true;
 }
 
 bool
-Debugger::receiveCompletionValue(Maybe<AutoCompartment>& ac, bool ok,
+Debugger::receiveCompletionValue(Maybe<AutoRealm>& ar, bool ok,
                                  HandleValue val,
                                  MutableHandleValue vp)
 {
-    JSContext* cx = ac->context();
+    JSContext* cx = ar->context();
 
     ResumeMode resumeMode;
     RootedValue value(cx);
     resultToCompletion(cx, ok, val, &resumeMode, &value);
-    ac.reset();
+    ar.reset();
     return wrapDebuggeeValue(cx, &value) &&
            newCompletionValue(cx, resumeMode, value, vp);
 }
 
 static bool
 GetResumptionProperty(JSContext* cx, HandleObject obj, HandlePropertyName name, ResumeMode namedMode,
                       ResumeMode& resumeMode, MutableHandleValue vp, int* hits)
 {
@@ -1607,117 +1607,117 @@ CheckResumptionValue(JSContext* cx, Abst
 }
 
 static bool
 GetThisValueForCheck(JSContext* cx, AbstractFramePtr frame, jsbytecode* pc,
                      MutableHandleValue thisv, Maybe<HandleValue>& maybeThisv)
 {
     if (frame.debuggerNeedsCheckPrimitiveReturn()) {
         {
-            AutoCompartment ac(cx, frame.environmentChain());
+            AutoRealm ar(cx, frame.environmentChain());
             if (!GetThisValueForDebuggerMaybeOptimizedOut(cx, frame, pc, thisv))
                 return false;
         }
 
         if (!cx->compartment()->wrap(cx, thisv))
             return false;
 
         MOZ_ASSERT_IF(thisv.isMagic(), thisv.isMagic(JS_UNINITIALIZED_LEXICAL));
         maybeThisv.emplace(HandleValue(thisv));
     }
 
     return true;
 }
 
 bool
-Debugger::processResumptionValue(Maybe<AutoCompartment>& ac, AbstractFramePtr frame,
+Debugger::processResumptionValue(Maybe<AutoRealm>& ar, AbstractFramePtr frame,
                                  const Maybe<HandleValue>& maybeThisv, HandleValue rval,
                                  ResumeMode& resumeMode, MutableHandleValue vp)
 {
-    JSContext* cx = ac->context();
+    JSContext* cx = ar->context();
 
     if (!ParseResumptionValue(cx, rval, resumeMode, vp) ||
         !unwrapDebuggeeValue(cx, vp) ||
         !CheckResumptionValue(cx, frame, maybeThisv, resumeMode, vp))
     {
         return false;
     }
 
-    ac.reset();
+    ar.reset();
     if (!cx->compartment()->wrap(cx, vp)) {
         resumeMode = ResumeMode::Terminate;
         vp.setUndefined();
     }
 
     return true;
 }
 
 ResumeMode
-Debugger::processParsedHandlerResultHelper(Maybe<AutoCompartment>& ac, AbstractFramePtr frame,
+Debugger::processParsedHandlerResultHelper(Maybe<AutoRealm>& ar, AbstractFramePtr frame,
                                            const Maybe<HandleValue>& maybeThisv, bool success,
                                            ResumeMode resumeMode, MutableHandleValue vp)
 {
     if (!success)
-        return handleUncaughtException(ac, vp, maybeThisv, frame);
-
-    JSContext* cx = ac->context();
+        return handleUncaughtException(ar, vp, maybeThisv, frame);
+
+    JSContext* cx = ar->context();
 
     if (!unwrapDebuggeeValue(cx, vp) ||
         !CheckResumptionValue(cx, frame, maybeThisv, resumeMode, vp))
     {
-        return handleUncaughtException(ac, vp, maybeThisv, frame);
-    }
-
-    ac.reset();
+        return handleUncaughtException(ar, vp, maybeThisv, frame);
+    }
+
+    ar.reset();
     if (!cx->compartment()->wrap(cx, vp)) {
         resumeMode = ResumeMode::Terminate;
         vp.setUndefined();
     }
 
     return resumeMode;
 }
 
 ResumeMode
-Debugger::processParsedHandlerResult(Maybe<AutoCompartment>& ac, AbstractFramePtr frame,
+Debugger::processParsedHandlerResult(Maybe<AutoRealm>& ar, AbstractFramePtr frame,
                                      jsbytecode* pc, bool success, ResumeMode resumeMode,
                                      MutableHandleValue vp)
 {
-    JSContext* cx = ac->context();
+    JSContext* cx = ar->context();
 
     RootedValue thisv(cx);
     Maybe<HandleValue> maybeThisv;
     if (!GetThisValueForCheck(cx, frame, pc, &thisv, maybeThisv)) {
-        ac.reset();
+        ar.reset();
         return ResumeMode::Terminate;
     }
 
-    return processParsedHandlerResultHelper(ac, frame, maybeThisv, success, resumeMode, vp);
+    return processParsedHandlerResultHelper(ar, frame, maybeThisv, success, resumeMode, vp);
 }
 
 ResumeMode
-Debugger::processHandlerResult(Maybe<AutoCompartment>& ac, bool success, const Value& rv,
+Debugger::processHandlerResult(Maybe<AutoRealm>& ar, bool success, const Value& rv,
                                AbstractFramePtr frame, jsbytecode* pc, MutableHandleValue vp)
 {
-    JSContext* cx = ac->context();
+    JSContext* cx = ar->context();
 
     RootedValue thisv(cx);
     Maybe<HandleValue> maybeThisv;
     if (!GetThisValueForCheck(cx, frame, pc, &thisv, maybeThisv)) {
-        ac.reset();
+        ar.reset();
         return ResumeMode::Terminate;
     }
 
     if (!success)
-        return handleUncaughtException(ac, vp, maybeThisv, frame);
+        return handleUncaughtException(ar, vp, maybeThisv, frame);
 
     RootedValue rootRv(cx, rv);
     ResumeMode resumeMode = ResumeMode::Continue;
     success = ParseResumptionValue(cx, rootRv, resumeMode, vp);
 
-    return processParsedHandlerResultHelper(ac, frame, maybeThisv, success, resumeMode, vp);
+    return processParsedHandlerResultHelper(ar, frame, maybeThisv, success, resumeMode, vp);
 }
 
 static bool
 CallMethodIfPresent(JSContext* cx, HandleObject obj, const char* name, size_t argc, Value* argv,
                     MutableHandleValue rval)
 {
     rval.setUndefined();
     JSAtom* atom = Atomize(cx, name, strlen(name));
@@ -1745,132 +1745,132 @@ CallMethodIfPresent(JSContext* cx, Handl
 
 ResumeMode
 Debugger::fireDebuggerStatement(JSContext* cx, MutableHandleValue vp)
 {
     RootedObject hook(cx, getHook(OnDebuggerStatement));
     MOZ_ASSERT(hook);
     MOZ_ASSERT(hook->isCallable());
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, object);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, object);
 
     ScriptFrameIter iter(cx);
     RootedValue scriptFrame(cx);
     if (!getFrame(cx, iter, &scriptFrame))
-        return reportUncaughtException(ac);
+        return reportUncaughtException(ar);
 
     RootedValue fval(cx, ObjectValue(*hook));
     RootedValue rv(cx);
     bool ok = js::Call(cx, fval, object, scriptFrame, &rv);
-    return processHandlerResult(ac, ok, rv, iter.abstractFramePtr(), iter.pc(), vp);
+    return processHandlerResult(ar, ok, rv, iter.abstractFramePtr(), iter.pc(), vp);
 }
 
 ResumeMode
 Debugger::fireExceptionUnwind(JSContext* cx, MutableHandleValue vp)
 {
     RootedObject hook(cx, getHook(OnExceptionUnwind));
     MOZ_ASSERT(hook);
     MOZ_ASSERT(hook->isCallable());
 
     RootedValue exc(cx);
     if (!cx->getPendingException(&exc))
         return ResumeMode::Terminate;
     cx->clearPendingException();
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, object);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, object);
 
     RootedValue scriptFrame(cx);
     RootedValue wrappedExc(cx, exc);
 
     FrameIter iter(cx);
     if (!getFrame(cx, iter, &scriptFrame) || !wrapDebuggeeValue(cx, &wrappedExc))
-        return reportUncaughtException(ac);
+        return reportUncaughtException(ar);
 
     RootedValue fval(cx, ObjectValue(*hook));
     RootedValue rv(cx);
     bool ok = js::Call(cx, fval, object, scriptFrame, wrappedExc, &rv);
-    ResumeMode resumeMode = processHandlerResult(ac, ok, rv, iter.abstractFramePtr(), iter.pc(), vp);
+    ResumeMode resumeMode = processHandlerResult(ar, ok, rv, iter.abstractFramePtr(), iter.pc(), vp);
     if (resumeMode == ResumeMode::Continue)
         cx->setPendingException(exc);
     return resumeMode;
 }
 
 ResumeMode
 Debugger::fireEnterFrame(JSContext* cx, MutableHandleValue vp)
 {
     RootedObject hook(cx, getHook(OnEnterFrame));
     MOZ_ASSERT(hook);
     MOZ_ASSERT(hook->isCallable());
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, object);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, object);
 
     RootedValue scriptFrame(cx);
 
     FrameIter iter(cx);
     if (!getFrame(cx, iter, &scriptFrame))
-        return reportUncaughtException(ac);
+        return reportUncaughtException(ar);
 
     RootedValue fval(cx, ObjectValue(*hook));
     RootedValue rv(cx);
     bool ok = js::Call(cx, fval, object, scriptFrame, &rv);
 
-    return processHandlerResult(ac, ok, rv, iter.abstractFramePtr(), iter.pc(), vp);
+    return processHandlerResult(ar, ok, rv, iter.abstractFramePtr(), iter.pc(), vp);
 }
 
 void
 Debugger::fireNewScript(JSContext* cx, Handle<DebuggerScriptReferent> scriptReferent)
 {
     RootedObject hook(cx, getHook(OnNewScript));
     MOZ_ASSERT(hook);
     MOZ_ASSERT(hook->isCallable());
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, object);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, object);
 
     JSObject* dsobj = wrapVariantReferent(cx, scriptReferent);
     if (!dsobj) {
-        reportUncaughtException(ac);
+        reportUncaughtException(ar);
         return;
     }
 
     RootedValue fval(cx, ObjectValue(*hook));
     RootedValue dsval(cx, ObjectValue(*dsobj));
     RootedValue rv(cx);
     if (!js::Call(cx, fval, object, dsval, &rv))
-        handleUncaughtException(ac);
+        handleUncaughtException(ar);
 }
 
 void
 Debugger::fireOnGarbageCollectionHook(JSContext* cx,
                                       const JS::dbg::GarbageCollectionEvent::Ptr& gcData)
 {
     MOZ_ASSERT(observedGC(gcData->majorGCNumber()));
     observedGCs.remove(gcData->majorGCNumber());
 
     RootedObject hook(cx, getHook(OnGarbageCollection));
     MOZ_ASSERT(hook);
     MOZ_ASSERT(hook->isCallable());
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, object);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, object);
 
     JSObject* dataObj = gcData->toJSObject(cx);
     if (!dataObj) {
-        reportUncaughtException(ac);
+        reportUncaughtException(ar);
         return;
     }
 
     RootedValue fval(cx, ObjectValue(*hook));
     RootedValue dataVal(cx, ObjectValue(*dataObj));
     RootedValue rv(cx);
     if (!js::Call(cx, fval, object, dataVal, &rv))
-        handleUncaughtException(ac);
+        handleUncaughtException(ar);
 }
 
 template <typename HookIsEnabledFun /* bool (Debugger*) */,
           typename FireHookFun /* ResumeMode (Debugger*) */>
 /* static */ ResumeMode
 Debugger::dispatchHook(JSContext* cx, HookIsEnabledFun hookIsEnabled, FireHookFun fireHook)
 {
     /*
@@ -2011,27 +2011,27 @@ Debugger::onTrap(JSContext* cx, MutableH
          *
          * The other has to do with non-compile-and-go scripts, which have no
          * specific global--until they are executed. Only now do we know which
          * global the script is running against.
          */
         Debugger* dbg = bp->debugger;
         bool hasDebuggee = dbg->enabled && dbg->debuggees.has(global);
         if (hasDebuggee) {
-            Maybe<AutoCompartment> ac;
-            ac.emplace(cx, dbg->object);
+            Maybe<AutoRealm> ar;
+            ar.emplace(cx, dbg->object);
             EnterDebuggeeNoExecute nx(cx, *dbg);
 
             RootedValue scriptFrame(cx);
             if (!dbg->getFrame(cx, iter, &scriptFrame))
-                return dbg->reportUncaughtException(ac);
+                return dbg->reportUncaughtException(ar);
             RootedValue rv(cx);
             Rooted<JSObject*> handler(cx, bp->handler);
             bool ok = CallMethodIfPresent(cx, handler, "hit", 1, scriptFrame.address(), &rv);
-            ResumeMode resumeMode = dbg->processHandlerResult(ac, ok, rv,  iter.abstractFramePtr(),
+            ResumeMode resumeMode = dbg->processHandlerResult(ar, ok, rv,  iter.abstractFramePtr(),
                                                               iter.pc(), vp);
             if (resumeMode != ResumeMode::Continue) {
                 savedExc.drop();
                 return resumeMode;
             }
 
             /* Calling JS code invalidates site. Reload it. */
             if (isJS)
@@ -2110,22 +2110,22 @@ Debugger::onSingleStep(JSContext* cx, Mu
         HandleDebuggerFrame frame = frames[i];
         OnStepHandler* handler = frame->onStepHandler();
         if (!handler)
             continue;
 
         Debugger* dbg = Debugger::fromChildJSObject(frame);
         EnterDebuggeeNoExecute nx(cx, *dbg);
 
-        Maybe<AutoCompartment> ac;
-        ac.emplace(cx, dbg->object);
+        Maybe<AutoRealm> ar;
+        ar.emplace(cx, dbg->object);
 
         ResumeMode resumeMode = ResumeMode::Continue;
         bool success = handler->onStep(cx, frame, resumeMode, vp);
-        resumeMode = dbg->processParsedHandlerResult(ac, iter.abstractFramePtr(), iter.pc(), success,
+        resumeMode = dbg->processParsedHandlerResult(ar, iter.abstractFramePtr(), iter.pc(), success,
                                                      resumeMode, vp);
         if (resumeMode != ResumeMode::Continue) {
             savedExc.drop();
             return resumeMode;
         }
     }
 
     vp.setUndefined();
@@ -2134,22 +2134,22 @@ Debugger::onSingleStep(JSContext* cx, Mu
 
 ResumeMode
 Debugger::fireNewGlobalObject(JSContext* cx, Handle<GlobalObject*> global, MutableHandleValue vp)
 {
     RootedObject hook(cx, getHook(OnNewGlobalObject));
     MOZ_ASSERT(hook);
     MOZ_ASSERT(hook->isCallable());
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, object);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, object);
 
     RootedValue wrappedGlobal(cx, ObjectValue(*global));
     if (!wrapDebuggeeValue(cx, &wrappedGlobal))
-        return reportUncaughtException(ac);
+        return reportUncaughtException(ar);
 
     // onNewGlobalObject is infallible, and thus is only allowed to return
     // undefined as a resumption value. If it returns anything else, we throw.
     // And if that happens, or if the hook itself throws, we invoke the
     // uncaughtExceptionHook so that we never leave an exception pending on the
     // cx. This allows JS_NewGlobalObject to avoid handling failures from debugger
     // hooks.
     RootedValue rv(cx);
@@ -2160,17 +2160,17 @@ Debugger::fireNewGlobalObject(JSContext*
                                   JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED);
         ok = false;
     }
     // NB: Even though we don't care about what goes into it, we have to pass vp
     // to handleUncaughtException so that it parses resumption values from the
     // uncaughtExceptionHook and tells the caller whether we should execute the
     // rest of the onNewGlobalObject hooks or not.
     ResumeMode resumeMode = ok ? ResumeMode::Continue
-                               : handleUncaughtException(ac, vp);
+                               : handleUncaughtException(ar, vp);
     MOZ_ASSERT(!cx->isExceptionPending());
     return resumeMode;
 }
 
 void
 Debugger::slowPathOnNewGlobalObject(JSContext* cx, Handle<GlobalObject*> global)
 {
     MOZ_ASSERT(!cx->runtime()->onNewGlobalObjectWatchers().isEmpty());
@@ -2262,24 +2262,24 @@ Debugger::isDebuggeeUnbarriered(const JS
 }
 
 bool
 Debugger::appendAllocationSite(JSContext* cx, HandleObject obj, HandleSavedFrame frame,
                                mozilla::TimeStamp when)
 {
     MOZ_ASSERT(trackingAllocationSites && enabled);
 
-    AutoCompartment ac(cx, object);
+    AutoRealm ar(cx, object);
     RootedObject wrappedFrame(cx, frame);
     if (!cx->compartment()->wrap(cx, &wrappedFrame))
         return false;
 
     RootedAtom ctorName(cx);
     {
-        AutoCompartment ac(cx, obj);
+        AutoRealm ar(cx, obj);
         if (!JSObject::constructorDisplayAtom(cx, obj, &ctorName))
             return false;
     }
     if (ctorName)
         cx->markAtom(ctorName);
 
     auto className = obj->getClass()->name;
     auto size = JS::ubi::Node(obj.get()).size(cx->runtime()->debuggerMallocSizeOf);
@@ -2303,48 +2303,48 @@ ResumeMode
 Debugger::firePromiseHook(JSContext* cx, Hook hook, HandleObject promise, MutableHandleValue vp)
 {
     MOZ_ASSERT(hook == OnNewPromise || hook == OnPromiseSettled);
 
     RootedObject hookObj(cx, getHook(hook));
     MOZ_ASSERT(hookObj);
     MOZ_ASSERT(hookObj->isCallable());
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, object);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, object);
 
     RootedValue dbgObj(cx, ObjectValue(*promise));
     if (!wrapDebuggeeValue(cx, &dbgObj))
-        return reportUncaughtException(ac);
+        return reportUncaughtException(ar);
 
     // Like onNewGlobalObject, the Promise hooks are infallible and the comments
     // in |Debugger::fireNewGlobalObject| apply here as well.
     RootedValue fval(cx, ObjectValue(*hookObj));
     RootedValue rv(cx);
     bool ok = js::Call(cx, fval, object, dbgObj, &rv);
     if (ok && !rv.isUndefined()) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                                   JSMSG_DEBUG_RESUMPTION_VALUE_DISALLOWED);
         ok = false;
     }
 
     ResumeMode resumeMode = ok ? ResumeMode::Continue
-                               : handleUncaughtException(ac, vp);
+                               : handleUncaughtException(ar, vp);
     MOZ_ASSERT(!cx->isExceptionPending());
     return resumeMode;
 }
 
 /* static */ void
 Debugger::slowPathPromiseHook(JSContext* cx, Hook hook, Handle<PromiseObject*> promise)
 {
     MOZ_ASSERT(hook == OnNewPromise || hook == OnPromiseSettled);
 
-    Maybe<AutoCompartment> ac;
+    Maybe<AutoRealm> ar;
     if (hook == OnNewPromise)
-        ac.emplace(cx, promise);
+        ar.emplace(cx, promise);
 
     assertSameCompartment(cx, promise);
 
     RootedValue rval(cx);
     ResumeMode resumeMode = dispatchHook(
         cx,
         [hook](Debugger* dbg) -> bool { return dbg->getHook(hook); },
         [&](Debugger* dbg) -> ResumeMode {
@@ -2540,17 +2540,17 @@ Debugger::updateExecutionObservabilityOf
 #endif
                 iter.abstractFramePtr().unsetIsDebuggee();
             }
         }
     }
 
     // See comment in unsetPrevUpToDateUntil.
     if (oldestEnabledFrame) {
-        AutoCompartment ac(cx, oldestEnabledFrame.environmentChain());
+        AutoRealm ar(cx, oldestEnabledFrame.environmentChain());
         DebugEnvironments::unsetPrevUpToDateUntil(cx, oldestEnabledFrame);
     }
 
     return true;
 }
 
 static inline void
 MarkBaselineScriptActiveIfObservable(JSScript* script, const Debugger::ExecutionObservableSet& obs)
@@ -2561,17 +2561,17 @@ MarkBaselineScriptActiveIfObservable(JSS
 
 static bool
 AppendAndInvalidateScript(JSContext* cx, Zone* zone, JSScript* script, Vector<JSScript*>& scripts)
 {
     // Enter the script's compartment as addPendingRecompile attempts to
     // cancel off-thread compilations, whose books are kept on the
     // script's compartment.
     MOZ_ASSERT(script->compartment()->zone() == zone);
-    AutoCompartment ac(cx, script);
+    AutoRealm ar(cx, script);
     zone->types.addPendingRecompile(cx, script);
     return scripts.append(script);
 }
 
 static bool
 UpdateExecutionObservabilityOfScriptsInZone(JSContext* cx, Zone* zone,
                                             const Debugger::ExecutionObservableSet& obs,
                                             Debugger::IsObserving observing)
@@ -4008,17 +4008,17 @@ Debugger::addDebuggeeGlobal(JSContext* c
      * 4. the debuggee's zone must be in this->debuggeeZones,
      * 5. if we are tracking allocations, the SavedStacksMetadataBuilder must be
      *    installed for this compartment, and
      * 6. JSCompartment::isDebuggee()'s bit must be set.
      *
      * All six indications must be kept consistent.
      */
 
-    AutoCompartment ac(cx, global);
+    AutoRealm ar(cx, global);
     Zone* zone = global->zone();
 
     // (1)
     auto* globalDebuggers = GlobalObject::getOrCreateDebuggers(cx, global);
     if (!globalDebuggers)
         return false;
     if (!globalDebuggers->append(this)) {
         ReportOutOfMemory(cx);
@@ -7611,17 +7611,17 @@ DebuggerFrame::getEnvironment(JSContext*
 
     Maybe<FrameIter> maybeIter;
     if (!DebuggerFrame::getFrameIter(cx, frame, maybeIter))
         return false;
     FrameIter& iter = *maybeIter;
 
     Rooted<Env*> env(cx);
     {
-        AutoCompartment ac(cx, iter.abstractFramePtr().environmentChain());
+        AutoRealm ar(cx, iter.abstractFramePtr().environmentChain());
         UpdateFrameIterPc(iter);
         env = GetDebugEnvironmentForFrame(cx, iter.abstractFramePtr(), iter.pc());
         if (!env)
             return false;
     }
 
     return dbg->wrapEnvironment(cx, env, result);
 }
@@ -7693,17 +7693,17 @@ DebuggerFrame::getThis(JSContext* cx, Ha
 
     Maybe<FrameIter> maybeIter;
     if (!DebuggerFrame::getFrameIter(cx, frame, maybeIter))
         return false;
     FrameIter& iter = *maybeIter;
 
     {
         AbstractFramePtr frame = iter.abstractFramePtr();
-        AutoCompartment ac(cx, frame.environmentChain());
+        AutoRealm ar(cx, frame.environmentChain());
 
         UpdateFrameIterPc(iter);
 
         if (!GetThisValueForDebuggerMaybeOptimizedOut(cx, frame, iter.pc(), result))
             return false;
     }
 
     return dbg->wrapDebuggeeValue(cx, result);
@@ -7772,17 +7772,17 @@ DebuggerFrame::setOnStepHandler(JSContex
             // Single stepping toggled on->off.
             FreeOp* fop = cx->runtime()->defaultFreeOp();
             if (!instance->debug().decrementStepModeCount(fop, wasmFrame->funcIndex()))
                 return false;
         }
     } else {
         if (handler && !prior) {
             // Single stepping toggled off->on.
-            AutoCompartment ac(cx, referent.environmentChain());
+            AutoRealm ar(cx, referent.environmentChain());
             // Ensure observability *before* incrementing the step mode count.
             // Calling this function after calling incrementStepModeCount
             // will make it a no-op.
             Debugger* dbg = frame->owner();
             if (!dbg->ensureExecutionObservabilityOfScript(cx, referent.script()))
                 return false;
             if (!referent.script()->incrementStepModeCount(cx))
                 return false;
@@ -7915,21 +7915,21 @@ DebuggerGenericEval(JSContext* cx, const
             if (!GetProperty(cx, bindings, bindings, keys[i], valp) ||
                 !dbg->unwrapDebuggeeValue(cx, valp))
             {
                 return false;
             }
         }
     }
 
-    Maybe<AutoCompartment> ac;
+    Maybe<AutoRealm> ar;
     if (iter)
-        ac.emplace(cx, iter->environmentChain(cx));
+        ar.emplace(cx, iter->environmentChain(cx));
     else
-        ac.emplace(cx, envArg);
+        ar.emplace(cx, envArg);
 
     Rooted<Env*> env(cx);
     if (iter) {
         env = GetDebugEnvironmentForFrame(cx, iter->abstractFramePtr(), iter->pc());
         if (!env)
             return false;
     } else {
         env = envArg;
@@ -7967,17 +7967,17 @@ DebuggerGenericEval(JSContext* cx, const
     LeaveDebuggeeNoExecute nnx(cx);
     RootedValue rval(cx);
     AbstractFramePtr frame = iter ? iter->abstractFramePtr() : NullFramePtr();
 
     bool ok = EvaluateInEnv(cx, env, frame, chars,
                             options.filename() ? options.filename() : "debugger eval code",
                             options.lineno(), &rval);
     Debugger::resultToCompletion(cx, ok, rval, &resumeMode, value);
-    ac.reset();
+    ar.reset();
     return dbg->wrapDebuggeeValue(cx, value);
 }
 
 /* static */ bool
 DebuggerFrame::eval(JSContext* cx, HandleDebuggerFrame frame, mozilla::Range<const char16_t> chars,
                     HandleObject bindings, const EvalOptions& options, ResumeMode& resumeMode,
                     MutableHandleValue value)
 {
@@ -8343,17 +8343,17 @@ DebuggerArguments_getArg(JSContext* cx, 
      * there is no guarantee this object has an ith argument.
      */
     MOZ_ASSERT(i >= 0);
     RootedValue arg(cx);
     RootedScript script(cx);
     if (unsigned(i) < frame.numActualArgs()) {
         script = frame.script();
         {
-            AutoCompartment ac(cx, script);
+            AutoRealm ar(cx, script);
             if (!script->ensureHasAnalyzedArgsUsage(cx))
                 return false;
         }
         if (unsigned(i) < frame.numFormalArgs()) {
             for (PositionalFormalParameterIter fi(script); fi; fi++) {
                 if (fi.argumentSlot() == unsigned(i)) {
                     // We might've been called before the CallObject was
                     // created.
@@ -8965,17 +8965,17 @@ DebuggerObject::environmentGetter(JSCont
     /* Only hand out environments of debuggee functions. */
     if (!dbg->observesGlobal(&fun->global())) {
         args.rval().setNull();
         return true;
     }
 
     Rooted<Env*> env(cx);
     {
-        AutoCompartment ac(cx, fun);
+        AutoRealm ar(cx, fun);
         env = GetDebugEnvironmentForFunction(cx, fun);
         if (!env)
             return false;
     }
 
     return dbg->wrapEnvironment(cx, env, args.rval());
 }
 
@@ -9585,17 +9585,17 @@ DebuggerObject::applyMethod(JSContext* c
 DebuggerObject::asEnvironmentMethod(JSContext* cx, unsigned argc, Value* vp)
 {
     THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "asEnvironment", args, dbg, referent);
     if (!RequireGlobalObject(cx, args.thisv(), referent))
         return false;
 
     Rooted<Env*> env(cx);
     {
-        AutoCompartment ac(cx, referent);
+        AutoRealm ar(cx, referent);
         env = GetDebugEnvironmentForGlobalLexicalEnvironment(cx);
         if (!env)
             return false;
     }
 
     return dbg->wrapEnvironment(cx, env, args.rval());
 }
 
@@ -9906,17 +9906,17 @@ DebuggerObject::isPromise() const
 /* static */ bool
 DebuggerObject::getClassName(JSContext* cx, HandleDebuggerObject object,
                              MutableHandleString result)
 {
     RootedObject referent(cx, object->referent());
 
     const char* className;
     {
-        AutoCompartment ac(cx, referent);
+        AutoRealm ar(cx, referent);
         className = GetObjectClassName(cx, referent);
     }
 
     JSAtom* str = Atomize(cx, className, strlen(className));
     if (!str)
         return false;
 
     result.set(str);
@@ -10213,56 +10213,56 @@ DebuggerObject::getPromiseReason(JSConte
     return object->owner()->wrapDebuggeeValue(cx, result);
 }
 
 /* static */ bool
 DebuggerObject::isExtensible(JSContext* cx, HandleDebuggerObject object, bool& result)
 {
     RootedObject referent(cx, object->referent());
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, referent);
-    ErrorCopier ec(ac);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, referent);
+    ErrorCopier ec(ar);
     return IsExtensible(cx, referent, &result);
 }
 
 /* static */ bool
 DebuggerObject::isSealed(JSContext* cx, HandleDebuggerObject object, bool& result)
 {
     RootedObject referent(cx, object->referent());
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, referent);
-
-    ErrorCopier ec(ac);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, referent);
+
+    ErrorCopier ec(ar);
     return TestIntegrityLevel(cx, referent, IntegrityLevel::Sealed, &result);
 }
 
 /* static */ bool
 DebuggerObject::isFrozen(JSContext* cx, HandleDebuggerObject object, bool& result)
 {
     RootedObject referent(cx, object->referent());
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, referent);
-
-    ErrorCopier ec(ac);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, referent);
+
+    ErrorCopier ec(ar);
     return TestIntegrityLevel(cx, referent, IntegrityLevel::Frozen, &result);
 }
 
 /* static */ bool
 DebuggerObject::getPrototypeOf(JSContext* cx, HandleDebuggerObject object,
                                MutableHandleDebuggerObject result)
 {
     RootedObject referent(cx, object->referent());
     Debugger* dbg = object->owner();
 
     RootedObject proto(cx);
     {
-        AutoCompartment ac(cx, referent);
+        AutoRealm ar(cx, referent);
         if (!GetPrototype(cx, referent, &proto))
             return false;
     }
 
     if (!proto) {
         result.set(nullptr);
         return true;
     }
@@ -10273,20 +10273,20 @@ DebuggerObject::getPrototypeOf(JSContext
 /* static */ bool
 DebuggerObject::getOwnPropertyNames(JSContext* cx, HandleDebuggerObject object,
                                     MutableHandle<IdVector> result)
 {
     RootedObject referent(cx, object->referent());
 
     AutoIdVector ids(cx);
     {
-        Maybe<AutoCompartment> ac;
-        ac.emplace(cx, referent);
-
-        ErrorCopier ec(ac);
+        Maybe<AutoRealm> ar;
+        ar.emplace(cx, referent);
+
+        ErrorCopier ec(ar);
         if (!GetPropertyKeys(cx, referent, JSITER_OWNONLY | JSITER_HIDDEN, &ids))
             return false;
     }
 
     for (size_t i = 0; i < ids.length(); i++)
         cx->markId(ids[i]);
 
     return result.append(ids.begin(), ids.end());
@@ -10295,20 +10295,20 @@ DebuggerObject::getOwnPropertyNames(JSCo
 /* static */ bool
 DebuggerObject::getOwnPropertySymbols(JSContext* cx, HandleDebuggerObject object,
                                       MutableHandle<IdVector> result)
 {
     RootedObject referent(cx, object->referent());
 
     AutoIdVector ids(cx);
     {
-        Maybe<AutoCompartment> ac;
-        ac.emplace(cx, referent);
-
-        ErrorCopier ec(ac);
+        Maybe<AutoRealm> ar;
+        ar.emplace(cx, referent);
+
+        ErrorCopier ec(ar);
         if (!GetPropertyKeys(cx, referent,
                              JSITER_OWNONLY | JSITER_HIDDEN | JSITER_SYMBOLS | JSITER_SYMBOLSONLY,
                              &ids))
             return false;
     }
 
     for (size_t i = 0; i < ids.length(); i++)
         cx->markId(ids[i]);
@@ -10320,21 +10320,21 @@ DebuggerObject::getOwnPropertySymbols(JS
 DebuggerObject::getOwnPropertyDescriptor(JSContext* cx, HandleDebuggerObject object,
                                          HandleId id, MutableHandle<PropertyDescriptor> desc)
 {
     RootedObject referent(cx, object->referent());
     Debugger* dbg = object->owner();
 
     /* Bug: This can cause the debuggee to run! */
     {
-        Maybe<AutoCompartment> ac;
-        ac.emplace(cx, referent);
+        Maybe<AutoRealm> ar;
+        ar.emplace(cx, referent);
         cx->markId(id);
 
-        ErrorCopier ec(ac);
+        ErrorCopier ec(ar);
         if (!GetOwnPropertyDescriptor(cx, referent, id, desc))
             return false;
     }
 
     if (desc.object()) {
         /* Rewrap the debuggee values in desc for the debugger. */
         if (!dbg->wrapDebuggeeValue(cx, desc.value()))
             return false;
@@ -10359,66 +10359,66 @@ DebuggerObject::getOwnPropertyDescriptor
     return true;
 }
 
 /* static */ bool
 DebuggerObject::preventExtensions(JSContext* cx, HandleDebuggerObject object)
 {
     RootedObject referent(cx, object->referent());
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, referent);
-
-    ErrorCopier ec(ac);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, referent);
+
+    ErrorCopier ec(ar);
     return PreventExtensions(cx, referent);
 }
 
 /* static */ bool
 DebuggerObject::seal(JSContext* cx, HandleDebuggerObject object)
 {
     RootedObject referent(cx, object->referent());
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, referent);
-
-    ErrorCopier ec(ac);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, referent);
+
+    ErrorCopier ec(ar);
     return SetIntegrityLevel(cx, referent, IntegrityLevel::Sealed);
 }
 
 /* static */ bool
 DebuggerObject::freeze(JSContext* cx, HandleDebuggerObject object)
 {
     RootedObject referent(cx, object->referent());
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, referent);
-
-    ErrorCopier ec(ac);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, referent);
+
+    ErrorCopier ec(ar);
     return SetIntegrityLevel(cx, referent, IntegrityLevel::Frozen);
 }
 
 /* static */ bool
 DebuggerObject::defineProperty(JSContext* cx, HandleDebuggerObject object, HandleId id,
                                Handle<PropertyDescriptor> desc_)
 {
     RootedObject referent(cx, object->referent());
     Debugger* dbg = object->owner();
 
     Rooted<PropertyDescriptor> desc(cx, desc_);
     if (!dbg->unwrapPropertyDescriptor(cx, referent, &desc))
         return false;
     JS_TRY_OR_RETURN_FALSE(cx, CheckPropertyDescriptorAccessors(cx, desc));
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, referent);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, referent);
     if (!cx->compartment()->wrap(cx, &desc))
         return false;
     cx->markId(id);
 
-    ErrorCopier ec(ac);
+    ErrorCopier ec(ar);
     if (!DefineProperty(cx, referent, id, desc))
         return false;
 
     return true;
 }
 
 /* static */ bool
 DebuggerObject::defineProperties(JSContext* cx, HandleDebuggerObject object,
@@ -10432,45 +10432,45 @@ DebuggerObject::defineProperties(JSConte
     if (!descs.append(descs_.begin(), descs_.end()))
         return false;
     for (size_t i = 0; i < descs.length(); i++) {
         if (!dbg->unwrapPropertyDescriptor(cx, referent, descs[i]))
             return false;
         JS_TRY_OR_RETURN_FALSE(cx, CheckPropertyDescriptorAccessors(cx, descs[i]));
     }
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, referent);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, referent);
     for (size_t i = 0; i < descs.length(); i++) {
         if (!cx->compartment()->wrap(cx, descs[i]))
             return false;
         cx->markId(ids[i]);
     }
 
-    ErrorCopier ec(ac);
+    ErrorCopier ec(ar);
     for (size_t i = 0; i < descs.length(); i++) {
         if (!DefineProperty(cx, referent, ids[i], descs[i]))
             return false;
     }
 
     return true;
 }
 
 /* static */ bool
 DebuggerObject::deleteProperty(JSContext* cx, HandleDebuggerObject object, HandleId id,
                                ObjectOpResult& result)
 {
     RootedObject referent(cx, object->referent());
 
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, referent);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, referent);
 
     cx->markId(id);
 
-    ErrorCopier ec(ac);
+    ErrorCopier ec(ar);
     return DeleteProperty(cx, referent, id, result);
 }
 
 /* static */ bool
 DebuggerObject::call(JSContext* cx, HandleDebuggerObject object, HandleValue thisv_,
                      Handle<ValueVector> args, MutableHandleValue result)
 {
     RootedObject referent(cx, object->referent());
@@ -10498,18 +10498,18 @@ DebuggerObject::call(JSContext* cx, Hand
         if (!dbg->unwrapDebuggeeValue(cx, args2[i]))
             return false;
     }
 
     /*
      * Enter the debuggee compartment and rewrap all input value for that compartment.
      * (Rewrapping always takes place in the destination compartment.)
      */
-    Maybe<AutoCompartment> ac;
-    ac.emplace(cx, referent);
+    Maybe<AutoRealm> ar;
+    ar.emplace(cx, referent);
     if (!cx->compartment()->wrap(cx, &calleev) || !cx->compartment()->wrap(cx, &thisv))
         return false;
     for (unsigned i = 0; i < args2.length(); ++i) {
         if (!cx->compartment()->wrap(cx, args2[i]))
             return false;
     }
 
     /*
@@ -10526,17 +10526,17 @@ DebuggerObject::call(JSContext* cx, Hand
         if (ok) {
             for (size_t i = 0; i < args2.length(); ++i)
                 invokeArgs[i].set(args2[i]);
 
             ok = js::Call(cx, calleev, thisv, invokeArgs, result);
         }
     }
 
-    return dbg->receiveCompletionValue(ac, ok, result, result);
+    return dbg->receiveCompletionValue(ar, ok, result, result);
 }
 
 /* static */ bool
 DebuggerObject::forceLexicalInitializationByName(JSContext* cx, HandleDebuggerObject object,
                                                  HandleId id, bool& result)
 {
     if (!JSID_IS_STRING(id)) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE,
@@ -10594,17 +10594,17 @@ DebuggerObject::makeDebuggeeValue(JSCont
 
     RootedValue value(cx, value_);
 
     /* Non-objects are already debuggee values. */
     if (value.isObject()) {
         // Enter this Debugger.Object's referent's compartment, and wrap the
         // argument as appropriate for references from there.
         {
-            AutoCompartment ac(cx, referent);
+            AutoRealm ar(cx, referent);
             if (!cx->compartment()->wrap(cx, &value))
                 return false;
         }
 
         // Back in the debugger's compartment, produce a new Debugger.Object
         // instance referring to the wrapped argument.
         if (!dbg->wrapDebuggeeValue(cx, &value))
             return false;
@@ -11157,20 +11157,20 @@ DebuggerEnvironment::getNames(JSContext*
                               MutableHandle<IdVector> result)
 {
     MOZ_ASSERT(environment->isDebuggee());
 
     Rooted<Env*> referent(cx, environment->referent());
 
     AutoIdVector ids(cx);
     {
-        Maybe<AutoCompartment> ac;
-        ac.emplace(cx, referent);
-
-        ErrorCopier ec(ac);
+        Maybe<AutoRealm> ar;
+        ar.emplace(cx, referent);
+
+        ErrorCopier ec(ar);
         if (!GetPropertyKeys(cx, referent, JSITER_HIDDEN, &ids))
             return false;
     }
 
     for (size_t i = 0; i < ids.length(); ++i) {
         jsid id = ids[i];
         if (JSID_IS_ATOM(id) && IsIdentifier(JSID_TO_ATOM(id))) {
             cx->markId(id);
@@ -11187,23 +11187,23 @@ DebuggerEnvironment::find(JSContext* cx,
                           MutableHandleDebuggerEnvironment result)
 {
     MOZ_ASSERT(environment->isDebuggee());
 
     Rooted<Env*> env(cx, environment->referent());
     Debugger* dbg = environment->owner();
 
     {
-        Maybe<AutoCompartment> ac;
-        ac.emplace(cx, env);
+        Maybe<AutoRealm> ar;
+        ar.emplace(cx, env);
 
         cx->markId(id);
 
         /* This can trigger resolve hooks. */
-        ErrorCopier ec(ac);
+        ErrorCopier ec(ar);
         for (; env; env = env->enclosingEnvironment()) {
             bool found;
             if (!HasProperty(cx, env, id, &found))
                 return false;
             if (found)
                 break;
         }
     }
@@ -11221,23 +11221,23 @@ DebuggerEnvironment::getVariable(JSConte
                                  HandleId id, MutableHandleValue result)
 {
     MOZ_ASSERT(environment->isDebuggee());
 
     Rooted<Env*> referent(cx, environment->referent());
     Debugger* dbg = environment->owner();
 
     {
-        Maybe<AutoCompartment> ac;
-        ac.emplace(cx, referent);
+        Maybe<AutoRealm> ar;
+        ar.emplace(cx, referent);
 
         cx->markId(id);
 
         /* This can trigger getters. */
-        ErrorCopier ec(ac);
+        ErrorCopier ec(ar);
 
         bool found;
         if (!HasProperty(cx, referent, id, &found))
             return false;
         if (!found) {
             result.setUndefined();
             return true;
         }
@@ -11278,24 +11278,24 @@ DebuggerEnvironment::setVariable(JSConte
     Rooted<Env*> referent(cx, environment->referent());
     Debugger* dbg = environment->owner();
 
     RootedValue value(cx, value_);
     if (!dbg->unwrapDebuggeeValue(cx, &value))
         return false;
 
     {
-        Maybe<AutoCompartment> ac;
-        ac.emplace(cx, referent);
+        Maybe<AutoRealm> ar;
+        ar.emplace(cx, referent);
         if (!cx->compartment()->wrap(cx, &value))
             return false;
         cx->markId(id);
 
         /* This can trigger setters. */
-        ErrorCopier ec(ac);
+        ErrorCopier ec(ar);
 
         /* Make sure the environment actually has the specified binding. */
         bool found;
         if (!HasProperty(cx, referent, id, &found))
             return false;
         if (!found) {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_DEBUG_VARIABLE_NOT_FOUND);
             return false;
@@ -11343,17 +11343,17 @@ Builder::Object::definePropertyToTrusted
     RootedId id(cx, AtomToId(atom));
 
     return DefineDataProperty(cx, value, id, trusted);
 }
 
 bool
 Builder::Object::defineProperty(JSContext* cx, const char* name, JS::HandleValue propval_)
 {
-    AutoCompartment ac(cx, debuggerObject());
+    AutoRealm ar(cx, debuggerObject());
 
     RootedValue propval(cx, propval_);
     if (!debugger()->wrapDebuggeeValue(cx, &propval))
         return false;
 
     return definePropertyToTrusted(cx, name, &propval);
 }
 
@@ -11362,26 +11362,26 @@ Builder::Object::defineProperty(JSContex
 {
     RootedValue propval(cx, ObjectOrNullValue(propval_));
     return defineProperty(cx, name, propval);
 }
 
 bool
 Builder::Object::defineProperty(JSContext* cx, const char* name, Builder::Object& propval_)
 {
-    AutoCompartment ac(cx, debuggerObject());
+    AutoRealm ar(cx, debuggerObject());
 
     RootedValue propval(cx, ObjectOrNullValue(propval_.value));
     return definePropertyToTrusted(cx, name, &propval);
 }
 
 Builder::Object
 Builder::newObject(JSContext* cx)
 {
-    AutoCompartment ac(cx, debuggerObject);
+    AutoRealm ar(cx, debuggerObject);
 
     RootedPlainObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
 
     // If the allocation failed, this will return a false Object, as the spec promises.
     return Object(cx, *this, obj);
 }
 
 
--- a/js/src/vm/Debugger.h
+++ b/js/src/vm/Debugger.h
@@ -555,92 +555,92 @@ class Debugger : private mozilla::Linked
     class ScriptQuery;
     class ObjectQuery;
 
     MOZ_MUST_USE bool addDebuggeeGlobal(JSContext* cx, Handle<GlobalObject*> obj);
     void removeDebuggeeGlobal(FreeOp* fop, GlobalObject* global,
                               WeakGlobalObjectSet::Enum* debugEnum);
 
     /*
-     * Report and clear the pending exception on ac.context, if any, and return
+     * Report and clear the pending exception on ar.context, if any, and return
      * ResumeMode::Terminate.
      */
-    ResumeMode reportUncaughtException(mozilla::Maybe<AutoCompartment>& ac);
+    ResumeMode reportUncaughtException(mozilla::Maybe<AutoRealm>& ar);
 
     /*
      * Cope with an error or exception in a debugger hook.
      *
      * If callHook is true, then call the uncaughtExceptionHook, if any. If, in
      * addition, vp is given, then parse the value returned by
      * uncaughtExceptionHook as a resumption value.
      *
      * If there is no uncaughtExceptionHook, or if it fails, report and clear
-     * the pending exception on ac.context and return ResumeMode::Terminate.
+     * the pending exception on ar.context and return ResumeMode::Terminate.
      *
-     * This always calls ac.leave(); ac is a parameter because this method must
-     * do some things in the debugger compartment and some things in the
-     * debuggee compartment.
+     * This always calls ar.leave(); ar is a parameter because this method must
+     * do some things in the debugger realm and some things in the debuggee
+     * realm.
      */
-    ResumeMode handleUncaughtException(mozilla::Maybe<AutoCompartment>& ac);
-    ResumeMode handleUncaughtException(mozilla::Maybe<AutoCompartment>& ac,
+    ResumeMode handleUncaughtException(mozilla::Maybe<AutoRealm>& ar);
+    ResumeMode handleUncaughtException(mozilla::Maybe<AutoRealm>& ar,
                                        MutableHandleValue vp,
                                        const mozilla::Maybe<HandleValue>& thisVForCheck = mozilla::Nothing(),
                                        AbstractFramePtr frame = NullFramePtr());
 
-    ResumeMode handleUncaughtExceptionHelper(mozilla::Maybe<AutoCompartment>& ac,
+    ResumeMode handleUncaughtExceptionHelper(mozilla::Maybe<AutoRealm>& ar,
                                              MutableHandleValue* vp,
                                              const mozilla::Maybe<HandleValue>& thisVForCheck,
                                              AbstractFramePtr frame);
 
     /*
      * Handle the result of a hook that is expected to return a resumption
      * value <https://wiki.mozilla.org/Debugger#Resumption_Values>. This is
      * called when we return from a debugging hook to debuggee code. The
      * interpreter wants a (ResumeMode, Value) pair telling it how to proceed.
      *
-     * Precondition: ac is entered. We are in the debugger compartment.
+     * Precondition: ar is entered. We are in the debugger compartment.
      *
-     * Postcondition: This called ac.leave(). See handleUncaughtException.
+     * Postcondition: This called ar.leave(). See handleUncaughtException.
      *
      * If `success` is false, the hook failed. If an exception is pending in
-     * ac.context(), return handleUncaughtException(ac, vp, callhook).
+     * ar.context(), return handleUncaughtException(ar, vp, callhook).
      * Otherwise just return ResumeMode::Terminate.
      *
-     * If `success` is true, there must be no exception pending in ac.context().
+     * If `success` is true, there must be no exception pending in ar.context().
      * `rv` may be:
      *
      *     undefined - Return `ResumeMode::Continue` to continue execution
      *         normally.
      *
      *     {return: value} or {throw: value} - Call unwrapDebuggeeValue to
      *         unwrap `value`. Store the result in `*vp` and return
      *         `ResumeMode::Return` or `ResumeMode::Throw`. The interpreter
      *         will force the current frame to return or throw an exception.
      *
      *     null - Return `ResumeMode::Terminate` to terminate the debuggee with
      *         an uncatchable error.
      *
      *     anything else - Make a new TypeError the pending exception and
-     *         return handleUncaughtException(ac, vp, callHook).
+     *         return handleUncaughtException(ar, vp, callHook).
      */
-    ResumeMode processHandlerResult(mozilla::Maybe<AutoCompartment>& ac, bool success, const Value& rv,
+    ResumeMode processHandlerResult(mozilla::Maybe<AutoRealm>& ar, bool success, const Value& rv,
                                     AbstractFramePtr frame, jsbytecode* pc, MutableHandleValue vp);
 
-    ResumeMode processParsedHandlerResult(mozilla::Maybe<AutoCompartment>& ac,
+    ResumeMode processParsedHandlerResult(mozilla::Maybe<AutoRealm>& ar,
                                           AbstractFramePtr frame, jsbytecode* pc,
                                           bool success, ResumeMode resumeMode,
                                           MutableHandleValue vp);
 
-    ResumeMode processParsedHandlerResultHelper(mozilla::Maybe<AutoCompartment>& ac,
+    ResumeMode processParsedHandlerResultHelper(mozilla::Maybe<AutoRealm>& ar,
                                                 AbstractFramePtr frame,
                                                 const mozilla::Maybe<HandleValue>& maybeThisv,
                                                 bool success, ResumeMode resumeMode,
                                                 MutableHandleValue vp);
 
-    bool processResumptionValue(mozilla::Maybe<AutoCompartment>& ac, AbstractFramePtr frame,
+    bool processResumptionValue(mozilla::Maybe<AutoRealm>& ar, AbstractFramePtr frame,
                                 const mozilla::Maybe<HandleValue>& maybeThis, HandleValue rval,
                                 ResumeMode& resumeMode, MutableHandleValue vp);
 
     GlobalObject* unwrapDebuggeeArgument(JSContext* cx, const Value& v);
 
     static void traceObject(JSTracer* trc, JSObject* obj);
 
     void trace(JSTracer* trc);
@@ -978,19 +978,19 @@ class Debugger : private mozilla::Linked
      * or create a Debugger.Environment object for the given Env. On success,
      * store the Environment object in *vp and return true.
      */
     MOZ_MUST_USE bool wrapEnvironment(JSContext* cx, Handle<Env*> env, MutableHandleValue vp);
     MOZ_MUST_USE bool wrapEnvironment(JSContext* cx, Handle<Env*> env,
                                       MutableHandleDebuggerEnvironment result);
 
     /*
-     * Like cx->compartment()->wrap(cx, vp), but for the debugger compartment.
+     * Like cx->compartment()->wrap(cx, vp), but for the debugger realm.
      *
-     * Preconditions: *vp is a value from a debuggee compartment; cx is in the
+     * Preconditions: *vp is a value from a debuggee realm; cx is in the
      * debugger's compartment.
      *
      * If *vp is an object, this produces a (new or existing) Debugger.Object
      * wrapper for it. Otherwise this is the same as JSCompartment::wrap.
      *
      * If *vp is a magic JS_OPTIMIZED_OUT value, this produces a plain object
      * of the form { optimizedOut: true }.
      *
@@ -1019,17 +1019,17 @@ class Debugger : private mozilla::Linked
      * value. Otherwise *vp is a primitive, so leave it alone.
      *
      * When passing values from the debuggee to the debugger:
      *     enter debugger compartment;
      *     call wrapDebuggeeValue;  // compartment- and debugger-wrapping
      *
      * When passing values from the debugger to the debuggee:
      *     call unwrapDebuggeeValue;  // debugger-unwrapping
-     *     enter debuggee compartment;
+     *     enter debuggee realm;
      *     call cx->compartment()->wrap;  // compartment-rewrapping
      *
      * (Extreme nerd sidebar: Unwrapping happens in two steps because there are
      * two different kinds of symmetry at work: regardless of which direction
      * we're going, we want any exceptions to be created and thrown in the
      * debugger compartment--mirror symmetry. But compartment wrapping always
      * happens in the target compartment--rotational symmetry.)
      */
@@ -1064,58 +1064,58 @@ class Debugger : private mozilla::Linked
      * Set |*result| to a JavaScript completion value corresponding to |resumeMode|
      * and |value|. |value| should be the return value or exception value, not
      * wrapped as a debuggee value. |cx| must be in the debugger compartment.
      */
     MOZ_MUST_USE bool newCompletionValue(JSContext* cx, ResumeMode resumeMode, const Value& value,
                                          MutableHandleValue result);
 
     /*
-     * Precondition: we are in the debuggee compartment (ac is entered) and ok
-     * is true if the operation in the debuggee compartment succeeded, false on
-     * error or exception.
+     * Precondition: we are in the debuggee realm (ar is entered) and ok is true
+     * if the operation in the debuggee realm succeeded, false on error or
+     * exception.
      *
-     * Postcondition: we are in the debugger compartment, having called
-     * ac.leave() even if an error occurred.
+     * Postcondition: we are in the debugger realm, having called ar.leave()
+     * even if an error occurred.
      *
-     * On success, a completion value is in vp and ac.context does not have a
+     * On success, a completion value is in vp and ar.context does not have a
      * pending exception. (This ordinarily returns true even if the ok argument
      * is false.)
      */
-    MOZ_MUST_USE bool receiveCompletionValue(mozilla::Maybe<AutoCompartment>& ac, bool ok,
+    MOZ_MUST_USE bool receiveCompletionValue(mozilla::Maybe<AutoRealm>& ar, bool ok,
                                              HandleValue val,
                                              MutableHandleValue vp);
 
     /*
      * Return the Debugger.Script object for |script|, or create a new one if
-     * needed. The context |cx| must be in the debugger compartment; |script|
-     * must be a script in a debuggee compartment.
+     * needed. The context |cx| must be in the debugger realm; |script| must be
+     * a script in a debuggee realm.
      */
     JSObject* wrapScript(JSContext* cx, HandleScript script);
 
     /*
      * Return the Debugger.Script object for |wasmInstance| (the toplevel
      * script), synthesizing a new one if needed. The context |cx| must be in
      * the debugger compartment; |wasmInstance| must be a WasmInstanceObject in
-     * the debuggee compartment.
+     * the debuggee realm.
      */
     JSObject* wrapWasmScript(JSContext* cx, Handle<WasmInstanceObject*> wasmInstance);
 
     /*
      * Return the Debugger.Source object for |source|, or create a new one if
      * needed. The context |cx| must be in the debugger compartment; |source|
-     * must be a script source object in a debuggee compartment.
+     * must be a script source object in a debuggee realm.
      */
     JSObject* wrapSource(JSContext* cx, js::HandleScriptSourceObject source);
 
     /*
      * Return the Debugger.Source object for |wasmInstance| (the entire module),
      * synthesizing a new one if needed. The context |cx| must be in the
      * debugger compartment; |wasmInstance| must be a WasmInstanceObject in the
-     * debuggee compartment.
+     * debuggee realm.
      */
     JSObject* wrapWasmSource(JSContext* cx, Handle<WasmInstanceObject*> wasmInstance);
 
   private:
     Debugger(const Debugger&) = delete;
     Debugger & operator=(const Debugger&) = delete;
 };
 
--- a/js/src/vm/GlobalObject.cpp
+++ b/js/src/vm/GlobalObject.cpp
@@ -504,17 +504,17 @@ GlobalObject::new_(JSContext* cx, const 
     MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
 
     JSCompartment* compartment = NewCompartment(cx, principals, options);
     if (!compartment)
         return nullptr;
 
     Rooted<GlobalObject*> global(cx);
     {
-        AutoCompartmentUnchecked ac(cx, compartment);
+        AutoRealmUnchecked ar(cx, compartment);
         global = GlobalObject::createInternal(cx, clasp);
         if (!global)
             return nullptr;
 
         if (hookOption == JS::FireOnNewGlobalHook)
             JS_FireOnNewGlobalObject(cx, global);
     }
 
--- a/js/src/vm/HelperThreads.cpp
+++ b/js/src/vm/HelperThreads.cpp
@@ -2068,17 +2068,17 @@ HelperThread::handleParseWorkload(AutoLo
         JSContext* cx = TlsContext.get();
 
         Zone* zone = task->parseGlobal->zoneFromAnyThread();
         zone->setHelperThreadOwnerContext(cx);
         auto resetOwnerContext = mozilla::MakeScopeExit([&] {
             zone->setHelperThreadOwnerContext(nullptr);
         });
 
-        AutoCompartment ac(cx, task->parseGlobal);
+        AutoRealm ar(cx, task->parseGlobal);
 
         task->parse(cx);
 
         cx->frontendCollectionPool().purge();
     }
 
     // The callback is invoked while we are still off thread.
     task->callback(task, task->callbackData);
--- a/js/src/vm/Iteration.cpp
+++ b/js/src/vm/Iteration.cpp
@@ -1361,17 +1361,17 @@ js::IteratorMore(JSContext* cx, HandleOb
     MOZ_ASSERT(IsWrapper(iterobj));
 
     RootedObject obj(cx, CheckedUnwrap(iterobj));
     if (!obj)
         return false;
 
     MOZ_RELEASE_ASSERT(obj->is<PropertyIteratorObject>());
     {
-        AutoCompartment ac(cx, obj);
+        AutoRealm ar(cx, obj);
         NativeIterator* ni = obj->as<PropertyIteratorObject>().getNativeIterator();
         NativeIteratorNext(ni, rval);
     }
     return cx->compartment()->wrap(cx, rval);
 }
 
 static const JSFunctionSpec iterator_proto_methods[] = {
     JS_SELF_HOSTED_SYM_FN(iterator, "IteratorIdentity", 0, 0),
--- a/js/src/vm/JSAtom.cpp
+++ b/js/src/vm/JSAtom.cpp
@@ -446,17 +446,17 @@ AtomizeAndCopyCharsInner(JSContext* cx, 
             atom->setPinned();
             p->setPinned(true);
         }
         return atom;
     }
 
     JSAtom* atom;
     {
-        AutoAtomsCompartment ac(cx, lock);
+        AutoAtomsRealm ar(cx, lock);
 
         JSFlatString* flat = NewStringCopyN<NoGC>(cx, tbchars, length);
         if (!flat) {
             // Grudgingly forgo last-ditch GC. The alternative would be to release
             // the lock, manually GC here, and retry from the top. If you fix this,
             // please also fix or comment the similar case in Symbol::new_.
             ReportOutOfMemory(cx);
             return nullptr;
--- a/js/src/vm/JSCompartment-inl.h
+++ b/js/src/vm/JSCompartment-inl.h
@@ -39,59 +39,59 @@ JSCompartment::unsafeUnbarrieredMaybeGlo
 inline bool
 JSCompartment::globalIsAboutToBeFinalized()
 {
     MOZ_ASSERT(zone_->isGCSweeping());
     return global_ && js::gc::IsAboutToBeFinalizedUnbarriered(global_.unsafeGet());
 }
 
 template <typename T>
-js::AutoCompartment::AutoCompartment(JSContext* cx, const T& target)
+js::AutoRealm::AutoRealm(JSContext* cx, const T& target)
   : cx_(cx),
     origin_(cx->compartment()),
     maybeLock_(nullptr)
 {
     cx_->enterCompartmentOf(target);
 }
 
 // Protected constructor that bypasses assertions in enterCompartmentOf. Used
 // only for entering the atoms compartment.
-js::AutoCompartment::AutoCompartment(JSContext* cx, JSCompartment* target,
-                                     js::AutoLockForExclusiveAccess& lock)
+js::AutoRealm::AutoRealm(JSContext* cx, JSCompartment* target,
+                         js::AutoLockForExclusiveAccess& lock)
   : cx_(cx),
     origin_(cx->compartment()),
     maybeLock_(&lock)
 {
     MOZ_ASSERT(target->isAtomsCompartment());
     cx_->enterAtomsCompartment(target, lock);
 }
 
 // Protected constructor that bypasses assertions in enterCompartmentOf. Should
 // not be used to enter the atoms compartment.
-js::AutoCompartment::AutoCompartment(JSContext* cx, JSCompartment* target)
+js::AutoRealm::AutoRealm(JSContext* cx, JSCompartment* target)
   : cx_(cx),
     origin_(cx->compartment()),
     maybeLock_(nullptr)
 {
     MOZ_ASSERT(!target->isAtomsCompartment());
     cx_->enterNonAtomsCompartment(target);
 }
 
-js::AutoCompartment::~AutoCompartment()
+js::AutoRealm::~AutoRealm()
 {
     cx_->leaveCompartment(origin_, maybeLock_);
 }
 
-js::AutoAtomsCompartment::AutoAtomsCompartment(JSContext* cx,
-                                               js::AutoLockForExclusiveAccess& lock)
-  : AutoCompartment(cx, cx->atomsCompartment(lock), lock)
+js::AutoAtomsRealm::AutoAtomsRealm(JSContext* cx,
+                                   js::AutoLockForExclusiveAccess& lock)
+  : AutoRealm(cx, cx->atomsCompartment(lock), lock)
 {}
 
-js::AutoCompartmentUnchecked::AutoCompartmentUnchecked(JSContext* cx, JSCompartment* target)
-  : AutoCompartment(cx, target)
+js::AutoRealmUnchecked::AutoRealmUnchecked(JSContext* cx, JSCompartment* target)
+  : AutoRealm(cx, target)
 {}
 
 inline bool
 JSCompartment::wrap(JSContext* cx, JS::MutableHandleValue vp)
 {
     /* Only GC things have to be wrapped or copied. */
     if (!vp.isGCThing())
         return true;
--- a/js/src/vm/JSCompartment.cpp
+++ b/js/src/vm/JSCompartment.cpp
@@ -1158,17 +1158,17 @@ CreateLazyScriptsForCompartment(JSContex
     }
 
     return true;
 }
 
 bool
 JSCompartment::ensureDelazifyScriptsForDebugger(JSContext* cx)
 {
-    AutoCompartmentUnchecked ac(cx, this);
+    AutoRealmUnchecked ar(cx, this);
     if (needsDelazificationForDebugger() && !CreateLazyScriptsForCompartment(cx))
         return false;
     debugModeBits &= ~DebuggerNeedsDelazification;
     return true;
 }
 
 void
 JSCompartment::updateDebuggerObservesFlag(unsigned flag)
--- a/js/src/vm/JSCompartment.h
+++ b/js/src/vm/JSCompartment.h
@@ -1252,69 +1252,69 @@ class MOZ_RAII AssertCompartmentUnchange
     }
 
   protected:
     JSContext * const cx;
     JSCompartment * const oldCompartment;
     MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
 };
 
-class AutoCompartment
+class AutoRealm
 {
-    JSContext * const cx_;
-    JSCompartment * const origin_;
+    JSContext* const cx_;
+    JSCompartment* const origin_;
     const AutoLockForExclusiveAccess* maybeLock_;
 
   public:
     template <typename T>
-    inline AutoCompartment(JSContext* cx, const T& target);
-    inline ~AutoCompartment();
+    inline AutoRealm(JSContext* cx, const T& target);
+    inline ~AutoRealm();
 
     JSContext* context() const { return cx_; }
     JSCompartment* origin() const { return origin_; }
 
   protected:
-    inline AutoCompartment(JSContext* cx, JSCompartment* target);
+    inline AutoRealm(JSContext* cx, JSCompartment* target);
 
     // Used only for entering the atoms compartment.
-    inline AutoCompartment(JSContext* cx, JSCompartment* target,
-                           AutoLockForExclusiveAccess& lock);
+    inline AutoRealm(JSContext* cx, JSCompartment* target,
+                     AutoLockForExclusiveAccess& lock);
 
   private:
-    AutoCompartment(const AutoCompartment&) = delete;
-    AutoCompartment & operator=(const AutoCompartment&) = delete;
+    AutoRealm(const AutoRealm&) = delete;
+    AutoRealm& operator=(const AutoRealm&) = delete;
 };
 
-class AutoAtomsCompartment : protected AutoCompartment
+class AutoAtomsRealm : protected AutoRealm
 {
   public:
-    inline AutoAtomsCompartment(JSContext* cx, AutoLockForExclusiveAccess& lock);
+    inline AutoAtomsRealm(JSContext* cx, AutoLockForExclusiveAccess& lock);
 };
 
-// Enter a compartment directly. Only use this where there's no target GC thing
-// to pass to AutoCompartment or where you need to avoid the assertions in
+// Enter a realm directly. Only use this where there's no target GC thing
+// to pass to AutoRealm or where you need to avoid the assertions in
 // JS::Compartment::enterCompartmentOf().
-class AutoCompartmentUnchecked : protected AutoCompartment
+class AutoRealmUnchecked : protected AutoRealm
 {
   public:
-    inline AutoCompartmentUnchecked(JSContext* cx, JSCompartment* target);
+    inline AutoRealmUnchecked(JSContext* cx, JSCompartment* target);
 };
 
 /*
- * Use this to change the behavior of an AutoCompartment slightly on error. If
+ * Use this to change the behavior of an AutoRealm slightly on error. If
  * the exception happens to be an Error object, copy it to the origin compartment
  * instead of wrapping it.
  */
 class ErrorCopier
 {
-    mozilla::Maybe<AutoCompartment>& ac;
+    mozilla::Maybe<AutoRealm>& ar;
 
   public:
-    explicit ErrorCopier(mozilla::Maybe<AutoCompartment>& ac)
-      : ac(ac) {}
+    explicit ErrorCopier(mozilla::Maybe<AutoRealm>& ar)
+      : ar(ar) {}
     ~ErrorCopier();
 };
 
 /*
  * AutoWrapperVector and AutoWrapperRooter can be used to store wrappers that
  * are obtained from the cross-compartment map. However, these classes should
  * not be used if the wrapper will escape. For example, it should not be stored
  * in the heap.
--- a/js/src/vm/JSContext.cpp
+++ b/js/src/vm/JSContext.cpp
@@ -1144,17 +1144,17 @@ js::RunJobs(JSContext* cx)
             // It's possible that queue draining was interrupted prematurely,
             // leaving the queue partly processed. In that case, slots for
             // already-executed entries will contain nullptrs, which we should
             // just skip.
             if (!job)
                 continue;
 
             cx->jobQueue->get()[i] = nullptr;
-            AutoCompartment ac(cx, job);
+            AutoRealm ar(cx, job);
             {
                 if (!JS::Call(cx, UndefinedHandleValue, job, args, &rval)) {
                     // Nothing we can do about uncatchable exceptions.
                     if (!cx->isExceptionPending())
                         continue;
                     RootedValue exn(cx);
                     if (cx->getPendingException(&exn)) {
                         /*
--- a/js/src/vm/JSContext.h
+++ b/js/src/vm/JSContext.h
@@ -20,17 +20,17 @@
 #include "vm/ErrorReporting.h"
 #include "vm/MallocProvider.h"
 #include "vm/Runtime.h"
 
 struct DtoaState;
 
 namespace js {
 
-class AutoCompartment;
+class AutoRealm;
 
 namespace jit {
 class JitContext;
 class DebugModeOSRVolatileJitFrameIter;
 } // namespace jit
 
 namespace gc {
 class AutoSuppressNurseryCellAlloc;
@@ -194,17 +194,17 @@ struct JSContext : public JS::RootingCon
      * This is not a problem since, in general, most places in the VM cannot
      * know that they were called from script (e.g., they may have been called
      * through the JSAPI via JS_CallFunction) and thus cannot expect fp.
      *
      * Compartments should be entered/left in a LIFO fasion. The depth of this
      * enter/leave stack is maintained by enterCompartmentDepth_ and queried by
      * hasEnteredCompartment.
      *
-     * To enter a compartment, code should prefer using AutoCompartment over
+     * To enter a compartment, code should prefer using AutoRealm over
      * manually calling cx->enterCompartment/leaveCompartment.
      */
   protected:
     js::ThreadData<unsigned> enterCompartmentDepth_;
 
     inline void setCompartment(JSCompartment* comp,
                                const js::AutoLockForExclusiveAccess* maybeLock = nullptr);
   public:
@@ -219,17 +219,17 @@ struct JSContext : public JS::RootingCon
 
   private:
     // We distinguish between entering the atoms compartment and all other
     // compartments. Entering the atoms compartment requires a lock.
     inline void enterNonAtomsCompartment(JSCompartment* c);
     inline void enterAtomsCompartment(JSCompartment* c,
                                       const js::AutoLockForExclusiveAccess& lock);
 
-    friend class js::AutoCompartment;
+    friend class js::AutoRealm;
 
   public:
     template <typename T>
     inline void enterCompartmentOf(const T& target);
     inline void enterNullCompartment();
     inline void leaveCompartment(JSCompartment* oldCompartment,
                                  const js::AutoLockForExclusiveAccess* maybeLock = nullptr);
 
@@ -260,17 +260,17 @@ struct JSContext : public JS::RootingCon
     static size_t offsetOfZone() {
         return offsetof(JSContext, zone_);
     }
 
     // Zone local methods that can be used freely.
     inline js::LifoAlloc& typeLifoAlloc();
 
     // Current global. This is only safe to use within the scope of the
-    // AutoCompartment from which it's called.
+    // AutoRealm from which it's called.
     inline js::Handle<js::GlobalObject*> global() const;
 
     // Methods to access runtime data that must be protected by locks.
     js::AtomSet& atoms(js::AutoLockForExclusiveAccess& lock) {
         return runtime_->atoms(lock);
     }
     JSCompartment* atomsCompartment(js::AutoLockForExclusiveAccess& lock) {
         return runtime_->atomsCompartment(lock);
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -2172,17 +2172,17 @@ js::GetObjectFromIncumbentGlobal(JSConte
 {
     RootedObject globalObj(cx, cx->runtime()->getIncumbentGlobal(cx));
     if (!globalObj) {
         obj.set(nullptr);
         return true;
     }
 
     {
-        AutoCompartment ac(cx, globalObj);
+        AutoRealm ar(cx, globalObj);
         Handle<GlobalObject*> global = globalObj.as<GlobalObject>();
         obj.set(GlobalObject::getOrCreateObjectPrototype(cx, global));
         if (!obj)
             return false;
     }
 
     // The object might be from a different compartment, so wrap it.
     if (obj && !cx->compartment()->wrap(cx, obj))
--- a/js/src/vm/JSScript.cpp
+++ b/js/src/vm/JSScript.cpp
@@ -3494,17 +3494,17 @@ js::detail::CopyScript(JSContext* cx, Ha
                     if (cx->compartment() != innerFun->compartment()) {
                         MOZ_ASSERT(innerFun->isAsmJSNative());
                         JS_ReportErrorASCII(cx, "AsmJS modules do not yet support cloning.");
                         return false;
                     }
                     clone = innerFun;
                 } else {
                     if (innerFun->isInterpretedLazy()) {
-                        AutoCompartment ac(cx, innerFun);
+                        AutoRealm ar(cx, innerFun);
                         if (!JSFunction::getOrCreateScript(cx, innerFun))
                             return false;
                     }
 
                     Scope* enclosing = innerFun->nonLazyScript()->enclosingScope();
                     RootedScope enclosingClone(cx, scopes[FindScopeIndex(src, *enclosing)]);
                     clone = CloneInnerInterpretedFunction(cx, enclosingClone, innerFun);
                 }
--- a/js/src/vm/SavedStacks.cpp
+++ b/js/src/vm/SavedStacks.cpp
@@ -1469,17 +1469,17 @@ SavedStacks::insertFrames(JSContext* cx,
             if (parent)
                 break;
         }
 
         // We'll be pushing this frame onto stackChain. Gather the information
         // needed to construct the SavedFrame::Lookup.
         Rooted<LocationValue> location(cx);
         {
-            AutoCompartmentUnchecked ac(cx, iter.compartment());
+            AutoRealmUnchecked ar(cx, iter.compartment());
             if (!cx->compartment()->savedStacks().getLocation(cx, iter, &location))
                 return false;
         }
 
         RootedAtom displayAtom(cx, iter.maybeFunctionDisplayAtom());
 
         auto principals = iter.compartment()->principals();
         MOZ_ASSERT_IF(framePtr && !iter.isWasm(), iter.pc());
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -2806,17 +2806,17 @@ JSRuntime::createSelfHostingGlobal(JSCon
         JS_GlobalObjectTraceHook
     };
 
     static const Class shgClass = {
         "self-hosting-global", JSCLASS_GLOBAL_FLAGS,
         &shgClassOps
     };
 
-    AutoCompartmentUnchecked ac(cx, compartment);
+    AutoRealmUnchecked ar(cx, compartment);
     Rooted<GlobalObject*> shg(cx, GlobalObject::createInternal(cx, &shgClass));
     if (!shg)
         return nullptr;
 
     cx->runtime()->selfHostingGlobal_ = shg;
     compartment->isSelfHosting = true;
     compartment->setIsSystem(true);
 
--- a/js/src/vm/Stack.cpp
+++ b/js/src/vm/Stack.cpp
@@ -1617,17 +1617,17 @@ jit::JitActivation::getRematerializedFra
         // preserve identity. Therefore, we always rematerialize an uninlined
         // frame and all its inlined frames at once.
         InlineFrameIterator inlineIter(cx, &iter);
         MaybeReadFallback recover(cx, this, &iter);
 
         // Frames are often rematerialized with the cx inside a Debugger's
         // compartment. To recover slots and to create CallObjects, we need to
         // be in the activation's compartment.
-        AutoCompartmentUnchecked ac(cx, compartment_);
+        AutoRealmUnchecked ar(cx, compartment_);
 
         if (!RematerializedFrame::RematerializeInlineFrames(cx, top, inlineIter, recover, frames))
             return nullptr;
 
         if (!rematerializedFrames_->add(p, top, Move(frames))) {
             ReportOutOfMemory(cx);
             return nullptr;
         }
--- a/js/src/vm/StringType.cpp
+++ b/js/src/vm/StringType.cpp
@@ -1035,17 +1035,17 @@ const StaticStrings::SmallChar StaticStr
 #undef R4
 #undef R6
 #undef R7
 
 bool
 StaticStrings::init(JSContext* cx)
 {
     AutoLockForExclusiveAccess lock(cx);
-    AutoAtomsCompartment ac(cx, lock);
+    AutoAtomsRealm ar(cx, lock);
 
     static_assert(UNIT_STATIC_LIMIT - 1 <= JSString::MAX_LATIN1_CHAR,
                   "Unit strings must fit in Latin1Char.");
 
     using Latin1Range = mozilla::Range<const Latin1Char>;
 
     for (uint32_t i = 0; i < UNIT_STATIC_LIMIT; i++) {
         Latin1Char buffer[] = { Latin1Char(i), '\0' };
--- a/js/src/vm/StructuredClone.cpp
+++ b/js/src/vm/StructuredClone.cpp
@@ -1777,17 +1777,17 @@ JSStructuredCloneWriter::transferOwnersh
 bool
 JSStructuredCloneWriter::write(HandleValue v)
 {
     if (!startWrite(v))
         return false;
 
     while (!counts.empty()) {
         RootedObject obj(context(), &objs.back().toObject());
-        AutoCompartment ac(context(), obj);
+        AutoRealm ar(context(), obj);
         if (counts.back()) {
             counts.back()--;
             RootedValue key(context(), entries.back());
             entries.popBack();
             checkStack();
 
             ESClass cls;
             if (!GetBuiltinClass(context(), obj, &cls))
@@ -2787,21 +2787,21 @@ JS_StructuredClone(JSContext* cx, Handle
       vp.setString(strValue);
       return true;
     }
 
     const JSStructuredCloneCallbacks* callbacks = optionalCallbacks;
 
     JSAutoStructuredCloneBuffer buf(JS::StructuredCloneScope::SameProcessSameThread, callbacks, closure);
     {
-        // If we use Maybe<AutoCompartment> here, G++ can't tell that the
+        // If we use Maybe<AutoRealm> here, G++ can't tell that the
         // destructor is only called when Maybe::construct was called, and
         // we get warnings about using uninitialized variables.
         if (value.isObject()) {
-            AutoCompartment ac(cx, &value.toObject());
+            AutoRealm ar(cx, &value.toObject());
             if (!buf.write(cx, value, callbacks, closure))
                 return false;
         } else {
             if (!buf.write(cx, value, callbacks, closure))
                 return false;
         }
     }
 
--- a/js/src/vm/SymbolType.cpp
+++ b/js/src/vm/SymbolType.cpp
@@ -43,17 +43,17 @@ Symbol::new_(JSContext* cx, JS::SymbolCo
             return nullptr;
     }
 
     // Lock to allocate. If symbol allocation becomes a bottleneck, this can
     // probably be replaced with an assertion that we're on the main thread.
     AutoLockForExclusiveAccess lock(cx);
     Symbol* sym;
     {
-        AutoAtomsCompartment ac(cx, lock);
+        AutoAtomsRealm ar(cx, lock);
         sym = newInternal(cx, code, cx->compartment()->randomHashCode(), atom, lock);
     }
     if (sym)
         cx->markAtom(sym);
     return sym;
 }
 
 Symbol*
@@ -69,17 +69,17 @@ Symbol::for_(JSContext* cx, HandleString
     SymbolRegistry::AddPtr p = registry.lookupForAdd(atom);
     if (p) {
         cx->markAtom(*p);
         return *p;
     }
 
     Symbol* sym;
     {
-        AutoAtomsCompartment ac(cx, lock);
+        AutoAtomsRealm ar(cx, lock);
         // Rehash the hash of the atom to give the corresponding symbol a hash
         // that is different than the hash of the corresponding atom.
         HashNumber hash = mozilla::HashGeneric(atom->hash());
         sym = newInternal(cx, SymbolCode::InSymbolRegistry, hash, atom, lock);
         if (!sym)
             return nullptr;
 
         // p is still valid here because we have held the lock since the