Bug 913586 (Part 4) - Update Maybe users in dom. r=bz
authorSeth Fowler <seth@mozilla.com>
Wed, 13 Aug 2014 15:39:41 -0700
changeset 222291 69d0a773505e1f8a7d3bc75ddb09c1af920f87e0
parent 222290 abad9c2ddec8da4740fd1471e23b7561d2fe18dc
child 222292 59b1637dc740e8e6e8bcbff8f12549ba6710be76
push id583
push userbhearsum@mozilla.com
push dateMon, 24 Nov 2014 19:04:58 +0000
treeherdermozilla-release@c107e74250f4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs913586
milestone34.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 913586 (Part 4) - Update Maybe users in dom. r=bz
dom/base/Console.cpp
dom/base/ScriptSettings.cpp
dom/base/ScriptSettings.h
dom/base/nsGlobalWindow.cpp
dom/base/nsJSUtils.cpp
dom/bindings/BindingDeclarations.h
dom/bindings/BindingUtils.cpp
dom/bindings/BindingUtils.h
dom/bindings/CallbackObject.cpp
dom/bindings/Codegen.py
dom/bindings/DOMString.h
dom/bindings/TypedArray.h
dom/events/EventListenerManager.cpp
dom/events/EventListenerService.cpp
dom/events/EventStateManager.cpp
dom/indexedDB/IDBRequest.cpp
dom/src/json/nsJSON.cpp
dom/system/nsDeviceSensors.cpp
dom/workers/WorkerPrivate.cpp
dom/workers/WorkerRunnable.cpp
dom/workers/XMLHttpRequest.cpp
--- a/dom/base/Console.cpp
+++ b/dom/base/Console.cpp
@@ -867,19 +867,19 @@ Console::Method(JSContext* aCx, MethodNa
     uint32_t language;
     nsresult rv = stack->GetLanguage(&language);
     if (NS_FAILED(rv)) {
       return;
     }
 
     if (language == nsIProgrammingLanguage::JAVASCRIPT ||
         language == nsIProgrammingLanguage::JAVASCRIPT2) {
-      callData->mTopStackFrame.construct();
+      callData->mTopStackFrame.emplace();
       nsresult rv = StackFrameToStackEntry(stack,
-                                           callData->mTopStackFrame.ref(),
+                                           *callData->mTopStackFrame,
                                            language);
       if (NS_FAILED(rv)) {
         return;
       }
 
       break;
     }
 
@@ -892,18 +892,18 @@ Console::Method(JSContext* aCx, MethodNa
     stack.swap(caller);
   } while (stack);
 
   if (NS_IsMainThread()) {
     callData->mStack = stack;
   } else {
     // nsIStackFrame is not threadsafe, so we need to snapshot it now,
     // before we post our runnable to the main thread.
-    callData->mReifiedStack.construct();
-    nsresult rv = ReifyStack(stack, callData->mReifiedStack.ref());
+    callData->mReifiedStack.emplace();
+    nsresult rv = ReifyStack(stack, *callData->mReifiedStack);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return;
     }
   }
 
   // Monotonic timer for 'time' and 'timeEnd'
   if ((aMethodName == MethodTime || aMethodName == MethodTimeEnd)) {
     if (mWindow) {
@@ -1033,18 +1033,18 @@ LazyStackGetter(JSContext* aCx, unsigned
 
 void
 Console::ProcessCallData(ConsoleCallData* aData)
 {
   MOZ_ASSERT(aData);
   MOZ_ASSERT(NS_IsMainThread());
 
   ConsoleStackEntry frame;
-  if (!aData->mTopStackFrame.empty()) {
-    frame = aData->mTopStackFrame.ref();
+  if (aData->mTopStackFrame) {
+    frame = *aData->mTopStackFrame;
   }
 
   AutoSafeJSContext cx;
   ClearException ce(cx);
   RootedDictionary<ConsoleEvent> event(cx);
 
   JSAutoCompartment ac(cx, aData->mGlobal);
 
@@ -1126,19 +1126,19 @@ Console::ProcessCallData(ConsoleCallData
   if (!JS_DefineProperty(cx, eventObj, "wrappedJSObject", eventValue, JSPROP_ENUMERATE)) {
     return;
   }
 
   if (ShouldIncludeStackrace(aData->mMethodName)) {
     // Now define the "stacktrace" property on eventObj.  There are two cases
     // here.  Either we came from a worker and have a reified stack, or we want
     // to define a getter that will lazily reify the stack.
-    if (!aData->mReifiedStack.empty()) {
+    if (aData->mReifiedStack) {
       JS::Rooted<JS::Value> stacktrace(cx);
-      if (!ToJSValue(cx, aData->mReifiedStack.ref(), &stacktrace) ||
+      if (!ToJSValue(cx, *aData->mReifiedStack, &stacktrace) ||
           !JS_DefineProperty(cx, eventObj, "stacktrace", stacktrace,
                              JSPROP_ENUMERATE)) {
         return;
       }
     } else {
       JSFunction* fun = js::NewFunctionWithReserved(cx, LazyStackGetter, 0, 0,
                                                     eventObj, "stacktrace");
       if (!fun) {
--- a/dom/base/ScriptSettings.cpp
+++ b/dom/base/ScriptSettings.cpp
@@ -232,20 +232,20 @@ AutoJSAPI::InitInternal(JSObject* aGloba
 {
   mCx = aCx;
   if (aIsMainThread) {
     // This Rooted<> is necessary only as long as AutoCxPusher::AutoCxPusher
     // can GC, which is only possible because XPCJSContextStack::Push calls
     // nsIPrincipal.Equals. Once that is removed, the Rooted<> will no longer
     // be necessary.
     JS::Rooted<JSObject*> global(JS_GetRuntime(aCx), aGlobal);
-    mCxPusher.construct(mCx);
-    mAutoNullableCompartment.construct(mCx, global);
+    mCxPusher.emplace(mCx);
+    mAutoNullableCompartment.emplace(mCx, global);
   } else {
-    mAutoNullableCompartment.construct(mCx, aGlobal);
+    mAutoNullableCompartment.emplace(mCx, aGlobal);
   }
 }
 
 AutoJSAPI::AutoJSAPI(nsIGlobalObject* aGlobalObject,
                      bool aIsMainThread,
                      JSContext* aCx)
 {
   MOZ_ASSERT(aGlobalObject);
@@ -363,15 +363,15 @@ AutoIncumbentScript::AutoIncumbentScript
 }
 
 AutoNoJSAPI::AutoNoJSAPI(bool aIsMainThread)
   : ScriptSettingsStackEntry()
 {
   MOZ_ASSERT_IF(nsContentUtils::GetCurrentJSContextForThread(),
                 !JS_IsExceptionPending(nsContentUtils::GetCurrentJSContextForThread()));
   if (aIsMainThread) {
-    mCxPusher.construct(static_cast<JSContext*>(nullptr),
-                        /* aAllowNull = */ true);
+    mCxPusher.emplace(static_cast<JSContext*>(nullptr),
+                      /* aAllowNull = */ true);
   }
 }
 
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/ScriptSettings.h
+++ b/dom/base/ScriptSettings.h
@@ -167,17 +167,17 @@ public:
   bool InitWithLegacyErrorReporting(nsGlobalWindow* aWindow);
 
   JSContext* cx() const {
     MOZ_ASSERT(mCx, "Must call Init before using an AutoJSAPI");
     MOZ_ASSERT_IF(NS_IsMainThread(), CxPusherIsStackTop());
     return mCx;
   }
 
-  bool CxPusherIsStackTop() const { return mCxPusher.ref().IsStackTop(); }
+  bool CxPusherIsStackTop() const { return mCxPusher->IsStackTop(); }
 
 protected:
   // Protected constructor, allowing subclasses to specify a particular cx to
   // be used. This constructor initialises the AutoJSAPI, so Init must NOT be
   // called on subclasses that use this.
   // If aGlobalObject, its associated JS global or aCx are null this will cause
   // an assertion, as will setting aIsMainThread incorrectly.
   AutoJSAPI(nsIGlobalObject* aGlobalObject, bool aIsMainThread, JSContext* aCx);
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -11793,17 +11793,17 @@ nsGlobalWindow::OpenInternal(const nsASt
       if (aJSCallerContext) {
         // If script in some other window is doing a window.open on us and
         // it's being blocked, then it's OK to close us afterwards, probably.
         // But if we're doing a window.open on ourselves and block the popup,
         // prevent this window from closing until after this script terminates
         // so that whatever popup blocker UI the app has will be visible.
         if (mContext == GetScriptContextFromJSContext(aJSCallerContext)) {
           mBlockScriptedClosingFlag = true;
-          closeUnblocker.construct(this);
+          closeUnblocker.emplace(this);
         }
       }
 
       FireAbuseEvents(true, false, aUrl, aName, aOptions);
       return aDoJSFixups ? NS_OK : NS_ERROR_FAILURE;
     }
   }
 
@@ -11842,17 +11842,17 @@ nsGlobalWindow::OpenInternal(const nsASt
       // nsIDOMWindow::OpenWindow and nsIWindowWatcher::OpenWindow.
 
       // Note: Because nsWindowWatcher is so broken, it's actually important
       // that we don't force a system caller here, because that screws it up
       // when it tries to compute the caller principal to associate with dialog
       // arguments. That whole setup just really needs to be rewritten. :-(
       Maybe<AutoNoJSAPI> nojsapi;
       if (!aContentModal) {
-        nojsapi.construct();
+        nojsapi.emplace();
       }
 
 
       rv = pwwatch->OpenWindow2(this, url.get(), name_ptr, options_ptr,
                                 /* aCalledFromScript = */ false,
                                 aDialog, aNavigate, nullptr, aExtraArgument,
                                 getter_AddRefs(domReturn));
 
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -222,17 +222,17 @@ nsJSUtils::EvaluateString(JSContext* aCx
   bool ok = false;
   nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
   NS_ENSURE_TRUE(ssm->ScriptAllowed(js::GetGlobalForObjectCrossCompartment(aScopeObject)), NS_OK);
 
   mozilla::Maybe<AutoDontReportUncaught> dontReport;
   if (!aEvaluateOptions.reportUncaught) {
     // We need to prevent AutoLastFrameCheck from reporting and clearing
     // any pending exceptions.
-    dontReport.construct(aCx);
+    dontReport.emplace(aCx);
   }
 
   // Scope the JSAutoCompartment so that we can later wrap the return value
   // into the caller's cx.
   {
     JSAutoCompartment ac(aCx, aScopeObject);
 
     JS::Rooted<JSObject*> rootedScope(aCx, aScopeObject);
--- a/dom/bindings/BindingDeclarations.h
+++ b/dom/bindings/BindingDeclarations.h
@@ -101,73 +101,71 @@ template<typename T, typename InternalTy
 class Optional_base
 {
 public:
   Optional_base()
   {}
 
   explicit Optional_base(const T& aValue)
   {
-    mImpl.construct(aValue);
+    mImpl.emplace(aValue);
   }
 
   template<typename T1, typename T2>
   explicit Optional_base(const T1& aValue1, const T2& aValue2)
   {
-    mImpl.construct(aValue1, aValue2);
+    mImpl.emplace(aValue1, aValue2);
   }
 
   bool WasPassed() const
   {
-    return !mImpl.empty();
+    return mImpl.isSome();
   }
 
   // Return InternalType here so we can work with it usefully.
   InternalType& Construct()
   {
-    mImpl.construct();
-    return mImpl.ref();
+    mImpl.emplace();
+    return *mImpl;
   }
 
   template <class T1>
   InternalType& Construct(const T1 &t1)
   {
-    mImpl.construct(t1);
-    return mImpl.ref();
+    mImpl.emplace(t1);
+    return *mImpl;
   }
 
   template <class T1, class T2>
   InternalType& Construct(const T1 &t1, const T2 &t2)
   {
-    mImpl.construct(t1, t2);
-    return mImpl.ref();
+    mImpl.emplace(t1, t2);
+    return *mImpl;
   }
 
   void Reset()
   {
-    if (WasPassed()) {
-      mImpl.destroy();
-    }
+    mImpl.reset();
   }
 
   const T& Value() const
   {
-    return mImpl.ref();
+    return *mImpl;
   }
 
   // Return InternalType here so we can work with it usefully.
   InternalType& Value()
   {
-    return mImpl.ref();
+    return *mImpl;
   }
 
   // And an explicit way to get the InternalType even if we're const.
   const InternalType& InternalValue() const
   {
-    return mImpl.ref();
+    return *mImpl;
   }
 
   // If we ever decide to add conversion operators for optional arrays
   // like the ones Nullable has, we'll need to ensure that Maybe<> has
   // the boolean before the actual data.
 
 private:
   // Forbid copy-construction and assignment
@@ -209,24 +207,24 @@ public:
   Optional(JSContext* cx, const T& aValue) :
     Optional_base<JS::Handle<T>, JS::Rooted<T> >(cx, aValue)
   {}
 
   // Override the const Value() to return the right thing so we're not
   // returning references to temporaries.
   JS::Handle<T> Value() const
   {
-    return this->mImpl.ref();
+    return *this->mImpl;
   }
 
   // And we have to override the non-const one too, since we're
   // shadowing the one on the superclass.
   JS::Rooted<T>& Value()
   {
-    return this->mImpl.ref();
+    return *this->mImpl;
   }
 };
 
 // A specialization of Optional for JSObject* to make sure that when someone
 // calls Construct() on it we will pre-initialized the JSObject* to nullptr so
 // it can be traced safely.
 template<>
 class Optional<JSObject*> : public Optional_base<JSObject*, JSObject*>
@@ -272,46 +270,46 @@ template<typename T>
 class Optional<NonNull<T> > : public Optional_base<T, NonNull<T> >
 {
 public:
   // We want our Value to actually return a non-const reference, even
   // if we're const.  At least for things that are normally pointer
   // types...
   T& Value() const
   {
-    return *this->mImpl.ref().get();
+    return *this->mImpl->get();
   }
 
   // And we have to override the non-const one too, since we're
   // shadowing the one on the superclass.
   NonNull<T>& Value()
   {
-    return this->mImpl.ref();
+    return *this->mImpl;
   }
 };
 
 // A specialization of Optional for OwningNonNull that lets us get a
 // T& from Value()
 template<typename T>
 class Optional<OwningNonNull<T> > : public Optional_base<T, OwningNonNull<T> >
 {
 public:
   // We want our Value to actually return a non-const reference, even
   // if we're const.  At least for things that are normally pointer
   // types...
   T& Value() const
   {
-    return *this->mImpl.ref().get();
+    return *this->mImpl->get();
   }
 
   // And we have to override the non-const one too, since we're
   // shadowing the one on the superclass.
   OwningNonNull<T>& Value()
   {
-    return this->mImpl.ref();
+    return *this->mImpl;
   }
 };
 
 // Specialization for strings.
 // XXXbz we can't pull in FakeString here, because it depends on internal
 // strings.  So we just have to forward-declare it and reimplement its
 // ToAStringPtr.
 
--- a/dom/bindings/BindingUtils.cpp
+++ b/dom/bindings/BindingUtils.cpp
@@ -1554,17 +1554,17 @@ GetPropertyOnPrototype(JSContext* cx, JS
 bool
 HasPropertyOnPrototype(JSContext* cx, JS::Handle<JSObject*> proxy,
                        JS::Handle<jsid> id)
 {
   JS::Rooted<JSObject*> obj(cx, proxy);
   Maybe<JSAutoCompartment> ac;
   if (xpc::WrapperFactory::IsXrayWrapper(obj)) {
     obj = js::UncheckedUnwrap(obj);
-    ac.construct(cx, obj);
+    ac.emplace(cx, obj);
   }
 
   bool found;
   // We ignore an error from GetPropertyOnPrototype.  We pass nullptr
   // for vp so that GetPropertyOnPrototype won't actually do a get.
   return !GetPropertyOnPrototype(cx, obj, id, &found, nullptr) || found;
 }
 
--- a/dom/bindings/BindingUtils.h
+++ b/dom/bindings/BindingUtils.h
@@ -918,17 +918,17 @@ WrapNewBindingNonWrapperCachedObject(JSC
     // Maybe<Handle> doesn't so much work, and in any case, adding
     // more Maybe (one for a Rooted and one for a Handle) adds more
     // code (and branches!) than just adding a single rooted.
     JS::Rooted<JSObject*> scope(cx, scopeArg);
     if (js::IsWrapper(scope)) {
       scope = js::CheckedUnwrap(scope, /* stopAtOuter = */ false);
       if (!scope)
         return false;
-      ac.construct(cx, scope);
+      ac.emplace(cx, scope);
     }
 
     MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
     obj = value->WrapObject(cx);
   }
 
   if (!obj) {
     return false;
@@ -965,17 +965,17 @@ WrapNewBindingNonWrapperCachedOwnedObjec
     // Maybe<Handle> doesn't so much work, and in any case, adding
     // more Maybe (one for a Rooted and one for a Handle) adds more
     // code (and branches!) than just adding a single rooted.
     JS::Rooted<JSObject*> scope(cx, scopeArg);
     if (js::IsWrapper(scope)) {
       scope = js::CheckedUnwrap(scope, /* stopAtOuter = */ false);
       if (!scope)
         return false;
-      ac.construct(cx, scope);
+      ac.emplace(cx, scope);
     }
 
     bool tookOwnership = false;
     MOZ_ASSERT(js::IsObjectInContextCompartment(scope, cx));
     obj = value->WrapObject(cx, &tookOwnership);
     MOZ_ASSERT_IF(obj, tookOwnership);
     if (tookOwnership) {
       value.forget();
--- a/dom/bindings/CallbackObject.cpp
+++ b/dom/bindings/CallbackObject.cpp
@@ -121,41 +121,41 @@ CallbackObject::CallSetup::CallSetup(Cal
 
     // Bail out if there's no useful global. This seems to happen intermittently
     // on gaia-ui tests, probably because nsInProcessTabChildGlobal is returning
     // null in some kind of teardown state.
     if (!globalObject->GetGlobalJSObject()) {
       return;
     }
 
-    mAutoEntryScript.construct(globalObject, mIsMainThread, cx);
-    mAutoEntryScript.ref().SetWebIDLCallerPrincipal(webIDLCallerPrincipal);
+    mAutoEntryScript.emplace(globalObject, mIsMainThread, cx);
+    mAutoEntryScript->SetWebIDLCallerPrincipal(webIDLCallerPrincipal);
     nsIGlobalObject* incumbent = aCallback->IncumbentGlobalOrNull();
     if (incumbent) {
       // The callback object traces its incumbent JS global, so in general it
       // should be alive here. However, it's possible that we could run afoul
       // of the same IPC global weirdness described above, wherein the
       // nsIGlobalObject has severed its reference to the JS global. Let's just
       // be safe here, so that nobody has to waste a day debugging gaia-ui tests.
       if (!incumbent->GetGlobalJSObject()) {
         return;
       }
-      mAutoIncumbentScript.construct(incumbent);
+      mAutoIncumbentScript.emplace(incumbent);
     }
 
     // Unmark the callable (by invoking Callback() and not the CallbackPreserveColor()
     // variant), and stick it in a Rooted before it can go gray again.
     // Nothing before us in this function can trigger a CC, so it's safe to wait
     // until here it do the unmark. This allows us to order the following two
     // operations _after_ the Push() above, which lets us take advantage of the
     // JSAutoRequest embedded in the pusher.
     //
     // We can do this even though we're not in the right compartment yet, because
     // Rooted<> does not care about compartments.
-    mRootedCallable.construct(cx, aCallback->Callback());
+    mRootedCallable.emplace(cx, aCallback->Callback());
   }
 
   // JS-implemented WebIDL is always OK to run, since it runs with Chrome
   // privileges anyway.
   if (mIsMainThread && !aIsJSImplementedWebIDL) {
     // Check that it's ok to run this callback at all.
     // Make sure to use realCallback to get the global of the callback object,
     // not the wrapper.
@@ -167,17 +167,17 @@ CallbackObject::CallSetup::CallSetup(Cal
     }
   }
 
   // Enter the compartment of our callback, so we can actually work with it.
   //
   // Note that if the callback is a wrapper, this will not be the same
   // compartment that we ended up in with mAutoEntryScript above, because the
   // entry point is based off of the unwrapped callback (realCallback).
-  mAc.construct(cx, mRootedCallable.ref());
+  mAc.emplace(cx, *mRootedCallable);
 
   // And now we're ready to go.
   mCx = cx;
 
   // Make sure the JS engine doesn't report exceptions we want to re-throw
   if ((mCompartment && mExceptionHandling == eRethrowContentExceptions) ||
       mExceptionHandling == eRethrowExceptions) {
     mSavedJSContextOptions = JS::ContextOptionsRef(cx);
@@ -214,17 +214,17 @@ CallbackObject::CallSetup::ShouldRethrow
 
 CallbackObject::CallSetup::~CallSetup()
 {
   // To get our nesting right we have to destroy our JSAutoCompartment first.
   // In particular, we want to do this before we try reporting any exceptions,
   // so we end up reporting them while in the compartment of our entry point,
   // not whatever cross-compartment wrappper mCallback might be.
   // Be careful: the JSAutoCompartment might not have been constructed at all!
-  mAc.destroyIfConstructed();
+  mAc.reset();
 
   // Now, if we have a JSContext, report any pending errors on it, unless we
   // were told to re-throw them.
   if (mCx) {
     bool needToDealWithException = JS_IsExceptionPending(mCx);
     if ((mCompartment && mExceptionHandling == eRethrowContentExceptions) ||
         mExceptionHandling == eRethrowExceptions) {
       // Restore the old context options
@@ -268,18 +268,18 @@ CallbackObject::CallSetup::~CallSetup()
         JS_ReportPendingException(mCx);
       }
       if (saved) {
         JS_RestoreFrameChain(mCx);
       }
     }
   }
 
-  mAutoIncumbentScript.destroyIfConstructed();
-  mAutoEntryScript.destroyIfConstructed();
+  mAutoIncumbentScript.reset();
+  mAutoEntryScript.reset();
 
   // It is important that this is the last thing we do, after leaving the
   // compartment and undoing all our entry/incumbent script changes
   if (mIsMainThread) {
     nsContentUtils::LeaveMicroTask();
   }
 }
 
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -550,17 +550,17 @@ def CallOnUnforgeableHolder(descriptor, 
         pre = fill(
             """
             // Scope for 'global', 'ac' and 'unforgeableHolder'
             {
               JS::Rooted<JSObject*> global(cx);
               Maybe<JSAutoCompartment> ac;
               if (${isXrayCheck}) {
                 global = js::GetGlobalForObjectCrossCompartment(js::UncheckedUnwrap(proxy));
-                ac.construct(cx, global);
+                ac.emplace(cx, global);
               } else {
                 global = js::GetGlobalForObjectCrossCompartment(proxy);
               }
             """,
             isXrayCheck=isXrayCheck)
     else:
         pre = dedent("""
             // Scope for 'global' and 'unforgeableHolder'
@@ -4333,17 +4333,17 @@ def getJSToNativeConversionInfo(type, de
             if isOptional and not isMember:
                 holderArgs = "${declName}.Value().SetValue()"
                 declType = CGTemplatedType("Optional", declType)
                 constructDecl = CGGeneric("${declName}.Construct();\n")
                 declLoc = "${declName}.Value()"
             else:
                 holderArgs = "${declName}.SetValue()"
             if holderType is not None:
-                constructHolder = CGGeneric("${holderName}.construct(%s);\n" % holderArgs)
+                constructHolder = CGGeneric("${holderName}.emplace(%s);\n" % holderArgs)
             else:
                 constructHolder = None
             # Don't need to pass those args when the holder is being constructed
             holderArgs = None
         else:
             holderArgs = "${declName}"
             constructHolder = None
 
@@ -5085,17 +5085,17 @@ def instantiateJSToNativeConversion(info
         if dealWithOptional:
             declConstruct = CGIndenter(
                 CGGeneric("%s.Construct(%s);\n" %
                           (originalDeclName,
                            getArgsCGThing(info.declArgs).define() if
                            info.declArgs else "")))
             if holderType is not None:
                 holderConstruct = CGIndenter(
-                    CGGeneric("%s.construct(%s);\n" %
+                    CGGeneric("%s.emplace(%s);\n" %
                               (originalHolderName,
                                getArgsCGThing(info.holderArgs).define() if
                                info.holderArgs else "")))
             else:
                 holderConstruct = None
         else:
             declConstruct = None
             holderConstruct = None
@@ -6322,23 +6322,23 @@ class CGPerSignatureCall(CGThing):
         argsPost = []
         if isConstructor:
             needsUnwrap = True
             needsUnwrappedVar = False
             unwrappedVar = "obj"
         elif descriptor.interface.isJSImplemented():
             needsUnwrap = True
             needsUnwrappedVar = True
-            argsPost.append("js::GetObjectCompartment(unwrappedObj.empty() ? obj : unwrappedObj.ref())")
+            argsPost.append("js::GetObjectCompartment(unwrappedObj ? *unwrappedObj : obj)")
         elif needScopeObject(returnType, arguments, self.extendedAttributes,
                              descriptor.wrapperCache, True,
                              idlNode.getExtendedAttribute("StoreInSlot")):
             needsUnwrap = True
             needsUnwrappedVar = True
-            argsPre.append("unwrappedObj.empty() ? obj : unwrappedObj.ref()")
+            argsPre.append("unwrappedObj ? *unwrappedObj : obj")
 
         if needsUnwrap and needsUnwrappedVar:
             # We cannot assign into obj because it's a Handle, not a
             # MutableHandle, so we need a separate Rooted.
             cgThings.append(CGGeneric("Maybe<JS::Rooted<JSObject*> > unwrappedObj;\n"))
             unwrappedVar = "unwrappedObj.ref()"
 
         if idlNode.isMethod() and idlNode.isLegacycaller():
@@ -6362,17 +6362,17 @@ class CGPerSignatureCall(CGThing):
             # It's very important that we construct our unwrappedObj, if we need
             # to do it, before we might start setting up Rooted things for our
             # arguments, so that we don't violate the stack discipline Rooted
             # depends on.
             cgThings.append(CGGeneric(
                 "bool objIsXray = xpc::WrapperFactory::IsXrayWrapper(obj);\n"))
             if needsUnwrappedVar:
                 cgThings.append(CGIfWrapper(
-                    CGGeneric("unwrappedObj.construct(cx, obj);\n"),
+                    CGGeneric("unwrappedObj.emplace(cx, obj);\n"),
                     "objIsXray"))
 
         for i in range(argConversionStartsAt, self.argCount):
             cgThings.append(
                 CGArgumentConverter(arguments[i], i, self.descriptor,
                                     argDescription % {"index": i + 1},
                                     invalidEnumValueFatal=not setter,
                                     lenientFloatCode=lenientFloatCode))
@@ -6397,17 +6397,17 @@ class CGPerSignatureCall(CGThing):
                 # that compartment as needed.  This is all happening after we've
                 # already done the conversions from JS values to WebIDL (C++)
                 # values, so we only need to worry about cases where there are 'any'
                 # or 'object' types, or other things that we represent as actual
                 # JSAPI types, present.  Effectively, we're emulating a
                 # CrossCompartmentWrapper, but working with the C++ types, not the
                 # original list of JS::Values.
                 cgThings.append(CGGeneric("Maybe<JSAutoCompartment> ac;\n"))
-                xraySteps.append(CGGeneric("ac.construct(cx, obj);\n"))
+                xraySteps.append(CGGeneric("ac.emplace(cx, obj);\n"))
                 xraySteps.extend(
                     wrapArgIntoCurrentCompartment(arg, argname, isMember=False)
                     for arg, argname in self.getArguments())
 
             cgThings.append(
                 CGIfWrapper(CGList(xraySteps),
                             "objIsXray"))
 
@@ -8280,17 +8280,17 @@ def getUnionTypeTemplateVars(unionType, 
     conversionInfo = getJSToNativeConversionInfo(
         type, descriptorProvider, failureCode=tryNextCode,
         isDefinitelyObject=not type.isDictionary(),
         isMember=("OwningUnion" if ownsMembers else None),
         sourceDescription="member of %s" % unionType)
 
     if conversionInfo.holderType is not None:
         assert not ownsMembers
-        destroyHolder = "%s.destroy();\n" % holderName
+        destroyHolder = "%s.reset();\n" % holderName
     else:
         destroyHolder = ""
 
     ctorNeedsCx = conversionInfo.declArgs == "cx"
     ctorArgs = "cx" if ctorNeedsCx else ""
 
     structType = conversionInfo.declType.define()
     externalType = getUnionAccessorSignatureType(type, descriptorProvider).define()
@@ -8316,17 +8316,17 @@ def getUnionTypeTemplateVars(unionType, 
 
     else:
         # Important: we need to not have our declName involve
         # maybe-GCing operations.
         if conversionInfo.holderType is not None:
             holderArgs = conversionInfo.holderArgs
             if holderArgs is None:
                 holderArgs = ""
-            initHolder = "%s.construct(%s);\n" % (holderName, holderArgs)
+            initHolder = "%s.emplace(%s);\n" % (holderName, holderArgs)
         else:
             initHolder = ""
 
         jsConversion = fill(
             initHolder + conversionInfo.template,
             val="value",
             declName="memberSlot",
             holderName=(holderName if ownsMembers else "%s.ref()" % holderName),
@@ -11062,18 +11062,18 @@ class CGDictionary(CGThing):
         if memberInits:
             body += fill(
                 """
                 bool isNull = val.isNullOrUndefined();
                 // We only need these if !isNull, in which case we have |cx|.
                 Maybe<JS::Rooted<JSObject *> > object;
                 Maybe<JS::Rooted<JS::Value> > temp;
                 if (!isNull) {
-                  object.construct(cx, &val.toObject());
-                  temp.construct(cx);
+                  object.emplace(cx, &val.toObject());
+                  temp.emplace(cx);
                 }
                 $*{memberInits}
                 """,
                 memberInits="\n".join(memberInits))
 
         body += "return true;\n"
 
         return ClassMethod("Init", "bool", [
@@ -11316,35 +11316,35 @@ class CGDictionary(CGThing):
             # anything we want.
             "holderName": "holder"
         }
         # We can't handle having a holderType here
         assert conversionInfo.holderType is None
         if conversionInfo.dealWithOptional:
             replacements["declName"] = "(" + replacements["declName"] + ".Value())"
         if member.defaultValue:
-            replacements["haveValue"] = "!isNull && !temp.ref().isUndefined()"
+            replacements["haveValue"] = "!isNull && !temp->isUndefined()"
 
         propId = self.makeIdName(member.identifier.name)
-        propGet = ("JS_GetPropertyById(cx, object.ref(), atomsCache->%s, &temp.ref())" %
+        propGet = ("JS_GetPropertyById(cx, *object, atomsCache->%s, temp.ptr())" %
                    propId)
 
         conversionReplacements = {
             "prop": self.makeMemberName(member.identifier.name),
             "convert": string.Template(conversionInfo.template).substitute(replacements),
             "propGet": propGet
         }
         conversion = ("if (!isNull && !${propGet}) {\n"
                       "  return false;\n"
                       "}\n")
         if member.defaultValue:
             conversion += "${convert}"
         else:
             conversion += (
-                "if (!isNull && !temp.ref().isUndefined()) {\n"
+                "if (!isNull && !temp->isUndefined()) {\n"
                 "  ${prop}.Construct();\n"
                 "${convert}"
                 "}\n")
             conversionReplacements["convert"] = indent(conversionReplacements["convert"])
 
         return CGGeneric(
             string.Template(conversion).substitute(conversionReplacements))
 
--- a/dom/bindings/DOMString.h
+++ b/dom/bindings/DOMString.h
@@ -41,41 +41,41 @@ class MOZ_STACK_CLASS DOMString {
 public:
   DOMString()
     : mStringBuffer(nullptr)
     , mLength(0)
     , mIsNull(false)
   {}
   ~DOMString()
   {
-    MOZ_ASSERT(mString.empty() || !mStringBuffer,
+    MOZ_ASSERT(!mString || !mStringBuffer,
                "Shouldn't have both present!");
   }
 
   operator nsString&()
   {
     return AsAString();
   }
 
   nsString& AsAString()
   {
     MOZ_ASSERT(!mStringBuffer, "We already have a stringbuffer?");
     MOZ_ASSERT(!mIsNull, "We're already set as null");
-    if (mString.empty()) {
-      mString.construct();
+    if (!mString) {
+      mString.emplace();
     }
-    return mString.ref();
+    return *mString;
   }
 
   bool HasStringBuffer() const
   {
-    MOZ_ASSERT(mString.empty() || !mStringBuffer,
+    MOZ_ASSERT(!mString || !mStringBuffer,
                "Shouldn't have both present!");
     MOZ_ASSERT(!mIsNull, "Caller should have checked IsNull() first");
-    return mString.empty();
+    return !mString;
   }
 
   // Get the stringbuffer.  This can only be called if HasStringBuffer()
   // returned true and StringBufferLength() is nonzero.  If that's true, it will
   // never return null.
   nsStringBuffer* StringBuffer() const
   {
     MOZ_ASSERT(!mIsNull, "Caller should have checked IsNull() first");
@@ -92,27 +92,27 @@ public:
   uint32_t StringBufferLength() const
   {
     MOZ_ASSERT(HasStringBuffer(), "Don't call this if there is no stringbuffer");
     return mLength;
   }
 
   void SetStringBuffer(nsStringBuffer* aStringBuffer, uint32_t aLength)
   {
-    MOZ_ASSERT(mString.empty(), "We already have a string?");
+    MOZ_ASSERT(mString.isNothing(), "We already have a string?");
     MOZ_ASSERT(!mIsNull, "We're already set as null");
     MOZ_ASSERT(!mStringBuffer, "Setting stringbuffer twice?");
     MOZ_ASSERT(aStringBuffer, "Why are we getting null?");
     mStringBuffer = aStringBuffer;
     mLength = aLength;
   }
 
   void SetOwnedString(const nsAString& aString)
   {
-    MOZ_ASSERT(mString.empty(), "We already have a string?");
+    MOZ_ASSERT(mString.isNothing(), "We already have a string?");
     MOZ_ASSERT(!mIsNull, "We're already set as null");
     MOZ_ASSERT(!mStringBuffer, "Setting stringbuffer twice?");
     nsStringBuffer* buf = nsStringBuffer::FromString(aString);
     if (buf) {
       SetStringBuffer(buf, aString.Length());
     } else if (aString.IsVoid()) {
       SetNull();
     } else if (!aString.IsEmpty()) {
@@ -124,39 +124,39 @@ public:
   {
     eTreatNullAsNull,
     eTreatNullAsEmpty,
     eNullNotExpected
   };
 
   void SetOwnedAtom(nsIAtom* aAtom, NullHandling aNullHandling)
   {
-    MOZ_ASSERT(mString.empty(), "We already have a string?");
+    MOZ_ASSERT(mString.isNothing(), "We already have a string?");
     MOZ_ASSERT(!mIsNull, "We're already set as null");
     MOZ_ASSERT(!mStringBuffer, "Setting stringbuffer twice?");
     MOZ_ASSERT(aAtom || aNullHandling != eNullNotExpected);
     if (aNullHandling == eNullNotExpected || aAtom) {
       SetStringBuffer(aAtom->GetStringBuffer(), aAtom->GetLength());
     } else if (aNullHandling == eTreatNullAsNull) {
       SetNull();
     }
   }
 
   void SetNull()
   {
     MOZ_ASSERT(!mStringBuffer, "Should have no stringbuffer if null");
-    MOZ_ASSERT(mString.empty(), "Should have no string if null");
+    MOZ_ASSERT(mString.isNothing(), "Should have no string if null");
     mIsNull = true;
   }
 
   bool IsNull() const
   {
-    MOZ_ASSERT(!mStringBuffer || mString.empty(),
+    MOZ_ASSERT(!mStringBuffer || mString.isNothing(),
                "How could we have a stringbuffer and a nonempty string?");
-    return mIsNull || (!mString.empty() && mString.ref().IsVoid());
+    return mIsNull || (mString && mString->IsVoid());
   }
 
   void ToString(nsAString& aString)
   {
     if (IsNull()) {
       SetDOMStringToNull(aString);
     } else if (HasStringBuffer()) {
       if (StringBufferLength() == 0) {
--- a/dom/bindings/TypedArray.h
+++ b/dom/bindings/TypedArray.h
@@ -157,17 +157,17 @@ public:
   }
 
   static inline JSObject*
   Create(JSContext* cx, nsWrapperCache* creator, uint32_t length,
          const T* data = nullptr) {
     JS::Rooted<JSObject*> creatorWrapper(cx);
     Maybe<JSAutoCompartment> ac;
     if (creator && (creatorWrapper = creator->GetWrapperPreserveColor())) {
-      ac.construct(cx, creatorWrapper);
+      ac.emplace(cx, creatorWrapper);
     }
 
     return CreateCommon(cx, length, data);
   }
 
   static inline JSObject*
   Create(JSContext* cx, uint32_t length, const T* data = nullptr) {
     return CreateCommon(cx, length, data);
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -970,17 +970,17 @@ EventListenerManager::HandleEventInterna
   //Set the value of the internal PreventDefault flag properly based on aEventStatus
   if (*aEventStatus == nsEventStatus_eConsumeNoDefault) {
     aEvent->mFlags.mDefaultPrevented = true;
   }
 
   nsAutoTObserverArray<Listener, 2>::EndLimitedIterator iter(mListeners);
   Maybe<nsAutoPopupStatePusher> popupStatePusher;
   if (mIsMainThreadELM) {
-    popupStatePusher.construct(Event::GetEventPopupControlState(aEvent));
+    popupStatePusher.emplace(Event::GetEventPopupControlState(aEvent));
   }
 
   bool hasListener = false;
   while (iter.HasMore()) {
     if (aEvent->mFlags.mImmediatePropagationStopped) {
       break;
     }
     Listener* listener = &iter.GetNext();
--- a/dom/events/EventListenerService.cpp
+++ b/dom/events/EventListenerService.cpp
@@ -85,27 +85,27 @@ EventListenerInfo::GetJSVal(JSContext* a
 {
   aJSVal.setNull();
   nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS = do_QueryInterface(mListener);
   if (wrappedJS) {
     JS::Rooted<JSObject*> object(aCx, wrappedJS->GetJSObject());
     if (!object) {
       return false;
     }
-    aAc.construct(aCx, object);
+    aAc.emplace(aCx, object);
     aJSVal.setObject(*object);
     return true;
   }
 
   nsCOMPtr<JSEventHandler> jsHandler = do_QueryInterface(mListener);
   if (jsHandler && jsHandler->GetTypedEventHandler().HasEventHandler()) {
     JS::Handle<JSObject*> handler =
       jsHandler->GetTypedEventHandler().Ptr()->Callable();
     if (handler) {
-      aAc.construct(aCx, handler);
+      aAc.emplace(aCx, handler);
       aJSVal.setObject(*handler);
       return true;
     }
   }
   return false;
 }
 
 NS_IMETHODIMP
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -3849,18 +3849,18 @@ EventStateManager::NotifyMouseOver(Widge
   // Remember mLastOverElement as the related content for the
   // DispatchMouseOrPointerEvent() call below, since NotifyMouseOut() resets it, bug 298477.
   nsCOMPtr<nsIContent> lastOverElement = wrapper->mLastOverElement;
 
   bool isPointer = aMouseEvent->mClass == ePointerEventClass;
   
   Maybe<EnterLeaveDispatcher> enterDispatcher;
   if (dispatch) {
-    enterDispatcher.construct(this, aContent, lastOverElement, aMouseEvent,
-                              isPointer ? NS_POINTER_ENTER : NS_MOUSEENTER);
+    enterDispatcher.emplace(this, aContent, lastOverElement, aMouseEvent,
+                            isPointer ? NS_POINTER_ENTER : NS_MOUSEENTER);
   }
 
   NotifyMouseOut(aMouseEvent, aContent);
 
   // Store the first mouseOver event we fire and don't refire mouseOver
   // to that element while the first mouseOver is still ongoing.
   wrapper->mFirstOverEventElement = aContent;
 
--- a/dom/indexedDB/IDBRequest.cpp
+++ b/dom/indexedDB/IDBRequest.cpp
@@ -190,17 +190,17 @@ IDBRequest::NotifyHelperCompleted(Helper
 
   // Otherwise we need to get the result from the helper.
   AutoJSAPI jsapi;
   Maybe<JSAutoCompartment> ac;
   if (GetScriptOwner()) {
     // If we have a script owner we want the SafeJSContext and then to enter
     // the script owner's compartment.
     jsapi.Init();
-    ac.construct(jsapi.cx(), GetScriptOwner());
+    ac.emplace(jsapi.cx(), GetScriptOwner());
   } else {
     // Otherwise our owner is a window and we use that to initialize.
     if (!jsapi.InitWithLegacyErrorReporting(GetOwner())) {
       IDB_WARNING("Failed to initialise AutoJSAPI!");
       rv = NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
       SetError(rv);
       return rv;
     }
--- a/dom/src/json/nsJSON.cpp
+++ b/dom/src/json/nsJSON.cpp
@@ -176,17 +176,17 @@ WriteCallback(const jschar *buf, uint32_
 NS_IMETHODIMP
 nsJSON::EncodeFromJSVal(JS::Value *value, JSContext *cx, nsAString &result)
 {
   result.Truncate();
 
   mozilla::Maybe<JSAutoCompartment> ac;
   if (value->isObject()) {
     JS::Rooted<JSObject*> obj(cx, &value->toObject());
-    ac.construct(cx, obj);
+    ac.emplace(cx, obj);
   }
 
   nsJSONWriter writer;
   JS::Rooted<JS::Value> vp(cx, *value);
   if (!JS_Stringify(cx, &vp, JS::NullPtr(), JS::NullHandleValue, WriteCallback, &writer)) {
     return NS_ERROR_XPC_BAD_CONVERT_JS;
   }
   *value = vp;
--- a/dom/system/nsDeviceSensors.cpp
+++ b/dom/system/nsDeviceSensors.cpp
@@ -338,74 +338,74 @@ nsDeviceSensors::FireDOMMotionEvent(nsID
                                     double y,
                                     double z)
 {
   // Attempt to coalesce events
   bool fireEvent = TimeStamp::Now() > mLastDOMMotionEventTime + TimeDuration::FromMilliseconds(DEFAULT_SENSOR_POLL);
 
   switch (type) {
   case nsIDeviceSensorData::TYPE_LINEAR_ACCELERATION:
-    if (mLastAcceleration.empty()) {
-      mLastAcceleration.construct();
+    if (!mLastAcceleration) {
+      mLastAcceleration.emplace();
     }
-    mLastAcceleration.ref().mX.SetValue(x);
-    mLastAcceleration.ref().mY.SetValue(y);
-    mLastAcceleration.ref().mZ.SetValue(z);
+    mLastAcceleration->mX.SetValue(x);
+    mLastAcceleration->mY.SetValue(y);
+    mLastAcceleration->mZ.SetValue(z);
     break;
   case nsIDeviceSensorData::TYPE_ACCELERATION:
-    if (mLastAccelerationIncluduingGravity.empty()) {
-      mLastAccelerationIncluduingGravity.construct();
+    if (!mLastAccelerationIncluduingGravity) {
+      mLastAccelerationIncluduingGravity.emplace();
     }
-    mLastAccelerationIncluduingGravity.ref().mX.SetValue(x);
-    mLastAccelerationIncluduingGravity.ref().mY.SetValue(y);
-    mLastAccelerationIncluduingGravity.ref().mZ.SetValue(z);
+    mLastAccelerationIncluduingGravity->mX.SetValue(x);
+    mLastAccelerationIncluduingGravity->mY.SetValue(y);
+    mLastAccelerationIncluduingGravity->mZ.SetValue(z);
     break;
   case nsIDeviceSensorData::TYPE_GYROSCOPE:
-    if (mLastRotationRate.empty()) {
-      mLastRotationRate.construct();
+    if (!mLastRotationRate) {
+      mLastRotationRate.emplace();
     }
-    mLastRotationRate.ref().mAlpha.SetValue(x);
-    mLastRotationRate.ref().mBeta.SetValue(y);
-    mLastRotationRate.ref().mGamma.SetValue(z);
+    mLastRotationRate->mAlpha.SetValue(x);
+    mLastRotationRate->mBeta.SetValue(y);
+    mLastRotationRate->mGamma.SetValue(z);
     break;
   }
 
   if (fireEvent) {
-    if (mLastAcceleration.empty()) {
-      mLastAcceleration.construct();
+    if (!mLastAcceleration) {
+      mLastAcceleration.emplace();
     }
-    if (mLastAccelerationIncluduingGravity.empty()) {
-      mLastAccelerationIncluduingGravity.construct();
+    if (!mLastAccelerationIncluduingGravity) {
+      mLastAccelerationIncluduingGravity.emplace();
     }
-    if (mLastRotationRate.empty()) {
-      mLastRotationRate.construct();
+    if (!mLastRotationRate) {
+      mLastRotationRate.emplace();
     }
-  } else if (mLastAcceleration.empty() ||
-             mLastAccelerationIncluduingGravity.empty() ||
-             mLastRotationRate.empty()) {
+  } else if (!mLastAcceleration ||
+             !mLastAccelerationIncluduingGravity ||
+             !mLastRotationRate) {
     return;
   }
 
   nsCOMPtr<nsIDOMEvent> event;
   domdoc->CreateEvent(NS_LITERAL_STRING("DeviceMotionEvent"), getter_AddRefs(event));
 
   DeviceMotionEvent* me = static_cast<DeviceMotionEvent*>(event.get());
 
   ErrorResult rv;
   me->InitDeviceMotionEvent(NS_LITERAL_STRING("devicemotion"),
                             true,
                             false,
-                            mLastAcceleration.ref(),
-                            mLastAccelerationIncluduingGravity.ref(),
-                            mLastRotationRate.ref(),
+                            *mLastAcceleration,
+                            *mLastAccelerationIncluduingGravity,
+                            *mLastRotationRate,
                             Nullable<double>(DEFAULT_SENSOR_POLL),
                             rv);
 
   event->SetTrusted(true);
 
   bool defaultActionEnabled = true;
   target->DispatchEvent(event, &defaultActionEnabled);
 
-  mLastRotationRate.destroy();
-  mLastAccelerationIncluduingGravity.destroy();
-  mLastAcceleration.destroy();
+  mLastRotationRate.reset();
+  mLastAccelerationIncluduingGravity.reset();
+  mLastAcceleration.reset();
   mLastDOMMotionEventTime = TimeStamp::Now();
 }
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -3625,27 +3625,27 @@ WorkerPrivate::Constructor(JSContext* aC
 
   MOZ_ASSERT_IF(aWorkerType != WorkerTypeDedicated,
                 !aSharedWorkerName.IsVoid());
   MOZ_ASSERT_IF(aWorkerType == WorkerTypeDedicated,
                 aSharedWorkerName.IsEmpty());
 
   Maybe<LoadInfo> stackLoadInfo;
   if (!aLoadInfo) {
-    stackLoadInfo.construct();
+    stackLoadInfo.emplace();
 
     nsresult rv = GetLoadInfo(aCx, nullptr, parent, aScriptURL,
-                              aIsChromeWorker, stackLoadInfo.addr());
+                              aIsChromeWorker, stackLoadInfo.ptr());
     if (NS_FAILED(rv)) {
       scriptloader::ReportLoadError(aCx, aScriptURL, rv, !parent);
       aRv.Throw(rv);
       return nullptr;
     }
 
-    aLoadInfo = stackLoadInfo.addr();
+    aLoadInfo = stackLoadInfo.ptr();
   }
 
   // NB: This has to be done before creating the WorkerPrivate, because it will
   // attempt to use static variables that are initialized in the RuntimeService
   // constructor.
   RuntimeService* runtimeService;
 
   if (!parent) {
@@ -3934,19 +3934,19 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
 
   InitializeGCTimers();
 
   Maybe<JSAutoCompartment> workerCompartment;
 
   for (;;) {
     // Workers lazily create a global object in CompileScriptRunnable. We need
     // to enter the global's compartment as soon as it has been created.
-    if (workerCompartment.empty()) {
+    if (!workerCompartment) {
       if (JSObject* global = js::DefaultObjectForContextOrNull(aCx)) {
-        workerCompartment.construct(aCx, global);
+        workerCompartment.emplace(aCx, global);
       }
     }
 
     Status currentStatus;
     bool normalRunnablesPending = false;
 
     {
       MutexAutoLock lock(mMutex);
@@ -4023,17 +4023,17 @@ WorkerPrivate::DoRunLoop(JSContext* aCx)
     // Start the periodic GC timer if it is not already running.
     SetGCTimerMode(PeriodicTimer);
 
     // Process a single runnable from the main queue.
     MOZ_ALWAYS_TRUE(NS_ProcessNextEvent(mThread, false));
 
     if (NS_HasPendingEvents(mThread)) {
       // Now *might* be a good time to GC. Let the JS engine make the decision.
-      if (!workerCompartment.empty()) {
+      if (workerCompartment) {
         JS_MaybeGC(aCx);
       }
     }
     else {
       // The normal event queue has been exhausted, cancel the periodic GC timer
       // and schedule the idle GC timer.
       SetGCTimerMode(IdleTimer);
     }
--- a/dom/workers/WorkerRunnable.cpp
+++ b/dom/workers/WorkerRunnable.cpp
@@ -97,17 +97,17 @@ WorkerRunnable::Dispatch(JSContext* aCx)
   }
 
   JSAutoRequest ar(aCx);
 
   JS::Rooted<JSObject*> global(aCx, JS::CurrentGlobalOrNull(aCx));
 
   Maybe<JSAutoCompartment> ac;
   if (global) {
-    ac.construct(aCx, global);
+    ac.emplace(aCx, global);
   }
 
   ok = PreDispatch(aCx, mWorkerPrivate);
 
   if (ok && !DispatchInternal()) {
     ok = false;
   }
 
@@ -303,38 +303,38 @@ WorkerRunnable::Run()
   // this is OK as we won't be running script in these circumstances.
   // It's important that aes is declared after jsapi, because if WorkerRun
   // creates a global then we construct aes before PostRun and we need them to
   // be destroyed in the correct order.
   mozilla::dom::AutoJSAPI jsapi;
   Maybe<mozilla::dom::AutoEntryScript> aes;
   JSContext* cx;
   if (globalObject) {
-    aes.construct(globalObject, isMainThread, isMainThread ? nullptr :
-                                              GetCurrentThreadJSContext());
-    cx = aes.ref().cx();
+    aes.emplace(globalObject, isMainThread, isMainThread ? nullptr :
+                                            GetCurrentThreadJSContext());
+    cx = aes->cx();
   } else {
     jsapi.Init();
     cx = jsapi.cx();
   }
 
   // If we're not on the worker thread we'll either be in our parent's
   // compartment or the null compartment, so we need to enter our own.
   Maybe<JSAutoCompartment> ac;
   if (!targetIsWorkerThread && mWorkerPrivate->GetWrapper()) {
-    ac.construct(cx, mWorkerPrivate->GetWrapper());
+    ac.emplace(cx, mWorkerPrivate->GetWrapper());
   }
 
   bool result = WorkerRun(cx, mWorkerPrivate);
 
   // In the case of CompileScriptRunnnable, WorkerRun above can cause us to
   // lazily create a global, so we construct aes here before calling PostRun.
-  if (targetIsWorkerThread && aes.empty() && mWorkerPrivate->GlobalScope()) {
-    aes.construct(mWorkerPrivate->GlobalScope(), false, GetCurrentThreadJSContext());
-    cx = aes.ref().cx();
+  if (targetIsWorkerThread && !aes && mWorkerPrivate->GlobalScope()) {
+    aes.emplace(mWorkerPrivate->GlobalScope(), false, GetCurrentThreadJSContext());
+    cx = aes->cx();
   }
 
   PostRun(cx, mWorkerPrivate, result);
 
   return result ? NS_OK : NS_ERROR_FAILURE;
 }
 
 NS_IMETHODIMP
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -1844,41 +1844,41 @@ XMLHttpRequest::SendInternal(const nsASt
   }
 
   AutoUnpinXHR autoUnpin(this);
   Maybe<AutoSyncLoopHolder> autoSyncLoop;
 
   nsCOMPtr<nsIEventTarget> syncLoopTarget;
   bool isSyncXHR = mProxy->mIsSyncXHR;
   if (isSyncXHR) {
-    autoSyncLoop.construct(mWorkerPrivate);
-    syncLoopTarget = autoSyncLoop.ref().EventTarget();
+    autoSyncLoop.emplace(mWorkerPrivate);
+    syncLoopTarget = autoSyncLoop->EventTarget();
   }
 
   mProxy->mOuterChannelId++;
 
   JSContext* cx = mWorkerPrivate->GetJSContext();
 
   nsRefPtr<SendRunnable> runnable =
     new SendRunnable(mWorkerPrivate, mProxy, aStringBody, Move(aBody),
                      aClonedObjects, syncLoopTarget, hasUploadListeners);
   if (!runnable->Dispatch(cx)) {
     aRv.Throw(NS_ERROR_FAILURE);
     return;
   }
 
   if (!isSyncXHR)  {
     autoUnpin.Clear();
-    MOZ_ASSERT(autoSyncLoop.empty());
+    MOZ_ASSERT(!autoSyncLoop);
     return;
   }
 
   autoUnpin.Clear();
 
-  if (!autoSyncLoop.ref().Run()) {
+  if (!autoSyncLoop->Run()) {
     aRv.Throw(NS_ERROR_FAILURE);
   }
 }
 
 bool
 XMLHttpRequest::Notify(JSContext* aCx, Status aStatus)
 {
   mWorkerPrivate->AssertIsOnWorkerThread();