Merge inbound to mozilla-central a=merge on a CLOSED TREE
authorCoroiu Cristina <ccoroiu@mozilla.com>
Sun, 17 Jun 2018 12:46:32 +0300
changeset 479529 c40cc0a89bc70511751d17ed0cdd569a74abac88
parent 479520 f527be41b97db03959f4c8116e5f76f58d49a1a5 (current diff)
parent 479528 ceec781c0e837ddfbb19a4979ffbb009dfc5edd4 (diff)
child 479535 de04d47566e1cf680adddb00737c41e510ed7c63
child 479540 61882e8a3cf3ffe6a23f90f54d6cd6091f0b6544
push id1757
push userffxbld-merge
push dateFri, 24 Aug 2018 17:02:43 +0000
treeherdermozilla-release@736023aebdb1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone62.0a1
first release with
nightly linux32
c40cc0a89bc7 / 62.0a1 / 20180617100056 / files
nightly linux64
c40cc0a89bc7 / 62.0a1 / 20180617100056 / files
nightly mac
c40cc0a89bc7 / 62.0a1 / 20180617100056 / files
nightly win32
c40cc0a89bc7 / 62.0a1 / 20180617100056 / files
nightly win64
c40cc0a89bc7 / 62.0a1 / 20180617100056 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge inbound to mozilla-central a=merge on a CLOSED TREE
--- a/dom/base/TabGroup.cpp
+++ b/dom/base/TabGroup.cpp
@@ -4,38 +4,46 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/dom/TabGroup.h"
 
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/TabChild.h"
 #include "mozilla/dom/DocGroup.h"
