UbiNodeShortestPaths.cpp (2538B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- 2 * vim: set ts=8 sts=2 et sw=2 tw=80: 3 * This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "js/UbiNodeShortestPaths.h" 8 9 #include <stdio.h> 10 #include <utility> 11 12 #include "util/Text.h" 13 14 namespace JS { 15 namespace ubi { 16 17 JS_PUBLIC_API BackEdge::Ptr BackEdge::clone() const { 18 auto clone = js::MakeUnique<BackEdge>(); 19 if (!clone) { 20 return nullptr; 21 } 22 23 clone->predecessor_ = predecessor(); 24 if (name()) { 25 clone->name_ = js::DuplicateString(name().get()); 26 if (!clone->name_) { 27 return nullptr; 28 } 29 } 30 return clone; 31 } 32 33 #ifdef DEBUG 34 35 static int32_t js_fputs(const char16_t* s, FILE* f) { 36 while (*s != 0) { 37 if (fputwc(wchar_t(*s), f) == static_cast<wint_t>(WEOF)) { 38 return WEOF; 39 } 40 s++; 41 } 42 return 1; 43 } 44 45 static void dumpNode(const JS::ubi::Node& node) { 46 fprintf(stderr, " %p ", (void*)node.identifier()); 47 js_fputs(node.typeName(), stderr); 48 if (node.coarseType() == JS::ubi::CoarseType::Object) { 49 if (const char* clsName = node.jsObjectClassName()) { 50 fprintf(stderr, " [object %s]", clsName); 51 } 52 } 53 fputc('\n', stderr); 54 } 55 56 JS_PUBLIC_API void dumpPaths(JSContext* cx, Node node, 57 uint32_t maxNumPaths /* = 10 */) { 58 JS::ubi::RootList rootList(cx, true); 59 auto [ok, nogc] = rootList.init(); 60 MOZ_ASSERT(ok); 61 62 NodeSet targets; 63 ok = targets.putNew(node); 64 MOZ_ASSERT(ok); 65 66 auto paths = ShortestPaths::Create(cx, nogc, maxNumPaths, &rootList, 67 std::move(targets)); 68 MOZ_ASSERT(paths.isSome()); 69 70 int i = 0; 71 ok = paths->forEachPath(node, [&](Path& path) { 72 fprintf(stderr, "Path %d:\n", i++); 73 for (auto backEdge : path) { 74 dumpNode(backEdge->predecessor()); 75 fprintf(stderr, " |\n"); 76 fprintf(stderr, " |\n"); 77 fprintf(stderr, " '"); 78 79 const char16_t* name = backEdge->name().get(); 80 if (!name) { 81 name = u"<no edge name>"; 82 } 83 js_fputs(name, stderr); 84 fprintf(stderr, "'\n"); 85 86 fprintf(stderr, " |\n"); 87 fprintf(stderr, " V\n"); 88 } 89 90 dumpNode(node); 91 fputc('\n', stderr); 92 return true; 93 }); 94 MOZ_ASSERT(ok); 95 96 if (i == 0) { 97 fprintf(stderr, "No retaining paths found.\n"); 98 } 99 } 100 #endif 101 102 } // namespace ubi 103 } // namespace JS