Bug 920294 - Fix DumpJSStack. r=jandem
authorTom Schuster <evilpies@gmail.com>
Sat, 26 Oct 2013 18:19:00 +0200
changeset 152346 1268bd66a094596cc4cda46c1903c9a027fd76fe
parent 152345 f9d56fbbdbd61144c590c041f7482ca96bcfba6e
child 152347 05c31c03a8dd7ca613840e8de25ad37f5487b1af
push id25531
push userphilringnalda@gmail.com
push dateSun, 27 Oct 2013 00:47:11 +0000
treeherdermozilla-central@e753ebb35e64 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs920294
milestone27.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 920294 - Fix DumpJSStack. r=jandem
js/src/vm/OldDebugAPI.cpp
--- a/js/src/vm/OldDebugAPI.cpp
+++ b/js/src/vm/OldDebugAPI.cpp
@@ -1024,16 +1024,21 @@ class AutoPropertyDescArray
 };
 
 } /* anonymous namespace */
 
 static const char *
 FormatValue(JSContext *cx, const Value &vArg, JSAutoByteString &bytes)
 {
     RootedValue v(cx, vArg);
+
+    mozilla::Maybe<AutoCompartment> ac;
+    if (v.isObject())
+        ac.construct(cx, &v.toObject());
+
     JSString *str = ToString<CanGC>(cx, v);
     if (!str)
         return nullptr;
     const char *buf = bytes.encodeLatin1(cx, str);
     if (!buf)
         return nullptr;
     const char *found = strstr(buf, "function ");
     if (found && (found - buf <= 2))
@@ -1054,26 +1059,16 @@ FormatFrame(JSContext *cx, const NonBuil
 
     const char *filename = script->filename();
     unsigned lineno = PCToLineNumber(script, pc);
     RootedFunction fun(cx, iter.maybeCallee());
     RootedString funname(cx);
     if (fun)
         funname = fun->atom();
 
-    RootedObject callObj(cx);
-    AutoPropertyDescArray callProps(cx);
-
-    if (!iter.isJit() && (showArgs || showLocals)) {
-        JSAbstractFramePtr frame(Jsvalify(iter.abstractFramePtr()));
-        callObj = frame.callObject(cx);
-        if (callObj)
-            callProps.fetch(callObj);
-    }
-
     RootedValue thisVal(cx);
     AutoPropertyDescArray thisProps(cx);
     if (iter.computeThis(cx)) {
         thisVal = iter.thisv();
         if (showThisProps && !thisVal.isPrimitive())
             thisProps.fetch(&thisVal.toObject());
     }
 
@@ -1084,118 +1079,85 @@ FormatFrame(JSContext *cx, const NonBuil
     } else if (fun) {
         buf = JS_sprintf_append(buf, "%d anonymous(", num);
     } else {
         buf = JS_sprintf_append(buf, "%d <TOP LEVEL>", num);
     }
     if (!buf)
         return buf;
 
-    // print the function arguments
-    if (showArgs && callObj) {
-        uint32_t namedArgCount = 0;
-        for (uint32_t i = 0; i < callProps->length; i++) {
-            JSPropertyDesc* desc = &callProps->array[i];
+    if (showArgs && iter.hasArgs()) {
+        BindingVector bindings(cx);
+        if (fun && fun->isInterpreted()) {
+            if (!FillBindingVector(script, &bindings))
+                return buf;
+        }
+
+
+        bool first = true;
+        for (unsigned i = 0; i < iter.numActualArgs(); i++) {
+            RootedValue arg(cx);
+            if (i < iter.numFormalArgs() && script->formalIsAliased(i)) {
+                for (AliasedFormalIter fi(script); ; fi++) {
+                    if (fi.frameIndex() == i) {
+                        arg = iter.callObj().aliasedVar(fi);
+                        break;
+                    }
+                }
+            } else if (script->argsObjAliasesFormals() && iter.hasArgsObj()) {
+                arg = iter.argsObj().arg(i);
+            } else {
+                arg = iter.unaliasedActual(i, DONT_CHECK_ALIASING);
+            }
+
+            JSAutoByteString valueBytes;
+            const char *value = FormatValue(cx, arg, valueBytes);
+
             JSAutoByteString nameBytes;
             const char *name = nullptr;
-            bool hasName = JSVAL_IS_STRING(desc->id);
-            if (hasName)
-                name = FormatValue(cx, desc->id, nameBytes);
-            JSAutoByteString valueBytes;
-            const char *value = FormatValue(cx, desc->value, valueBytes);
 
-            if (value && (name || !hasName)) {
+            if (i < bindings.length()) {
+                name = nameBytes.encodeLatin1(cx, bindings[i].name());
+                if (!buf)
+                    return NULL;
+            }
+
+            if (value) {
                 buf = JS_sprintf_append(buf, "%s%s%s%s%s%s",
-                                        namedArgCount ? ", " : "",
+                                        !first ? ", " : "",
                                         name ? name :"",
                                         name ? " = " : "",
-                                        desc->value.isString() ? "\"" : "",
+                                        arg.isString() ? "\"" : "",
                                         value ? value : "?unknown?",
-                                        desc->value.isString() ? "\"" : "");
+                                        arg.isString() ? "\"" : "");
                 if (!buf)
                     return buf;
+
+                first = false;
             } else {
-                buf = JS_sprintf_append(buf, "    <Failed to get named argument while inspecting stack frame>\n");
+                buf = JS_sprintf_append(buf, "    <Failed to get argument while inspecting stack frame>\n");
+                if (!buf)
+                    return buf;
                 cx->clearPendingException();
 
             }
-            namedArgCount++;
-        }
-
-        // print any unnamed trailing args (found in 'arguments' object)
-        RootedValue val(cx);
-        if (JS_GetProperty(cx, callObj, "arguments", &val) && val.isObject()) {
-            uint32_t argCount;
-            RootedObject argsObj(cx, &val.toObject());
-            if (JS_GetProperty(cx, argsObj, "length", &val) &&
-                ToUint32(cx, val, &argCount) &&
-                argCount > namedArgCount)
-            {
-                for (uint32_t k = namedArgCount; k < argCount; k++) {
-                    char number[8];
-                    JS_snprintf(number, 8, "%d", (int) k);
-
-                    JSAutoByteString valueBytes;
-                    const char *value = nullptr;
-                    if (JS_GetProperty(cx, argsObj, number, &val) &&
-                        (value = FormatValue(cx, val, valueBytes)))
-                    {
-                        buf = JS_sprintf_append(buf, "%s%s%s%s",
-                                                k ? ", " : "",
-                                                val.isString() ? "\"" : "",
-                                                value ? value : "?unknown?",
-                                                val.isString() ? "\"" : "");
-                        if (!buf)
-                            return buf;
-                    } else {
-                        buf = JS_sprintf_append(buf, "    <Failed to get argument while inspecting stack frame>\n");
-                        cx->clearPendingException();
-                    }
-                }
-            } else {
-                buf = JS_sprintf_append(buf, "    <Failed to get 'length' while inspecting stack frame>\n");
-                cx->clearPendingException();
-            }
-        } else {
-            buf = JS_sprintf_append(buf, "    <Failed to get 'arguments' while inspecting stack frame>\n");
-            cx->clearPendingException();
         }
     }
 
     // print filename and line number
     buf = JS_sprintf_append(buf, "%s [\"%s\":%d]\n",
                             fun ? ")" : "",
                             filename ? filename : "<unknown>",
                             lineno);
     if (!buf)
         return buf;
 
-    // print local variables
-    if (showLocals && callProps->array) {
-        for (uint32_t i = 0; i < callProps->length; i++) {
-            JSPropertyDesc* desc = &callProps->array[i];
-            JSAutoByteString nameBytes;
-            JSAutoByteString valueBytes;
-            const char *name = FormatValue(cx, desc->id, nameBytes);
-            const char *value = FormatValue(cx, desc->value, valueBytes);
 
-            if (name && value) {
-                buf = JS_sprintf_append(buf, "    %s = %s%s%s\n",
-                                        name,
-                                        desc->value.isString() ? "\"" : "",
-                                        value,
-                                        desc->value.isString() ? "\"" : "");
-                if (!buf)
-                    return buf;
-            } else {
-                buf = JS_sprintf_append(buf, "    <Failed to get local while inspecting stack frame>\n");
-                cx->clearPendingException();
-            }
-        }
-    }
+    // Note: Right now we don't dump the local variables anymore, because
+    // that is hard to support across all the JITs etc.
 
     // print the value of 'this'
     if (showLocals) {
         if (!thisVal.isUndefined()) {
             JSAutoByteString thisValBytes;
             RootedString thisValStr(cx, ToString<CanGC>(cx, thisVal));
             const char *str = nullptr;
             if (thisValStr &&