+#include "mozilla/dom/TimeoutManager.h"
 #include "mozilla/AbstractThread.h"
 #include "mozilla/ClearOnShutdown.h"
 #include "mozilla/StaticPtr.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/ThrottledEventQueue.h"
 #include "nsIDocShell.h"
 #include "nsIEffectiveTLDService.h"
 #include "nsIURI.h"
 
 namespace mozilla {
 namespace dom {
 
 static StaticRefPtr<TabGroup> sChromeTabGroup;
 
+LinkedList<TabGroup>* TabGroup::sTabGroups = nullptr;
+
 TabGroup::TabGroup(bool aIsChrome)
  : mLastWindowLeft(false)
  , mThrottledQueuesInitialized(false)
  , mNumOfIndexedDBTransactions(0)
  , mNumOfIndexedDBDatabases(0)
  , mIsChrome(aIsChrome)
  , mForegroundCount(0)
 {
+  if (!sTabGroups) {
+    sTabGroups = new LinkedList<TabGroup>();
+  }
+  sTabGroups->insertBack(this);
+
   CreateEventTargets(/* aNeedValidation = */ !aIsChrome);
 
   // Do not throttle runnables from chrome windows.  In theory we should
   // not have abuse issues from these windows and many browser chrome
   // tests have races that fail if we do throttle chrome runnables.
   if (aIsChrome) {
     MOZ_ASSERT(!sChromeTabGroup);
     return;
@@ -49,16 +57,25 @@ TabGroup::TabGroup(bool aIsChrome)
   }
 }
 
 TabGroup::~TabGroup()
 {
   MOZ_ASSERT(mDocGroups.IsEmpty());
   MOZ_ASSERT(mWindows.IsEmpty());
   MOZ_RELEASE_ASSERT(mLastWindowLeft || mIsChrome);
+
+  LinkedListElement<TabGroup>* listElement =
+    static_cast<LinkedListElement<TabGroup>*>(this);
+  listElement->remove();
+
+  if (sTabGroups->isEmpty()) {
+    delete sTabGroups;
+    sTabGroups = nullptr;
+  }
 }
 
 void
 TabGroup::EnsureThrottledEventQueues()
 {
   if (mThrottledQueuesInitialized) {
     return;
   }
@@ -318,10 +335,42 @@ TabGroup::Count(bool aActiveOnly) const
     if (iter.Get()->mDocGroup->IsActive()) {
       ++count;
     }
   }
 
   return count;
 }
 
+/*static*/ bool
+TabGroup::HasOnlyThrottableTabs()
+{
+  if (!sTabGroups) {
+    return false;
+  }
+
+  for (TabGroup* tabGroup = sTabGroups->getFirst(); tabGroup;
+       tabGroup =
+         static_cast<LinkedListElement<TabGroup>*>(tabGroup)->getNext()) {
+    for (auto iter = tabGroup->Iter(); !iter.Done(); iter.Next()) {
+      DocGroup* docGroup = iter.Get()->mDocGroup;
+      for (auto* documentInDocGroup : *docGroup) {
+        if (documentInDocGroup->IsCurrentActiveDocument()) {
+          nsPIDOMWindowInner* win =
+            documentInDocGroup->GetInnerWindow();
+          if (win && win->IsCurrentInnerWindow()) {
+            nsPIDOMWindowOuter* outer = win->GetOuterWindow();
+            if (outer) {
+              TimeoutManager& tm = win->TimeoutManager();
+              if (!tm.BudgetThrottlingEnabled(outer->IsBackground())) {
+                return false;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+  return true;
+}
+
 } // namespace dom
 } // namespace mozilla
--- a/dom/base/TabGroup.h
+++ b/dom/base/TabGroup.h
@@ -41,17 +41,18 @@ class TabChild;
 // more detail, a DocGroup is actually a collection of documents, and a
 // TabGroup is a collection of DocGroups. A TabGroup typically will contain
 // (through its DocGroups) the documents from one or more tabs related by
 // window.opener. A DocGroup is a member of exactly one TabGroup.
 
 class DocGroup;
 class TabChild;
 
-class TabGroup final : public SchedulerGroup
+class TabGroup final : public SchedulerGroup,
+                       public LinkedListElement<TabGroup>
 {
 private:
   class HashEntry : public nsCStringHashKey
   {
   public:
     // NOTE: Weak reference. The DocGroup destructor removes itself from its
     // owning TabGroup.
     DocGroup* mDocGroup;
@@ -141,16 +142,26 @@ public:
     return mNumOfIndexedDBTransactions;
   }
 
   Atomic<uint32_t>& IndexedDBDatabaseCounter()
   {
     return mNumOfIndexedDBDatabases;
   }
 
+  static LinkedList<TabGroup>* GetTabGroupList()
+  {
+    return sTabGroups;
+  }
+
+  // This returns true if all the window objects in all the TabGroups are
+  // either inactive (for example in bfcache) or are in background tabs which
+  // can be throttled.
+  static bool HasOnlyThrottableTabs();
+
 private:
   virtual AbstractThread*
   AbstractMainThreadForImpl(TaskCategory aCategory) override;
 
   TabGroup* AsTabGroup() override { return this; }
 
   void EnsureThrottledEventQueues();
 
@@ -162,14 +173,16 @@ private:
   Atomic<uint32_t> mNumOfIndexedDBTransactions;
   Atomic<uint32_t> mNumOfIndexedDBDatabases;
   const bool mIsChrome;
 
   // Main thread only
   DocGroupMap mDocGroups;
   nsTArray<nsPIDOMWindowOuter*> mWindows;
   uint32_t mForegroundCount;
+
+  static LinkedList<TabGroup>* sTabGroups;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // defined(TabGroup_h)
--- a/dom/base/TimeoutManager.h
+++ b/dom/base/TimeoutManager.h
@@ -106,16 +106,18 @@ public:
   }
 
   void BeginSyncOperation();
   void EndSyncOperation();
 
   nsIEventTarget*
   EventTarget();
 
+  bool BudgetThrottlingEnabled(bool aIsBackground) const;
+
   static const uint32_t InvalidFiringId;
 
 private:
   void MaybeStartThrottleTimeout();
 
   // Return true if |aTimeout| needs to be reinserted into the timeout list.
   bool RescheduleTimeout(mozilla::dom::Timeout* aTimeout,
                          const TimeStamp& aLastCallbackTime,
@@ -144,18 +146,16 @@ private:
                          const TimeStamp& aNow = TimeStamp::Now());
 
   void RecordExecution(Timeout* aRunningTimeout,
                        Timeout* aTimeout);
 
   void UpdateBudget(const TimeStamp& aNow,
                     const TimeDuration& aDuration = TimeDuration());
 
-  bool BudgetThrottlingEnabled(bool aIsBackground) const;
-
 private:
   struct Timeouts {
     explicit Timeouts(const TimeoutManager& aManager)
       : mManager(aManager)
     {
     }
 
     // Insert aTimeout into the list, before all timeouts that would
--- a/dom/smil/nsSMILKeySpline.h
+++ b/dom/smil/nsSMILKeySpline.h
@@ -11,26 +11,37 @@
 #include "mozilla/PodOperations.h"
 
 /**
  * Utility class to provide scaling defined in a keySplines element.
  */
 class nsSMILKeySpline
 {
 public:
-  nsSMILKeySpline() { /* caller must call Init later */ }
+  nsSMILKeySpline()
+    : mX1(0)
+    , mY1(0)
+    , mX2(0)
+    , mY2(0)
+  { 
+    /* caller must call Init later */\
+  }
 
   /**
    * Creates a new key spline control point description.
    *
    * aX1, etc. are the x1, y1, x2, y2 cubic Bezier control points as defined by
    * SMILANIM 3.2.3. They must each be in the range 0.0 <= x <= 1.0
    */
   nsSMILKeySpline(double aX1, double aY1,
                   double aX2, double aY2)
+    : mX1(0)
+    , mY1(0)
+    , mX2(0)
+    , mY2(0)
   {
     Init(aX1, aY1, aX2, aY2);
   }
 
   double X1() const { return mX1; }
   double Y1() const { return mY1; }
   double X2() const { return mX2; }
   double Y2() const { return mY2; }
--- a/dom/smil/nsSMILValue.cpp
+++ b/dom/smil/nsSMILValue.cpp
@@ -9,16 +9,17 @@
 #include <string.h>
 
 //----------------------------------------------------------------------
 // Public methods
 
 nsSMILValue::nsSMILValue(const nsISMILType* aType)
   : mType(nsSMILNullType::Singleton())
 {
+  mU.mBool = false;
   if (!aType) {
     NS_ERROR("Trying to construct nsSMILValue with null mType pointer");
     return;
   }
 
   InitAndCheckPostcondition(aType);
 }
 
--- a/dom/svg/DOMSVGPathSegList.h
+++ b/dom/svg/DOMSVGPathSegList.h
@@ -225,17 +225,20 @@ private:
    * store the indexes into the internal SVGPathData of the internal seg data
    * that our DOMSVGPathSeg items wrap (the internal segment data is or varying
    * length, so we can't just use the index of our DOMSVGPathSeg items
    * themselves). The reason that we have this separate struct rather than
    * just storing the internal indexes in the DOMSVGPathSeg items is because we
    * want to create the DOMSVGPathSeg items lazily on demand.
    */
   struct ItemProxy {
-    ItemProxy(){}
+    ItemProxy()
+      : mItem(nullptr)
+      , mInternalDataIndex(0)
+    {}
     ItemProxy(DOMSVGPathSeg *aItem, uint32_t aInternalDataIndex)
       : mItem(aItem)
       , mInternalDataIndex(aInternalDataIndex)
     {}
 
     DOMSVGPathSeg *mItem;
     uint32_t mInternalDataIndex;
   };
--- a/dom/svg/SVGAnimatedNumberList.h
+++ b/dom/svg/SVGAnimatedNumberList.h
@@ -38,17 +38,19 @@ class SVGAnimationElement;
  */
 class SVGAnimatedNumberList
 {
   // friends so that they can get write access to mBaseVal
   friend class DOMSVGNumber;
   friend class DOMSVGNumberList;
 
 public:
-  SVGAnimatedNumberList() {}
+  SVGAnimatedNumberList()
+    : mIsBaseSet(false)
+  {}
 
   /**
    * Because it's so important that mBaseVal and its DOMSVGNumberList wrapper
    * (if any) be kept in sync (see the comment in
    * DOMSVGAnimatedNumberList::InternalBaseValListWillChangeTo), this method
    * returns a const reference. Only our friend classes may get mutable
    * references to mBaseVal.
    */
--- a/dom/svg/SVGGeometryElement.h
+++ b/dom/svg/SVGGeometryElement.h
@@ -107,17 +107,21 @@ public:
 
   /**
    * For use with GetAsSimplePath.
    */
   class SimplePath
   {
   public:
     SimplePath()
-      : mType(NONE)
+      : mX(0.0)
+      , mY(0.0)
+      , mWidthOrX2(0.0)
+      , mHeightOrY2(0.0)
+      , mType(NONE)
     {}
     bool IsPath() const {
       return mType != NONE;
     }
     void SetRect(Float x, Float y, Float width, Float height) {
       mX = x;
       mY = y;
       mWidthOrX2 = width;
--- a/dom/svg/SVGLength.h
+++ b/dom/svg/SVGLength.h
@@ -28,20 +28,18 @@ namespace mozilla {
  *
  * The DOM wrapper class for this class is DOMSVGLength.
  */
 class SVGLength
 {
 public:
 
   SVGLength()
-#ifdef DEBUG
     : mValue(0.0f)
     , mUnit(dom::SVGLengthBinding::SVG_LENGTHTYPE_UNKNOWN) // caught by IsValid()
-#endif
   {}
 
   SVGLength(float aValue, uint8_t aUnit)
     : mValue(aValue)
     , mUnit(aUnit)
   {
     NS_ASSERTION(IsValid(), "Constructed an invalid length");
   }
--- a/dom/svg/SVGLengthList.h
+++ b/dom/svg/SVGLengthList.h
@@ -306,16 +306,18 @@ private:
  * numeric_limits<float>::quiet_NaN().
  */
 class MOZ_STACK_CLASS SVGUserUnitList
 {
 public:
 
   SVGUserUnitList()
     : mList(nullptr)
+    , mElement(nullptr)
+    , mAxis(0)
   {}
 
   void Init(const SVGLengthList *aList, nsSVGElement *aElement, uint8_t aAxis) {
     mList = aList;
     mElement = aElement;
     mAxis = aAxis;
   }
 
--- a/dom/svg/SVGMotionSMILType.cpp
+++ b/dom/svg/SVGMotionSMILType.cpp
@@ -59,17 +59,20 @@ struct PathPointParams {  // Point along
  * from a path (e.g. when accumulating a repeated animation) will generally
  * take you to an arbitrary point *off* of the path.
  */
 struct MotionSegment
 {
   // Default constructor just locks us into being a Translation, and leaves
   // other fields uninitialized (since client is presumably about to set them)
   MotionSegment()
-    : mSegmentType(eSegmentType_Translation)
+    : mRotateType(eRotateType_Auto),
+      mRotateAngle(0.0),
+      mSegmentType(eSegmentType_Translation),
+      mU{}
   { }
 
   // Constructor for a translation
   MotionSegment(float aX, float aY, float aRotateAngle)
     : mRotateType(eRotateType_Explicit), mRotateAngle(aRotateAngle),
       mSegmentType(eSegmentType_Translation)
   {
     mU.mTranslationParams.mX = aX;
--- a/dom/svg/nsSVGViewBox.h
+++ b/dom/svg/nsSVGViewBox.h
@@ -27,17 +27,23 @@ class SVGAnimationElement;
 } // namespace mozilla
 
 struct nsSVGViewBoxRect
 {
   float x, y;
   float width, height;
   bool none;
 
-  nsSVGViewBoxRect() : none(true) {}
+  nsSVGViewBoxRect()
+    : x(0.0)
+    , y(0.0)
+    , width(0.0)
+    , height(0.0)
+    , none(true)
+  {}
   nsSVGViewBoxRect(float aX, float aY, float aWidth, float aHeight) :
     x(aX), y(aY), width(aWidth), height(aHeight), none(false) {}
   nsSVGViewBoxRect(const nsSVGViewBoxRect& rhs) :
     x(rhs.x), y(rhs.y), width(rhs.width), height(rhs.height), none(rhs.none) {}
   bool operator==(const nsSVGViewBoxRect& aOther) const;
 
   static nsresult FromString(const nsAString& aStr, nsSVGViewBoxRect *aViewBox);
 };
--- a/js/src/builtin/ReflectParse.cpp
+++ b/js/src/builtin/ReflectParse.cpp
@@ -277,18 +277,17 @@ class NodeBuilder
                 return false;
 
             if (funv.isNullOrUndefined()) {
                 callbacks[i].setNull();
                 continue;
             }
 
             if (!funv.isObject() || !funv.toObject().is<JSFunction>()) {
-                ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_NOT_FUNCTION,
-                                      JSDVG_SEARCH_STACK, funv, nullptr, nullptr, nullptr);
+                ReportValueError(cx, JSMSG_NOT_FUNCTION, JSDVG_SEARCH_STACK, funv, nullptr);
                 return false;
             }
 
             callbacks[i].set(funv);
         }
 
         return true;
     }
@@ -3357,19 +3356,18 @@ reflect_parse(JSContext* cx, uint32_t ar
     bool loc = true;
     RootedObject builder(cx);
     ParseGoal target = ParseGoal::Script;
 
     RootedValue arg(cx, args.get(1));
 
     if (!arg.isNullOrUndefined()) {
         if (!arg.isObject()) {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                                  JSDVG_SEARCH_STACK, arg, nullptr,
-                                  "not an object", nullptr);
+            ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, arg, nullptr,
+                             "not an object");
             return false;
         }
 
         RootedObject config(cx, &arg.toObject());
 
         RootedValue prop(cx);
 
         /* config.loc */
@@ -3409,33 +3407,32 @@ reflect_parse(JSContext* cx, uint32_t ar
         /* config.builder */
         RootedId builderId(cx, NameToId(cx->names().builder));
         RootedValue nullVal(cx, NullValue());
         if (!GetPropertyDefault(cx, config, builderId, nullVal, &prop))
             return false;
 
         if (!prop.isNullOrUndefined()) {
             if (!prop.isObject()) {
-                ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                                      JSDVG_SEARCH_STACK, prop, nullptr,
-                                      "not an object", nullptr);
+                ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, prop, nullptr,
+                                 "not an object");
                 return false;
             }
             builder = &prop.toObject();
         }
 
         /* config.target */
         RootedId targetId(cx, NameToId(cx->names().target));
         RootedValue scriptVal(cx, StringValue(cx->names().script));
         if (!GetPropertyDefault(cx, config, targetId, scriptVal, &prop))
             return false;
 
         if (!prop.isString()) {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK,
-                                  prop, nullptr, "not 'script' or 'module'", nullptr);
+            ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, prop, nullptr,
+                             "not 'script' or 'module'");
             return false;
         }
 
         RootedString stringProp(cx, prop.toString());
         bool isScript = false;
         bool isModule = false;
         if (!EqualStrings(cx, stringProp, cx->names().script, &isScript))
             return false;
--- a/js/src/builtin/Stream.cpp
+++ b/js/src/builtin/Stream.cpp
@@ -265,27 +265,25 @@ static MOZ_MUST_USE JSObject*
 PromiseRejectedWithPendingError(JSContext* cx) {
     // Not much we can do about uncatchable exceptions, just bail.
     RootedValue exn(cx);
     if (!GetAndClearException(cx, &exn))
         return nullptr;
     return PromiseObject::unforgeableReject(cx, exn);
 }
 
-static bool
-ReportArgTypeError(JSContext* cx, const char* funName, const char* expectedType,
-                   HandleValue arg)
+static void
+ReportArgTypeError(JSContext* cx, const char* funName, const char* expectedType, HandleValue arg)
 {
     UniqueChars bytes = DecompileValueGenerator(cx, JSDVG_SEARCH_STACK, arg, nullptr);
     if (!bytes)
-        return false;
-
-    return JS_ReportErrorFlagsAndNumberLatin1(cx, JSREPORT_ERROR, GetErrorMessage,
-                                              nullptr, JSMSG_NOT_EXPECTED_TYPE,
-                                              funName, expectedType, bytes.get());
+        return;
+
+    JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NOT_EXPECTED_TYPE, funName,
+                               expectedType, bytes.get());
 }
 
 static MOZ_MUST_USE bool
 RejectWithPendingError(JSContext* cx, Handle<PromiseObject*> promise) {
     // Not much we can do about uncatchable exceptions, just bail.
     RootedValue exn(cx);
     if (!GetAndClearException(cx, &exn))
         return false;
@@ -302,18 +300,18 @@ ReturnPromiseRejectedWithPendingError(JS
     args.rval().setObject(*promise);
     return true;
 }
 
 static MOZ_MUST_USE bool
 RejectNonGenericMethod(JSContext* cx, const CallArgs& args,
                        const char* className, const char* methodName)
 {
-    ReportValueError3(cx, JSMSG_INCOMPATIBLE_PROTO, JSDVG_SEARCH_STACK, args.thisv(),
-                      nullptr, className, methodName);
+    ReportValueError(cx, JSMSG_INCOMPATIBLE_PROTO, JSDVG_SEARCH_STACK, args.thisv(),
+                     nullptr, className, methodName);
 
     return ReturnPromiseRejectedWithPendingError(cx, args);
 }
 
 inline static MOZ_MUST_USE NativeObject*
 SetNewList(JSContext* cx, HandleNativeObject container, uint32_t slot)
 {
     NativeObject* list = NewList(cx);
@@ -798,18 +796,18 @@ ReadableStream_locked(JSContext* cx, uns
 // Streams spec, 3.2.4.2. cancel ( reason )
 static MOZ_MUST_USE bool
 ReadableStream_cancel(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
     // Step 1: If ! IsReadableStream(this) is false, return a promise rejected
     //         with a TypeError exception.
     if (!Is<ReadableStream>(args.thisv())) {
-        ReportValueError3(cx, JSMSG_INCOMPATIBLE_PROTO, JSDVG_SEARCH_STACK, args.thisv(),
-                          nullptr, "cancel", "");
+        ReportValueError(cx, JSMSG_INCOMPATIBLE_PROTO, JSDVG_SEARCH_STACK, args.thisv(),
+                         nullptr, "cancel", "");
         return ReturnPromiseRejectedWithPendingError(cx, args);
     }
 
     Rooted<ReadableStream*> stream(cx, &args.thisv().toObject().as<ReadableStream>());
 
     // Step 2: If ! IsReadableStreamLocked(this) is true, return a promise
     //         rejected with a TypeError exception.
     if (stream->locked()) {
--- a/js/src/builtin/Symbol.cpp
+++ b/js/src/builtin/Symbol.cpp
@@ -145,18 +145,18 @@ SymbolObject::for_(JSContext* cx, unsign
 bool
 SymbolObject::keyFor(JSContext* cx, unsigned argc, Value* vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     // step 1
     HandleValue arg = args.get(0);
     if (!arg.isSymbol()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK,
-                              arg, nullptr, "not a symbol", nullptr);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, arg, nullptr,
+                         "not a symbol");
         return false;
     }
 
     // step 2
     if (arg.toSymbol()->code() == JS::SymbolCode::InSymbolRegistry) {
 #ifdef DEBUG
         RootedString desc(cx, arg.toSymbol()->description());
         MOZ_ASSERT(Symbol::for_(cx, desc) == arg.toSymbol());
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -1299,32 +1299,30 @@ SaveStack(JSContext* cx, unsigned argc, 
     CallArgs args = CallArgsFromVp(argc, vp);
 
     JS::StackCapture capture((JS::AllFrames()));
     if (args.length() >= 1) {
         double maxDouble;
         if (!ToNumber(cx, args[0], &maxDouble))
             return false;
         if (mozilla::IsNaN(maxDouble) || maxDouble < 0 || maxDouble > UINT32_MAX) {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                                  JSDVG_SEARCH_STACK, args[0], nullptr,
-                                  "not a valid maximum frame count", NULL);
+            ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[0], nullptr,
+                             "not a valid maximum frame count");
             return false;
         }
         uint32_t max = uint32_t(maxDouble);
         if (max > 0)
             capture = JS::StackCapture(JS::MaxFrames(max));
     }
 
     RootedObject compartmentObject(cx);
     if (args.length() >= 2) {
         if (!args[1].isObject()) {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                                  JSDVG_SEARCH_STACK, args[0], nullptr,
-                                  "not an object", NULL);
+            ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[0], nullptr,
+                             "not an object");
             return false;
         }
         compartmentObject = UncheckedUnwrap(&args[1].toObject());
         if (!compartmentObject)
             return false;
     }
 
     RootedObject stack(cx);
@@ -3588,26 +3586,24 @@ FindPath(JSContext* cx, unsigned argc, V
                                   "findPath", "1", "");
         return false;
     }
 
     // We don't ToString non-objects given as 'start' or 'target', because this
     // test is all about object identity, and ToString doesn't preserve that.
     // Non-GCThing endpoints don't make much sense.
     if (!args[0].isObject() && !args[0].isString() && !args[0].isSymbol()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                              JSDVG_SEARCH_STACK, args[0], nullptr,
-                              "not an object, string, or symbol", NULL);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[0], nullptr,
+                         "not an object, string, or symbol");
         return false;
     }
 
     if (!args[1].isObject() && !args[1].isString() && !args[1].isSymbol()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                              JSDVG_SEARCH_STACK, args[0], nullptr,
-                              "not an object, string, or symbol", NULL);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[0], nullptr,
+                         "not an object, string, or symbol");
         return false;
     }
 
     Rooted<GCVector<Value>> nodes(cx, GCVector<Value>(cx));
     Vector<heaptools::EdgeName> edges(cx);
 
     {
         // We can't tolerate the GC moving things around while we're searching
@@ -3693,53 +3689,49 @@ ShortestPaths(JSContext* cx, unsigned ar
     CallArgs args = CallArgsFromVp(argc, vp);
     if (!args.requireAtLeast(cx, "shortestPaths", 3))
         return false;
 
     // We don't ToString non-objects given as 'start' or 'target', because this
     // test is all about object identity, and ToString doesn't preserve that.
     // Non-GCThing endpoints don't make much sense.
     if (!args[0].isObject() && !args[0].isString() && !args[0].isSymbol()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                              JSDVG_SEARCH_STACK, args[0], nullptr,
-                              "not an object, string, or symbol", nullptr);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[0], nullptr,
+                         "not an object, string, or symbol");
         return false;
     }
 
     if (!args[1].isObject() || !args[1].toObject().is<ArrayObject>()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                              JSDVG_SEARCH_STACK, args[1], nullptr,
-                              "not an array object", nullptr);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[1], nullptr,
+                         "not an array object");
         return false;
     }
 
     RootedArrayObject objs(cx, &args[1].toObject().as<ArrayObject>());
     size_t length = objs->getDenseInitializedLength();
     if (length == 0) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                              JSDVG_SEARCH_STACK, args[1], nullptr,
-                              "not a dense array object with one or more elements", nullptr);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[1], nullptr,
+                         "not a dense array object with one or more elements");
         return false;
     }
 
     for (size_t i = 0; i < length; i++) {
         RootedValue el(cx, objs->getDenseElement(i));
         if (!el.isObject() && !el.isString() && !el.isSymbol()) {
             JS_ReportErrorASCII(cx, "Each target must be an object, string, or symbol");
             return false;
         }
     }
 
     int32_t maxNumPaths;
     if (!JS::ToInt32(cx, args[2], &maxNumPaths))
         return false;
     if (maxNumPaths <= 0) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                              JSDVG_SEARCH_STACK, args[2], nullptr,
-                              "not greater than 0", nullptr);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, args[2], nullptr,
+                         "not greater than 0");
         return false;
     }
 
     // We accumulate the results into a GC-stable form, due to the fact that the
     // JS::ubi::ShortestPaths lifetime (when operating on the live heap graph)
     // is bounded within an AutoCheckCannotGC.
     Rooted<GCVector<GCVector<GCVector<Value>>>> values(cx, GCVector<GCVector<GCVector<Value>>>(cx));
     Vector<Vector<Vector<JS::ubi::EdgeName>>> names(cx);
