Source code

Revision control

Copy as Markdown

Other Tools

// The shortestPaths function exists solely to let the fuzzers go to town and
// exercise the code paths it calls into, hence the only things to assert
// relate to the shortestPaths test function API.
//
// The actual behavior of JS::ubi::ShortestPaths is tested in
// js/src/jsapi-tests/testUbiNode.cpp, where we can actually control the
// structure of the heap graph to test specific shapes.
function f(x) {
return x + x;
}
var g = f.bind(null, 5);
var o = {
p: g
};
function describe(v) {
return v === undefined ? "(undefined)"
: v === null ? "(null)"
: typeof(v) === "object" ? Object.prototype.toString.call(v)
: typeof(v);
}
function dumpPaths(results) {
results = results.map(paths =>
paths.map(path =>
path.map(({predecessor, edge}) =>
predecessor !== undefined ?
{ predecessor: describe(predecessor), edge }
:
{ edge }
)
)
);
print(JSON.stringify(results, null, 2));
}
print("shortestPaths([Object, f, o.p], {start: this, maxNumPaths: 5})");
var paths = shortestPaths([Object, f, o.p], {start: this, maxNumPaths: 5});
dumpPaths(paths);
print();
print("shortestPaths([f], {start: o, maxNumPaths: 1})")
paths = shortestPaths([f], {start: o, maxNumPaths: 1});
dumpPaths(paths);
print();
print("shortestPaths([f], {start: this, maxNumPaths: 5})")
paths = shortestPaths([f], {start: this, maxNumPaths: 5});
dumpPaths(paths);
print();
print("shortestPaths([f], {maxNumPaths: 5})")
paths = shortestPaths([f], {maxNumPaths: 5});
dumpPaths(paths);
assertEq(paths[0].length <= 5, true, "Too many paths reported");
paths = shortestPaths([f, g]);
assertEq(paths.length, 2, "Two sets of paths expected");
paths = shortestPaths([f], {maxNumPaths: 1});
assertEq(paths[0].length, 1, "Single path expected");
print();
print("shortestPaths([1234n])")
paths = shortestPaths([1234n]);
dumpPaths(paths);
// Error messages are more generic under PBL.
if (!getBuildConfiguration('pbl')) {
var exc;
try { paths = shortestPaths(); } catch (exc) { e = ""+exc; };
assertEq(e.includes("TypeError") && e.includes("1 argument required"), true);
try { paths = shortestPaths(100, {}); } catch (exc) { e = ""+exc; };
assertEq(e, "TypeError: 100 is not an array object");
try { paths = shortestPaths([f], {start: 200}); } catch (exc) { e = ""+exc; };
assertEq(e, "TypeError: 200 is not a GC thing");
try { paths = shortestPaths([f, {}, {}, {}], { maxNumPaths: 0x40000000 }); } catch (exc) { e = "" + exc; };
assertEq(e, "out of memory");
try { paths = shortestPaths([f], { maxNumPaths: -1 }); } catch (exc) { e = "" + exc; };
assertEq(e, "TypeError: -1 is not greater than 0");
let arr = [{}];
let objWithGetter = {get start() { arr.length = 0; return {}; }};
try { paths = shortestPaths(arr, objWithGetter); } catch (exc) { e = ""+exc; }
assertEq(e, "TypeError: arr is not a dense array object with one or more elements");
}