summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/saved-stacks/principals-01.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/saved-stacks/principals-01.js')
-rw-r--r--js/src/jit-test/tests/saved-stacks/principals-01.js70
1 files changed, 70 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/saved-stacks/principals-01.js b/js/src/jit-test/tests/saved-stacks/principals-01.js
new file mode 100644
index 0000000000..85b46feb87
--- /dev/null
+++ b/js/src/jit-test/tests/saved-stacks/principals-01.js
@@ -0,0 +1,70 @@
+// Test that SavedFrame.prototype.parent gives the next older frame whose
+// principals are subsumed by the caller's principals.
+
+// Given a string of letters |expected|, say "abc", assert that the stack
+// contains calls to a series of functions named by the next letter from
+// the string, say a, b, and then c. Younger frames appear earlier in
+// |expected| than older frames.
+function check(expected, stack) {
+ print("check(" + JSON.stringify(expected) + ") against:\n" + stack);
+ count++;
+
+ while (stack.length && expected.length) {
+ assertEq(stack.shift(), expected[0]);
+ expected = expected.slice(1);
+ }
+
+ if (expected.length > 0) {
+ throw new Error("Missing frames for: " + expected);
+ }
+ if (stack.length > 0 && !stack.every(s => s === null)) {
+ throw new Error("Unexpected extra frame(s):\n" + stack);
+ }
+}
+
+// Go from a SavedFrame linked list to an array of function display names.
+function extract(stack) {
+ const results = [];
+ while (stack) {
+ results.push(stack.functionDisplayName);
+ stack = stack.parent;
+ }
+ return results;
+}
+
+const low = newGlobal({ principal: 0 });
+const mid = newGlobal({ principal: 0xffff });
+const high = newGlobal({ principal: 0xfffff });
+
+var count = 0;
+
+ eval('function a() { check("a", extract(saveStack())); b(); }');
+low .eval('function b() { check("b", extract(saveStack())); c(); }');
+mid .eval('function c() { check("cba", extract(saveStack())); d(); }');
+high.eval('function d() { check("dcba", extract(saveStack())); e(); }');
+ eval('function e() { check("ecba", extract(saveStack())); f(); }');
+low .eval('function f() { check("fb", extract(saveStack())); g(); }');
+mid .eval('function g() { check("gfecba", extract(saveStack())); h(); }');
+high.eval('function h() { check("hgfedcba", extract(saveStack())); }');
+
+// Make everyone's functions visible to each other, as needed.
+ b = low .b;
+low .c = mid .c;
+mid .d = high.d;
+high.e = e;
+ f = low .f;
+low .g = mid .g;
+mid .h = high.h;
+
+low.check = mid.check = high.check = check;
+
+// They each must have their own extract so that CCWs don't mess up the
+// principals when we ask for the parent property.
+low. eval("" + extract);
+mid. eval("" + extract);
+high.eval("" + extract);
+
+// Kick the whole process off.
+a();
+
+assertEq(count, 8);