--- a/js/src/ctypes/CTypes.cpp
+++ b/js/src/ctypes/CTypes.cpp
@@ -92,20 +92,18 @@ GetDeflatedUTF8StringLength(JSContext* m
     }
     return nbytes;
 
   bad_surrogate:
     if (maybecx) {
         js::gc::AutoSuppressGC suppress(maybecx);
         char buffer[10];
         SprintfLiteral(buffer, "0x%x", c);
-        JS_ReportErrorFlagsAndNumberASCII(maybecx, JSREPORT_ERROR,
-                                          GetErrorMessage,
-                                          nullptr, JSMSG_BAD_SURROGATE_CHAR,
-                                          buffer);
+        JS_ReportErrorNumberASCII(maybecx, GetErrorMessage, nullptr, JSMSG_BAD_SURROGATE_CHAR,
+                                  buffer);
     }
     return (size_t) -1;
 }
 
 template size_t
 GetDeflatedUTF8StringLength(JSContext* maybecx, const Latin1Char* chars,
                             size_t nchars);
 
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -7088,17 +7088,17 @@ JSErrorNotes::copy(JSContext* cx)
 {
     auto copiedNotes = MakeUnique<JSErrorNotes>();
     if (!copiedNotes) {
         ReportOutOfMemory(cx);
         return nullptr;
     }
 
     for (auto&& note : *this) {
-        js::UniquePtr<JSErrorNotes::Note> copied(CopyErrorNote(cx, note.get()));
+        UniquePtr<JSErrorNotes::Note> copied = CopyErrorNote(cx, note.get());
         if (!copied)
             return nullptr;
 
         if (!copiedNotes->notes_.append(std::move(copied)))
             return nullptr;
     }
 
     return copiedNotes;
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -491,23 +491,16 @@ static const uint8_t JSPROP_INTERNAL_USE
 
 /* native that can be called as a ctor */
 static const unsigned JSFUN_CONSTRUCTOR =     0x400;
 
 /* | of all the JSFUN_* flags */
 static const unsigned JSFUN_FLAGS_MASK =      0x400;
 
 /*
- * If set, will allow redefining a non-configurable property, but only on a
- * non-DOM global.  This is a temporary hack that will need to go away in bug
- * 1105518.
- */
-static const unsigned JSPROP_REDEFINE_NONCONFIGURABLE = 0x1000;
-
-/*
  * Resolve hooks and enumerate hooks must pass this flag when calling
  * JS_Define* APIs to reify lazily-defined properties.
  *
  * JSPROP_RESOLVING is used only with property-defining APIs. It tells the
  * engine to skip the resolve hook when performing the lookup at the beginning
  * of property definition. This keeps the resolve hook from accidentally
  * triggering itself: unchecked recursion.
  *
@@ -2107,17 +2100,16 @@ class WrappedPtrOperations<JS::PropertyD
     void assertValid() const {
 #ifdef DEBUG
         MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE | JSPROP_IGNORE_ENUMERATE |
                                      JSPROP_PERMANENT | JSPROP_IGNORE_PERMANENT |
                                      JSPROP_READONLY | JSPROP_IGNORE_READONLY |
                                      JSPROP_IGNORE_VALUE |
                                      JSPROP_GETTER |
                                      JSPROP_SETTER |
-                                     JSPROP_REDEFINE_NONCONFIGURABLE |
                                      JSPROP_RESOLVING |
                                      SHADOWABLE)) == 0);
         MOZ_ASSERT(!hasAll(JSPROP_IGNORE_ENUMERATE | JSPROP_ENUMERATE));
         MOZ_ASSERT(!hasAll(JSPROP_IGNORE_PERMANENT | JSPROP_PERMANENT));
         if (isAccessorDescriptor()) {
             MOZ_ASSERT(!has(JSPROP_READONLY));
             MOZ_ASSERT(!has(JSPROP_IGNORE_READONLY));
             MOZ_ASSERT(!has(JSPROP_IGNORE_VALUE));
@@ -2129,29 +2121,27 @@ class WrappedPtrOperations<JS::PropertyD
             MOZ_ASSERT(!hasAll(JSPROP_IGNORE_READONLY | JSPROP_READONLY));
             MOZ_ASSERT_IF(has(JSPROP_IGNORE_VALUE), value().isUndefined());
         }
 
         MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_ENUMERATE));
         MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_PERMANENT));
         MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_READONLY));
         MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_IGNORE_VALUE));
-        MOZ_ASSERT_IF(has(JSPROP_RESOLVING), !has(JSPROP_REDEFINE_NONCONFIGURABLE));
 #endif
     }
 
     void assertComplete() const {
 #ifdef DEBUG
         assertValid();
         MOZ_ASSERT((attributes() & ~(JSPROP_ENUMERATE |
                                      JSPROP_PERMANENT |
                                      JSPROP_READONLY |
                                      JSPROP_GETTER |
                                      JSPROP_SETTER |
-                                     JSPROP_REDEFINE_NONCONFIGURABLE |
                                      JSPROP_RESOLVING |
                                      SHADOWABLE)) == 0);
         MOZ_ASSERT_IF(isAccessorDescriptor(), has(JSPROP_GETTER) && has(JSPROP_SETTER));
 #endif
     }
 
     void assertCompleteIfFound() const {
 #ifdef DEBUG
--- a/js/src/jsdate.cpp
+++ b/js/src/jsdate.cpp
@@ -2649,18 +2649,17 @@ date_toJSON(JSContext* cx, unsigned argc
 
     /* Step 4. */
     RootedValue toISO(cx);
     if (!GetProperty(cx, obj, obj, cx->names().toISOString, &toISO))
         return false;
 
     /* Step 5. */
     if (!IsCallable(toISO)) {
-        JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, js::GetErrorMessage, nullptr,
-                                          JSMSG_BAD_TOISOSTRING_PROP);
+        JS_ReportErrorNumberASCII(cx, js::GetErrorMessage, nullptr, JSMSG_BAD_TOISOSTRING_PROP);
         return false;
     }
 
     /* Step 6. */
     return Call(cx, toISO, obj, args.rval());
 }
 
 /* Interface to PRMJTime date struct. */
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -9,25 +9,27 @@
  */
 
 #include "jsexn.h"
 
 #include "mozilla/ScopeExit.h"
 #include "mozilla/Sprintf.h"
 
 #include <string.h>
