diff --git a/docshell/base/timeline/JavascriptTimelineMarker.h b/docshell/base/timeline/JavascriptTimelineMarker.h index 47c9943a5e7f..5a99242831b8 100644 --- a/docshell/base/timeline/JavascriptTimelineMarker.h +++ b/docshell/base/timeline/JavascriptTimelineMarker.h @@ -62,7 +62,8 @@ public: return; } - if (!JS::CopyAsyncStack(aCx, asyncStack, asyncCause, &parentFrame, 0)) { + if (JS::IsSavedFrame(asyncStack) && + !JS::CopyAsyncStack(aCx, asyncStack, asyncCause, &parentFrame, 0)) { JS_ClearPendingException(aCx); } else { stackFrame.mAsyncParent = parentFrame; diff --git a/js/src/jsapi.h b/js/src/jsapi.h index e4cdc12737d9..7610d556ca92 100644 --- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -5996,6 +5996,13 @@ GetSavedFrameParent(JSContext* cx, HandleObject savedFrame, MutableHandleObject extern JS_PUBLIC_API(bool) BuildStackString(JSContext* cx, HandleObject stack, MutableHandleString stringp, size_t indent = 0); +/** + * Return true iff the given object is either a SavedFrame object or wrapper + * around a SavedFrame object, and it is not the SavedFrame.prototype object. + */ +extern JS_PUBLIC_API(bool) +IsSavedFrame(JSObject* obj); + } /* namespace JS */ diff --git a/js/src/vm/SavedStacks.cpp b/js/src/vm/SavedStacks.cpp index a224bfe57973..5c0588d9d56b 100644 --- a/js/src/vm/SavedStacks.cpp +++ b/js/src/vm/SavedStacks.cpp @@ -930,6 +930,19 @@ BuildStackString(JSContext* cx, HandleObject stack, MutableHandleString stringp, return true; } +JS_PUBLIC_API(bool) +IsSavedFrame(JSObject* obj) +{ + if (!obj) + return false; + + JSObject* unwrapped = CheckedUnwrap(obj); + if (!unwrapped) + return false; + + return js::SavedFrame::isSavedFrameAndNotProto(*unwrapped); +} + } /* namespace JS */ namespace js {