mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1277278 part 1 - Remove ContextOptions and make autoJSAPIOwnsErrorReporting the default. r=luke
--HG-- extra : rebase_source : aa1dcba100a3bb7a5057b07284cf4a99353afe5a
This commit is contained in:
parent
825b101112
commit
66faed38af
@ -550,7 +550,6 @@ BodyUtil::ConsumeJson(JSContext* aCx, JS::MutableHandle<JS::Value> aValue,
|
||||
{
|
||||
aRv.MightThrowJSException();
|
||||
|
||||
AutoForceSetExceptionOnContext forceExn(aCx);
|
||||
JS::Rooted<JS::Value> json(aCx);
|
||||
if (!JS_ParseJSON(aCx, aStr.get(), aStr.Length(), &json)) {
|
||||
if (!JS_IsExceptionPending(aCx)) {
|
||||
|
@ -296,7 +296,6 @@ GetWebIDLCallerPrincipal()
|
||||
|
||||
AutoJSAPI::AutoJSAPI()
|
||||
: mCx(nullptr)
|
||||
, mOldAutoJSAPIOwnsErrorReporting(false)
|
||||
, mIsMainThread(false) // For lack of anything better
|
||||
{
|
||||
}
|
||||
@ -312,13 +311,6 @@ AutoJSAPI::~AutoJSAPI()
|
||||
|
||||
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());
|
||||
}
|
||||
@ -358,8 +350,6 @@ AutoJSAPI::InitInternal(nsIGlobalObject* aGlobalObject, JSObject* 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
|
||||
@ -432,8 +422,7 @@ AutoJSAPI::InitInternal(nsIGlobalObject* aGlobalObject, JSObject* aGlobal,
|
||||
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");
|
||||
|
@ -311,8 +311,6 @@ private:
|
||||
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;
|
||||
|
@ -149,8 +149,6 @@ nsJSUtils::EvaluateString(JSContext* aCx,
|
||||
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());
|
||||
@ -278,8 +276,6 @@ nsJSUtils::CompileModule(JSContext* aCx,
|
||||
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());
|
||||
@ -305,8 +301,6 @@ nsJSUtils::ModuleDeclarationInstantiation(JSContext* aCx, JS::Handle<JSObject*>
|
||||
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());
|
||||
@ -326,8 +320,6 @@ 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());
|
||||
|
@ -206,18 +206,6 @@ GetCurrentJSStack(int32_t aMaxDepth)
|
||||
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
|
||||
|
@ -54,19 +54,6 @@ CreateException(JSContext* aCx, nsresult aRv,
|
||||
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 {
|
||||
|
||||
|
@ -58,7 +58,6 @@ ToJSValue(JSContext* aCx,
|
||||
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);
|
||||
|
@ -2623,7 +2623,6 @@ Promise::ResolveInternal(JSContext* aCx,
|
||||
mResolvePending = true;
|
||||
|
||||
if (aValue.isObject()) {
|
||||
MOZ_ASSERT(JS::ContextOptionsRef(aCx).autoJSAPIOwnsErrorReporting());
|
||||
JS::Rooted<JSObject*> valueObj(aCx, &aValue.toObject());
|
||||
|
||||
// Thenables.
|
||||
|
@ -410,7 +410,6 @@ WrapperAnswer::RecvCallOrConstruct(const ObjectId& objId,
|
||||
|
||||
RootedValue rval(cx);
|
||||
{
|
||||
MOZ_ASSERT(JS::ContextOptionsRef(cx).autoJSAPIOwnsErrorReporting());
|
||||
HandleValueArray args = HandleValueArray::subarray(vals, 2, vals.length() - 2);
|
||||
if (construct) {
|
||||
RootedObject obj(cx);
|
||||
|
@ -584,7 +584,7 @@ CompileError::throwError(JSContext* cx)
|
||||
// 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);
|
||||
|
@ -42,16 +42,6 @@ BEGIN_TEST(testCallArgs_isConstructing_native)
|
||||
|
||||
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
|
||||
@ -93,14 +83,4 @@ BEGIN_TEST(testCallArgs_isConstructing_constructor)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool init() override
|
||||
{
|
||||
if (!JSAPITest::init())
|
||||
return false;
|
||||
|
||||
JS::ContextOptionsRef(cx).setAutoJSAPIOwnsErrorReporting(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testCallArgs_isConstructing_constructor)
|
||||
|
@ -203,7 +203,6 @@ BEGIN_TEST(testProfileStrings_isCalledWhenError)
|
||||
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 */
|
||||
|
@ -312,13 +312,7 @@ class JSAPITest
|
||||
}
|
||||
|
||||
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() {
|
||||
|
@ -700,12 +700,6 @@ 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)
|
||||
{
|
||||
@ -2825,29 +2819,6 @@ 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)
|
||||
@ -2856,7 +2827,6 @@ JS_CallFunctionValue(JSContext* cx, HandleObject obj, HandleValue fval, const Ha
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, fval, args);
|
||||
AutoLastFrameCheck lfc(cx);
|
||||
|
||||
InvokeArgs iargs(cx);
|
||||
if (!FillArgumentsFromArraylike(cx, iargs, args))
|
||||
@ -2874,7 +2844,6 @@ JS_CallFunction(JSContext* cx, HandleObject obj, HandleFunction fun, const Handl
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, fun, args);
|
||||
AutoLastFrameCheck lfc(cx);
|
||||
|
||||
InvokeArgs iargs(cx);
|
||||
if (!FillArgumentsFromArraylike(cx, iargs, args))
|
||||
@ -2893,7 +2862,6 @@ JS_CallFunctionName(JSContext* cx, HandleObject obj, const char* name, const Han
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, obj, args);
|
||||
AutoLastFrameCheck lfc(cx);
|
||||
|
||||
JSAtom* atom = Atomize(cx, name, strlen(name));
|
||||
if (!atom)
|
||||
@ -2919,7 +2887,6 @@ JS::Call(JSContext* cx, HandleValue thisv, HandleValue fval, const JS::HandleVal
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, thisv, fval, args);
|
||||
AutoLastFrameCheck lfc(cx);
|
||||
|
||||
InvokeArgs iargs(cx);
|
||||
if (!FillArgumentsFromArraylike(cx, iargs, args))
|
||||
@ -2935,7 +2902,6 @@ JS::Construct(JSContext* cx, HandleValue fval, HandleObject newTarget, const JS:
|
||||
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);
|
||||
@ -2962,7 +2928,6 @@ JS::Construct(JSContext* cx, HandleValue fval, const JS::HandleValueArray& args,
|
||||
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);
|
||||
@ -3994,7 +3959,6 @@ Compile(JSContext* cx, const ReadOnlyCompileOptions& options, SyntacticScopeOpti
|
||||
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) {
|
||||
@ -4163,17 +4127,7 @@ 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)
|
||||
@ -4189,17 +4143,7 @@ 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)
|
||||
@ -4311,7 +4255,6 @@ CompileFunction(JSContext* cx, const ReadOnlyCompileOptions& optionsArg,
|
||||
assertSameCompartment(cx, enclosingDynamicScope);
|
||||
assertSameCompartment(cx, enclosingStaticScope);
|
||||
RootedAtom funAtom(cx);
|
||||
AutoLastFrameCheck lfc(cx);
|
||||
|
||||
if (name) {
|
||||
funAtom = Atomize(cx, name, strlen(name));
|
||||
@ -4423,7 +4366,6 @@ ExecuteScript(JSContext* cx, HandleObject scope, HandleScript script, Value* rva
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, scope, script);
|
||||
MOZ_ASSERT_IF(!IsGlobalLexicalScope(scope), script->hasNonSyntacticScope());
|
||||
AutoLastFrameCheck lfc(cx);
|
||||
return Execute(cx, script, *scope, rval);
|
||||
}
|
||||
|
||||
@ -4503,8 +4445,6 @@ Evaluate(JSContext* cx, HandleObject scope, Handle<StaticScope*> staticScope,
|
||||
CHECK_REQUEST(cx);
|
||||
assertSameCompartment(cx, scope);
|
||||
|
||||
AutoLastFrameCheck lfc(cx);
|
||||
|
||||
MOZ_ASSERT_IF(!IsGlobalLexicalScope(scope), HasNonSyntacticStaticScopeChain(staticScope));
|
||||
|
||||
options.setIsRunOnce(true);
|
||||
@ -4656,8 +4596,6 @@ JS::CompileModule(JSContext* cx, const ReadOnlyCompileOptions& options,
|
||||
AssertHeapIsIdle(cx);
|
||||
CHECK_REQUEST(cx);
|
||||
|
||||
AutoLastFrameCheck lfc(cx);
|
||||
|
||||
module.set(frontend::CompileModule(cx, options, srcBuf));
|
||||
return !!module;
|
||||
}
|
||||
@ -4710,8 +4648,8 @@ JS::GetModuleScript(JSContext* cx, JS::HandleObject 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);
|
||||
@ -4734,17 +4672,6 @@ JS_NewHelper(JSContext* cx, HandleObject ctor, const JS::HandleValueArray& input
|
||||
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)
|
||||
{
|
||||
|
@ -1268,69 +1268,6 @@ 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*)
|
||||
|
@ -225,17 +225,15 @@ ReportError(JSContext* cx, const char* message, JSErrorReport* reportp,
|
||||
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.
|
||||
@ -304,36 +302,7 @@ js::ReportOutOfMemory(ExclusiveContext* cxArg)
|
||||
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
|
||||
@ -964,7 +933,6 @@ JSContext::JSContext(JSRuntime* rt)
|
||||
: ExclusiveContext(rt, &rt->mainThread, Context_JS),
|
||||
throwing(false),
|
||||
unwrappedException_(this),
|
||||
options_(),
|
||||
overRecursed_(false),
|
||||
propagatingForcedReturn_(false),
|
||||
liveVolatileJitFrameIterators_(nullptr),
|
||||
|
@ -321,9 +321,6 @@ struct JSContext : public js::ExclusiveContext,
|
||||
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_;
|
||||
@ -363,14 +360,6 @@ struct JSContext : public js::ExclusiveContext,
|
||||
*/
|
||||
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
|
||||
|
@ -6453,9 +6453,6 @@ NewContext(JSRuntime* rt)
|
||||
if (!cx)
|
||||
return nullptr;
|
||||
|
||||
JS::ContextOptionsRef(cx).setDontReportUncaught(true);
|
||||
JS::ContextOptionsRef(cx).setAutoJSAPIOwnsErrorReporting(true);
|
||||
|
||||
JSShellContextData* data = NewContextData();
|
||||
if (!data) {
|
||||
DestroyContext(cx, false);
|
||||
|
@ -2714,25 +2714,15 @@ MaybePrintAndClearPendingException(JSContext* cx, FILE* file)
|
||||
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
|
||||
|
@ -239,7 +239,6 @@ nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(JSContext* cx,
|
||||
// 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);
|
||||
}
|
||||
@ -274,8 +273,6 @@ nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(JSContext* cx,
|
||||
JS_ClearPendingException(cx);
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_ASSERT(ContextOptionsRef(cx).autoJSAPIOwnsErrorReporting());
|
||||
} else if (!success) {
|
||||
NS_WARNING("QI hook ran OOMed - this is probably a bug!");
|
||||
}
|
||||
@ -1213,7 +1210,6 @@ pre_call_clean_up:
|
||||
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.
|
||||
|
@ -687,8 +687,6 @@ private:
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user