+#include <utility>
 
 #include "jsapi.h"
 #include "jsnum.h"
 #include "jstypes.h"
 #include "jsutil.h"
 
 #include "gc/FreeOp.h"
 #include "gc/Marking.h"
 #include "js/CharacterEncoding.h"
+#include "js/UniquePtr.h"
 #include "js/Wrapper.h"
 #include "util/StringBuffer.h"
 #include "vm/ErrorObject.h"
 #include "vm/GlobalObject.h"
 #include "vm/JSContext.h"
 #include "vm/JSFunction.h"
 #include "vm/JSObject.h"
 #include "vm/JSScript.h"
@@ -262,17 +264,17 @@ CopyExtraData(JSContext* cx, uint8_t** c
 
 bool
 CopyExtraData(JSContext* cx, uint8_t** cursor, JSErrorNotes::Note* copy, JSErrorNotes::Note* report)
 {
     return true;
 }
 
 template <typename T>
-static T*
+static UniquePtr<T>
 CopyErrorHelper(JSContext* cx, T* report)
 {
     /*
      * We use a single malloc block to make a deep copy of JSErrorReport or
      * JSErrorNotes::Note, except JSErrorNotes linked from JSErrorReport with
      * the following layout:
      *   JSErrorReport or JSErrorNotes::Note
      *   char array with characters for message_
@@ -293,54 +295,51 @@ CopyErrorHelper(JSContext* cx, T* report
      * The mallocSize can not overflow since it represents the sum of the
      * sizes of already allocated objects.
      */
     size_t mallocSize = sizeof(T) + messageSize + filenameSize + ExtraMallocSize(report);
     uint8_t* cursor = cx->pod_calloc<uint8_t>(mallocSize);
     if (!cursor)
         return nullptr;
 
-    T* copy = new (cursor) T();
+    UniquePtr<T> copy(new (cursor) T());
     cursor += sizeof(T);
 
     if (report->message()) {
         copy->initBorrowedMessage((const char*)cursor);
         js_memcpy(cursor, report->message().c_str(), messageSize);
         cursor += messageSize;
     }
 
     if (report->filename) {
         copy->filename = (const char*)cursor;
         js_memcpy(cursor, report->filename, filenameSize);
         cursor += filenameSize;
     }
 
-    if (!CopyExtraData(cx, &cursor, copy, report)) {
-        /* js_delete calls destructor for T and js_free for pod_calloc. */
-        js_delete(copy);
+    if (!CopyExtraData(cx, &cursor, copy.get(), report))
         return nullptr;
-    }
 
-    MOZ_ASSERT(cursor == (uint8_t*)copy + mallocSize);
+    MOZ_ASSERT(cursor == (uint8_t*)copy.get() + mallocSize);
 
     /* Copy non-pointer members. */
     copy->lineno = report->lineno;
     copy->column = report->column;
     copy->errorNumber = report->errorNumber;
 
     return copy;
 }
 
-JSErrorNotes::Note*
+UniquePtr<JSErrorNotes::Note>
 js::CopyErrorNote(JSContext* cx, JSErrorNotes::Note* note)
 {
     return CopyErrorHelper(cx, note);
 }
 
-JSErrorReport*
+UniquePtr<JSErrorReport>
 js::CopyErrorReport(JSContext* cx, JSErrorReport* report)
 {
     return CopyErrorHelper(cx, report);
 }
 
 struct SuppressErrorsGuard
 {
     JSContext* cx;
@@ -681,22 +680,22 @@ js::ErrorToException(JSContext* cx, JSEr
 
     uint32_t lineNumber = reportp->lineno;
     uint32_t columnNumber = reportp->column;
 
     RootedObject stack(cx);
     if (!CaptureStack(cx, &stack))
         return;
 
-    js::ScopedJSFreePtr<JSErrorReport> report(CopyErrorReport(cx, reportp));
+    UniquePtr<JSErrorReport> report = CopyErrorReport(cx, reportp);
     if (!report)
         return;
 
-    RootedObject errObject(cx, ErrorObject::create(cx, exnType, stack, fileName,
-                                                   lineNumber, columnNumber, &report, messageStr));
+    RootedObject errObject(cx, ErrorObject::create(cx, exnType, stack, fileName, lineNumber,
+                                                   columnNumber, std::move(report), messageStr));
     if (!errObject)
         return;
 
     // Throw it.
     cx->setPendingException(ObjectValue(*errObject));
 
     // Flag the error report passed in to indicate an exception was raised.
     reportp->flags |= JSREPORT_EXCEPTION;
@@ -985,17 +984,17 @@ ErrorReport::populateUncaughtExceptionRe
     toStringResult_ = ownedReport.message();
     reportp = &ownedReport;
     return true;
 }
 
 JSObject*
 js::CopyErrorObject(JSContext* cx, Handle<ErrorObject*> err)
 {
-    js::ScopedJSFreePtr<JSErrorReport> copyReport;
+    UniquePtr<JSErrorReport> copyReport;
     if (JSErrorReport* errorReport = err->getErrorReport()) {
         copyReport = CopyErrorReport(cx, errorReport);
         if (!copyReport)
             return nullptr;
     }
 
     RootedString message(cx, err->getMessage());
     if (message && !cx->compartment()->wrap(cx, &message))
@@ -1007,34 +1006,36 @@ js::CopyErrorObject(JSContext* cx, Handl
     if (!cx->compartment()->wrap(cx, &stack))
         return nullptr;
     uint32_t lineNumber = err->lineNumber();
     uint32_t columnNumber = err->columnNumber();
     JSExnType errorType = err->type();
 
     // Create the Error object.
     return ErrorObject::create(cx, errorType, stack, fileName,
-                               lineNumber, columnNumber, &copyReport, message);
+                               lineNumber, columnNumber, std::move(copyReport), message);
 }
 
 JS_PUBLIC_API(bool)
 JS::CreateError(JSContext* cx, JSExnType type, HandleObject stack, HandleString fileName,
                     uint32_t lineNumber, uint32_t columnNumber, JSErrorReport* report,
                     HandleString message, MutableHandleValue rval)
 {
     assertSameCompartment(cx, stack, fileName, message);
     AssertObjectIsSavedFrameOrWrapper(cx, stack);
 
-    js::ScopedJSFreePtr<JSErrorReport> rep;
-    if (report)
+    js::UniquePtr<JSErrorReport> rep;
+    if (report) {
         rep = CopyErrorReport(cx, report);
+        if (!rep)
+            return false;
+    }
 
-    RootedObject obj(cx,
-        js::ErrorObject::create(cx, type, stack, fileName,
-                                lineNumber, columnNumber, &rep, message));
+    JSObject* obj = js::ErrorObject::create(cx, type, stack, fileName, lineNumber, columnNumber,
+                                            std::move(rep), message);
     if (!obj)
         return false;
 
     rval.setObject(*obj);
     return true;
 }
 
 const char*
--- a/js/src/jsexn.h
+++ b/js/src/jsexn.h
@@ -9,25 +9,26 @@
  */
 
 #ifndef jsexn_h
 #define jsexn_h
 
 #include "jsapi.h"
 #include "NamespaceImports.h"
 
+#include "js/UniquePtr.h"
 #include "vm/JSContext.h"
 
 namespace js {
 class ErrorObject;
 
-JSErrorNotes::Note*
+UniquePtr<JSErrorNotes::Note>
 CopyErrorNote(JSContext* cx, JSErrorNotes::Note* note);
 
-JSErrorReport*
+UniquePtr<JSErrorReport>
 CopyErrorReport(JSContext* cx, JSErrorReport* report);
 
 JSString*
 ComputeStackString(JSContext* cx);
 
 /*
  * Given a JSErrorReport, check to see if there is an exception associated with
  * the error number.  If there is, then create an appropriate exception object,
--- a/js/src/vm/CharacterEncoding.cpp
+++ b/js/src/vm/CharacterEncoding.cpp
@@ -225,33 +225,31 @@ JS::Utf8ToOneUcs4Char(const uint8_t* utf
     return ucs4Char;
 }
 
 static void
 ReportInvalidCharacter(JSContext* cx, uint32_t offset)
 {
     char buffer[10];
     SprintfLiteral(buffer, "%u", offset);
-    JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
-                                      JSMSG_MALFORMED_UTF8_CHAR, buffer);
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_MALFORMED_UTF8_CHAR, buffer);
 }
 
 static void
 ReportBufferTooSmall(JSContext* cx, uint32_t dummy)
 {
     JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BUFFER_TOO_SMALL);
 }
 
 static void
 ReportTooBigCharacter(JSContext* cx, uint32_t v)
 {
     char buffer[10];
     SprintfLiteral(buffer, "0x%x", v + 0x10000);
-    JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
-                                      JSMSG_UTF8_CHAR_TOO_LARGE, buffer);
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_UTF8_CHAR_TOO_LARGE, buffer);
 }
 
 enum InflateUTF8Action {
     CountAndReportInvalids,
     CountAndIgnoreInvalids,
     AssertNoInvalids,
     Copy,
     FindEncoding
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -269,19 +269,18 @@ GetOrCreateFunctionScript(JSContext* cx,
 
 static bool
 ValueToIdentifier(JSContext* cx, HandleValue v, MutableHandleId id)
 {
     if (!ValueToId<CanGC>(cx, v, id))
         return false;
     if (!JSID_IS_ATOM(id) || !IsIdentifier(JSID_TO_ATOM(id))) {
         RootedValue val(cx, v);
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE,
-                              JSDVG_SEARCH_STACK, val, nullptr, "not an identifier",
-                              nullptr);
+        ReportValueError(cx, JSMSG_UNEXPECTED_TYPE, JSDVG_SEARCH_STACK, val, nullptr,
+                         "not an identifier");
         return false;
     }
     return true;
 }
 
 class js::AutoRestoreRealmDebugMode
 {
     Realm* realm_;
@@ -517,23 +516,21 @@ RequireGlobalObject(JSContext* cx, Handl
 
         /* ... and WindowProxies around Windows. */
         if (IsWindowProxy(obj)) {
             obj = ToWindowIfWindowProxy(obj);
             isWindowProxy = "a WindowProxy referring to ";
         }
 
         if (obj->is<GlobalObject>()) {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_WRAPPER_IN_WAY,
-                                  JSDVG_SEARCH_STACK, dbgobj, nullptr,
-                                  isWrapper, isWindowProxy);
+            ReportValueError(cx, JSMSG_DEBUG_WRAPPER_IN_WAY, JSDVG_SEARCH_STACK, dbgobj, nullptr,
+                             isWrapper, isWindowProxy);
         } else {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_BAD_REFERENT,
-                                  JSDVG_SEARCH_STACK, dbgobj, nullptr,
-                                  "a global object", nullptr);
+            ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK, dbgobj, nullptr,
+                             "a global object");
         }
         return false;
     }
 
     return true;
 }
 
 
