Bug 1038238 - Part 3: js::ComputeStackString should use SavedFrame; r=jorendorff
authorNick Fitzgerald <fitzgen@gmail.com>
Fri, 27 Mar 2015 13:08:46 -0700
changeset 266600 7304e101be54728c10b1e6e465b18818dec2e941
parent 266599 ba50784c810d71cf43ee6c519896f749aa259637
child 266601 b336dc0af92c339da912b09f205fb9bffc9afdf3
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs1038238
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1038238 - Part 3: js::ComputeStackString should use SavedFrame; r=jorendorff
js/src/jsexn.cpp
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -267,79 +267,40 @@ struct SuppressErrorsGuard
     {}
 
     ~SuppressErrorsGuard()
     {
         JS_SetErrorReporter(cx->runtime(), prevReporter);
     }
 };
 
+// Cut off the stack if it gets too deep (most commonly for infinite recursion
+// errors).
+static const size_t MAX_REPORTED_STACK_DEPTH = 1u << 7;
+
+static bool
+CaptureStack(JSContext *cx, MutableHandleObject stack)
+{
+    return CaptureCurrentStack(cx, stack, MAX_REPORTED_STACK_DEPTH);
+}
+
 JSString *
 js::ComputeStackString(JSContext *cx)
 {
-    StringBuffer sb(cx);
+    SuppressErrorsGuard seg(cx);
 
-    {
-        RootedAtom atom(cx);
-        SuppressErrorsGuard seg(cx);
-        for (NonBuiltinFrameIter i(cx, FrameIter::ALL_CONTEXTS, FrameIter::GO_THROUGH_SAVED,
-                                   cx->compartment()->principals);
-             !i.done();
-             ++i)
-        {
-            /* First append the function name, if any. */
-            if (i.isNonEvalFunctionFrame())
-                atom = i.functionDisplayAtom();
-            else
-                atom = nullptr;
-            if (atom && !sb.append(atom))
-                return nullptr;
-
-            /* Next a @ separating function name from source location. */
-            if (!sb.append('@'))
-                return nullptr;
-
-            /* Now the filename. */
+    RootedObject stack(cx);
+    if (!CaptureStack(cx, &stack))
+        return nullptr;
 
-            /* First, try the `//# sourceURL=some-display-url.js` directive. */
-            if (const char16_t *display = i.scriptDisplayURL()) {
-                if (!sb.append(display, js_strlen(display)))
-                    return nullptr;
-            }
-            /* Second, try the actual filename. */
-            else if (const char *filename = i.scriptFilename()) {
-                if (!sb.append(filename, strlen(filename)))
-                    return nullptr;
-            }
-
-            uint32_t column = 0;
-            uint32_t line = i.computeLine(&column);
-            // Now the line number
-            if (!sb.append(':') || !NumberValueToStringBuffer(cx, NumberValue(line), sb))
-                return nullptr;
+    RootedString str(cx);
+    if (!StringifySavedFrameStack(cx, stack, &str))
+        return nullptr;
 
-            // Finally, : followed by the column number (1-based, as in other browsers)
-            // and a newline.
-            if (!sb.append(':') || !NumberValueToStringBuffer(cx, NumberValue(column + 1), sb) ||
-                !sb.append('\n'))
-            {
-                return nullptr;
-            }
-
-            /*
-             * Cut off the stack if it gets too deep (most commonly for
-             * infinite recursion errors).
-             */
-            const size_t MaxReportedStackDepth = 1u << 20;
-            if (sb.length() > MaxReportedStackDepth)
-                break;
-        }
-    }
-
-    return sb.finishString();
+    return str.get();
 }
 
 static void
 exn_finalize(FreeOp *fop, JSObject *obj)
 {
     if (JSErrorReport *report = obj->as<ErrorObject>().getErrorReport())
         fop->free_(report);
 }
@@ -355,26 +316,16 @@ js::ErrorFromException(JSContext *cx, Ha
     // will fail if they can't unwrap it.
     RootedObject obj(cx, UncheckedUnwrap(objArg));
     if (!obj->is<ErrorObject>())
         return nullptr;
 
     return obj->as<ErrorObject>().getOrCreateErrorReport(cx);
 }
 
-// Cut off the stack if it gets too deep (most commonly for infinite recursion
-// errors).
-static const size_t MAX_REPORTED_STACK_DEPTH = 1u << 7;
-
-static bool
-CaptureStack(JSContext *cx, MutableHandleObject stack)
-{
-    return CaptureCurrentStack(cx, stack, MAX_REPORTED_STACK_DEPTH);
-}
-
 bool
 Error(JSContext *cx, unsigned argc, Value *vp)
 {
     CallArgs args = CallArgsFromVp(argc, vp);
 
     /* Compute the error message, if any. */
     RootedString message(cx, nullptr);
     if (args.hasDefined(0)) {