Bug 1220031 - Add JS::ubi::Node::scriptFilename; r=sfink
authorNick Fitzgerald <fitzgen@gmail.com>
Wed, 04 Nov 2015 05:49:33 -0800
changeset 271189 133b747de1a7412aad77504617b1475af740c79d
parent 271188 72b526b94dee56b752fde45eb136db7b691c2d4a
child 271190 d1005e79cfc6a322db3967f933776c948bf251f8
push id29634
push usercbook@mozilla.com
push dateThu, 05 Nov 2015 10:59:26 +0000
treeherdermozilla-central@59c648a3f955 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssfink
bugs1220031
milestone45.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 1220031 - Add JS::ubi::Node::scriptFilename; r=sfink
js/public/UbiNode.h
js/src/jit/IonCode.h
js/src/jsapi-tests/testUbiNode.cpp
js/src/jsscript.cpp
js/src/jsscript.h
--- a/js/public/UbiNode.h
+++ b/js/public/UbiNode.h
@@ -634,16 +634,22 @@ class Base {
     // of the out parameter. True is returned on success, false is returned on
     // OOM.
     virtual bool jsObjectConstructorName(JSContext* cx,
                                          UniquePtr<char16_t[], JS::FreePolicy>& outName) const {
         outName.reset(nullptr);
         return true;
     }
 
+    // Methods for CoarseType::Script referents
+
+    // Return the script's source's filename if available. If unavailable,
+    // return nullptr.
+    virtual const char* scriptFilename() const { return nullptr; }
+
   private:
     Base(const Base& rhs) = delete;
     Base& operator=(const Base& rhs) = delete;
 };
 
 // A traits template with a specialization for each referent type that
 // ubi::Node supports. The specialization must be the concrete subclass of
 // Base that represents a pointer to the referent type. It must also
@@ -774,16 +780,18 @@ class Node {
     JS::Zone* zone()                const { return base()->zone(); }
     JSCompartment* compartment()    const { return base()->compartment(); }
     const char* jsObjectClassName() const { return base()->jsObjectClassName(); }
     bool jsObjectConstructorName(JSContext* cx,
                                  UniquePtr<char16_t[], JS::FreePolicy>& outName) const {
         return base()->jsObjectConstructorName(cx, outName);
     }
 
+    const char* scriptFilename() const { return base()->scriptFilename(); }
+
     using Size = Base::Size;
     Size size(mozilla::MallocSizeOf mallocSizeof) const {
         return base()->size(mallocSizeof);
     }
 
     UniquePtr<EdgeRange> edges(JSRuntime* rt, bool wantNames = true) const {
         return base()->edges(rt, wantNames);
     }
@@ -1047,16 +1055,17 @@ struct Concrete<JS::Symbol> : TracerConc
     static void construct(void* storage, JS::Symbol* ptr) {
         new (storage) Concrete(ptr);
     }
 };
 
 template<> struct Concrete<JSScript> : TracerConcreteWithCompartment<JSScript> {
     CoarseType coarseType() const final { return CoarseType::Script; }
     Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
+    const char* scriptFilename() const final;
 
   protected:
     explicit Concrete(JSScript *ptr) : TracerConcreteWithCompartment<JSScript>(ptr) { }
 
   public:
     static void construct(void *storage, JSScript *ptr) { new (storage) Concrete(ptr); }
 };
 
--- a/js/src/jit/IonCode.h
+++ b/js/src/jit/IonCode.h
@@ -777,16 +777,17 @@ IsMarked(const jit::VMFunction*)
 
 // JS::ubi::Nodes can point to js::jit::JitCode instances; they're js::gc::Cell
 // instances with no associated compartment.
 namespace JS {
 namespace ubi {
 template<>
 struct Concrete<js::jit::JitCode> : TracerConcrete<js::jit::JitCode> {
     CoarseType coarseType() const final { return CoarseType::Script; }
+
     Size size(mozilla::MallocSizeOf mallocSizeOf) const override {
         Size size = js::gc::Arena::thingSize(get().asTenured().getAllocKind());
         size += get().bufferSize();
         size += get().headerSize();
         return size;
     }
 
   protected:
--- a/js/src/jsapi-tests/testUbiNode.cpp
+++ b/js/src/jsapi-tests/testUbiNode.cpp
@@ -341,8 +341,42 @@ BEGIN_TEST(test_ubiPostOrder)
     CHECK(visited[4] == 'c');
     CHECK(visited[5] == 'b');
     CHECK(visited[6] == 'a');
     CHECK(visited[7] == 'r');
 
     return true;
 }
 END_TEST(test_ubiPostOrder)
+
+BEGIN_TEST(test_JS_ubi_Node_scriptFilename)
+{
+    JS::RootedValue val(cx);
+    CHECK(evaluate("(function one() {                      \n"  // 1
+                   "  return (function two() {             \n"  // 2
+                   "    return (function three() {         \n"  // 3
+                   "      return function four() {};       \n"  // 4
+                   "    }());                              \n"  // 5
+                   "  }());                                \n"  // 6
+                   "}());                                  \n", // 7
+                   "my-cool-filename.js",
+                   1,
+                   &val));
+
+    CHECK(val.isObject());
+    JS::RootedObject obj(cx, &val.toObject());
+
+    CHECK(obj->is<JSFunction>());
+    JS::RootedFunction func(cx, &obj->as<JSFunction>());
+
+    JS::RootedScript script(cx, func->getOrCreateScript(cx));
+    CHECK(script);
+    CHECK(script->filename());
+
+    JS::ubi::Node node(script);
+    const char* filename = node.scriptFilename();
+    CHECK(filename);
+    CHECK(strcmp(filename, script->filename()) == 0);
+    CHECK(strcmp(filename, "my-cool-filename.js") == 0);
+
+    return true;
+}
+END_TEST(test_JS_ubi_Node_scriptFilename)
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -4401,15 +4401,35 @@ JS::ubi::Concrete<JSScript>::size(mozill
     size += baselineStubsSize;
 
     size += jit::SizeOfIonData(&get(), mallocSizeOf);
 
     MOZ_ASSERT(size > 0);
     return size;
 }
 
+const char*
+JS::ubi::Concrete<JSScript>::scriptFilename() const
+{
+    return get().filename();
+}
+
 JS::ubi::Node::Size
 JS::ubi::Concrete<js::LazyScript>::size(mozilla::MallocSizeOf mallocSizeOf) const
 {
     Size size = js::gc::Arena::thingSize(get().asTenured().getAllocKind());
     size += get().sizeOfExcludingThis(mallocSizeOf);
     return size;
 }
+
+const char*
+JS::ubi::Concrete<js::LazyScript>::scriptFilename() const
+{
+    auto sourceObject = get().sourceObject();
+    if (!sourceObject)
+        return nullptr;
+
+    auto source = sourceObject->source();
+    if (!source)
+        return nullptr;
+
+    return source->filename();
+}
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -2482,16 +2482,17 @@ CloneGlobalScript(JSContext* cx, Handle<
 // JS::ubi::Nodes can point to js::LazyScripts; they're js::gc::Cell instances
 // with no associated compartment.
 namespace JS {
 namespace ubi {
 template<>
 struct Concrete<js::LazyScript> : TracerConcrete<js::LazyScript> {
     CoarseType coarseType() const final { return CoarseType::Script; }
     Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
+    const char* scriptFilename() const final;
 
   protected:
     explicit Concrete(js::LazyScript *ptr) : TracerConcrete<js::LazyScript>(ptr) { }
 
   public:
     static void construct(void *storage, js::LazyScript *ptr) { new (storage) Concrete(ptr); }
 };
 } // namespace ubi