From ea5c73450b5ff89f71ba095bfff4e12a996979ef Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Thu, 3 Jul 2014 12:26:18 -0700 Subject: [PATCH] Bug 1031143: Include omitted patch reject fixes. CLOSED TREE r=borked --- js/src/builtin/TestingFunctions.cpp | 17 ++++++++++++++++- js/src/vm/SavedStacks.cpp | 16 ++++++++++++++-- js/src/vm/SavedStacks.h | 5 +++-- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/js/src/builtin/TestingFunctions.cpp b/js/src/builtin/TestingFunctions.cpp index 2a9c060d55c1..0d357a178b9b 100644 --- a/js/src/builtin/TestingFunctions.cpp +++ b/js/src/builtin/TestingFunctions.cpp @@ -880,8 +880,23 @@ static bool SaveStack(JSContext *cx, unsigned argc, jsval *vp) { CallArgs args = CallArgsFromVp(argc, vp); + + unsigned maxFrameCount = 0; + if (args.length() >= 1) { + double d; + if (!ToNumber(cx, args[0], &d)) + return false; + if (d < 0) { + js_ReportValueErrorFlags(cx, JSREPORT_ERROR, JSMSG_UNEXPECTED_TYPE, + JSDVG_SEARCH_STACK, args[0], JS::NullPtr(), + "not a valid maximum frame count", NULL); + return false; + } + maxFrameCount = d; + } + Rooted stack(cx); - if (!JS::CaptureCurrentStack(cx, &stack)) + if (!JS::CaptureCurrentStack(cx, &stack, maxFrameCount)) return false; args.rval().setObjectOrNull(stack); return true; diff --git a/js/src/vm/SavedStacks.cpp b/js/src/vm/SavedStacks.cpp index 05796bc5058c..94d0aa0ea6cb 100644 --- a/js/src/vm/SavedStacks.cpp +++ b/js/src/vm/SavedStacks.cpp @@ -498,8 +498,20 @@ SavedStacks::insertFrames(JSContext *cx, ScriptFrameIter &iter, MutableHandleSav // script and callee should keep compartment alive. JSCompartment *compartment = iter.compartment(); RootedSavedFrame parentFrame(cx); - if (!insertFrames(cx, ++iter, &parentFrame)) - return false; + + // If maxFrameCount is zero, then there's no limit on the number of frames. + if (maxFrameCount == 0) { + if (!insertFrames(cx, ++iter, &parentFrame, 0)) + return false; + } else if (maxFrameCount == 1) { + // Since we were only asked to save one frame, the SavedFrame we're + // building here should have no parent, even if there are older frames + // on the stack. + parentFrame = nullptr; + } else { + if (!insertFrames(cx, ++iter, &parentFrame, maxFrameCount - 1)) + return false; + } AutoLocationValueRooter location(cx); if (!getLocation(cx, script, pc, &location)) diff --git a/js/src/vm/SavedStacks.h b/js/src/vm/SavedStacks.h index f7125db74338..4809aa63745a 100644 --- a/js/src/vm/SavedStacks.h +++ b/js/src/vm/SavedStacks.h @@ -104,7 +104,7 @@ class SavedStacks { bool init(); bool initialized() const { return frames.initialized(); } - bool saveCurrentStack(JSContext *cx, MutableHandleSavedFrame frame); + bool saveCurrentStack(JSContext *cx, MutableHandleSavedFrame frame, unsigned maxFrameCount = 0); void sweep(JSRuntime *rt); void trace(JSTracer *trc); uint32_t count(); @@ -116,7 +116,8 @@ class SavedStacks { SavedFrame::Set frames; JSObject *savedFrameProto; - bool insertFrames(JSContext *cx, ScriptFrameIter &iter, MutableHandleSavedFrame frame); + bool insertFrames(JSContext *cx, ScriptFrameIter &iter, MutableHandleSavedFrame frame, + unsigned maxFrameCount = 0); SavedFrame *getOrCreateSavedFrame(JSContext *cx, const SavedFrame::Lookup &lookup); // |SavedFrame.prototype| is created lazily and held weakly. It should only // be accessed through this method.