@@ -5356,19 +5353,18 @@ static JSObject*
 DebuggerScript_checkThis(JSContext* cx, const CallArgs& args, const char* fnname,
                          const char* refname)
 {
     JSObject* thisobj = DebuggerScript_check(cx, args.thisv(), fnname);
     if (!thisobj)
         return nullptr;
 
     if (!GetScriptReferent(thisobj).is<ReferentT>()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_BAD_REFERENT,
-                              JSDVG_SEARCH_STACK, args.thisv(), nullptr,
-                              refname, nullptr);
+        ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK, args.thisv(), nullptr,
+                         refname);
         return nullptr;
     }
 
     return thisobj;
 }
 
 #define THIS_DEBUGSCRIPT_REFERENT(cx, argc, vp, fnname, args, obj, referent)        \
     CallArgs args = CallArgsFromVp(argc, vp);                                       \
@@ -7002,19 +6998,18 @@ static NativeObject*
 DebuggerSource_checkThis(JSContext* cx, const CallArgs& args, const char* fnname,
                          const char* refname)
 {
     NativeObject* thisobj = DebuggerSource_check(cx, args.thisv(), fnname);
     if (!thisobj)
         return nullptr;
 
     if (!GetSourceReferent(thisobj).is<ReferentT>()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_BAD_REFERENT,
-                              JSDVG_SEARCH_STACK, args.thisv(), nullptr,
-                              refname, nullptr);
+        ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK, args.thisv(), nullptr,
+                         refname);
         return nullptr;
     }
 
     return thisobj;
 }
 
 #define THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, fnname, args, obj, referent)        \
     CallArgs args = CallArgsFromVp(argc, vp);                                       \
@@ -7087,19 +7082,18 @@ DebuggerSource_getText(JSContext* cx, un
 }
 
 static bool
 DebuggerSource_getBinary(JSContext* cx, unsigned argc, Value* vp)
 {
     THIS_DEBUGSOURCE_REFERENT(cx, argc, vp, "(get binary)", args, obj, referent);
 
     if (!referent.is<WasmInstanceObject*>()) {
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_BAD_REFERENT,
-                              JSDVG_SEARCH_STACK, args.thisv(), nullptr,
-                              "a wasm source", nullptr);
+        ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK, args.thisv(), nullptr,
+                         "a wasm source");
         return false;
     }
 
     RootedWasmInstanceObject wasmInstance(cx, referent.as<WasmInstanceObject*>());
     if (!wasmInstance->instance().debug().binarySource()) {
         JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
                                   JSMSG_DEBUG_NO_BINARY_SOURCE);
         return false;
@@ -8092,19 +8086,18 @@ DebuggerFrame::getFrameIter(JSContext* c
 }
 
 /* static */ bool
 DebuggerFrame::requireScriptReferent(JSContext* cx, HandleDebuggerFrame frame)
 {
     AbstractFramePtr referent = DebuggerFrame::getReferent(frame);
     if (!referent.hasScript()) {
         RootedValue frameobj(cx, ObjectValue(*frame));
-        ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_BAD_REFERENT,
-                              JSDVG_SEARCH_STACK, frameobj, nullptr,
-                              "a script frame", nullptr);
+        ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK, frameobj, nullptr,
+                         "a script frame");
         return false;
     }
     return true;
 }
 
 void
 DebuggerFrame::freeFrameIterData(FreeOp* fop)
 {
@@ -10702,23 +10695,21 @@ DebuggerObject::requireGlobal(JSContext*
         /* ... and WindowProxies around Windows. */
         if (IsWindowProxy(referent)) {
             referent = ToWindowIfWindowProxy(referent);
             isWindowProxy = "a WindowProxy referring to ";
         }
 
         RootedValue dbgobj(cx, ObjectValue(*object));
         if (referent->is<GlobalObject>()) {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_WRAPPER_IN_WAY,
-                                  JSDVG_SEARCH_STACK, dbgobj, nullptr,
-                                  isWrapper, isWindowProxy);
+            ReportValueError(cx, JSMSG_DEBUG_WRAPPER_IN_WAY, JSDVG_SEARCH_STACK, dbgobj, nullptr,
+                             isWrapper, isWindowProxy);
         } else {
-            ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_DEBUG_BAD_REFERENT,
-                                  JSDVG_SEARCH_STACK, dbgobj, nullptr,
-                                  "a global object", nullptr);
+            ReportValueError(cx, JSMSG_DEBUG_BAD_REFERENT, JSDVG_SEARCH_STACK, dbgobj, nullptr,
+                             "a global object");
         }
         return false;
     }
 
     return true;
 }
 
 /* static */ bool
--- a/js/src/vm/ErrorObject.cpp
+++ b/js/src/vm/ErrorObject.cpp
@@ -4,16 +4,18 @@
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "vm/ErrorObject-inl.h"
 
 #include "mozilla/Range.h"
 
+#include <utility>
+
 #include "jsexn.h"
 
 #include "js/CallArgs.h"
 #include "js/CharacterEncoding.h"
 #include "vm/GlobalObject.h"
 #include "vm/SelfHosting.h"
 #include "vm/StringType.h"
 
