Bug 1187062 - Part 3: Add jsapi-tests for JS::ubi::StackFrame; r=sfink
authorNick Fitzgerald <fitzgen@gmail.com>
Fri, 14 Aug 2015 17:49:06 -0700
changeset 257945 638c65c33cfab3411ff26eb0c06836062c20ca5d
parent 257944 40ffe3eacef1cbbc600250f67d9a483c0f4be3d0
child 257946 3a12957a6bd3166c3c0f6b5667264ddd040e6318
push id29238
push userryanvm@gmail.com
push dateMon, 17 Aug 2015 13:06:57 +0000
treeherdermozilla-central@a6eeb28458fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1187062
milestone43.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 1187062 - Part 3: Add jsapi-tests for JS::ubi::StackFrame; r=sfink
js/src/jsapi-tests/testUbiNode.cpp
--- a/js/src/jsapi-tests/testUbiNode.cpp
+++ b/js/src/jsapi-tests/testUbiNode.cpp
@@ -1,15 +1,16 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+#include "builtin/TestingFunctions.h"
 #include "js/UbiNode.h"
-
 #include "jsapi-tests/tests.h"
+#include "vm/SavedFrame.h"
 
 using JS::RootedObject;
 using JS::RootedScript;
 using JS::RootedString;
 
 // ubi::Node::zone works
 BEGIN_TEST(test_ubiNodeZone)
 {
@@ -98,8 +99,99 @@ BEGIN_TEST(test_ubiNodeJSObjectConstruct
     mozilla::UniquePtr<char16_t[], JS::FreePolicy> ctorName;
     CHECK(JS::ubi::Node(&val.toObject()).jsObjectConstructorName(cx, ctorName));
     CHECK(ctorName);
     CHECK(js_strcmp(ctorName.get(), MOZ_UTF16("Ctor")) == 0);
 
     return true;
 }
 END_TEST(test_ubiNodeJSObjectConstructorName)
+
+template <typename F, typename G>
+static bool
+checkString(const char* expected, F fillBufferFunction, G stringGetterFunction)
+{
+    auto expectedLength = strlen(expected);
+    char16_t buf[1024];
+    if (fillBufferFunction(mozilla::RangedPtr<char16_t>(buf, 1024), 1024) != expectedLength ||
+        !EqualChars(buf, expected, expectedLength))
+    {
+        return false;
+    }
+
+    auto string = stringGetterFunction();
+    // Expecting a |JSAtom*| from a live |JS::ubi::StackFrame|.
+    if (!string.template is<JSAtom*>() ||
+        !StringEqualsAscii(string.template as<JSAtom*>(), expected))
+    {
+        return false;
+    }
+
+    return true;
+}
+
+BEGIN_TEST(test_ubiStackFrame)
+{
+    CHECK(js::DefineTestingFunctions(cx, global, false));
+
+    JS::RootedValue val(cx);
+    CHECK(evaluate("(function one() {                      \n"  // 1
+                   "  return (function two() {             \n"  // 2
+                   "    return (function three() {         \n"  // 3
+                   "      return saveStack();              \n"  // 4
+                   "    }());                              \n"  // 5
+                   "  }());                                \n"  // 6
+                   "}());                                  \n", // 7
+                   "filename.js",
+                   1,
+                   &val));
+
+    CHECK(val.isObject());
+    JS::RootedObject obj(cx, &val.toObject());
+
+    CHECK(obj->is<SavedFrame>());
+    JS::Rooted<SavedFrame*> savedFrame(cx, &obj->as<SavedFrame>());
+
+    JS::ubi::StackFrame ubiFrame(savedFrame);
+
+    // All frames should be from the "filename.js" source.
+    while (ubiFrame) {
+        CHECK(checkString("filename.js",
+                          [&] (mozilla::RangedPtr<char16_t> ptr, size_t length) {
+                              return ubiFrame.source(ptr, length);
+                          },
+                          [&] {
+                              return ubiFrame.source();
+                          }));
+        ubiFrame = ubiFrame.parent();
+    }
+
+    ubiFrame = savedFrame;
+
+    auto bufferFunctionDisplayName = [&] (mozilla::RangedPtr<char16_t> ptr, size_t length) {
+        return ubiFrame.functionDisplayName(ptr, length);
+    };
+    auto getFunctionDisplayName = [&] {
+        return ubiFrame.functionDisplayName();
+    };
+
+    CHECK(checkString("three", bufferFunctionDisplayName, getFunctionDisplayName));
+    CHECK(ubiFrame.line() == 4);
+
+    ubiFrame = ubiFrame.parent();
+    CHECK(checkString("two", bufferFunctionDisplayName, getFunctionDisplayName));
+    CHECK(ubiFrame.line() == 3);
+
+    ubiFrame = ubiFrame.parent();
+    CHECK(checkString("one", bufferFunctionDisplayName, getFunctionDisplayName));
+    CHECK(ubiFrame.line() == 2);
+
+    ubiFrame = ubiFrame.parent();
+    CHECK(ubiFrame.functionDisplayName().is<JSAtom*>());
+    CHECK(ubiFrame.functionDisplayName().as<JSAtom*>() == nullptr);
+    CHECK(ubiFrame.line() == 1);
+
+    ubiFrame = ubiFrame.parent();
+    CHECK(!ubiFrame);
+
+    return true;
+}
+END_TEST(test_ubiStackFrame)