Bug 1277278 part 1 - Remove ContextOptions and make autoJSAPIOwnsErrorReporting the default. r=luke
authorJan de Mooij <jdemooij@mozilla.com>
Tue, 07 Jun 2016 20:30:48 +0200
changeset 300948 aaebaccae0a2c9595c3009f08cdb4c84ad82d4b4
parent 300947 2974a3e8359293611f4789cf1165c6317e119f1a
child 300949 3e9f480972b441c53802cace2cacbfb7510c53c6
push id19599
push usercbook@mozilla.com
push dateWed, 08 Jun 2016 10:16:21 +0000
treeherderfx-team@81f4cc3f6f4c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs1277278
milestone50.0a1
Bug 1277278 part 1 - Remove ContextOptions and make autoJSAPIOwnsErrorReporting the default. r=luke
dom/base/BodyUtil.cpp
dom/base/ScriptSettings.cpp
dom/base/ScriptSettings.h
dom/base/nsJSUtils.cpp
dom/bindings/Exceptions.cpp
dom/bindings/Exceptions.h
dom/bindings/ToJSValue.cpp
dom/promise/Promise.cpp
js/ipc/WrapperAnswer.cpp
js/src/frontend/TokenStream.cpp
js/src/jsapi-tests/testCallArgs.cpp
js/src/jsapi-tests/testProfileStrings.cpp
js/src/jsapi-tests/tests.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/shell/js.cpp
js/src/vm/SelfHosting.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
netwerk/base/ProxyAutoConfig.cpp
--- a/dom/base/BodyUtil.cpp
+++ b/dom/base/BodyUtil.cpp
@@ -545,17 +545,16 @@ BodyUtil::ConsumeText(uint32_t aInputLen
 
 // static
 void
 BodyUtil::ConsumeJson(JSContext* aCx, JS::MutableHandle<JS::Value> aValue,
                        const nsString& aStr, ErrorResult& aRv)
 {
   aRv.MightThrowJSException();
 
-  AutoForceSetExceptionOnContext forceExn(aCx);
   JS::Rooted<JS::Value> json(aCx);
   if (!JS_ParseJSON(aCx, aStr.get(), aStr.Length(), &json)) {
     if (!JS_IsExceptionPending(aCx)) {
       aRv.Throw(NS_ERROR_DOM_UNKNOWN_ERR);
       return;
     }
 
     JS::Rooted<JS::Value> exn(aCx);
--- a/dom/base/ScriptSettings.cpp
+++ b/dom/base/ScriptSettings.cpp
@@ -291,39 +291,31 @@ GetWebIDLCallerPrincipal()
     return nullptr;
   }
 
   return aes->mWebIDLCallerPrincipal;
 }
 
 AutoJSAPI::AutoJSAPI()
   : mCx(nullptr)
-  , mOldAutoJSAPIOwnsErrorReporting(false)
   , mIsMainThread(false) // For lack of anything better
 {
 }
 
 AutoJSAPI::~AutoJSAPI()
 {
   if (!mCx) {
     // No need to do anything here: we never managed to Init, so can't have an
     // exception on our (nonexistent) JSContext.  We also don't need to restore
     // any state on it.
     return;
   }
 
   ReportException();
 
-  // We need to do this _after_ processing the existing exception, because the
-  // JS engine can throw while doing that, and uses this bit to determine what
-  // to do in that case: squelch the exception if the bit is set, otherwise
-  // call the error reporter. Calling WarningOnlyErrorReporter with a
-  // non-warning will assert, so we need to make sure we do the former.
-  JS::ContextOptionsRef(cx()).setAutoJSAPIOwnsErrorReporting(mOldAutoJSAPIOwnsErrorReporting);
-
   if (mOldErrorReporter.isSome()) {
     JS_SetErrorReporter(JS_GetRuntime(cx()), mOldErrorReporter.value());
   }
 }
 
 void
 WarningOnlyErrorReporter(JSContext* aCx, const char* aMessage,
                          JSErrorReport* aRep);
@@ -353,18 +345,16 @@ AutoJSAPI::InitInternal(nsIGlobalObject*
     mAutoNullableCompartment.emplace(mCx, global);
   } else {
     mAutoNullableCompartment.emplace(mCx, aGlobal);
   }
 
   JSRuntime* rt = JS_GetRuntime(aCx);
   mOldErrorReporter.emplace(JS_GetErrorReporter(rt));
 
-  mOldAutoJSAPIOwnsErrorReporting = JS::ContextOptionsRef(aCx).autoJSAPIOwnsErrorReporting();
-  JS::ContextOptionsRef(aCx).setAutoJSAPIOwnsErrorReporting(true);
   JS_SetErrorReporter(rt, WarningOnlyErrorReporter);
 
 #ifdef DEBUG
   if (haveException) {
     JS::Rooted<JS::Value> exn(aCx);
     JS_GetPendingException(aCx, &exn);
 
     JS_ClearPendingException(aCx);
@@ -427,18 +417,17 @@ AutoJSAPI::InitInternal(nsIGlobalObject*
     MOZ_ASSERT(false, "We had an exception; we should not have");
   }
 #endif // DEBUG
 }
 
 AutoJSAPI::AutoJSAPI(nsIGlobalObject* aGlobalObject,
                      bool aIsMainThread,
                      JSContext* aCx)
-  : mOldAutoJSAPIOwnsErrorReporting(false)
-  , mIsMainThread(aIsMainThread)
+  : mIsMainThread(aIsMainThread)
 {
   MOZ_ASSERT(aGlobalObject);
   MOZ_ASSERT(aGlobalObject->GetGlobalJSObject(), "Must have a JS global");
   MOZ_ASSERT(aCx);
   MOZ_ASSERT(aIsMainThread == NS_IsMainThread());
 
   InitInternal(aGlobalObject, aGlobalObject->GetGlobalJSObject(), aCx,
                aIsMainThread);
--- a/dom/base/ScriptSettings.h
+++ b/dom/base/ScriptSettings.h
@@ -306,18 +306,16 @@ private:
   // while we're being used.  This _could_ become a JS::Rooted<JSObject*> if we
   // grabbed our JSContext in our constructor instead of waiting for Init(), so
   // we could construct this at that point.  It might be worth it do to that.
   RefPtr<nsIGlobalObject> mGlobalObject;
   mozilla::Maybe<danger::AutoCxPusher> mCxPusher;
   mozilla::Maybe<JSAutoNullableCompartment> mAutoNullableCompartment;
   JSContext *mCx;
 
-  // Track state between the old and new error reporting modes.
-  bool mOldAutoJSAPIOwnsErrorReporting;
   // Whether we're mainthread or not; set when we're initialized.
   bool mIsMainThread;
   Maybe<JSErrorReporter> mOldErrorReporter;
 
   void InitInternal(nsIGlobalObject* aGlobalObject, JSObject* aGlobal,
                     JSContext* aCx, bool aIsMainThread);
 
   AutoJSAPI(const AutoJSAPI&) = delete;
--- a/dom/base/nsJSUtils.cpp
+++ b/dom/base/nsJSUtils.cpp
@@ -144,18 +144,16 @@ nsJSUtils::EvaluateString(JSContext* aCx
                           JS::CompileOptions& aCompileOptions,
                           const EvaluateOptions& aEvaluateOptions,
                           JS::MutableHandle<JS::Value> aRetValue,
                           void **aOffThreadToken)
 {
   PROFILER_LABEL("nsJSUtils", "EvaluateString",
     js::ProfileEntry::Category::JS);
 
-  MOZ_ASSERT(JS::ContextOptionsRef(aCx).autoJSAPIOwnsErrorReporting(),
-             "Caller must own error reporting");
   MOZ_ASSERT_IF(aCompileOptions.versionSet,
                 aCompileOptions.version != JSVERSION_UNKNOWN);
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
   MOZ_ASSERT(aSrcBuf.get());
   MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aEvaluationGlobal) ==
              aEvaluationGlobal);
   MOZ_ASSERT_IF(aOffThreadToken, aCompileOptions.noScriptRval);
   MOZ_ASSERT(NS_IsMainThread());
@@ -273,18 +271,16 @@ nsJSUtils::CompileModule(JSContext* aCx,
                        JS::SourceBufferHolder& aSrcBuf,
                        JS::Handle<JSObject*> aEvaluationGlobal,
                        JS::CompileOptions &aCompileOptions,
                        JS::MutableHandle<JSObject*> aModule)
 {
   PROFILER_LABEL("nsJSUtils", "CompileModule",
     js::ProfileEntry::Category::JS);
 
-  MOZ_ASSERT(JS::ContextOptionsRef(aCx).autoJSAPIOwnsErrorReporting(),
-             "Caller must own error reporting");
   MOZ_ASSERT_IF(aCompileOptions.versionSet,
                 aCompileOptions.version != JSVERSION_UNKNOWN);
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
   MOZ_ASSERT(aSrcBuf.get());
   MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(aEvaluationGlobal) ==
              aEvaluationGlobal);
   MOZ_ASSERT(JS::CurrentGlobalOrNull(aCx) == aEvaluationGlobal);
   MOZ_ASSERT(NS_IsMainThread());
@@ -300,18 +296,16 @@ nsJSUtils::CompileModule(JSContext* aCx,
 }
 
 nsresult
 nsJSUtils::ModuleDeclarationInstantiation(JSContext* aCx, JS::Handle<JSObject*> aModule)
 {
   PROFILER_LABEL("nsJSUtils", "ModuleDeclarationInstantiation",
     js::ProfileEntry::Category::JS);
 
-  MOZ_ASSERT(JS::ContextOptionsRef(aCx).autoJSAPIOwnsErrorReporting(),
-             "Caller must own error reporting");
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(nsContentUtils::IsInMicroTask());
 
   NS_ENSURE_TRUE(xpc::Scriptability::Get(aModule).Allowed(), NS_OK);
 
   if (!JS::ModuleDeclarationInstantiation(aCx, aModule)) {
     return NS_ERROR_FAILURE;
@@ -321,18 +315,16 @@ nsJSUtils::ModuleDeclarationInstantiatio
 }
 
 nsresult
 nsJSUtils::ModuleEvaluation(JSContext* aCx, JS::Handle<JSObject*> aModule)
 {
   PROFILER_LABEL("nsJSUtils", "ModuleEvaluation",
     js::ProfileEntry::Category::JS);
 
-  MOZ_ASSERT(JS::ContextOptionsRef(aCx).autoJSAPIOwnsErrorReporting(),
-             "Caller must own error reporting");
   MOZ_ASSERT(aCx == nsContentUtils::GetCurrentJSContext());
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_ASSERT(nsContentUtils::IsInMicroTask());
 
   NS_ENSURE_TRUE(xpc::Scriptability::Get(aModule).Allowed(), NS_OK);
 
   if (!JS::ModuleEvaluation(aCx, aModule)) {
     return NS_ERROR_FAILURE;
--- a/dom/bindings/Exceptions.cpp
+++ b/dom/bindings/Exceptions.cpp
@@ -201,28 +201,16 @@ GetCurrentJSStack(int32_t aMaxDepth)
 
   if (!cx || !js::GetContextCompartment(cx)) {
     return nullptr;
   }
 
   return dom::exceptions::CreateStack(cx, aMaxDepth);
 }
 
-AutoForceSetExceptionOnContext::AutoForceSetExceptionOnContext(JSContext* aCx)
-  : mCx(aCx)
-{
-  mOldValue = JS::ContextOptionsRef(mCx).autoJSAPIOwnsErrorReporting();
-  JS::ContextOptionsRef(mCx).setAutoJSAPIOwnsErrorReporting(true);
-}
-
-AutoForceSetExceptionOnContext::~AutoForceSetExceptionOnContext()
-{
-  JS::ContextOptionsRef(mCx).setAutoJSAPIOwnsErrorReporting(mOldValue);
-}
-
 namespace exceptions {
 
 class JSStackFrame : public nsIStackFrame
 {
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(JSStackFrame)
   NS_DECL_NSISTACKFRAME
--- a/dom/bindings/Exceptions.h
+++ b/dom/bindings/Exceptions.h
@@ -49,29 +49,16 @@ CreateException(JSContext* aCx, nsresult
                 const nsACString& aMessage = EmptyCString());
 
 // aMaxDepth can be used to define a maximal depth for the stack trace. If the
 // value is -1, a default maximal depth will be selected.  Will return null if
 // there is no JS stack right now.
 already_AddRefed<nsIStackFrame>
 GetCurrentJSStack(int32_t aMaxDepth = -1);
 
-// Throwing a TypeError on an ErrorResult may result in SpiderMonkey using its
-// own error reporting mechanism instead of just setting the exception on the
-// context.  This happens if no script is running. Bug 1107777 adds a flag that
-// forcibly turns this behaviour off. This is a stack helper to set the flag.
-class MOZ_STACK_CLASS AutoForceSetExceptionOnContext {
-private:
-  JSContext* mCx;
-  bool mOldValue;
-public:
-  explicit AutoForceSetExceptionOnContext(JSContext* aCx);
-  ~AutoForceSetExceptionOnContext();
-};
-
 // Internal stuff not intended to be widely used.
 namespace exceptions {
 
 // aMaxDepth can be used to define a maximal depth for the stack trace. If the
 // value is -1, a default maximal depth will be selected.  Will return null if
 // there is no JS stack right now.
 already_AddRefed<nsIStackFrame>
 CreateStack(JSContext* aCx, int32_t aMaxDepth = -1);
--- a/dom/bindings/ToJSValue.cpp
+++ b/dom/bindings/ToJSValue.cpp
@@ -53,17 +53,16 @@ ToJSValue(JSContext* aCx,
 bool
 ToJSValue(JSContext* aCx,
           ErrorResult& aArgument,
           JS::MutableHandle<JS::Value> aValue)
 {
   MOZ_ASSERT(aArgument.Failed());
   MOZ_ASSERT(!aArgument.IsUncatchableException(),
              "Doesn't make sense to convert uncatchable exception to a JS value!");
-  AutoForceSetExceptionOnContext forceExn(aCx);
   DebugOnly<bool> throwResult = aArgument.MaybeSetPendingException(aCx);
   MOZ_ASSERT(throwResult);
   DebugOnly<bool> getPendingResult = JS_GetPendingException(aCx, aValue);
   MOZ_ASSERT(getPendingResult);
   JS_ClearPendingException(aCx);
   return true;
 }
 
--- a/dom/promise/Promise.cpp
+++ b/dom/promise/Promise.cpp
@@ -2618,17 +2618,16 @@ Promise::ResolveInternal(JSContext* aCx,
 {
   NS_ASSERT_OWNINGTHREAD(Promise);
 
   CycleCollectedJSRuntime* runtime = CycleCollectedJSRuntime::Get();
 
   mResolvePending = true;
 
   if (aValue.isObject()) {
-    MOZ_ASSERT(JS::ContextOptionsRef(aCx).autoJSAPIOwnsErrorReporting());
     JS::Rooted<JSObject*> valueObj(aCx, &aValue.toObject());
 
     // Thenables.
     JS::Rooted<JS::Value> then(aCx);
     if (!JS_GetProperty(aCx, valueObj, "then", &then)) {
       HandleException(aCx);
       return;
     }
--- a/js/ipc/WrapperAnswer.cpp
+++ b/js/ipc/WrapperAnswer.cpp
@@ -405,17 +405,16 @@ WrapperAnswer::RecvCallOrConstruct(const
                 return fail(aes, rs);
             if (!vals.append(v))
                 return fail(aes, rs);
         }
     }
 
     RootedValue rval(cx);
     {
-        MOZ_ASSERT(JS::ContextOptionsRef(cx).autoJSAPIOwnsErrorReporting());
         HandleValueArray args = HandleValueArray::subarray(vals, 2, vals.length() - 2);
         if (construct) {
             RootedObject obj(cx);
             if (!JS::Construct(cx, vals[0], args, &obj))
                 return fail(aes, rs);
             rval.setObject(*obj);
         } else {
             if(!JS::Call(cx, vals[1], vals[0], args, &rval))
--- a/js/src/frontend/TokenStream.cpp
+++ b/js/src/frontend/TokenStream.cpp
@@ -579,17 +579,17 @@ CompileError::throwError(JSContext* cx)
     // returns false, the top-level reporter will eventually receive the
     // uncaught exception report.
     if (ErrorToException(cx, message, &report, nullptr, nullptr))
         return;
 
     // Like ReportError, don't call the error reporter if the embedding is
     // responsible for handling exceptions. In this case the error reporter
     // must only be used for warnings.
-    if (cx->options().autoJSAPIOwnsErrorReporting() && !JSREPORT_IS_WARNING(report.flags))
+    if (!JSREPORT_IS_WARNING(report.flags))
         return;
 
     CallErrorReporter(cx, message, &report);
 }
 
 CompileError::~CompileError()
 {
     js_free((void*)report.linebuf());
--- a/js/src/jsapi-tests/testCallArgs.cpp
+++ b/js/src/jsapi-tests/testCallArgs.cpp
@@ -37,26 +37,16 @@ BEGIN_TEST(testCallArgs_isConstructing_n
     CHECK(JS_IsExceptionPending(cx));
     JS_ClearPendingException(cx);
 
     EVAL("customNative();", &result);
     CHECK(result.isUndefined());
 
     return true;
 }
-
-virtual bool init() override
-{
-    if (!JSAPITest::init())
-        return false;
-
-    JS::ContextOptionsRef(cx).setAutoJSAPIOwnsErrorReporting(true);
-
-    return true;
-}
 END_TEST(testCallArgs_isConstructing_native)
 
 static bool
 CustomConstructor(JSContext* cx, unsigned argc, JS::Value* vp)
 {
     JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
 
     MOZ_RELEASE_ASSERT(!JS_IsExceptionPending(cx));
@@ -88,19 +78,9 @@ BEGIN_TEST(testCallArgs_isConstructing_c
     EVAL("new customConstructor();", &result);
     CHECK(result.isObject());
 
     EVAL("customConstructor();", &result);
     CHECK(result.isUndefined());
 
     return true;
 }
-
-virtual bool init() override
-{
-    if (!JSAPITest::init())
-        return false;
-
-    JS::ContextOptionsRef(cx).setAutoJSAPIOwnsErrorReporting(true);
-
-    return true;
-}
 END_TEST(testCallArgs_isConstructing_constructor)
--- a/js/src/jsapi-tests/testProfileStrings.cpp
+++ b/js/src/jsapi-tests/testProfileStrings.cpp
@@ -198,17 +198,16 @@ BEGIN_TEST(testProfileStrings_isCalledWh
 {
     CHECK(initialize(cx));
     JS::RuntimeOptionsRef(cx).setBaseline(true)
                              .setIon(true);
 
     EXEC("function check2() { throw 'a'; }");
 
     reset(cx);
-    JS::ContextOptionsRef(cx).setDontReportUncaught(true);
     {
         JS::RootedValue rval(cx);
         /* Make sure the stack resets and we have an entry for each stack */
         bool ok = JS_CallFunctionName(cx, global, "check2", JS::HandleValueArray::empty(),
                                       &rval);
         CHECK(!ok);
         CHECK(psize == 0);
         CHECK(cx->runtime()->spsProfiler.stringsCount() == 1);
--- a/js/src/jsapi-tests/tests.h
+++ b/js/src/jsapi-tests/tests.h
@@ -307,23 +307,17 @@ class JSAPITest
 
         fprintf(stderr, "%s:%u:%s\n",
                 report->filename ? report->filename : "<no filename>",
                 (unsigned int) report->lineno,
                 message);
     }
 
     virtual JSContext* createContext() {
-        JSContext* cx = JS_NewContext(rt, 8192);
-        if (!cx)
-            return nullptr;
-
-        JS::ContextOptionsRef(cx).setDontReportUncaught(true);
-        JS::ContextOptionsRef(cx).setAutoJSAPIOwnsErrorReporting(true);
-        return cx;
+        return JS_NewContext(rt, 8192);
     }
 
     virtual const JSClass * getGlobalClass() {
         return basicGlobalClass();
     }
 
     virtual JSObject * createGlobal(JSPrincipals* principals = nullptr);
 };
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -695,22 +695,16 @@ JS::RuntimeOptionsRef(JSRuntime* rt)
 }
 
 JS_PUBLIC_API(JS::RuntimeOptions&)
 JS::RuntimeOptionsRef(JSContext* cx)
 {
     return cx->runtime()->options();
 }
 
-JS_PUBLIC_API(JS::ContextOptions&)
-JS::ContextOptionsRef(JSContext* cx)
-{
-    return cx->options();
-}
-
 JS_PUBLIC_API(const char*)
 JS_GetImplementationVersion(void)
 {
     return "JavaScript-C" MOZILLA_VERSION;
 }
 
 JS_PUBLIC_API(void)
 JS_SetDestroyCompartmentCallback(JSRuntime* rt, JSDestroyCompartmentCallback callback)
@@ -2820,48 +2814,24 @@ JS::IsCallable(JSObject* obj)
 }
 
 JS_PUBLIC_API(bool)
 JS::IsConstructor(JSObject* obj)
 {
     return obj->isConstructor();
 }
 
-struct AutoLastFrameCheck
-{
-    explicit AutoLastFrameCheck(JSContext* cx
-                                MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
-      : cx(cx)
-    {
-        MOZ_ASSERT(cx);
-        MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-    }
-
-    ~AutoLastFrameCheck() {
-        if (cx->isExceptionPending() &&
-            !JS_IsRunning(cx) &&
-            (!cx->options().dontReportUncaught() && !cx->options().autoJSAPIOwnsErrorReporting())) {
-            ReportUncaughtException(cx);
-        }
-    }
-
-  private:
-    JSContext* cx;
-    MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
-};
-
 JS_PUBLIC_API(bool)
 JS_CallFunctionValue(JSContext* cx, HandleObject obj, HandleValue fval, const HandleValueArray& args,
                      MutableHandleValue rval)
 {
     MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, fval, args);
-    AutoLastFrameCheck lfc(cx);
 
     InvokeArgs iargs(cx);
     if (!FillArgumentsFromArraylike(cx, iargs, args))
         return false;
 
     RootedValue thisv(cx, ObjectOrNullValue(obj));
     return Call(cx, fval, thisv, iargs, rval);
 }
@@ -2869,17 +2839,16 @@ JS_CallFunctionValue(JSContext* cx, Hand
 JS_PUBLIC_API(bool)
 JS_CallFunction(JSContext* cx, HandleObject obj, HandleFunction fun, const HandleValueArray& args,
                 MutableHandleValue rval)
 {
     MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, fun, args);
-    AutoLastFrameCheck lfc(cx);
 
     InvokeArgs iargs(cx);
     if (!FillArgumentsFromArraylike(cx, iargs, args))
         return false;
 
     RootedValue fval(cx, ObjectValue(*fun));
     RootedValue thisv(cx, ObjectOrNullValue(obj));
     return Call(cx, fval, thisv, iargs, rval);
@@ -2888,17 +2857,16 @@ JS_CallFunction(JSContext* cx, HandleObj
 JS_PUBLIC_API(bool)
 JS_CallFunctionName(JSContext* cx, HandleObject obj, const char* name, const HandleValueArray& args,
                     MutableHandleValue rval)
 {
     MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, obj, args);
-    AutoLastFrameCheck lfc(cx);
 
     JSAtom* atom = Atomize(cx, name, strlen(name));
     if (!atom)
         return false;
 
     RootedValue fval(cx);
     RootedId id(cx, AtomToId(atom));
     if (!GetProperty(cx, obj, obj, id, &fval))
@@ -2914,33 +2882,31 @@ JS_CallFunctionName(JSContext* cx, Handl
 
 JS_PUBLIC_API(bool)
 JS::Call(JSContext* cx, HandleValue thisv, HandleValue fval, const JS::HandleValueArray& args,
          MutableHandleValue rval)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, thisv, fval, args);
-    AutoLastFrameCheck lfc(cx);
 
     InvokeArgs iargs(cx);
     if (!FillArgumentsFromArraylike(cx, iargs, args))
         return false;
 
     return Call(cx, fval, thisv, iargs, rval);
 }
 
 JS_PUBLIC_API(bool)
 JS::Construct(JSContext* cx, HandleValue fval, HandleObject newTarget, const JS::HandleValueArray& args,
               MutableHandleObject objp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, fval, newTarget, args);
-    AutoLastFrameCheck lfc(cx);
 
     if (!IsConstructor(fval)) {
         ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, JSDVG_IGNORE_STACK, fval, nullptr);
         return false;
     }
 
     RootedValue newTargetVal(cx, ObjectValue(*newTarget));
     if (!IsConstructor(newTargetVal)) {
@@ -2957,17 +2923,16 @@ JS::Construct(JSContext* cx, HandleValue
 
 JS_PUBLIC_API(bool)
 JS::Construct(JSContext* cx, HandleValue fval, const JS::HandleValueArray& args,
               MutableHandleObject objp)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, fval, args);
-    AutoLastFrameCheck lfc(cx);
 
     if (!IsConstructor(fval)) {
         ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, JSDVG_IGNORE_STACK, fval, nullptr);
         return false;
     }
 
     ConstructArgs cargs(cx);
     if (!FillArgumentsFromArraylike(cx, cargs, args))
@@ -3989,17 +3954,16 @@ enum SyntacticScopeOption { HasSyntactic
 
 static bool
 Compile(JSContext* cx, const ReadOnlyCompileOptions& options, SyntacticScopeOption scopeOption,
         SourceBufferHolder& srcBuf, MutableHandleScript script)
 {
     MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
-    AutoLastFrameCheck lfc(cx);
 
     Rooted<StaticScope*> staticScope(cx, &cx->global()->lexicalScope().staticBlock());
     if (scopeOption == HasNonSyntacticScope) {
         staticScope = StaticNonSyntacticScope::create(cx, staticScope);
         if (!staticScope)
             return false;
     }
 
@@ -4158,53 +4122,33 @@ JS::CompileOffThread(JSContext* cx, cons
     MOZ_ASSERT(CanCompileOffThread(cx, options, length));
     return StartOffThreadParseScript(cx, options, chars, length, callback, callbackData);
 }
 
 JS_PUBLIC_API(JSScript*)
 JS::FinishOffThreadScript(JSContext* maybecx, JSRuntime* rt, void* token)
 {
     MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
-
-    if (maybecx) {
-        RootedScript script(maybecx);
-        {
-            AutoLastFrameCheck lfc(maybecx);
-            script = HelperThreadState().finishScriptParseTask(maybecx, rt, token);
-        }
-        return script;
-    } else {
-        return HelperThreadState().finishScriptParseTask(maybecx, rt, token);
-    }
+    return HelperThreadState().finishScriptParseTask(maybecx, rt, token);
 }
 
 JS_PUBLIC_API(bool)
 JS::CompileOffThreadModule(JSContext* cx, const ReadOnlyCompileOptions& options,
                            const char16_t* chars, size_t length,
                            OffThreadCompileCallback callback, void* callbackData)
 {
     MOZ_ASSERT(CanCompileOffThread(cx, options, length));
     return StartOffThreadParseModule(cx, options, chars, length, callback, callbackData);
 }
 
 JS_PUBLIC_API(JSObject*)
 JS::FinishOffThreadModule(JSContext* maybecx, JSRuntime* rt, void* token)
 {
     MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt));
-
-    if (maybecx) {
-        RootedObject module(maybecx);
-        {
-            AutoLastFrameCheck lfc(maybecx);
-            module = HelperThreadState().finishModuleParseTask(maybecx, rt, token);
-        }
-        return module;
-    } else {
-        return HelperThreadState().finishModuleParseTask(maybecx, rt, token);
-    }
+    return HelperThreadState().finishModuleParseTask(maybecx, rt, token);
 }
 
 JS_PUBLIC_API(bool)
 JS_CompileScript(JSContext* cx, const char* ascii, size_t length,
                  const JS::CompileOptions& options, MutableHandleScript script)
 {
     return Compile(cx, options, ascii, length, script);
 }
@@ -4306,17 +4250,16 @@ CompileFunction(JSContext* cx, const Rea
                 MutableHandleFunction fun)
 {
     MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, enclosingDynamicScope);
     assertSameCompartment(cx, enclosingStaticScope);
     RootedAtom funAtom(cx);
-    AutoLastFrameCheck lfc(cx);
 
     if (name) {
         funAtom = Atomize(cx, name, strlen(name));
         if (!funAtom)
             return false;
     }
 
     Rooted<PropertyNameVector> formals(cx, PropertyNameVector(cx));
@@ -4418,17 +4361,16 @@ JS_DecompileFunction(JSContext* cx, Hand
 MOZ_NEVER_INLINE static bool
 ExecuteScript(JSContext* cx, HandleObject scope, HandleScript script, Value* rval)
 {
     MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, scope, script);
     MOZ_ASSERT_IF(!IsGlobalLexicalScope(scope), script->hasNonSyntacticScope());
-    AutoLastFrameCheck lfc(cx);
     return Execute(cx, script, *scope, rval);
 }
 
 static bool
 ExecuteScript(JSContext* cx, AutoObjectVector& scopeChain, HandleScript scriptArg, Value* rval)
 {
     RootedObject dynamicScope(cx);
     Rooted<StaticScope*> staticScope(cx);
@@ -4498,18 +4440,16 @@ Evaluate(JSContext* cx, HandleObject sco
          SourceBufferHolder& srcBuf, MutableHandleValue rval)
 {
     CompileOptions options(cx, optionsArg);
     MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, scope);
 
-    AutoLastFrameCheck lfc(cx);
-
     MOZ_ASSERT_IF(!IsGlobalLexicalScope(scope), HasNonSyntacticStaticScopeChain(staticScope));
 
     options.setIsRunOnce(true);
     SourceCompressionTask sct(cx);
     RootedScript script(cx, frontend::CompileScript(cx, &cx->tempLifoAlloc(),
                                                     scope, staticScope,
                                                     /* evalCaller = */ nullptr, options,
                                                     srcBuf, /* source = */ nullptr, &sct));
@@ -4651,18 +4591,16 @@ JS::SetModuleResolveHook(JSContext* cx, 
 JS_PUBLIC_API(bool)
 JS::CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
                   SourceBufferHolder& srcBuf, JS::MutableHandleObject module)
 {
     MOZ_ASSERT(!cx->runtime()->isAtomsCompartment(cx->compartment()));
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
 
-    AutoLastFrameCheck lfc(cx);
-
     module.set(frontend::CompileModule(cx, options, srcBuf));
     return !!module;
 }
 
 JS_PUBLIC_API(void)
 JS::SetModuleHostDefinedField(JSObject* module, JS::Value value)
 {
     module->as<ModuleObject>().setHostDefinedField(value);
@@ -4705,18 +4643,18 @@ JS_PUBLIC_API(JSScript*)
 JS::GetModuleScript(JSContext* cx, JS::HandleObject moduleArg)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, moduleArg);
     return moduleArg->as<ModuleObject>().script();
 }
 
-static JSObject*
-JS_NewHelper(JSContext* cx, HandleObject ctor, const JS::HandleValueArray& inputArgs)
+JS_PUBLIC_API(JSObject*)
+JS_New(JSContext* cx, HandleObject ctor, const JS::HandleValueArray& inputArgs)
 {
     AssertHeapIsIdle(cx);
     CHECK_REQUEST(cx);
     assertSameCompartment(cx, ctor, inputArgs);
 
     RootedValue ctorVal(cx, ObjectValue(*ctor));
     if (!IsConstructor(ctorVal)) {
         ReportValueError(cx, JSMSG_NOT_CONSTRUCTOR, JSDVG_IGNORE_STACK, ctorVal, nullptr);
@@ -4729,27 +4667,16 @@ JS_NewHelper(JSContext* cx, HandleObject
 
     RootedObject obj(cx);
     if (!js::Construct(cx, ctorVal, args, ctorVal, &obj))
         return nullptr;
 
     return obj;
 }
 
-JS_PUBLIC_API(JSObject*)
-JS_New(JSContext* cx, HandleObject ctor, const JS::HandleValueArray& inputArgs)
-{
-    RootedObject obj(cx);
-    {
-        AutoLastFrameCheck lfc(cx);
-        obj = JS_NewHelper(cx, ctor, inputArgs);
-    }
-    return obj;
-}
-
 JS_PUBLIC_API(bool)
 JS_CheckForInterrupt(JSContext* cx)
 {
     return js::CheckForInterrupt(cx);
 }
 
 JS_PUBLIC_API(JSInterruptCallback)
 JS_SetInterruptCallback(JSRuntime* rt, JSInterruptCallback callback)
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1263,79 +1263,16 @@ class JS_PUBLIC_API(RuntimeOptions) {
 };
 
 JS_PUBLIC_API(RuntimeOptions&)
 RuntimeOptionsRef(JSRuntime* rt);
 
 JS_PUBLIC_API(RuntimeOptions&)
 RuntimeOptionsRef(JSContext* cx);
 
-class JS_PUBLIC_API(ContextOptions) {
-  public:
-    ContextOptions()
-      : dontReportUncaught_(false),
-        autoJSAPIOwnsErrorReporting_(false)
-    {
-    }
-
-    bool dontReportUncaught() const { return dontReportUncaught_; }
-    ContextOptions& setDontReportUncaught(bool flag) {
-        dontReportUncaught_ = flag;
-        return *this;
-    }
-    ContextOptions& toggleDontReportUncaught() {
-        dontReportUncaught_ = !dontReportUncaught_;
-        return *this;
-    }
-
-    bool autoJSAPIOwnsErrorReporting() const { return autoJSAPIOwnsErrorReporting_; }
-    ContextOptions& setAutoJSAPIOwnsErrorReporting(bool flag) {
-        autoJSAPIOwnsErrorReporting_ = flag;
-        return *this;
-    }
-    ContextOptions& toggleAutoJSAPIOwnsErrorReporting() {
-        autoJSAPIOwnsErrorReporting_ = !autoJSAPIOwnsErrorReporting_;
-        return *this;
-    }
-
-
-  private:
-    bool privateIsNSISupports_ : 1;
-    bool dontReportUncaught_ : 1;
-    // dontReportUncaught isn't respected by all JSAPI codepaths, particularly the
-    // JS_ReportError* functions that eventually report the error even when dontReportUncaught is
-    // set, if script is not running. We want a way to indicate that the embedder will always
-    // handle any exceptions, and that SpiderMonkey should just leave them on the context. This is
-    // the way we want to do all future error handling in Gecko - stealing the exception explicitly
-    // from the context and handling it as per the situation. This will eventually become the
-    // default and these 2 flags should go away.
-    bool autoJSAPIOwnsErrorReporting_ : 1;
-};
-
-JS_PUBLIC_API(ContextOptions&)
-ContextOptionsRef(JSContext* cx);
-
-class JS_PUBLIC_API(AutoSaveContextOptions) {
-  public:
-    explicit AutoSaveContextOptions(JSContext* cx)
-      : cx_(cx),
-        oldOptions_(ContextOptionsRef(cx_))
-    {
-    }
-
-    ~AutoSaveContextOptions()
-    {
-        ContextOptionsRef(cx_) = oldOptions_;
-    }
-
-  private:
-    JSContext* cx_;
-    JS::ContextOptions oldOptions_;
-};
-
 } /* namespace JS */
 
 extern JS_PUBLIC_API(const char*)
 JS_GetImplementationVersion(void);
 
 extern JS_PUBLIC_API(void)
 JS_SetDestroyCompartmentCallback(JSRuntime* rt, JSDestroyCompartmentCallback callback);
 
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -220,27 +220,25 @@ ReportError(JSContext* cx, const char* m
      */
     MOZ_ASSERT(reportp);
     if ((!callback || callback == GetErrorMessage) &&
         reportp->errorNumber == JSMSG_UNCAUGHT_EXCEPTION)
     {
         reportp->flags |= JSREPORT_EXCEPTION;
     }
 
-    if (cx->options().autoJSAPIOwnsErrorReporting() || JS_IsRunning(cx)) {
-        if (ErrorToException(cx, message, reportp, callback, userRef))
-            return;
+    if (ErrorToException(cx, message, reportp, callback, userRef))
+        return;
 
-        /*
-         * The AutoJSAPI error reporter only allows warnings to be reported so
-         * just ignore this error rather than try to report it.
-         */
-        if (cx->options().autoJSAPIOwnsErrorReporting() && !JSREPORT_IS_WARNING(reportp->flags))
-            return;
-    }
+    /*
+     * The AutoJSAPI error reporter only allows warnings to be reported so
+     * just ignore this error rather than try to report it.
+     */
+    if (!JSREPORT_IS_WARNING(reportp->flags))
+        return;
 
     /*
      * Call the error reporter only if an exception wasn't raised.
      */
     if (message)
         CallErrorReporter(cx, message, reportp);
 }
 
@@ -299,46 +297,17 @@ js::ReportOutOfMemory(ExclusiveContext* 
     JSContext* cx = cxArg->asJSContext();
     cx->runtime()->hadOutOfMemory = true;
     AutoSuppressGC suppressGC(cx);
 
     /* Report the oom. */
     if (JS::OutOfMemoryCallback oomCallback = cx->runtime()->oomCallback)
         oomCallback(cx, cx->runtime()->oomCallbackData);
 
-    if (cx->options().autoJSAPIOwnsErrorReporting() || JS_IsRunning(cx)) {
-        cx->setPendingException(StringValue(cx->names().outOfMemory));
-        return;
-    }
-
-    /* Get the message for this error, but we don't expand any arguments. */
-    const JSErrorFormatString* efs = GetErrorMessage(nullptr, JSMSG_OUT_OF_MEMORY);
-    const char* msg = efs ? efs->format : "Out of memory";
-
-    /* Fill out the report, but don't do anything that requires allocation. */
-    JSErrorReport report;
-    report.flags = JSREPORT_ERROR;
-    report.errorNumber = JSMSG_OUT_OF_MEMORY;
-    PopulateReportBlame(cx, &report);
-
-    /* Report the error. */
-    if (JSErrorReporter onError = cx->runtime()->errorReporter)
-        onError(cx, msg, &report);
-
-    /*
-     * We would like to enforce the invariant that any exception reported
-     * during an OOM situation does not require wrapping. Besides avoiding
-     * allocation when memory is low, this reduces the number of places where
-     * we might need to GC.
-     *
-     * When JS code is running, we set the pending exception to an atom, which
-     * does not need wrapping. If no JS code is running, no exception should be
-     * set at all.
-     */
-    MOZ_ASSERT(!cx->isExceptionPending());
+    cx->setPendingException(StringValue(cx->names().outOfMemory));
 }
 
 void
 js::ReportOverRecursed(JSContext* maybecx, unsigned errorNumber)
 {
 #ifdef JS_MORE_DETERMINISTIC
     /*
      * We cannot make stack depth deterministic across different
@@ -959,17 +928,16 @@ ExclusiveContext::recoverFromOutOfMemory
     if (ParseTask* task = helperThread()->parseTask())
         task->outOfMemory = false;
 }
 
 JSContext::JSContext(JSRuntime* rt)
   : ExclusiveContext(rt, &rt->mainThread, Context_JS),
     throwing(false),
     unwrappedException_(this),
-    options_(),
     overRecursed_(false),
     propagatingForcedReturn_(false),
     liveVolatileJitFrameIterators_(nullptr),
     reportGranularity(JS_DEFAULT_JITREPORT_GRANULARITY),
     resolvingList(nullptr),
     generatingError(false),
     cycleDetectorSet(this),
     data(nullptr),
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -316,19 +316,16 @@ struct JSContext : public js::ExclusiveC
     friend class js::jit::DebugModeOSRVolatileJitFrameIterator;
     friend void js::ReportOverRecursed(JSContext*, unsigned errorNumber);
 
   private:
     /* Exception state -- the exception member is a GC root by definition. */
     bool                throwing;            /* is there a pending exception? */
     JS::PersistentRooted<JS::Value> unwrappedException_; /* most-recently-thrown exception */
 
-    /* Per-context options. */
-    JS::ContextOptions  options_;
-
     // True if the exception currently being thrown is by result of
     // ReportOverRecursed. See Debugger::slowPathOnExceptionUnwind.
     bool                overRecursed_;
 
     // True if propagating a forced return from an interrupt handler during
     // debug mode.
     bool                propagatingForcedReturn_;
 
@@ -358,24 +355,16 @@ struct JSContext : public js::ExclusiveC
      * - The newest scripted frame's version, if there is such a frame.
      * - The version from the compartment.
      * - The default version.
      *
      * Note: if this ever shows up in a profile, just add caching!
      */
     JSVersion findVersion() const;
 
-    const JS::ContextOptions& options() const {
-        return options_;
-    }
-
-    JS::ContextOptions& options() {
-        return options_;
-    }
-
     js::LifoAlloc& tempLifoAlloc() { return runtime()->tempLifoAlloc; }
 
     unsigned            outstandingRequests;/* number of JS_BeginRequest calls
                                                without the corresponding
                                                JS_EndRequest. */
 
     bool jitIsBroken;
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -6448,19 +6448,16 @@ static const JS::AsmJSCacheOps asmJSCach
 
 static JSContext*
 NewContext(JSRuntime* rt)
 {
     JSContext* cx = JS_NewContext(rt, gStackChunkSize);
     if (!cx)
         return nullptr;
 
-    JS::ContextOptionsRef(cx).setDontReportUncaught(true);
-    JS::ContextOptionsRef(cx).setAutoJSAPIOwnsErrorReporting(true);
-
     JSShellContextData* data = NewContextData();
     if (!data) {
         DestroyContext(cx, false);
         return nullptr;
     }
 
     JS_SetContextPrivate(cx, data);
     return cx;
--- a/js/src/vm/SelfHosting.cpp
+++ b/js/src/vm/SelfHosting.cpp
@@ -2709,35 +2709,25 @@ MaybePrintAndClearPendingException(JSCon
 
     MOZ_ASSERT(!JSREPORT_IS_WARNING(report.report()->flags));
     PrintError(cx, file, report.message(), report.report(), true);
 }
 
 class MOZ_STACK_CLASS AutoSelfHostingErrorReporter
 {
     JSContext* cx_;
-    bool prevDontReportUncaught_;
-    bool prevAutoJSAPIOwnsErrorReporting_;
     JSErrorReporter oldReporter_;
 
   public:
     explicit AutoSelfHostingErrorReporter(JSContext* cx)
-      : cx_(cx),
-        prevDontReportUncaught_(cx_->options().dontReportUncaught()),
-        prevAutoJSAPIOwnsErrorReporting_(cx_->options().autoJSAPIOwnsErrorReporting())
+      : cx_(cx)
     {
-        cx_->options().setDontReportUncaught(true);
-        cx_->options().setAutoJSAPIOwnsErrorReporting(true);
-
         oldReporter_ = JS_SetErrorReporter(cx_->runtime(), selfHosting_WarningReporter);
     }
     ~AutoSelfHostingErrorReporter() {
-        cx_->options().setDontReportUncaught(prevDontReportUncaught_);
-        cx_->options().setAutoJSAPIOwnsErrorReporting(prevAutoJSAPIOwnsErrorReporting_);
-
         JS_SetErrorReporter(cx_->runtime(), oldReporter_);
 
         // Exceptions in self-hosted code will usually be printed to stderr in
         // ErrorToException, but not all exceptions are handled there. For
         // instance, ReportOutOfMemory will throw the "out of memory" string
         // without going through ErrorToException. We handle these other
         // exceptions here.
         MaybePrintAndClearPendingException(cx_, stderr);
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -234,17 +234,16 @@ nsXPCWrappedJSClass::CallQueryInterfaceO
 
     id = xpc_NewIDObject(cx, jsobj, aIID);
     if (id) {
         // Throwing NS_NOINTERFACE is the prescribed way to fail QI from JS. It
         // is not an exception that is ever worth reporting, but we don't want
         // to eat all exceptions either.
 
         {
-            MOZ_ASSERT(JS::ContextOptionsRef(cx).autoJSAPIOwnsErrorReporting());
             RootedValue arg(cx, JS::ObjectValue(*id));
             success = JS_CallFunctionValue(cx, jsobj, fun, HandleValueArray(arg), &retval);
         }
 
         if (!success && JS_IsExceptionPending(cx)) {
             RootedValue jsexception(cx, NullValue());
 
             if (JS_GetPendingException(cx, &jsexception)) {
@@ -269,18 +268,16 @@ nsXPCWrappedJSClass::CallQueryInterfaceO
                         rv = (nsresult)(uint32_t)(jsexception.toDouble());
                     else
                         rv = (nsresult)(jsexception.toInt32());
 
                     if (rv == NS_NOINTERFACE)
                         JS_ClearPendingException(cx);
                 }
             }
-
-            MOZ_ASSERT(ContextOptionsRef(cx).autoJSAPIOwnsErrorReporting());
         } else if (!success) {
             NS_WARNING("QI hook ran OOMed - this is probably a bug!");
         }
     }
 
     if (success)
         success = JS_ValueToObject(cx, retval, &retObj);
 
@@ -1208,17 +1205,16 @@ pre_call_clean_up:
     RootedValue rval(cx);
     if (XPT_MD_IS_GETTER(info->flags)) {
         success = JS_GetProperty(cx, obj, name, &rval);
     } else if (XPT_MD_IS_SETTER(info->flags)) {
         rval = *argv;
         success = JS_SetProperty(cx, obj, name, rval);
     } else {
         if (!fval.isPrimitive()) {
-            MOZ_ASSERT(JS::ContextOptionsRef(cx).autoJSAPIOwnsErrorReporting());
             success = JS_CallFunctionValue(cx, thisObj, fval, args, &rval);
         } else {
             // The property was not an object so can't be a function.
             // Let's build and 'throw' an exception.
 
             static const nsresult code =
                     NS_ERROR_XPC_JSOBJECT_HAS_NO_FUNCTION_NAMED;
             static const char format[] = "%s \"%s\"";
--- a/netwerk/base/ProxyAutoConfig.cpp
+++ b/netwerk/base/ProxyAutoConfig.cpp
@@ -682,18 +682,16 @@ private:
      */
     JS_SetNativeStackQuota(mRuntime, 128 * sizeof(size_t) * 1024);
 
     JS_SetErrorReporter(mRuntime, PACWarningReporter);
 
     mContext = JS_NewContext(mRuntime, 0);
     NS_ENSURE_TRUE(mContext, NS_ERROR_OUT_OF_MEMORY);
 
-    JS::ContextOptionsRef(mContext).setAutoJSAPIOwnsErrorReporting(true);
-
     JSAutoRequest ar(mContext);
 
     JS::CompartmentOptions options;
     options.creationOptions().setZone(JS::SystemZone);
     options.behaviors().setVersion(JSVERSION_LATEST);
     mGlobal = JS_NewGlobalObject(mContext, &sGlobalClass, nullptr,
                                  JS::DontFireOnNewGlobalHook, options);
     if (!mGlobal) {