@@ -33,17 +35,17 @@ js::ErrorObject::assignInitialShape(JSCo
         return nullptr;
     if (!NativeObject::addDataProperty(cx, obj, cx->names().lineNumber, LINENUMBER_SLOT, 0))
         return nullptr;
     return NativeObject::addDataProperty(cx, obj, cx->names().columnNumber, COLUMNNUMBER_SLOT, 0);
 }
 
 /* static */ bool
 js::ErrorObject::init(JSContext* cx, Handle<ErrorObject*> obj, JSExnType type,
-                      ScopedJSFreePtr<JSErrorReport>* errorReport, HandleString fileName,
+                      UniquePtr<JSErrorReport> errorReport, HandleString fileName,
                       HandleObject stack, uint32_t lineNumber, uint32_t columnNumber,
                       HandleString message)
 {
     AssertObjectIsSavedFrameOrWrapper(cx, stack);
     assertSameCompartment(cx, obj, stack);
 
     // Null out early in case of error, for exn_finalize's sake.
     obj->initReservedSlot(ERROR_REPORT_SLOT, PrivateValue(nullptr));
@@ -67,33 +69,33 @@ js::ErrorObject::init(JSContext* cx, Han
     MOZ_ASSERT(obj->lookupPure(NameToId(cx->names().lineNumber))->slot() == LINENUMBER_SLOT);
     MOZ_ASSERT(obj->lookupPure(NameToId(cx->names().columnNumber))->slot() ==
                COLUMNNUMBER_SLOT);
     MOZ_ASSERT_IF(message,
                   obj->lookupPure(NameToId(cx->names().message))->slot() == MESSAGE_SLOT);
 
     MOZ_ASSERT(JSEXN_ERR <= type && type < JSEXN_LIMIT);
 
-    JSErrorReport* report = errorReport ? errorReport->forget() : nullptr;
+    JSErrorReport* report = errorReport.release();
     obj->initReservedSlot(EXNTYPE_SLOT, Int32Value(type));
     obj->initReservedSlot(STACK_SLOT, ObjectOrNullValue(stack));
     obj->setReservedSlot(ERROR_REPORT_SLOT, PrivateValue(report));
     obj->initReservedSlot(FILENAME_SLOT, StringValue(fileName));
     obj->initReservedSlot(LINENUMBER_SLOT, Int32Value(lineNumber));
     obj->initReservedSlot(COLUMNNUMBER_SLOT, Int32Value(columnNumber));
     if (message)
         obj->setSlotWithType(cx, messageShape, StringValue(message));
 
     return true;
 }
 
 /* static */ ErrorObject*
 js::ErrorObject::create(JSContext* cx, JSExnType errorType, HandleObject stack,
                         HandleString fileName, uint32_t lineNumber, uint32_t columnNumber,
-                        ScopedJSFreePtr<JSErrorReport>* report, HandleString message,
+                        UniquePtr<JSErrorReport> report, HandleString message,
                         HandleObject protoArg /* = nullptr */)
 {
     AssertObjectIsSavedFrameOrWrapper(cx, stack);
 
     RootedObject proto(cx, protoArg);
     if (!proto) {
         proto = GlobalObject::getOrCreateCustomErrorPrototype(cx, cx->global(), errorType);
         if (!proto)
@@ -104,17 +106,17 @@ js::ErrorObject::create(JSContext* cx, J
     {
         const Class* clasp = ErrorObject::classForType(errorType);
         JSObject* obj = NewObjectWithGivenProto(cx, clasp, proto);
         if (!obj)
             return nullptr;
         errObject = &obj->as<ErrorObject>();
     }
 
-    if (!ErrorObject::init(cx, errObject, errorType, report, fileName, stack,
+    if (!ErrorObject::init(cx, errObject, errorType, std::move(report), fileName, stack,
                            lineNumber, columnNumber, message))
     {
         return nullptr;
     }
 
     return errObject;
 }
 
@@ -151,21 +153,21 @@ js::ErrorObject::getOrCreateErrorReport(
         return nullptr;
 
     UniqueChars utf8 = StringToNewUTF8CharsZ(cx, *message);
     if (!utf8)
         return nullptr;
     report.initOwnedMessage(utf8.release());
 
     // Cache and return.
-    JSErrorReport* copy = CopyErrorReport(cx, &report);
+    UniquePtr<JSErrorReport> copy = CopyErrorReport(cx, &report);
     if (!copy)
         return nullptr;
-    setReservedSlot(ERROR_REPORT_SLOT, PrivateValue(copy));
-    return copy;
+    setReservedSlot(ERROR_REPORT_SLOT, PrivateValue(copy.get()));
+    return copy.release();
 }
 
 static bool
 FindErrorInstanceOrPrototype(JSContext* cx, HandleObject obj, MutableHandleObject result)
 {
     // Walk up the prototype chain until we find an error object instance or
     // prototype object. This allows code like:
     //  Object.create(Error.prototype).stack
--- a/js/src/vm/ErrorObject.h
+++ b/js/src/vm/ErrorObject.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef vm_ErrorObject_h_
 #define vm_ErrorObject_h_
 
 #include "mozilla/ArrayUtils.h"
 
+#include "js/UniquePtr.h"
 #include "vm/NativeObject.h"
 #include "vm/SavedStacks.h"
 #include "vm/Shape.h"
 
 namespace js {
 
 /*
  * Initialize the exception constructor/prototype hierarchy.
@@ -30,17 +31,17 @@ class ErrorObject : public NativeObject
     createConstructor(JSContext* cx, JSProtoKey key);
 
     /* For access to createProto. */
     friend JSObject*
     js::InitExceptionClasses(JSContext* cx, HandleObject global);
 
     static bool
     init(JSContext* cx, Handle<ErrorObject*> obj, JSExnType type,
-         ScopedJSFreePtr<JSErrorReport>* errorReport, HandleString fileName, HandleObject stack,
+         UniquePtr<JSErrorReport> errorReport, HandleString fileName, HandleObject stack,
          uint32_t lineNumber, uint32_t columnNumber, HandleString message);
 
     static const ClassSpec classSpecs[JSEXN_ERROR_LIMIT];
     static const Class protoClasses[JSEXN_ERROR_LIMIT];
 
   protected:
     static const uint32_t EXNTYPE_SLOT          = 0;
     static const uint32_t STACK_SLOT            = EXNTYPE_SLOT + 1;
@@ -65,17 +66,17 @@ class ErrorObject : public NativeObject
     }
 
     // Create an error of the given type corresponding to the provided location
     // info.  If |message| is non-null, then the error will have a .message
     // property with that value; otherwise the error will have no .message
     // property.
     static ErrorObject*
     create(JSContext* cx, JSExnType type, HandleObject stack, HandleString fileName,
-           uint32_t lineNumber, uint32_t columnNumber, ScopedJSFreePtr<JSErrorReport>* report,
+           uint32_t lineNumber, uint32_t columnNumber, UniquePtr<JSErrorReport> report,
            HandleString message, HandleObject proto = nullptr);
 
     /*
      * Assign the initial error shape to the empty object.  (This shape does
      * *not* include .message, which must be added separately if needed; see
      * ErrorObject::init.)
      */
     static Shape*
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -989,17 +989,17 @@ js::CheckClassHeritageOperation(JSContex
     if (heritage.isNull())
         return true;
 
     if (heritage.isObject()) {
         ReportIsNotFunction(cx, heritage, 0, CONSTRUCT);
         return false;
     }
 
-    ReportValueError2(cx, JSMSG_BAD_HERITAGE, -1, heritage, nullptr, "not an object or null");
+    ReportValueError(cx, JSMSG_BAD_HERITAGE, -1, heritage, nullptr, "not an object or null");
     return false;
 }
 
 JSObject*
 js::ObjectWithProtoOperation(JSContext* cx, HandleValue val)
 {
     if (!val.isObjectOrNull()) {
         ReportValueError(cx, JSMSG_NOT_OBJORNULL, -1, val, nullptr);
--- a/js/src/vm/JSContext.cpp
+++ b/js/src/vm/JSContext.cpp
@@ -890,46 +890,36 @@ js::ReportIsNotDefined(JSContext* cx, Ha
 
 void
 js::ReportIsNotDefined(JSContext* cx, HandlePropertyName name)
 {
     RootedId id(cx, NameToId(name));
     ReportIsNotDefined(cx, id);
 }
 
-bool
-js::ReportIsNullOrUndefined(JSContext* cx, int spindex, HandleValue v,
-                            HandleString fallback)
+void
+js::ReportIsNullOrUndefined(JSContext* cx, int spindex, HandleValue v)
 {
-    bool ok;
-
-    UniqueChars bytes = DecompileValueGenerator(cx, spindex, v, fallback);
-    if (!bytes)
-        return false;
+    MOZ_ASSERT(v.isNullOrUndefined());
 
-    if (strcmp(bytes.get(), js_undefined_str) == 0 ||
-        strcmp(bytes.get(), js_null_str) == 0) {
-        ok = JS_ReportErrorFlagsAndNumberLatin1(cx, JSREPORT_ERROR,
-                                                GetErrorMessage, nullptr,
-                                                JSMSG_NO_PROPERTIES,
-                                                bytes.get());
+    UniqueChars bytes = DecompileValueGenerator(cx, spindex, v, nullptr);
+    if (!bytes)
+        return;
+
+    if (strcmp(bytes.get(), js_undefined_str) == 0 || strcmp(bytes.get(), js_null_str) == 0) {
+        JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_NO_PROPERTIES,
+                                   bytes.get());
     } else if (v.isUndefined()) {
-        ok = JS_ReportErrorFlagsAndNumberLatin1(cx, JSREPORT_ERROR,
-                                                GetErrorMessage, nullptr,
-                                                JSMSG_UNEXPECTED_TYPE,
-                                                bytes.get(), js_undefined_str);
+        JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE,
+                                   bytes.get(), js_undefined_str);
     } else {
         MOZ_ASSERT(v.isNull());
-        ok = JS_ReportErrorFlagsAndNumberLatin1(cx, JSREPORT_ERROR,
-                                                GetErrorMessage, nullptr,
-                                                JSMSG_UNEXPECTED_TYPE,
-                                                bytes.get(), js_null_str);
+        JS_ReportErrorNumberLatin1(cx, GetErrorMessage, nullptr, JSMSG_UNEXPECTED_TYPE,
+                                   bytes.get(), js_null_str);
     }
-
-    return ok;
 }
 
 void
 js::ReportMissingArg(JSContext* cx, HandleValue v, unsigned arg)
 {
     char argbuf[11];
     UniqueChars bytes;
 
@@ -945,28 +935,24 @@ js::ReportMissingArg(JSContext* cx, Hand
                                argbuf, bytes ? bytes.get() : "");
 }
 
 bool
 js::ReportValueErrorFlags(JSContext* cx, unsigned flags, const unsigned errorNumber,
                           int spindex, HandleValue v, HandleString fallback,
                           const char* arg1, const char* arg2)
 {
-    UniqueChars bytes;
-    bool ok;
-
     MOZ_ASSERT(js_ErrorFormatString[errorNumber].argCount >= 1);
     MOZ_ASSERT(js_ErrorFormatString[errorNumber].argCount <= 3);
-    bytes = DecompileValueGenerator(cx, spindex, v, fallback);
+    UniqueChars bytes = DecompileValueGenerator(cx, spindex, v, fallback);
     if (!bytes)
         return false;
 
-    ok = JS_ReportErrorFlagsAndNumberLatin1(cx, flags, GetErrorMessage, nullptr, errorNumber,
-                                            bytes.get(), arg1, arg2);
-    return ok;
+    return JS_ReportErrorFlagsAndNumberLatin1(cx, flags, GetErrorMessage, nullptr, errorNumber,
+                                              bytes.get(), arg1, arg2);
 }
 
 JSObject*
 js::CreateErrorNotesArray(JSContext* cx, JSErrorReport* report)
 {
     RootedArrayObject notesArray(cx, NewDenseEmptyArray(cx));
     if (!notesArray)
         return nullptr;
--- a/js/src/vm/JSContext.h
+++ b/js/src/vm/JSContext.h
@@ -1010,43 +1010,38 @@ extern void
 ReportIsNotDefined(JSContext* cx, HandlePropertyName name);
 
 extern void
 ReportIsNotDefined(JSContext* cx, HandleId id);
 
 /*
  * Report an attempt to access the property of a null or undefined value (v).
  */
-extern bool
-ReportIsNullOrUndefined(JSContext* cx, int spindex, HandleValue v, HandleString fallback);
+extern void
+ReportIsNullOrUndefined(JSContext* cx, int spindex, HandleValue v);
 
 extern void
 ReportMissingArg(JSContext* cx, js::HandleValue v, unsigned arg);
 
 /*
  * Report error using js_DecompileValueGenerator(cx, spindex, v, fallback) as
  * the first argument for the error message. If the error message has less
  * then 3 arguments, use null for arg1 or arg2.
  */
 extern bool
 ReportValueErrorFlags(JSContext* cx, unsigned flags, const unsigned errorNumber,
                       int spindex, HandleValue v, HandleString fallback,
                       const char* arg1, const char* arg2);
 
-#define ReportValueError(cx,errorNumber,spindex,v,fallback)                   \
-    ((void)ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber,             \
-                                    spindex, v, fallback, nullptr, nullptr))
-
-#define ReportValueError2(cx,errorNumber,spindex,v,fallback,arg1)             \
-    ((void)ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber,             \
-                                    spindex, v, fallback, arg1, nullptr))
-
-#define ReportValueError3(cx,errorNumber,spindex,v,fallback,arg1,arg2)        \
-    ((void)ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber,             \
-                                    spindex, v, fallback, arg1, arg2))
+inline void
+ReportValueError(JSContext* cx, const unsigned errorNumber, int spindex, HandleValue v,
+                 HandleString fallback, const char* arg1 = nullptr, const char* arg2 = nullptr)
+{
+    ReportValueErrorFlags(cx, JSREPORT_ERROR, errorNumber, spindex, v, fallback, arg1, arg2);
+}
 
 JSObject*
 CreateErrorNotesArray(JSContext* cx, JSErrorReport* report);
 
 } /* namespace js */
 
 extern const JSErrorFormatString js_ErrorFormatString[JSErr_Limit];
 
--- a/js/src/vm/JSFunction.cpp
+++ b/js/src/vm/JSFunction.cpp
@@ -111,18 +111,17 @@ AdvanceToActiveCallLinear(JSContext* cx,
             return true;
     }
     return false;
 }
 
 void
 js::ThrowTypeErrorBehavior(JSContext* cx)
 {
-    JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
-                                     JSMSG_THROW_TYPE_ERROR);
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_THROW_TYPE_ERROR);
 }
 
 static bool
 IsSloppyNormalFunction(JSFunction* fun)
 {
     // FunctionDeclaration or FunctionExpression in sloppy mode.
     if (fun->kind() == JSFunction::NormalFunction) {
         if (fun->isBuiltin() || fun->isBoundFunction())
@@ -306,18 +305,17 @@ CallerGetterImpl(JSContext* cx, const Ca
         JSFunction* callerFun = &callerObj->as<JSFunction>();
         if (IsWrappedAsyncFunction(callerFun))
             callerFun = GetUnwrappedAsyncFunction(callerFun);
         else if (IsWrappedAsyncGenerator(callerFun))
             callerFun = GetUnwrappedAsyncGenerator(callerFun);
         MOZ_ASSERT(!callerFun->isBuiltin(), "non-builtin iterator returned a builtin?");
 
         if (callerFun->strict()) {
-            JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
-                                              JSMSG_CALLER_IS_STRICT);
+            JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CALLER_IS_STRICT);
             return false;
         }
     }
 
     args.rval().setObject(*caller);
     return true;
 }
 
@@ -375,18 +373,17 @@ CallerSetterImpl(JSContext* cx, const Ca
     JSObject* callerObj = CheckedUnwrap(caller);
     if (!callerObj)
         return true;
 
     JSFunction* callerFun = &callerObj->as<JSFunction>();
     MOZ_ASSERT(!callerFun->isBuiltin(), "non-builtin iterator returned a builtin?");
 
     if (callerFun->strict()) {
-        JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
-                                          JSMSG_CALLER_IS_STRICT);
+        JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CALLER_IS_STRICT);
         return false;
     }
 
     return true;
 }
 
 static bool
 CallerSetter(JSContext* cx, unsigned argc, Value* vp)
--- a/js/src/vm/JSObject.cpp
+++ b/js/src/vm/JSObject.cpp
@@ -2619,43 +2619,16 @@ js::HasOwnDataPropertyPure(JSContext* cx
     if (!LookupOwnPropertyPure(cx, obj, id, &prop))
         return false;
 
     *result = prop && !prop.isDenseOrTypedArrayElement() &&
               prop.shape()->isDataProperty();
     return true;
 }
 
-/* static */ bool
-JSObject::reportReadOnly(JSContext* cx, jsid id, unsigned report)
-{
-    RootedValue val(cx, IdToValue(id));
-    return ReportValueErrorFlags(cx, report, JSMSG_READ_ONLY,
-                                 JSDVG_IGNORE_STACK, val, nullptr,
-                                 nullptr, nullptr);
-}
-
-/* static */ bool
-JSObject::reportNotConfigurable(JSContext* cx, jsid id, unsigned report)
-{
-    RootedValue val(cx, IdToValue(id));
-    return ReportValueErrorFlags(cx, report, JSMSG_CANT_DELETE,
-                                 JSDVG_IGNORE_STACK, val, nullptr,
-                                 nullptr, nullptr);
-}
-
-/* static */ bool
-JSObject::reportNotExtensible(JSContext* cx, HandleObject obj, unsigned report)
-{
-    RootedValue val(cx, ObjectValue(*obj));
-    return ReportValueErrorFlags(cx, report, JSMSG_OBJECT_NOT_EXTENSIBLE,
-                                 JSDVG_IGNORE_STACK, val, nullptr,
-                                 nullptr, nullptr);
-}
-
 bool
 js::GetPrototypeIfOrdinary(JSContext* cx, HandleObject obj, bool* isOrdinary,
                            MutableHandleObject protop)
 {
     if (obj->is<js::ProxyObject>())
         return js::Proxy::getPrototypeIfOrdinary(cx, obj, isOrdinary, protop);
 
     *isOrdinary = true;
@@ -3081,20 +3054,20 @@ ReportCantConvert(JSContext* cx, unsigne
         str = JS_AtomizeAndPinString(cx, clasp->name);
         if (!str)
             return false;
     } else {
         str = nullptr;
     }
 
     RootedValue val(cx, ObjectValue(*obj));
-    ReportValueError2(cx, errorNumber, JSDVG_SEARCH_STACK, val, str,
-                      hint == JSTYPE_UNDEFINED
-                      ? "primitive type"
-                      : hint == JSTYPE_STRING ? "string" : "number");
+    ReportValueError(cx, errorNumber, JSDVG_SEARCH_STACK, val, str,
+                     hint == JSTYPE_UNDEFINED
+                     ? "primitive type"
+                     : hint == JSTYPE_STRING ? "string" : "number");
     return false;
 }
 
 bool
 JS::OrdinaryToPrimitive(JSContext* cx, HandleObject obj, JSType hint, MutableHandleValue vp)
 {
     MOZ_ASSERT(hint == JSTYPE_NUMBER || hint == JSTYPE_STRING || hint == JSTYPE_UNDEFINED);
 
@@ -3268,30 +3241,30 @@ js::PrimitiveToObject(JSContext* cx, con
     MOZ_ASSERT(v.isSymbol());
     RootedSymbol symbol(cx, v.toSymbol());
     return SymbolObject::create(cx, symbol);
 #endif
 }
 
 /*
  * Invokes the ES5 ToObject algorithm on vp, returning the result. If vp might
- * already be an object, use ToObject. reportCantConvert controls how null and
+ * already be an object, use ToObject. reportScanStack controls how null and
  * undefined errors are reported.
  *
  * Callers must handle the already-object case.
  */
 JSObject*
 js::ToObjectSlow(JSContext* cx, JS::HandleValue val, bool reportScanStack)
 {
     MOZ_ASSERT(!val.isMagic());
     MOZ_ASSERT(!val.isObject());
 
     if (val.isNullOrUndefined()) {
         if (reportScanStack) {
-            ReportIsNullOrUndefined(cx, JSDVG_SEARCH_STACK, val, nullptr);
+            ReportIsNullOrUndefined(cx, JSDVG_SEARCH_STACK, val);
         } else {
             JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_CANT_CONVERT_TO,
                                       val.isNull() ? "null" : "undefined", "object");
         }
         return nullptr;
     }
 
     return PrimitiveToObject(cx, val);
--- a/js/src/vm/JSObject.h
+++ b/js/src/vm/JSObject.h
@@ -475,21 +475,16 @@ class JSObject : public js::gc::Cell
     MOZ_ALWAYS_INLINE bool isCallable() const;
     MOZ_ALWAYS_INLINE bool isConstructor() const;
     MOZ_ALWAYS_INLINE JSNative callHook() const;
     MOZ_ALWAYS_INLINE JSNative constructHook() const;
 
     MOZ_ALWAYS_INLINE void finalize(js::FreeOp* fop);
 
   public:
-    static bool reportReadOnly(JSContext* cx, jsid id, unsigned report = JSREPORT_ERROR);
-    static bool reportNotConfigurable(JSContext* cx, jsid id, unsigned report = JSREPORT_ERROR);
-    static bool reportNotExtensible(JSContext* cx, js::HandleObject obj,
-                                    unsigned report = JSREPORT_ERROR);
-
     static bool nonNativeSetProperty(JSContext* cx, js::HandleObject obj, js::HandleId id,
                                      js::HandleValue v, js::HandleValue receiver,
                                      JS::ObjectOpResult& result);
     static bool nonNativeSetElement(JSContext* cx, js::HandleObject obj, uint32_t index,
                                     js::HandleValue v, js::HandleValue receiver,
                                     JS::ObjectOpResult& result);
 
     static bool swap(JSContext* cx, JS::HandleObject a, JS::HandleObject b);
--- a/js/src/vm/NativeObject-inl.h
+++ b/js/src/vm/NativeObject-inl.h
@@ -962,18 +962,19 @@ LookupPropertyInline(JSContext* cx,
     return true;
 }
 
 inline bool
 ThrowIfNotConstructing(JSContext *cx, const CallArgs &args, const char *builtinName)
 {
     if (args.isConstructing())
         return true;
-    return JS_ReportErrorFlagsAndNumberASCII(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
-                                             JSMSG_BUILTIN_CTOR_NO_NEW, builtinName);
+    JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr, JSMSG_BUILTIN_CTOR_NO_NEW,
+                              builtinName);
+    return false;
 }
 
 inline bool
 IsPackedArray(JSObject* obj)
 {
     if (!obj->is<ArrayObject>() || obj->hasLazyGroup())
         return false;
     AutoSweepObjectGroup sweep(obj->group());
--- a/js/src/vm/NativeObject.cpp
+++ b/js/src/vm/NativeObject.cpp
@@ -1702,28 +1702,18 @@ js::NativeDefineProperty(JSContext* cx, 
         // type for this property that doesn't match the value in the slot.
         // Update the type here, even though this DefineProperty call is
         // otherwise a no-op. (See bug 1125624 comment 13.)
         if (!prop.isDenseOrTypedArrayElement() && desc.hasValue())
             UpdateShapeTypeAndValue(cx, obj, prop.shape(), id, desc.value());
         return result.succeed();
     }
 
-    // Non-standard hack: Allow redefining non-configurable properties if
-    // JSPROP_REDEFINE_NONCONFIGURABLE is set _and_ the object is a non-DOM
-    // global. The idea is that a DOM object can never have such a thing on
-    // its proto chain directly on the web, so we should be OK optimizing
-    // access to accessors found on such an object. Bug 1105518 contemplates
-    // removing this hack.
-    bool skipRedefineChecks = (desc.attributes() & JSPROP_REDEFINE_NONCONFIGURABLE) &&
-                              obj->is<GlobalObject>() &&
-                              !obj->getClass()->isDOMClass();
-
     // Step 4.
-    if (!IsConfigurable(shapeAttrs) && !skipRedefineChecks) {
+    if (!IsConfigurable(shapeAttrs)) {
         if (desc.hasConfigurable() && desc.configurable())
             return result.fail(JSMSG_CANT_REDEFINE_PROP);
         if (desc.hasEnumerable() && desc.enumerable() != IsEnumerable(shapeAttrs))
             return result.fail(JSMSG_CANT_REDEFINE_PROP);
     }
 
     // Fill in desc.[[Configurable]] and desc.[[Enumerable]] if missing.
     if (!desc.hasConfigurable())
@@ -1748,79 +1738,77 @@ js::NativeDefineProperty(JSContext* cx, 
             desc.setValue(currentValue);
             desc.setWritable(IsWritable(shapeAttrs));
         } else {
             desc.setGetterObject(prop.shape()->getterObject());
             desc.setSetterObject(prop.shape()->setterObject());
         }
     } else if (desc.isDataDescriptor() != IsDataDescriptor(shapeAttrs)) {
         // Step 6.
-        if (!IsConfigurable(shapeAttrs) && !skipRedefineChecks)
+        if (!IsConfigurable(shapeAttrs))
             return result.fail(JSMSG_CANT_REDEFINE_PROP);
 
         // Fill in desc fields with default values (steps 6.b.i and 6.c.i).
         CompletePropertyDescriptor(&desc);
     } else if (desc.isDataDescriptor()) {
         // Step 7.
         bool frozen = !IsConfigurable(shapeAttrs) && !IsWritable(shapeAttrs);
 
         // Step 7.a.i.1.
-        if (frozen && desc.hasWritable() && desc.writable() && !skipRedefineChecks)
+        if (frozen && desc.hasWritable() && desc.writable())
             return result.fail(JSMSG_CANT_REDEFINE_PROP);
 
         if (frozen || !desc.hasValue()) {
             RootedValue currentValue(cx);
             if (!GetExistingPropertyValue(cx, obj, id, prop, &currentValue))
                 return false;
 
             if (!desc.hasValue()) {
                 // Fill in desc.[[Value]].
                 desc.setValue(currentValue);
             } else {
                 // Step 7.a.i.2.
                 bool same;
                 MOZ_ASSERT(!cx->helperThread());
                 if (!SameValue(cx, desc.value(), currentValue, &same))
                     return false;
-                if (!same && !skipRedefineChecks)
+                if (!same)
                     return result.fail(JSMSG_CANT_REDEFINE_PROP);
             }
         }
 
         // Step 7.a.i.3.
-        if (frozen && !skipRedefineChecks)
+        if (frozen)
             return result.succeed();
 
         // Fill in desc.[[Writable]].
         if (!desc.hasWritable())
             desc.setWritable(IsWritable(shapeAttrs));
     } else {
         // Step 8.
         MOZ_ASSERT(prop.shape()->isAccessorDescriptor());
         MOZ_ASSERT(desc.isAccessorDescriptor());
 
         // The spec says to use SameValue, but since the values in
         // question are objects, we can just compare pointers.
         if (desc.hasSetterObject()) {
             // Step 8.a.i.
             if (!IsConfigurable(shapeAttrs) &&
-                desc.setterObject() != prop.shape()->setterObject() &&
-                !skipRedefineChecks)
+                desc.setterObject() != prop.shape()->setterObject())
             {
                 return result.fail(JSMSG_CANT_REDEFINE_PROP);
             }
         } else {
             // Fill in desc.[[Set]] from shape.
             desc.setSetterObject(prop.shape()->setterObject());
         }
         if (desc.hasGetterObject()) {
             // Step 8.a.ii.
             if (!IsConfigurable(shapeAttrs) &&
-                desc.getterObject() != prop.shape()->getterObject() &&
-                !skipRedefineChecks)
+                desc.getterObject() != prop.shape()->getterObject())
             {
                 return result.fail(JSMSG_CANT_REDEFINE_PROP);
             }
         } else {
             // Fill in desc.[[Get]] from shape.
             desc.setGetterObject(prop.shape()->getterObject());
         }
 
--- a/js/src/vm/RegExpObject.cpp
+++ b/js/src/vm/RegExpObject.cpp
@@ -1418,18 +1418,17 @@ js::ParseRegExpFlags(JSContext* cx, JSSt
         ok = ::ParseRegExpFlags(linear->twoByteChars(nogc), len, flagsOut, &invalidFlag);
     }
 
     if (!ok) {
         TwoByteChars range(&invalidFlag, 1);
         UniqueChars utf8(JS::CharsToNewUTF8CharsZ(nullptr, range).c_str());
         if (!utf8)
             return false;
-        JS_ReportErrorFlagsAndNumberUTF8(cx, JSREPORT_ERROR, GetErrorMessage, nullptr,
-                                         JSMSG_BAD_REGEXP_FLAG, utf8.get());
+        JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, JSMSG_BAD_REGEXP_FLAG, utf8.get());
         return false;
     }
 
     return true;
 }
 
 template<XDRMode mode>
 XDRResult
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -2901,18 +2901,18 @@ VerifyGlobalNames(JSContext* cx, Handle<
                     break;
                 }
             }
         }
     }
 
     if (nameMissing) {
         RootedValue value(cx, IdToValue(id));
-        return ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_NO_SUCH_SELF_HOSTED_PROP,
-                                     JSDVG_IGNORE_STACK, value, nullptr, nullptr, nullptr);
+        ReportValueError(cx, JSMSG_NO_SUCH_SELF_HOSTED_PROP, JSDVG_IGNORE_STACK, value, nullptr);
+        return false;
     }
 #endif // DEBUG
 
     return true;
 }
 
 bool
 JSRuntime::initSelfHosting(JSContext* cx)
--- a/layout/painting/DisplayItemClipChain.h
+++ b/layout/painting/DisplayItemClipChain.h
@@ -67,18 +67,19 @@ struct DisplayItemClipChain {
     , mASR(aASR)
     , mParent(aParent)
 #ifdef DEBUG
     , mOnStack(true)
 #endif
   {}
 
   DisplayItemClipChain()
+    : mASR(nullptr)
 #ifdef DEBUG
-    : mOnStack(true)
+    , mOnStack(true)
 #endif
   {}
 
   DisplayItemClip mClip;
   const ActiveScrolledRoot* mASR;
   RefPtr<const DisplayItemClipChain> mParent;
   uint32_t mRefCount = 0;
 #ifdef DEBUG
--- a/layout/painting/DottedCornerFinder.cpp
+++ b/layout/painting/DottedCornerFinder.cpp
@@ -52,17 +52,17 @@ DottedCornerFinder::DottedCornerFinder(c
                                        const Point& aCn, Float aRn,
                                        const Size& aCornerDim)
  : mOuterBezier(aOuterBezier),
    mInnerBezier(aInnerBezier),
    mCorner(aCorner),
    mNormalSign((aCorner == C_TL || aCorner == C_BR) ? -1.0f : 1.0f),
    mC0(aC0), mCn(aCn),
    mR0(aR0), mRn(aRn), mMaxR(std::max(aR0, aRn)),
-   mCenterCurveOrigin(mC0.x, mCn.y),
+   mCenterCurveOrigin(mC0.x, mCn.y), mCenterCurveR(0.0),
    mInnerCurveOrigin(mInnerBezier.mPoints[0].x, mInnerBezier.mPoints[3].y),
    mBestOverlap(0.0f),
    mHasZeroBorderWidth(false), mHasMore(true),
    mMaxCount(aCornerDim.width + aCornerDim.height),
    mType(OTHER),
    mI(0), mCount(0)
 {
   NS_ASSERTION(mR0 > 0.0f || mRn > 0.0f,
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -528,16 +528,17 @@ FrameLayerBuilder::DestroyDisplayItemDat
  * makes it more likely a display item will be rendered to an opaque
  * layer, giving us the best chance of getting subpixel AA.
  */
 class PaintedLayerData {
 public:
   PaintedLayerData() :
     mAnimatedGeometryRoot(nullptr),
     mASR(nullptr),
+    mClipChain(nullptr),
     mReferenceFrame(nullptr),
     mLayer(nullptr),
     mSolidColor(NS_RGBA(0, 0, 0, 0)),
     mIsSolidColorInVisibleRegion(false),
     mNeedComponentAlpha(false),
     mForceTransparentSurface(false),
     mHideAllLayersBelow(false),
     mOpaqueForAnimatedGeometryRootParent(false),
@@ -1632,17 +1633,18 @@ public:
   PaintedDisplayItemLayerUserData() :
     mForcedBackgroundColor(NS_RGBA(0,0,0,0)),
     mXScale(1.f), mYScale(1.f),
     mAppUnitsPerDevPixel(0),
     mTranslation(0, 0),
     mAnimatedGeometryRootPosition(0, 0),
     mLastItemCount(0),
     mContainerLayerFrame(nullptr),
-    mHasExplicitLastPaintOffset(false) {}
+    mHasExplicitLastPaintOffset(false),
+    mDisabledAlpha(false) {}
 
   NS_INLINE_DECL_REFCOUNTING(PaintedDisplayItemLayerUserData);
 
   /**
    * A color that should be painted over the bounds of the layer's visible
    * region before any other content is painted.
    */
   nscolor mForcedBackgroundColor;
@@ -1720,16 +1722,17 @@ public:
   bool mDisabledAlpha;
 
 protected:
   ~PaintedDisplayItemLayerUserData() = default;
 };
 
 FrameLayerBuilder::FrameLayerBuilder()
   : mRetainingManager(nullptr)
+  , mDisplayListBuilder(nullptr)
   , mContainingPaintedLayer(nullptr)
   , mInactiveLayerClip(nullptr)
   , mInvalidateAllLayers(false)
   , mInLayerTreeCompressionMode(false)
   , mIsInactiveLayerManager(false)
 {
   MOZ_COUNT_CTOR(FrameLayerBuilder);
 }
--- a/layout/painting/nsCSSRendering.cpp
+++ b/layout/painting/nsCSSRendering.cpp
@@ -72,17 +72,20 @@ static int gFrameTreeLockCount = 0;
 
 // To avoid storing this data on nsInlineFrame (bloat) and to avoid
 // recalculating this for each frame in a continuation (perf), hold
 // a cache of various coordinate information that we need in order
 // to paint inline backgrounds.
 struct InlineBackgroundData
 {
   InlineBackgroundData()
-      : mFrame(nullptr), mLineContainer(nullptr)
+      : mFrame(nullptr), mLineContainer(nullptr),
+        mContinuationPoint(0), mUnbrokenMeasure(0), 
+        mLineContinuationPoint(0), mPIStartBorderData{},
+        mBidiEnabled(false), mVertical(false)
   {
   }
 
   ~InlineBackgroundData()
   {
   }
 
   void Reset()
--- a/layout/painting/nsCSSRenderingGradients.h
+++ b/layout/painting/nsCSSRenderingGradients.h
@@ -86,17 +86,22 @@ public:
                                   const nsRect& aDest,
                                   const nsRect& aFill,
                                   const nsSize& aRepeatSize,
                                   const mozilla::CSSIntRect& aSrc,
                                   bool aIsBackfaceVisible,
                                   float aOpacity = 1.0);
 
 private:
-  nsCSSGradientRenderer() {}
+  nsCSSGradientRenderer()
+    : mPresContext(nullptr)
+    , mGradient(nullptr)
+    , mRadiusX(0.0)
+    , mRadiusY(0.0)
+  {}
 
   /**
    * Attempts to paint the tiles for a gradient by painting it once to an
    * offscreen surface and then painting that offscreen surface with
    * ExtendMode::Repeat to cover all tiles.
    *
    * Returns false if the optimization wasn't able to be used, in which case
    * a fallback should be used.
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -318,16 +318,19 @@ struct ActiveScrolledRoot {
 
   RefPtr<const ActiveScrolledRoot> mParent;
   nsIScrollableFrame* mScrollableFrame;
 
   NS_INLINE_DECL_REFCOUNTING(ActiveScrolledRoot)
 
 private:
   ActiveScrolledRoot()
+    : mScrollableFrame(nullptr)
+    , mDepth(0)
+    , mRetained(false)
   {
   }
 
   ~ActiveScrolledRoot()
   {
     if (mScrollableFrame && mRetained) {
       nsIFrame* f = do_QueryFrame(mScrollableFrame);
       f->DeleteProperty(ActiveScrolledRootCache());
--- a/layout/painting/nsImageRenderer.h
+++ b/layout/painting/nsImageRenderer.h
@@ -28,18 +28,21 @@ class IpcResourceUpdateQueue;
 // A CSSSizeOrRatio represents a (possibly partially specified) size for use
 // in computing image sizes. Either or both of the width and height might be
 // given. A ratio of width to height may also be given. If we at least two
 // of these then we can compute a concrete size, that is a width and height.
 struct CSSSizeOrRatio
 {
   CSSSizeOrRatio()
     : mRatio(0, 0)
+    , mWidth(0)
+    , mHeight(0)
     , mHasWidth(false)
-    , mHasHeight(false) {}
+    , mHasHeight(false)
+  {}
 
   bool CanComputeConcreteSize() const
   {
     return mHasWidth + mHasHeight + HasRatio() >= 2;
   }
   bool IsConcrete() const { return mHasWidth && mHasHeight; }
   bool HasRatio() const { return mRatio.width > 0 && mRatio.height > 0; }
   bool IsEmpty() const
--- a/layout/svg/SVGContextPaint.h
+++ b/layout/svg/SVGContextPaint.h
@@ -185,17 +185,20 @@ public:
 
   void SetFillOpacity(float aOpacity) { mFillOpacity = aOpacity; }
   float GetFillOpacity() const override { return mFillOpacity; }
 
   void SetStrokeOpacity(float aOpacity) { mStrokeOpacity = aOpacity; }
   float GetStrokeOpacity() const override { return mStrokeOpacity; }
 
   struct Paint {
-    Paint() : mPaintType(eStyleSVGPaintType_None) {}
+    Paint()
+      : mPaintDefinition{}
+      , mPaintType(eStyleSVGPaintType_None)
+    {}
 
     void SetPaintServer(nsIFrame* aFrame,
                         const gfxMatrix& aContextMatrix,
                         nsSVGPaintServerFrame* aPaintServerFrame) {
       mPaintType = eStyleSVGPaintType_Server;
       mPaintDefinition.mPaintServerFrame = aPaintServerFrame;
       mFrame = aFrame;
       mContextMatrix = aContextMatrix;
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -2434,20 +2434,22 @@ CharIterator::CharIterator(SVGTextFrame*
                            CharIterator::CharacterFilter aFilter,
                            nsIContent* aSubtree,
                            bool aPostReflow)
   : mFilter(aFilter),
     mFrameIterator(aSVGTextFrame, aSubtree),
     mFrameForTrimCheck(nullptr),
     mTrimmedOffset(0),
     mTrimmedLength(0),
+    mTextRun(nullptr),
     mTextElementCharIndex(0),
     mGlyphStartTextElementCharIndex(0),
-    mLengthAdjustScaleFactor(aSVGTextFrame->mLengthAdjustScaleFactor)
-  , mPostReflow(aPostReflow)
+    mGlyphUndisplayedCharacters(0),
+    mLengthAdjustScaleFactor(aSVGTextFrame->mLengthAdjustScaleFactor),
+    mPostReflow(aPostReflow)
 {
   if (!AtEnd()) {
     mSkipCharsIterator = TextFrame()->EnsureTextRun(nsTextFrame::eInflated);
     mTextRun = TextFrame()->GetTextRun(nsTextFrame::eInflated);
     mTextElementCharIndex = mFrameIterator.UndisplayedCharacters();
     UpdateGlyphStartTextElementCharIndex();
     if (!MatchesFilter()) {
       Next();
@@ -2767,17 +2769,18 @@ public:
                            const gfxMatrix& aCanvasTM,
                            imgDrawingParams& aImgParams,
                            bool aShouldPaintSVGGlyphs)
     : DrawPathCallbacks(aShouldPaintSVGGlyphs),
       mSVGTextFrame(aSVGTextFrame),
       mContext(aContext),
       mFrame(aFrame),
       mCanvasTM(aCanvasTM),
-      mImgParams(aImgParams)
+      mImgParams(aImgParams),
+      mColor(0)
   {
   }
 
   void NotifySelectionBackgroundNeedsFill(const Rect& aBackgroundRect,
                                           nscolor aColor,
                                           DrawTarget& aDrawTarget) override;
   void PaintDecorationLine(Rect aPath, nscolor aColor) override;
   void PaintSelectionDecorationLine(Rect aPath, nscolor aColor) override;